src/modules/bluetooth/bluetooth-util.c | 18 ---- src/modules/bluetooth/module-bluetooth-device.c | 104 +++++++++--------------- 2 files changed, 41 insertions(+), 81 deletions(-)
New commits: commit fcaef8285aec9d22764b8d41e6e1379f5cfd583f Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Fri Sep 28 17:45:31 2012 +0200 bluetooth: Unlink sink-sources in stop_thread() Avoid duplicated code by moving the unlinking of sinks and sources to stop_thread(). After all, they need to be unlinked when the thread is stopped. diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index e55c8c6..4a88a08 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2033,6 +2033,12 @@ static void stop_thread(struct userdata *u) { pa_assert(u); + if (u->sink && !USE_SCO_OVER_PCM(u)) + pa_sink_unlink(u->sink); + + if (u->source && !USE_SCO_OVER_PCM(u)) + pa_source_unlink(u->source); + if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); @@ -2213,20 +2219,12 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { } } - if (u->sink) { + if (u->sink) inputs = pa_sink_move_all_start(u->sink, NULL); - if (!USE_SCO_OVER_PCM(u)) - pa_sink_unlink(u->sink); - } - - if (u->source) { + if (u->source) outputs = pa_source_move_all_start(u->source, NULL); - if (!USE_SCO_OVER_PCM(u)) - pa_source_unlink(u->source); - } - stop_thread(u); if (USE_SCO_OVER_PCM(u)) @@ -2680,12 +2678,6 @@ void pa__done(pa_module *m) { if (!(u = m->userdata)) return; - if (u->sink && !USE_SCO_OVER_PCM(u)) - pa_sink_unlink(u->sink); - - if (u->source && !USE_SCO_OVER_PCM(u)) - pa_source_unlink(u->source); - stop_thread(u); if (USE_SCO_OVER_PCM(u)) commit 8560b495bda60c6876927280ec34cbf0ddd29fc8 Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Fri Sep 28 17:45:30 2012 +0200 bluetooth: Release transport in stop_thread() Avoid duplicated code by releasing the transport inside stop_thread(), along with the rest of the thread-related cleanup. diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 0f39772..e55c8c6 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1987,13 +1987,6 @@ static int setup_transport(struct userdata *u) { return -1; } - /* release transport if exist */ - if (u->transport) { - bt_transport_release(u); - pa_xfree(u->transport); - u->transport = NULL; - } - /* check if profile has a transport */ t = pa_bluetooth_device_get_transport(d, u->profile); if (t == NULL) { @@ -2066,6 +2059,12 @@ static void stop_thread(struct userdata *u) { u->hsp.nrec_changed_slot = NULL; } + if (u->transport) { + bt_transport_release(u); + pa_xfree(u->transport); + u->transport = NULL; + } + if (u->sink) { if (u->profile == PROFILE_HSP) { k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink); @@ -2230,12 +2229,6 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { stop_thread(u); - if (u->profile != PROFILE_OFF && u->transport) { - bt_transport_release(u); - pa_xfree(u->transport); - u->transport = NULL; - } - if (USE_SCO_OVER_PCM(u)) restore_sco_volume_callbacks(u); @@ -2740,11 +2733,6 @@ void pa__done(pa_module *m) { pa_xfree(u->address); pa_xfree(u->path); - if (u->transport) { - bt_transport_release(u); - pa_xfree(u->transport); - } - if (u->discovery) pa_bluetooth_discovery_unref(u->discovery); commit 0c5054e04a09fa52cafe7fc5666b41322d39dfcf Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Fri Sep 28 17:45:29 2012 +0200 bluetooth: Don't find device if set profile is off If the card is being set to off profile, it is not necessary to check if the device exists. This could potentially happen during shutdown, immediately before the module is unloaded. diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index bfb47d1..0f39772 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2184,7 +2184,6 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { struct userdata *u; enum profile *d; pa_queue *inputs = NULL, *outputs = NULL; - const pa_bluetooth_device *device; pa_assert(c); pa_assert(new_profile); @@ -2192,28 +2191,27 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { d = PA_CARD_PROFILE_DATA(new_profile); - if (!(device = pa_bluetooth_discovery_get_by_path(u->discovery, u->path))) { - pa_log_error("Failed to get device object."); - return -PA_ERR_IO; - } - - /* The state signal is sent by bluez, so it is racy to check - strictly for CONNECTED, we should also accept STREAMING state - as being good enough. However, if the profile is used - concurrently (which is unlikely), ipc will fail later on, and - module will be unloaded. */ - if (device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) { - pa_log_warn("HSP is not connected, refused to switch profile"); - return -PA_ERR_IO; - } else if (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) { - pa_log_warn("A2DP Sink is not connected, refused to switch profile"); - return -PA_ERR_IO; - } else if (device->audio_source_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP_SOURCE) { - pa_log_warn("A2DP Source is not connected, refused to switch profile"); - return -PA_ERR_IO; - } else if (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW) { - pa_log_warn("HandsfreeGateway is not connected, refused to switch profile"); - return -PA_ERR_IO; + if (*d != PROFILE_OFF) { + const pa_bluetooth_device *device; + + if (!(device = pa_bluetooth_discovery_get_by_path(u->discovery, u->path))) { + pa_log_error("Failed to get device object."); + return -PA_ERR_IO; + } + + if (device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) { + pa_log_warn("HSP is not connected, refused to switch profile"); + return -PA_ERR_IO; + } else if (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) { + pa_log_warn("A2DP Sink is not connected, refused to switch profile"); + return -PA_ERR_IO; + } else if (device->audio_source_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP_SOURCE) { + pa_log_warn("A2DP Source is not connected, refused to switch profile"); + return -PA_ERR_IO; + } else if (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW) { + pa_log_warn("HandsfreeGateway is not connected, refused to switch profile"); + return -PA_ERR_IO; + } } if (u->sink) { commit b76ee008731843fb4c40b3bb642d2388bc4b348f Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Fri Sep 28 17:45:28 2012 +0200 bluetooth: Fix potential assertion failure It might happen that a PropertyChanged signal is received but the corresponding card profile has not been created, leading to an assertion failure in filter_cb() due to inexistent ports. This can happen if BlueZ misbehaves, or also if the UUIDs are reported later on (i.e. during pairing discovery). In any case, the signal should just be ignored. diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 3e518b5..bfb47d1 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1357,7 +1357,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } else if (dbus_message_is_signal(m, "org.bluez.HandsfreeGateway", "PropertyChanged")) { pa_bt_audio_state_t state = parse_state_property_change(m); - if (state != PA_BT_AUDIO_STATE_INVALID) { + if (state != PA_BT_AUDIO_STATE_INVALID && pa_hashmap_get(u->card->profiles, "hfgw")) { pa_device_port *port; pa_port_available_t available = audio_state_to_availability(state); @@ -1373,7 +1373,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } else if (dbus_message_is_signal(m, "org.bluez.Headset", "PropertyChanged")) { pa_bt_audio_state_t state = parse_state_property_change(m); - if (state != PA_BT_AUDIO_STATE_INVALID) { + if (state != PA_BT_AUDIO_STATE_INVALID && pa_hashmap_get(u->card->profiles, "hsp")) { pa_device_port *port; pa_port_available_t available = audio_state_to_availability(state); @@ -1389,7 +1389,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } else if (dbus_message_is_signal(m, "org.bluez.AudioSource", "PropertyChanged")) { pa_bt_audio_state_t state = parse_state_property_change(m); - if (state != PA_BT_AUDIO_STATE_INVALID) { + if (state != PA_BT_AUDIO_STATE_INVALID && pa_hashmap_get(u->card->profiles, "a2dp_source")) { pa_device_port *port; pa_port_available_t available = audio_state_to_availability(state); @@ -1402,7 +1402,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } else if (dbus_message_is_signal(m, "org.bluez.AudioSink", "PropertyChanged")) { pa_bt_audio_state_t state = parse_state_property_change(m); - if (state != PA_BT_AUDIO_STATE_INVALID) { + if (state != PA_BT_AUDIO_STATE_INVALID && pa_hashmap_get(u->card->profiles, "a2dp")) { pa_device_port *port; pa_port_available_t available = audio_state_to_availability(state); commit 94dbf25e816af19f7ec9911828279b990e77482e Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Fri Sep 28 17:45:27 2012 +0200 bluetooth: Trivial function rename Former setup_bt() was just setting up the transport, so it's easier to follow if the function name makes this more explicit. diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index e3ec6ae..3e518b5 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1976,7 +1976,7 @@ static void bt_transport_config(struct userdata *u) { } /* Run from main thread */ -static int setup_bt(struct userdata *u) { +static int setup_transport(struct userdata *u) { const pa_bluetooth_device *d; const pa_bluetooth_transport *t; @@ -2016,7 +2016,7 @@ static int init_profile(struct userdata *u) { pa_assert(u); pa_assert(u->profile != PROFILE_OFF); - if (setup_bt(u) < 0) + if (setup_transport(u) < 0) return -1; if (u->profile == PROFILE_A2DP || commit 67c00905560fbdecaa6bc07d6e1416155d65881b Author: Mikel Astiz <mikel.as...@bmw-carit.de> Date: Fri Sep 28 17:45:26 2012 +0200 bluetooth: Ignore Device.DisconnectRequested Handling the signal DisconnectRequested should be unnecessary since the profile-specific interfaces will be later disconnected, leading to module unload. Additionally, the signal is problematic: if an interface (i.e. A2DP AudioSource) is playing at the time DisconnectRequested is signaled, the following sequence can occur: 1. AudioSource is playing 2. DisconnectRequested is received 3. Module is unloaded due to DisconnectRequested 4. AudioSource state changes from playing to connected 5. module-bluetooth-discover loads the module 6. AudioSource state changes from connected to disconnected Therefore the module is unnecessarily loaded, to be unloaded immediately afterwards. This can easily be reproduced if a device is unpaired while the audio is streaming. The simplest solution to this consists of removing step 3, by just ignoring the DisconnectRequested signal. This reverts commit 8169a6a6c921215c1353e8a34fccbdc4e2e20440. diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index b161937..e14c8c8 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -862,22 +862,6 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } else if (dbus_message_is_signal(m, "org.bluez.Device", "DisconnectRequested")) { - pa_bluetooth_device *d; - - if ((d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) { - /* Device will disconnect in 2 sec */ - d->audio_state = PA_BT_AUDIO_STATE_DISCONNECTED; - d->audio_sink_state = PA_BT_AUDIO_STATE_DISCONNECTED; - d->audio_source_state = PA_BT_AUDIO_STATE_DISCONNECTED; - d->headset_state = PA_BT_AUDIO_STATE_DISCONNECTED; - d->hfgw_state = PA_BT_AUDIO_STATE_DISCONNECTED; - - run_callback(y, d, FALSE); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } else if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) { const char *name, *old_owner, *new_owner; @@ -1471,7 +1455,6 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'", "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'", "type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'", - "type='signal',sender='org.bluez',interface='org.bluez.Device',member='DisconnectRequested'", "type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'", @@ -1537,7 +1520,6 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'", "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'", "type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'", - "type='signal',sender='org.bluez',interface='org.bluez.Device',member='DisconnectRequested'", "type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'", _______________________________________________ pulseaudio-commits mailing list pulseaudio-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-commits