[pulseaudio-commits] 4 commits - src/modules

Tanu Kaskinen tanuk at kemper.freedesktop.org
Wed Aug 22 00:21:16 PDT 2012


 src/modules/bluetooth/module-bluetooth-device.c |   23 ++++-
 src/modules/bluetooth/module-bluetooth-policy.c |   94 ++++++++++++++++++++++--
 2 files changed, 106 insertions(+), 11 deletions(-)

New commits:
commit 9f924a9dda2c3b636d77756475832d2fa20b092d
Author: Mikel Astiz <mikel.astiz at bmw-carit.de>
Date:   Wed Aug 22 09:04:22 2012 +0200

    bluetooth: Support HFGW in module-bluetooth-policy
    
    Add support for hfgw card profile in module-bluetooth-policy, just like
    a2dp_source is handled.
    
    In this case also the sink needs to be connected using module-loopback.

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c
index 0d66eb0..03beeb2 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 {
     bool enable_a2dp_source;
+    bool 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) {
         goto fail;
     }
 
+    u->enable_hfgw = TRUE;
+    if (pa_modargs_get_value_boolean(ma, "hfgw", &u->enable_hfgw) < 0) {
+        pa_log("Failed to parse hfgw argument.");
+        goto fail;
+    }
+
     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);
+
     pa_modargs_free(ma);
     return 0;
 
@@ -129,5 +180,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);
 }

commit 2d6db0335f0a2754136835acea2e92496460c24b
Author: Mikel Astiz <mikel.astiz at bmw-carit.de>
Date:   Wed Aug 22 09:04:21 2012 +0200

    bluetooth: Generalize module-bluetooth-policy
    
    Instead of focusing on a2dp_source only, prepare the module to support
    several profiles. It will be possible to enable/disable each of them
    using module arguments.

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c
index 8ae7c4f..0d66eb0 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -28,6 +28,7 @@
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/core.h>
+#include <pulsecore/modargs.h>
 #include <pulsecore/source-output.h>
 #include <pulsecore/source.h>
 #include <pulsecore/core-util.h>
@@ -35,16 +36,25 @@
 #include "module-bluetooth-policy-symdef.h"
 
 PA_MODULE_AUTHOR("Frédéric Dalleau");
-PA_MODULE_DESCRIPTION("When an A2DP source is added, load module-loopback");
+PA_MODULE_DESCRIPTION("When a bluetooth sink or source is added, load module-loopback");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE(
+        "a2dp_source=<Handle a2dp_source card profile (sink role)?>");
+
+static const char* const valid_modargs[] = {
+    "a2dp_source",
+    NULL
+};
 
 struct userdata {
-     pa_hook_slot *source_put_slot;
+    bool enable_a2dp_source;
+    pa_hook_slot *source_put_slot;
 };
 
 /* When a source is created, loopback it to default sink */
 static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, void *userdata) {
+    struct userdata *u = userdata;
     const char *s;
     const char *role;
     char *args;
@@ -60,12 +70,11 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
     if (!pa_streq(s, "bluetooth"))
         return PA_HOOK_OK;
 
-    /* Restrict to A2DP profile (sink role) */
     s = pa_proplist_gets(source->proplist, "bluetooth.protocol");
     if (!s)
         return PA_HOOK_OK;
 
-    if (pa_streq(s, "a2dp_source"))
+    if (u->enable_a2dp_source && pa_streq(s, "a2dp_source")) /* A2DP profile (we're doing sink role) */
         role = "music";
     else {
         pa_log_debug("Profile %s cannot be selected for loopback", s);
@@ -81,15 +90,32 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
 }
 
 int pa__init(pa_module *m) {
+    pa_modargs *ma;
     struct userdata *u;
 
     pa_assert(m);
 
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log_error("Failed to parse module arguments");
+        return -1;
+    }
+
     m->userdata = u = pa_xnew(struct userdata, 1);
 
+    u->enable_a2dp_source = TRUE;
+    if (pa_modargs_get_value_boolean(ma, "a2dp_source", &u->enable_a2dp_source) < 0) {
+        pa_log("Failed to parse a2dp_source argument.");
+        goto fail;
+    }
+
     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);
 
+    pa_modargs_free(ma);
     return 0;
