Commit graph

322 commits

Author SHA1 Message Date
Barnabás Pőcze
708e5443ae spa: bluez: add steal_reply_and_unref() helper
This function retrieves the reply from a DBusPendingCall and unrefs the call.
2023-07-15 01:04:23 +02:00
Barnabás Pőcze
183270f53c spa: bluez: add cancel_and_unref() dbus helper
This function cancels and unrefs a DBusPendingCall and
resets the pointer to NULL.
2023-07-15 01:04:22 +02:00
Barnabás Pőcze
33a5c4ba10 spa: bluez: fix spelling of HAVE_REALLOCARRAY feature macro
It should have two `R`s not three.
2023-07-14 18:20:07 +02:00
Barnabás Pőcze
abe8c3581f spa: bluez: free spa_bt_transport::configuration
`spa_bt_transport_free()` did not free `spa_bt_transport::configuration`,
so fix that.
2023-07-13 21:27:53 +02:00
Barnabás Pőcze
6275269f09 spa: bluez: remove some unused variables 2023-07-03 19:40:31 +02:00
Barnabás Pőcze
f6ea5421e6 spa: bluez: do not open-code asprintf() 2023-07-03 19:40:31 +02:00
Barnabás Pőcze
605404c781 spa: bluez: device_stop_timer(): remove redundant decl
Also move the declaration of `media_codec_switch_free()`
up to the beginning of the file, near the other decls.
2023-07-03 19:40:31 +02:00
Pauli Virtanen
7aae8c45ec bluez5: do not delay transport release if it is not active
Transport release should not be delayed if it is not active, since the
fd cannot be used any more, and the transport needs to be reacquired to
get a working fd.

Fixes reacquiring transports if the remote side causes them to become
inactive.
2023-05-26 07:17:51 +00:00
Pauli Virtanen
1d23d21ffe bluez5: check if we have any codecs before trying to register
Don't try to register A2DP / BAP with BlueZ if we don't have any codecs
for that.
2023-05-18 14:36:16 +03:00
Barnabás Pőcze
4d5f3620af spa: bluez: initalize DBusError object
The DBusError passed to `dbus_set_error_from_message()` must
be initialized, otherwise libdbus aborts:

  dbus[129473]: arguments to dbus_set_error_from_message() were incorrect,
                assertion "(error) == NULL || !dbus_error_is_set ((error))"
                failed in file dbus-message.c line 4043.
  This is normally a bug in some application using the D-Bus library.
2023-05-03 11:27:25 +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
9c788d0c7e bluez5: unref pending calls after cancel
Cancel doesn't decrease refcount, so needs unref too.
2023-04-30 18:38:30 +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
9d7d3599db bluez5: output silence if no data for some ISO sinks
When a sink contributing to an ISO CIG does not have data, output
silence for it, as long as at least one sink in the CIG is running.
Only if writes to sockets fail, pause all streams to reset
synchronization.

This way we write exactly the same number of packets for each CIS at the
same time, which probably is the best tested configuration in BT
adapters and devices. We also don't then have to pause output if some
sinks are not running or miss their timing, as we generate silence on
the fly.

When using iso-io, have it initialize the codec instance, and have
media-sink uses that instance, so that silence and actual audio are
encoded with the same codec.
2023-04-14 22:29:03 +03:00
Pauli Virtanen
2d1b02b5a2 bluez5: wait for all pending transports in CIG before marking active
Mark transports in CIG active only after all acquires are completed, so
that all iso-io are present before sinks are started.
2023-04-14 22:29:01 +03:00
Pauli Virtanen
645822b30b bluez5: refresh device set leader when current one disconnects 2023-04-12 10:12:00 +00:00
Pauli Virtanen
1a44754f8d bluez5: wait for devices in the same set before emitting nodes
Emit nodes only after all devices in the same set are ready, or until
add timeout elapses.
2023-04-10 07:00:44 +00: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
e0939ff8ab bluez5: don't set bluez timeout on transport release
Setting bluez timeout on transport release makes codec switches delayed,
and is not necessary.
2023-04-03 16:35:22 +00:00
Pauli Virtanen
c0d55eae86 bluez5: use release timeout for all transport types
Avoiding unnecessary release + reacquire when nodes restart makes sense
for all transport types.  Do timed releases for all transport types, not
only SCO.
2023-04-03 16:35:22 +00:00
Pauli Virtanen
b50ca80281 bluez5: do transport release synchronously
Do transport release synchronously for simplicity.  BlueZ handles
releasing while acquire is pending, but acquire while release is pending
would fail the acquire.

