/* Run from main thread */
static int add_sink(struct userdata *u) {
+ char *k;
+
if (USE_SCO_OVER_PCM(u)) {
pa_proplist *p;
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;
/* 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");
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;
/* Run from main thread */
static void stop_thread(struct userdata *u) {
+ char *k;
+
pa_assert(u);
if (u->thread) {
}
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;
}
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;
}
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;
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)
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;
}
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);
/* 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;
void pa__done(pa_module *m) {
struct userdata *u;
- char *k;
pa_assert(m);
stop_thread(u);
+ if (USE_SCO_OVER_PCM(u))
+ restore_sco_volume_callbacks(u);
+
if (u->connection) {
if (u->path) {
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);