1 /* @file
2  * @brief Internal APIs for Audio Endpoint handling
3 
4  * Copyright (c) 2020 Intel Corporation
5  * Copyright (c) 2022-2023 Nordic Semiconductor ASA
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <stdbool.h>
11 #include <stdint.h>
12 #include <stddef.h>
13 
14 #include <zephyr/autoconf.h>
15 #include <zephyr/bluetooth/audio/audio.h>
16 #include <zephyr/bluetooth/audio/bap.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/iso.h>
19 #include <zephyr/kernel.h>
20 #include <zephyr/sys/atomic.h>
21 #include <zephyr/sys/slist.h>
22 #include <zephyr/types.h>
23 
24 #include "ascs_internal.h"
25 #include "bap_stream.h"
26 
27 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
28 #define UNICAST_GROUP_CNT	 CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_COUNT
29 #define UNICAST_GROUP_STREAM_CNT CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT
30 #else /* !CONFIG_BT_BAP_UNICAST_CLIENT */
31 #define UNICAST_GROUP_CNT 0
32 #define UNICAST_GROUP_STREAM_CNT 0
33 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
34 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
35 #define BROADCAST_STREAM_CNT CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT
36 #else /* !CONFIG_BT_BAP_BROADCAST_SOURCE */
37 #define BROADCAST_STREAM_CNT 0
38 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
39 
40 /* Temp struct declarations to handle circular dependencies */
41 struct bt_bap_unicast_group;
42 struct bt_bap_broadcast_source;
43 struct bt_bap_broadcast_sink;
44 
45 struct bt_bap_ep {
46 	uint8_t  dir;
47 	uint8_t  cig_id;
48 	uint8_t  cis_id;
49 	struct bt_ascs_ase_status status;
50 	struct bt_bap_stream *stream;
51 	struct bt_audio_codec_cfg codec_cfg;
52 	struct bt_bap_qos_cfg qos;
53 	struct bt_bap_qos_cfg_pref qos_pref;
54 	struct bt_bap_iso *iso;
55 
56 	/* unicast stopped reason */
57 	uint8_t reason;
58 
59 	/* Used by the unicast server and client */
60 	bool receiver_ready;
61 
62 	/* TODO: Create a union to reduce memory usage */
63 	struct bt_bap_unicast_group *unicast_group;
64 	struct bt_bap_broadcast_source *broadcast_source;
65 	struct bt_bap_broadcast_sink *broadcast_sink;
66 };
67 
68 struct bt_bap_unicast_group_cig_param {
69 	uint32_t c_to_p_interval;
70 	uint32_t p_to_c_interval;
71 	uint16_t c_to_p_latency;
72 	uint16_t p_to_c_latency;
73 	uint8_t framing;
74 	uint8_t packing;
75 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
76 	uint8_t c_to_p_ft;
77 	uint8_t p_to_c_ft;
78 	uint16_t iso_interval;
79 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
80 };
81 
82 struct bt_bap_unicast_group {
83 	/* Group-wide QoS used to create the CIG */
84 	struct bt_bap_unicast_group_cig_param cig_param;
85 
86 	/* Unicast group fields */
87 	uint8_t index;
88 	bool allocated;
89 	/* Used to determine whether any stream in this group has been started which will prevent
90 	 * reconfiguring it
91 	 */
92 	bool has_been_connected;
93 	struct bt_iso_cig *cig;
94 	/* The ISO API for CIG creation requires an array of pointers to ISO channels */
95 	struct bt_iso_chan *cis[UNICAST_GROUP_STREAM_CNT];
96 	sys_slist_t streams;
97 };
98 
99 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
100 struct bt_audio_broadcast_stream_data {
101 	/** Codec Specific Data len */
102 	size_t data_len;
103 	/** Codec Specific Data */
104 	uint8_t data[CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE];
105 };
106 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
107 
108 struct bt_bap_broadcast_source {
109 	uint8_t stream_count;
110 	uint8_t packing;
111 	bool encryption;
112 
113 	struct bt_iso_big *big;
114 	struct bt_bap_qos_cfg *qos;
115 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
116 	/* Stored advanced parameters */
117 	uint8_t irc;
118 	uint8_t pto;
119 	uint16_t iso_interval;
120 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
121 
122 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
123 	/* The codec specific configured data for each stream in the subgroup */
124 	struct bt_audio_broadcast_stream_data stream_data[BROADCAST_STREAM_CNT];
125 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
126 	uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE];
127 
128 	/* The complete codec specific configured data for each stream in the subgroup.
129 	 * This contains both the subgroup and the BIS-specific data for each stream.
130 	 */
131 	struct bt_audio_codec_cfg codec_cfg[BROADCAST_STREAM_CNT];
132 
133 	/* The subgroups containing the streams used to create the broadcast source */
134 	sys_slist_t subgroups;
135 };
136 
137 enum bt_bap_broadcast_sink_flag {
138 	/** Sink has been initialized */
139 	BT_BAP_BROADCAST_SINK_FLAG_INITIALIZED,
140 
141 	/** BIGInfo has been received */
142 	BT_BAP_BROADCAST_SINK_FLAG_BIGINFO_RECEIVED,
143 
144 	/** Periodic Advertising is syncing */
145 	BT_BAP_BROADCAST_SINK_FLAG_SYNCING,
146 
147 	/** Broadcast sink instance is scanning */
148 	BT_BAP_BROADCAST_SINK_FLAG_SCANNING,
149 
150 	/** The BIG is encrypted */
151 	BT_BAP_BROADCAST_SINK_FLAG_BIG_ENCRYPTED,
152 
153 	/** The Scan Delegator Source ID is valid */
154 	BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID,
155 
156 	/** Total number of flags */
157 	BT_BAP_BROADCAST_SINK_FLAG_NUM_FLAGS,
158 };
159 
160 struct bt_bap_broadcast_sink_subgroup {
161 	uint32_t bis_indexes;
162 };
163 
164 struct bt_bap_broadcast_sink_bis {
165 	uint8_t index;
166 	struct bt_iso_chan *chan;
167 	struct bt_audio_codec_cfg codec_cfg;
168 };
169 
170 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
171 struct bt_bap_broadcast_sink {
172 	uint8_t index; /* index of broadcast_snks array */
173 	uint8_t stream_count;
174 	uint8_t bass_src_id;
175 	uint8_t subgroup_count;
176 	uint16_t iso_interval;
177 	uint16_t biginfo_num_bis;
178 	uint32_t broadcast_id; /* 24 bit */
179 	uint32_t indexes_bitfield;
180 	uint32_t valid_indexes_bitfield; /* based on codec support */
181 	struct bt_bap_qos_cfg qos_cfg;
182 	struct bt_le_per_adv_sync *pa_sync;
183 	struct bt_iso_big *big;
184 	uint8_t base_size;
185 	uint8_t base[BT_BASE_MAX_SIZE];
186 	struct bt_bap_broadcast_sink_bis bis[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
187 	struct bt_bap_broadcast_sink_subgroup subgroups[CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT];
188 	const struct bt_bap_scan_delegator_recv_state *recv_state;
189 	/* The streams used to create the broadcast sink */
190 	sys_slist_t streams;
191 
192 	/** Flags */
193 	ATOMIC_DEFINE(flags, BT_BAP_BROADCAST_SINK_FLAG_NUM_FLAGS);
194 };
195 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
196 
bt_bap_ep_state_str(uint8_t state)197 static inline const char *bt_bap_ep_state_str(uint8_t state)
198 {
199 	switch (state) {
200 	case BT_BAP_EP_STATE_IDLE:
201 		return "idle";
202 	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
203 		return "codec-configured";
204 	case BT_BAP_EP_STATE_QOS_CONFIGURED:
205 		return "qos-configured";
206 	case BT_BAP_EP_STATE_ENABLING:
207 		return "enabling";
208 	case BT_BAP_EP_STATE_STREAMING:
209 		return "streaming";
210 	case BT_BAP_EP_STATE_DISABLING:
211 		return "disabling";
212 	case BT_BAP_EP_STATE_RELEASING:
213 		return "releasing";
214 	default:
215 		return "unknown";
216 	}
217 }
218 
219 bool bt_bap_ep_is_broadcast_snk(const struct bt_bap_ep *ep);
220 bool bt_bap_ep_is_broadcast_src(const struct bt_bap_ep *ep);
221 bool bt_bap_ep_is_unicast_client(const struct bt_bap_ep *ep);
222