Commit graph

14161 commits

Author SHA1 Message Date
George Kiagiadakis
5ccd1c5619 bluez5: backend-native: update hfp_hf_in_progress at the end of the CLCC update
When we skip the CIEV event in order to update the call list with CLCC,
we may receive multiple +CLCC events or even none, if the calls are
disconnected. To avoid any mistakes, update the hfp_hf_in_progress flag
after the CLCC update is entirely done.
2025-08-01 15:39:06 +00:00
George Kiagiadakis
e4b0f68e0b bluez5: telephony: implement asynchronous D-Bus calls
This removes the need to call poll() on the rfcomm socket in order
to wait for replies from the AG.

Use a queue to buffer all the commands that are to be sent to the AG
and match them to replies when they are received. Optionally associate
each command with a DBusMessage that is assumed to be a method call
from the telephony interface, which is then replied to when the rfcomm
command reply is received. Also associate each command with a state,
so that it is always deterministic what gets executed after the reply
is received.

On the telephony module, pass on the DBusMessage on the callbacks and
add a method to allow the receiver to send a reply. Only send FAILED
directly when the callback is not handled. Also, remove the return value
from the Dial() command (it was not advertised on the introspection
anyway) to make things easier.
2025-08-01 15:39:06 +00:00
Wim Taymans
0b647a9009 pod: fuse can_collect, SKIP and COLLECT
Make one COLLECT function that always reads all the varargs (SKIP)
and then tries to collect the pod+body with type checks
(can_collect + COLLECT). This makes things nicer because we can do
everything in one go and we only do one type check.
2025-08-01 16:23:37 +02:00
Wim Taymans
88d7d5706a conf: fix priority of the overrides
A config file with a higher level should override one with a lower
level.

Fixes #4816
2025-08-01 10:49:26 +02:00
Wim Taymans
bef0706238 Revert "pod: remove checks from spa_pod_body_get_*()"
This partially reverts commit f7ae61cb1e.

We do want to do the checks in spa_pod_body_get_*() for extra safety.
The reason they were removed is because then we do the checks twice in
the parser. It should however be possible to fuse the can_collect and
COLLECT and SKIP calls together in the future.
2025-08-01 10:46:45 +02:00
Wim Taymans
00dbe9cb2a pod: add missing parser varargs formats 2025-07-31 14:13:41 +02:00
Pauli Virtanen
121608f040 bluez5: allow framing for BAP
There's actually no reason to disable framed qos presets.
2025-07-31 10:58:00 +00:00
Wim Taymans
8495bffee5 modules: use safer pod parsing for control sequence 2025-07-31 11:50:11 +02:00
Wim Taymans
28510f3117 bluez: safely parse the control data from buffers 2025-07-31 11:24:29 +02:00
Wim Taymans
f4ab704948 spa: use safe IO_Control parsing
The IO_Control areas are in shaed memory and need to use the parser to
safely extract the info.
2025-07-31 11:23:30 +02:00
Wim Taymans
ede1924ded pod: add more functions for easy pod+body parsing
Add functions to parse an object and struct from pod+body.
2025-07-31 11:21:28 +02:00
Wim Taymans
45ed70d480 control: mark the input as const, we don't change it 2025-07-31 10:54:09 +02:00
Wim Taymans
4715e36a5c spa: don't free the mix_list ports
We can't move the mix_list ports to the free_list like that because the
elements in the list use a different list to link together. Also, we
don't need to free those ports at all because they will be freed when we
move the port_list to the free_list.
2025-07-31 10:20:59 +02:00
Wim Taymans
5743849b50 tools: use safer spa_pod_parser for control events 2025-07-30 19:08:36 +02:00
Wim Taymans
a3da53f66e alsa: fix seq compilation 2025-07-30 18:54:16 +02:00
Wim Taymans
7f7b4be82d alsa: use the safer pod parser for control events 2025-07-30 18:43:34 +02:00
Wim Taymans
abcf70538d pod: add barrier around memcpy
We need to be sure that the compiler does not perform invented loads
after we checked the pod size. Otherwise we could have found that the
size was ok, only to be overwritten by an invalid size.

One way of avoiding this is to surround the memcpy with a barrier.

