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