Skip to content

Commit 2c0b99d

Browse files
committed
Optional support for ASHA Sink with advertisement
1 parent e6c97c9 commit 2c0b99d

17 files changed

Lines changed: 1013 additions & 75 deletions

.github/spellcheck-wordlist.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ ARGS
153153
asound
154154
asoundrc
155155
asrsync
156+
ATT
156157
autoreconf
157158
ay
158159
BAC
@@ -163,8 +164,8 @@ BCS
163164
bdaddr
164165
bfr
165166
bluealsa
166-
bluealsad
167167
BlueALSA's
168+
bluealsad
168169
bluetoothctl
169170
bluetoothd
170171
BRSF
@@ -182,6 +183,7 @@ CKPD
182183
CLCC
183184
CLCK
184185
CMER
186+
CoC
185187
ctrl
186188
ctx
187189
dbus
@@ -195,7 +197,6 @@ dpsnk
195197
dpsrc
196198
DYN
197199
EAGAIN
198-
EDE
199200
EINTR
200201
EINVAL
201202
ENODEV
@@ -207,7 +208,6 @@ EQMID
207208
errno
208209
FB
209210
FC
210-
fdf
211211
fdX
212212
ffb
213213
ffff
@@ -225,6 +225,7 @@ HCTL
225225
HEv
226226
hfpag
227227
hfphf
228+
HiSync
228229
HiSyncId
229230
hspag
230231
hsphs
@@ -258,6 +259,7 @@ openaptx
258259
PCH
259260
pfd
260261
pfds
262+
PSM
261263
pthread
262264
ptr
263265
qsort

.github/spellcheck.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ matrix:
5252
# Ignore parameter name in docstring
5353
- open: '@param '
5454
close: '\W'
55+
# Ignore UUID strings
56+
- open: '[0-9a-f]{8}-[0-9a-f]{4}-'
57+
content: '[0-9a-f]{4}-[0-9a-f]{4}-'
58+
close: '[0-9a-f]{12}'
5559
# Ignore printf format placeholder
5660
- open: '%'
5761
content: '#?(l|z)'

doc/bluealsad.8.rst

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.. SPDX-FileCopyrightText: 2020-2025 BlueALSA developers
1+
.. SPDX-FileCopyrightText: 2020-2026 BlueALSA developers
22
.. SPDX-License-Identifier: MIT
33
44
=========
@@ -9,7 +9,7 @@ bluealsad
99
Bluetooth Audio ALSA Backend
1010
----------------------------
1111

12-
:Date: December 2025
12+
:Date: January 2026
1313
:Manual section: 8
1414
:Manual group: System Manager's Manual
1515
:Version: $VERSION$
@@ -264,8 +264,31 @@ OPTIONS
264264
- **standard** - standard quality (44.1 kHz: 606 kbps, 48 kHz: 660 kbps)
265265
- **high** - high quality (44.1 kHz: 909 kbps, 48 kHz: 990 kbps)
266266

267+
--asha-sync-id=ID
268+
Set ASHA Sink HiSync ID to *ID*.
269+
270+
The *ID* must be a 16-digit hexadecimal number (64 bits).
271+
272+
--asha-side=SIDE
273+
Set ASHA Sink device side to *SIDE*.
274+
Default value is **left**.
275+
276+
The *SIDE* can be one of:
277+
278+
- **left** - left side device
279+
- **left+** - left side of a binaural device
280+
- **right** - right side device
281+
- **right+** - right side of a binaural device
282+
283+
--asha-advertise
284+
Enable LE advertising for ASHA Sink.
285+
286+
--asha-adv-name=NAME
287+
Set the name used in the ASHA Sink advertising.
288+
By default, the name is set as "BlueALSA ASHA".
289+
267290
--midi-advertise
268-
Advertise BLE-MIDI service using Bluetooth LE advertising.
291+
Enable LE advertising for BLE-MIDI.
269292

270293
--midi-adv-name=NAME
271294
Set the name used in the BLE-MIDI advertising.
@@ -340,6 +363,7 @@ The list of profile *NAME*-s accepted by the ``--profile=NAME`` option:
340363
- **a2dp-source** - Advanced Audio Source (streaming audio to connected device)
341364
- **a2dp-sink** - Advanced Audio Sink (receiving audio from connected device)
342365
- **asha-source** - Audio Streaming for Hearing Aids Source
366+
- **asha-sink** - Audio Streaming for Hearing Aids Sink
343367
- **hfp-ofono** - Hands-Free AG/HF handled by oFono
344368
- **hfp-ag** - Hands-Free Audio Gateway
345369
- **hfp-hf** - Hands-Free

