Commit graph

49 commits

Author SHA1 Message Date
Georg Chini
998dfdf4cc bluez5-device: Correctly handle suspend/resume cyle for audio gateway role of ofono backend
When the ofono backend released a tranport during suspend of sink or source, the
transport state was not changed to IDLE. Therefore pa_bluetooth_transport_set_state()
would return immediately when trying to resume. Even though the transport was acquired
correctly, setup_stream() would never be called and the resume failed.

This patch sets the transport state to IDLE when the transport is released. On resume,
the first call to transport_acquire() will be done from the message handler of the
*_SET_STATE message when source or sink are set to RUNNING. This call will only request
the setup of the connection, so setup_stream() cannot be called.
When the transport changes the state to PLAYING in hf_audio_agent_new_connection(),
handle_transport_state_change() is called. Because the sink or source state is already
RUNNING, the pa_{source,sink}_suspend() call will not lead to a state change message
and the I/O thread must be signaled explicitely to setup the stream.

The first setup of the device would also fail, which was only visible when the profile
was restored after connecting the headset. When trying to restore the headset_head_unit
profile, the profile was shortly set to off, so the headset always returned to a2dp.

This patch allows a delayed setup for the headset_head_unit profile, so that the profile
can successfully be restored.
2017-05-04 13:14:51 +02:00
Luiz Augusto von Dentz
69c212f8c1 bluetooth: Auto recover if profile is 'off'
This means something went wrong, which in case of ofono backend it is
probably due to the profile not connecting immediately, but it can be
safely restored in that case the transport is playing which means the
profile has recovered connectivity.
2017-05-04 12:59:48 +02:00
Georg Chini
fe70b9e11a source/sink: Allow pa_{source, sink}_get_latency_within_thread() to return negative values
The reported latency of source or sink is based on measured initial conditions.
If the conditions contain an error, the estimated latency values may become negative.
This does not indicate that the latency is indeed negative but can be considered
merely an offset error. The current get_latency_in_thread() calls and the
implementations of the PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY messages truncate negative
latencies because they do not make sense from a physical point of view. In fact,
the values are truncated twice, once in the message handler and a second time in
the pa_{source,sink}_get_latency_within_thread() call itself.
This leads to two problems for the latency controller within module-loopback:

- Truncating leads to discontinuities in the latency reports which then trigger
  unwanted end to end latency corrections.
- If a large negative port latency offsets is set, the reported latency is always 0,
  making it impossible to control the end to end latency at all.

This patch is a pre-condition for solving these problems.
It adds a new flag to pa_{sink,source}_get_latency_within_thread() to allow
negative return values. Truncating is also removed in all implementations of the
PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY message handlers. The allow_negative flag
is set to false for all calls of pa_{sink,source}_get_latency_within_thread()
except when used within PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY. This means that the
original behavior is not altered in most cases. Only if a positive latency offset
is set and the message returns a negative value, the reported latency is smaller
because the values are not truncated twice.

Additionally let PA_SOURCE_MESSAGE_GET_LATENCY return -pa_sink_get_latency_within_thread()
for monitor sources because the source gets the data before it is played.
2017-04-17 19:50:10 +02:00
Tanu Kaskinen
d7e85813bd bluetooth: allow UTF-8 in device descriptions
Users may configure the device alias to have characters outside the
ASCII range, so our name cleanup routine was too aggressive. Let's just
make sure that the device description is a valid UTF-8 string.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=98160
2017-04-02 20:48:52 +03:00
Wim Taymans
e1dc75da99 backend-native: add support for the HSP Headset role
This is a rebase of Wim Taymans patch to support the HSP headset role that has
somehow been forgotten. Original patch can be found at
https://lists.freedesktop.org/archives/pulseaudio-discuss/2015-February/023242.html
Rebase and minor changes by Georg Chini.

In addition to the HSP Audio Gateway, also add support for the headset
role in the native bluetooth backend. In this role, pulseaudio is used as
headset.

In the headset role, we create source and sink to receive and send the samples
from the gateway, respectively. Module-bluetooth-policy will automatically load
loopback modules to link these to a sink and source for playback. Because this
makes the source the speaker and the sink the microphone, we need to reverse the
roles of source and sink compared to the gateway role.

In the gateway role, adjusting the sink volume generates a +VGS command to set
the volume on the headset. Likewise, receiving AT+VGS updates the sink volume.

