Commit graph

115 commits

Author SHA1 Message Date
Silviu Florian Barbulescu
8660066af6 Add suport for braodcast sink 2023-08-24 16:31:03 +00:00
Silviu Florian Barbulescu
b07bb4e106 Check if the adapter supports bap broadcast before registering the broadcast endpoint. 2023-08-24 16:31:03 +00:00
Silviu Florian Barbulescu
ef3fac401d bluez5: Add LE Audio BAP broadcast source support
Once Pipewire is started it will try to register a BAP broadcast source media endpoint on UUID 00001852-0000-1000-8000-00805f9b34fb if the media codec that supports BAP and the adapter indicates LE Audio is supported.
When the endpoint is detected (over DBus) by Pipewire and it has a broadcast sink UUID, a new device will be created with the address 00:00:00:00:00:00. This device will be our simulated remote device. This is done because a broadcast source emitting device does not need any connection to start transmitting the audio. This device is set as connected.
When the SetConfiguration DBus method is called and the spa_bt_transport structure with the profile BAP broadcast source is created we switch the device from the one read from DBus to the one created by us. This is done because in BlueZ, when the transport is created, at the Device property, BlueZ sets the adapter as the device that the transport is connected to. Here the device will have the newly created SPA_BT_PROFILE_BAP_BROADCAST_SINK profile connected.
Added code that allows to create a node in the graph for a device connected to the SPA_BT_PROFILE_BAP_BROADCAST_SINK profile.
2023-08-24 16:31:03 +00:00
Pauli Virtanen
04951ac15f bluez5: make set transport volume calls async
The transport set volume call may take a long time or never complete, so
make them async to not block main loop.

Also reduce log level to info for the failed volume setting, as this is
something the user can do nothing about.
2023-04-30 18:44:33 +03:00
Pauli Virtanen
420f7cb48e bluez5: select BAP audio locations in SelectProperties
Do BAP audio location selection properly in SelectProperties, now that
BlueZ provides the supported locations there. Remove a previous
workaround.

The audio location in SelectProperties determines the audio channel
allocation, which determines the channel positions.
2023-04-25 21:44:38 +03:00
Pauli Virtanen
d642569394 bluez5: parse device set information via dbus
Parse device set information from DBus, and link devices to each other
according to it.  Add signal for notifying about device set changes.
2023-04-10 07:00:44 +00:00
Pauli Virtanen
eca13ec230 bluez5: iso-io: get BAP interval from dbus, not getsockopt
For ISO server sockets, the QOS struct from getsockopt contains values
with different meaning from ISO client socket. Get the values via DBus
instead, which is right in both cases.
2023-04-10 07:00:44 +00:00
Pauli Virtanen
6e94487057 bluez5: set BAP channel location from transport if unset
If BAP codec configuration is mono channel with unspecified location,
set the channel position from transport location.

This in principle should be set in SelectProperties, but currently BlueZ
doesn't tell us that yet there, so we hack it up later on.
2023-04-10 07:00:44 +00:00
Pauli Virtanen
cec050ac25 bluez5: add spa_bt_iso_io that does the low-level part for ISO
Add factored out helper for ISO socket I/O.

ISO sockets need synchronization of writes and audio position for
different stream fds in the same isochronous group, and it's easier to
separate out the part that coordinates it.
2023-04-03 16:35:22 +00:00
Pauli Virtanen
13a9964a71 bluez5: don't try to acquire if we are getting errors
If transport goes into error state too often, fail instead of trying to
acquire it again.

This avoids getting into a tight acquire->fail->reacquire loop.
2023-03-18 15:39:56 +02:00
Pauli Virtanen
dfd30f37dc bluez5: parse BAP transport CIG/CIS properties 2023-03-17 16:56:31 +00:00
Pauli Virtanen
63118b130e bluez5: make A2DP/BAP transport acquire/release async
Change A2DP/BAP transport acquire and release to be async.

Since BlueZ acquiring ISO sockets blocks until all sockets in same CIG
are acquired, BAP transports must be acquired asynchronously.
2023-03-17 16:56:31 +00:00
Pauli Virtanen
1d5c693d33 bluez5: change sink/source run state follow transport state
Allow asynchronous changes in transport state in the sinks/sources.

Also allow transport acquire to be actually synchronous, in this case it
must set transport state during acquire call.

Separate driver start/stop from transport start/stop.
2023-03-17 16:56:31 +00:00
Pauli Virtanen
b9d7ecb5b2 bluez5: handle BAP presentation delay and transport latency
For BAP server audio sink, set buffering target so that we try to match
the target presentation delay.  Also adjust requested node latency to be
smaller than the delay.