misc/bash-completion/bluealsad

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ _bluealsad() {
211211
readarray -t COMPREPLY < <(compgen -P "$prefix" -W "${list[*]}" -- "$cur")
212212
return
213213
;;
214-
--loglevel|--sbc-quality|--aac-latm-version|--mp3-algorithm|--mp3-vbr-quality|--ldac-quality)
214+
--loglevel|--sbc-quality|--aac-latm-version|--mp3-algorithm|--mp3-vbr-quality|--ldac-quality|--asha-side)
215215
readarray -t list < <(_bluealsa_enum_values "$1" "$prev")
216216
readarray -t COMPREPLY < <(compgen -W "${list[*]}" -- "$cur")
217217
return

src/Makefile.am

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# BlueALSA - Makefile.am
2-
# SPDX-FileCopyrightText: 2016-2025 BlueALSA developers
2+
# SPDX-FileCopyrightText: 2016-2026 BlueALSA developers
33
# SPDX-License-Identifier: MIT
44

55
SUBDIRS = shared
@@ -23,6 +23,8 @@ BUILT_SOURCES = \
2323
dbus/org.ofono.h \
2424
dbus/org.ofono.c
2525

26+
CODEGEN_DEFS =
27+
2628
MOSTLYCLEANFILES = \
2729
$(dist_dbusconf_DATA) \
2830
$(BUILT_SOURCES)
@@ -83,9 +85,13 @@ libbluealsad_la_SOURCES += \
8385
endif
8486

8587
if ENABLE_ASHA
88+
CODEGEN_DEFS += --define=ENABLE_GATT
8689
libbluealsad_la_SOURCES += \
8790
asha-g722.c \
88-
asha.c
91+
asha.c \
92+
bt-asha.c \
93+
bt-advertising.c \
94+
bt-gatt.c
8995
endif
9096

9197
if ENABLE_FASTSTREAM
@@ -110,9 +116,10 @@ libbluealsad_la_SOURCES += \
110116
endif
111117

112118
if ENABLE_MIDI
119+
CODEGEN_DEFS += --define=ENABLE_GATT
113120
libbluealsad_la_SOURCES += \
114121
ble-midi.c \
115-
bluez-midi.c \
122+
bt-midi.c \
116123
bt-advertising.c \
117124
bt-gatt.c \
118125
midi.c
@@ -201,11 +208,6 @@ DBUSCONF_SUBS = \
201208
.conf.in.conf:
202209
$(SED) -e '$(DBUSCONF_SUBS)' < $< > $@
203210

204-
CODEGEN_DEFS =
205-
if ENABLE_MIDI
206-
CODEGEN_DEFS += --define=ENABLE_MIDI
207-
endif
208-
209211
.xml.h:
210212
$(srcdir)/dbus/dbus-codegen.py --output $@ $(CODEGEN_DEFS) \
211213
--interface-info-header --interface-skeleton-header $<

src/ba-config.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
#include "codec-sbc.h"
2626
#include "hfp.h"
27+
#include "shared/bluetooth.h"
28+
#include "shared/bluetooth-asha.h"
2729

