1 /** @file
2  *  @brief Bluetooth Basic Audio Profile (BAP) Unicast Server role.
3  *
4  *  Copyright (c) 2021-2024 Nordic Semiconductor ASA
5  *  Copyright (c) 2022 Codecoup
6  *  Copyright (c) 2023 NXP
7  *
8  *  SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #include <errno.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <string.h>
15 
16 #include <zephyr/autoconf.h>
17 #include <zephyr/bluetooth/audio/audio.h>
18 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
19 #include <zephyr/bluetooth/audio/bap.h>
20 #include <zephyr/bluetooth/audio/lc3.h>
21 #include <zephyr/bluetooth/audio/pacs.h>
22 #include <zephyr/bluetooth/audio/tbs.h>
23 #include <zephyr/bluetooth/bluetooth.h>
24 #include <zephyr/bluetooth/conn.h>
25 #include <zephyr/bluetooth/gap.h>
26 #include <zephyr/bluetooth/hci_types.h>
27 #include <zephyr/bluetooth/iso.h>
28 #include <zephyr/kernel.h>
29 #include <zephyr/net_buf.h>
30 #include <zephyr/sys/byteorder.h>
31 #include <zephyr/sys/printk.h>
32 #include <zephyr/sys/util.h>
33 #include <zephyr/sys/util_macro.h>
34 
35 #include "tmap_peripheral.h"
36 
37 static const struct bt_audio_codec_cap lc3_codec_cap =
38 	BT_AUDIO_CODEC_CAP_LC3(BT_AUDIO_CODEC_CAP_FREQ_16KHZ | BT_AUDIO_CODEC_CAP_FREQ_32KHZ |
39 				       BT_AUDIO_CODEC_CAP_FREQ_48KHZ,
40 			       BT_AUDIO_CODEC_CAP_DURATION_7_5 | BT_AUDIO_CODEC_CAP_DURATION_10,
41 			       BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(2), 30, 155u, 1u,
42 			       (AVAILABLE_SINK_CONTEXT | AVAILABLE_SOURCE_CONTEXT));
43 
44 static struct bt_conn *default_conn;
45 static struct bt_bap_stream streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
46 				    CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
47 static struct audio_source {
48 	struct bt_bap_stream *stream;
49 	uint16_t seq_num;
50 } source_streams[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
51 static size_t configured_source_stream_count;
52 
53 static const struct bt_bap_qos_cfg_pref qos_pref =
54 	BT_BAP_QOS_CFG_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 20000, 40000, 20000, 40000);
55 
print_hex(const uint8_t * ptr,size_t len)56 static void print_hex(const uint8_t *ptr, size_t len)
57 {
58 	while (len-- != 0) {
59 		printk("%02x", *ptr++);
60 	}
61 }
62 
print_cb(struct bt_data * data,void * user_data)63 static bool print_cb(struct bt_data *data, void *user_data)
64 {
65 	const char *str = (const char *)user_data;
66 
67 	printk("%s: type 0x%02x value_len %u\n", str, data->type, data->data_len);
68 	print_hex(data->data, data->data_len);
69 	printk("\n");
70 
71 	return true;
72 }
73 
print_codec_cfg(const struct bt_audio_codec_cfg * codec_cfg)74 static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg)
75 {
76 	printk("codec_cfg 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cfg->id, codec_cfg->cid,
77 	       codec_cfg->vid, codec_cfg->data_len);
78 
79 	if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
80 		enum bt_audio_location chan_allocation;
81 		int ret;
82 
83 		/* LC3 uses the generic LTV format - other codecs might do as well */
84 
85 		bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, print_cb, "data");
86 
87 		ret = bt_audio_codec_cfg_get_freq(codec_cfg);
88 		if (ret > 0) {
89 			printk("  Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret));
90 		}
91 
92 		ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
93 		if (ret > 0) {
94 			printk("  Frame Duration: %d us\n",
95 			       bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret));
96 		}
97 
98 		ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, false);
99 		if (ret == 0) {
100 			printk("  Channel allocation: 0x%x\n", chan_allocation);
101 		}
102 
103 		printk("  Octets per frame: %d (negative means value not pressent)\n",
104 		       bt_audio_codec_cfg_get_octets_per_frame(codec_cfg));
105 		printk("  Frames per SDU: %d\n",
106 		       bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true));
107 	} else {
108 		print_hex(codec_cfg->data, codec_cfg->data_len);
109 	}
110 
111 	bt_audio_data_parse(codec_cfg->meta, codec_cfg->meta_len, print_cb, "meta");
112 }
113 
print_qos(const struct bt_bap_qos_cfg * qos)114 static void print_qos(const struct bt_bap_qos_cfg *qos)
115 {
116 	printk("QoS: interval %u framing 0x%02x phy 0x%02x sdu %u "
117 	       "rtn %u latency %u pd %u\n",
118 	       qos->interval, qos->framing, qos->phy, qos->sdu,
119 	       qos->rtn, qos->latency, qos->pd);
120 }
121 
stream_alloc(void)122 static struct bt_bap_stream *stream_alloc(void)
123 {
124 	for (size_t i = 0; i < ARRAY_SIZE(streams); i++) {
125 		struct bt_bap_stream *stream = &streams[i];
126 
127 		if (!stream->conn) {
128 			return stream;
129 		}
130 	}
131 
132 	return NULL;
133 }
134 
lc3_config(struct bt_conn * conn,const struct bt_bap_ep * ep,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_stream ** stream,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)135 static int lc3_config(struct bt_conn *conn, const struct bt_bap_ep *ep, enum bt_audio_dir dir,
136 		      const struct bt_audio_codec_cfg *codec_cfg, struct bt_bap_stream **stream,
137 		      struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp)
138 {
139 
140 	printk("ASE Codec Config: conn %p ep %p dir %u\n", conn, ep, dir);
141 
142 	print_codec_cfg(codec_cfg);
143 
144 	*stream = stream_alloc();
145 	if (*stream == NULL) {
146 		printk("No streams available\n");
147 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE);
148 
149 		return -ENOMEM;
150 	}
151 
152 	printk("ASE Codec Config stream %p\n", *stream);
153 
154 	if (dir == BT_AUDIO_DIR_SOURCE) {
155 		source_streams[configured_source_stream_count++].stream = *stream;
156 	}
157 
158 	*pref = qos_pref;
159 
160 	return 0;
161 }
162 
lc3_reconfig(struct bt_bap_stream * stream,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)163 static int lc3_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir,
164 			const struct bt_audio_codec_cfg *codec_cfg,
165 			struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp)
166 {
167 	printk("ASE Codec Reconfig: stream %p\n", stream);
168 	print_codec_cfg(codec_cfg);
169 	*pref = qos_pref;
170 
171 	return 0;
172 }
173 
lc3_qos(struct bt_bap_stream * stream,const struct bt_bap_qos_cfg * qos,struct bt_bap_ascs_rsp * rsp)174 static int lc3_qos(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg *qos,
175 		   struct bt_bap_ascs_rsp *rsp)
176 {
177 	printk("QoS: stream %p qos %p\n", stream, qos);
178 
179 	print_qos(qos);
180 
181 	return 0;
182 }
183 
lc3_enable(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)184 static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len,
185 		      struct bt_bap_ascs_rsp *rsp)
186 {
187 	printk("Enable: stream %p meta_len %zu\n", stream, meta_len);
188 
189 	return 0;
190 }
191 
lc3_start(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)192 static int lc3_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
193 {
194 	printk("Start: stream %p\n", stream);
195 
196 	return 0;
197 }
198 
199 struct data_func_param {
200 	struct bt_bap_ascs_rsp *rsp;
201 	bool stream_context_present;
202 };
203 
data_func_cb(struct bt_data * data,void * user_data)204 static bool data_func_cb(struct bt_data *data, void *user_data)
205 {
206 	struct data_func_param *func_param = (struct data_func_param *)user_data;
207 
208 	if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(data->type)) {
209 		printk("Invalid metadata type %u or length %u\n", data->type, data->data_len);
210 		*func_param->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED,
211 						   data->type);
212 
213 		return false;
214 	}
215 
216 	if (data->type == BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT) {
217 		func_param->stream_context_present = true;
218 	}
219 
220 	if (data->type == BT_AUDIO_METADATA_TYPE_CCID_LIST) {
221 		for (uint8_t j = 0; j < data->data_len; j++) {
222 			const uint8_t ccid = data->data[j];
223 
224 			if (!(IS_ENABLED(CONFIG_BT_TBS_CLIENT_CCID) &&
225 			      bt_tbs_client_get_by_ccid(default_conn, ccid) != NULL)) {
226 				printk("CCID %u is unknown", ccid);
227 				*func_param->rsp =
228 					BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED,
229 							BT_BAP_ASCS_REASON_NONE);
230 
231 				return false;
232 			}
233 		}
234 	}
235 
236 	return true;
237 }
238 
lc3_metadata(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)239 static int lc3_metadata(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len,
240 			struct bt_bap_ascs_rsp *rsp)
241 {
242 	struct data_func_param func_param = {
243 		.rsp = rsp,
244 		.stream_context_present = false,
245 	};
246 	int err;
247 
248 	printk("Metadata: stream %p meta_len %zu\n", stream, meta_len);
249 
250 	err = bt_audio_data_parse(meta, meta_len, data_func_cb, &func_param);
251 	if (err != 0) {
252 		return err;
253 	}
254 
255 	if (!func_param.stream_context_present) {
256 		printk("Stream audio context not present on peer!");
257 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED,
258 				       BT_BAP_ASCS_REASON_NONE);
259 
260 		return -EINVAL;
261 	}
262 
263 	return 0;
264 }
265 
lc3_disable(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)266 static int lc3_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
267 {
268 	printk("Disable: stream %p\n", stream);
269 
270 	return 0;
271 }
272 
lc3_stop(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)273 static int lc3_stop(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
274 {
275 	printk("Stop: stream %p\n", stream);
276 
277 	return 0;
278 }
279 
lc3_release(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)280 static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
281 {
282 	printk("Release: stream %p\n", stream);
283 
284 	return 0;
285 }
286 
287 static struct bt_bap_unicast_server_register_param param = {
288 	CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
289 	CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
290 };
291 
292 static const struct bt_bap_unicast_server_cb unicast_server_cb = {
293 	.config = lc3_config,
294 	.reconfig = lc3_reconfig,
295 	.qos = lc3_qos,
296 	.enable = lc3_enable,
297 	.start = lc3_start,
298 	.metadata = lc3_metadata,
299 	.disable = lc3_disable,
300 	.stop = lc3_stop,
301 	.release = lc3_release,
302 };
303 
stream_recv(struct bt_bap_stream * stream,const struct bt_iso_recv_info * info,struct net_buf * buf)304 static void stream_recv(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info,
305 			struct net_buf *buf)
306 {
307 	if (buf->len != 0) {
308 		printk("Incoming audio on stream %p len %u\n", stream, buf->len);
309 	}
310 	/* TODO: decode data (if applicable) */
311 }
312 
stream_enabled(struct bt_bap_stream * stream)313 static void stream_enabled(struct bt_bap_stream *stream)
314 {
315 	struct bt_bap_ep_info ep_info;
316 	int err;
317 
318 	err = bt_bap_ep_get_info(stream->ep, &ep_info);
319 	if (err != 0) {
320 		printk("Failed to get ep info: %d\n", err);
321 		return;
322 	}
323 
324 	/* The unicast server is responsible for starting the sink streams */
325 	if (ep_info.dir == BT_AUDIO_DIR_SINK) {
326 		/* Automatically do the receiver start ready operation */
327 		err = bt_bap_stream_start(stream);
328 
329 		if (err != 0) {
330 			printk("Failed to start stream %p: %d", stream, err);
331 		}
332 	}
333 }
334 
335 static struct bt_bap_stream_ops stream_ops = {
336 	.recv = stream_recv,
337 	.enabled = stream_enabled
338 };
339 
connected(struct bt_conn * conn,uint8_t err)340 static void connected(struct bt_conn *conn, uint8_t err)
341 {
342 	default_conn = bt_conn_ref(conn);
343 }
344 
disconnected(struct bt_conn * conn,uint8_t reason)345 static void disconnected(struct bt_conn *conn, uint8_t reason)
346 {
347 	if (conn != default_conn) {
348 		return;
349 	}
350 
351 	bt_conn_unref(default_conn);
352 	default_conn = NULL;
353 
354 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SRC)) {
355 		/* reset data */
356 		(void)memset(source_streams, 0, sizeof(source_streams));
357 		configured_source_stream_count = 0U;
358 	}
359 }
360 
361 BT_CONN_CB_DEFINE(conn_callbacks) = {
362 	.connected = connected,
363 	.disconnected = disconnected,
364 };
365 
366 static struct bt_pacs_cap cap = {
367 	.codec_cap = &lc3_codec_cap,
368 };
369 
bap_unicast_sr_init(void)370 int bap_unicast_sr_init(void)
371 {
372 	bt_bap_unicast_server_register(&param);
373 	bt_bap_unicast_server_register_cb(&unicast_server_cb);
374 
375 	if (IS_ENABLED(CONFIG_BT_PAC_SNK)) {
376 		/* Register CT required capabilities */
377 		bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap);
378 
379 		if (IS_ENABLED(CONFIG_TMAP_PERIPHERAL_LEFT)) {
380 			bt_pacs_set_location(BT_AUDIO_DIR_SINK, BT_AUDIO_LOCATION_FRONT_LEFT);
381 		} else {
382 			bt_pacs_set_location(BT_AUDIO_DIR_SINK, BT_AUDIO_LOCATION_FRONT_RIGHT);
383 		}
384 
385 		bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
386 					       AVAILABLE_SINK_CONTEXT);
387 		bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
388 					       AVAILABLE_SINK_CONTEXT);
389 	}
390 
391 	if (IS_ENABLED(CONFIG_BT_PAC_SRC)) {
392 		/* Register CT required capabilities */
393 		bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap);
394 
395 		if (IS_ENABLED(CONFIG_TMAP_PERIPHERAL_LEFT)) {
396 			bt_pacs_set_location(BT_AUDIO_DIR_SOURCE, BT_AUDIO_LOCATION_FRONT_LEFT);
397 		} else {
398 			bt_pacs_set_location(BT_AUDIO_DIR_SOURCE, BT_AUDIO_LOCATION_FRONT_RIGHT);
399 		}
400 
401 		bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE,
402 					       AVAILABLE_SOURCE_CONTEXT);
403 		bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
404 					       AVAILABLE_SOURCE_CONTEXT);
405 	}
406 
407 	for (size_t i = 0; i < ARRAY_SIZE(streams); i++) {
408 		bt_bap_stream_cb_register(&streams[i], &stream_ops);
409 	}
410 
411 	return 0;
412 }
413