From: Marc-Andr? Lureau <marc-andre.lureau@xxxxxxxxx> The current implementation is totally bogus, it cast the over_sink userdata to the bluetooth-device userdata... It was failing nicely because the previous code had a gentle safe-guard in u->profile == PROFILE_HSP, and u->profile was just random. There is no easy way to associate additional data to a sink or source. Two solutions seems possible: looking up loaded modules and check which one was handling the sink/source, or using pa_shared. I went for the second solution. --- src/modules/bluetooth/module-bluetooth-device.c | 59 +++++++++++++++++++---- 1 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 10fb5ed..455a53a 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -39,6 +39,7 @@ #include <pulsecore/core-rtclock.h> #include <pulsecore/core-util.h> #include <pulsecore/core-error.h> +#include <pulsecore/shared.h> #include <pulsecore/socket-util.h> #include <pulsecore/thread.h> #include <pulsecore/thread-mq.h> @@ -1798,14 +1799,21 @@ fail: /* Run from main thread */ static void sink_set_volume_cb(pa_sink *s) { - struct userdata *u = s->userdata; DBusMessage *m; dbus_uint16_t gain; + struct userdata *u; + char *k; - pa_assert(u); + pa_assert(s); + pa_assert(s->core); - if (u->profile != PROFILE_HSP) - return; + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) s); + u = pa_shared_get(s->core, k); + pa_xfree(k); + + pa_assert(u); + pa_assert(u->sink == s); + pa_assert(u->profile == PROFILE_HSP); gain = (pa_cvolume_max(&s->real_volume) * 15) / PA_VOLUME_NORM; @@ -1822,14 +1830,21 @@ static void sink_set_volume_cb(pa_sink *s) { /* Run from main thread */ static void source_set_volume_cb(pa_source *s) { - struct userdata *u = s->userdata; DBusMessage *m; dbus_uint16_t gain; + struct userdata *u; + char *k; - pa_assert(u); + pa_assert(s); + pa_assert(s->core); - if (u->profile != PROFILE_HSP) - return; + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) s); + u = pa_shared_get(s->core, k); + pa_xfree(k); + + pa_assert(u); + pa_assert(u->source == s); + pa_assert(u->profile == PROFILE_HSP); gain = (pa_cvolume_max(&s->volume) * 15) / PA_VOLUME_NORM; @@ -2687,7 +2702,7 @@ int pa__init(pa_module* m) { struct userdata *u; const char *address, *path; DBusError err; - char *mike, *speaker, *transport; + char *mike, *speaker, *transport, *k; const pa_bluetooth_device *device; pa_assert(m); @@ -2788,6 +2803,18 @@ int pa__init(pa_module* m) { /* Connect to the BT service */ init_bt(u); + if (u->hsp.sco_sink) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_sink); + pa_shared_set(u->core, k, u); + pa_xfree(k); + } + + if (u->hsp.sco_source) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_source); + pa_shared_set(u->core, k, u); + pa_xfree(k); + } + if (u->profile != PROFILE_OFF) if (init_profile(u) < 0) goto fail; @@ -2820,6 +2847,8 @@ int pa__get_n_used(pa_module *m) { void pa__done(pa_module *m) { struct userdata *u; + char *k; + pa_assert(m); if (!(u = m->userdata)) @@ -2860,6 +2889,18 @@ void pa__done(pa_module *m) { shutdown_bt(u); + if (u->hsp.sco_sink) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_sink); + pa_shared_remove(u->core, k); + pa_xfree(k); + } + + if (u->hsp.sco_source) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_source); + pa_shared_remove(u->core, k); + pa_xfree(k); + } + if (u->a2dp.buffer) pa_xfree(u->a2dp.buffer); -- 1.7.4.1