* [PATCH] shared/asha: prime volume before starting audio
@ 2026-10-13 3:46 Kyle Pepper
2026-10-13 5:03 ` bluez.test.bot
0 siblings, 1 reply; 2+ messages in thread
From: Kyle Pepper @ 2026-10-13 3:46 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz
Some tested renderers remain silent unless the Volume characteristic is
written before START. Prime it with the selected volume and keep the
write best effort.
Test volume-before-START ordering and best-effort failure handling.
Assisted-by: OpenCode:gpt-6.1-sol
---
Submission review notes (not part of the commit message):
Local validation is for base 7428ca2df9356363079db0f48412c20cbdb9471f.
Compatibility with newer upstream tips has not been verified locally.
N8 startup evidence is from the combined downstream stack, not a
volume-only hardware ablation. Native ordering/failure unit tests are
included; other renderer coverage and human contribution review remain.
.gitignore | 1 +
Makefile.am | 6 +++
src/shared/asha.c | 4 ++
unit/test-asha-start.c | 99 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 110 insertions(+)
create mode 100644 unit/test-asha-start.c
diff --git a/.gitignore b/.gitignore
index 06b24735df..adff1ea84a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -112,6 +112,7 @@ unit/test-lib
unit/test-mgmt
unit/test-uhid
unit/test-hfp
+unit/test-asha-start
unit/test-crypto
unit/test-ecc
unit/test-hog
diff --git a/Makefile.am b/Makefile.am
index f742458d11..a56d66873b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -706,6 +706,12 @@ unit_test_avrcp_LDADD = lib/libbluetooth-internal.la \
unit_tests += unit/test-hfp
+unit_tests += unit/test-asha-start
+
+unit_test_asha_start_SOURCES = unit/test-asha-start.c
+unit_test_asha_start_LDADD = src/libshared-glib.la \
+ lib/libbluetooth-internal.la $(GLIB_LIBS)
+
unit_test_hfp_SOURCES = unit/test-hfp.c
unit_test_hfp_LDADD = src/libshared-glib.la $(GLIB_LIBS)
diff --git a/src/shared/asha.c b/src/shared/asha.c
index 79bb29bf9a..b5e8d67567 100644
--- a/src/shared/asha.c
+++ b/src/shared/asha.c
@@ -262,6 +262,10 @@ unsigned int bt_asha_start(struct bt_asha *asha, bt_asha_cb_t cb,
return 0;
}
+ /* Some renderers require a Volume write before START. */
+ if (!bt_asha_set_volume(asha, asha->volume))
+ DBG("ASHA volume priming failed, continuing with START");
+
ret = asha_send_acp(asha, acp_start_cmd, sizeof(acp_start_cmd), cb,
user_data);
if (ret < 0)
diff --git a/unit/test-asha-start.c b/unit/test-asha-start.c
new file mode 100644
index 0000000000..49df54c1f3
--- /dev/null
+++ b/unit/test-asha-start.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+#include <assert.h>
+
+/* Source-level mocks remain effective with link-time optimization. */
+#define bt_gatt_client_write_without_response test_write_command
+#define bt_gatt_client_write_value test_write_request
+#include "src/shared/asha.c"
+#undef bt_gatt_client_write_without_response
+#undef bt_gatt_client_write_value
+#include "src/shared/tester.h"
+
+static unsigned int commands, requests;
+static bool volume_ok, start_ok;
+static int8_t selected_volume;
+
+void btd_error(uint16_t index, const char *format, ...)
+{
+}
+
+void btd_debug(uint16_t index, const char *format, ...)
+{
+}
+
+unsigned int test_write_command(struct bt_gatt_client *client, uint16_t handle,
+ bool signed_write,
+ const uint8_t *value, uint16_t length)
+{
+ assert(client && handle == 0x82 && !signed_write);
+ assert(length == 1 && (int8_t) value[0] == selected_volume);
+ assert(requests == 0);
+ commands++;
+ return volume_ok;
+}
+
+unsigned int test_write_request(struct bt_gatt_client *client, uint16_t handle,
+ const uint8_t *value, uint16_t length,
+ bt_gatt_client_callback_t callback, void *data,
+ bt_gatt_client_destroy_func_t destroy)
+{
+ assert(client && handle == 0x79);
+ assert(commands == 1 && requests == 0);
+ assert(length == 5 && value[0] == 0x01 && value[1] == 0x01);
+ assert((int8_t) value[3] == selected_volume);
+ assert(callback && data && !destroy);
+ requests++;
+ return start_ok;
+}
+
+static void test_start(const void *user_data)
+{
+ const int8_t volumes[] = { -128, -127, -64, 0 };
+ unsigned int i, fail;
+
+ for (i = 0; i < ARRAY_SIZE(volumes); i++) {
+ for (fail = 0; fail < 2; fail++) {
+ struct bt_asha asha = {
+ .client = (void *) 1, .acp_handle = 0x79,
+ .volume_handle = 0x82, .volume = volumes[i],
+ };
+
+ selected_volume = volumes[i];
+ commands = requests = 0;
+ volume_ok = !fail;
+ start_ok = true;
+ assert(bt_asha_start(&asha, NULL, NULL) == 0);
+ assert(commands == 1 && requests == 1);
+ assert(asha.state == ASHA_STARTING);
+ assert(asha.volume == selected_volume);
+
+ /* A repeated start must not write the volume again. */
+ bt_asha_start(&asha, NULL, NULL);
+ assert(commands == 1 && requests == 1);
+ }
+ }
+
+ {
+ struct bt_asha asha = {
+ .client = (void *) 1, .acp_handle = 0x79,
+ .volume_handle = 0x82, .volume = -64,
+ };
+
+ commands = requests = 0;
+ selected_volume = asha.volume;
+ volume_ok = true;
+ start_ok = false;
+ assert(bt_asha_start(&asha, NULL, NULL) == (unsigned int) -1);
+ assert(asha.state == ASHA_STOPPED);
+ assert(commands == 1 && requests == 1);
+ }
+
+ tester_test_passed();
+}
+
+int main(int argc, char *argv[])
+{
+ tester_init(&argc, &argv);
+ tester_add("ASHA/start/volume", NULL, NULL, test_start, NULL);
+ return tester_run();
+}
base-commit: 7428ca2df9356363079db0f48412c20cbdb9471f
^ permalink raw reply related [flat|nested] 2+ messages in thread* RE: shared/asha: prime volume before starting audio
2026-10-13 3:46 [PATCH] shared/asha: prime volume before starting audio Kyle Pepper
@ 2026-10-13 5:03 ` bluez.test.bot
0 siblings, 0 replies; 2+ messages in thread
From: bluez.test.bot @ 2026-10-13 5:03 UTC (permalink / raw)
To: linux-bluetooth, cochcoder
[-- Attachment #1: Type: text/plain, Size: 3430 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/series/1184354/
---Test result---
Test Summary:
CheckPatch PASS 0.47 seconds
GitLint PASS 0.27 seconds
BuildEll PASS 19.44 seconds
BluezMake PASS 291.44 seconds
MakeCheck PASS 14.18 seconds
MakeDistcheck PASS 145.25 seconds
CheckValgrind PASS 231.58 seconds
CheckSmatch PASS 290.49 seconds
bluezmakeextell PASS 93.58 seconds
TestFunctional FAIL 1198.04 seconds
IncrementalBuild PASS 293.18 seconds
ScanBuild PASS 1131.33 seconds
Details
##############################
Test: TestFunctional - FAIL
Desc: Run test-functional
Output:
FAIL functional.test_bluetoothctl::test_bluetoothctl_pair_bredr[hosts15-vm2]: pytest_bluezenv.rpc.RemoteError: <pexpect.popen_spawn.PopenSpawn object at 0x7f9674e9e510>
searcher: searcher_re:
0: re.compile(b'Changing pairable on succeeded')
<pexpect.popen_spawn.PopenSpawn object at 0x7f9674e9e510>
searcher: searcher_re:
0: re.compile(b'Changing pairable on succeeded')
Remote traceback:
Traceback (most recent call last):
File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/rpc.py", line 102, in server_stream
result = method(*msg["a"], **msg["kw"])
File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/env.py", line 256, in call_plugin
return getattr(self.plugins[name], method)(*a, **kw)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/host_plugins.py", line 502, in expect
ret = self.ctl.expect(*a, **kw)
File "/usr/lib/python3/dist-packages/pexpect/spawnbase.py", line 354, in expect
return self.expect_list(compiled_pattern_list,
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
timeout, searchwindowsize, async_)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/pexpect/spawnbase.py", line 383, in expect_list
return exp.expect_loop(timeout)
~~~~~~~~~~~~~~~^^^^^^^^^
File "/usr/lib/python3/dist-packages/pexpect/expect.py", line 181, in expect_loop
return self.timeout(e)
~~~~~~~~~~~~^^^
File "/usr/lib/python3/dist-packages/pexpect/expect.py", line 144, in timeout
raise exc
pexpect.exceptions.TIMEOUT: <pexpect.popen_spawn.PopenSpawn object at 0x7f9674e9e510>
searcher: searcher_re:
0: re.compile(b'Changing pairable on succeeded')
<pexpect.popen_spawn.PopenSpawn object at 0x7f9674e9e510>
searcher: searcher_re:
0: re.compile(b'Changing pairable on succeeded')
FAIL functional.test_hog::test_hog[sci-hosts18-vm2]: pytest_bluezenv.rpc.RemoteTimeoutError: Connection recv timed out
https://github.com/bluez/bluez/pull/2665
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-13 5:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 3:46 [PATCH] shared/asha: prime volume before starting audio Kyle Pepper
2026-10-13 5:03 ` bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox