Merge ~dirksu/bluez:plucky into ~bluetooth/bluez:plucky

Proposed by Dirk Su
Status: Merged
Merged at revision: 23e55189502af7a32fb342db61f22270561c268f
Proposed branch: ~dirksu/bluez:plucky
Merge into: ~bluetooth/bluez:plucky
Diff against target: 339 lines (+305/-0)
5 files modified
debian/changelog (+9/-0)
debian/patches/a2dp-Remove-Endpoints-cache-entries-on-device-remova.patch (+91/-0)
debian/patches/audio-upgrade-versions-to-latest-possible-to-qualify.patch (+92/-0)
debian/patches/profiles-avdtp-Fix-reply-for-bad-media-transport-for.patch (+110/-0)
debian/patches/series (+3/-0)
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Review via email: mp+492285@code.launchpad.net

Commit message

Add upstream patches to improve audio profiles compatibility

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 62a4537..22ddb20 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,12 @@
6+bluez (5.79-2ubuntu1.2) plucky; urgency=medium
7+
8+ * Improve audio profiles compatibility (LP: #2122382)
9+ d/patches: audio-upgrade-versions-to-latest-possible-to-qualify.patch
10+ d/patches: a2dp-Remove-Endpoints-cache-entries-on-device-remova.patch
11+ d/patches: profiles-avdtp-Fix-reply-for-bad-media-transport-for.patch
12+
13+ -- Dirk Su <dirk.su@canonical.com> Wed, 10 Sep 2025 11:08:45 +0800
14+
15 bluez (5.79-2ubuntu1.1) plucky; urgency=medium
16
17 * d/patches/reconnect-hsp-on-a2dp-reconnect.patch: Correct the patch to fix
18diff --git a/debian/patches/a2dp-Remove-Endpoints-cache-entries-on-device-remova.patch b/debian/patches/a2dp-Remove-Endpoints-cache-entries-on-device-remova.patch
19new file mode 100644
20index 0000000..ca376c1
21--- /dev/null
22+++ b/debian/patches/a2dp-Remove-Endpoints-cache-entries-on-device-remova.patch
23@@ -0,0 +1,91 @@
24+From ea3f4047e452b081e34d017cce316aba9d623301 Mon Sep 17 00:00:00 2001
25+From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Danis?= <frederic.danis@collabora.com>
26+Date: Mon, 17 Feb 2025 12:48:02 +0100
27+Subject: [PATCH] a2dp: Remove Endpoints cache entries on device removal
28+
29+When a device is removed, currently the endpoints and last used info
30+are kept in cache:
31+ [General]
32+ Name=Frederic's Phone
33+
34+ [Endpoints]
35+ 01=00:00:01:29f50235
36+ 02=00:02:01:80010484e200
37+ LastUsed=01:02
38+
39+This may prevent future connection, after a new pairing, to use the
40+best codec available.
41+
42+Bug-Ubuntu: https://bugs.launchpad.net/bugs/2122382
43+---
44+ profiles/audio/a2dp.c | 40 ++++++++++++++++++++++++++++++++++++++++
45+ 1 file changed, 40 insertions(+)
46+
47+diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
48+index 0eac151db..81dbbfae3 100644
49+--- a/profiles/audio/a2dp.c
50++++ b/profiles/audio/a2dp.c
51+@@ -880,6 +880,44 @@ static void store_remote_seps(struct a2dp_channel *chan)
52+ g_key_file_free(key_file);
53+ }
54+
55++static void remove_endpoints_cache(struct btd_service *service)
56++{
57++ struct btd_device *device = btd_service_get_device(service);
58++ char filename[PATH_MAX];
59++ char dst_addr[18];
60++ GKeyFile *key_file;
61++ GError *gerr = NULL;
62++ char *data;
63++ gsize length = 0;
64++
65++ ba2str(device_get_address(device), dst_addr);
66++
67++ create_filename(filename, PATH_MAX, "/%s/cache/%s",
68++ btd_adapter_get_storage_dir(device_get_adapter(device)),
69++ dst_addr);
70++
71++ key_file = g_key_file_new();
72++ if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
73++ g_error_free(gerr);
74++ g_key_file_free(key_file);
75++ return;
76++ }
77++ g_key_file_remove_group(key_file, "Endpoints", NULL);
78++
79++ data = g_key_file_to_data(key_file, &length, NULL);
80++ if (length > 0) {
81++ create_file(filename, 0600);
82++ if (!g_file_set_contents(filename, data, length, &gerr)) {
83++ error("Unable set contents for %s: (%s)", filename,
84++ gerr->message);
85++ g_error_free(gerr);
86++ }
87++ }
88++
89++ g_free(data);
90++ g_key_file_free(key_file);
91++}
92++
93+ static void invalidate_remote_cache(struct a2dp_setup *setup,
94+ struct avdtp_error *err)
95+ {
96+@@ -3352,6 +3390,7 @@ static int a2dp_source_probe(struct btd_service *service)
97+ static void a2dp_source_remove(struct btd_service *service)
98+ {
99+ source_unregister(service);
100++ remove_endpoints_cache(service);
101+ }
102+
103+ static int a2dp_sink_probe(struct btd_service *service)
104+@@ -3366,6 +3405,7 @@ static int a2dp_sink_probe(struct btd_service *service)
105+ static void a2dp_sink_remove(struct btd_service *service)
106+ {
107+ sink_unregister(service);
108++ remove_endpoints_cache(service);
109+ }
110+
111+ static int a2dp_source_connect(struct btd_service *service)
112+--
113+2.43.0
114+
115diff --git a/debian/patches/audio-upgrade-versions-to-latest-possible-to-qualify.patch b/debian/patches/audio-upgrade-versions-to-latest-possible-to-qualify.patch
116new file mode 100644
117index 0000000..853f265
118--- /dev/null
119+++ b/debian/patches/audio-upgrade-versions-to-latest-possible-to-qualify.patch
120@@ -0,0 +1,92 @@
121+From f0e9ecb9f4fe3a7bdb011dc155cf6ad657a289ee Mon Sep 17 00:00:00 2001
122+From: Raghavender Reddy Bujala <quic_rbujala@quicinc.com>
123+Date: Wed, 12 Feb 2025 14:35:53 +0530
124+Subject: [PATCH] audio: upgrade versions to latest possible to qualify
125+
126+Most of the existing profile versions are withdrawn
127+to make PTS successfull, need to upgrade the version
128+for audio profiles and there are no mandatory feature
129+changes between these versions are seen.
130+
131+Version changes
132+A2DP from 1.3 to 1.4
133+HFP from 1.7 to 1.8
134+AVRCP TG from 1.5 to 1.6
135+AVCTP from 1.3 to 1.4
136+
137+Bug-Ubuntu: https://bugs.launchpad.net/bugs/2122382
138+---
139+ profiles/audio/a2dp.c | 2 +-
140+ profiles/audio/avrcp.c | 6 +++---
141+ src/profile.c | 4 ++--
142+ 3 files changed, 6 insertions(+), 6 deletions(-)
143+
144+diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
145+index 438ef29a8..0eac151db 100644
146+--- a/profiles/audio/a2dp.c
147++++ b/profiles/audio/a2dp.c
148+@@ -1595,7 +1595,7 @@ static sdp_record_t *a2dp_record(uint8_t type)
149+ sdp_record_t *record;
150+ sdp_data_t *psm, *version, *features;
151+ uint16_t lp = AVDTP_UUID;
152+- uint16_t a2dp_ver = 0x0103, avdtp_ver = 0x0103, feat = 0x000f;
153++ uint16_t a2dp_ver = 0x0104, avdtp_ver = 0x0103, feat = 0x000f;
154+
155+ record = sdp_record_alloc();
156+ if (!record)
157+diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
158+index 6378b7a6e..7e9a383b0 100644
159+--- a/profiles/audio/avrcp.c
160++++ b/profiles/audio/avrcp.c
161+@@ -138,7 +138,7 @@
162+
163+ #define AVRCP_BROWSING_TIMEOUT 1
164+ #define AVRCP_CT_VERSION 0x0106
165+-#define AVRCP_TG_VERSION 0x0105
166++#define AVRCP_TG_VERSION 0x0106
167+
168+ #define AVRCP_SCOPE_MEDIA_PLAYER_LIST 0x00
169+ #define AVRCP_SCOPE_MEDIA_PLAYER_VFS 0x01
170+@@ -414,7 +414,7 @@ static sdp_record_t *avrcp_ct_record(bool browsing)
171+ sdp_record_t *record;
172+ sdp_data_t *psm[2], *version, *features;
173+ uint16_t lp = AVCTP_CONTROL_PSM;
174+- uint16_t avctp_ver = 0x0103;
175++ uint16_t avctp_ver = 0x0104;
176+ uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
177+ AVRCP_FEATURE_CATEGORY_2 |
178+ AVRCP_FEATURE_CATEGORY_3 |
179+@@ -493,7 +493,7 @@ static sdp_record_t *avrcp_tg_record(bool browsing)
180+ sdp_record_t *record;
181+ sdp_data_t *psm_control, *version, *features;
182+ uint16_t lp = AVCTP_CONTROL_PSM;
183+- uint16_t avctp_ver = 0x0103;
184++ uint16_t avctp_ver = 0x0104;
185+ uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
186+ AVRCP_FEATURE_CATEGORY_2 |
187+ AVRCP_FEATURE_CATEGORY_3 |
188+diff --git a/src/profile.c b/src/profile.c
189+index af32dbd9f..9fdfb7dff 100644
190+--- a/src/profile.c
191++++ b/src/profile.c
192+@@ -2075,7 +2075,7 @@ static struct default_settings {
193+ .authorize = true,
194+ .auto_connect = true,
195+ .get_record = get_hfp_hf_record,
196+- .version = 0x0107,
197++ .version = 0x0108,
198+ }, {
199+ .uuid = HSP_HS_UUID,
200+ .name = "Headset unit",
201+@@ -2095,7 +2095,7 @@ static struct default_settings {
202+ .authorize = true,
203+ .auto_connect = true,
204+ .get_record = get_hfp_ag_record,
205+- .version = 0x0107,
206++ .version = 0x0108,
207+ /* HFP 1.7.2: By default features bitfield is 0b001001 */
208+ .features = 0x09,
209+ }, {
210+--
211+2.43.0
212+
213diff --git a/debian/patches/profiles-avdtp-Fix-reply-for-bad-media-transport-for.patch b/debian/patches/profiles-avdtp-Fix-reply-for-bad-media-transport-for.patch
214new file mode 100644
215index 0000000..6a5f48f
216--- /dev/null
217+++ b/debian/patches/profiles-avdtp-Fix-reply-for-bad-media-transport-for.patch
218@@ -0,0 +1,110 @@
219+From f2120e3ded0656c8eda3d8058ee35654aba3fd09 Mon Sep 17 00:00:00 2001
220+From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Danis?= <frederic.danis@collabora.com>
221+Date: Wed, 26 Mar 2025 10:07:11 +0100
222+Subject: [PATCH] profiles/avdtp: Fix reply for bad media transport format
223+
224+Currently the avdtp_setconf_cmd() fails to check the capability length
225+of the Media Transport Service Category, which should be 0, because
226+caps_to_list() doesn't add it to the list of services as it should
227+be bigger than packet boundary.
228+
229+This commit adds an &err parameter to caps_to_list() and set the error
230+to AVDTP_BAD_MEDIA_TRANSPORT_FORMAT if Media Transport capability as
231+invalid length.
232+
233+This is required for passing AVDTP/SNK/ACP/TRA/BTR/BI-01-C PTS test
234+case:
235+To verify that the IUT (ACP) is able to issue a set configuration
236+reject response to the INT if the format of the media transport is
237+incorrect.
238+
239+Bug-Ubuntu: https://bugs.launchpad.net/bugs/2122382
240+---
241+ profiles/audio/avdtp.c | 35 ++++++++++++++++++++---------------
242+ 1 file changed, 20 insertions(+), 15 deletions(-)
243+
244+diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
245+index 80fbe847e..dd8458f20 100644
246+--- a/profiles/audio/avdtp.c
247++++ b/profiles/audio/avdtp.c
248+@@ -1312,7 +1312,8 @@ struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
249+
250+ static GSList *caps_to_list(uint8_t *data, size_t size,
251+ struct avdtp_service_capability **codec,
252+- gboolean *delay_reporting)
253++ gboolean *delay_reporting,
254++ uint8_t *err)
255+ {
256+ struct avdtp_service_capability *cap;
257+ GSList *caps;
258+@@ -1328,6 +1329,17 @@ static GSList *caps_to_list(uint8_t *data, size_t size,
259+
260+ cap = (struct avdtp_service_capability *)data;
261+
262++ /* Verify that the Media Transport capability's length = 0.
263++ * Reject otherwise
264++ */
265++ if (cap->category == AVDTP_MEDIA_TRANSPORT &&
266++ cap->length != 0) {
267++ error("Invalid media transport in getcap resp");
268++ if (err)
269++ *err = AVDTP_BAD_MEDIA_TRANSPORT_FORMAT;
270++ break;
271++ }
272++
273+ if (sizeof(*cap) + cap->length > size) {
274+ error("Invalid capability data in getcap resp");
275+ break;
276+@@ -1494,9 +1506,8 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
277+ struct conf_rej rej;
278+ struct avdtp_local_sep *sep;
279+ struct avdtp_stream *stream;
280+- uint8_t err, category = 0x00;
281++ uint8_t err = 0, category = 0x00;
282+ struct btd_service *service;
283+- GSList *l;
284+
285+ if (size < sizeof(struct setconf_req)) {
286+ error("Too short getcap request");
287+@@ -1552,7 +1563,10 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
288+ stream->caps = caps_to_list(req->caps,
289+ size - sizeof(struct setconf_req),
290+ &stream->codec,
291+- &stream->delay_reporting);
292++ &stream->delay_reporting,
293++ &err);
294++ if (err)
295++ goto failed_stream;
296+
297+ if (!stream->caps || !stream->codec) {
298+ err = AVDTP_UNSUPPORTED_CONFIGURATION;
299+@@ -1560,16 +1574,6 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
300+ goto failed_stream;
301+ }
302+
303+- /* Verify that the Media Transport capability's length = 0. Reject otherwise */
304+- for (l = stream->caps; l != NULL; l = g_slist_next(l)) {
305+- struct avdtp_service_capability *cap = l->data;
306+-
307+- if (cap->category == AVDTP_MEDIA_TRANSPORT && cap->length != 0) {
308+- err = AVDTP_BAD_MEDIA_TRANSPORT_FORMAT;
309+- goto failed_stream;
310+- }
311+- }
312+-
313+ if (stream->delay_reporting && session->version < 0x0103)
314+ session->version = 0x0103;
315+
316+@@ -2827,7 +2831,8 @@ static gboolean avdtp_get_capabilities_resp(struct avdtp *session,
317+ }
318+
319+ sep->caps = caps_to_list(resp->caps, size - sizeof(struct getcap_resp),
320+- &sep->codec, &sep->delay_reporting);
321++ &sep->codec, &sep->delay_reporting,
322++ NULL);
323+
324+ return TRUE;
325+ }
326+--
327+2.43.0
328+
329diff --git a/debian/patches/series b/debian/patches/series
330index b1a72e2..484b084 100644
331--- a/debian/patches/series
332+++ b/debian/patches/series
333@@ -15,3 +15,6 @@ raspi-bcm43xx-load-firmware.patch
334 raspi-bcm43xx-3wire.patch
335 ubuntu_error_restart.patch
336 reconnect-hsp-on-a2dp-reconnect.patch
337+profiles-avdtp-Fix-reply-for-bad-media-transport-for.patch
338+a2dp-Remove-Endpoints-cache-entries-on-device-remova.patch
339+audio-upgrade-versions-to-latest-possible-to-qualify.patch

Subscribers

People subscribed via source and target branches

to all changes: