1 /** @file
2  * @brief Advanced Audio Distribution Profile header.
3  */
4 
5 /*
6  * Copyright (c) 2015-2016 Intel Corporation
7  * Copyright 2024 NXP
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_A2DP_H_
12 #define ZEPHYR_INCLUDE_BLUETOOTH_A2DP_H_
13 
14 #include <stdint.h>
15 
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/l2cap.h>
18 #include <zephyr/bluetooth/classic/avdtp.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #define BT_A2DP_STREAM_BUF_RESERVE (12U + BT_L2CAP_BUF_SIZE(0))
25 
26 /** SBC IE length */
27 #define BT_A2DP_SBC_IE_LENGTH      (4U)
28 /** MPEG1,2 IE length */
29 #define BT_A2DP_MPEG_1_2_IE_LENGTH (4U)
30 /** MPEG2,4 IE length */
31 #define BT_A2DP_MPEG_2_4_IE_LENGTH (6U)
32 /** The max IE (Codec Info Element) length */
33 #define BT_A2DP_MAX_IE_LENGTH      (8U)
34 
35 /** @brief define the audio endpoint
36  *  @param _role BT_AVDTP_SOURCE or BT_AVDTP_SINK.
37  *  @param _codec value of enum bt_a2dp_codec_id.
38  *  @param _capability the codec capability.
39  */
40 #define BT_A2DP_EP_INIT(_role, _codec, _capability)                                                \
41 	{                                                                                          \
42 		.codec_type = _codec,                                                              \
43 		.sep = {.sep_info = {.media_type = BT_AVDTP_AUDIO, .tsep = _role}},                \
44 		.codec_cap = _capability, .stream = NULL,                                          \
45 	}
46 
47 /** @brief define the audio sink endpoint
48  *  @param _codec value of enum bt_a2dp_codec_id.
49  *  @param _capability the codec capability.
50  */
51 #define BT_A2DP_SINK_EP_INIT(_codec, _capability)                                                  \
52 	BT_A2DP_EP_INIT(BT_AVDTP_SINK, _codec, _capability)
53 
54 /** @brief define the audio source endpoint
55  *  @param _codec value of enum bt_a2dp_codec_id.
56  *  @param _capability the codec capability.
57  */
58 #define BT_A2DP_SOURCE_EP_INIT(_codec, _capability)                                                \
59 	BT_A2DP_EP_INIT(BT_AVDTP_SOURCE, _codec, _capability)
60 
61 /** @brief define the SBC sink endpoint that can be used as
62  * bt_a2dp_register_endpoint's parameter.
63  *
64  * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SINK_EP_DEFAULT
65  * is more convenient for user to register SBC endpoint.
66  *
67  *  @param _name unique structure name postfix.
68  *  @param _freq sbc codec frequency.
69  *               for example: A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000
70  *  @param _ch_mode sbc codec channel mode.
71  *               for example: A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO
72  *  @param _blk_len sbc codec block length.
73  *               for example: A2DP_SBC_BLK_LEN_16
74  *  @param _subband sbc codec subband.
75  *               for example: A2DP_SBC_SUBBAND_8
76  *  @param _alloc_mthd sbc codec allocate method.
77  *               for example: A2DP_SBC_ALLOC_MTHD_LOUDNESS
78  *  @param _min_bitpool sbc codec min bit pool. for example: 18
79  *  @param _max_bitpool sbc codec max bit pool. for example: 35
80  *  @
81  */
82 #define BT_A2DP_SBC_SINK_EP(_name, _freq, _ch_mode, _blk_len, _subband, _alloc_mthd, _min_bitpool, \
83 			    _max_bitpool)                                                          \
84 	static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = {                                \
85 		.len = BT_A2DP_SBC_IE_LENGTH,                                                      \
86 		.codec_ie = {_freq | _ch_mode, _blk_len | _subband | _alloc_mthd, _min_bitpool,    \
87 			     _max_bitpool}};                                                       \
88 	static struct bt_a2dp_ep _name =                                                           \
89 		BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC, (&bt_a2dp_ep_cap_ie##_name))
90 
91 /** @brief define the SBC source endpoint that can be used as bt_a2dp_register_endpoint's
92  * parameter.
93  *
94  * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SOURCE_EP_DEFAULT
95  * is more convenient for user to register SBC endpoint.
96  *
97  *  @param _name the endpoint variable name.
98  *  @param _freq sbc codec frequency.
99  *               for example: A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000
100  *  @param _ch_mode sbc codec channel mode.
101  *               for example: A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO
102  *  @param _blk_len sbc codec block length.
103  *               for example: A2DP_SBC_BLK_LEN_16
104  *  @param _subband sbc codec subband.
105  *               for example: A2DP_SBC_SUBBAND_8
106  *  @param _alloc_mthd sbc codec allocate method.
107  *               for example: A2DP_SBC_ALLOC_MTHD_LOUDNESS
108  *  @param _min_bitpool sbc codec min bit pool. for example: 18
109  *  @param _max_bitpool sbc codec max bit pool. for example: 35
110  */
111 #define BT_A2DP_SBC_SOURCE_EP(_name, _freq, _ch_mode, _blk_len, _subband, _alloc_mthd,             \
112 			      _min_bitpool, _max_bitpool)                                          \
113 	static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = {                                \
114 		.len = BT_A2DP_SBC_IE_LENGTH,                                                      \
115 		.codec_ie = {_freq | _ch_mode, _blk_len | _subband | _alloc_mthd, _min_bitpool,    \
116 			     _max_bitpool}};                                                       \
117 	static struct bt_a2dp_ep _name =                                                           \
118 		BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name)
119 
120 /** @brief define the default SBC sink endpoint that can be used as
121  * bt_a2dp_register_endpoint's parameter.
122  *
123  * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SINK_EP_DEFAULT
124  * is more convenient for user to register SBC endpoint.
125  *
126  *  @param _name the endpoint variable name.
127  */
128 #define BT_A2DP_SBC_SINK_EP_DEFAULT(_name)                                                         \
129 	static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = {                                \
130 		.len = BT_A2DP_SBC_IE_LENGTH,                                                      \
131 		.codec_ie = {A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 |                 \
132 				     A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO |              \
133 				     A2DP_SBC_CH_MODE_JOINT,                                       \
134 			     A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 |                            \
135 				     A2DP_SBC_ALLOC_MTHD_LOUDNESS,                                 \
136 			     18U, 35U}};                                                           \
137 	static struct bt_a2dp_ep _name =                                                           \
138 		BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name)
139 
140 /** @brief define the default SBC source endpoint that can be used as bt_a2dp_register_endpoint's
141  * parameter.
142  *
143  * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SOURCE_EP_DEFAULT
144  * is more convenient for user to register SBC endpoint.
145  *
146  *  @param _name the endpoint variable name.
147  */
148 #define BT_A2DP_SBC_SOURCE_EP_DEFAULT(_name)                                                       \
149 	static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = {                                \
150 		.len = BT_A2DP_SBC_IE_LENGTH,                                                      \
151 		.codec_ie = {A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 |                 \
152 				     A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO |              \
153 				     A2DP_SBC_CH_MODE_JOINT,                                       \
154 			     A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 |                            \
155 				     A2DP_SBC_ALLOC_MTHD_LOUDNESS,                                 \
156 			     18U, 35U},                                                            \
157 	};                                                                                         \
158 	static struct bt_a2dp_ep _name =                                                           \
159 		BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name)
160 
161 /** @brief define the SBC default configuration.
162  *
163  *  @param _name unique structure name postfix.
164  *  @param _freq_cfg sbc codec frequency.
165  *               for example: A2DP_SBC_SAMP_FREQ_44100
166  *  @param _ch_mode_cfg sbc codec channel mode.
167  *               for example: A2DP_SBC_CH_MODE_JOINT
168  *  @param _blk_len_cfg sbc codec block length.
169  *               for example: A2DP_SBC_BLK_LEN_16
170  *  @param _subband_cfg sbc codec subband.
171  *               for example: A2DP_SBC_SUBBAND_8
172  *  @param _alloc_mthd_cfg sbc codec allocate method.
173  *               for example: A2DP_SBC_ALLOC_MTHD_LOUDNESS
174  *  @param _min_bitpool_cfg sbc codec min bit pool. for example: 18
175  *  @param _max_bitpool_cfg sbc codec max bit pool. for example: 35
176  */
177 #define BT_A2DP_SBC_EP_CFG(_name, _freq_cfg, _ch_mode_cfg, _blk_len_cfg, _subband_cfg,             \
178 			   _alloc_mthd_cfg, _min_bitpool_cfg, _max_bitpool_cfg)                    \
179 	static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = {                                 \
180 		.len = BT_A2DP_SBC_IE_LENGTH,                                                      \
181 		.codec_ie = {_freq_cfg | _ch_mode_cfg,                                             \
182 			     _blk_len_cfg | _subband_cfg | _alloc_mthd_cfg, _min_bitpool_cfg,      \
183 			     _max_bitpool_cfg},                                                    \
184 	};                                                                                         \
185 	struct bt_a2dp_codec_cfg _name = {                                                         \
186 		.codec_config = &bt_a2dp_codec_ie##_name,                                          \
187 	}
188 
189 /** @brief define the SBC default configuration.
190  *
191  *  @param _name unique structure name postfix.
192  *  @param _freq_cfg the frequency to configure the remote same codec type endpoint.
193  */
194 #define BT_A2DP_SBC_EP_CFG_DEFAULT(_name, _freq_cfg)                                               \
195 	static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = {                                 \
196 		.len = BT_A2DP_SBC_IE_LENGTH,                                                      \
197 		.codec_ie = {_freq_cfg | A2DP_SBC_CH_MODE_JOINT,                                   \
198 			     A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 |                            \
199 				     A2DP_SBC_ALLOC_MTHD_LOUDNESS,                                 \
200 			     18U, 35U},                                                            \
201 	};                                                                                         \
202 	struct bt_a2dp_codec_cfg _name = {                                                         \
203 		.codec_config = &bt_a2dp_codec_ie##_name,                                          \
204 	}
205 
206 /**
207  * @brief A2DP error code
208  */
209 enum bt_a2dp_err_code {
210 	/** Media Codec Type is not valid */
211 	BT_A2DP_INVALID_CODEC_TYPE = 0xC1,
212 	/** Media Codec Type is not supported */
213 	BT_A2DP_NOT_SUPPORTED_CODEC_TYPE = 0xC2,
214 	/** Sampling Frequency is not valid or multiple values have been selected */
215 	BT_A2DP_INVALID_SAMPLING_FREQUENCY = 0xC3,
216 	/** Sampling Frequency is not supported */
217 	BT_A2DP_NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4,
218 	/** Channel Mode is not valid or multiple values have been selected */
219 	BT_A2DP_INVALID_CHANNEL_MODE = 0xC5,
220 	/** Channel Mode is not supported */
221 	BT_A2DP_NOT_SUPPORTED_CHANNEL_MODE = 0xC6,
222 	/** None or multiple values have been selected for Number of Subbands */
223 	BT_A2DP_INVALID_SUBBANDS = 0xC7,
224 	/** Number of Subbands is not supported */
225 	BT_A2DP_NOT_SUPPORTED_SUBBANDS = 0xC8,
226 	/** None or multiple values have been selected for Allocation Method */
227 	BT_A2DP_INVALID_ALLOCATION_METHOD = 0xC9,
228 	/** Allocation Method is not supported */
229 	BT_A2DP_NOT_SUPPORTED_ALLOCATION_METHOD = 0xCA,
230 	/** Minimum Bitpool Value is not valid */
231 	BT_A2DP_INVALID_MINIMUM_BITPOOL_VALUE = 0xCB,
232 	/** Minimum Bitpool Value is not supported */
233 	BT_A2DP_NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCC,
234 	/** Maximum Bitpool Value is not valid */
235 	BT_A2DP_INVALID_MAXIMUM_BITPOOL_VALUE = 0xCD,
236 	/** Maximum Bitpool Value is not supported */
237 	BT_A2DP_NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCE,
238 	/** None or multiple values have been selected for Layer */
239 	BT_A2DP_INVALID_LAYER = 0xCF,
240 	/** Layer is not supported */
241 	BT_A2DP_NOT_SUPPORTED_LAYER = 0xD0,
242 	/** CRC is not supported */
243 	BT_A2DP_NOT_SUPPORTED_CRC = 0xD1,
244 	/** MPF-2 is not supported */
245 	BT_A2DP_NOT_SUPPORTED_MPF = 0xD2,
246 	/** VBR is not supported */
247 	BT_A2DP_NOT_SUPPORTED_VBR = 0xD3,
248 	/** None or multiple values have been selected for Bit Rate */
249 	BT_A2DP_INVALID_BIT_RATE = 0xD4,
250 	/** Bit Rate is not supported */
251 	BT_A2DP_NOT_SUPPORTED_BIT_RATE = 0xD5,
252 	/** Either 1) Object type is not valid or
253 	 * 2) None or multiple values have been selected for Object Type
254 	 */
255 	BT_A2DP_INVALID_OBJECT_TYPE = 0xD6,
256 	/** Object Type is not supported */
257 	BT_A2DP_NOT_SUPPORTED_OBJECT_TYPE = 0xD7,
258 	/** Either 1) Channels is not valid or
259 	 * 2) None or multiple values have been selected for Channels
260 	 */
261 	BT_A2DP_INVALID_CHANNELS = 0xD8,
262 	/** Channels is not supported */
263 	BT_A2DP_NOT_SUPPORTED_CHANNELS = 0xD9,
264 	/** Version is not valid */
265 	BT_A2DP_INVALID_VERSION = 0xDA,
266 	/** Version is not supported */
267 	BT_A2DP_NOT_SUPPORTED_VERSION = 0xDB,
268 	/** Maximum SUL is not acceptable for the Decoder in the SNK */
269 	BT_A2DP_NOT_SUPPORTED_MAXIMUM_SUL = 0xDC,
270 	/** None or multiple values have been selected for Block Length */
271 	BT_A2DP_INVALID_BLOCK_LENGTH = 0xDD,
272 	/** The requested CP Type is not supported */
273 	BT_A2DP_INVALID_CP_TYPE = 0xE0,
274 	/** The format of Content Protection Service Capability/Content
275 	 * Protection Scheme Dependent Data is not correct
276 	 */
277 	BT_A2DP_INVALID_CP_FORMAT = 0xE1,
278 	/** The codec parameter is invalid.
279 	 * Used if a more specific error code does not exist for the codec in use
280 	 */
281 	BT_A2DP_INVALID_CODEC_PARAMETER = 0xE2,
282 	/** The codec parameter is not supported.
283 	 * Used if a more specific error code does not exist for the codec in use
284 	 */
285 	BT_A2DP_NOT_SUPPORTED_CODEC_PARAMETER = 0xE3,
286 	/** Combination of Object Type and DRC is invalid */
287 	BT_A2DP_INVALID_DRC = 0xE4,
288 	/** DRC is not supported */
289 	BT_A2DP_NOT_SUPPORTED_DRC = 0xE5,
290 };
291 
292 /** @brief Codec Type */
293 enum bt_a2dp_codec_type {
294 	/** Codec SBC */
295 	BT_A2DP_SBC = 0x00,
296 	/** Codec MPEG-1 */
297 	BT_A2DP_MPEG1 = 0x01,
298 	/** Codec MPEG-2 */
299 	BT_A2DP_MPEG2 = 0x02,
300 	/** Codec ATRAC */
301 	BT_A2DP_ATRAC = 0x04,
302 	/** Codec Non-A2DP */
303 	BT_A2DP_VENDOR = 0xff
304 };
305 
306 /** @brief A2DP structure */
307 struct bt_a2dp;
308 
309 /* Internal to pass build */
310 struct bt_a2dp_stream;
311 
312 /** @brief codec information elements for the endpoint */
313 struct bt_a2dp_codec_ie {
314 	/** Length of codec_cap */
315 	uint8_t len;
316 	/** codec information element */
317 	uint8_t codec_ie[BT_A2DP_MAX_IE_LENGTH];
318 };
319 
320 /** @brief The endpoint configuration */
321 struct bt_a2dp_codec_cfg {
322 	/** The media codec configuration content */
323 	struct bt_a2dp_codec_ie *codec_config;
324 };
325 
326 /** @brief Stream End Point */
327 struct bt_a2dp_ep {
328 	/** Code Type @ref bt_a2dp_codec_type */
329 	uint8_t codec_type;
330 	/** Capabilities */
331 	struct bt_a2dp_codec_ie *codec_cap;
332 	/** AVDTP Stream End Point Identifier */
333 	struct bt_avdtp_sep sep;
334 	/* Internally used stream object pointer */
335 	struct bt_a2dp_stream *stream;
336 };
337 
338 struct bt_a2dp_ep_info {
339 	/** Code Type @ref bt_a2dp_codec_type */
340 	uint8_t codec_type;
341 	/** Codec capabilities, if SBC, use function of a2dp_codec_sbc.h to parse it */
342 	struct bt_a2dp_codec_ie codec_cap;
343 	/** Stream End Point Information */
344 	struct bt_avdtp_sep_info sep_info;
345 };
346 
347 /** @brief Helper enum to be used as return value of bt_a2dp_discover_ep_cb.
348  *  The value informs the caller to perform further pending actions or stop them.
349  */
350 enum {
351 	BT_A2DP_DISCOVER_EP_STOP = 0,
352 	BT_A2DP_DISCOVER_EP_CONTINUE,
353 };
354 
355 /** @typedef bt_a2dp_discover_ep_cb
356  *
357  *  @brief Called when a stream endpoint is discovered.
358  *
359  *  A function of this type is given by the user to the bt_a2dp_discover_param
360  *  object. It'll be called on each valid stream endpoint discovery completion.
361  *  When no more endpoint then NULL is passed to the user. Otherwise user can get
362  *  valid endpoint information from parameter info, user can set parameter ep to
363  *  get the endpoint after the callback is return.
364  *  The returned function value allows the user to control retrieving follow-up
365  *  endpoints if any. If the user doesn't want to read more endpoints since
366  *  current found endpoints fulfill its requirements then should return
367  *  BT_A2DP_DISCOVER_EP_STOP. Otherwise returned value means
368  *  more subcall iterations are allowable.
369  *
370  *  @param a2dp a2dp connection object identifying a2dp connection to queried remote.
371  *  @param info Object pointing to the information of the callbacked endpoint.
372  *  @param ep If the user want to use this found endpoint, user can set value to it
373  *  to get the endpoint that can be used further in other A2DP APIs. It is NULL if info
374  *  is NULL (no more endpoint is found).
375  *
376  *  @return BT_A2DP_DISCOVER_EP_STOP in case of no more need to continue discovery
377  *  for next endpoint. By returning BT_A2DP_DISCOVER_EP_STOP user allows this
378  *  discovery continuation.
379  */
380 typedef uint8_t (*bt_a2dp_discover_ep_cb)(struct bt_a2dp *a2dp, struct bt_a2dp_ep_info *info,
381 					  struct bt_a2dp_ep **ep);
382 
383 struct bt_a2dp_discover_param {
384 	/** discover callback */
385 	bt_a2dp_discover_ep_cb cb;
386 	/** The discovered endpoint info that is callbacked by cb */
387 	struct bt_a2dp_ep_info info;
388 	/** The max count of remote endpoints that can be got,
389 	 *  it save endpoint info internally.
390 	 */
391 	struct bt_avdtp_sep_info *seps_info;
392 	/** The max count of seps (stream endpoint) that can be got in this call route */
393 	uint8_t sep_count;
394 };
395 
396 /** @brief The connecting callback */
397 struct bt_a2dp_cb {
398 	/** @brief A a2dp connection has been established.
399 	 *
400 	 *  This callback notifies the application of a a2dp connection.
401 	 *  It means the AVDTP L2CAP connection.
402 	 *  In case the err parameter is non-zero it means that the
403 	 *  connection establishment failed.
404 	 *
405 	 *  @param a2dp a2dp connection object.
406 	 *  @param err error code.
407 	 */
408 	void (*connected)(struct bt_a2dp *a2dp, int err);
409 	/** @brief A a2dp connection has been disconnected.
410 	 *
411 	 *  This callback notifies the application that a a2dp connection
412 	 *  has been disconnected.
413 	 *
414 	 *  @param a2dp a2dp connection object.
415 	 */
416 	void (*disconnected)(struct bt_a2dp *a2dp);
417 	/**
418 	 * @brief Endpoint config request callback
419 	 *
420 	 * The callback is called whenever an endpoint is requested to be
421 	 * configured.
422 	 *
423 	 *  @param a2dp a2dp connection object.
424 	 *  @param[in]  ep        Local Audio Endpoint being configured.
425 	 *  @param[in]  codec_cfg Codec configuration.
426 	 *  @param[out] stream    Pointer to stream that will be configured for the endpoint.
427 	 *  @param[out] rsp_err_code  give the error code if response error.
428 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
429 	 *
430 	 * @return 0 in case of success or negative value in case of error.
431 	 */
432 	int (*config_req)(struct bt_a2dp *a2dp, struct bt_a2dp_ep *ep,
433 			  struct bt_a2dp_codec_cfg *codec_cfg, struct bt_a2dp_stream **stream,
434 			  uint8_t *rsp_err_code);
435 	/**
436 	 * @brief Endpoint config request callback
437 	 *
438 	 * The callback is called whenever an endpoint is requested to be
439 	 * reconfigured.
440 	 *
441 	 *  @param[in] stream    Pointer to stream object.
442 	 *  @param[out] rsp_err_code  give the error code if response error.
443 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
444 	 *
445 	 * @return 0 in case of success or negative value in case of error.
446 	 */
447 	int (*reconfig_req)(struct bt_a2dp_stream *stream, struct bt_a2dp_codec_cfg *codec_cfg,
448 			    uint8_t *rsp_err_code);
449 	/** @brief Callback function for bt_a2dp_stream_config() and bt_a2dp_stream_reconfig()
450 	 *
451 	 *  Called when the codec configure operation is completed.
452 	 *
453 	 *  @param[in] stream    Pointer to stream object.
454 	 *  @param[in] rsp_err_code the remote responded error code
455 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
456 	 */
457 	void (*config_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code);
458 	/**
459 	 * @brief Stream establishment request callback
460 	 *
461 	 * The callback is called whenever an stream is requested to be
462 	 * established (open cmd and create the stream l2cap channel).
463 	 *
464 	 *  @param[in] stream    Pointer to stream object.
465 	 *  @param[out] rsp_err_code  give the error code if response error.
466 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
467 	 *
468 	 * @return 0 in case of success or negative value in case of error.
469 	 */
470 	int (*establish_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code);
471 	/** @brief Callback function for bt_a2dp_stream_establish()
472 	 *
473 	 *  Called when the establishment operation is completed.
474 	 *  (open cmd and create the stream l2cap channel).
475 	 *
476 	 *  @param[in] stream    Pointer to stream object.
477 	 *  @param[in] rsp_err_code the remote responded error code
478 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
479 	 */
480 	void (*establish_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code);
481 	/**
482 	 * @brief Stream release request callback
483 	 *
484 	 * The callback is called whenever an stream is requested to be
485 	 * released (release cmd and release the l2cap channel)
486 	 *
487 	 *  @param[in] stream    Pointer to stream object.
488 	 *  @param[out] rsp_err_code  give the error code if response error.
489 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
490 	 *
491 	 * @return 0 in case of success or negative value in case of error.
492 	 */
493 	int (*release_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code);
494 	/** @brief Callback function for bt_a2dp_stream_release()
495 	 *
496 	 *  Called when the release operation is completed.
497 	 *  (release cmd and release the l2cap channel)
498 	 *
499 	 *  @param[in] stream    Pointer to stream object.
500 	 *  @param[in] rsp_err_code the remote responded error code
501 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
502 	 */
503 	void (*release_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code);
504 	/**
505 	 * @brief Stream start request callback
506 	 *
507 	 * The callback is called whenever an stream is requested to be
508 	 * started.
509 	 *
510 	 *  @param[in] stream    Pointer to stream object.
511 	 *  @param[out] rsp_err_code  give the error code if response error.
512 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
513 	 *
514 	 * @return 0 in case of success or negative value in case of error.
515 	 */
516 	int (*start_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code);
517 	/** @brief Callback function for bt_a2dp_stream_start()
518 	 *
519 	 *  Called when the start operation is completed.
520 	 *
521 	 *  @param[in] stream    Pointer to stream object.
522 	 *  @param[in] rsp_err_code the remote responded error code
523 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
524 	 */
525 	void (*start_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code);
526 	/**
527 	 * @brief Stream suspend request callback
528 	 *
529 	 * The callback is called whenever an stream is requested to be
530 	 * suspended.
531 	 *
532 	 *  @param[in] stream    Pointer to stream object.
533 	 *  @param[out] rsp_err_code  give the error code if response error.
534 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
535 	 *
536 	 * @return 0 in case of success or negative value in case of error.
537 	 */
538 	int (*suspend_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code);
539 	/** @brief Callback function for bt_a2dp_stream_suspend()
540 	 *
541 	 *  Called when the suspend operation is completed.
542 	 *
543 	 *  @param[in] stream    Pointer to stream object.
544 	 *  @param[in] rsp_err_code the remote responded error code
545 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
546 	 */
547 	void (*suspend_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code);
548 	/**
549 	 * @brief Stream abort request callback
550 	 *
551 	 * The callback is called whenever an stream is requested to be
552 	 * aborted.
553 	 *
554 	 *  @param[in] stream    Pointer to stream object.
555 	 *  @param[out] rsp_err_code  give the error code if response error.
556 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
557 	 *
558 	 * @return 0 in case of success or negative value in case of error.
559 	 */
560 	int (*abort_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code);
561 	/** @brief Callback function for bt_a2dp_stream_abort()
562 	 *
563 	 *  Called when the abort operation is completed.
564 	 *
565 	 *  @param[in] stream    Pointer to stream object.
566 	 *  @param[in] rsp_err_code the remote responded error code
567 	 *                          bt_a2dp_err_code or bt_avdtp_err_code
568 	 */
569 	void (*abort_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code);
570 };
571 
572 /** @brief A2DP Connect.
573  *
574  *  This function is to be called after the conn parameter is obtained by
575  *  performing a GAP procedure. The API is to be used to establish A2DP
576  *  connection between devices.
577  *  This function only establish AVDTP L2CAP Signaling connection.
578  *  After connection success, the callback that is registered by
579  *  bt_a2dp_register_connect_callback is called.
580  *
581  *  @param conn Pointer to bt_conn structure.
582  *
583  *  @return pointer to struct bt_a2dp in case of success or NULL in case
584  *  of error.
585  */
586 struct bt_a2dp *bt_a2dp_connect(struct bt_conn *conn);
587 
588 /** @brief disconnect l2cap a2dp
589  *
590  * This function close AVDTP L2CAP Signaling connection.
591  * It closes the AVDTP L2CAP Media connection too if it is established.
592  *
593  *  @param a2dp The a2dp instance.
594  *
595  *  @return 0 in case of success and error code in case of error.
596  */
597 int bt_a2dp_disconnect(struct bt_a2dp *a2dp);
598 
599 /** @brief Endpoint Registration.
600  *
601  *  @param ep Pointer to bt_a2dp_ep structure.
602  *  @param media_type Media type that the Endpoint is, #bt_avdtp_media_type.
603  *  @param sep_type Stream endpoint type, #bt_avdtp_sep_type.
604  *
605  *  @return 0 in case of success and error code in case of error.
606  */
607 int bt_a2dp_register_ep(struct bt_a2dp_ep *ep, uint8_t media_type, uint8_t sep_type);
608 
609 /** @brief register callback.
610  *
611  *  The cb is called when bt_a2dp_connect is called or it is operated by remote device.
612  *
613  *  @param cb The callback function.
614  *
615  *  @return 0 in case of success and error code in case of error.
616  */
617 int bt_a2dp_register_cb(struct bt_a2dp_cb *cb);
618 
619 /** @brief Discover remote endpoints.
620  *
621  *  @param a2dp The a2dp instance.
622  *  @param param the discover used param.
623  *
624  *  @return 0 in case of success and error code in case of error.
625  */
626 int bt_a2dp_discover(struct bt_a2dp *a2dp, struct bt_a2dp_discover_param *param);
627 
628 /** @brief A2DP Stream */
629 struct bt_a2dp_stream {
630 	/** local endpoint */
631 	struct bt_a2dp_ep *local_ep;
632 	/** remote endpoint */
633 	struct bt_a2dp_ep *remote_ep;
634 	/** remote endpoint's Stream End Point ID */
635 	uint8_t remote_ep_id;
636 	/** Audio stream operations */
637 	struct bt_a2dp_stream_ops *ops;
638 	/** the a2dp connection */
639 	struct bt_a2dp *a2dp;
640 	/** the stream current configuration */
641 	struct bt_a2dp_codec_ie codec_config;
642 };
643 
644 /** @brief The stream endpoint related operations */
645 struct bt_a2dp_stream_ops {
646 	/**
647 	 * @brief Stream configured callback
648 	 *
649 	 * The callback is called whenever an Audio Stream has been configured or reconfigured.
650 	 *
651 	 * @param stream Stream object that has been configured.
652 	 */
653 	void (*configured)(struct bt_a2dp_stream *stream);
654 	/**
655 	 * @brief Stream establishment callback
656 	 *
657 	 * The callback is called whenever an Audio Stream has been established.
658 	 *
659 	 * @param stream Stream object that has been established.
660 	 */
661 	void (*established)(struct bt_a2dp_stream *stream);
662 	/**
663 	 * @brief Stream release callback
664 	 *
665 	 * The callback is called whenever an Audio Stream has been released.
666 	 * After released, the stream becomes invalid.
667 	 *
668 	 * @param stream Stream object that has been released.
669 	 */
670 	void (*released)(struct bt_a2dp_stream *stream);
671 	/**
672 	 * @brief Stream start callback
673 	 *
674 	 * The callback is called whenever an Audio Stream has been started.
675 	 *
676 	 * @param stream Stream object that has been started.
677 	 */
678 	void (*started)(struct bt_a2dp_stream *stream);
679 	/**
680 	 * @brief Stream suspend callback
681 	 *
682 	 * The callback is called whenever an Audio Stream has been suspended.
683 	 *
684 	 * @param stream Stream object that has been suspended.
685 	 */
686 	void (*suspended)(struct bt_a2dp_stream *stream);
687 	/**
688 	 * @brief Stream abort callback
689 	 *
690 	 * The callback is called whenever an Audio Stream has been aborted.
691 	 * After aborted, the stream becomes invalid.
692 	 *
693 	 * @param stream Stream object that has been aborted.
694 	 */
695 	void (*aborted)(struct bt_a2dp_stream *stream);
696 #if defined(CONFIG_BT_A2DP_SINK)
697 	/** @brief the media streaming data, only for sink
698 	 *
699 	 *  @param buf the data buf
700 	 *  @param seq_num the sequence number
701 	 *  @param ts the time stamp
702 	 */
703 	void (*recv)(struct bt_a2dp_stream *stream, struct net_buf *buf, uint16_t seq_num,
704 		     uint32_t ts);
705 #endif
706 #if defined(CONFIG_BT_A2DP_SOURCE)
707 	/**
708 	 * @brief Stream audio HCI sent callback
709 	 *
710 	 * This callback will be called once the controller marks the SDU
711 	 * as completed. When the controller does so is implementation
712 	 * dependent. It could be after the SDU is enqueued for transmission,
713 	 * or after it is sent on air or flushed.
714 	 *
715 	 * This callback is only used if the ISO data path is HCI.
716 	 *
717 	 * @param stream Stream object.
718 	 */
719 	void (*sent)(struct bt_a2dp_stream *stream);
720 #endif
721 };
722 
723 /**
724  * @brief Register Audio callbacks for a stream.
725  *
726  * Register Audio callbacks for a stream.
727  *
728  * @param stream Stream object.
729  * @param ops    Stream operations structure.
730  */
731 void bt_a2dp_stream_cb_register(struct bt_a2dp_stream *stream, struct bt_a2dp_stream_ops *ops);
732 
733 /** @brief configure endpoint.
734  *
735  *  bt_a2dp_discover can be used to find remote's endpoints.
736  *  This function to configure the selected endpoint that is found by
737  *  bt_a2dp_discover.
738  *  This function sends AVDTP_SET_CONFIGURATION.
739  *
740  *  @param a2dp The a2dp instance.
741  *  @param stream Stream object.
742  *  @param local_ep The configured endpoint that is registered.
743  *  @param remote_ep The remote endpoint.
744  *  @param config The config to configure the endpoint.
745  *
746  *  @return 0 in case of success and error code in case of error.
747  */
748 int bt_a2dp_stream_config(struct bt_a2dp *a2dp, struct bt_a2dp_stream *stream,
749 			  struct bt_a2dp_ep *local_ep, struct bt_a2dp_ep *remote_ep,
750 			  struct bt_a2dp_codec_cfg *config);
751 
752 /** @brief establish a2dp streamer.
753  *
754  * This function sends the AVDTP_OPEN command and create the l2cap channel.
755  *
756  *  @param stream The stream object.
757  *
758  *  @return 0 in case of success and error code in case of error.
759  */
760 int bt_a2dp_stream_establish(struct bt_a2dp_stream *stream);
761 
762 /** @brief release a2dp streamer.
763  *
764  * This function sends the AVDTP_CLOSE command and release the l2cap channel.
765  * After release, the stream becomes invalid.
766  *
767  *  @param stream The stream object.
768  *
769  *  @return 0 in case of success and error code in case of error.
770  */
771 int bt_a2dp_stream_release(struct bt_a2dp_stream *stream);
772 
773 /** @brief start a2dp streamer.
774  *
775  * This function sends the AVDTP_START command.
776  *
777  *  @param stream The stream object.
778  *
779  *  @return 0 in case of success and error code in case of error.
780  */
781 int bt_a2dp_stream_start(struct bt_a2dp_stream *stream);
782 
783 /** @brief suspend a2dp streamer.
784  *
785  * This function sends the AVDTP_SUSPEND command.
786  *
787  *  @param stream The stream object.
788  *
789  *  @return 0 in case of success and error code in case of error.
790  */
791 int bt_a2dp_stream_suspend(struct bt_a2dp_stream *stream);
792 
793 /** @brief re-configure a2dp streamer
794  *
795  * This function sends the AVDTP_RECONFIGURE command.
796  *
797  *  @param stream The stream object.
798  *  @param config The config to configure the stream.
799  *
800  *  @return 0 in case of success and error code in case of error.
801  */
802 int bt_a2dp_stream_reconfig(struct bt_a2dp_stream *stream, struct bt_a2dp_codec_cfg *config);
803 
804 /** @brief abort a2dp streamer.
805  *
806  * This function sends the AVDTP_ABORT command.
807  * After abort, the stream becomes invalid.
808  *
809  *  @param stream The stream object.
810  *
811  *  @return 0 in case of success and error code in case of error.
812  */
813 int bt_a2dp_stream_abort(struct bt_a2dp_stream *stream);
814 
815 /** @brief get the stream l2cap mtu
816  *
817  *  @param stream The stream object.
818  *
819  *  @return mtu value
820  */
821 uint32_t bt_a2dp_get_mtu(struct bt_a2dp_stream *stream);
822 
823 #if defined(CONFIG_BT_A2DP_SOURCE)
824 /** @brief send a2dp media data
825  *
826  * Only A2DP source side can call this function.
827  *
828  *  @param stream The stream object.
829  *  @param buf  The data.
830  *  @param seq_num The sequence number.
831  *  @param ts The time stamp.
832  *
833  *  @return 0 in case of success and error code in case of error.
834  */
835 int bt_a2dp_stream_send(struct bt_a2dp_stream *stream, struct net_buf *buf, uint16_t seq_num,
836 			uint32_t ts);
837 #endif
838 
839 #ifdef __cplusplus
840 }
841 #endif
842 
843 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_A2DP_H_ */
844