See #4822
2025-07-30 18:10:09 +02:00
Wim Taymans
6d07eaea1f seq: rework port handling
Dynamically allocate ports as we need them.
Use port lists to iterate active ports.
2025-07-30 17:32:02 +02:00
Wim Taymans
8f45cfcbc9 audiomixer: rework the port logic
Use port lists for faster and safer updates of the mixer ports.
2025-07-30 16:49:45 +02:00
Wim Taymans
77494086c1 pod: add support for vararg building and parsing of pod+body 2025-07-30 15:14:49 +02:00
Wim Taymans
f7ae61cb1e pod: remove checks from spa_pod_body_get_*()
The pattern is _is_foo() and then _get_foo(). This allows us to reuse
some of the get code in the parser without doing checks twice.
2025-07-30 12:56:39 +02:00
Wim Taymans
2c11f65701 pod: avoid child size check
This will give us 0 children later and is not a problem for this
function.
2025-07-30 11:02:00 +02:00
Pauli Virtanen
847982eb0e resample: keep fractional part of in_rate when interpolating
When interpolating with rate correction != 1.0, don't floor the
resulting input rate to the nearest smallest integer.

This allows rate corrections < 1/in_rate to have some effect, and
reduces jumps in the response. One of the jumps is inconveniently
between rate=1.0 and rate=1.0+eps and will cause rate corrections to
oscillate if target rate varies close to 1.0.
2025-07-30 07:59:52 +00:00
Pauli Virtanen
244d5a1cc1 resample: use fixed point for resample phase and input rate
If phase is float, calculations in impl_native_in_len/out_len can
produce wrong results due to rounding error.

It's probably better to not be in the business of predicting
floating-point rounding, so replace this by fixed-point arithmetic.

Also make sure `offset+1` cannot overflow data->filter array in
do_resample_inter* due to float multiplication possibly rounding up.
2025-07-30 07:59:52 +00:00
Pauli Virtanen
3cade43cf3 test-resample: add test for floating point rounding producing bad in_len
If phase is float, calculations in impl_native_in_len/out_len don't
necessarily match with do_resample, because e.g.

    float phase0 = 7999.99;
    float phase = phase0;
    int frac = 8000, out_rate = 8000, n = 64, count = 0;
    for (int j = 0; j < n; ++j) {
        phase += frac;
        if (phase >= out_rate) {
                phase -= out_rate;
                count++;
        }
    }
    printf("count = %d\n", count);      /* count = 64 */

    count = (int)(phase0 + n*frac) / out_rate;
    printf("count = %d\n", count);      /* count = 65 */

don't give the same result.

Also add test where floating point multiplication rounding up to nearest
in

    float ph = phase * pm;
    uint32_t offset = (uint32_t)floorf(ph);

computation results to offset+1 > data->n_phases, accessing filter array
beyond bounds.  (The accessed value is still inside allocated memory
block, but contains unrelated values; the test passes silently.)
2025-07-30 07:59:52 +00:00
Pauli Virtanen
84e8d59782 resample: fix off-by-one in out_len calculation
Fix off-by-one and add test.
2025-07-30 07:59:52 +00:00
Carlos Rafael Giani
91ebfac75b module-rtp: Clear after reading in direct timestamp mode 2025-07-29 17:24:09 +02:00
Wim Taymans
0cab2fcb75 pod: don't unpack array values in get_values
This is only for choice, everything else stays the pod.
2025-07-29 17:01:47 +02:00
Wim Taymans
3785896533 mixer: rework the control mixers to use the parser
Using the parser for the spa_pod_sequence in the data buffers is
required in order to safely read the pods while there could be
concurrent writes.

See #4822
2025-07-29 15:33:43 +02:00
Wim Taymans
e317edcfb9 pod: rework the parser
Make a new body.h file with some functions to deal with pod and their
body. Make the iter.h functions use mostly this.

Rework the parser so that it only uses body.h functions. With the separation
of pod+body, we can read and verify the pod once and then use the
verified copy to handle the rest of the body safely.

We do this because iter.h only works in pods in memory that doesn't change
because it is vulnerable to modifications of the data after verifying it.

The new parser is not vulnerable to this and will not cause invalid
memory access when used on shared memory. There is however no need for
atomic operations to read the headers, whever is read is either valid
and useable of invalid and rejected.

See #4822
2025-07-29 15:15:02 +02:00
Wim Taymans
e2c291d18e pw-top: reduce flicker when updating
Use wearase() instead of wclear() before redrawing

Fixes #4818
2025-07-29 14:57:04 +02:00
Wim Taymans
56e2d52b65 control: fix fastpath compilation 2025-07-27 17:17:55 +02:00
Wim Taymans
927ab0f4b8 control: improve port handling in control mixer
Use lists to manage the free, allocated and acitve mixer ports. We can
then avoid some checks and make things more threadsafe.
2025-07-27 16:51:52 +02:00
Wim Taymans
1957d3fb00 pulse: avoid a compiler warning 2025-07-25 17:37:56 +02:00
Wim Taymans
87333537d2 pod: also check 0 terminted strings in copy_string
Use get_string() to get a pointer to the string in the pod so that we
also check if it has a 0 terminator.