2830
/* Initialize global configuration variable. */
2931
struct ba_config config = {
@@ -55,8 +57,8 @@ struct ba_config config = {
5557
.hfp.codecs.lc3_swb = true,
5658
#endif
5759

58-
/* built-in Apple accessory identification */
59-
.hfp.xapl_vendor_id = 0xB103,
60+
/* Built-in Apple accessory identification. */
61+
.hfp.xapl_vendor_id = BT_COMPID_LINUX_FOUNDATION,
6062
.hfp.xapl_product_id = 0xA15A,
6163
.hfp.xapl_sw_version = 0x0400,
6264
.hfp.xapl_product_name = "BlueALSA",
@@ -74,7 +76,12 @@ struct ba_config config = {
7476
.a2dp.force_44100 = false,
7577

7678
#if ENABLE_ASHA
79+
.asha.id = ASHA_HI_SYNC_ID_INIT(
80+
BT_COMPID_LINUX_FOUNDATION, 0xB1, 0x03, 0xA1, 0x5A, 0x04, 0x05),
81+
.asha.side = ASHA_CAPABILITY_SIDE_LEFT,
7782
.asha.codecs.g722 = true,
83+
.asha.advertise = false,
84+
.asha.name = "BlueALSA ASHA",
7885
#endif
7986

8087
#if ENABLE_MIDI
@@ -134,13 +141,9 @@ struct ba_config config = {
134141
};
135142

136143
int ba_config_init(void) {
137-
138144
config.hci_filter = g_array_sized_new(FALSE, FALSE, sizeof(const char *), 4);
139-
140145
config.main_thread = pthread_self();
141-
142146
config.null_fd = open("/dev/null", O_WRONLY | O_NONBLOCK);
143-
144147
return 0;
145148
}
146149

src/ba-config.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <gio/gio.h>
2424
#include <glib.h>
2525

26+
#include "shared/bluetooth-asha.h"
27+
2628
struct ba_config {
2729

2830
/* set of enabled profiles */
@@ -120,11 +122,26 @@ struct ba_config {
120122
bool force_44100;
121123

122124
} a2dp;
125+
123126
#if ENABLE_ASHA
124127
struct {
128+
129+
/* Device ID. */
130+
asha_hi_sync_id_t id;
131+
/* The side of the device. */
132+
unsigned int side;
133+
/* Indicates whether the device is part of a binaural set. */
134+
bool binaural;
135+
125136
struct {
126137
bool g722;
127138
} codecs;
139+
140+
/* Advertise ASHA via LE advertisement. */
141+
bool advertise;
142+
/* Name used in the LE advertisement. */
143+
char name[16];
144+
128145
} asha;
129146
#endif
130147

src/bluez.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* BlueALSA - bluez.c
3-
* SPDX-FileCopyrightText: 2016-2025 BlueALSA developers
3+
* SPDX-FileCopyrightText: 2016-2026 BlueALSA developers
44
* SPDX-License-Identifier: MIT
55
*/
66

@@ -39,9 +39,8 @@
3939
#include "ba-transport-pcm.h"
4040
#include "bluealsa-dbus.h"
4141
#include "bluez-iface.h"
42-
#if ENABLE_MIDI
43-
# include "bluez-midi.h"
44-
#endif
42+
#include "bt-asha.h"
43+
#include "bt-midi.h"
4544
#include "dbus.h"
4645
#include "error.h"
4746
#include "hci.h"
@@ -83,18 +82,22 @@ struct bluez_dbus_object_data {
8382
/**
8483
* BlueALSA copy of BlueZ adapter data. */
8584
struct bluez_adapter {
86-
/* reference to the adapter structure */
87-
struct ba_adapter *adapter;
88-
/* manager for media endpoint objects */
89-
GDBusObjectManagerServer *manager_media_application;
90-
/* manager for battery provider objects */
91-
GDBusObjectManagerServer *manager_battery_provider;
85+
/* Reference to the adapter structure. */
86+
struct ba_adapter * adapter;
87+
/* Manager for media endpoint objects. */
88+
GDBusObjectManagerServer * manager_media_application;
89+
/* Manager for battery provider objects. */
90+
GDBusObjectManagerServer * manager_battery_provider;
91+
#if ENABLE_ASHA
92+
/* Bluetooth ASHA based on BlueZ GATT application. */
93+
BluetoothASHA * asha;
94+
#endif
9295
#if ENABLE_MIDI
9396
/* Bluetooth LE MIDI based on BlueZ GATT application. */
9497
BluetoothMIDI * midi;
9598
#endif
96-
/* array of SEP configs per connected devices */
97-
GHashTable *device_sep_configs_map;
99+
/* Array of SEP configs per connected devices. */
100+
GHashTable * device_sep_configs_map;
98101
};
99102

100103
static pthread_mutex_t bluez_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -222,6 +225,14 @@ static void bluez_adapter_register_media_application(
222225
* to be available on the given adapter. */
223226
static void bluez_adapter_register_gatt_applications(
224227
G_GNUC_UNUSED struct bluez_adapter * b_adapter) {
228+
#if ENABLE_ASHA
229+
if (config.profile.asha_sink) {
230+
char path[64];
231+
struct ba_adapter * a = b_adapter->adapter;
232+
snprintf(path, sizeof(path), "/org/bluez/%s/ASHA", a->hci.name);
233+
b_adapter->asha = bluetooth_asha_new(a, path);
234+
}
235+
#endif
225236
#if ENABLE_MIDI
226237
if (config.profile.midi) {
227238
char path[64];
@@ -236,6 +247,9 @@ static void bluez_adapter_free(
236247
struct bluez_adapter * b_adapter) {
237248
if (b_adapter->adapter == NULL)
238249
return;
250+
#if ENABLE_ASHA
251+
g_clear_object(&b_adapter->asha);
252+
#endif
239253
#if ENABLE_MIDI
240254
g_clear_object(&b_adapter->midi);
241255
#endif
@@ -1294,9 +1308,9 @@ static void bluez_media_endpoint_process_asha(
12941308
goto fail;
12951309
}
12961310

1297-
/* Make sure that HiSyncId size is valid. */
1311+
/* Make sure that HiSync ID size is valid. */
12981312
if (id_size != sizeof(asha_hi_sync_id_t)) {
1299-
error("Invalid HiSyncId size: %zu != %zu", id_size, sizeof(asha_hi_sync_id_t));
1313+
error("Invalid HiSync ID size: %zu != %zu", id_size, sizeof(asha_hi_sync_id_t));
13001314
goto fail;
13011315
}
13021316

0 commit comments

Comments
 (0)