1 /** @file
2  *  @brief Bluetooth Public Broadcast Profile shell
3  */
4 
5 /*
6  * Copyright 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 
15 #include <zephyr/bluetooth/audio/audio.h>
16 #include <zephyr/bluetooth/audio/pbp.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/gap.h>
19 #include <zephyr/kernel.h>
20 #include <zephyr/net/buf.h>
21 #include <zephyr/shell/shell.h>
22 #include <zephyr/shell/shell_string_conv.h>
23 #include <zephyr/sys/__assert.h>
24 #include <zephyr/sys/util.h>
25 
26 #include "shell/bt.h"
27 
28 #define PBS_DEMO                'P', 'B', 'P'
29 
30 const uint8_t pba_metadata[] = {
31 	BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, PBS_DEMO)
32 };
33 
34 /* Buffer to hold the Public Broadcast Announcement */
35 NET_BUF_SIMPLE_DEFINE_STATIC(pbp_ad_buf, BT_PBP_MIN_PBA_SIZE + ARRAY_SIZE(pba_metadata));
36 
37 enum bt_pbp_announcement_feature pbp_features;
38 extern const struct shell *ctx_shell;
39 
cmd_pbp_set_features(const struct shell * sh,size_t argc,char ** argv)40 static int cmd_pbp_set_features(const struct shell *sh, size_t argc, char **argv)
41 {
42 	int err = 0;
43 	enum bt_pbp_announcement_feature features;
44 
45 	features = shell_strtoul(argv[1], 16, &err);
46 	if (err != 0) {
47 		shell_error(sh, "Could not parse received features: %d", err);
48 
49 		return -ENOEXEC;
50 	}
51 
52 	pbp_features = features;
53 
54 	return err;
55 }
56 
pbp_ad_data_add(struct bt_data data[],size_t data_size)57 size_t pbp_ad_data_add(struct bt_data data[], size_t data_size)
58 {
59 	int err;
60 
61 	net_buf_simple_reset(&pbp_ad_buf);
62 
63 	err = bt_pbp_get_announcement(pba_metadata,
64 				      ARRAY_SIZE(pba_metadata),
65 				      pbp_features,
66 				      &pbp_ad_buf);
67 
68 	if (err != 0) {
69 		shell_info(ctx_shell, "Create Public Broadcast Announcement");
70 	} else {
71 		shell_error(ctx_shell, "Failed to create Public Broadcast Announcement: %d", err);
72 	}
73 
74 	__ASSERT(data_size > 0, "No space for Public Broadcast Announcement");
75 	data[0].type = BT_DATA_SVC_DATA16;
76 	data[0].data_len = pbp_ad_buf.len;
77 	data[0].data = pbp_ad_buf.data;
78 
79 	return 1U;
80 }
81 
cmd_pbp(const struct shell * sh,size_t argc,char ** argv)82 static int cmd_pbp(const struct shell *sh, size_t argc, char **argv)
83 {
84 	if (argc > 1) {
85 		shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]);
86 	} else {
87 		shell_error(sh, "%s missing subcomand", argv[0]);
88 	}
89 
90 	return -ENOEXEC;
91 }
92 
93 SHELL_STATIC_SUBCMD_SET_CREATE(pbp_cmds,
94 	SHELL_CMD_ARG(set_features, NULL,
95 		      "Set the Public Broadcast Announcement features",
96 		      cmd_pbp_set_features, 2, 0),
97 	SHELL_SUBCMD_SET_END
98 );
99 
100 SHELL_CMD_ARG_REGISTER(pbp, &pbp_cmds, "Bluetooth pbp shell commands", cmd_pbp, 1, 1);
101