/** @file * @brief Advanced Audio Distribution Profile header. */ /* * Copyright (c) 2015-2016 Intel Corporation * Copyright 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_A2DP_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_A2DP_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define BT_A2DP_STREAM_BUF_RESERVE (12U + BT_L2CAP_BUF_SIZE(0)) /** SBC IE length */ #define BT_A2DP_SBC_IE_LENGTH (4U) /** MPEG1,2 IE length */ #define BT_A2DP_MPEG_1_2_IE_LENGTH (4U) /** MPEG2,4 IE length */ #define BT_A2DP_MPEG_2_4_IE_LENGTH (6U) /** The max IE (Codec Info Element) length */ #define BT_A2DP_MAX_IE_LENGTH (8U) /** @brief define the audio endpoint * @param _role BT_AVDTP_SOURCE or BT_AVDTP_SINK. * @param _codec value of enum bt_a2dp_codec_id. * @param _capability the codec capability. */ #define BT_A2DP_EP_INIT(_role, _codec, _capability) \ { \ .codec_type = _codec, \ .sep = {.sep_info = {.media_type = BT_AVDTP_AUDIO, .tsep = _role}}, \ .codec_cap = _capability, .stream = NULL, \ } /** @brief define the audio sink endpoint * @param _codec value of enum bt_a2dp_codec_id. * @param _capability the codec capability. */ #define BT_A2DP_SINK_EP_INIT(_codec, _capability) \ BT_A2DP_EP_INIT(BT_AVDTP_SINK, _codec, _capability) /** @brief define the audio source endpoint * @param _codec value of enum bt_a2dp_codec_id. * @param _capability the codec capability. */ #define BT_A2DP_SOURCE_EP_INIT(_codec, _capability) \ BT_A2DP_EP_INIT(BT_AVDTP_SOURCE, _codec, _capability) /** @brief define the SBC sink endpoint that can be used as * bt_a2dp_register_endpoint's parameter. * * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SINK_EP_DEFAULT * is more convenient for user to register SBC endpoint. * * @param _name unique structure name postfix. * @param _freq sbc codec frequency. * for example: A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 * @param _ch_mode sbc codec channel mode. * for example: A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO * @param _blk_len sbc codec block length. * for example: A2DP_SBC_BLK_LEN_16 * @param _subband sbc codec subband. * for example: A2DP_SBC_SUBBAND_8 * @param _alloc_mthd sbc codec allocate method. * for example: A2DP_SBC_ALLOC_MTHD_LOUDNESS * @param _min_bitpool sbc codec min bit pool. for example: 18 * @param _max_bitpool sbc codec max bit pool. for example: 35 * @ */ #define BT_A2DP_SBC_SINK_EP(_name, _freq, _ch_mode, _blk_len, _subband, _alloc_mthd, _min_bitpool, \ _max_bitpool) \ static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ .len = BT_A2DP_SBC_IE_LENGTH, \ .codec_ie = {_freq | _ch_mode, _blk_len | _subband | _alloc_mthd, _min_bitpool, \ _max_bitpool}}; \ static struct bt_a2dp_ep _name = \ BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC, (&bt_a2dp_ep_cap_ie##_name)) /** @brief define the SBC source endpoint that can be used as bt_a2dp_register_endpoint's * parameter. * * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SOURCE_EP_DEFAULT * is more convenient for user to register SBC endpoint. * * @param _name the endpoint variable name. * @param _freq sbc codec frequency. * for example: A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 * @param _ch_mode sbc codec channel mode. * for example: A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO * @param _blk_len sbc codec block length. * for example: A2DP_SBC_BLK_LEN_16 * @param _subband sbc codec subband. * for example: A2DP_SBC_SUBBAND_8 * @param _alloc_mthd sbc codec allocate method. * for example: A2DP_SBC_ALLOC_MTHD_LOUDNESS * @param _min_bitpool sbc codec min bit pool. for example: 18 * @param _max_bitpool sbc codec max bit pool. for example: 35 */ #define BT_A2DP_SBC_SOURCE_EP(_name, _freq, _ch_mode, _blk_len, _subband, _alloc_mthd, \ _min_bitpool, _max_bitpool) \ static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ .len = BT_A2DP_SBC_IE_LENGTH, \ .codec_ie = {_freq | _ch_mode, _blk_len | _subband | _alloc_mthd, _min_bitpool, \ _max_bitpool}}; \ static struct bt_a2dp_ep _name = \ BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name) /** @brief define the default SBC sink endpoint that can be used as * bt_a2dp_register_endpoint's parameter. * * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SINK_EP_DEFAULT * is more convenient for user to register SBC endpoint. * * @param _name the endpoint variable name. */ #define BT_A2DP_SBC_SINK_EP_DEFAULT(_name) \ static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ .len = BT_A2DP_SBC_IE_LENGTH, \ .codec_ie = {A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 | \ A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO | \ A2DP_SBC_CH_MODE_JOINT, \ A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | \ A2DP_SBC_ALLOC_MTHD_LOUDNESS, \ 18U, 35U}}; \ static struct bt_a2dp_ep _name = \ BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name) /** @brief define the default SBC source endpoint that can be used as bt_a2dp_register_endpoint's * parameter. * * SBC is mandatory as a2dp specification, BT_A2DP_SBC_SOURCE_EP_DEFAULT * is more convenient for user to register SBC endpoint. * * @param _name the endpoint variable name. */ #define BT_A2DP_SBC_SOURCE_EP_DEFAULT(_name) \ static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ .len = BT_A2DP_SBC_IE_LENGTH, \ .codec_ie = {A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 | \ A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO | \ A2DP_SBC_CH_MODE_JOINT, \ A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | \ A2DP_SBC_ALLOC_MTHD_LOUDNESS, \ 18U, 35U}, \ }; \ static struct bt_a2dp_ep _name = \ BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name) /** @brief define the SBC default configuration. * * @param _name unique structure name postfix. * @param _freq_cfg sbc codec frequency. * for example: A2DP_SBC_SAMP_FREQ_44100 * @param _ch_mode_cfg sbc codec channel mode. * for example: A2DP_SBC_CH_MODE_JOINT * @param _blk_len_cfg sbc codec block length. * for example: A2DP_SBC_BLK_LEN_16 * @param _subband_cfg sbc codec subband. * for example: A2DP_SBC_SUBBAND_8 * @param _alloc_mthd_cfg sbc codec allocate method. * for example: A2DP_SBC_ALLOC_MTHD_LOUDNESS * @param _min_bitpool_cfg sbc codec min bit pool. for example: 18 * @param _max_bitpool_cfg sbc codec max bit pool. for example: 35 */ #define BT_A2DP_SBC_EP_CFG(_name, _freq_cfg, _ch_mode_cfg, _blk_len_cfg, _subband_cfg, \ _alloc_mthd_cfg, _min_bitpool_cfg, _max_bitpool_cfg) \ static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = { \ .len = BT_A2DP_SBC_IE_LENGTH, \ .codec_ie = {_freq_cfg | _ch_mode_cfg, \ _blk_len_cfg | _subband_cfg | _alloc_mthd_cfg, _min_bitpool_cfg, \ _max_bitpool_cfg}, \ }; \ struct bt_a2dp_codec_cfg _name = { \ .codec_config = &bt_a2dp_codec_ie##_name, \ } /** @brief define the SBC default configuration. * * @param _name unique structure name postfix. * @param _freq_cfg the frequency to configure the remote same codec type endpoint. */ #define BT_A2DP_SBC_EP_CFG_DEFAULT(_name, _freq_cfg) \ static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = { \ .len = BT_A2DP_SBC_IE_LENGTH, \ .codec_ie = {_freq_cfg | A2DP_SBC_CH_MODE_JOINT, \ A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | \ A2DP_SBC_ALLOC_MTHD_LOUDNESS, \ 18U, 35U}, \ }; \ struct bt_a2dp_codec_cfg _name = { \ .codec_config = &bt_a2dp_codec_ie##_name, \ } /** * @brief A2DP error code */ enum bt_a2dp_err_code { /** Media Codec Type is not valid */ BT_A2DP_INVALID_CODEC_TYPE = 0xC1, /** Media Codec Type is not supported */ BT_A2DP_NOT_SUPPORTED_CODEC_TYPE = 0xC2, /** Sampling Frequency is not valid or multiple values have been selected */ BT_A2DP_INVALID_SAMPLING_FREQUENCY = 0xC3, /** Sampling Frequency is not supported */ BT_A2DP_NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4, /** Channel Mode is not valid or multiple values have been selected */ BT_A2DP_INVALID_CHANNEL_MODE = 0xC5, /** Channel Mode is not supported */ BT_A2DP_NOT_SUPPORTED_CHANNEL_MODE = 0xC6, /** None or multiple values have been selected for Number of Subbands */ BT_A2DP_INVALID_SUBBANDS = 0xC7, /** Number of Subbands is not supported */ BT_A2DP_NOT_SUPPORTED_SUBBANDS = 0xC8, /** None or multiple values have been selected for Allocation Method */ BT_A2DP_INVALID_ALLOCATION_METHOD = 0xC9, /** Allocation Method is not supported */ BT_A2DP_NOT_SUPPORTED_ALLOCATION_METHOD = 0xCA, /** Minimum Bitpool Value is not valid */ BT_A2DP_INVALID_MINIMUM_BITPOOL_VALUE = 0xCB, /** Minimum Bitpool Value is not supported */ BT_A2DP_NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCC, /** Maximum Bitpool Value is not valid */ BT_A2DP_INVALID_MAXIMUM_BITPOOL_VALUE = 0xCD, /** Maximum Bitpool Value is not supported */ BT_A2DP_NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCE, /** None or multiple values have been selected for Layer */ BT_A2DP_INVALID_LAYER = 0xCF, /** Layer is not supported */ BT_A2DP_NOT_SUPPORTED_LAYER = 0xD0, /** CRC is not supported */ BT_A2DP_NOT_SUPPORTED_CRC = 0xD1, /** MPF-2 is not supported */ BT_A2DP_NOT_SUPPORTED_MPF = 0xD2, /** VBR is not supported */ BT_A2DP_NOT_SUPPORTED_VBR = 0xD3, /** None or multiple values have been selected for Bit Rate */ BT_A2DP_INVALID_BIT_RATE = 0xD4, /** Bit Rate is not supported */ BT_A2DP_NOT_SUPPORTED_BIT_RATE = 0xD5, /** Either 1) Object type is not valid or * 2) None or multiple values have been selected for Object Type */ BT_A2DP_INVALID_OBJECT_TYPE = 0xD6, /** Object Type is not supported */ BT_A2DP_NOT_SUPPORTED_OBJECT_TYPE = 0xD7, /** Either 1) Channels is not valid or * 2) None or multiple values have been selected for Channels */ BT_A2DP_INVALID_CHANNELS = 0xD8, /** Channels is not supported */ BT_A2DP_NOT_SUPPORTED_CHANNELS = 0xD9, /** Version is not valid */ BT_A2DP_INVALID_VERSION = 0xDA, /** Version is not supported */ BT_A2DP_NOT_SUPPORTED_VERSION = 0xDB, /** Maximum SUL is not acceptable for the Decoder in the SNK */ BT_A2DP_NOT_SUPPORTED_MAXIMUM_SUL = 0xDC, /** None or multiple values have been selected for Block Length */ BT_A2DP_INVALID_BLOCK_LENGTH = 0xDD, /** The requested CP Type is not supported */ BT_A2DP_INVALID_CP_TYPE = 0xE0, /** The format of Content Protection Service Capability/Content * Protection Scheme Dependent Data is not correct */ BT_A2DP_INVALID_CP_FORMAT = 0xE1, /** The codec parameter is invalid. * Used if a more specific error code does not exist for the codec in use */ BT_A2DP_INVALID_CODEC_PARAMETER = 0xE2, /** The codec parameter is not supported. * Used if a more specific error code does not exist for the codec in use */ BT_A2DP_NOT_SUPPORTED_CODEC_PARAMETER = 0xE3, /** Combination of Object Type and DRC is invalid */ BT_A2DP_INVALID_DRC = 0xE4, /** DRC is not supported */ BT_A2DP_NOT_SUPPORTED_DRC = 0xE5, }; /** @brief Codec Type */ enum bt_a2dp_codec_type { /** Codec SBC */ BT_A2DP_SBC = 0x00, /** Codec MPEG-1 */ BT_A2DP_MPEG1 = 0x01, /** Codec MPEG-2 */ BT_A2DP_MPEG2 = 0x02, /** Codec ATRAC */ BT_A2DP_ATRAC = 0x04, /** Codec Non-A2DP */ BT_A2DP_VENDOR = 0xff }; /** @brief A2DP structure */ struct bt_a2dp; /* Internal to pass build */ struct bt_a2dp_stream; /** @brief codec information elements for the endpoint */ struct bt_a2dp_codec_ie { /** Length of codec_cap */ uint8_t len; /** codec information element */ uint8_t codec_ie[BT_A2DP_MAX_IE_LENGTH]; }; /** @brief The endpoint configuration */ struct bt_a2dp_codec_cfg { /** The media codec configuration content */ struct bt_a2dp_codec_ie *codec_config; }; /** @brief Stream End Point */ struct bt_a2dp_ep { /** Code Type @ref bt_a2dp_codec_type */ uint8_t codec_type; /** Capabilities */ struct bt_a2dp_codec_ie *codec_cap; /** AVDTP Stream End Point Identifier */ struct bt_avdtp_sep sep; /* Internally used stream object pointer */ struct bt_a2dp_stream *stream; }; struct bt_a2dp_ep_info { /** Code Type @ref bt_a2dp_codec_type */ uint8_t codec_type; /** Codec capabilities, if SBC, use function of a2dp_codec_sbc.h to parse it */ struct bt_a2dp_codec_ie codec_cap; /** Stream End Point Information */ struct bt_avdtp_sep_info sep_info; }; /** @brief Helper enum to be used as return value of bt_a2dp_discover_ep_cb. * The value informs the caller to perform further pending actions or stop them. */ enum { BT_A2DP_DISCOVER_EP_STOP = 0, BT_A2DP_DISCOVER_EP_CONTINUE, }; /** @typedef bt_a2dp_discover_ep_cb * * @brief Called when a stream endpoint is discovered. * * A function of this type is given by the user to the bt_a2dp_discover_param * object. It'll be called on each valid stream endpoint discovery completion. * When no more endpoint then NULL is passed to the user. Otherwise user can get * valid endpoint information from parameter info, user can set parameter ep to * get the endpoint after the callback is return. * The returned function value allows the user to control retrieving follow-up * endpoints if any. If the user doesn't want to read more endpoints since * current found endpoints fulfill its requirements then should return * BT_A2DP_DISCOVER_EP_STOP. Otherwise returned value means * more subcall iterations are allowable. * * @param a2dp a2dp connection object identifying a2dp connection to queried remote. * @param info Object pointing to the information of the callbacked endpoint. * @param ep If the user want to use this found endpoint, user can set value to it * to get the endpoint that can be used further in other A2DP APIs. It is NULL if info * is NULL (no more endpoint is found). * * @return BT_A2DP_DISCOVER_EP_STOP in case of no more need to continue discovery * for next endpoint. By returning BT_A2DP_DISCOVER_EP_STOP user allows this * discovery continuation. */ typedef uint8_t (*bt_a2dp_discover_ep_cb)(struct bt_a2dp *a2dp, struct bt_a2dp_ep_info *info, struct bt_a2dp_ep **ep); struct bt_a2dp_discover_param { /** discover callback */ bt_a2dp_discover_ep_cb cb; /** The discovered endpoint info that is callbacked by cb */ struct bt_a2dp_ep_info info; /** The max count of remote endpoints that can be got, * it save endpoint info internally. */ struct bt_avdtp_sep_info *seps_info; /** The max count of seps (stream endpoint) that can be got in this call route */ uint8_t sep_count; }; /** @brief The connecting callback */ struct bt_a2dp_cb { /** @brief A a2dp connection has been established. * * This callback notifies the application of a a2dp connection. * It means the AVDTP L2CAP connection. * In case the err parameter is non-zero it means that the * connection establishment failed. * * @param a2dp a2dp connection object. * @param err error code. */ void (*connected)(struct bt_a2dp *a2dp, int err); /** @brief A a2dp connection has been disconnected. * * This callback notifies the application that a a2dp connection * has been disconnected. * * @param a2dp a2dp connection object. */ void (*disconnected)(struct bt_a2dp *a2dp); /** * @brief Endpoint config request callback * * The callback is called whenever an endpoint is requested to be * configured. * * @param a2dp a2dp connection object. * @param[in] ep Local Audio Endpoint being configured. * @param[in] codec_cfg Codec configuration. * @param[out] stream Pointer to stream that will be configured for the endpoint. * @param[out] rsp_err_code give the error code if response error. * bt_a2dp_err_code or bt_avdtp_err_code * * @return 0 in case of success or negative value in case of error. */ int (*config_req)(struct bt_a2dp *a2dp, struct bt_a2dp_ep *ep, struct bt_a2dp_codec_cfg *codec_cfg, struct bt_a2dp_stream **stream, uint8_t *rsp_err_code); /** * @brief Endpoint config request callback * * The callback is called whenever an endpoint is requested to be * reconfigured. * * @param[in] stream Pointer to stream object. * @param[out] rsp_err_code give the error code if response error. * bt_a2dp_err_code or bt_avdtp_err_code * * @return 0 in case of success or negative value in case of error. */ int (*reconfig_req)(struct bt_a2dp_stream *stream, struct bt_a2dp_codec_cfg *codec_cfg, uint8_t *rsp_err_code); /** @brief Callback function for bt_a2dp_stream_config() and bt_a2dp_stream_reconfig() * * Called when the codec configure operation is completed. * * @param[in] stream Pointer to stream object. * @param[in] rsp_err_code the remote responded error code * bt_a2dp_err_code or bt_avdtp_err_code */ void (*config_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** * @brief Stream establishment request callback * * The callback is called whenever an stream is requested to be * established (open cmd and create the stream l2cap channel). * * @param[in] stream Pointer to stream object. * @param[out] rsp_err_code give the error code if response error. * bt_a2dp_err_code or bt_avdtp_err_code * * @return 0 in case of success or negative value in case of error. */ int (*establish_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code); /** @brief Callback function for bt_a2dp_stream_establish() * * Called when the establishment operation is completed. * (open cmd and create the stream l2cap channel). * * @param[in] stream Pointer to stream object. * @param[in] rsp_err_code the remote responded error code * bt_a2dp_err_code or bt_avdtp_err_code */ void (*establish_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** * @brief Stream release request callback * * The callback is called whenever an stream is requested to be * released (release cmd and release the l2cap channel) * * @param[in] stream Pointer to stream object. * @param[out] rsp_err_code give the error code if response error. * bt_a2dp_err_code or bt_avdtp_err_code * * @return 0 in case of success or negative value in case of error. */ int (*release_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code); /** @brief Callback function for bt_a2dp_stream_release() * * Called when the release operation is completed. * (release cmd and release the l2cap channel) * * @param[in] stream Pointer to stream object. * @param[in] rsp_err_code the remote responded error code * bt_a2dp_err_code or bt_avdtp_err_code */ void (*release_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** * @brief Stream start request callback * * The callback is called whenever an stream is requested to be * started. * * @param[in] stream Pointer to stream object. * @param[out] rsp_err_code give the error code if response error. * bt_a2dp_err_code or bt_avdtp_err_code * * @return 0 in case of success or negative value in case of error. */ int (*start_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code); /** @brief Callback function for bt_a2dp_stream_start() * * Called when the start operation is completed. * * @param[in] stream Pointer to stream object. * @param[in] rsp_err_code the remote responded error code * bt_a2dp_err_code or bt_avdtp_err_code */ void (*start_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** * @brief Stream suspend request callback * * The callback is called whenever an stream is requested to be * suspended. * * @param[in] stream Pointer to stream object. * @param[out] rsp_err_code give the error code if response error. * bt_a2dp_err_code or bt_avdtp_err_code * * @return 0 in case of success or negative value in case of error. */ int (*suspend_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code); /** @brief Callback function for bt_a2dp_stream_suspend() * * Called when the suspend operation is completed. * * @param[in] stream Pointer to stream object. * @param[in] rsp_err_code the remote responded error code * bt_a2dp_err_code or bt_avdtp_err_code */ void (*suspend_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** * @brief Stream abort request callback * * The callback is called whenever an stream is requested to be * aborted. * * @param[in] stream Pointer to stream object. * @param[out] rsp_err_code give the error code if response error. * bt_a2dp_err_code or bt_avdtp_err_code * * @return 0 in case of success or negative value in case of error. */ int (*abort_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code); /** @brief Callback function for bt_a2dp_stream_abort() * * Called when the abort operation is completed. * * @param[in] stream Pointer to stream object. * @param[in] rsp_err_code the remote responded error code * bt_a2dp_err_code or bt_avdtp_err_code */ void (*abort_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); }; /** @brief A2DP Connect. * * This function is to be called after the conn parameter is obtained by * performing a GAP procedure. The API is to be used to establish A2DP * connection between devices. * This function only establish AVDTP L2CAP Signaling connection. * After connection success, the callback that is registered by * bt_a2dp_register_connect_callback is called. * * @param conn Pointer to bt_conn structure. * * @return pointer to struct bt_a2dp in case of success or NULL in case * of error. */ struct bt_a2dp *bt_a2dp_connect(struct bt_conn *conn); /** @brief disconnect l2cap a2dp * * This function close AVDTP L2CAP Signaling connection. * It closes the AVDTP L2CAP Media connection too if it is established. * * @param a2dp The a2dp instance. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_disconnect(struct bt_a2dp *a2dp); /** @brief Endpoint Registration. * * @param ep Pointer to bt_a2dp_ep structure. * @param media_type Media type that the Endpoint is, #bt_avdtp_media_type. * @param sep_type Stream endpoint type, #bt_avdtp_sep_type. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_register_ep(struct bt_a2dp_ep *ep, uint8_t media_type, uint8_t sep_type); /** @brief register callback. * * The cb is called when bt_a2dp_connect is called or it is operated by remote device. * * @param cb The callback function. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_register_cb(struct bt_a2dp_cb *cb); /** @brief Discover remote endpoints. * * @param a2dp The a2dp instance. * @param param the discover used param. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_discover(struct bt_a2dp *a2dp, struct bt_a2dp_discover_param *param); /** @brief A2DP Stream */ struct bt_a2dp_stream { /** local endpoint */ struct bt_a2dp_ep *local_ep; /** remote endpoint */ struct bt_a2dp_ep *remote_ep; /** remote endpoint's Stream End Point ID */ uint8_t remote_ep_id; /** Audio stream operations */ struct bt_a2dp_stream_ops *ops; /** the a2dp connection */ struct bt_a2dp *a2dp; /** the stream current configuration */ struct bt_a2dp_codec_ie codec_config; }; /** @brief The stream endpoint related operations */ struct bt_a2dp_stream_ops { /** * @brief Stream configured callback * * The callback is called whenever an Audio Stream has been configured or reconfigured. * * @param stream Stream object that has been configured. */ void (*configured)(struct bt_a2dp_stream *stream); /** * @brief Stream establishment callback * * The callback is called whenever an Audio Stream has been established. * * @param stream Stream object that has been established. */ void (*established)(struct bt_a2dp_stream *stream); /** * @brief Stream release callback * * The callback is called whenever an Audio Stream has been released. * After released, the stream becomes invalid. * * @param stream Stream object that has been released. */ void (*released)(struct bt_a2dp_stream *stream); /** * @brief Stream start callback * * The callback is called whenever an Audio Stream has been started. * * @param stream Stream object that has been started. */ void (*started)(struct bt_a2dp_stream *stream); /** * @brief Stream suspend callback * * The callback is called whenever an Audio Stream has been suspended. * * @param stream Stream object that has been suspended. */ void (*suspended)(struct bt_a2dp_stream *stream); /** * @brief Stream abort callback * * The callback is called whenever an Audio Stream has been aborted. * After aborted, the stream becomes invalid. * * @param stream Stream object that has been aborted. */ void (*aborted)(struct bt_a2dp_stream *stream); #if defined(CONFIG_BT_A2DP_SINK) /** @brief the media streaming data, only for sink * * @param buf the data buf * @param seq_num the sequence number * @param ts the time stamp */ void (*recv)(struct bt_a2dp_stream *stream, struct net_buf *buf, uint16_t seq_num, uint32_t ts); #endif #if defined(CONFIG_BT_A2DP_SOURCE) /** * @brief Stream audio HCI sent callback * * This callback will be called once the controller marks the SDU * as completed. When the controller does so is implementation * dependent. It could be after the SDU is enqueued for transmission, * or after it is sent on air or flushed. * * This callback is only used if the ISO data path is HCI. * * @param stream Stream object. */ void (*sent)(struct bt_a2dp_stream *stream); #endif }; /** * @brief Register Audio callbacks for a stream. * * Register Audio callbacks for a stream. * * @param stream Stream object. * @param ops Stream operations structure. */ void bt_a2dp_stream_cb_register(struct bt_a2dp_stream *stream, struct bt_a2dp_stream_ops *ops); /** @brief configure endpoint. * * bt_a2dp_discover can be used to find remote's endpoints. * This function to configure the selected endpoint that is found by * bt_a2dp_discover. * This function sends AVDTP_SET_CONFIGURATION. * * @param a2dp The a2dp instance. * @param stream Stream object. * @param local_ep The configured endpoint that is registered. * @param remote_ep The remote endpoint. * @param config The config to configure the endpoint. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_config(struct bt_a2dp *a2dp, struct bt_a2dp_stream *stream, struct bt_a2dp_ep *local_ep, struct bt_a2dp_ep *remote_ep, struct bt_a2dp_codec_cfg *config); /** @brief establish a2dp streamer. * * This function sends the AVDTP_OPEN command and create the l2cap channel. * * @param stream The stream object. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_establish(struct bt_a2dp_stream *stream); /** @brief release a2dp streamer. * * This function sends the AVDTP_CLOSE command and release the l2cap channel. * After release, the stream becomes invalid. * * @param stream The stream object. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_release(struct bt_a2dp_stream *stream); /** @brief start a2dp streamer. * * This function sends the AVDTP_START command. * * @param stream The stream object. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_start(struct bt_a2dp_stream *stream); /** @brief suspend a2dp streamer. * * This function sends the AVDTP_SUSPEND command. * * @param stream The stream object. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_suspend(struct bt_a2dp_stream *stream); /** @brief re-configure a2dp streamer * * This function sends the AVDTP_RECONFIGURE command. * * @param stream The stream object. * @param config The config to configure the stream. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_reconfig(struct bt_a2dp_stream *stream, struct bt_a2dp_codec_cfg *config); /** @brief abort a2dp streamer. * * This function sends the AVDTP_ABORT command. * After abort, the stream becomes invalid. * * @param stream The stream object. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_abort(struct bt_a2dp_stream *stream); /** @brief get the stream l2cap mtu * * @param stream The stream object. * * @return mtu value */ uint32_t bt_a2dp_get_mtu(struct bt_a2dp_stream *stream); #if defined(CONFIG_BT_A2DP_SOURCE) /** @brief send a2dp media data * * Only A2DP source side can call this function. * * @param stream The stream object. * @param buf The data. * @param seq_num The sequence number. * @param ts The time stamp. * * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_send(struct bt_a2dp_stream *stream, struct net_buf *buf, uint16_t seq_num, uint32_t ts); #endif #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_BLUETOOTH_A2DP_H_ */