In the headset role, receiving a +VGS should set the source volume and any
source volume changes should be reported back to the gateway with AT+VGS.
2017-03-07 15:17:43 +02:00
Georg Chini
066d4c2c23 bluez5-device: Use correct constants for fixed latency in PA_{SINK, SOURCE}_MESSAGE_GET_LATENCY
The PA_{SINK,SOURCE}_GET_LATENCY message handlers falsely always added the A2DP latency as fixed
latency instead of the profile specific constant.
2017-02-16 13:20:13 +02:00
Georg Chini
1c80af147d bluetooth: Make use of getsockopt() to determine MTU configurable
A recent patch changed the MTU size from the default value of 48 to the value
returned by getsockopt(). This breaks HSP for some setups. To circumvent the
problem, this patch introduces a boolean parameter "autodetect_mtu" for
module-bluetooth-discover, module-bluez5-discover and module-bluez5-device to
make this use of getsockopt() configurable.
2017-02-14 11:48:10 +02:00
Tanu Kaskinen
60695e3d84 don't assume that pa_asyncq_new() always succeeds
Bug 96741 shows a case where an assertion is hit, because
pa_asyncq_new() failed due to running out of file descriptors.
pa_asyncq_new() is used in only one place (not counting the call in
asyncq-test): pa_asyncmsgq_new(). Now pa_asyncmsgq_new() can fail too,
which requires error handling in many places. One of those places is
pa_thread_mq_init(), which can now fail too, and that needs additional
error handling in many more places. Luckily there weren't any places
where adding better error handling wouldn't have been easy, so there are
many changes in this patch, but they are not complicated.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=96741
2016-12-20 01:19:06 +02:00
Juha Kuikka
6a786c9375 bluetooth: fix race condition in BlueZ5 device disconnection
SW: Pulseaudio 8.0 / BlueZ 5.39

Symptoms:
While disconnecting/reconnecting a paired bluetooth headset (LG HBS750)
audio fails roughly on every other connection.

On a failed connection "pactl list cards" shows the bluetooth device's
card but "Active Profile: off". Issuing "pacmd set-card-profile X
a2dp_sink" makes audio work immediately.

I realized that when this happened, the previous disconnection did not
remove the card, instead it was only configured for "Active Profile:
off" but otherwise left in place.

Upon looking at PA debug logs I saw that the transport for the a2dp_sink
was first set into disconnected state and then into idle state. In
"device_connection_changed_cb()" this causes the
"pa_bluetooth_device_any_transport_connected()" return true and the
module-bluez5-device is not unloaded.

Further investigation shows that this is caused by a race of
module-bluez5-device.c:thread_func() and
MediaPoint1::ClearConfiguration().

When the FD in thread_func() is closed (POLLHUP) an
BLUETOOTH_MESSAGE_STREAM_FD_HUP message is sent into the main thread.
The handler of this message unconditionally sets the transport into IDLE
state. This is a problem if it has already been set into DISCONNECTED
state.
2016-11-28 13:17:44 +02:00
Pali Rohár
2abcbd2041 bluetooth: bluez5: Add profile name to sinks and sources
See commit 380a7fc240.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
2016-09-18 14:58:49 +03:00
Peter Meerwald-Stadler
4231befa77 bluetooth: Don't free modargs twice
CID1353139

Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
2016-08-16 10:31:44 +02:00
Tanu Kaskinen
32c2a6d64a bluetooth: don't create the HSP/HFP profile twice
create_card_profile() used to get called separately for HSP and HFP,
so if a headset supports both profiles, a profile named
"headset_head_unit" would get created twice. The second instance would
get immediately freed, so that wasn't a particularly serious problem.
However, I think it makes more sense to create the profile only once.
This patch makes things so that before a profile is created, we check
what name that profile would have, and if a profile with that name
already exists, we don't create the profile.

A couple of Yocto releases (jethro and krogoth) have non-upstream
patches that suffer from this double creation. The patches add
associations between profiles and ports, and those associations use
the profile name as the key. When the second profile gets freed, the
associations between the profile and its ports get removed, and since
the profile name is used as the key, this erroneously affects the
first profile too. Crashing ensues.

BugLink: https://bugzilla.yoctoproject.org/show_bug.cgi?id=10018
2016-08-10 21:37:33 +03:00
Tanu Kaskinen
7b62601401 card: move profile selection after pa_card_new()
I want module-alsa-card to set the availability of unavailable
profiles before the initial card profile gets selected, so that the
selection logic can use correct availability information.
module-alsa-card initializes the jack state after calling
pa_card_new(), however, and the profile selection happens in
pa_card_new(). This patch solves that by moving parts of pa_card_new()
to pa_card_choose_initial_profile() and pa_card_put().