Also fix BAP transport presentation delay value parsing, and parse also
the other BAP transport properties. Of these, transport latency value
needs to be taken into account in the total sink latency.
2023-02-19 22:44:23 +02:00
Barnabás Pőcze
934ab3036e treewide: use SPDX tags to specify copyright information
SPDX tags make the licensing information easy to understand and clear,
and they are machine parseable.

See https://spdx.dev for more information.
2023-02-16 10:54:48 +00:00
Pauli Virtanen
fb43a71543 bluez5: SupportedUUIDs is an adapter-specific property
The DBus adapter objects has both .Adapter1 and .Media1 interfaces.

Change handling of this so that we wait for both properties to appear.
2023-01-27 19:25:16 +02:00
Pauli Virtanen
7b54a891b4 bluez5: separate object manager for A2DP and BAP
BlueZ fails registering object managers containing A2DP endpoints if
controller is in LE-only mode.

Make the A2DP and BAP object managers separate, so that failure to
register one does not prevent registering the other.

Also rename some functions to indicate which ones deal with the legacy
BlueZ API.
2023-01-27 19:25:16 +02:00
Pauli Virtanen
d94832942e bluez5: allow codecs to share endpoints
AVDTP in principle allows 62 endpoints, but in practice it appears some
devices (Samsung Galaxy Buds2 Pro, Redmi Buds 3 Lite, probably others)
fail to connect A2DP when the number is somewhere above 24.  A2DP
connection works when initiated from the Central, but not when the
device itself does it, so these devices are not fully broken.  We should
reduce the number of registered A2DP endpoints to avoid running into
problems with such broken devices.

Some of our source codecs are the same actual codec with the same
configuration, and don't need separate source endpoints.

Allow codecs to not have a registered endpoint (fill_caps == NULL), and
tolerate codecs with the same endpoint name.  In codec switch, keep
track separately which of the codecs with the same endpoint name the
local endpoint is currently associated with.
2022-10-26 18:59:26 +03:00
Frédéric Danis
28b4fbecfb bluez5: Manage BAP linked transports
Multiple transport from the same device may share the same stream (CIS)
and group (CIG) but for different direction, e.g. a speaker and a
microphone. In this case they are linked.
In this case:
- On acquire, if another transport has already been acquired, the new
  transport should not call Acquire or TryAcquire but re-use values from
  the previously acquired transport,
- on release, the closing of transport fd and call to Release should be
  done only for the last transport.
2022-09-15 11:17:20 +00:00
Frédéric Danis
cd50188787 bluez5: Fix node creation depending on device role
We can't determine which remote endpoint or device the
SelectConfiguration() call is associated with. For LE Audio BAP, as this
method is called only for the Initiator we set the whole instance as a
Central/Initiator.
This flag is unset on BAP media endpoint removal.
2022-09-15 11:17:20 +00:00
Frédéric Danis
284da66deb bluez5: Add BAP_SINK/SOURCE from PACS UUID to adapter profiles
BAP sink/source are characteristics of the PACS profile, but we're more
interested by those characteristics then the more generic profile.
2022-09-15 11:17:20 +00:00
Frédéric Danis
96acc5a79a bluez5: Add LE Audio BAP support to bluez5-device 2022-09-15 11:17:20 +00:00
Frédéric Danis
fd0bcb1699 bluez5: Add LE Audio BAP support to media-codecs 2022-09-15 11:17:20 +00:00
Frédéric Danis
00d51c3d31 bluez5: Rename codec API from *a2dp* to *media*
The BlueZ Media1 interface will not only be used for A2DP but also for
LE Audio and code related can be shared.
2022-09-15 11:17:20 +00:00
Frédéric Danis
e7f17e1523 bluez5: use lower case for UUIDs
BlueZ uses lower case version for the UUIDs in its DBus interface.
This will simplify future UUID tests.
2022-08-03 06:15:54 +00:00
Pauli Virtanen
0dc8255057 bluez5: handle sink vs. source correctly in get_supported_codecs
Make a distinction between sink and source endpoints when determining
supported codecs.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
ca18b8b733 bluez5: endpoint can be used only by one device at a time
AVDTP (v1.3 Sec 5.3) has a limitation that a local SEP (on the same
adapter) can be connected to at most one remote SEP. Trying to do have
it connected to multiple remotes either fails or causes misbehavior
later on.

Skip SetConfigure the same local endpoint for multiple remote ones in
codec switch. BlueZ observes this restriction in SelectConfiguration,
so also it won't try to do invalid configurations.

In BlueZ 5.64, the SetConfiguration calls succeed, but subsequent
transport acquires will fail. (Likely already the SetConfiguration DBus
call should fail.)