+
+fail:
+    pa_modargs_free(ma);
+    return -1;
 }
 
 void pa__done(pa_module *m) {

commit 69f4d4af16f11aa87c1b8ecde821d2fd32f17a78
Author: Mikel Astiz <mikel.astiz at bmw-carit.de>
Date:   Wed Aug 22 09:04:20 2012 +0200

    bluetooth: Trivial style fix
    
    Use consistent style for pointer types in module-bluetooth-policy.

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c
index 7f19447..8ae7c4f 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -44,7 +44,7 @@ struct userdata {
 };
 
 /* When a source is created, loopback it to default sink */
-static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, void* userdata) {
+static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, void *userdata) {
     const char *s;
     const char *role;
     char *args;
@@ -80,7 +80,7 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
     return PA_HOOK_OK;
 }
 
-int pa__init(pa_module*m) {
+int pa__init(pa_module *m) {
     struct userdata *u;
 
     pa_assert(m);
@@ -92,7 +92,7 @@ int pa__init(pa_module*m) {
     return 0;
 }
 
-void pa__done(pa_module*m) {
+void pa__done(pa_module *m) {
     struct userdata *u;
 
     pa_assert(m);

commit 2ef75a07b5da212d983525bf12228c995b4d3f0d
Author: Mikel Astiz <mikel.astiz at bmw-carit.de>
Date:   Wed Aug 22 09:04:19 2012 +0200

    bluetooth: Fix bluetooth.protocol property
    
    Property bluetooth.protocol did make a distinction between A2DP sink and
    source roles but on the contrary did not separate HFP roles (headset vs
    gateway). For consistency, they should both behave similarly.
    
    This automatically fixes another incosistency: the HFGW (or HSP) sink
    was set to bluetooth.protocol="sco", while the source was set to "hsp".
    There is no use for this distinction, since the protocol (including the
    role) is the same.

diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 44748df..623ef91 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1466,6 +1466,21 @@ static void connect_ports(struct userdata *u, void *sink_or_source_new_data, pa_
     }
 }
 
+static const char *profile_to_string(enum profile profile) {
+    switch(profile) {
+        case PROFILE_A2DP:
+            return "a2dp";
+        case PROFILE_A2DP_SOURCE:
+            return "a2dp_source";
+        case PROFILE_HSP:
+            return "hsp";
+        case PROFILE_HFGW:
+            return "hfgw";
+        default:
+            pa_assert_not_reached();
+    }
+}
+
 /* Run from main thread */
 static int add_sink(struct userdata *u) {
     char *k;
@@ -1475,7 +1490,7 @@ static int add_sink(struct userdata *u) {
 
         u->sink = u->hsp.sco_sink;
         p = pa_proplist_new();
-        pa_proplist_sets(p, "bluetooth.protocol", "sco");
+        pa_proplist_sets(p, "bluetooth.protocol", profile_to_string(u->profile));
         pa_proplist_update(u->sink->proplist, PA_UPDATE_MERGE, p);
         pa_proplist_free(p);
 
@@ -1490,7 +1505,7 @@ static int add_sink(struct userdata *u) {
         data.driver = __FILE__;
         data.module = u->module;
         pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
-        pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile == PROFILE_A2DP ? "a2dp" : "sco");
+        pa_proplist_sets(data.proplist, "bluetooth.protocol", profile_to_string(u->profile));
         if (u->profile == PROFILE_HSP)
             pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
         data.card = u->card;
@@ -1539,7 +1554,7 @@ static int add_source(struct userdata *u) {
 
     if (USE_SCO_OVER_PCM(u)) {
         u->source = u->hsp.sco_source;
-        pa_proplist_sets(u->source->proplist, "bluetooth.protocol", "hsp");
+        pa_proplist_sets(u->source->proplist, "bluetooth.protocol", profile_to_string(u->profile));
 
         if (!u->hsp.source_state_changed_slot)
             u->hsp.source_state_changed_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) source_state_changed_cb, u);
@@ -1552,7 +1567,7 @@ static int add_source(struct userdata *u) {
         data.driver = __FILE__;
         data.module = u->module;
         pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
-        pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile == PROFILE_A2DP_SOURCE ? "a2dp_source" : "hsp");
+        pa_proplist_sets(data.proplist, "bluetooth.protocol", profile_to_string(u->profile));
         if ((u->profile == PROFILE_HSP) || (u->profile == PROFILE_HFGW))
             pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
 



More information about the pulseaudio-commits mailing list