pa_card_choose_initial_profile() applies the profile selection policy,
so module-alsa-card can first call pa_card_new(), then initialize the
jack state, and then call pa_card_choose_initial_profile(). After that
module-alsa-card can still override the profile selection policy, in
case module-alsa-card was loaded with the "profile" argument. Finally,
pa_card_put() finalizes the card creation.

An alternative solution would have been to move the jack
initialization to happen before pa_card_new() and use pa_card_new_data
instead of pa_card in the jack initialization code, but I disliked
that idea (I want to get rid of the "new data" pattern eventually).

The order in which the initial profile policy is applied is reversed
in this patch. Previously the first one to set it won, now the last
one to set it wins. I think this is better, because if you have N
parties that want to set the profile, we avoid checking N times
whether someone else has already set the profile.
2016-06-28 16:55:42 +03:00
Kiran Krishnappa
96b368b960 module: Remove redundant core argument from pa_module_unload()
pa_module_unload() takes two pointers: pa_module and pa_core.
The pa_core pointer is also available via the pa_module object,
so the pa_core argument is redundant

[David Henningsson: Rebased to git HEAD]
2015-12-07 09:31:58 +01:00
Sagar Nageshmurthy
ff329cdabb Fix: Prevent calling pa_rtpoll_free() for a NULL rtpoll
Flushing the asyncmsgq can cause arbitrarily callbacks to run, potentially
causing recursion into pa_thread_mq_done again. Because of this; rtpoll which
is cleared in the second iteration is tried to free once again by the first
iteration leading to PA crash.
2015-03-27 14:34:15 +01:00
Ondrej Holecek
5effc83479 update FSF addresses to FSF web page
FSF addresses used in PA sources are no longer valid and rpmlint
generates numerous warnings during packaging because of this.
This patch changes all FSF addresses to FSF web page according to
the GPL how-to: https://www.gnu.org/licenses/gpl-howto.en.html

Done automatically by sed-ing through sources.
2015-01-14 22:20:40 +02:00
David Henningsson
de1e78a47c bluez5: Do not suspend on no -> unknown profile transitions
In case a transport is currently disconnected and transitions to
idle, that should not count as a "remote hang up" event.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
2014-12-19 11:50:28 +01:00
Peter Meerwald
fa092af59c rtpoll: Drop extra wait_op argument to pa_rtpoll_run()
is always true, not used

Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
2014-11-09 22:53:06 +01:00
Wim Taymans
34a5c754a9 backend-native: implement volume control
Parse the gain changed AT commands from the headset and fire 2 new
hooks as a result. The device will connect to those hooks and change the
source/sink volumes.

When the source/sink volume changes, set the gain on the microphone or
speaker respectively. Make sure we do nothing if the transport can not
handle the gain changes.
2014-10-31 10:46:10 +05:30
Wim Taymans
2251085dda bluez5-device: use get_profile_direction
Use the get_profile_direction() helper function to decide when to add a
source and a sink instead of enumerating profiles.
2014-10-31 10:46:10 +05:30
João Paulo Rechi Vita
7fac520d89 bluetooth: Switch transport state to idle in case of HUP
In case the socket HUP the transport state should be set to idle which
will indicate the profile is no longer available.
2014-09-18 10:53:49 +03:00
Tanu Kaskinen
638d0a51e2 bluetooth: Always initialize profile->available
If the transport for the profile doesn't exist, the old behaviour was
to leave cp->available at the default value, which is
PA_AVAILABLE_UNKNOWN, but if there's no transport, the profile should
be marked as unavailable.
2014-08-24 12:38:18 +03:00
Luiz Augusto von Dentz
bdef2dbd0a bluetooth: Assert transport has a matching profile
It is a bug if a transport has no matching profile.
2014-08-22 12:24:39 +03:00
João Paulo Rechi Vita
1f0de01bfc bluetooth: Add basic support for HEADSET profiles
This commit adds basic support for devices implementing HSP Headset
Unit, HSP Audio Gateway, HFP Handsfree Unit, HFP Audio Gateway to the
BlueZ 5 bluetooth audio devices driver module (module-bluez5-device).
2014-08-22 12:10:12 +03:00
Tanu Kaskinen
15ae55ed9b bluetooth: Refactor POLLHUP handling
The code in the "io_fail" section was only used for HUP handling, but
there were jumps to there also from places where reading or writing
failed, because the read/write failure could have been caused by HUP.
This patch simplifies things by checking for HUP condition before
trying to read or write. Now if reading or writing fails, we will
jump to "fail" directly instead of going via the "io_fail" label. As
a result, the "io_fail" label isn't needed any more.
2014-06-24 13:29:39 +03:00
João Paulo Rechi Vita
5881368bf4 bluetooth: Notify the main thread of a stream fd HUP 2014-06-01 14:45:31 +03:00
João Paulo Rechi Vita
01feb3c162 bluetooth: Rename variable to improve code readability
The label 'u' is used throughout the code to name pointers to the struct
userdata.
2014-06-01 13:37:23 +03:00
João Paulo Rechi Vita
09933e582b bluetooth: Change BlueZ 5 card profile name from a2dp to a2dp_sink
This name is more acurate with regards of what role we're currently
playing and we've already been using it in
pa_bluetooth_profile_to_string() since 449d6cb.
2014-05-25 12:24:17 +03:00
James Bunton
3f21c21628 bluetooth: Fix timing to count based on decoded data
Currently the latency information is being updated based on the encoded
SBC data instead of the decoded PCM data. Fixing this required moving
the timing update to be after the packet has been decoded.
2014-03-03 18:06:21 +02:00
James Bunton
4a5f48e7a4 bluetooth: Don't abort on SBC decoding error
The Nokia E7 running Symbian Belle Refresh seems to generate invalid SBC
packets every few minutes. This causes pulseaudio to disconnect the
stream and log "SBC decoding error (-3)".

