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