1 /*
2  * Copyright (c) 2022-2024 Nordic Semiconductor ASA
3  * Copyright 2023 NXP
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <zephyr/bluetooth/bluetooth.h>
12 #include <zephyr/bluetooth/audio/audio.h>
13 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
14 #include <zephyr/bluetooth/audio/cap.h>
15 #include <zephyr/bluetooth/audio/bap.h>
16 #include <zephyr/bluetooth/audio/tmap.h>
17 #include <zephyr/bluetooth/byteorder.h>
18 #include <zephyr/bluetooth/crypto.h>
19 #include <zephyr/bluetooth/gap.h>
20 #include <zephyr/bluetooth/iso.h>
21 #include <zephyr/bluetooth/uuid.h>
22 #include <zephyr/kernel.h>
23 #include <zephyr/net_buf.h>
24 #include <zephyr/sys/printk.h>
25 #include <zephyr/sys/util.h>
26 #include <zephyr/types.h>
27 
28 #define BROADCAST_ENQUEUE_COUNT 2U
29 
30 NET_BUF_POOL_FIXED_DEFINE(tx_pool,
31 			  (BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT),
32 			  BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8, NULL);
33 
34 static K_SEM_DEFINE(sem_broadcast_started, 0, 1);
35 static K_SEM_DEFINE(sem_broadcast_stopped, 0, 1);
36 
37 static struct bt_cap_stream broadcast_source_stream;
38 static struct bt_cap_stream *broadcast_stream;
39 
40 static uint8_t bis_codec_data[] = {BT_AUDIO_CODEC_DATA(
41 	BT_AUDIO_CODEC_CFG_FREQ, BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CFG_FREQ_48KHZ))};
42 
43 static const uint8_t new_metadata[] = {
44 	BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT,
45 			    BT_BYTES_LIST_LE16(BT_AUDIO_CONTEXT_TYPE_MEDIA))
46 };
47 
48 static struct bt_bap_lc3_preset broadcast_preset_48_2_1 =
49 	BT_BAP_LC3_UNICAST_PRESET_48_2_1(BT_AUDIO_LOCATION_FRONT_LEFT,
50 					BT_AUDIO_CONTEXT_TYPE_MEDIA);
51 
52 struct bt_cap_initiator_broadcast_stream_param stream_params;
53 struct bt_cap_initiator_broadcast_subgroup_param subgroup_param;
54 struct bt_cap_initiator_broadcast_create_param create_param;
55 struct bt_cap_broadcast_source *broadcast_source;
56 static struct k_work_delayable audio_send_work;
57 struct bt_le_ext_adv *ext_adv;
58 
59 static uint8_t tmap_addata[] = {
60 	BT_UUID_16_ENCODE(BT_UUID_TMAS_VAL), /* TMAS UUID */
61 	BT_BYTES_LIST_LE16(BT_TMAP_ROLE_BMS), /* TMAP Role */
62 };
63 
broadcast_started_cb(struct bt_bap_stream * stream)64 static void broadcast_started_cb(struct bt_bap_stream *stream)
65 {
66 	printk("Stream %p started\n", stream);
67 	k_sem_give(&sem_broadcast_started);
68 }
69 
broadcast_stopped_cb(struct bt_bap_stream * stream,uint8_t reason)70 static void broadcast_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
71 {
72 	printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
73 
74 	k_sem_give(&sem_broadcast_stopped);
75 }
76 
broadcast_sent_cb(struct bt_bap_stream * stream)77 static void broadcast_sent_cb(struct bt_bap_stream *stream)
78 {
79 	static uint8_t mock_data[CONFIG_BT_ISO_TX_MTU];
80 	static bool mock_data_initialized;
81 	static uint32_t seq_num;
82 	struct net_buf *buf;
83 	int ret;
84 
85 	if (broadcast_preset_48_2_1.qos.sdu > CONFIG_BT_ISO_TX_MTU) {
86 		printk("Invalid SDU %u for the MTU: %d",
87 		       broadcast_preset_48_2_1.qos.sdu, CONFIG_BT_ISO_TX_MTU);
88 		return;
89 	}
90 
91 	if (!mock_data_initialized) {
92 		for (size_t i = 0U; i < ARRAY_SIZE(mock_data); i++) {
93 			/* Initialize mock data */
94 			mock_data[i] = (uint8_t)i;
95 		}
96 		mock_data_initialized = true;
97 	}
98 
99 	buf = net_buf_alloc(&tx_pool, K_NO_WAIT);
100 	if (buf == NULL) {
101 		printk("Could not allocate buffer when sending on %p\n", stream);
102 
103 		/* Retry next SDU interval */
104 		k_work_schedule(&audio_send_work, K_USEC(broadcast_preset_48_2_1.qos.interval));
105 		return;
106 	}
107 
108 	net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
109 	net_buf_add_mem(buf, mock_data, broadcast_preset_48_2_1.qos.sdu);
110 	ret = bt_bap_stream_send(stream, buf, seq_num++);
111 	if (ret < 0) {
112 		net_buf_unref(buf);
113 
114 		/* Retry next SDU interval */
115 		k_work_schedule(&audio_send_work, K_USEC(broadcast_preset_48_2_1.qos.interval));
116 		return;
117 	}
118 }
119 
audio_timer_timeout(struct k_work * work)120 static void audio_timer_timeout(struct k_work *work)
121 {
122 	broadcast_sent_cb(&broadcast_stream->bap_stream);
123 }
124 
125 static struct bt_bap_stream_ops broadcast_stream_ops = {
126 	.started = broadcast_started_cb,
127 	.stopped = broadcast_stopped_cb,
128 	.sent = broadcast_sent_cb
129 };
130 
131 static const struct bt_data ad[] = {
132 	BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
133 };
134 
setup_extended_adv(struct bt_le_ext_adv ** adv)135 static int setup_extended_adv(struct bt_le_ext_adv **adv)
136 {
137 	int err;
138 
139 	/* Create a non-connectable advertising set */
140 	err = bt_le_ext_adv_create(BT_BAP_ADV_PARAM_BROADCAST_FAST, NULL, adv);
141 	if (err != 0) {
142 		printk("Unable to create extended advertising set: %d\n", err);
143 		return err;
144 	}
145 
146 	/* Set advertising data to have complete local name set */
147 	err = bt_le_ext_adv_set_data(*adv, ad, ARRAY_SIZE(ad), NULL, 0);
148 	if (err) {
149 		printk("Failed to set advertising data (err %d)\n", err);
150 		return 0;
151 	}
152 
153 	/* Set periodic advertising parameters */
154 	err = bt_le_per_adv_set_param(*adv, BT_BAP_PER_ADV_PARAM_BROADCAST_FAST);
155 	if (err) {
156 		printk("Failed to set periodic advertising parameters: %d\n",
157 		       err);
158 		return err;
159 	}
160 
161 	return 0;
162 }
163 
setup_extended_adv_data(struct bt_cap_broadcast_source * source,struct bt_le_ext_adv * adv)164 static int setup_extended_adv_data(struct bt_cap_broadcast_source *source,
165 				   struct bt_le_ext_adv *adv)
166 {
167 	/* Broadcast Audio Streaming Endpoint advertising data */
168 	NET_BUF_SIMPLE_DEFINE(ad_buf,
169 			      BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE);
170 	NET_BUF_SIMPLE_DEFINE(base_buf, 128);
171 	struct bt_data ext_ad[2];
172 	struct bt_data per_ad;
173 	uint32_t broadcast_id;
174 	int err;
175 
176 	err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE);
177 	if (err) {
178 		printk("Unable to generate broadcast ID: %d\n", err);
179 		return err;
180 	}
181 
182 	/* Setup extended advertising data */
183 	ext_ad[0].type = BT_DATA_SVC_DATA16;
184 	ext_ad[0].data_len = ARRAY_SIZE(tmap_addata);
185 	ext_ad[0].data = tmap_addata;
186 	/* Broadcast Audio Announcement */
187 	net_buf_simple_add_le16(&ad_buf, BT_UUID_BROADCAST_AUDIO_VAL);
188 	net_buf_simple_add_le24(&ad_buf, broadcast_id);
189 	ext_ad[1].type = BT_DATA_SVC_DATA16;
190 	ext_ad[1].data_len = ad_buf.len + sizeof(ext_ad[1].type);
191 	ext_ad[1].data = ad_buf.data;
192 
193 	err = bt_le_ext_adv_set_data(adv, ext_ad, ARRAY_SIZE(ext_ad), NULL, 0);
194 	if (err != 0) {
195 		printk("Failed to set extended advertising data: %d\n", err);
196 		return err;
197 	}
198 
199 	/* Setup periodic advertising data */
200 	err = bt_cap_initiator_broadcast_get_base(source, &base_buf);
201 	if (err != 0) {
202 		printk("Failed to get encoded BASE: %d\n", err);
203 		return err;
204 	}
205 
206 	per_ad.type = BT_DATA_SVC_DATA16;
207 	per_ad.data_len = base_buf.len;
208 	per_ad.data = base_buf.data;
209 	err = bt_le_per_adv_set_data(adv, &per_ad, 1);
210 	if (err != 0) {
211 		printk("Failed to set periodic advertising data: %d\n", err);
212 		return err;
213 	}
214 
215 	return 0;
216 }
217 
start_extended_adv(struct bt_le_ext_adv * adv)218 static int start_extended_adv(struct bt_le_ext_adv *adv)
219 {
220 	int err;
221 
222 	/* Start extended advertising */
223 	err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
224 	if (err) {
225 		printk("Failed to start extended advertising: %d\n", err);
226 		return err;
227 	}
228 
229 	/* Enable Periodic Advertising */
230 	err = bt_le_per_adv_start(adv);
231 	if (err) {
232 		printk("Failed to enable periodic advertising: %d\n", err);
233 		return err;
234 	}
235 
236 	return 0;
237 }
238 
stop_and_delete_extended_adv(struct bt_le_ext_adv * adv)239 static int stop_and_delete_extended_adv(struct bt_le_ext_adv *adv)
240 {
241 	int err;
242 
243 	/* Stop extended advertising */
244 	err = bt_le_per_adv_stop(adv);
245 	if (err) {
246 		printk("Failed to stop periodic advertising: %d\n", err);
247 		return err;
248 	}
249 
250 	err = bt_le_ext_adv_stop(adv);
251 	if (err) {
252 		printk("Failed to stop extended advertising: %d\n", err);
253 		return err;
254 	}
255 
256 	err = bt_le_ext_adv_delete(adv);
257 	if (err) {
258 		printk("Failed to delete extended advertising: %d\n", err);
259 		return err;
260 	}
261 
262 	return 0;
263 }
264 
reset(void)265 static int reset(void)
266 {
267 	k_sem_reset(&sem_broadcast_started);
268 	k_sem_reset(&sem_broadcast_stopped);
269 
270 	return 0;
271 }
272 
cap_initiator_init(void)273 int cap_initiator_init(void)
274 {
275 	broadcast_stream = &broadcast_source_stream;
276 	bt_bap_stream_cb_register(&broadcast_stream->bap_stream, &broadcast_stream_ops);
277 	k_work_init_delayable(&audio_send_work, audio_timer_timeout);
278 
279 	return 0;
280 }
281 
cap_initiator_setup(void)282 void cap_initiator_setup(void)
283 {
284 	int err;
285 
286 	stream_params.stream = &broadcast_source_stream;
287 	stream_params.data_len = ARRAY_SIZE(bis_codec_data);
288 	stream_params.data = bis_codec_data;
289 
290 	subgroup_param.stream_count = 1U;
291 	subgroup_param.stream_params = &stream_params;
292 	subgroup_param.codec_cfg = &broadcast_preset_48_2_1.codec_cfg;
293 
294 	create_param.subgroup_count = 1U;
295 	create_param.subgroup_params = &subgroup_param;
296 	create_param.qos = &broadcast_preset_48_2_1.qos;
297 	create_param.packing = BT_ISO_PACKING_SEQUENTIAL;
298 	create_param.encryption = false;
299 
300 	while (true) {
301 		err = reset();
302 		if (err != 0) {
303 			printk("Resetting failed: %d - Aborting\n", err);
304 			return;
305 		}
306 		printk("Creating broadcast source\n");
307 
308 		err = setup_extended_adv(&ext_adv);
309 		if (err != 0) {
310 			printk("Unable to setup extended advertiser: %d\n", err);
311 			return;
312 		}
313 
314 		err = bt_cap_initiator_broadcast_audio_create(&create_param, &broadcast_source);
315 		if (err != 0) {
316 			printk("Unable to create broadcast source: %d\n", err);
317 			return;
318 		}
319 
320 		err = bt_cap_initiator_broadcast_audio_start(broadcast_source, ext_adv);
321 		if (err != 0) {
322 			printk("Unable to start broadcast source: %d\n", err);
323 			return;
324 		}
325 
326 		err = setup_extended_adv_data(broadcast_source, ext_adv);
327 		if (err != 0) {
328 			printk("Unable to setup extended advertising data: %d\n", err);
329 			return;
330 		}
331 
332 		err = start_extended_adv(ext_adv);
333 		if (err != 0) {
334 			printk("Unable to start extended advertiser: %d\n", err);
335 			return;
336 		}
337 		k_sem_take(&sem_broadcast_started, K_FOREVER);
338 
339 		/* Initialize sending */
340 		for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
341 			broadcast_sent_cb(&broadcast_stream->bap_stream);
342 		}
343 
344 		/* Run for a little while */
345 		k_sleep(K_SECONDS(10));
346 
347 		err = bt_cap_initiator_broadcast_audio_update(broadcast_source,
348 							      new_metadata,
349 							      ARRAY_SIZE(new_metadata));
350 		if (err != 0) {
351 			printk("Failed to update broadcast source metadata: %d\n", err);
352 			return;
353 		}
354 
355 		/* Run for a little while */
356 		k_sleep(K_SECONDS(10));
357 
358 		err = bt_cap_initiator_broadcast_audio_stop(broadcast_source);
359 		if (err != 0) {
360 			printk("Failed to stop broadcast source: %d\n", err);
361 			return;
362 		}
363 		k_sem_take(&sem_broadcast_stopped, K_FOREVER);
364 
365 		err = bt_cap_initiator_broadcast_audio_delete(broadcast_source);
366 		if (err != 0) {
367 			printk("Failed to stop broadcast source: %d\n", err);
368 			return;
369 		}
370 		broadcast_source = NULL;
371 
372 		err = stop_and_delete_extended_adv(ext_adv);
373 		if (err != 0) {
374 			printk("Failed to stop and delete extended advertising: %d\n", err);
375 			return;
376 		}
377 	}
378 }
379