If a single packet is bad, pulseaudio should keep playing the stream.
2014-03-03 18:06:21 +02:00
Tanu Kaskinen
ce304d6208 Pass the profile object instead of the profile name to pa_card_set_profile()
When setting attribute foo, or in this case the card profile, in my
opinion the thing passed to the set_foo() function should be of the
type of foo, not a string identifier that can be used to search for
the actual foo in set_foo().

This is mostly a question of taste, but there's at least some small
benefit from passing the actual object: often the profile object is
already available when calling pa_card_set_profile(), so passing the
card name would cause unnecessary searching when pa_card_set_profile()
needs to look up the profile from the hashmap.
2013-11-29 07:25:13 +02:00
Tanu Kaskinen
189708a597 bluetooth: Add a comment about messing with the IDLE suspend cause 2013-09-29 19:47:16 +03:00
João Paulo Rechi Vita
dc4be17e07 bluetooth: Fail to load driver if discovery module is not loaded
For quite some time now the device driver module doesn't work well
without the discovery module, so for the BlueZ 5 support we'll prevent
the device driver module to be loaded if the discovery module is not
loaded.
2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
774c73309d bluetooth: Implement get_n_used() for module-bluez5-device 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
ef24f7f3aa bluetooth: Handle changes to BlueZ 5 transports state 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
8d303f0bd1 bluetooth: Process source messages for BlueZ 5 cards 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
05366fdc22 bluetooth: Process sink messages for BlueZ 5 cards 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
eb9813c833 bluetooth: Create I/O thread function for BlueZ 5 cards
Create the thread function, the render and push functions for A2DP, the
process message function for communication between the I/O thread and
the main thread, and other helper functions related to them.
2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
44462904df bluetooth: Set card profile for BlueZ 5 cards 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
d243fdd07b bluetooth: Start / stop I/O thread for BlueZ 5 cards 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
8d1decffd7 bluetooth: Create source for BlueZ 5 cards 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
0274032141 bluetooth: Create sink for BlueZ 5 cards 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
7e80678cc5 bluetooth: Initialize profiles for BlueZ 5 cards
Initialized the currently active profile, configure and acquire the
transport.
2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
a0ed6d7970 bluetooth: Create BlueZ 5 card profile for each audio UUID 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
5a9007338b bluetooth: Create BlueZ 5 card ports 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
501f5e2898 bluetooth: Create BlueZ 5 card 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
6ba1610b6f bluetooth: Unload module-bluez5-device on device's disconnection 2013-09-29 16:54:38 +03:00
João Paulo Rechi Vita
da61957602 bluetooth: Get BlueZ 5 device object
Get the remote device information stored in pa_bluetooth_discovery. This
also creates the mandatory parameter 'path' for module-bluez5-device,
which is used to inform the object path of the remote device in BlueZ on
the module load.
2013-09-29 16:54:37 +03:00
João Paulo Rechi Vita
384f4751eb bluetooth: Create module-bluez5-device 2013-09-29 16:54:37 +03:00