Otherwise we need to maintain an operation chain to handle trying to
acquire/release while the other operation is pending.  This makes things
complex with little gained, as releases generally don't block for a long
time.
2023-03-26 15:12:51 +03:00
Pauli Virtanen
fc56361ffd bluez5: set right transport active when acquiring linked
The linked transport should be activated, the main one was already
activated above.
2023-03-26 12:44:13 +03: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
397059017b bluez5: don't rely on bluez event ordering for acquire
Don't assume that transport State property update arrives after acquire
completion callback.

It currently does, but best to not rely on it.
2023-03-18 14:11:54 +02:00
Pauli Virtanen
eb12a3dfca bluez5: acquire all BAP transports in a CIG at the same time
We need to acquire and release all transports in the same CIG at the
same time.

Due to current kernel ISO socket limitations, this cannot be done one by
one.
2023-03-17 16:56:31 +00: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
fa3ee2e20b bluez5: allow disabling sink or source endpoints
Add option bluez5.roles that selects which endpoints (A2DP, BAP, HFP,
HSP) will be enabled.

This extends and deprecates bluez5.headset-roles.
2023-03-16 20:58:55 +02: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
987b772b97 bluez5: don't claim sbc is supported when there's no A2DP at all
Handle failure to register legacy A2DP endpoints.
2023-02-06 06:35:40 +00:00
Pauli Virtanen
1ed9daa8c5 bluez5: fix supported codecs when as BAP Server
BAP Clients do not have endpoints associated with them, and we only know
that codecs on currently configured transports are supported.

Handle this case in spa_bt_device_supports_media_codec
2023-01-29 17:38:21 +02: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
Wim Taymans
6207d98ff1 spa: add debug log context
Make a real debug context with a log function and move it to a new file.
This way we don't need to redefine a macro.
Make a new context for debugging to a log file. Make new functions to
debug to a log file.
Move the stringbuffer to string utils.
Integrate file/line/func and topics into the debug log.
We can remove some more things from the pipewire log_object function and
also add support for topics.
2023-01-18 17:51:16 +01:00
Pauli Virtanen
37d78ce29e bluez5: disable LE Audio if using legacy bluez API 2023-01-17 19:58:42 +02:00
Pauli Virtanen
a372c89544 bluez5: lc3: handle multiple PACs in capabilities
BlueZ may send multiple PACs in the capabilities delimited by zero LTV.
Handle this case by selecting the "best" one.

The configuration size may also for BAP generally be different from PAC
size.
2023-01-17 19:58:42 +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
Pauli Virtanen
99406aefea bluez5: deal with missing endpoint path in selectproperties 2022-10-26 18:59:26 +03:00
Barnabás Pőcze
95eeb7c2ec spa: bluez: dbus: add endpoint (un)registration helpers
Introduce `unregister_media_endpoint()` to unregister the specified
media endpoint object from dbus. Moreover, move the logic that decides
whether or not a particular codec should be registered for a given
direction into `endpoint_should_be_registered()` and use that in
both `(un)register_media_endpoint()`.
2022-10-21 13:39:31 +00:00
Pauli Virtanen
9846e0cb7a bluez5: in SelectProperties, parse QoS values and pass to get_qos
The codec may need to take into account endpoint preferred QoS values,
so parse this information and pass it to the codec's get_qos.

All the QoS struct values need to be set, as otherwise BlueZ may pass
uninitialized zero values over the air, which devices can reject.  This
does not apply to CIG/CIS ids, which are automatically allocated by
default.

Fixes connecting to nrf5340 devkit, which requires a valid TargetLatency
value.
2022-10-12 07:26:00 +00:00
Barnabás Pőcze
61453b91bd spa: bluez: dbus: emit added devices when adding new listener
Previously, when a new listener was registered,
it was not made aware of the already added devices.
2022-10-08 18:16:25 +02:00
Barnabás Pőcze
52af41850d spa: bluez: dbus: harmonize label indentation 2022-10-08 18:05:11 +02:00
Barnabás Pőcze
fd979a3cf7 spa: bluez: dbus: use tabs for indentation 2022-10-08 18:05:11 +02:00
Barnabás Pőcze
253c8b48fc spa: bluez: dbus: use spa_strstartswith() 2022-10-08 18:05:11 +02:00
Barnabás Pőcze
8ca5c0f15b spa: bluez: dbus: do not use NameHasOwner()
Commit 947ee152d3 ("bluez: check dbus service before enumerating objects")
introduced a check that would esure that GetManagedObjects()
is not called if the "org.bluez" name has no owner. This
was done to avoid auto-starting the bluez daemon.

However, this is not needed because it is possible to set on
a per-message basis whether or not the destination service
should be automatically started by the dbus daemon.
2022-10-08 17:59:41 +02:00
Barnabás Pőcze
1d3497b0cd spa: bluez: dbus: do not call GetManagedObjects() if there is a pending call 2022-10-08 17:59:41 +02:00