This all has the consequence, with the current approach to the
codec=endpoint correspondence, that if multiple devices are connected to
the same adapter, they currently have to use different codecs.
2022-05-30 07:35:54 +00:00
Pauli Virtanen
377bc16eb5 bluez5: handle any quantum in a2dp-sink
Remove quantum limitation from a2dp-sink, and adjust how flushing is
done.

The "low-latency" A2DP codecs are not able to flush all data at once, so
for them flush based on a timeout, such that "excess samples" for each
quantum is bounded.  We also limit excess samples for the other A2DP
codecs, based on some testing on flaky headset/adapter combinations (for
most cases, this does not appear to matter).

Leave decision of packet sizes to the codecs. Currently, we send packets
based on min_latency, but sendinf full packets might help with stutter
on some headset/adapter combinations.  The slightly increased latency
hardly matters against the 100ms delays in BT headsets.

Bump codec API version.
2022-03-11 18:09:55 +02:00
Pauli Virtanen
24fd273820 bluez5: backend-ofono: don't do codec probe connections + add wait
Codec probe connections can trigger bad behavior from oFono if done when
device is busy (e.g. at connect), and they might be done at the same
time as A2DP transport is acquired which cannot work.

Also, oFono will not reply to DBus Acquire, if device does not complete
codec negotiation correctly. This is most likely to happen just after
device connect, when it is busy with other stuff (eg A2DP).