Fix the test case now that is_string returns true even for non
zero-terminated strings.
2025-07-25 17:33:46 +02:00
Wim Taymans
b991e9acc9 pod: check string zero byte only when parsing
The _is_type() macros should simply check the type in the header and if
the size is large enough to look into the type specifics. Further
validation of the values should be done when the value is retrieved.

Following this logic, the String zero byte check should be done in the
get_string() function.
2025-07-25 17:33:46 +02:00
Demi Marie Obenour
9e789c65c2 src: check that POD arrays have the correct size for their type
The parser does not check that POD arrays have the correct size for
their type, so the calling code must do that.

This also enumerates some of the code that cannot handle the size of the
values of an array not being the exact expected size for its type.
There is a lot of it.
2025-07-24 16:27:42 -04:00
Wim Taymans
0f6b365138 pod: don't call deref in reserve bytes
We already know that we could succesfully allocate enough space for the
bytes because we checked that before so simply move to the body of the
new bytes pod. We don't need to do the extensive checks we do in deref.
2025-07-24 18:35:21 +02:00
Wim Taymans
0c33101a42 pod: remove unused function 2025-07-24 18:22:14 +02:00
Wim Taymans
a85c24e9ca builder: support building pod + data + suffix
Add a function that can build a pod from a pod definition, a body data
and a suffix.

We can use this to build strings and bytes and arrays like the other
primitives, which makes it possible to add them to choices or arrays.

Fixes #4588
2025-07-24 16:23:54 +02:00
Wim Taymans
42b779974c module-rtp: don't leak opus codec and ptp_sender
Add a deinit() function and use it to free the opus codec we created in
init().

Also free the ptp_sender when it was created.
2025-07-24 13:16:15 +02:00
Demi Marie Obenour
a09bf57944 meson: Always use -fno-strict-aliasing and -fno-strict-overflow
SPA does not respect the C strict aliasing rules at all, so any code
that uses it must be built with -fno-strict-aliasing.  Furthermore,
there is code in SPA that compares pointers that point to different
objects, so -fno-strict-overflow is also needed.
2025-07-24 07:30:28 +00:00
Carlos Rafael Giani
2bcc8589fa module-rtp: Fix and improve direct timestamp mode and documentation
Direct timestamp mode was incorrectly using over/underrun detection logic
and fill level tracking logic that is actually meant for the other mode
(referred to from now on as "constant latency mode"). Over/underruns are
tracked implicitly in the direct timestamp mode, and the absolute fill
level is not relevant in that mode, since the latency is not needed to
be constant then.

Also improve log lines and the RTP module documentation to define these
buffer modes clearly and explain their differences and use cases.

Opus and MIDI code get TODOs added, since their direct timestamp mode
implementations still may be incorrect. Fixing those will be done in
a separate commit.
2025-07-24 07:28:53 +00:00
Martin Geier
f8b0d0a43c rtp: include stream delay to a read position
When a stream has some delay, a time t1 + delay has to be read in time
t1 to play it when expected.
Decrease target_buffer by delay to start playback sooner, so sound
is played at correct time when delay is applied.

Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
2025-07-24 07:28:53 +00:00
Carlos Rafael Giani
1ed8f771bd doc: spa: Minor improvements to driver architecture documentation 2025-07-24 07:28:53 +00:00
Barnabás Pőcze
c7838cbbcb spa: node: io: fix typo in documentation
`SPA_IO_RATE_MATCH_ACTIVE` -> `SPA_IO_RATE_MATCH_FLAG_ACTIVE`
2025-07-23 21:26:29 +02:00
Pauli Virtanen
5fa137cc0d meson.build: make spa-json-dump available for subprojects
Add override that provides host binary for subprojects to use.

Also fix cross-compilation to use the host binary.
2025-07-23 12:19:21 +00:00
Wim Taymans
0b0912cc5b resample: optimize phase scaling
Precalculate the constant factor to avoid a division for each sample.
2025-07-23 14:11:11 +02:00
Wim Taymans
b52c490709 resample: fix compilation
Also fix a compiler warning in clang
2025-07-23 12:52:27 +02:00
Wim Taymans
c54d3764b2 stream: update the docs a little
Give some more information about the delay field and how it can be
negative.
2025-07-23 12:46:45 +02:00