Commit graph

932 commits

Author SHA1 Message Date
Barnabás Pőcze
06030ddf76 spa: bluez: backend-hsphfpd: fix dbus type
Use `DBUS_TYPE_STRING` for a string and not `DBUS_TYPE_BOOLEAN`.
2023-05-03 11:27:25 +00:00
Barnabás Pőcze
abe9615fec spa: bluez: backend-hsphfpd: use dbus_bool_t for DBUS_TYPE_BOOLEAN 2023-05-03 11:27:25 +00:00
Barnabás Pőcze
36bfd5263f spa: bluez: do not check if service is running
It is inherently racy, and we have a better way to ensure that
we won't autostart the service:

  dbus_message_set_auto_start()

So use that.

This commit also adds a missing call to `dbus_pending_call_unref()`
and indirectly fixes a type mismatch (`dbus_bool_t` vs. `bool`)
that was present in `is_dbus_service_running()`.
2023-05-03 11:27:25 +00: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
Daniel Houck
c20e7788c5 Add 3M WorkTunes Connect to bluez-hardware.conf 2023-04-24 07:20:05 +00:00
Pauli Virtanen
ed82f9b83b bluez5: media-source: remove unnecessary workaround
The duplex polling issue was due to spa_loop_add_source failing
when source and sink were both using the same fd. We now dup, so the
issue no longer exists.

Remove the now unnecessary workaround, and check the return values from
spa_add_source.
2023-04-23 18:43:05 +03:00
Pauli Virtanen
f7b57d87d6 bluez5: backend-native: fix off-by-one in at+xevent 2023-04-22 13:26:54 +03:00
Pauli Virtanen
87269e85db bluez5: AT+XEVENT input validation, cleanups & respond OK
Also support AT+XEVENT=BATTERY,%u which some devices apparently send.
2023-04-20 16:03:47 +00:00
delaosa
65ddd0a42b bluez5: Add battery level reporting via AT+XEVENT 2023-04-20 16:03:47 +00:00
Wim Taymans
0333ddff45 pod-builder: move some code around to help gcc 13
Make sure to pop the frame before returning errors to stop gcc13
from complaining with -Wdangling-pointer

Fixes #3171
2023-04-20 17:52:27 +02:00
Pauli Virtanen
11df633b9b bluez5: media-source: transport not started is not an error
Transport not being started should not be considered IO error in
produce_buffer.
2023-04-18 23:30:22 +03:00
Pauli Virtanen
b619616c2a bluez5: media-sink: don't fail A2DP duplex sink if remote idles
Don't emit node error for A2DP duplex sink channel, or when BAP server.
These can occur under normal conditions (remote side suspends
transport), and are not errors.
2023-04-18 22:29:48 +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
a8770d501c bluez5: fix glib signal disconnect
Disconnect glib signal in the right way, silencing a glib warning.
2023-04-14 20:06:57 +03:00
Pauli Virtanen
bb5d01068e bluez5: iso-io: larger idle time
Use larger idle time, so that it's bigger than transport latency, in
case that helps to reset synchronization on controller/device side.
2023-04-12 10:12:00 +00:00
Pauli Virtanen
facef4a6c6 bluez5: lc3: use high-reliability QoS defaults
Use the "high-reliability" values for QoS parameters instead of the
low-latency ones. Under some condition BlueZ does not pass on the
endpoint QoS values to us, in which case we may end up selecting bad
latency.
2023-04-12 10:12:00 +00:00
Pauli Virtanen
645822b30b bluez5: refresh device set leader when current one disconnects 2023-04-12 10:12:00 +00:00
Pauli Virtanen
5b55118e7f bluez5: media-sink: fix reference time vs. resampling delay
Determine correctly if we are resampling, and have the associated delay.

Add off-by-one sample adjustment to the resampling delay, which seems to
correctly align the resampled audio with non-resampled.
2023-04-12 10:12:00 +00:00
Pauli Virtanen
5d1782760c bluez5: media-sink: resync ISO streams on playback start
Resynchronize ISO streams on playback (re)start, so the stream positions
are aligned immediately.  This is better than relying on rate matching
to correct any offsets.
2023-04-10 14:50:42 +00:00
Pauli Virtanen
882f9ad2b3 bluez5: emit BAP device set nodes as needed
Emit BAP device set nodes, which the session manager can use to combine
the sinks/sources of a device set to a single sink/source.