Remove codec probe connections altogether: instead, we guess mSBC if
mSBC is enabled and otherwise CVSD. If the guess turns out to be wrong,
which is unlikely (almost all devices have mSBC), we recreate the
transport with correct codec (from main loop, must not be done in
*_acquire because that can destroy nodes + unload the spa libs while
we're being called from there).

To avoid oFono DBus hangs at startup, add delay before marking the
profile connected, enforcing a time difference to A2DP operations.
2022-03-05 17:46:40 +00:00
Pauli Virtanen
4bb3ff739a bluez5: keepalive A2DP source / SCO AG dynamic node transports
When acting as SCO AG / A2DP sink, the remote end should decide when to
close the connection.  This does not work currently properly, because
stopping sources/sinks releases the transport, which causes it to go
idle, and which then destroys dynamic nodes.  The sources/sinks should
not cause the transport to be released.

Implement keepalive flag for spa_bt_transport, such that
spa_bt_transport_release does not actually release the transport when
the refcount reaches zero. Set the flag for dynamic nodes when the
transport becomes pending (remote end connects) and unset the flag when
idle (remote end disconnected, or dynamic node removed).
2022-01-31 21:59:39 +02:00
Pauli Virtanen
1da23145df bluez5: probe adapter msbc capability via hci commands
Using a probe connection to determine adapter msbc capability causes
problems on some adapters (ff8c3d2, 84bc0490a5, 717004334b,
pipewire#2030) and seems to be a bad idea.

Go back to probing for transparent msbc transport capability via HCI
commands. bluetooth/hci.h may be deprecated later, but for now it's
better to go back to using it.  (In practice, adapters not supporting
esco appear to be fairly rare; kernel commit in 2013 refers to "older
devices", so if we can't use HCI, assume the adapter supports the
necessary modes.)
2022-01-30 22:00:32 +02:00
Pauli Virtanen
cc43b2f601 bluez5: rate limit BlueZ SetConfiguration calls
A2DP profile may disappear if several SetConfiguration events occur too
rapidly. Rate limit these calls when switching codecs.

This resolves failures if e.g. the session manager attempts to set the
profile immediately after the device is created, which previously might
cause a failure.
2022-01-04 22:14:10 +02:00
Pauli Virtanen
2329a4d323 bluez5: quirks for headset without a2dp duplex codecs
See #1756 (another headset with non-working, probably faststream duplex)
2021-11-08 08:25:55 +00:00
Pauli Virtanen
4b831021fb bluez5: add a dummy AVRCP player as a workaround
Some devices (Bose Mini Soundlink II, Air 1 Plus, ...) don't enable
AVRCP volume control, or fail to enable it before a hardware button is
pressed.  However, these devices appear to enable it, if an AVRCP player
is present.

As a workaround, register a dummy AVRCP player for each adapter. It only
displays the current transport acquisition state as playing/stopped, but
just its presence appears to be enough to make devices behave.

Multiple AVRCP players interfere with each other, as BlueZ uses the one
registered earliest as the default player. So add also a config option
for disabling this. (It's not common to have mpris-proxy etc. running,
so defaulting to true should be OK.)

See pipewire#1157
2021-10-10 16:24:41 +03:00
Pauli Virtanen
c620121529 bluez5: add faststream quirks
For some devices FastStream causes problems. Add quirk for disabling it.
2021-10-03 20:55:02 +03:00
Pauli Virtanen
90b4efd98d bluez5: cleanup hfp/hsp backend handling + config file option
It seems not uncommon that people have not properly configured ofono
running, which results to loss of HFP/HSP functionality. It's less
surprising if the backend selection is fixed in the configuration file,
and (by default) does not depend on running services.

Add a configuration file option for selecting HFP/HSP backend, and set
the default value to the native backend. Emit warnings if conflicting
backend services are detected to be running.

Also cleanup hfp/hsp backend handling a bit, now that it's mostly
abstracted behind an interface.
2021-09-19 17:33:32 +00:00
Pauli Virtanen
dedc08cdf8 bluez5: enable duplex for aptx-ll
aptX-LL sink devices may send back mSBC encoded data corresponding to
microphone input.  It appears to be enabled when the bidirectional link
is set in the caps, and the device also supports this.

Implement mSBC decoding in the duplex channel.

Tested to be working on Avantree Aria Pro.
2021-08-22 17:41:50 +03:00
Zsombor Welker
f5850af4d8 bluez5: handle XAPL battery level per Apple Guidelines
Corrects the handling of AT+XAPL Apple extensions to send
`+XAPL=iPhone,2` instead of `+XAPL: iPhone,2` based on Apple's
documentation.

Replaces magic numbers with enum values.

[Accessory Design Guidelines](https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf)
2021-08-13 10:30:36 +02:00
Zsombor Welker
f87942027f bluez5: report HF indicator 2 based battery status
HF indicator 2 (see [assigned-numbers], Hands-Free Profile) is able to
report battery percentage at 1% intervals (in range [0, 100]), contrary
to the `+XAPL` `+IPHONEACCEV` extension which only supports 10%
increments.  This does not guarantee increased granularity however, as
peers may still be limited to imprecise battery measurements internally
or round to coarser percentages.
Supporting both additionally broadens the range of devices for which PW
can report its battery level.

[assigned-numbers]:
https://www.bluetooth.com/specifications/assigned-numbers/
2021-08-12 18:45:44 +00:00
Huang-Huang Bao
9f2d6d6d28 bluez5: fix rounding error on hardware volume conversion
Ensure the conversions between spa_bt_volume_linear_to_hw and spa_bt_volume_hw_to_linear are reversible when
operating on hardware volume.
2021-07-30 08:46:14 +00:00
Barnabás Pőcze
f5d51162c4 treewide: mark things static and const
Mark some structures, arrays static/const at various places.
In some cases this prevents unnecessary initialization
when a function is entered.

All in all, the text segments across all shared
libraries are reduced by about 2 KiB. However,
the total size increases by about 2 KiB as well.
2021-06-30 14:44:08 +02:00
Pauli Virtanen
9d38d375d2 bluez5: add and use quirk for broken mic HW volume
Some headsets emit AT+VGM even though +VGM commands do not actually
adjust the recording volume.
2021-06-22 10:58:50 +03:00
Pauli Virtanen
b57ae8c2a6 bluez5: add support for hardware quirk/feature database
Implement hardware quirk/feature database with pattern matching.
2021-06-22 10:58:50 +03:00
Pauli Virtanen
2c9764da1d bluez5: parse bluez vendor/product ids
It seems few devices support the Device Id via bluez.

Try to figure out vendor/product ids for usb devices also via sysfs.
Also try to figure out the adapter bus type.
2021-06-22 10:58:50 +03:00
Huang-Huang Bao
3433f40cd9 bluez5: fix device connection issue if profile(UUIDs) info is delayed
Keep all types of devices, only emit device info if device has audio profiles.
Heuristically add profiles based on bluez actions so device can still be connected
even without initial UUIDs info from signal InterfaceAdded for org.bluez.Device1.

Fixes #1330
2021-06-21 07:10:02 +00:00
Huang-Huang Bao
d3fcc0a37a bluez5: correct parameter names in spa_bt_sco_io_create declaration
From its definition and parameters passed to its function call, the 3rd parameter
is read_mtu and the 4th is write_mtu.

Fixes #1256
2021-06-05 15:17:10 +00:00
Huang-Huang Bao
38bcec9022
bluez5: add port latency reporting 2021-05-28 20:02:10 +08:00
Andrea Gelmini
47ef2b6b09 Fix typos 2021-04-30 07:40:20 +00:00
Huang-Huang Bao
0dde4f8774 bluez5: cache a2dp volumes activation info
So we don't get a sudden boost on soft volumes when switching profile/codec.
2021-04-21 08:54:10 +00:00
Huang-Huang Bao
edee633f96
bluez5: add property to enable hardware volume control 2021-04-17 19:35:46 +08:00