diff options
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-device.c | 101 |
1 files changed, 69 insertions, 32 deletions
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index b0e0a7b4..e4a2ceff 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1959,6 +1959,8 @@ static pa_hook_result_t source_state_changed_cb(pa_core *c, pa_source *s, struct /* Run from main thread */ static int add_sink(struct userdata *u) { + char *k; + if (USE_SCO_OVER_PCM(u)) { pa_proplist *p; @@ -2012,6 +2014,10 @@ static int add_sink(struct userdata *u) { if (u->profile == PROFILE_HSP) { u->sink->set_volume = sink_set_volume_cb; u->sink->n_volume_steps = 16; + + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink); + pa_shared_set(u->core, k, u); + pa_xfree(k); } return 0; @@ -2019,6 +2025,8 @@ static int add_sink(struct userdata *u) { /* Run from main thread */ static int add_source(struct userdata *u) { + char *k; + if (USE_SCO_OVER_PCM(u)) { u->source = u->hsp.sco_source; pa_proplist_sets(u->source->proplist, "bluetooth.protocol", "hsp"); @@ -2077,6 +2085,10 @@ static int add_source(struct userdata *u) { if (u->profile == PROFILE_HSP) { u->source->set_volume = source_set_volume_cb; u->source->n_volume_steps = 16; + + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source); + pa_shared_set(u->core, k, u); + pa_xfree(k); } return 0; @@ -2323,6 +2335,8 @@ static int init_profile(struct userdata *u) { /* Run from main thread */ static void stop_thread(struct userdata *u) { + char *k; + pa_assert(u); if (u->thread) { @@ -2347,11 +2361,23 @@ static void stop_thread(struct userdata *u) { } if (u->sink) { + if (u->profile == PROFILE_HSP) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink); + pa_shared_remove(u->core, k); + pa_xfree(k); + } + pa_sink_unref(u->sink); u->sink = NULL; } if (u->source) { + if (u->profile == PROFILE_HSP) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source); + pa_shared_remove(u->core, k); + pa_xfree(k); + } + pa_source_unref(u->source); u->source = NULL; } @@ -2381,8 +2407,20 @@ static int start_thread(struct userdata *u) { if (USE_SCO_OVER_PCM(u)) { if (sco_over_pcm_state_update(u) < 0) { - u->sink = NULL; - u->source = NULL; + char *k; + + if (u->sink) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink); + pa_shared_remove(u->core, k); + pa_xfree(k); + u->sink = NULL; + } + if (u->source) { + k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source); + pa_shared_remove(u->core, k); + pa_xfree(k); + u->source = NULL; + } return -1; } @@ -2419,6 +2457,22 @@ static int start_thread(struct userdata *u) { return 0; } +static void save_sco_volume_callbacks(struct userdata *u) { + pa_assert(u); + pa_assert(USE_SCO_OVER_PCM(u)); + + u->hsp.sco_sink_set_volume = u->hsp.sco_sink->set_volume; + u->hsp.sco_source_set_volume = u->hsp.sco_source->set_volume; +} + +static void restore_sco_volume_callbacks(struct userdata *u) { + pa_assert(u); + pa_assert(USE_SCO_OVER_PCM(u)); + + u->hsp.sco_sink->set_volume = u->hsp.sco_sink_set_volume; + u->hsp.sco_source->set_volume = u->hsp.sco_source_set_volume; +} + /* Run from main thread */ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { struct userdata *u; @@ -2472,9 +2526,15 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { stop_thread(u); shutdown_bt(u); + if (USE_SCO_OVER_PCM(u)) + restore_sco_volume_callbacks(u); + u->profile = *d; u->sample_spec = u->requested_sample_spec; + if (USE_SCO_OVER_PCM(u)) + save_sco_volume_callbacks(u); + init_bt(u); if (u->profile != PROFILE_OFF) @@ -2639,6 +2699,9 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) { d = PA_CARD_PROFILE_DATA(u->card->active_profile); u->profile = *d; + if (USE_SCO_OVER_PCM(u)) + save_sco_volume_callbacks(u); + return 0; } @@ -2702,7 +2765,7 @@ int pa__init(pa_module* m) { struct userdata *u; const char *address, *path; DBusError err; - char *mike, *speaker, *transport, *k; + char *mike, *speaker, *transport; const pa_bluetooth_device *device; pa_assert(m); @@ -2803,20 +2866,6 @@ int pa__init(pa_module* m) { /* Connect to the BT service */ init_bt(u); - if (u->hsp.sco_sink) { - u->hsp.sco_sink_set_volume = u->hsp.sco_sink->set_volume; - 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) { - u->hsp.sco_source_set_volume = u->hsp.sco_source->set_volume; - 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; @@ -2849,7 +2898,6 @@ int pa__get_n_used(pa_module *m) { void pa__done(pa_module *m) { struct userdata *u; - char *k; pa_assert(m); @@ -2864,6 +2912,9 @@ void pa__done(pa_module *m) { stop_thread(u); + if (USE_SCO_OVER_PCM(u)) + restore_sco_volume_callbacks(u); + if (u->connection) { if (u->path) { @@ -2891,20 +2942,6 @@ void pa__done(pa_module *m) { shutdown_bt(u); - if (u->hsp.sco_sink) { - u->hsp.sco_sink->set_volume = u->hsp.sco_sink_set_volume; - 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) { - u->hsp.sco_source->set_volume = u->hsp.sco_source_set_volume; - 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); |