Emit the actual sinks/sources with media.class=.../Internal to hide them
from pipewire-pulse.

Add separate device set routes to the set leader device.  Other routes
of the set members will be marked as unavailable when the set is active.

Accordingly, return failure for attempts to set these unavailable
routes, so that volumes etc. of the "internal" nodes are only controlled
via the device set route.
2023-04-10 07:00:44 +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
ae76789f24 bluez5: iso-io: ensure streams are initially marked idle
Mark streams idle when they are being stopped/started, so that the
pause-to-sync logic always triggers when they are added.
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
8f840e703b bluez5: lc3: number of blocks is not the number of channels
The number of channels is determined by Audio_Channel_Allocation.
One frame block contains all channels. (BAP v1.0.1 Sec. 4.2)

Fix the handling of frame blocks and counting of numbers of channels. We
support and configure only one frame block per packet.

Consider omitted Audio_Channel_Allocation to indicate MONO stream (see
BAP v1.0.1 Sec 4.3.2).
2023-04-10 07:00:44 +00:00
Pauli Virtanen
e4cd99f76f bluez5: add some debug for media-sink 2023-04-10 07:00:44 +00:00
Pauli Virtanen
772ff3365b bluez5: backend-native: add two missing OK HFP replies
We should reply OK to both AT+BIEV and AT+IPHONEACCEV.
2023-04-08 11:05:06 +00:00
Sourav Das
8cf9986774 spa:bluez5: fix compilation
on lower bluez version, BT_ISO_QOS macro is not available
    So, need to check it also fixes the compilation.
2023-04-06 09:19:47 +00:00
Pauli Virtanen
6db234ad0c bluez5: media-sink: use iso-io for BAP
Use the ISO IO helpers to get synchronized BAP output, and rate match to
the ISO schedule.

The rate matching is necessary, since the driver may be ticking at a
corrected rate, different from the ISO interval rate.
2023-04-03 16:35:22 +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
0ed124f0fb bluez5: add rate matching for BAP to media-sink
Add basics for rate matching.
2023-04-03 16:35:22 +00:00
Pauli Virtanen
41c155bb4c bluez5: split rate control out of decode-buffer 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
Wim Taymans
3698593481 spa: reuse code to clear the timers
We have set_timeout and enable_flush_timer functions to disable the
timers so use those.
2023-03-24 17:55:15 +01:00
Wim Taymans
157a97cc98 bluez5: do rate matching before next timeout
Because else we might not have a rate and divide by 0.
2023-03-24 16:13:51 +01:00
Wim Taymans
7b6680ba57 plugins: simplify target_ handling
Drivers should only read the target_ values in the timeout, update the
timeout with the new duration and then update the position.

For the position we simply need to add the previous duration to the
position and then set the new duration + rate.

Otherwise, everything else should read the duration/rate and not use
the target_ values.
2023-03-24 11:36:15 +01:00
Wim Taymans
6e8625cf96 node: update the duration/rate from the target
Before scheduling the graph from the driver, update the duration and
rate with the new targets.
2023-03-23 18:39:27 +01:00
Pauli Virtanen
282c7975fa bluez5: backend-native: fix getsockopt/fcntl error code handling 2023-03-19 21:33:28 +02:00
Pauli Virtanen
aa06c547d9 bluez5: align audio output of all BAP sinks
Make BAP nodes align the first sample of their packets at multiples of
the ISO interval, counted in the shared graph sample position.  This
skips a few samples (< 10ms) at the start of playback to ensure the
alignment.

Since the sinks align their flush timing to the graph time, this also
results to them sending packets corresponding to the same graph time at
the same real time instants.

Due to packet queues in kernel/controller, the playback may still be off
by multiples of packets. Kernel changes are needed to address that part.

This works towards making BAP left and right channels to be
synchronized in TWS headsets, where the two earpieces currently appear
as different devices.
2023-03-19 19:18:10 +02:00
Pauli Virtanen
2bc48e1c18 bluez5: backend-native: make SCO acquire asynchronous
Don't block main loop in connect() for SCO sockets, as we can now do it
asynchronously.  Can be useful if connecting runs into problems.
2023-03-18 16:10:18 +02:00
Pauli Virtanen
73d7252f24 bluez5: use nonblocking i/o for SCO
Although SCO sockets usually don't block, they could, so do nonblocking
reads/writes.
2023-03-18 16:08:36 +02: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