feat(ble_audio): Support ISO & LE Audio functionalities (Preview)

This commit is contained in:
Linyan Liu
2026-04-17 09:46:23 +08:00
committed by BOT
parent 15a0d3fdea
commit 3ef5da096a
383 changed files with 155035 additions and 5 deletions
@@ -0,0 +1,359 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_aics_api.h"
#if CONFIG_BT_AICS
esp_ble_audio_aics_t *esp_ble_audio_aics_free_instance_get(void)
{
return bt_aics_free_instance_get_safe();
}
void *esp_ble_audio_aics_svc_decl_get(esp_ble_audio_aics_t *aics)
{
if (aics == NULL) {
return NULL;
}
return bt_aics_svc_decl_get_safe(aics);
}
esp_err_t esp_ble_audio_aics_register(esp_ble_audio_aics_t *aics,
esp_ble_audio_aics_register_param_t *param)
{
int err;
if (aics == NULL || param == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (param->mute > ESP_BLE_AUDIO_AICS_STATE_MUTE_DISABLED ||
param->gain_mode > ESP_BLE_AUDIO_AICS_MODE_AUTO ||
param->type > ESP_BLE_AUDIO_AICS_INPUT_TYPE_AMBIENT ||
param->units == 0 ||
param->min_gain > param->max_gain ||
param->gain < param->min_gain ||
param->gain > param->max_gain) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_register_safe(aics, param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_activate(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_activate_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_deactivate(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_deactivate_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_AICS */
#if CONFIG_BT_AICS || CONFIG_BT_AICS_CLIENT
esp_err_t esp_ble_audio_aics_state_get(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_state_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_gain_setting_get(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_gain_setting_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_type_get(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_type_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_status_get(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_status_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_disable_mute(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_disable_mute_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_unmute(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_unmute_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_mute(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_mute_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_gain_set_manual_only(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_gain_set_manual_only_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_gain_set_auto_only(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_gain_set_auto_only_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_manual_gain_set(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_manual_gain_set_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_automatic_gain_set(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_automatic_gain_set_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_gain_set(esp_ble_audio_aics_t *inst, int8_t gain)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_gain_set_safe(inst, gain);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_description_get(esp_ble_audio_aics_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_description_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_aics_description_set(esp_ble_audio_aics_t *inst,
const char *description)
{
int err;
if (inst == NULL || description == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_aics_description_set_safe(inst, description);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_AICS || CONFIG_BT_AICS_CLIENT */
#if CONFIG_BT_AICS_CLIENT
esp_err_t esp_ble_audio_aics_discover(uint16_t conn_handle, esp_ble_audio_aics_t *inst,
const esp_ble_audio_aics_discover_param_t *param)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (inst == NULL || param == NULL ||
param->end_handle <= param->start_handle) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_aics_discover(conn, inst, param);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_ble_audio_aics_t *esp_ble_audio_aics_client_free_instance_get(void)
{
return bt_aics_client_free_instance_get_safe();
}
esp_err_t esp_ble_audio_aics_client_cb_register(esp_ble_audio_aics_t *inst,
esp_ble_audio_aics_cb_t *cb)
{
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
bt_aics_client_cb_register_safe(inst, cb);
return ESP_OK;
}
#endif /* CONFIG_BT_AICS_CLIENT */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,722 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_cap_api.h"
#if CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER
esp_err_t esp_ble_audio_cap_acceptor_register(const esp_ble_audio_csip_set_member_register_param_t *param,
esp_ble_audio_csip_set_member_svc_inst_t **svc_inst)
{
int err;
if (param == NULL || svc_inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (param->lockable && param->rank == 0) {
/* Rank cannot be 0 if service is lockable */
return ESP_ERR_INVALID_ARG;
}
if (param->rank > param->set_size) {
/* Invalid rank (shall be less than or equal to set_size */
return ESP_ERR_INVALID_ARG;
}
#if CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT > 1
if (param->parent == NULL) {
/* Parent service not provided */
return ESP_ERR_INVALID_ARG;
}
#endif /* CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT > 1 */
err = bt_cap_acceptor_register_safe(param, svc_inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */
#if CONFIG_BT_CAP
esp_err_t esp_ble_audio_cap_stream_ops_register(esp_ble_audio_cap_stream_t *stream,
esp_ble_audio_bap_stream_ops_t *ops)
{
if (stream == NULL || ops == NULL) {
return ESP_ERR_INVALID_ARG;
}
bt_cap_stream_ops_register_safe(stream, ops);
return ESP_OK;
}
#if CONFIG_BT_AUDIO_TX
esp_err_t esp_ble_audio_cap_stream_send(esp_ble_audio_cap_stream_t *stream,
const uint8_t *sdu, uint16_t sdu_len,
uint16_t seq_num)
{
struct net_buf buf = {
/* Note: only data and len are used */
.data = (void *)sdu,
.len = sdu_len,
};
int err;
if (stream == NULL || (!sdu ^ !sdu_len)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_stream_send_safe(stream, &buf, seq_num);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_stream_send_ts(esp_ble_audio_cap_stream_t *stream,
const uint8_t *sdu, uint16_t sdu_len,
uint16_t seq_num, uint32_t ts)
{
struct net_buf buf = {
/* Note: only data and len are used */
.data = (void *)sdu,
.len = sdu_len,
};
int err;
if (stream == NULL || (!sdu ^ !sdu_len)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_stream_send_ts_safe(stream, &buf, seq_num, ts);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_stream_get_tx_sync(esp_ble_audio_cap_stream_t *stream,
esp_ble_iso_tx_info_t *info)
{
int err;
if (stream == NULL || info == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_stream_get_tx_sync_safe(stream, info);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_AUDIO_TX */
#endif /* CONFIG_BT_CAP */
#if CONFIG_BT_BAP_UNICAST_CLIENT
esp_err_t esp_ble_audio_cap_unicast_group_create(const esp_ble_audio_cap_unicast_group_param_t *param,
esp_ble_audio_cap_unicast_group_t **unicast_group)
{
int err;
if (param == NULL || unicast_group == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_unicast_group_create_safe(param, unicast_group);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_unicast_group_reconfig(esp_ble_audio_cap_unicast_group_t *unicast_group,
const esp_ble_audio_cap_unicast_group_param_t *param)
{
int err;
if (unicast_group == NULL || param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_unicast_group_reconfig_safe(unicast_group, param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_unicast_group_add_streams(esp_ble_audio_cap_unicast_group_t *unicast_group,
const esp_ble_audio_cap_unicast_group_stream_pair_param_t params[],
size_t num_param)
{
int err;
if (unicast_group == NULL || params == NULL || num_param == 0) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_unicast_group_add_streams_safe(unicast_group, params, num_param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_unicast_group_delete(esp_ble_audio_cap_unicast_group_t *unicast_group)
{
int err;
if (unicast_group == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_unicast_group_delete_safe(unicast_group);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
#if CONFIG_BT_CAP_INITIATOR
esp_err_t esp_ble_audio_cap_initiator_register_cb(const esp_ble_audio_cap_initiator_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_register_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_unregister_cb(const esp_ble_audio_cap_initiator_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_unregister_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_BAP_UNICAST_CLIENT
esp_err_t esp_ble_audio_cap_initiator_unicast_discover(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_cap_initiator_unicast_discover(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_start(const esp_ble_audio_cap_unicast_audio_start_param_t *param)
{
int err;
if (param == NULL || param->count == 0 || param->stream_params == NULL ||
param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_unicast_audio_start_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_update(const esp_ble_audio_cap_unicast_audio_update_param_t *param)
{
int err;
if (param == NULL || param->count == 0 || param->stream_params == NULL ||
param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_unicast_audio_update_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_stop(const esp_ble_audio_cap_unicast_audio_stop_param_t *param)
{
int err;
if (param == NULL || param->count == 0 || param->streams == NULL ||
param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_unicast_audio_stop_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_cancel(void)
{
int err;
err = bt_cap_initiator_unicast_audio_cancel_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
#if CONFIG_BT_BAP_BROADCAST_SOURCE
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_create(const esp_ble_audio_cap_initiator_broadcast_create_param_t *param,
esp_ble_audio_cap_broadcast_source_t **broadcast_source)
{
int err;
if (param == NULL || broadcast_source == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_broadcast_audio_create_safe(param, broadcast_source);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_start(esp_ble_audio_cap_broadcast_source_t *broadcast_source,
uint8_t adv_handle)
{
esp_err_t ret = ESP_OK;
void *adv;
int err;
if (broadcast_source == NULL) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
adv = bt_le_ext_adv_find(adv_handle);
if (adv == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_cap_initiator_broadcast_audio_start(broadcast_source, adv);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_update(esp_ble_audio_cap_broadcast_source_t *broadcast_source,
const uint8_t meta[], size_t meta_len)
{
int err;
if (broadcast_source == NULL || meta == NULL || meta_len == 0) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_broadcast_audio_update_safe(broadcast_source, meta, meta_len);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_stop(esp_ble_audio_cap_broadcast_source_t *broadcast_source)
{
int err;
if (broadcast_source == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_broadcast_audio_stop_safe(broadcast_source);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_delete(esp_ble_audio_cap_broadcast_source_t *broadcast_source)
{
int err;
if (broadcast_source == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_broadcast_audio_delete_safe(broadcast_source);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_initiator_broadcast_get_base(esp_ble_audio_cap_broadcast_source_t *broadcast_source,
struct net_buf_simple *base_buf)
{
int err;
if (broadcast_source == NULL || base_buf == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_initiator_broadcast_get_base_safe(broadcast_source, base_buf);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
#endif /* CONFIG_BT_CAP_INITIATOR */
#if CONFIG_BT_CAP_HANDOVER
esp_err_t esp_ble_audio_cap_handover_register_cb(const esp_ble_audio_cap_handover_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_handover_register_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_handover_unregister_cb(const esp_ble_audio_cap_handover_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_handover_unregister_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_handover_unicast_to_broadcast(
const esp_ble_audio_cap_handover_unicast_to_broadcast_param_t *param)
{
int err;
if (param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_handover_unicast_to_broadcast_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_handover_broadcast_to_unicast(
const esp_ble_audio_cap_handover_broadcast_to_unicast_param_t *param)
{
int err;
if (param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_handover_broadcast_to_unicast_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_CAP_HANDOVER */
#if CONFIG_BT_CAP_COMMANDER
esp_err_t esp_ble_audio_cap_commander_register_cb(const esp_ble_audio_cap_commander_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_register_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_commander_unregister_cb(const esp_ble_audio_cap_commander_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_unregister_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_commander_discover(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_cap_commander_discover(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_cap_commander_cancel(void)
{
int err;
err = bt_cap_commander_cancel_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_BAP_BROADCAST_ASSISTANT
esp_err_t esp_ble_audio_cap_commander_broadcast_reception_start(
const esp_ble_audio_cap_commander_broadcast_reception_start_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_broadcast_reception_start_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_commander_broadcast_reception_stop(
const esp_ble_audio_cap_commander_broadcast_reception_stop_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_broadcast_reception_stop_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_cap_commander_distribute_broadcast_code(
const esp_ble_audio_cap_commander_distribute_broadcast_code_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_distribute_broadcast_code_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT */
#if CONFIG_BT_VCP_VOL_CTLR
esp_err_t esp_ble_audio_cap_commander_change_volume(
const esp_ble_audio_cap_commander_change_volume_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->members == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_change_volume_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_VCP_VOL_CTLR_VOCS
esp_err_t esp_ble_audio_cap_commander_change_volume_offset(
const esp_ble_audio_cap_commander_change_volume_offset_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_change_volume_offset_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_VCP_VOL_CTLR_VOCS */
esp_err_t esp_ble_audio_cap_commander_change_volume_mute_state(
const esp_ble_audio_cap_commander_change_volume_mute_state_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->members == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_change_volume_mute_state_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_VCP_VOL_CTLR */
#if CONFIG_BT_MICP_MIC_CTLR
esp_err_t esp_ble_audio_cap_commander_change_microphone_mute_state(
const esp_ble_audio_cap_commander_change_microphone_mute_state_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->members == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_change_microphone_mute_state_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_MICP_MIC_CTLR_AICS
esp_err_t esp_ble_audio_cap_commander_change_microphone_gain_setting(
const esp_ble_audio_cap_commander_change_microphone_gain_setting_param_t *param)
{
int err;
if (param == NULL || param->count == 0 ||
param->count > CONFIG_BT_MAX_CONN || param->param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_cap_commander_change_microphone_gain_setting_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
#endif /* CONFIG_BT_MICP_MIC_CTLR */
#endif /* CONFIG_BT_CAP_COMMANDER */
@@ -0,0 +1,181 @@
/*
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_ccp_api.h"
#if CONFIG_BT_CCP_CALL_CONTROL_SERVER
esp_err_t esp_ble_audio_ccp_call_control_server_register_bearer(
const esp_ble_audio_tbs_register_param_t *param,
esp_ble_audio_ccp_call_control_server_bearer_t **bearer)
{
esp_err_t err;
if (param == NULL || bearer == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_server_register_bearer_safe(param, bearer);
if (err) {
/* Map Zephyr error codes to ESP-IDF error codes */
switch (err) {
case -EINVAL:
return ESP_ERR_INVALID_ARG;
case -ENOMEM:
return ESP_ERR_NO_MEM;
case -EALREADY:
return ESP_ERR_INVALID_STATE;
case -EAGAIN:
return ESP_ERR_INVALID_STATE;
default:
return ESP_FAIL;
}
}
return ESP_OK;
}
esp_err_t esp_ble_audio_ccp_call_control_server_unregister_bearer(
esp_ble_audio_ccp_call_control_server_bearer_t *bearer)
{
esp_err_t err;
if (bearer == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_server_unregister_bearer_safe(bearer);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_ccp_call_control_server_set_bearer_provider_name(
esp_ble_audio_ccp_call_control_server_bearer_t *bearer, const char *name)
{
esp_err_t err;
if (bearer == NULL || name == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_server_set_bearer_provider_name_safe(bearer, name);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_ccp_call_control_server_get_bearer_provider_name(
esp_ble_audio_ccp_call_control_server_bearer_t *bearer, const char **name)
{
esp_err_t err;
if (bearer == NULL || name == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_server_get_bearer_provider_name_safe(bearer, name);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_CCP_CALL_CONTROL_SERVER */
#if CONFIG_BT_CCP_CALL_CONTROL_CLIENT
esp_err_t esp_ble_audio_ccp_call_control_client_discover(
esp_ble_conn_t *conn, esp_ble_audio_ccp_call_control_client_t **out_client)
{
esp_err_t err;
if (conn == NULL || out_client == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_client_discover_safe(conn, out_client);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_ccp_call_control_client_register_cb(
esp_ble_audio_ccp_call_control_client_cb_t *cb)
{
esp_err_t err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_client_register_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_ccp_call_control_client_unregister_cb(
esp_ble_audio_ccp_call_control_client_cb_t *cb)
{
esp_err_t err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_client_unregister_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_ccp_call_control_client_get_bearers(
esp_ble_audio_ccp_call_control_client_t *client,
esp_ble_audio_ccp_call_control_client_bearers_t *bearers)
{
esp_err_t err;
if (client == NULL || bearers == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_client_get_bearers_safe(client, bearers);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_CCP_CALL_CONTROL_CLIENT */
#if CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME
esp_err_t esp_ble_audio_ccp_call_control_client_read_bearer_provider_name(
esp_ble_audio_ccp_call_control_client_bearer_t *bearer)
{
esp_err_t err;
if (bearer == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_ccp_call_control_client_read_bearer_provider_name_safe(bearer);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: 2020 Intel Corporation
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_ble_audio_common_api.h"
esp_err_t esp_ble_audio_data_parse(const uint8_t ltv[], size_t size,
bool (*func)(uint8_t type,
const uint8_t *data,
uint8_t data_len,
void *user_data),
void *user_data)
{
return esp_ble_iso_data_parse(ltv, size, func, user_data);
}
esp_err_t esp_ble_audio_data_get_val(const uint8_t ltv_data[],
size_t size, uint8_t type,
const uint8_t **data,
uint8_t *data_len)
{
int ret;
if (ltv_data == NULL || data == NULL || data_len == NULL) {
return ESP_ERR_INVALID_ARG;
}
ret = bt_audio_data_get_val(ltv_data, size, type, data);
if (ret < 0) {
return ESP_FAIL;
}
*data_len = ret;
return ESP_OK;
}
uint8_t esp_ble_audio_get_chan_count(esp_ble_audio_location_t chan_allocation)
{
return bt_audio_get_chan_count(chan_allocation);
}
esp_err_t esp_ble_audio_gattc_disc_start(uint16_t conn_handle)
{
int err;
err = bt_gattc_disc_start_safe(conn_handle);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
void esp_ble_audio_gap_app_post_event(uint8_t type, void *param)
{
bt_le_gap_app_post_event(type, param);
}
void esp_ble_audio_gatt_app_post_event(uint8_t type, void *param)
{
bt_le_gatt_app_post_event(type, param);
}
esp_err_t esp_ble_audio_common_init(esp_ble_audio_init_info_t *info)
{
bool gap_cb_registered = false;
bool gatt_cb_registered = false;
int err;
if (info) {
if (info->gap_cb) {
err = bt_le_gap_app_cb_register(info->gap_cb);
if (err) {
return ESP_FAIL;
}
gap_cb_registered = true;
}
if (info->gatt_cb) {
err = bt_le_gatt_app_cb_register(info->gatt_cb);
if (err) {
goto unregister_gap;
}
gatt_cb_registered = true;
}
}
err = bt_le_host_init();
if (err) {
goto unregister_gatt;
}
err = bt_le_audio_init();
if (err) {
bt_le_host_deinit();
goto unregister_gatt;
}
return ESP_OK;
unregister_gatt:
if (gatt_cb_registered) {
bt_le_gatt_app_cb_unregister();
}
unregister_gap:
if (gap_cb_registered) {
bt_le_gap_app_cb_unregister();
}
return ESP_FAIL;
}
esp_err_t esp_ble_audio_common_start(esp_ble_audio_start_info_t *info)
{
int err;
if (info) {
#if CONFIG_BT_CSIP_SET_MEMBER
uint8_t cas_included = 0;
for (size_t i = 0; i < ARRAY_SIZE(info->csis_insts); i++) {
if (info->csis_insts[i].svc_inst &&
info->csis_insts[i].included_by_cas) {
cas_included++;
}
}
/* From CAS Spec:
* The CAS shall include no more than one instance of CSIS.
*/
if (cas_included > 1) {
return ESP_ERR_INVALID_ARG;
}
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
}
err = bt_le_audio_start(info);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
@@ -0,0 +1,290 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_csip_api.h"
#if CONFIG_BT_CSIP_SET_MEMBER
void *esp_ble_audio_csip_set_member_svc_decl_get(const esp_ble_audio_csip_set_member_svc_inst_t *svc_inst)
{
if (svc_inst == NULL) {
return NULL;
}
return bt_csip_set_member_svc_decl_get_safe(svc_inst);
}
esp_err_t esp_ble_audio_csip_set_member_register(const esp_ble_audio_csip_set_member_register_param_t *param,
esp_ble_audio_csip_set_member_svc_inst_t **svc_inst)
{
int err;
if (param == NULL || svc_inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (param->lockable && param->rank == 0) {
/* Rank cannot be 0 if service is lockable */
return ESP_ERR_INVALID_ARG;
}
if (param->rank > param->set_size) {
/* Invalid rank (shall be less than or equal to set_size */
return ESP_ERR_INVALID_ARG;
}
#if CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT > 1
if (param->parent == NULL) {
/* Parent service not provided */
return ESP_ERR_INVALID_ARG;
}
#endif /* CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT > 1 */
err = bt_csip_set_member_register_safe(param, svc_inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_member_unregister(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst)
{
int err;
if (svc_inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_member_unregister_safe(svc_inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_member_sirk(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
const uint8_t sirk[ESP_BLE_AUDIO_CSIP_SIRK_SIZE])
{
int err;
if (svc_inst == NULL || sirk == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_member_sirk_safe(svc_inst, sirk);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_member_set_size_and_rank(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
uint8_t size, uint8_t rank)
{
int err;
if (svc_inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_member_set_size_and_rank_safe(svc_inst, size, rank);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_member_get_info(const esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
esp_ble_audio_csip_set_member_set_info_t *info)
{
int err;
if (svc_inst == NULL || info == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_member_get_info_safe(svc_inst, info);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_member_generate_rsi(const esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
uint8_t rsi[ESP_BLE_AUDIO_CSIP_RSI_SIZE])
{
int err;
if (svc_inst == NULL || rsi == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_member_generate_rsi_safe(svc_inst, rsi);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_member_lock(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
bool lock, bool force)
{
int err;
if (svc_inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_member_lock_safe(svc_inst, lock, force);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
#if CONFIG_BT_CSIP_SET_COORDINATOR
esp_err_t esp_ble_audio_csip_set_coordinator_discover(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_csip_set_coordinator_discover(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_ble_audio_csip_set_coordinator_set_member_t *
esp_ble_audio_csip_set_coordinator_set_member_by_conn(uint16_t conn_handle)
{
esp_ble_audio_csip_set_coordinator_set_member_t *ret = NULL;
void *conn;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
goto unlock;
}
ret = bt_csip_set_coordinator_set_member_by_conn(conn);
unlock:
bt_le_host_unlock();
return ret;
}
bool esp_ble_audio_csip_set_coordinator_is_set_member(const uint8_t sirk[ESP_BLE_AUDIO_CSIP_SIRK_SIZE],
uint8_t data_type, const uint8_t *data, uint8_t data_len)
{
struct bt_data ad = {
.type = data_type,
.data = data,
.data_len = data_len,
};
if (sirk == NULL || data_type != BT_DATA_CSIS_RSI ||
data == NULL || data_len != ESP_BLE_AUDIO_CSIP_RSI_SIZE) {
return false;
}
return bt_csip_set_coordinator_is_set_member_safe(sirk, &ad);
}
esp_err_t esp_ble_audio_csip_set_coordinator_register_cb(esp_ble_audio_csip_set_coordinator_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_coordinator_register_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_coordinator_ordered_access(const esp_ble_audio_csip_set_coordinator_set_member_t *members[],
uint8_t count,
const esp_ble_audio_csip_set_coordinator_set_info_t *set_info,
bt_csip_set_coordinator_ordered_access_t cb)
{
int err;
if (members == NULL ||
count == 0 || count > CONFIG_BT_MAX_CONN ||
set_info == NULL || cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_coordinator_ordered_access_safe(members, count, set_info, cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_coordinator_lock(const esp_ble_audio_csip_set_coordinator_set_member_t **members,
uint8_t count,
const esp_ble_audio_csip_set_coordinator_set_info_t *set_info)
{
int err;
if (members == NULL || count > CONFIG_BT_MAX_CONN || set_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_coordinator_lock_safe(members, count, set_info);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_csip_set_coordinator_release(const esp_ble_audio_csip_set_coordinator_set_member_t **members,
uint8_t count,
const esp_ble_audio_csip_set_coordinator_set_info_t *set_info)
{
int err;
if (members == NULL || count > CONFIG_BT_MAX_CONN || set_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_csip_set_coordinator_release_safe(members, count, set_info);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_CSIP_SET_COORDINATOR */
@@ -0,0 +1,268 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_gmap_api.h"
#if CONFIG_BT_GMAP
esp_err_t esp_ble_audio_gmap_cb_register(const esp_ble_audio_gmap_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_gmap_cb_register_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_gmap_discover(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_gmap_discover(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#define GMAP_ROLE_MASK (ESP_BLE_AUDIO_GMAP_ROLE_UGG | \
ESP_BLE_AUDIO_GMAP_ROLE_UGT | \
ESP_BLE_AUDIO_GMAP_ROLE_BGS | \
ESP_BLE_AUDIO_GMAP_ROLE_BGR)
static bool valid_gmap_role(esp_ble_audio_gmap_role_t role)
{
if (role == 0 || (role & GMAP_ROLE_MASK) != role) {
/* Invalid role */
return false;
}
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_UGG) != 0 &&
!IS_ENABLED(CONFIG_BT_GMAP_UGG_SUPPORTED)) {
/* Device does not support the UGG role */
return false;
}
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_UGT) != 0 &&
!IS_ENABLED(CONFIG_BT_GMAP_UGT_SUPPORTED)) {
/* Device does not support the UGT role */
return false;
}
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_BGS) != 0 &&
!IS_ENABLED(CONFIG_BT_GMAP_BGS_SUPPORTED)) {
/* Device does not support the BGS role */
return false;
}
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_BGR) != 0 &&
!IS_ENABLED(CONFIG_BT_GMAP_BGR_SUPPORTED)) {
/* Device does not support the BGR role */
return false;
}
return true;
}
static bool valid_gmap_features(esp_ble_audio_gmap_role_t role,
esp_ble_audio_gmap_feat_t features)
{
#if CONFIG_BT_GMAP_UGG_SUPPORTED
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_UGG) != 0) {
esp_ble_audio_gmap_ugg_feat_t ugg_feat = features.ugg_feat;
if ((ugg_feat & ESP_BLE_AUDIO_GMAP_UGG_FEAT_MULTIPLEX) != 0 &&
CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT == 0) {
/* Cannot support ESP_BLE_AUDIO_GMAP_UGG_FEAT_MULTIPLEX with
* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT == 0.
*/
return false;
}
if ((ugg_feat & ESP_BLE_AUDIO_GMAP_UGG_FEAT_96KBPS_SOURCE) != 0 &&
CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT == 0) {
/* Cannot support ESP_BLE_AUDIO_GMAP_UGG_FEAT_96KBPS_SOURCE with
* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT == 0.
*/
return false;
}
if ((ugg_feat & ESP_BLE_AUDIO_GMAP_UGG_FEAT_MULTISINK) != 0 &&
(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT < 2 ||
CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT < 2)) {
/* Cannot support ESP_BLE_AUDIO_GMAP_UGG_FEAT_MULTISINK with
* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT or
* CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT < 2.
*/
return false;
}
}
#endif /* CONFIG_BT_GMAP_UGG_SUPPORTED */
#if CONFIG_BT_GMAP_UGT_SUPPORTED
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_UGT) != 0) {
esp_ble_audio_gmap_ugt_feat_t ugt_feat = features.ugt_feat;
esp_ble_audio_gmap_bgr_feat_t bgr_feat = features.bgr_feat;
if ((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_SOURCE) == 0 &&
(ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_SINK) == 0) {
/* Device shall support either ESP_BLE_AUDIO_GMAP_UGT_FEAT_SOURCE or
* ESP_BLE_AUDIO_GMAP_UGT_FEAT_SINK.
*/
return false;
}
if ((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_SOURCE) == 0 &&
((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_80KBPS_SOURCE) != 0 ||
(ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISOURCE) != 0)) {
/* Device shall support ESP_BLE_AUDIO_GMAP_UGT_FEAT_SOURCE if
* ESP_BLE_AUDIO_GMAP_UGT_FEAT_80KBPS_SOURCE or
* ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISOURCE is supported.
*/
return false;
}
if ((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_SOURCE) != 0 &&
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT == 0) {
/* Cannot support ESP_BLE_AUDIO_GMAP_UGT_FEAT_SOURCE with
* CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT == 0.
*/
return false;
}
if ((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISOURCE) != 0 &&
(CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2 ||
CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2)) {
/* Cannot support ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISOURCE with
* CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT or
* CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2.
*/
return false;
}
if ((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_SINK) != 0 &&
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT == 0) {
/* Cannot support ESP_BLE_AUDIO_GMAP_UGT_FEAT_SINK with
* CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT == 0.
*/
return false;
}
if ((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_SINK) == 0 &&
((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_64KBPS_SINK) != 0 ||
(ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISINK) != 0 ||
(ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTIPLEX) != 0)) {
/* Device shall support ESP_BLE_AUDIO_GMAP_UGT_FEAT_SINK if
* ESP_BLE_AUDIO_GMAP_UGT_FEAT_64KBPS_SINK,
* ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISINK or
* ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTIPLEX is supported.
*/
return false;
}
if ((ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISINK) != 0 &&
(CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT < 2 ||
CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2)) {
/* Cannot support ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISINK with
* CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT or
* CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2.
*/
return false;
}
/* If the device supports both the UGT and BGT roles, then it needs
* have the same support for multiplexing for both roles.
*/
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_BGR) != 0 &&
IS_ENABLED(CONFIG_BT_GMAP_BGR_SUPPORTED) &&
!!(ugt_feat & ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTIPLEX) !=
!!(bgr_feat & ESP_BLE_AUDIO_GMAP_BGR_FEAT_MULTIPLEX)) {
/* Device shall support ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTIPLEX if
* ESP_BLE_AUDIO_GMAP_BGR_FEAT_MULTIPLEX is supported, and vice versa.
*/
return false;
}
}
#endif /* CONFIG_BT_GMAP_UGT_SUPPORTED */
#if CONFIG_BT_GMAP_BGR_SUPPORTED
if ((role & ESP_BLE_AUDIO_GMAP_ROLE_BGR) != 0) {
esp_ble_audio_gmap_bgr_feat_t bgr_feat = features.bgr_feat;
if ((bgr_feat & ESP_BLE_AUDIO_GMAP_BGR_FEAT_MULTISINK) != 0 &&
CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT < 2) {
/* Cannot support ESP_BLE_AUDIO_GMAP_BGR_FEAT_MULTISINK with
* CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT < 2.
*/
return false;
}
}
#endif /* CONFIG_BT_GMAP_BGR_SUPPORTED */
/* If the roles are not supported, then the feature characteristics
* are not instantiated and the feature values do not need to be
* checked, as they will never be read (thus ignore by the stack).
*/
return true;
}
esp_err_t esp_ble_audio_gmap_register(esp_ble_audio_gmap_role_t role,
esp_ble_audio_gmap_feat_t features)
{
int err;
if (valid_gmap_role(role) == false ||
valid_gmap_features(role, features) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_gmap_register_safe(role, features);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_gmap_set_role(esp_ble_audio_gmap_role_t role,
esp_ble_audio_gmap_feat_t features)
{
int err;
if (valid_gmap_role(role) == false ||
valid_gmap_features(role, features) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_gmap_set_role_safe(role, features);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_GMAP */
@@ -0,0 +1,281 @@
/*
* SPDX-FileCopyrightText: 2022 Codecoup
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_has_api.h"
#if CONFIG_BT_HAS_CLIENT
esp_err_t esp_ble_audio_has_client_cb_register(const esp_ble_audio_has_client_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_client_cb_register_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_client_discover(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_has_client_discover(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_has_client_presets_read(esp_ble_audio_has_t *has,
uint8_t index,
uint8_t max_count)
{
int err;
if (has == NULL ||
index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE ||
max_count == 0) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_client_presets_read_safe(has, index, max_count);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_client_preset_set(esp_ble_audio_has_t *has,
uint8_t index, bool sync)
{
int err;
if (has == NULL || index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_client_preset_set_safe(has, index, sync);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_client_preset_next(esp_ble_audio_has_t *has, bool sync)
{
int err;
if (has == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_client_preset_next_safe(has, sync);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_client_preset_prev(esp_ble_audio_has_t *has, bool sync)
{
int err;
if (has == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_client_preset_prev_safe(has, sync);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_HAS_CLIENT */
#if CONFIG_BT_HAS
esp_err_t esp_ble_audio_has_register(const esp_ble_audio_has_features_param_t *features)
{
int err;
if (features == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_register_safe(features);
if (err) {
return ESP_FAIL;
}
#if BLE_AUDIO_SVC_SEP_ADD
err = bt_le_has_init();
if (err) {
return ESP_FAIL;
}
#endif /* BLE_AUDIO_SVC_SEP_ADD */
return ESP_OK;
}
esp_err_t esp_ble_audio_has_preset_register(const esp_ble_audio_has_preset_register_param_t *param)
{
int err;
if (param == NULL ||
param->index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE ||
param->name == NULL ||
param->ops == NULL || param->ops->select == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (strlen(param->name) < ESP_BLE_AUDIO_HAS_PRESET_NAME_MIN ||
strlen(param->name) > ESP_BLE_AUDIO_HAS_PRESET_NAME_MAX) {
return ESP_ERR_INVALID_ARG;
}
if (!IS_ENABLED(CONFIG_BT_HAS_PRESET_NAME_DYNAMIC) &&
(param->properties & ESP_BLE_AUDIO_HAS_PROP_WRITABLE) > 0) {
/* Writable presets is not supported */
return ESP_ERR_INVALID_ARG;
}
err = bt_has_preset_register_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_preset_unregister(uint8_t index)
{
int err;
if (index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_preset_unregister_safe(index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_preset_available(uint8_t index)
{
int err;
if (index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_preset_available_safe(index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_preset_unavailable(uint8_t index)
{
int err;
if (index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_preset_unavailable_safe(index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_preset_active_set(uint8_t index)
{
int err;
if (index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_preset_active_set_safe(index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
uint8_t esp_ble_audio_has_preset_active_get(void)
{
return bt_has_preset_active_get_safe();
}
esp_err_t esp_ble_audio_has_preset_name_change(uint8_t index, const char *name)
{
int err;
if (index == ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE || name == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (strlen(name) < ESP_BLE_AUDIO_HAS_PRESET_NAME_MIN ||
strlen(name) > ESP_BLE_AUDIO_HAS_PRESET_NAME_MAX) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_preset_name_change_safe(index, name);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_has_features_set(const esp_ble_audio_has_features_param_t *features)
{
int err;
if (features == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_has_features_set_safe(features);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_HAS */
@@ -0,0 +1,947 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_mcs_defs.h"
#include "esp_ble_audio_mcc_api.h"
#if CONFIG_BT_MCC
esp_err_t esp_ble_audio_mcc_init(esp_ble_audio_mcc_cb_t *cb)
{
int err;
err = bt_mcc_init_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_mcc_discover_mcs(uint16_t conn_handle, bool subscribe)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_discover_mcs(conn, subscribe);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_read_player_name(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_player_name(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#if CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL
esp_err_t esp_ble_audio_mcc_read_icon_url(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_icon_url(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL */
#if CONFIG_BT_MCC_READ_TRACK_TITLE
esp_err_t esp_ble_audio_mcc_read_track_title(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_track_title(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_TRACK_TITLE */
#if CONFIG_BT_MCC_READ_TRACK_DURATION
esp_err_t esp_ble_audio_mcc_read_track_duration(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_track_duration(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_TRACK_DURATION */
#if CONFIG_BT_MCC_READ_TRACK_POSITION
esp_err_t esp_ble_audio_mcc_read_track_position(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_track_position(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_TRACK_POSITION */
#if CONFIG_BT_MCC_SET_TRACK_POSITION
esp_err_t esp_ble_audio_mcc_set_track_position(uint16_t conn_handle, int32_t pos)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_set_track_position(conn, pos);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_SET_TRACK_POSITION */
#if CONFIG_BT_MCC_READ_PLAYBACK_SPEED
esp_err_t esp_ble_audio_mcc_read_playback_speed(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_playback_speed(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_PLAYBACK_SPEED */
#if CONFIG_BT_MCC_SET_PLAYBACK_SPEED
esp_err_t esp_ble_audio_mcc_set_playback_speed(uint16_t conn_handle, int8_t speed)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_set_playback_speed(conn, speed);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_SET_PLAYBACK_SPEED */
#if CONFIG_BT_MCC_READ_SEEKING_SPEED
esp_err_t esp_ble_audio_mcc_read_seeking_speed(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_seeking_speed(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_SEEKING_SPEED */
#if CONFIG_BT_MCC_READ_PLAYING_ORDER
esp_err_t esp_ble_audio_mcc_read_playing_order(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_playing_order(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_PLAYING_ORDER */
#if CONFIG_BT_MCC_SET_PLAYING_ORDER
esp_err_t esp_ble_audio_mcc_set_playing_order(uint16_t conn_handle, uint8_t order)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_set_playing_order(conn, order);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_SET_PLAYING_ORDER */
#if CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED
esp_err_t esp_ble_audio_mcc_read_playing_orders_supported(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_playing_orders_supported(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED */
#if CONFIG_BT_MCC_READ_MEDIA_STATE
esp_err_t esp_ble_audio_mcc_read_media_state(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_media_state(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_MEDIA_STATE */
#if CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT
#define MCS_VALID_OP(opcode) \
(IN_RANGE((opcode), ESP_BLE_AUDIO_MCS_OPC_PLAY, ESP_BLE_AUDIO_MCS_OPC_STOP) || \
(opcode == ESP_BLE_AUDIO_MCS_OPC_MOVE_RELATIVE) || \
IN_RANGE((opcode), ESP_BLE_AUDIO_MCS_OPC_PREV_SEGMENT, ESP_BLE_AUDIO_MCS_OPC_GOTO_SEGMENT) || \
IN_RANGE((opcode), ESP_BLE_AUDIO_MCS_OPC_PREV_TRACK, ESP_BLE_AUDIO_MCS_OPC_GOTO_TRACK) || \
IN_RANGE((opcode), ESP_BLE_AUDIO_MCS_OPC_PREV_GROUP, ESP_BLE_AUDIO_MCS_OPC_GOTO_GROUP))
esp_err_t esp_ble_audio_mcc_send_cmd(uint16_t conn_handle,
const esp_ble_audio_mpl_cmd_t *cmd)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (cmd == NULL || MCS_VALID_OP(cmd->opcode) == false) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_send_cmd(conn, cmd);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT */
#if CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED
esp_err_t esp_ble_audio_mcc_read_opcodes_supported(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_opcodes_supported(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED */
#if CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID
esp_err_t esp_ble_audio_mcc_read_content_control_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_content_control_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID */
#if CONFIG_BT_MCC_OTS
esp_err_t esp_ble_audio_mcc_read_icon_obj_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_icon_obj_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_read_segments_obj_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_segments_obj_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_read_current_track_obj_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_current_track_obj_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_set_current_track_obj_id(uint16_t conn_handle, uint64_t id)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (ESP_BLE_AUDIO_MCS_VALID_OBJ_ID(id) == false) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_set_current_track_obj_id(conn, id);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_read_next_track_obj_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_next_track_obj_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_set_next_track_obj_id(uint16_t conn_handle, uint64_t id)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (ESP_BLE_AUDIO_MCS_VALID_OBJ_ID(id) == false) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_set_next_track_obj_id(conn, id);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_read_current_group_obj_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_current_group_obj_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_set_current_group_obj_id(uint16_t conn_handle, uint64_t id)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (ESP_BLE_AUDIO_MCS_VALID_OBJ_ID(id) == false) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_set_current_group_obj_id(conn, id);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_read_parent_group_obj_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_parent_group_obj_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_send_search(uint16_t conn_handle,
const esp_ble_audio_mpl_search_t *search)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (search == NULL || IN_RANGE(search->len,
ESP_BLE_AUDIO_SEARCH_LEN_MIN,
ESP_BLE_AUDIO_SEARCH_LEN_MAX) == false) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_send_search(conn, search);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_read_search_results_obj_id(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_read_search_results_obj_id(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_otc_read_object_metadata(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_otc_read_object_metadata(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_otc_read_icon_object(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_otc_read_icon_object(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_otc_read_track_segments_object(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_otc_read_track_segments_object(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_otc_read_current_track_object(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_otc_read_current_track_object(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_otc_read_next_track_object(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_otc_read_next_track_object(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_otc_read_current_group_object(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_otc_read_current_group_object(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_mcc_otc_read_parent_group_object(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_mcc_otc_read_parent_group_object(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#if CONFIG_BT_MCC_SHELL
struct bt_ots_client *esp_ble_audio_mcc_otc_inst(uint16_t conn_handle)
{
struct bt_ots_client *ret = NULL;
void *conn;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
goto unlock;
}
ret = bt_mcc_otc_inst(conn);
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCC_SHELL */
#endif /* CONFIG_BT_MCC_OTS */
#endif /* CONFIG_BT_MCC */
@@ -0,0 +1,585 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_mcs_defs.h"
#include "esp_ble_audio_media_proxy_api.h"
#if CONFIG_BT_MCTL_LOCAL_PLAYER_LOCAL_CONTROL
esp_err_t esp_ble_audio_media_proxy_ctrl_register(esp_ble_audio_media_proxy_ctrl_cbs_t *ctrl_cbs)
{
int err;
if (ctrl_cbs == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_register_safe(ctrl_cbs);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
#if CONFIG_BT_MCTL_REMOTE_PLAYER_CONTROL
esp_err_t esp_ble_audio_media_proxy_ctrl_discover_player(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_media_proxy_ctrl_discover_player(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_MCTL_REMOTE_PLAYER_CONTROL */
#if CONFIG_BT_MCTL_LOCAL_PLAYER_LOCAL_CONTROL || CONFIG_BT_MCTL_REMOTE_PLAYER_CONTROL
esp_err_t esp_ble_audio_media_proxy_ctrl_get_player_name(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_player_name_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_icon_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_icon_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_icon_url(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_icon_url_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_title(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_track_title_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_duration(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_track_duration_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_position(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_track_position_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_set_track_position(esp_ble_audio_media_player_t *player,
int32_t position)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_set_track_position_safe(player, position);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_playback_speed(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_playback_speed_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_set_playback_speed(esp_ble_audio_media_player_t *player,
int8_t speed)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_set_playback_speed_safe(player, speed);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_seeking_speed(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_seeking_speed_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_segments_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_track_segments_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_current_track_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_current_track_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_set_current_track_id(esp_ble_audio_media_player_t *player,
uint64_t id)
{
int err;
if (player == NULL || (IS_ENABLED(CONFIG_BT_MCTL_LOCAL_PLAYER_LOCAL_CONTROL) &&
ESP_BLE_AUDIO_MCS_VALID_OBJ_ID(id) == false)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_set_current_track_id_safe(player, id);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_next_track_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_next_track_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_set_next_track_id(esp_ble_audio_media_player_t *player,
uint64_t id)
{
int err;
if (player == NULL || ESP_BLE_AUDIO_MCS_VALID_OBJ_ID(id) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_set_next_track_id_safe(player, id);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_parent_group_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_parent_group_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_current_group_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_current_group_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_set_current_group_id(esp_ble_audio_media_player_t *player,
uint64_t id)
{
int err;
if (player == NULL || (IS_ENABLED(CONFIG_BT_MCTL_LOCAL_PLAYER_LOCAL_CONTROL) &&
ESP_BLE_AUDIO_MCS_VALID_OBJ_ID(id) == false)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_set_current_group_id_safe(player, id);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_playing_order(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_playing_order_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_set_playing_order(esp_ble_audio_media_player_t *player,
uint8_t order)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_set_playing_order_safe(player, order);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_playing_orders_supported(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_playing_orders_supported_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_media_state(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_media_state_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_send_command(esp_ble_audio_media_player_t *player,
const esp_ble_audio_mpl_cmd_t *command)
{
int err;
if (player == NULL || command == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_send_command_safe(player, command);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_commands_supported(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_commands_supported_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_send_search(esp_ble_audio_media_player_t *player,
const esp_ble_audio_mpl_search_t *search)
{
int err;
if (player == NULL || search == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_send_search_safe(player, search);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_search_results_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_search_results_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_ctrl_get_content_ctrl_id(esp_ble_audio_media_player_t *player)
{
int err;
if (player == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_ctrl_get_content_ctrl_id_safe(player);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_MCTL_LOCAL_PLAYER_LOCAL_CONTROL || CONFIG_BT_MCTL_REMOTE_PLAYER_CONTROL */
#if CONFIG_BT_MCTL_LOCAL_PLAYER_CONTROL
static bool pl_calls_is_valid(const esp_ble_audio_media_proxy_pl_calls_t *pl_calls)
{
if (pl_calls == NULL) {
return false;
}
if (pl_calls->get_player_name == NULL ||
pl_calls->get_icon_url == NULL ||
pl_calls->get_track_title == NULL ||
pl_calls->get_track_duration == NULL ||
pl_calls->get_track_position == NULL ||
pl_calls->set_track_position == NULL ||
pl_calls->get_playback_speed == NULL ||
pl_calls->set_playback_speed == NULL ||
pl_calls->get_seeking_speed == NULL ||
pl_calls->get_playing_order == NULL ||
pl_calls->set_playing_order == NULL ||
pl_calls->get_playing_orders_supported == NULL ||
pl_calls->get_media_state == NULL ||
pl_calls->send_command == NULL ||
pl_calls->get_commands_supported == NULL ||
pl_calls->get_content_ctrl_id == NULL) {
return false;
}
#if CONFIG_BT_MPL_OBJECTS
if (pl_calls->get_icon_id == NULL ||
pl_calls->get_track_segments_id == NULL ||
pl_calls->get_current_track_id == NULL ||
pl_calls->set_current_track_id == NULL ||
pl_calls->get_next_track_id == NULL ||
pl_calls->set_next_track_id == NULL ||
pl_calls->get_parent_group_id == NULL ||
pl_calls->get_current_group_id == NULL ||
pl_calls->set_current_group_id == NULL ||
pl_calls->send_search == NULL ||
pl_calls->get_search_results_id == NULL) {
return false;
}
#endif /* CONFIG_BT_MPL_OBJECTS */
return true;
}
esp_err_t esp_ble_audio_media_proxy_pl_register(esp_ble_audio_media_proxy_pl_calls_t *pl_calls)
{
int err;
if (pl_calls_is_valid(pl_calls) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_media_proxy_pl_register_safe(pl_calls);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_media_proxy_pl_init(void)
{
int err;
err = bt_media_proxy_pl_init_safe();
if (err) {
return ESP_FAIL;
}
#if CONFIG_BT_MCS && BLE_AUDIO_SVC_SEP_ADD
err = bt_le_media_proxy_pl_init();
if (err) {
return ESP_FAIL;
}
#endif /* CONFIG_BT_MCS && BLE_AUDIO_SVC_SEP_ADD */
return ESP_OK;
}
#endif /* CONFIG_BT_MCTL_LOCAL_PLAYER_CONTROL */
#if CONFIG_BT_MCS && CONFIG_BT_OTS
struct bt_ots *esp_ble_audio_mcs_get_ots(void)
{
return bt_mcs_get_ots_safe();
}
#endif /* CONFIG_BT_MCS && CONFIG_BT_OTS */
@@ -0,0 +1,231 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_micp_api.h"
#if CONFIG_BT_MICP_MIC_DEV
esp_err_t esp_ble_audio_micp_mic_dev_register(esp_ble_audio_micp_mic_dev_register_param_t *param)
{
int err;
if (param == NULL ||
(CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT && param->aics_param == NULL)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_micp_mic_dev_register_safe(param);
if (err) {
return ESP_FAIL;
}
#if BLE_AUDIO_SVC_SEP_ADD
err = bt_le_micp_mic_dev_init();
if (err) {
return ESP_FAIL;
}
#endif /* BLE_AUDIO_SVC_SEP_ADD */
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_dev_included_get(esp_ble_audio_micp_included_t *included)
{
int err;
if (included == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_micp_mic_dev_included_get_safe(included);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_dev_unmute(void)
{
int err;
err = bt_micp_mic_dev_unmute_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_dev_mute(void)
{
int err;
err = bt_micp_mic_dev_mute_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_dev_mute_disable(void)
{
int err;
err = bt_micp_mic_dev_mute_disable_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_dev_mute_get(void)
{
int err;
err = bt_micp_mic_dev_mute_get_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_MICP_MIC_DEV */
#if CONFIG_BT_MICP_MIC_CTLR
#if CONFIG_BT_MICP_MIC_CTLR_AICS
esp_err_t esp_ble_audio_micp_mic_ctlr_included_get(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr,
esp_ble_audio_micp_included_t *included)
{
int err;
if (mic_ctlr == NULL || included == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_micp_mic_ctlr_included_get_safe(mic_ctlr, included);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
esp_ble_audio_micp_mic_ctlr_t *esp_ble_audio_micp_mic_ctlr_get_by_conn(uint16_t conn_handle)
{
esp_ble_audio_micp_mic_ctlr_t *ret = NULL;
void *conn;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
goto unlock;
}
ret = bt_micp_mic_ctlr_get_by_conn(conn);
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_micp_mic_ctlr_discover(uint16_t conn_handle,
esp_ble_audio_micp_mic_ctlr_t **mic_ctlr)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (mic_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_micp_mic_ctlr_discover(conn, mic_ctlr);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_micp_mic_ctlr_unmute(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr)
{
int err;
if (mic_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_micp_mic_ctlr_unmute_safe(mic_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_ctlr_mute(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr)
{
int err;
if (mic_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_micp_mic_ctlr_mute_safe(mic_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_ctlr_mute_get(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr)
{
int err;
if (mic_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_micp_mic_ctlr_mute_get_safe(mic_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_micp_mic_ctlr_cb_register(esp_ble_audio_micp_mic_ctlr_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_micp_mic_ctlr_cb_register_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_MICP_MIC_CTLR */
@@ -0,0 +1,200 @@
/*
* SPDX-FileCopyrightText: 2021 Intel Corporation
* SPDX-FileCopyrightText: 2021-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_pacs_api.h"
#if CONFIG_BT_PACS
esp_err_t esp_ble_audio_pacs_register(const esp_ble_audio_pacs_register_param_t *param)
{
int err;
if (param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_pacs_register_safe(param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_pacs_unregister(void)
{
int err;
err = bt_pacs_unregister_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
static bool dir_is_valid(esp_ble_audio_dir_t dir)
{
if (dir != ESP_BLE_AUDIO_DIR_SINK &&
dir != ESP_BLE_AUDIO_DIR_SOURCE) {
return false;
}
return true;
}
esp_err_t esp_ble_audio_pacs_cap_register(esp_ble_audio_dir_t dir,
esp_ble_audio_pacs_cap_t *cap)
{
int err;
if (dir_is_valid(dir) == false ||
cap == NULL || cap->codec_cap == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_pacs_cap_register_safe(dir, cap);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_pacs_cap_unregister(esp_ble_audio_dir_t dir,
esp_ble_audio_pacs_cap_t *cap)
{
int err;
if (dir_is_valid(dir) == false || cap == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_pacs_cap_unregister_safe(dir, cap);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_pacs_set_location(esp_ble_audio_dir_t dir,
esp_ble_audio_location_t location)
{
int err;
if (dir_is_valid(dir) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_pacs_set_location_safe(dir, location);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_pacs_set_available_contexts(esp_ble_audio_dir_t dir,
esp_ble_audio_context_t contexts)
{
int err;
if (dir_is_valid(dir) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_pacs_set_available_contexts_safe(dir, contexts);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_ble_audio_context_t esp_ble_audio_pacs_get_available_contexts(esp_ble_audio_dir_t dir)
{
if (dir_is_valid(dir) == false) {
return ESP_BLE_AUDIO_CONTEXT_TYPE_NONE;
}
return bt_pacs_get_available_contexts_safe(dir);
}
esp_err_t esp_ble_audio_pacs_conn_set_available_contexts_for_conn(uint16_t conn_handle,
esp_ble_audio_dir_t dir,
esp_ble_audio_context_t *contexts)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
/* Note: contexts could be NULL */
if (dir_is_valid(dir) == false) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_pacs_conn_set_available_contexts_for_conn(conn, dir, contexts);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_ble_audio_context_t esp_ble_audio_pacs_get_available_contexts_for_conn(uint16_t conn_handle,
esp_ble_audio_dir_t dir)
{
esp_ble_audio_context_t ret = ESP_BLE_AUDIO_CONTEXT_TYPE_NONE;
void *conn;
if (dir_is_valid(dir) == false) {
return ESP_BLE_AUDIO_CONTEXT_TYPE_NONE;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
goto unlock;
}
ret = bt_pacs_get_available_contexts_for_conn(conn, dir);
unlock:
bt_le_host_unlock();
return ret;
}
esp_err_t esp_ble_audio_pacs_set_supported_contexts(esp_ble_audio_dir_t dir,
esp_ble_audio_context_t contexts)
{
int err;
if (dir_is_valid(dir) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_pacs_set_supported_contexts_safe(dir, contexts);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_PACS */
@@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2023 NXP
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_pbp_api.h"
#if CONFIG_BT_PBP
esp_err_t esp_ble_audio_pbp_get_announcement(const uint8_t meta[], size_t meta_len,
esp_ble_audio_pbp_announcement_feature_t features,
struct net_buf_simple *pba_data_buf)
{
int err;
if (pba_data_buf == NULL ||
pba_data_buf->size < (meta_len + ESP_BLE_AUDIO_PBP_MIN_PBA_SIZE)) {
return ESP_ERR_INVALID_ARG;
}
if ((meta == NULL && meta_len != 0) || (meta != NULL && meta_len == 0)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_pbp_get_announcement(meta, meta_len, features, pba_data_buf);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_pbp_parse_announcement(uint8_t data_type, const uint8_t *data, uint8_t data_len,
esp_ble_audio_pbp_announcement_feature_t *features,
uint8_t **meta, uint8_t *meta_len)
{
struct bt_data ad = {
.type = data_type,
.data = data,
.data_len = data_len,
};
int ret;
if (data == NULL || data_len == 0 || features == NULL ||
meta == NULL || meta_len == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (data_type != BT_DATA_SVC_DATA16 ||
data_len < ESP_BLE_AUDIO_PBP_MIN_PBA_SIZE) {
return ESP_ERR_INVALID_ARG;
}
ret = bt_pbp_parse_announcement(&ad, features, meta);
if (ret < 0) {
return ESP_FAIL;
}
*meta_len = ret;
return ESP_OK;
}
#endif /* CONFIG_BT_PBP */
@@ -0,0 +1,997 @@
/*
* SPDX-FileCopyrightText: 2020 Bose Corporation
* SPDX-FileCopyrightText: 2021 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_tbs_api.h"
#if CONFIG_BT_TBS
esp_err_t esp_ble_audio_tbs_accept(uint8_t call_index)
{
int err;
err = bt_tbs_accept_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_hold(uint8_t call_index)
{
int err;
err = bt_tbs_hold_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_retrieve(uint8_t call_index)
{
int err;
err = bt_tbs_retrieve_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_terminate(uint8_t call_index)
{
int err;
err = bt_tbs_terminate_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_originate(uint8_t bearer_index,
char *uri,
uint8_t *call_index)
{
int err;
if (uri == NULL || call_index == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_originate_safe(bearer_index, uri, call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_join(uint8_t call_index_cnt, uint8_t *call_indexes)
{
int err;
if (call_index_cnt == 0 || call_indexes == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_join_safe(call_index_cnt, call_indexes);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_remote_answer(uint8_t call_index)
{
int err;
err = bt_tbs_remote_answer_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_remote_hold(uint8_t call_index)
{
int err;
err = bt_tbs_remote_hold_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_remote_retrieve(uint8_t call_index)
{
int err;
err = bt_tbs_remote_retrieve_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_remote_terminate(uint8_t call_index)
{
int err;
err = bt_tbs_remote_terminate_safe(call_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_remote_incoming(uint8_t bearer_index,
const char *to,
const char *from,
const char *friendly_name,
uint8_t *call_index)
{
int ret;
if (to == NULL || from == NULL ||
friendly_name == NULL || call_index == NULL) {
return ESP_ERR_INVALID_ARG;
}
ret = bt_tbs_remote_incoming_safe(bearer_index, to, from, friendly_name);
if (ret < 0) {
return ESP_FAIL;
}
*call_index = ret;
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_set_bearer_provider_name(uint8_t bearer_index, const char *name)
{
int err;
if (name == NULL || strlen(name) == 0 ||
strlen(name) >= CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_set_bearer_provider_name_safe(bearer_index, name);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_set_bearer_technology(uint8_t bearer_index, uint8_t new_technology)
{
int err;
if (new_technology < ESP_BLE_AUDIO_TBS_TECHNOLOGY_3G ||
new_technology > ESP_BLE_AUDIO_TBS_TECHNOLOGY_WCDMA) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_set_bearer_technology_safe(bearer_index, new_technology);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_set_signal_strength(uint8_t bearer_index, uint8_t new_signal_strength)
{
int err;
if (new_signal_strength > ESP_BLE_AUDIO_TBS_SIGNAL_STRENGTH_MAX &&
new_signal_strength != ESP_BLE_AUDIO_TBS_SIGNAL_STRENGTH_UNKNOWN) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_set_signal_strength_safe(bearer_index, new_signal_strength);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#define TBS_VALID_STATUS_FLAGS(val) ((val) <= (BIT(0) | BIT(1)))
esp_err_t esp_ble_audio_tbs_set_status_flags(uint8_t bearer_index, uint16_t status_flags)
{
int err;
if (TBS_VALID_STATUS_FLAGS(status_flags) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_set_status_flags_safe(bearer_index, status_flags);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_set_uri_scheme_list(uint8_t bearer_index,
const char **uri_list,
uint8_t uri_count)
{
uint8_t count = CONFIG_BT_TBS_BEARER_COUNT;
int err;
if (count == 0 || bearer_index >= count ||
(uri_count && uri_list == NULL)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_set_uri_scheme_list_safe(bearer_index, uri_list, uri_count);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
void esp_ble_audio_tbs_register_cb(esp_ble_audio_tbs_cb_t *cbs)
{
bt_tbs_register_cb_safe(cbs);
}
static bool valid_register_param(const esp_ble_audio_tbs_register_param_t *param)
{
if (param == NULL) {
return false;
}
if (param->provider_name == NULL) {
return false;
}
if (strlen(param->provider_name) == 0 ||
strlen(param->provider_name) >= CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH) {
/* Provider name empty or length not less than CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH */
return false;
}
if (param->uci == NULL) {
return false;
}
if (param->uri_schemes_supported == NULL) {
return false;
}
if (IN_RANGE(param->technology,
ESP_BLE_AUDIO_TBS_TECHNOLOGY_3G,
ESP_BLE_AUDIO_TBS_TECHNOLOGY_WCDMA) == false) {
return false;
}
if (param->supported_features > ESP_BLE_AUDIO_TBS_FEATURE_ALL) {
return false;
}
if (CONFIG_BT_TBS_BEARER_COUNT == 0 && param->gtbs == false) {
return false;
}
return true;
}
esp_err_t esp_ble_audio_tbs_register_bearer(const esp_ble_audio_tbs_register_param_t *param,
uint8_t *bearer_index)
{
int ret;
if (param == NULL || valid_register_param(param) == false || bearer_index == NULL) {
return ESP_ERR_INVALID_ARG;
}
/* Note: currently only GTBS is supported */
if (param->gtbs == false) {
return ESP_ERR_INVALID_ARG;
}
ret = bt_tbs_register_bearer_safe(param);
if (ret < 0) {
return ESP_FAIL;
}
*bearer_index = ret;
#if BLE_AUDIO_SVC_SEP_ADD
if (bt_le_gtbs_init()) {
bt_tbs_unregister_bearer_safe(*bearer_index);
return ESP_FAIL;
}
#endif /* BLE_AUDIO_SVC_SEP_ADD */
return ESP_OK;
}
esp_err_t esp_ble_audio_tbs_unregister_bearer(uint8_t bearer_index)
{
int err;
err = bt_tbs_unregister_bearer_safe(bearer_index);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_TBS */
#if CONFIG_BT_TBS_CLIENT
esp_err_t esp_ble_audio_tbs_client_discover(uint16_t conn_handle)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_discover(conn);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#if CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL
esp_err_t esp_ble_audio_tbs_client_set_signal_strength_interval(uint16_t conn_handle,
uint8_t inst_index,
uint8_t interval)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_set_signal_strength_interval(conn, inst_index, interval);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL */
#if CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL
#define TBS_MIN_URI_LEN 3 /* a:b */
#define FIRST_PRINTABLE_ASCII_CHAR ' ' /* space */
static inline bool tbs_valid_uri(const uint8_t *uri, size_t uri_len)
{
if (uri_len > CONFIG_BT_TBS_MAX_URI_LENGTH || uri_len < TBS_MIN_URI_LEN) {
return false;
}
if (uri[0] < FIRST_PRINTABLE_ASCII_CHAR) {
/* Invalid first char */
return false;
}
for (size_t i = 1; i < uri_len; i++) {
if (uri[i] == ':' && uri[i + 1] >= FIRST_PRINTABLE_ASCII_CHAR) {
return true;
}
}
return false;
}
esp_err_t esp_ble_audio_tbs_client_originate_call(uint16_t conn_handle,
uint8_t inst_index,
const char *uri)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (uri == NULL ||
tbs_valid_uri((const uint8_t *)uri, strlen(uri)) == false) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_originate_call(conn, inst_index, uri);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL */
#if CONFIG_BT_TBS_CLIENT_TERMINATE_CALL
esp_err_t esp_ble_audio_tbs_client_terminate_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_terminate_call(conn, inst_index, call_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_TERMINATE_CALL */
#if CONFIG_BT_TBS_CLIENT_HOLD_CALL
esp_err_t esp_ble_audio_tbs_client_hold_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_hold_call(conn, inst_index, call_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_HOLD_CALL */
#if CONFIG_BT_TBS_CLIENT_ACCEPT_CALL
esp_err_t esp_ble_audio_tbs_client_accept_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_accept_call(conn, inst_index, call_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_ACCEPT_CALL */
#if CONFIG_BT_TBS_CLIENT_RETRIEVE_CALL
esp_err_t esp_ble_audio_tbs_client_retrieve_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_retrieve_call(conn, inst_index, call_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_RETRIEVE_CALL */
#if CONFIG_BT_TBS_CLIENT_JOIN_CALLS
esp_err_t esp_ble_audio_tbs_client_join_calls(uint16_t conn_handle,
uint8_t inst_index,
const uint8_t *call_indexes,
uint8_t count)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (call_indexes == NULL ||
count < 2 || count > CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_join_calls(conn, inst_index, call_indexes, count);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_JOIN_CALLS */
#if CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME
esp_err_t esp_ble_audio_tbs_client_read_bearer_provider_name(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_bearer_provider_name(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME */
#if CONFIG_BT_TBS_CLIENT_BEARER_UCI
esp_err_t esp_ble_audio_tbs_client_read_bearer_uci(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_bearer_uci(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_BEARER_UCI */
#if CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY
esp_err_t esp_ble_audio_tbs_client_read_technology(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_technology(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY */
#if CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST
esp_err_t esp_ble_audio_tbs_client_read_uri_list(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_uri_list(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST */
#if CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH
esp_err_t esp_ble_audio_tbs_client_read_signal_strength(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_signal_strength(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH */
#if CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL
esp_err_t esp_ble_audio_tbs_client_read_signal_interval(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_signal_interval(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL */
#if CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS
esp_err_t esp_ble_audio_tbs_client_read_current_calls(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_current_calls(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS */
#if CONFIG_BT_TBS_CLIENT_CCID
esp_err_t esp_ble_audio_tbs_client_read_ccid(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_ccid(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_CCID */
#if CONFIG_BT_TBS_CLIENT_INCOMING_URI
esp_err_t esp_ble_audio_tbs_client_read_call_uri(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_call_uri(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_INCOMING_URI */
#if CONFIG_BT_TBS_CLIENT_STATUS_FLAGS
esp_err_t esp_ble_audio_tbs_client_read_status_flags(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_status_flags(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_STATUS_FLAGS */
esp_err_t esp_ble_audio_tbs_client_read_call_state(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_call_state(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#if CONFIG_BT_TBS_CLIENT_INCOMING_CALL
esp_err_t esp_ble_audio_tbs_client_read_remote_uri(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_remote_uri(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_INCOMING_CALL */
#if CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME
esp_err_t esp_ble_audio_tbs_client_read_friendly_name(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_friendly_name(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME */
#if CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES
esp_err_t esp_ble_audio_tbs_client_read_optional_opcodes(uint16_t conn_handle, uint8_t inst_index)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tbs_client_read_optional_opcodes(conn, inst_index);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES */
esp_err_t esp_ble_audio_tbs_client_register_cb(esp_ble_audio_tbs_client_cb_t *cbs)
{
int err;
if (cbs == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_tbs_client_register_cb_safe(cbs);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_TBS_CLIENT_CCID
esp_ble_audio_tbs_instance_t *esp_ble_audio_tbs_client_get_by_ccid(uint16_t conn_handle, uint8_t ccid)
{
esp_ble_audio_tbs_instance_t *ret = NULL;
void *conn;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
goto unlock;
}
ret = lib_tbs_client_get_by_ccid(conn, ccid);
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_TBS_CLIENT_CCID */
#endif /* CONFIG_BT_TBS_CLIENT */
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2023 NXP
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_tmap_api.h"
#if CONFIG_BT_TMAP
esp_err_t esp_ble_audio_tmap_register(esp_ble_audio_tmap_role_t role)
{
int err;
err = bt_tmap_register_safe(role);
if (err) {
return ESP_FAIL;
}
#if BLE_AUDIO_SVC_SEP_ADD
err = bt_le_tmas_init();
if (err) {
return ESP_FAIL;
}
#endif /* BLE_AUDIO_SVC_SEP_ADD */
return ESP_OK;
}
esp_err_t esp_ble_audio_tmap_discover(uint16_t conn_handle,
const esp_ble_audio_tmap_cb_t *tmap_cb)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_tmap_discover(conn, tmap_cb);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
void esp_ble_audio_tmap_set_role(esp_ble_audio_tmap_role_t role)
{
bt_tmap_set_role_safe(role);
}
#endif /* CONFIG_BT_TMAP */
@@ -0,0 +1,430 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_vcp_api.h"
#if CONFIG_BT_VCP_VOL_REND
esp_err_t esp_ble_audio_vcp_vol_rend_included_get(esp_ble_audio_vcp_included_t *included)
{
int err;
if (included == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_rend_included_get_safe(included);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_register(esp_ble_audio_vcp_vol_rend_register_param_t *param)
{
int err;
if (param == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT && param->vocs_param == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT && param->aics_param == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (param->mute > ESP_BLE_AUDIO_VCP_STATE_MUTED || param->step == 0) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_rend_register_safe(param);
if (err) {
return ESP_FAIL;
}
#if BLE_AUDIO_SVC_SEP_ADD
err = bt_le_vcp_vol_rend_init();
if (err) {
return ESP_FAIL;
}
#endif /* BLE_AUDIO_SVC_SEP_ADD */
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_set_step(uint8_t volume_step)
{
int err;
if (volume_step == 0) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_rend_set_step_safe(volume_step);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_get_state(void)
{
int err;
err = bt_vcp_vol_rend_get_state_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_get_flags(void)
{
int err;
err = bt_vcp_vol_rend_get_flags_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_vol_down(void)
{
int err;
err = bt_vcp_vol_rend_vol_down_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_vol_up(void)
{
int err;
err = bt_vcp_vol_rend_vol_up_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_unmute_vol_down(void)
{
int err;
err = bt_vcp_vol_rend_unmute_vol_down_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_unmute_vol_up(void)
{
int err;
err = bt_vcp_vol_rend_unmute_vol_up_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_set_vol(uint8_t volume)
{
int err;
err = bt_vcp_vol_rend_set_vol_safe(volume);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_unmute(void)
{
int err;
err = bt_vcp_vol_rend_unmute_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_rend_mute(void)
{
int err;
err = bt_vcp_vol_rend_mute_safe();
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_VCP_VOL_REND */
#if CONFIG_BT_VCP_VOL_CTLR
esp_err_t esp_ble_audio_vcp_vol_ctlr_cb_register(esp_ble_audio_vcp_vol_ctlr_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_cb_register_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_cb_unregister(esp_ble_audio_vcp_vol_ctlr_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_cb_unregister_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_discover(uint16_t conn_handle,
esp_ble_audio_vcp_vol_ctlr_t **vol_ctlr)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_vcp_vol_ctlr_discover(conn, vol_ctlr);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
esp_ble_audio_vcp_vol_ctlr_t *esp_ble_audio_vcp_vol_ctlr_get_by_conn(uint16_t conn_handle)
{
esp_ble_audio_vcp_vol_ctlr_t *ret = NULL;
void *conn;
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
goto unlock;
}
ret = bt_vcp_vol_ctlr_get_by_conn(conn);
unlock:
bt_le_host_unlock();
return ret;
}
#if CONFIG_BT_VCP_VOL_CTLR_VOCS || CONFIG_BT_VCP_VOL_CTLR_AICS
esp_err_t esp_ble_audio_vcp_vol_ctlr_included_get(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr,
esp_ble_audio_vcp_included_t *included)
{
int err;
if (vol_ctlr == NULL || included == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_included_get_safe(vol_ctlr, included);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_VCP_VOL_CTLR_VOCS || CONFIG_BT_VCP_VOL_CTLR_AICS */
esp_err_t esp_ble_audio_vcp_vol_ctlr_read_state(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_read_state_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_read_flags(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_read_flags_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_vol_down(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_vol_down_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_vol_up(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_vol_up_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_unmute_vol_down(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_unmute_vol_down_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_unmute_vol_up(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_unmute_vol_up_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_set_vol(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr, uint8_t volume)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_set_vol_safe(vol_ctlr, volume);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_unmute(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_unmute_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vcp_vol_ctlr_mute(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr)
{
int err;
if (vol_ctlr == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vcp_vol_ctlr_mute_safe(vol_ctlr);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_VCP_VOL_CTLR */
@@ -0,0 +1,198 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_audio_vocs_api.h"
#if CONFIG_BT_VOCS
esp_ble_audio_vocs_t *esp_ble_audio_vocs_free_instance_get(void)
{
return bt_vocs_free_instance_get_safe();
}
void *esp_ble_audio_vocs_svc_decl_get(esp_ble_audio_vocs_t *vocs)
{
if (vocs == NULL) {
return NULL;
}
return bt_vocs_svc_decl_get_safe(vocs);
}
esp_err_t esp_ble_audio_vocs_register(esp_ble_audio_vocs_t *vocs,
const esp_ble_audio_vocs_register_param_t *param)
{
int err;
if (vocs == NULL || param == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vocs_register_safe(vocs, param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_VOCS */
#if CONFIG_BT_VOCS || CONFIG_BT_VOCS_CLIENT
esp_err_t esp_ble_audio_vocs_state_get(esp_ble_audio_vocs_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vocs_state_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vocs_state_set(esp_ble_audio_vocs_t *inst, int16_t offset)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vocs_state_set_safe(inst, offset);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vocs_location_get(esp_ble_audio_vocs_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vocs_location_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vocs_location_set(esp_ble_audio_vocs_t *inst, uint32_t location)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vocs_location_set_safe(inst, location);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vocs_description_get(esp_ble_audio_vocs_t *inst)
{
int err;
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vocs_description_get_safe(inst);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_audio_vocs_description_set(esp_ble_audio_vocs_t *inst,
const char *description)
{
int err;
if (inst == NULL || description == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_vocs_description_set_safe(inst, description);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_VOCS || CONFIG_BT_VOCS_CLIENT */
#if CONFIG_BT_VOCS_CLIENT
esp_err_t esp_ble_audio_vocs_client_cb_register(esp_ble_audio_vocs_t *inst,
esp_ble_audio_vocs_cb_t *cb)
{
if (inst == NULL) {
return ESP_ERR_INVALID_ARG;
}
bt_vocs_client_cb_register_safe(inst, cb);
return ESP_OK;
}
esp_ble_audio_vocs_t *esp_ble_audio_vocs_client_free_instance_get(void)
{
return bt_vocs_client_free_instance_get_safe();
}
esp_err_t esp_ble_audio_vocs_discover(uint16_t conn_handle,
esp_ble_audio_vocs_t *inst,
const esp_ble_audio_vocs_discover_param_t *param)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (inst == NULL || param == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (param->start_handle == 0 ||
param->end_handle == 0 ||
param->end_handle < param->start_handle) {
/* Start handle and end handle shall be non-zero and
* start handle shall be less than end handle.
*/
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_vocs_discover(conn, inst, param);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_VOCS_CLIENT */
@@ -0,0 +1,293 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_AICS_API_H_
#define ESP_BLE_AUDIO_AICS_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/aics.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< The mute state is unmuted */
#define ESP_BLE_AUDIO_AICS_STATE_UNMUTED BT_AICS_STATE_UNMUTED
/*!< The mute state is muted */
#define ESP_BLE_AUDIO_AICS_STATE_MUTED BT_AICS_STATE_MUTED
/*!< The mute state is disabled */
#define ESP_BLE_AUDIO_AICS_STATE_MUTE_DISABLED BT_AICS_STATE_MUTE_DISABLED
/*!< The gain mode is manual only and cannot be changed to automatic */
#define ESP_BLE_AUDIO_AICS_MODE_MANUAL_ONLY BT_AICS_MODE_MANUAL_ONLY
/*!< The gain mode is automatic only and cannot be changed to manual */
#define ESP_BLE_AUDIO_AICS_MODE_AUTO_ONLY BT_AICS_MODE_AUTO_ONLY
/*!< The gain mode is manual */
#define ESP_BLE_AUDIO_AICS_MODE_MANUAL BT_AICS_MODE_MANUAL
/*!< The gain mode is automatic */
#define ESP_BLE_AUDIO_AICS_MODE_AUTO BT_AICS_MODE_AUTO
/*!< The input is unspecified */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_UNSPECIFIED BT_AICS_INPUT_TYPE_UNSPECIFIED
/*!< The input is a Bluetooth Audio Stream */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_BLUETOOTH BT_AICS_INPUT_TYPE_BLUETOOTH
/*!< The input is a microphone */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_MICROPHONE BT_AICS_INPUT_TYPE_MICROPHONE
/*!< The input is analog */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_ANALOG BT_AICS_INPUT_TYPE_ANALOG
/*!< The input is digital */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_DIGITAL BT_AICS_INPUT_TYPE_DIGITAL
/*!< The input is a radio (AM/FM/XM/etc.) */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_RADIO BT_AICS_INPUT_TYPE_RADIO
/*!< The input is a Streaming Audio Source */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_STREAMING BT_AICS_INPUT_TYPE_STREAMING
/*!< The input is transparent / pass-through */
#define ESP_BLE_AUDIO_AICS_INPUT_TYPE_AMBIENT BT_AICS_INPUT_TYPE_AMBIENT
/** Audio Input Control Service instance. */
typedef struct bt_aics esp_ble_audio_aics_t;
/** Structure to hold callbacks for Audio Input Control Service. */
typedef struct bt_aics_cb esp_ble_audio_aics_cb_t;
/** Structure for initializing an Audio Input Control Service instance. */
typedef struct bt_aics_register_param esp_ble_audio_aics_register_param_t;
/** Structure for discovering an Audio Input Control Service instance. */
typedef struct bt_aics_discover_param esp_ble_audio_aics_discover_param_t;
/**
* @brief Get a free instance of Audio Input Control Service from the pool.
*
* @return Audio Input Control Service instance in case of success or NULL in case of error.
*/
esp_ble_audio_aics_t *esp_ble_audio_aics_free_instance_get(void);
/**
* @brief Get the service declaration attribute.
*
* The first service attribute returned can be included in any other GATT service.
*
* @param aics Audio Input Control Service instance.
*
* @return Pointer to the attributes of the service.
*/
void *esp_ble_audio_aics_svc_decl_get(esp_ble_audio_aics_t *aics);
/**
* @brief Initialize the Audio Input Control Service instance.
*
* @param aics Audio Input Control Service instance.
* @param param Audio Input Control Service register parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_register(esp_ble_audio_aics_t *aics,
esp_ble_audio_aics_register_param_t *param);
/**
* @brief Activates an Audio Input Control Service instance.
*
* Audio Input Control Services are activated by default, but this will allow
* the server reactivate an Audio Input Control Service instance after it has
* been deactivated.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_activate(esp_ble_audio_aics_t *inst);
/**
* @brief Deactivates an Audio Input Control Service instance.
*
* Audio Input Control Services are activated by default, but this will allow
* the server to deactivate an Audio Input Control Service.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_deactivate(esp_ble_audio_aics_t *inst);
/**
* @brief Read the Audio Input Control Service input state.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_state_get(esp_ble_audio_aics_t *inst);
/**
* @brief Read the Audio Input Control Service gain settings.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_gain_setting_get(esp_ble_audio_aics_t *inst);
/**
* @brief Read the Audio Input Control Service input type.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_type_get(esp_ble_audio_aics_t *inst);
/**
* @brief Read the Audio Input Control Service input status.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_status_get(esp_ble_audio_aics_t *inst);
/**
* @brief Disable mute in the Audio Input Control Service.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_disable_mute(esp_ble_audio_aics_t *inst);
/**
* @brief Unmute the Audio Input Control Service input.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_unmute(esp_ble_audio_aics_t *inst);
/**
* @brief Mute the Audio Input Control Service input.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_mute(esp_ble_audio_aics_t *inst);
/**
* @brief Set manual only gain mode in Audio Input Control Service.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_gain_set_manual_only(esp_ble_audio_aics_t *inst);
/**
* @brief Set automatic only gain mode in Audio Input Control Service.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_gain_set_auto_only(esp_ble_audio_aics_t *inst);
/**
* @brief Set input gain to manual.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_manual_gain_set(esp_ble_audio_aics_t *inst);
/**
* @brief Set the input gain to automatic.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_automatic_gain_set(esp_ble_audio_aics_t *inst);
/**
* @brief Set the input gain.
*
* @param inst The instance pointer.
* @param gain The gain to set (-128 to 127) in gain setting units.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_gain_set(esp_ble_audio_aics_t *inst, int8_t gain);
/**
* @brief Read the Audio Input Control Service description.
*
* @param inst The instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_description_get(esp_ble_audio_aics_t *inst);
/**
* @brief Set the Audio Input Control Service description.
*
* @param inst The instance pointer.
* @param description The description as an UTF-8 encoded string.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_description_set(esp_ble_audio_aics_t *inst,
const char *description);
/**
* @brief Discover an Audio Input Control Service.
*
* Attempts to discover an Audio Input Control Service on a server given the
* @p param.
*
* @param conn_handle Connection handle.
* @param inst The instance pointer.
* @param param Pointer to the parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_discover(uint16_t conn_handle, esp_ble_audio_aics_t *inst,
const esp_ble_audio_aics_discover_param_t *param);
/**
* @brief Get a new Audio Input Control Service client instance.
*
* @return Pointer to the instance, or NULL if no free instances are left.
*/
esp_ble_audio_aics_t *esp_ble_audio_aics_client_free_instance_get(void);
/**
* @brief Registers the callbacks for the Audio Input Control Service client.
*
* @param inst The instance pointer.
* @param cb Pointer to the callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_aics_client_cb_register(esp_ble_audio_aics_t *inst,
esp_ble_audio_aics_cb_t *cb);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_AICS_API_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,967 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFS_H_
#define ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFS_H_
#include "sdkconfig.h"
#include <zephyr/bluetooth/audio/bap_lc3_preset.h>
#include "esp_ble_audio_lc3_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Struct to hold a BAP defined LC3 preset */
typedef struct bt_bap_lc3_preset esp_ble_audio_bap_lc3_preset_t;
/*!< Helper to declare an LC3 preset structure */
#define ESP_BLE_AUDIO_BAP_LC3_PRESET(_codec, _qos) \
BT_BAP_LC3_PRESET(_codec, _qos)
/**
* @brief Define an LC3 preset configuration.
*
* @param _name Preset configuration name.
* @param _freq Sample frequency (in Hz).
* @param _duration Frame duration (in microseconds).
* @param _loc Audio channel location.
* @param _len Frame length in octets.
* @param _frames_per_sdu Number of frames per SDU.
* @param _stream_context Stream context (e.g., Media, Conversational, etc.).
* @param _interval Audio frame interval (in microseconds).
* @param _sdu SDU size in octets.
* @param _rtn Number of retransmissions.
* @param _latency Maximum transport latency (in milliseconds).
* @param _pd Presentation delay (in microseconds).
*/
#define ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, _freq, _duration, _loc, _len, \
_frames_per_sdu, _stream_context, \
_interval, _sdu, _rtn, _latency, _pd) \
static uint8_t codec_cfg_data_##_name[] = \
ESP_BLE_AUDIO_CODEC_CFG_LC3_DATA(_freq, _duration, _loc, _len, _frames_per_sdu); \
static uint8_t codec_cfg_meta_##_name[] = \
ESP_BLE_AUDIO_CODEC_CFG_LC3_META(_stream_context); \
static esp_ble_audio_bap_lc3_preset_t _name = \
ESP_BLE_AUDIO_BAP_LC3_PRESET(ESP_BLE_AUDIO_CODEC_CFG_LC3(codec_cfg_data_##_name, \
codec_cfg_meta_##_name), \
ESP_BLE_AUDIO_BAP_QOS_CFG_UNFRAMED(_interval, _sdu, _rtn, \
_latency, _pd));
/**
* @brief Helper to declare LC3 Unicast 8_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_8_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 26u, 1, \
_stream_context, \
7500u, 26u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 8_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_8_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 30U, 1, \
_stream_context, \
10000u, 30u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 16_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_16_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 30U, 1, \
_stream_context, \
7500u, 30u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 16_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_16_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 40U, 1, \
_stream_context, \
10000u, 40u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 24_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_24_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 45U, 1, \
_stream_context, \
7500u, 45u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 24_2_1 codec configuration.
*
* Mandatory to support as unicast server.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_24_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 60U, 1, \
_stream_context, \
10000u, 60u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 32_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_32_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 60U, 1, \
_stream_context, \
7500u, 60u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 32_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_32_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 80U, 1, \
_stream_context, \
10000u, 80u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 441_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_441_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 97U, 1, \
_stream_context, \
8163u, 97u, 5u, 24u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 441_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_441_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 130U, 1, \
_stream_context, \
10884u, 130u, 5u, 31u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 75U, 1, \
_stream_context, \
7500u, 75u, 5u, 15u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 100U, 1, \
_stream_context, \
10000u, 100u, 5u, 20u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_3_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_3_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 90U, 1, \
_stream_context, \
7500u, 90u, 5u, 15u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_4_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_4_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 120u, 1, \
_stream_context, \
10000u, 120u, 5u, 20u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_5_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_5_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 117u, 1, \
_stream_context, \
7500u, 117u, 5u, 15u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_6_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_6_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 155u, 1, \
_stream_context, \
10000u, 155u, 5u, 20u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 8_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_8_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 26u, 1, \
_stream_context, \
7500u, 26u, 13u, 75u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 8_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_8_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 30U, 1, \
_stream_context, \
10000u, 30u, 13u, 95u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 16_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_16_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 30U, 1, \
_stream_context, \
7500u, 30u, 13u, 75u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 16_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_16_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 40U, 1, \
_stream_context, \
10000u, 40u, 13u, 95u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 24_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_24_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 45U, 1, \
_stream_context, \
7500u, 45u, 13u, 75u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 24_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_24_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 60U, 1, \
_stream_context, \
10000u, 60u, 13u, 95u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 32_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_32_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 60U, 1, \
_stream_context, \
7500u, 60u, 13u, 75u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 32_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_32_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 80U, 1, \
_stream_context, \
10000u, 80u, 13u, 95u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 441_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_441_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 97U, 1, \
_stream_context, \
8163u, 97u, 13u, 80u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 441_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_441_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 130U, 1, \
_stream_context, \
10884u, 130u, 13u, 85u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 75U, 1, \
_stream_context, \
7500u, 75u, 13u, 75u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 100U, 1, \
_stream_context, \
10000u, 100u, 13u, 95u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_3_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_3_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 90U, 1, \
_stream_context, \
7500u, 90u, 13u, 75u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_4_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_4_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 120u, 1, \
_stream_context, \
10000u, 120u, 13u, 100u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_5_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_5_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 117u, 1, \
_stream_context, \
7500u, 117u, 13u, 75u, 40000u)
/**
* @brief Helper to declare LC3 Unicast 48_6_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_UNICAST_PRESET_48_6_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 155u, 1, \
_stream_context, \
10000u, 155u, 13u, 100u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 8_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_8_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 26u, 1, \
_stream_context, \
7500u, 26u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 8_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_8_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 30U, 1, \
_stream_context, \
10000u, 30u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 16_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_16_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 30U, 1, \
_stream_context, \
7500u, 30u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 16_2_1 codec configuration.
*
* Mandatory to support as both broadcast source and sink.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_16_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 40U, 1, \
_stream_context, \
10000u, 40u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 24_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_24_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 45U, 1, \
_stream_context, \
7500u, 45u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 24_2_1 codec configuration.
*
* Mandatory to support as broadcast sink.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_24_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 60U, 1, \
_stream_context, \
10000u, 60u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 32_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_32_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 60U, 1, \
_stream_context, \
7500u, 60u, 2u, 8u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 32_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_32_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 80U, 1, \
_stream_context, \
10000u, 80u, 2u, 10u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 441_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_441_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 97U, 1, \
_stream_context, \
8163u, 97u, 4u, 24u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 441_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_441_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 130U, 1, \
_stream_context, \
10884u, 130u, 4u, 31u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_1_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_1_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 75U, 1, \
_stream_context, \
7500u, 75u, 4u, 15u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_2_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_2_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 100U, 1, \
_stream_context, \
10000u, 100u, 4u, 20u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_3_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_3_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 90U, 1, \
_stream_context, \
7500u, 90u, 4u, 15u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_4_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_4_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 120u, 1, \
_stream_context, \
10000u, 120u, 4u, 20u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_5_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_5_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 117u, 1, \
_stream_context, \
7500u, 117u, 4u, 15u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_6_1 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_6_1_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 155u, 1, \
_stream_context, \
10000u, 155u, 4u, 20u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 8_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_8_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 26u, 1, \
_stream_context, \
7500u, 26u, 4u, 45u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 8_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_8_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_8KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 30U, 1, \
_stream_context, \
10000u, 30u, 4u, 60u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 16_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_16_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 30U, 1, \
_stream_context, \
7500u, 30u, 4u, 45u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 16_2_2 codec configuration.
*
* Mandatory to support as both broadcast source and sink.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_16_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 40U, 1, \
_stream_context, \
10000u, 40u, 4u, 60u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 24_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_24_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 45U, 1, \
_stream_context, \
7500u, 45u, 4u, 45u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 24_2_2 codec configuration.
*
* Mandatory to support as broadcast sink.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_24_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_24KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 60U, 1, \
_stream_context, \
10000u, 60u, 4u, 60u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 32_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_32_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 60U, 1, \
_stream_context, \
7500u, 60u, 4u, 45u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 32_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_32_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 80U, 1, \
_stream_context, \
10000u, 80u, 4u, 60u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 441_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_441_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 97U, 1, \
_stream_context, \
8163u, 97u, 4u, 54u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 441_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_441_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_44KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 130U, 1, \
_stream_context, \
10884u, 130u, 4u, 60u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_1_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_1_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 75U, 1, \
_stream_context, \
7500u, 75u, 4u, 50u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_2_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_2_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 100U, 1, \
_stream_context, \
10000u, 100u, 4u, 65u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_3_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_3_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 90U, 1, \
_stream_context, \
7500u, 90u, 4u, 50u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_4_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_4_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 120u, 1, \
_stream_context, \
10000u, 120u, 4u, 65u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_5_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_5_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 117u, 1, \
_stream_context, \
7500u, 117u, 4u, 50u, 40000u)
/**
* @brief Helper to declare LC3 Broadcast 48_6_2 codec configuration.
*
* @param _loc Audio channel location bitfield.
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_BAP_LC3_BROADCAST_PRESET_48_6_2_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 155u, 1, \
_stream_context, \
10000u, 155u, 4u, 65u, 40000u)
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_BAP_LC3_PRESET_DEFS_H_ */
@@ -0,0 +1,659 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_CAP_API_H_
#define ESP_BLE_AUDIO_CAP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/cap.h>
#include "common/init.h"
#include "common/host.h"
#include "esp_ble_audio_bap_api.h"
#include "esp_ble_audio_csip_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< The set is an ad-hoc set */
#define ESP_BLE_AUDIO_CAP_SET_TYPE_AD_HOC BT_CAP_SET_TYPE_AD_HOC
/*!< The set is a CSIP Coordinated Set */
#define ESP_BLE_AUDIO_CAP_SET_TYPE_CSIP BT_CAP_SET_TYPE_CSIP
/** Type of CAP set */
typedef enum bt_cap_set_type esp_ble_audio_cap_set_type_t;
/** Common Audio Profile stream structure */
typedef struct bt_cap_stream esp_ble_audio_cap_stream_t;
/** Common Audio Broadcast Source structure */
typedef struct bt_cap_broadcast_source esp_ble_audio_cap_broadcast_source_t;
/** Common Audio Unicast Group structure */
typedef struct bt_cap_unicast_group esp_ble_audio_cap_unicast_group_t;
/** Callback structure for CAP procedures */
typedef struct bt_cap_initiator_cb esp_ble_audio_cap_initiator_cb_t;
/** Union represents a Common Audio Set member that are either in a Coordinated or ad-hoc set */
typedef union bt_cap_set_member esp_ble_audio_cap_set_member_t;
/** Parameter structure for each stream in the unicast group */
typedef struct bt_cap_unicast_group_stream_param \
esp_ble_audio_cap_unicast_group_stream_param_t;
/* Parameter structure for the unicast group functions */
typedef struct bt_cap_unicast_group_stream_pair_param \
esp_ble_audio_cap_unicast_group_stream_pair_param_t;
/** Parameters for the creating unicast groups */
typedef struct bt_cap_unicast_group_param \
esp_ble_audio_cap_unicast_group_param_t;
/** CAP unicast audio stream specific parameters for starting audio */
typedef struct bt_cap_unicast_audio_start_stream_param \
esp_ble_audio_cap_unicast_audio_start_stream_param_t;
/** CAP unicast audio specific parameters for starting audio */
typedef struct bt_cap_unicast_audio_start_param \
esp_ble_audio_cap_unicast_audio_start_param_t;
/** CAP unicast audio stream specific parameters for updating audio */
typedef struct bt_cap_unicast_audio_update_stream_param \
esp_ble_audio_cap_unicast_audio_update_stream_param_t;
/** CAP unicast audio specific parameters for updating audio */
typedef struct bt_cap_unicast_audio_update_param \
esp_ble_audio_cap_unicast_audio_update_param_t;
/** CAP unicast audio specific parameters for stopping audio */
typedef struct bt_cap_unicast_audio_stop_param \
esp_ble_audio_cap_unicast_audio_stop_param_t;
/** CAP Initiator broadcast audio stream specific parameters */
typedef struct bt_cap_initiator_broadcast_stream_param \
esp_ble_audio_cap_initiator_broadcast_stream_param_t;
/** CAP Initiator broadcast audio subgroup specific parameters */
typedef struct bt_cap_initiator_broadcast_subgroup_param \
esp_ble_audio_cap_initiator_broadcast_subgroup_param_t;
/** CAP Initiator broadcast audio specific parameters for creating audio */
typedef struct bt_cap_initiator_broadcast_create_param \
esp_ble_audio_cap_initiator_broadcast_create_param_t;
/** Callback structure for CAP Handover procedures */
typedef struct bt_cap_handover_cb esp_ble_audio_cap_handover_cb_t;
/** CAP Handover unicast audio to broadcast audio specific parameters */
typedef struct bt_cap_handover_unicast_to_broadcast_param \
esp_ble_audio_cap_handover_unicast_to_broadcast_param_t;
/** CAP Handover broadcast audio to unicast audio specific parameters */
typedef struct bt_cap_handover_broadcast_to_unicast_param \
esp_ble_audio_cap_handover_broadcast_to_unicast_param_t;
/** Callback structure for CAP Commander procedures */
typedef struct bt_cap_commander_cb esp_ble_audio_cap_commander_cb_t;
/** CAP Commander broadcast audio member specific parameters for starting audio reception */
typedef struct bt_cap_commander_broadcast_reception_start_member_param \
esp_ble_audio_cap_commander_broadcast_reception_start_member_param_t;
/** CAP Commander broadcast audio specific parameters for starting audio reception */
typedef struct bt_cap_commander_broadcast_reception_start_param \
esp_ble_audio_cap_commander_broadcast_reception_start_param_t;
/** CAP Commander broadcast audio member specific parameters for stopping audio reception */
typedef struct bt_cap_commander_broadcast_reception_stop_member_param \
esp_ble_audio_cap_commander_broadcast_reception_stop_member_param_t;
/** CAP Commander broadcast audio specific parameters for stopping audio reception */
typedef struct bt_cap_commander_broadcast_reception_stop_param \
esp_ble_audio_cap_commander_broadcast_reception_stop_param_t;
/** CAP Commander member parameters for distributing broadcast code */
typedef struct bt_cap_commander_distribute_broadcast_code_member_param \
esp_ble_audio_cap_commander_distribute_broadcast_code_member_param_t;
/** Parameters for distributing broadcast code */
typedef struct bt_cap_commander_distribute_broadcast_code_param \
esp_ble_audio_cap_commander_distribute_broadcast_code_param_t;
/** Parameters for changing absolute volume */
typedef struct bt_cap_commander_change_volume_param \
esp_ble_audio_cap_commander_change_volume_param_t;
/** Parameters for changing volume offset for a member */
typedef struct bt_cap_commander_change_volume_offset_member_param \
esp_ble_audio_cap_commander_change_volume_offset_member_param_t;
/** Parameters for changing volume offset */
typedef struct bt_cap_commander_change_volume_offset_param \
esp_ble_audio_cap_commander_change_volume_offset_param_t;
/** Parameters for changing volume mute state */
typedef struct bt_cap_commander_change_volume_mute_state_param \
esp_ble_audio_cap_commander_change_volume_mute_state_param_t;
/** Parameters for changing microphone mute state */
typedef struct bt_cap_commander_change_microphone_mute_state_param \
esp_ble_audio_cap_commander_change_microphone_mute_state_param_t;
/** Parameters for changing microphone gain setting for a member */
typedef struct bt_cap_commander_change_microphone_gain_setting_member_param \
esp_ble_audio_cap_commander_change_microphone_gain_setting_member_param_t;
/** Parameters for changing microphone gain setting */
typedef struct bt_cap_commander_change_microphone_gain_setting_param \
esp_ble_audio_cap_commander_change_microphone_gain_setting_param_t;
/**
* @brief Register the Common Audio Service.
*
* This will register and enable the service and make it discoverable by
* clients. This will also register a Coordinated Set Identification
* Service instance.
*
* @param param Coordinated Set Identification Service register parameters.
* @param svc_inst Pointer to the registered Coordinated Set Identification Service.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_acceptor_register(const esp_ble_audio_csip_set_member_register_param_t *param,
esp_ble_audio_csip_set_member_svc_inst_t **svc_inst);
/**
* @brief Discovers audio support on a remote device.
*
* This will discover the Common Audio Service (CAS) on the remote device, to
* verify if the remote device supports the Common Audio Profile.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_unicast_discover(uint16_t conn_handle);
/**
* @brief Register Audio operations for a Common Audio Profile stream.
*
* Register Audio operations for a stream.
*
* @param stream Stream object.
* @param ops Stream operations structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_stream_ops_register(esp_ble_audio_cap_stream_t *stream,
esp_ble_audio_bap_stream_ops_t *ops);
/**
* @brief Send data to Common Audio Profile stream without timestamp.
*
* Sends data over the specified CAP audio stream with a sequence number.
*
* @param stream Stream object.
* @param sdu Buffer containing data to be sent.
* @param sdu_len Length of data to be sent.
* @param seq_num Packet Sequence number. This value shall be incremented
* for each call to this function and at least once per SDU
* interval for a specific channel.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_stream_send(esp_ble_audio_cap_stream_t *stream,
const uint8_t *sdu, uint16_t sdu_len,
uint16_t seq_num);
/**
* @brief Send data to Common Audio Profile stream with timestamp.
*
* Sends data over the specified CAP audio stream with a sequence number.
*
* @param stream Stream object.
* @param sdu Buffer containing data to be sent.
* @param sdu_len Length of data to be sent.
* @param seq_num Packet Sequence number. This value shall be incremented
* for each call to this function and at least once per SDU
* interval for a specific channel.
* @param ts Timestamp of the SDU in microseconds (us). This value can
* be used to transmit multiple SDUs in the same SDU interval
* in a CIG or BIG.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_stream_send_ts(esp_ble_audio_cap_stream_t *stream,
const uint8_t *sdu, uint16_t sdu_len,
uint16_t seq_num, uint32_t ts);
/**
* @brief Get ISO transmission timing info for a Common Audio Profile stream.
*
* @param stream Stream object.
* @param info Transmit info object.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_stream_get_tx_sync(esp_ble_audio_cap_stream_t *stream,
esp_ble_iso_tx_info_t *info);
/**
* @brief Create unicast group.
*
* Create a new audio unicast group with one or more audio streams as a unicast client.
* All streams shall share the same framing.
* All streams in the same direction shall share the same interval and latency (see
* esp_ble_audio_bap_qos_cfg_t).
*
* @param param The unicast group create parameters.
* @param unicast_group Pointer to the unicast group created.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_unicast_group_create(const esp_ble_audio_cap_unicast_group_param_t *param,
esp_ble_audio_cap_unicast_group_t **unicast_group);
/**
* @brief Reconfigure unicast group.
*
* Reconfigure a unicast group with one or more audio streams as a unicast client.
* All streams shall share the same framing.
* All streams in the same direction shall share the same interval and latency (see
* esp_ble_audio_bap_qos_cfg_t).
* All streams in @p param shall already belong to @p unicast_group.
* Use esp_ble_audio_cap_unicast_group_add_streams() to add additional streams.
*
* @param unicast_group Pointer to the unicast group created.
* @param param The unicast group reconfigure parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_unicast_group_reconfig(esp_ble_audio_cap_unicast_group_t *unicast_group,
const esp_ble_audio_cap_unicast_group_param_t *param);
/**
* @brief Add streams to a unicast group as a unicast client.
*
* This function can be used to add additional streams to a esp_ble_audio_cap_unicast_group_t.
*
* This can be called at any time before any of the streams in the group has been started
* (see esp_ble_audio_bap_stream_ops_t.started()).
* This can also be called after the streams have been stopped (see
* esp_ble_audio_bap_stream_ops_t.stopped()).
*
* Once a stream has been added to a unicast group, it cannot be removed. To remove a stream
* from a group, the group must be deleted with esp_ble_audio_cap_unicast_group_delete(), but
* this will require all streams in the group to be released first.
*
* @param unicast_group Pointer to the unicast group
* @param params Array of stream parameters with streams being added to the group.
* @param num_param Number of parameters in @p params.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_unicast_group_add_streams(esp_ble_audio_cap_unicast_group_t *unicast_group,
const esp_ble_audio_cap_unicast_group_stream_pair_param_t params[],
size_t num_param);
/**
* @brief Delete audio unicast group.
*
* Delete a audio unicast group as a client. All streams in the group shall
* be in the idle or configured state.
*
* @param unicast_group Pointer to the unicast group to delete.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_unicast_group_delete(esp_ble_audio_cap_unicast_group_t *unicast_group);
/**
* @brief Register Common Audio Profile Initiator callbacks.
*
* @param cb The callback structure. Shall remain static.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_register_cb(const esp_ble_audio_cap_initiator_cb_t *cb);
/**
* @brief Unregister Common Audio Profile Initiator callbacks.
*
* @param cb The callback structure that was previously registered.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_unregister_cb(const esp_ble_audio_cap_initiator_cb_t *cb);
/**
* @brief Setup and start unicast audio streams for a set of devices.
*
* @param param Parameters to start the audio streams.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_start(const esp_ble_audio_cap_unicast_audio_start_param_t *param);
/**
* @brief Update unicast audio streams.
*
* This will update the metadata of one or more streams.
*
* @param param Update parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_update(const esp_ble_audio_cap_unicast_audio_update_param_t *param);
/**
* @brief Stop unicast audio streams.
*
* This will stop one or more streams.
*
* @param param Stop parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_stop(const esp_ble_audio_cap_unicast_audio_stop_param_t *param);
/**
* @brief Cancel any current Common Audio Profile procedure.
*
* This will stop the current procedure from continuing and making it possible to run a new
* Common Audio Profile procedure.
*
* It is recommended to do this if any existing procedure takes longer time than expected, which
* could indicate a missing response from the Common Audio Profile Acceptor.
*
* This does not send any requests to any Common Audio Profile Acceptors involved with the current
* procedure, and thus notifications from the Common Audio Profile Acceptors may arrive after this
* has been called. It is thus recommended to either only use this if a procedure has stalled, or
* wait a short while before starting any new Common Audio Profile procedure after this has been
* called to avoid getting notifications from the cancelled procedure. The wait time depends on
* the connection interval, the number of devices in the previous procedure and the behavior of the
* Common Audio Profile Acceptors.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_unicast_audio_cancel(void);
/**
* @brief Create a Common Audio Profile broadcast source.
*
* Create a new audio broadcast source with one or more audio streams.
*
* @param param Parameters to start the audio streams.
* @param broadcast_source Pointer to the broadcast source created.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_create(const esp_ble_audio_cap_initiator_broadcast_create_param_t *param,
esp_ble_audio_cap_broadcast_source_t **broadcast_source);
/**
* @brief Start Common Audio Profile broadcast source.
*
* The broadcast source will be visible for scanners once this has been called,
* and the device will advertise audio announcements.
*
* @param broadcast_source Pointer to the broadcast source.
* @param adv_handle Handle of an extended advertising set with
* periodic advertising configured.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_start(
esp_ble_audio_cap_broadcast_source_t *broadcast_source,
uint8_t adv_handle);
/**
* @brief Update broadcast audio streams for a Common Audio Profile broadcast source.
*
* @param broadcast_source The broadcast source to update.
* @param meta The new metadata. The metadata shall contain a list
* of CCIDs as well as a non-0 context bitfield.
* @param meta_len The length of @p meta.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_update(esp_ble_audio_cap_broadcast_source_t *broadcast_source,
const uint8_t meta[], size_t meta_len);
/**
* @brief Stop broadcast audio streams for a Common Audio Profile broadcast source.
*
* @param broadcast_source The broadcast source to stop. The audio streams
* in this will be stopped and reset.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_stop(esp_ble_audio_cap_broadcast_source_t *broadcast_source);
/**
* @brief Delete Common Audio Profile broadcast source.
*
* @param broadcast_source The broadcast source to delete.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_broadcast_audio_delete(esp_ble_audio_cap_broadcast_source_t *broadcast_source);
/**
* @brief Get the Broadcast Audio Stream Endpoint of a Common Audio Profile
* broadcast source.
*
* This will encode the BASE of a broadcast source into a buffer, that can be
* used for advertisement. The encoded BASE will thus be encoded as
* little-endian. The BASE shall be put into the periodic advertising data.
*
* See table 3.15 in the Basic Audio Profile v1.0.1 for the structure.
*
* @param broadcast_source Pointer to the broadcast source.
* @param base_buf Pointer to a buffer where the BASE will be inserted.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_initiator_broadcast_get_base(esp_ble_audio_cap_broadcast_source_t *broadcast_source,
struct net_buf_simple *base_buf);
/**
* @brief Register Common Audio Profile Handover callbacks.
*
* @param cb The callback structure. Shall remain static.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_handover_register_cb(const esp_ble_audio_cap_handover_cb_t *cb);
/**
* @brief Unregister Common Audio Profile Handover callbacks.
*
* @param cb The callback structure that was previously registered.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_handover_unregister_cb(const esp_ble_audio_cap_handover_cb_t *cb);
/**
* @brief Hands over the sink streams in a unicast group to a broadcast source.
*
* All streams in the provided unicast group will be stopped and released. The sink streams
* will be transferred to a broadcast source, and the broadcast source information will be
* shared with all accepters that are currently receiving audio. Any stream that is not in
* the streaming state will only be released.
*
* esp_ble_audio_bap_broadcast_assistant_discover() must have been successfully perform for
* all members in @p param before starting this procedure.
*
* @param param The parameters for the handover.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_handover_unicast_to_broadcast(
const esp_ble_audio_cap_handover_unicast_to_broadcast_param_t *param);
/**
* @brief Hands over the data streams in a broadcast source to a unicast group.
*
* The streams in the broadcast source will be stopped and the broadcast source
* will be deleted.
*
* @param param The parameters for the handover.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_handover_broadcast_to_unicast(
const esp_ble_audio_cap_handover_broadcast_to_unicast_param_t *param);
/**
* @brief Register Common Audio Profile Commander callbacks.
*
* @param cb The callback structure. Shall remain static.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_register_cb(const esp_ble_audio_cap_commander_cb_t *cb);
/**
* @brief Unregister Common Audio Profile Commander callbacks.
*
* @param cb The callback structure that was previously registered.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_unregister_cb(const esp_ble_audio_cap_commander_cb_t *cb);
/**
* @brief Discovers audio support on a remote device.
*
* This will discover the Common Audio Service (CAS) on the remote device,
* to verify if the remote device supports the Common Audio Profile.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_discover(uint16_t conn_handle);
/**
* @brief Cancel any current Common Audio Profile commander procedure.
*
* This will stop the current procedure from continuing and making it possible to run a new
* Common Audio Profile procedure.
*
* It is recommended to do this if any existing procedure takes longer time than expected, which
* could indicate a missing response from the Common Audio Profile Acceptor.
*
* This does not send any requests to any Common Audio Profile Acceptors involved with the
* current procedure, and thus notifications from the Common Audio Profile Acceptors may
* arrive after this has been called. It is thus recommended to either only use this if a
* procedure has stalled, or wait a short while before starting any new Common Audio Profile
* procedure after this has been called to avoid getting notifications from the cancelled
* procedure. The wait time depends on the connection interval, the number of devices in the
* previous procedure and the behavior of the Common Audio Profile Acceptors.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_cancel(void);
/**
* @brief Starts the reception of broadcast audio on one or more remote
* Common Audio Profile Acceptors.
*
* @param param The parameters to start the broadcast audio
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_broadcast_reception_start(
const esp_ble_audio_cap_commander_broadcast_reception_start_param_t *param);
/**
* @brief Stops the reception of broadcast audio on one or more remote
* Common Audio Profile Acceptors.
*
* @param param The parameters to stop the broadcast audio
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_broadcast_reception_stop(
const esp_ble_audio_cap_commander_broadcast_reception_stop_param_t *param);
/**
* @brief Distributes the broadcast code on one or more remote Common
* Audio Profile Acceptors.
*
* @param param The parameters for distributing the broadcast code.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_distribute_broadcast_code(
const esp_ble_audio_cap_commander_distribute_broadcast_code_param_t *param);
/**
* @brief Change the volume on one or more Common Audio Profile Acceptors.
*
* @param param The parameters for the volume change.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_change_volume(
const esp_ble_audio_cap_commander_change_volume_param_t *param);
/**
* @brief Change the volume offset on one or more Common Audio Profile Acceptors.
*
* @param param The parameters for the volume offset change.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_change_volume_offset(
const esp_ble_audio_cap_commander_change_volume_offset_param_t *param);
/**
* @brief Change the volume mute state on one or more Common Audio Profile Acceptors.
*
* @param param The parameters for the volume mute state change.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_change_volume_mute_state(
const esp_ble_audio_cap_commander_change_volume_mute_state_param_t *param);
/**
* @brief Change the microphone mute state on one or more Common Audio Profile Acceptors.
*
* @param param The parameters for the microphone mute state change.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_change_microphone_mute_state(
const esp_ble_audio_cap_commander_change_microphone_mute_state_param_t *param);
/**
* @brief Change the microphone gain setting on one or more Common Audio Profile Acceptors.
*
* @param param The parameters for the microphone gain setting change.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_cap_commander_change_microphone_gain_setting(
const esp_ble_audio_cap_commander_change_microphone_gain_setting_param_t *param);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_CAP_API_H_ */
@@ -0,0 +1,171 @@
/*
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_CCP_API_H_
#define ESP_BLE_AUDIO_CCP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/ccp.h>
#include "common/init.h"
#include "common/host.h"
#include "esp_ble_audio_tbs_api.h"
#include "esp_ble_audio_common_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Abstract Call Control Server Telephone Bearer structure */
typedef struct bt_ccp_call_control_server_bearer \
esp_ble_audio_ccp_call_control_server_bearer_t;
/** Abstract Call Control Client structure. */
typedef struct bt_ccp_call_control_client \
esp_ble_audio_ccp_call_control_client_t;
/** Abstract Call Control Client bearer structure. */
typedef struct bt_ccp_call_control_client_bearer \
esp_ble_audio_ccp_call_control_client_bearer_t;
/** Struct with information about bearers of a client */
typedef struct bt_ccp_call_control_client_bearers \
esp_ble_audio_ccp_call_control_client_bearers_t;
/** Struct to hold the Telephone Bearer Service client callbacks */
typedef struct bt_ccp_call_control_client_cb \
esp_ble_audio_ccp_call_control_client_cb_t;
/**
* @brief Register a Telephone Bearer.
*
* This will register a Telephone Bearer Service (TBS) (or a Generic Telephone
* Bearer service (GTBS)) with the provided parameters.
*
* As per the TBS specification, the GTBS shall be instantiated for the feature,
* and as such a GTBS shall always be registered before any TBS can be registered.
* Similarly, all TBS shall be unregistered before the GTBS can be unregistered
* with esp_ble_audio_ccp_call_control_server_unregister_bearer().
*
* @param param The parameters to initialize the bearer.
* @param bearer Pointer to the initialized bearer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_server_register_bearer(
const esp_ble_audio_tbs_register_param_t *param,
esp_ble_audio_ccp_call_control_server_bearer_t **bearer);
/**
* @brief Unregister a Telephone Bearer.
*
* This will unregister a Telephone Bearer Service (TBS) (or a Generic Telephone
* Bearer service (GTBS)) with the provided parameters. The bearer shall be
* registered first by esp_ble_audio_ccp_call_control_server_register_bearer()
* before it can be unregistered.
*
* All TBS shall be unregistered before the GTBS can be unregistered with.
*
* @param bearer The bearer to unregister.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_server_unregister_bearer(
esp_ble_audio_ccp_call_control_server_bearer_t *bearer);
/**
* @brief Set a new bearer provider name.
*
* @param bearer The bearer to set the name for.
* @param name The new bearer provider name.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_server_set_bearer_provider_name(
esp_ble_audio_ccp_call_control_server_bearer_t *bearer, const char *name);
/**
* @brief Get the bearer provider name.
*
* @param bearer The bearer to get the name for.
* @param name Pointer that will be updated to be the bearer provider name.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_server_get_bearer_provider_name(
esp_ble_audio_ccp_call_control_server_bearer_t *bearer, const char **name);
/**
* @brief Discovers the Telephone Bearer Service (TBS) support on a remote device.
*
* This will discover the Telephone Bearer Service (TBS) and Generic Telephone Bearer
* Service (GTBS) on the remote device.
*
* @param conn Connection to a remote server.
* @param out_client Pointer to client instance on success.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_client_discover(
esp_ble_conn_t *conn, esp_ble_audio_ccp_call_control_client_t **out_client);
/**
* @brief Register callbacks for the Call Control Client.
*
* @param cb The callback struct.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_client_register_cb(
esp_ble_audio_ccp_call_control_client_cb_t *cb);
/**
* @brief Unregister callbacks for the Call Control Client.
*
* @param cb The callback struct.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_client_unregister_cb(
esp_ble_audio_ccp_call_control_client_cb_t *cb);
/**
* @brief Get the bearers of a client instance.
*
* @param client The client to get the bearers of.
* @param bearers The bearers struct that will be populated
* with the bearers of @p client.
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_client_get_bearers(
esp_ble_audio_ccp_call_control_client_t *client,
esp_ble_audio_ccp_call_control_client_bearers_t *bearers);
/**
* @brief Read the bearer provider name of a remote TBS bearer.
*
* @param bearer The bearer to read the name from.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_ccp_call_control_client_read_bearer_provider_name(
esp_ble_audio_ccp_call_control_client_bearer_t *bearer);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_CCP_API_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,172 @@
/*
* SPDX-FileCopyrightText: 2020 Intel Corporation
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_COMMON_API_H_
#define ESP_BLE_AUDIO_COMMON_API_H_
#include <stdint.h>
#include <string.h>
#include <stddef.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include "common/init.h"
#include "common/host.h"
#include "common/app/gatt.h"
#include "esp_ble_iso_common_api.h"
#include "esp_ble_audio_defs.h"
#include "esp_ble_audio_csip_api.h"
#include "esp_ble_audio_vcp_api.h"
#include "esp_ble_audio_micp_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Helper for parsing length-type-value data.
*
* @param ltv Length-type-value (LTV) encoded data.
* @param size Size of the @p ltv data.
* @param func Callback function which will be called for each element
* that's found in the data. The callback should return
* true to continue parsing, or false to stop parsing.
* @param user_data User data to be passed to the callback.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_data_parse(const uint8_t ltv[], size_t size,
bool (*func)(uint8_t type,
const uint8_t *data,
uint8_t data_len,
void *user_data),
void *user_data);
/**
* @brief Get the value of a specific data type in an length-type-value data array.
*
* @param ltv_data The array containing the length-type-value tuples.
* @param size The size of @p ltv_data.
* @param type The type to get the value for.
* @param data Pointer to the data-pointer to update when item is found.
* Any found data will be little endian.
* @param data_len Length The length of found @p data (may be 0).
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_data_get_val(const uint8_t ltv_data[],
size_t size, uint8_t type,
const uint8_t **data,
uint8_t *data_len);
/**
* @brief Function to get the number of channels from the channel allocation.
*
* @param chan_allocation The channel allocation.
*
* @return The number of channels.
*/
uint8_t esp_ble_audio_get_chan_count(esp_ble_audio_location_t chan_allocation);
/**
* @brief Start GATT service discovery.
*
* @note This function is only needed while using NimBLE Host.
*
* @param conn_handle Connection Handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_gattc_disc_start(uint16_t conn_handle);
/*!< Audio GAP Extended Scan Recv event */
#define ESP_BLE_AUDIO_GAP_EVENT_EXT_SCAN_RECV BT_LE_GAP_APP_EVENT_EXT_SCAN_RECV
/*!< Audio GAP Periodic Sync Established event */
#define ESP_BLE_AUDIO_GAP_EVENT_PA_SYNC BT_LE_GAP_APP_EVENT_PA_SYNC
/*!< Audio GAP Periodic Sync Lost event */
#define ESP_BLE_AUDIO_GAP_EVENT_PA_SYNC_LOST BT_LE_GAP_APP_EVENT_PA_SYNC_LOST
/*!< Audio GAP Connection Complete event */
#define ESP_BLE_AUDIO_GAP_EVENT_ACL_CONNECT BT_LE_GAP_APP_EVENT_ACL_CONNECT
/*!< Audio GAP Disconnection Complete event */
#define ESP_BLE_AUDIO_GAP_EVENT_ACL_DISCONNECT BT_LE_GAP_APP_EVENT_ACL_DISCONNECT
/*!< Audio GAP Security Change event */
#define ESP_BLE_AUDIO_GAP_EVENT_SECURITY_CHANGE BT_LE_GAP_APP_EVENT_SECURITY_CHANGE
/** Audio GAP application event structure */
typedef struct bt_le_gap_app_event esp_ble_audio_gap_app_event_t;
/*!< Audio GATT MTU exchange complete event */
#define ESP_BLE_AUDIO_GATT_EVENT_GATT_MTU_CHANGE BT_LE_GATT_APP_EVENT_GATT_MTU_CHANGE
/*!< Audio GATT client discovery complete event */
#define ESP_BLE_AUDIO_GATT_EVENT_GATTC_DISC_CMPL BT_LE_GATT_APP_EVENT_GATTC_DISC_CMPL
/** Audio GATT application event structure */
typedef struct bt_le_gatt_app_event esp_ble_audio_gatt_app_event_t;
/** Contains callback functions for GAP and GATT events */
typedef struct {
bt_le_gap_app_cb gap_cb; /*!< GAP event callbacks */
bt_le_gatt_app_cb gatt_cb; /*!< GATT event callbacks */
} esp_ble_audio_init_info_t;
/**
* @brief Post an application-layer GAP event for audio internal usage.
*
* @note This function is only needed while using NimBLE Host.
*
* @param type Event type.
* @param param Event parameters.
*/
void esp_ble_audio_gap_app_post_event(uint8_t type, void *param);
/**
* @brief Post an application-layer GATT event for audio internal usage.
*
* @note This function is only needed while using NimBLE Host.
*
* @param type Event type.
* @param param Event parameters.
*/
void esp_ble_audio_gatt_app_post_event(uint8_t type, void *param);
/**
* @brief Initialize BLE Audio common functionality.
*
* @param info Initialization parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_common_init(esp_ble_audio_init_info_t *info);
/** Contains service instances for audio profiles */
typedef struct {
#if CONFIG_BT_CSIP_SET_MEMBER
struct {
esp_ble_audio_csip_set_member_svc_inst_t *svc_inst; /*!< Pointer of CSIS Service instance */
bool included_by_cas; /*!< Indicate if the CSIS Service is included by CAS */
} csis_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT]; /*!< Structures of CSIS Service instances */
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
uint8_t dummy; /*!< Dummy field to avoid empty struct */
} esp_ble_audio_start_info_t;
/**
* @brief Start BLE Audio services.
*
* @param info Service instances to start.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_common_start(esp_ble_audio_start_info_t *info);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_COMMON_API_H_ */
@@ -0,0 +1,294 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_CSIP_API_H_
#define ESP_BLE_AUDIO_CSIP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/csip.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< Size of the Set Identification Resolving Key (SIRK) */
#define ESP_BLE_AUDIO_CSIP_SIRK_SIZE BT_CSIP_SIRK_SIZE
/*!< Size of the Resolvable Set Identifier (RSI) */
#define ESP_BLE_AUDIO_CSIP_RSI_SIZE BT_CSIP_RSI_SIZE
/*!< Accept the request to read the SIRK as plaintext */
#define ESP_BLE_AUDIO_CSIP_READ_SIRK_REQ_RSP_ACCEPT BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT
/*!< Accept the request to read the SIRK, but return encrypted SIRK */
#define ESP_BLE_AUDIO_CSIP_READ_SIRK_REQ_RSP_ACCEPT_ENC BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT_ENC
/*!< Reject the request to read the SIRK */
#define ESP_BLE_AUDIO_CSIP_READ_SIRK_REQ_RSP_REJECT BT_CSIP_READ_SIRK_REQ_RSP_REJECT
/*!< SIRK is available only via an OOB procedure */
#define ESP_BLE_AUDIO_CSIP_READ_SIRK_REQ_RSP_OOB_ONLY BT_CSIP_READ_SIRK_REQ_RSP_OOB_ONLY
/**
* @brief Helper to declare bt_data array including RSI.
*
* This macro is mainly for creating an array of struct bt_data elements.
*
* @param _rsi Pointer to the RSI value.
*/
#define ESP_BLE_AUDIO_CSIP_DATA_RSI(_rsi) BT_CSIP_DATA_RSI(_rsi)
/** Callback structure for the Coordinated Set Identification Service */
typedef struct bt_csip_set_member_cb esp_ble_audio_csip_set_member_cb_t;
/** Coordinated Set Identification Service instance */
typedef struct bt_csip_set_member_svc_inst esp_ble_audio_csip_set_member_svc_inst_t;
/** Register structure for Coordinated Set Identification Service */
typedef struct bt_csip_set_member_register_param esp_ble_audio_csip_set_member_register_param_t;
/** Struct to hold information about a service instance */
typedef struct bt_csip_set_member_set_info esp_ble_audio_csip_set_member_set_info_t;
/** Struct to hold the Coordinated Set Identification Profile Set Coordinator callbacks */
typedef struct bt_csip_set_coordinator_cb esp_ble_audio_csip_set_coordinator_cb_t;
/** Information about a specific set */
typedef struct bt_csip_set_coordinator_set_info esp_ble_audio_csip_set_coordinator_set_info_t;
/** Struct representing a coordinated set instance on a remote device */
typedef struct bt_csip_set_coordinator_csis_inst esp_ble_audio_csip_set_coordinator_csis_inst_t;
/** Struct representing a remote device as a set member */
typedef struct bt_csip_set_coordinator_set_member esp_ble_audio_csip_set_coordinator_set_member_t;
/**
* @brief Get the service declaration attribute.
*
* The first service attribute can be included in any other GATT service.
*
* @param svc_inst Pointer to the Coordinated Set Identification Service.
*
* @return The first CSIS attribute instance.
*/
void *esp_ble_audio_csip_set_member_svc_decl_get(const esp_ble_audio_csip_set_member_svc_inst_t *svc_inst);
/**
* @brief Register a Coordinated Set Identification Service instance.
*
* This will register and enable the service and make it discoverable by clients.
*
* This shall only be done as a server.
*
* @param param Coordinated Set Identification Service register parameters.
* @param svc_inst Pointer to the registered Coordinated Set Identification Service.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_member_register(const esp_ble_audio_csip_set_member_register_param_t *param,
esp_ble_audio_csip_set_member_svc_inst_t **svc_inst);
/**
* @brief Unregister a Coordinated Set Identification Service instance.
*
* This will unregister and disable the service instance.
*
* @param svc_inst Pointer to the registered Coordinated Set Identification Service.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_member_unregister(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst);
/**
* @brief Set the SIRK of a service instance.
*
* @param svc_inst Pointer to the registered Coordinated Set Identification Service.
* @param sirk The new SIRK.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_member_sirk(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
const uint8_t sirk[ESP_BLE_AUDIO_CSIP_SIRK_SIZE]);
/**
* @brief Set a new size and rank for a service instance.
*
* This function can be used to dynamically change the size and rank of a service instance.
* It is important to note that a set cannot have multiple devices with the same rank in a
* set, and it is up to the caller of this function to ensure that.
* Similarly, it is important that the size is updated on all devices in the set at the same
* time.
*
* If CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE is enabled, this will also send a notification
* to all connected or bonded clients.
*
* @param svc_inst The service instance.
* @param size The new set size.
* @param rank The new rank. Ignored if the @p svc_inst is not lockable.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_member_set_size_and_rank(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
uint8_t size, uint8_t rank);
/**
* @brief Get information about a service instances.
*
* @param svc_inst The service instance.
* @param info Pointer to a struct to store the information in.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_member_get_info(const esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
esp_ble_audio_csip_set_member_set_info_t *info);
/**
* @brief Generate the Resolvable Set Identifier (RSI) value.
*
* This will generate RSI for given @p svc_inst instance.
*
* @param svc_inst Pointer to the Coordinated Set Identification Service.
* @param rsi Pointer to the 6-octet newly generated RSI data in little-endian.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_member_generate_rsi(const esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
uint8_t rsi[ESP_BLE_AUDIO_CSIP_RSI_SIZE]);
/**
* @brief Locks a specific Coordinated Set Identification Service instance on the server.
*
* @param svc_inst Pointer to the Coordinated Set Identification Service.
* @param lock If true lock the set, if false release the set.
* @param force This argument only have meaning when @p lock is false
* (release) and will force release the lock, regardless of who
* took the lock.
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_member_lock(esp_ble_audio_csip_set_member_svc_inst_t *svc_inst,
bool lock, bool force);
/**
* @brief Initialise the csip_set_coordinator instance for a connection.
* This will do a discovery on the device and prepare the instance
* for following commands.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_coordinator_discover(uint16_t conn_handle);
/**
* @brief Get the set member from a connection pointer.
*
* Get the Coordinated Set Identification Profile Set Coordinator pointer
* from connection handle.
* Only Set Coordinators that have been initiated can be retrieved.
*
* @param conn_handle Connection handle.
*
* @return Pointer to a Coordinated Set Identification Profile Set Coordinator instance.
* NULL if the connection has not been found or has not done discovery yet.
*/
esp_ble_audio_csip_set_coordinator_set_member_t *
esp_ble_audio_csip_set_coordinator_set_member_by_conn(uint16_t conn_handle);
/**
* @brief Check if advertising data indicates a set member.
*
* @param sirk The SIRK of the set to check against.
* @param data_type Type of the advertising data.
* @param data Pointer of the advertising data.
* @param data_len Length of the advertising data.
*
* @return True if the advertising data indicates a set member, false otherwise.
*/
bool esp_ble_audio_csip_set_coordinator_is_set_member(const uint8_t sirk[ESP_BLE_AUDIO_CSIP_SIRK_SIZE],
uint8_t data_type, const uint8_t *data, uint8_t data_len);
/**
* @brief Registers callbacks for csip_set_coordinator.
*
* @param cb Pointer to the callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_coordinator_register_cb(esp_ble_audio_csip_set_coordinator_cb_t *cb);
/**
* @brief Access Coordinated Set devices in an ordered manner as a client.
*
* This function will read the lock state of all devices and if all devices are
* in the unlocked state, then @p cb will be called with the same members as
* provided by @p members, but where the members are ordered by rank (if present).
*
* This procedure only works if all the members have the lock characteristic,
* and all either has rank = 0 or unique ranks.
*
* If any of the members are in the locked state, the procedure will be cancelled.
*
* This can only be done on members that are bonded.
*
* @param members Array of set members to access.
* @param count Number of set members in @p members.
* @param set_info Pointer to the a specific set_info struct, as a member may
* be part of multiple sets.
* @param cb The callback function to be called for each member.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_coordinator_ordered_access(const esp_ble_audio_csip_set_coordinator_set_member_t *members[],
uint8_t count,
const esp_ble_audio_csip_set_coordinator_set_info_t *set_info,
bt_csip_set_coordinator_ordered_access_t cb);
/**
* @brief Lock an array of set members.
*
* The members will be locked starting from lowest rank going up.
*
* @param members Array of set members to lock.
* @param count Number of set members in @p members.
* @param set_info Pointer to the a specific set_info struct, as a member
* may be part of multiple sets.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_coordinator_lock(const esp_ble_audio_csip_set_coordinator_set_member_t **members,
uint8_t count,
const esp_ble_audio_csip_set_coordinator_set_info_t *set_info);
/**
* @brief Release an array of set members.
*
* The members will be released starting from highest rank going down.
*
* @param members Array of set members to lock.
* @param count Number of set members in @p members.
* @param set_info Pointer to the a specific set_info struct, as a member
* may be part of multiple sets.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_csip_set_coordinator_release(const esp_ble_audio_csip_set_coordinator_set_member_t **members,
uint8_t count,
const esp_ble_audio_csip_set_coordinator_set_info_t *set_info);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_CSIP_API_H_ */
@@ -0,0 +1,567 @@
/*
* SPDX-FileCopyrightText: 2020 Intel Corporation
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_DEFS_H_
#define ESP_BLE_AUDIO_DEFS_H_
#include <stdint.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include <zephyr/bluetooth/audio/audio.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!< Minimum ATT MTU size required by Basic Audio Profile (BAP) */
#define ESP_BLE_AUDIO_ATT_MTU_MIN 64
/**
* Audio direction sink.
*
* For a BAP Unicast Client or Broadcast Source this is considered outgoing audio (TX).
* For a BAP Unicast Server or Broadcast Sink this is considered incoming audio (RX).
*/
#define ESP_BLE_AUDIO_DIR_SINK BT_AUDIO_DIR_SINK
/**
* Audio direction source.
*
* For a BAP Unicast Client or Broadcast Source this is considered incoming audio (RX).
* For a BAP Unicast Server or Broadcast Sink this is considered outgoing audio (TX).
*/
#define ESP_BLE_AUDIO_DIR_SOURCE BT_AUDIO_DIR_SOURCE
/** Audio direction from the perspective of the BAP Unicast Server / BAP Broadcast Sink */
typedef enum bt_audio_dir esp_ble_audio_dir_t;
/*!< Size of the stream language value, e.g. "eng" */
#define ESP_BLE_AUDIO_LANG_SIZE BT_AUDIO_LANG_SIZE
/*!< Size of the broadcast ID in octets */
#define ESP_BLE_AUDIO_BROADCAST_ID_SIZE BT_AUDIO_BROADCAST_ID_SIZE
/*!< Maximum broadcast ID value */
#define ESP_BLE_AUDIO_BROADCAST_ID_MAX BT_AUDIO_BROADCAST_ID_MAX
/*!< Indicates that the server have no preference for the presentation delay */
#define ESP_BLE_AUDIO_PD_PREF_NONE BT_AUDIO_PD_PREF_NONE
/*!< Maximum presentation delay in microseconds */
#define ESP_BLE_AUDIO_PD_MAX BT_AUDIO_PD_MAX
/*!< Indicates that the unicast server does not have a preference for any retransmission number */
#define ESP_BLE_AUDIO_RTN_PREF_NONE BT_AUDIO_RTN_PREF_NONE
/*!< The minimum size of a Broadcast Name as defined by Bluetooth Assigned Numbers */
#define ESP_BLE_AUDIO_BROADCAST_NAME_LEN_MIN BT_AUDIO_BROADCAST_NAME_LEN_MIN
/*!< The maximum size of a Broadcast Name as defined by Bluetooth Assigned Numbers */
#define ESP_BLE_AUDIO_BROADCAST_NAME_LEN_MAX BT_AUDIO_BROADCAST_NAME_LEN_MAX
/*!< Unicast Server is connectable and is requesting a connection. */
#define ESP_BLE_AUDIO_UNICAST_ANNOUNCEMENT_GENERAL BT_AUDIO_UNICAST_ANNOUNCEMENT_GENERAL
/*!< Unicast Server is connectable but is not requesting a connection. */
#define ESP_BLE_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED
/*!< No context type */
#define ESP_BLE_AUDIO_CONTEXT_TYPE_NONE BT_AUDIO_CONTEXT_TYPE_NONE
/**
* Identifies audio where the use case context does not match any other defined value,
* or where the context is unknown or cannot be determined.
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_UNSPECIFIED BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED
/**
* Conversation between humans, for example, in telephony or video calls, including
* traditional cellular as well as VoIP and Push-to-Talk
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_CONVERSATIONAL BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL
/*!< Media, for example, music playback, radio, podcast or movie soundtrack, or tv audio */
#define ESP_BLE_AUDIO_CONTEXT_TYPE_MEDIA BT_AUDIO_CONTEXT_TYPE_MEDIA
/**
* Audio associated with video gaming, for example gaming media; gaming effects; music
* and in-game voice chat between participants; or a mix of all the above
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_GAME BT_AUDIO_CONTEXT_TYPE_GAME
/*!< Instructional audio, for example, in navigation, announcements, or user guidance */
#define ESP_BLE_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL BT_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL
/*!< Man-machine communication, for example, with voice recognition or virtual assistants */
#define ESP_BLE_AUDIO_CONTEXT_TYPE_VOICE_ASSISTANTS BT_AUDIO_CONTEXT_TYPE_VOICE_ASSISTANTS
/**
* Live audio, for example, from a microphone where audio is perceived both through a
* direct acoustic path and through an LE Audio Stream
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_LIVE BT_AUDIO_CONTEXT_TYPE_LIVE
/**
* Sound effects including keyboard and touch feedback; menu and user interface sounds;
* and other system sounds
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_SOUND_EFFECTS BT_AUDIO_CONTEXT_TYPE_SOUND_EFFECTS
/**
* Notification and reminder sounds; attention-seeking audio, for example,
* in beeps signaling the arrival of a message
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_NOTIFICATIONS BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS
/**
* Alerts the user to an incoming call, for example, an incoming telephony or video call,
* including traditional cellular as well as VoIP and Push-to-Talk
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_RINGTONE BT_AUDIO_CONTEXT_TYPE_RINGTONE
/**
* Alarms and timers; immediate alerts, for example, in a critical battery alarm,
* timer expiry or alarm clock, toaster, cooker, kettle, microwave, etc.
*/
#define ESP_BLE_AUDIO_CONTEXT_TYPE_ALERTS BT_AUDIO_CONTEXT_TYPE_ALERTS
/*!< Emergency alarm Emergency sounds, for example, fire alarms or other urgent alerts */
#define ESP_BLE_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM BT_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM
/*!< Any known context */
#define ESP_BLE_AUDIO_CONTEXT_TYPE_ANY BT_AUDIO_CONTEXT_TYPE_ANY
/** Audio Context Type for Generic Audio */
typedef enum bt_audio_context esp_ble_audio_context_t;
/*!< No rating */
#define ESP_BLE_AUDIO_PARENTAL_RATING_NO_RATING BT_AUDIO_PARENTAL_RATING_NO_RATING
/*!< For all ages */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_ANY BT_AUDIO_PARENTAL_RATING_AGE_ANY
/*!< Recommended for listeners of age 5 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_5_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_5_OR_ABOVE
/*!< Recommended for listeners of age 6 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_6_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_6_OR_ABOVE
/*!< Recommended for listeners of age 7 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_7_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_7_OR_ABOVE
/*!< Recommended for listeners of age 8 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_8_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_8_OR_ABOVE
/*!< Recommended for listeners of age 9 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_9_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_9_OR_ABOVE
/*!< Recommended for listeners of age 10 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE
/*!< Recommended for listeners of age 11 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_11_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_11_OR_ABOVE
/*!< Recommended for listeners of age 12 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_12_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_12_OR_ABOVE
/*!< Recommended for listeners of age 13 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_13_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_13_OR_ABOVE
/*!< Recommended for listeners of age 14 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_14_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_14_OR_ABOVE
/*!< Recommended for listeners of age 15 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_15_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_15_OR_ABOVE
/*!< Recommended for listeners of age 16 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_16_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_16_OR_ABOVE
/*!< Recommended for listeners of age 17 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_17_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_17_OR_ABOVE
/*!< Recommended for listeners of age 18 and above */
#define ESP_BLE_AUDIO_PARENTAL_RATING_AGE_18_OR_ABOVE BT_AUDIO_PARENTAL_RATING_AGE_18_OR_ABOVE
/** Parental rating defined by the Generic Audio assigned numbers */
typedef enum bt_audio_parental_rating esp_ble_audio_parental_rating_t;
/*!< No audio data is being transmitted */
#define ESP_BLE_AUDIO_ACTIVE_STATE_DISABLED BT_AUDIO_ACTIVE_STATE_DISABLED
/*!< Audio data is being transmitted */
#define ESP_BLE_AUDIO_ACTIVE_STATE_ENABLED BT_AUDIO_ACTIVE_STATE_ENABLED
/** Audio Active State defined by the Generic Audio assigned numbers */
typedef enum bt_audio_active_state esp_ble_audio_active_state_t;
/*!< Preferred audio context */
#define ESP_BLE_AUDIO_METADATA_TYPE_PREF_CONTEXT BT_AUDIO_METADATA_TYPE_PREF_CONTEXT
/*!< Streaming audio context */
#define ESP_BLE_AUDIO_METADATA_TYPE_STREAM_CONTEXT BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT
/*!< UTF-8 encoded title or summary of stream content */
#define ESP_BLE_AUDIO_METADATA_TYPE_PROGRAM_INFO BT_AUDIO_METADATA_TYPE_PROGRAM_INFO
/*!< Language */
#define ESP_BLE_AUDIO_METADATA_TYPE_LANG BT_AUDIO_METADATA_TYPE_LANG
/*!< Array of 8-bit CCID values */
#define ESP_BLE_AUDIO_METADATA_TYPE_CCID_LIST BT_AUDIO_METADATA_TYPE_CCID_LIST
/*!< Parental rating */
#define ESP_BLE_AUDIO_METADATA_TYPE_PARENTAL_RATING BT_AUDIO_METADATA_TYPE_PARENTAL_RATING
/*!< UTF-8 encoded URI for additional Program information */
#define ESP_BLE_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI
/*!< Audio active state */
#define ESP_BLE_AUDIO_METADATA_TYPE_AUDIO_STATE BT_AUDIO_METADATA_TYPE_AUDIO_STATE
/*!< Broadcast Audio Immediate Rendering flag */
#define ESP_BLE_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE
/*!< Assisted listening stream */
#define ESP_BLE_AUDIO_METADATA_TYPE_ASSISTED_LISTENING_STREAM BT_AUDIO_METADATA_TYPE_ASSISTED_LISTENING_STREAM
/*!< UTF-8 encoded Broadcast name */
#define ESP_BLE_AUDIO_METADATA_TYPE_BROADCAST_NAME BT_AUDIO_METADATA_TYPE_BROADCAST_NAME
/*!< Extended metadata */
#define ESP_BLE_AUDIO_METADATA_TYPE_EXTENDED BT_AUDIO_METADATA_TYPE_EXTENDED
/*!< Vendor specific metadata */
#define ESP_BLE_AUDIO_METADATA_TYPE_VENDOR BT_AUDIO_METADATA_TYPE_VENDOR
/**
* @brief Helper to check whether metadata type is known by the stack.
*
* @param _type Metadata type.
*/
#define ESP_BLE_AUDIO_METADATA_TYPE_IS_KNOWN(_type) \
BT_AUDIO_METADATA_TYPE_IS_KNOWN(_type)
/** Metadata types defined by the Generic Audio assigned numbers */
typedef enum bt_audio_metadata_type esp_ble_audio_metadata_type_t;
/*!< Mono Audio (no specified Audio Location) */
#define ESP_BLE_AUDIO_LOCATION_MONO_AUDIO BT_AUDIO_LOCATION_MONO_AUDIO
/*!< Front Left */
#define ESP_BLE_AUDIO_LOCATION_FRONT_LEFT BT_AUDIO_LOCATION_FRONT_LEFT
/*!< Front Right */
#define ESP_BLE_AUDIO_LOCATION_FRONT_RIGHT BT_AUDIO_LOCATION_FRONT_RIGHT
/*!< Front Center */
#define ESP_BLE_AUDIO_LOCATION_FRONT_CENTER BT_AUDIO_LOCATION_FRONT_CENTER
/*!< Low Frequency Effects 1 */
#define ESP_BLE_AUDIO_LOCATION_LOW_FREQ_EFFECTS_1 BT_AUDIO_LOCATION_LOW_FREQ_EFFECTS_1
/*!< Back Left */
#define ESP_BLE_AUDIO_LOCATION_BACK_LEFT BT_AUDIO_LOCATION_BACK_LEFT
/*!< Back Right */
#define ESP_BLE_AUDIO_LOCATION_BACK_RIGHT BT_AUDIO_LOCATION_BACK_RIGHT
/*!< Front Left of Center */
#define ESP_BLE_AUDIO_LOCATION_FRONT_LEFT_OF_CENTER BT_AUDIO_LOCATION_FRONT_LEFT_OF_CENTER
/*!< Front Right of Center */
#define ESP_BLE_AUDIO_LOCATION_FRONT_RIGHT_OF_CENTER BT_AUDIO_LOCATION_FRONT_RIGHT_OF_CENTER
/*!< Back Center */
#define ESP_BLE_AUDIO_LOCATION_BACK_CENTER BT_AUDIO_LOCATION_BACK_CENTER
/*!< Low Frequency Effects 2 */
#define ESP_BLE_AUDIO_LOCATION_LOW_FREQ_EFFECTS_2 BT_AUDIO_LOCATION_LOW_FREQ_EFFECTS_2
/*!< Side Left */
#define ESP_BLE_AUDIO_LOCATION_SIDE_LEFT BT_AUDIO_LOCATION_SIDE_LEFT
/*!< Side Right */
#define ESP_BLE_AUDIO_LOCATION_SIDE_RIGHT BT_AUDIO_LOCATION_SIDE_RIGHT
/*!< Top Front Left */
#define ESP_BLE_AUDIO_LOCATION_TOP_FRONT_LEFT BT_AUDIO_LOCATION_TOP_FRONT_LEFT
/*!< Top Front Right */
#define ESP_BLE_AUDIO_LOCATION_TOP_FRONT_RIGHT BT_AUDIO_LOCATION_TOP_FRONT_RIGHT
/*!< Top Front Center */
#define ESP_BLE_AUDIO_LOCATION_TOP_FRONT_CENTER BT_AUDIO_LOCATION_TOP_FRONT_CENTER
/*!< Top Center */
#define ESP_BLE_AUDIO_LOCATION_TOP_CENTER BT_AUDIO_LOCATION_TOP_CENTER
/*!< Top Back Left */
#define ESP_BLE_AUDIO_LOCATION_TOP_BACK_LEFT BT_AUDIO_LOCATION_TOP_BACK_LEFT
/*!< Top Back Right */
#define ESP_BLE_AUDIO_LOCATION_TOP_BACK_RIGHT BT_AUDIO_LOCATION_TOP_BACK_RIGHT
/*!< Top Side Left */
#define ESP_BLE_AUDIO_LOCATION_TOP_SIDE_LEFT BT_AUDIO_LOCATION_TOP_SIDE_LEFT
/*!< Top Side Right */
#define ESP_BLE_AUDIO_LOCATION_TOP_SIDE_RIGHT BT_AUDIO_LOCATION_TOP_SIDE_RIGHT
/*!< Top Back Center */
#define ESP_BLE_AUDIO_LOCATION_TOP_BACK_CENTER BT_AUDIO_LOCATION_TOP_BACK_CENTER
/*!< Bottom Front Center */
#define ESP_BLE_AUDIO_LOCATION_BOTTOM_FRONT_CENTER BT_AUDIO_LOCATION_BOTTOM_FRONT_CENTER
/*!< Bottom Front Left */
#define ESP_BLE_AUDIO_LOCATION_BOTTOM_FRONT_LEFT BT_AUDIO_LOCATION_BOTTOM_FRONT_LEFT
/*!< Bottom Front Right */
#define ESP_BLE_AUDIO_LOCATION_BOTTOM_FRONT_RIGHT BT_AUDIO_LOCATION_BOTTOM_FRONT_RIGHT
/*!< Front Left Wide */
#define ESP_BLE_AUDIO_LOCATION_FRONT_LEFT_WIDE BT_AUDIO_LOCATION_FRONT_LEFT_WIDE
/*!< Front Right Wide */
#define ESP_BLE_AUDIO_LOCATION_FRONT_RIGHT_WIDE BT_AUDIO_LOCATION_FRONT_RIGHT_WIDE
/*!< Left Surround */
#define ESP_BLE_AUDIO_LOCATION_LEFT_SURROUND BT_AUDIO_LOCATION_LEFT_SURROUND
/*!< Right Surround */
#define ESP_BLE_AUDIO_LOCATION_RIGHT_SURROUND BT_AUDIO_LOCATION_RIGHT_SURROUND
/*!< Any known location */
#define ESP_BLE_AUDIO_LOCATION_ANY BT_AUDIO_LOCATION_ANY
/** Location values defined by the Generic Audio assigned numbers */
typedef enum bt_audio_location esp_ble_audio_location_t;
/*!< Unspecified audio enhancement */
#define ESP_BLE_AUDIO_ASSISTED_LISTENING_STREAM_UNSPECIFIED BT_AUDIO_ASSISTED_LISTENING_STREAM_UNSPECIFIED
/** Assisted Listening Stream defined by the Generic Audio assigned numbers */
typedef enum bt_audio_assisted_listening_stream esp_ble_audio_assisted_listening_stream_t;
/*!< Size in octets of a 16-bit UUID */
#define ESP_BLE_AUDIO_UUID_SIZE_16 BT_UUID_SIZE_16
/*!< Audio Input Control Service UUID value */
#define ESP_BLE_AUDIO_UUID_AICS_VAL BT_UUID_AICS_VAL
/*!< Audio Stream Control Service UUID value */
#define ESP_BLE_AUDIO_UUID_ASCS_VAL BT_UUID_ASCS_VAL
/*!< Broadcast Audio Scan Service UUID value */
#define ESP_BLE_AUDIO_UUID_BASS_VAL BT_UUID_BASS_VAL
/*!< Basic Audio Announcement Service UUID value */
#define ESP_BLE_AUDIO_UUID_BASIC_AUDIO_VAL BT_UUID_BASIC_AUDIO_VAL
/*!< Broadcast Audio Announcement Service UUID value */
#define ESP_BLE_AUDIO_UUID_BROADCAST_AUDIO_VAL BT_UUID_BROADCAST_AUDIO_VAL
/*!< Common Audio Service UUID value */
#define ESP_BLE_AUDIO_UUID_CAS_VAL BT_UUID_CAS_VAL
/*!< Coordinated Set Identification Service UUID value */
#define ESP_BLE_AUDIO_UUID_CSIS_VAL BT_UUID_CSIS_VAL
/*!< Gaming Service UUID value */
#define ESP_BLE_AUDIO_UUID_GMAS_VAL BT_UUID_GMAS_VAL
/*!< Generic Media Control Service UUID value */
#define ESP_BLE_AUDIO_UUID_GMCS_VAL BT_UUID_GMCS_VAL
/*!< Generic Telephone Bearer Service UUID value */
#define ESP_BLE_AUDIO_UUID_GTBS_VAL BT_UUID_GTBS_VAL
/*!< Hearing Access Service UUID value */
#define ESP_BLE_AUDIO_UUID_HAS_VAL BT_UUID_HAS_VAL
/*!< Media Control Service UUID value */
#define ESP_BLE_AUDIO_UUID_MCS_VAL BT_UUID_MCS_VAL
/*!< Microphone Control Service UUID value */
#define ESP_BLE_AUDIO_UUID_MICS_VAL BT_UUID_MICS_VAL
/*!< Published Audio Capabilities Service UUID value */
#define ESP_BLE_AUDIO_UUID_PACS_VAL BT_UUID_PACS_VAL
/*!< Public Broadcast Announcement Service UUID value */
#define ESP_BLE_AUDIO_UUID_PBA_VAL BT_UUID_PBA_VAL
/*!< Telephone Bearer Service UUID value */
#define ESP_BLE_AUDIO_UUID_TBS_VAL BT_UUID_TBS_VAL
/*!< Telephony and Media Audio Service UUID value */
#define ESP_BLE_AUDIO_UUID_TMAS_VAL BT_UUID_TMAS_VAL
/*!< Volume Control Service UUID value */
#define ESP_BLE_AUDIO_UUID_VCS_VAL BT_UUID_VCS_VAL
/*!< Volume Offset Control Service UUID value */
#define ESP_BLE_AUDIO_UUID_VOCS_VAL BT_UUID_VOCS_VAL
/*!< Object Transfer Service UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_VAL BT_UUID_OTS_VAL
/*!< Audio Input Control Service State value */
#define ESP_BLE_AUDIO_UUID_AICS_STATE_VAL BT_UUID_AICS_STATE_VAL
/*!< Audio Input Control Service Gain Settings Properties value */
#define ESP_BLE_AUDIO_UUID_AICS_GAIN_SETTINGS_VAL BT_UUID_AICS_GAIN_SETTINGS_VAL
/*!< Audio Input Control Service Input Type value */
#define ESP_BLE_AUDIO_UUID_AICS_INPUT_TYPE_VAL BT_UUID_AICS_INPUT_TYPE_VAL
/*!< Audio Input Control Service Input Status value */
#define ESP_BLE_AUDIO_UUID_AICS_INPUT_STATUS_VAL BT_UUID_AICS_INPUT_STATUS_VAL
/*!< Audio Input Control Service Control Point value */
#define ESP_BLE_AUDIO_UUID_AICS_CONTROL_VAL BT_UUID_AICS_CONTROL_VAL
/*!< Audio Input Control Service Input Description value */
#define ESP_BLE_AUDIO_UUID_AICS_DESCRIPTION_VAL BT_UUID_AICS_DESCRIPTION_VAL
/*!< Audio Stream Endpoint Sink Characteristic value */
#define ESP_BLE_AUDIO_UUID_ASCS_ASE_SNK_VAL BT_UUID_ASCS_ASE_SNK_VAL
/*!< Audio Stream Endpoint Source Characteristic value */
#define ESP_BLE_AUDIO_UUID_ASCS_ASE_SRC_VAL BT_UUID_ASCS_ASE_SRC_VAL
/*!< Audio Stream Endpoint Control Point Characteristic value */
#define ESP_BLE_AUDIO_UUID_ASCS_ASE_CP_VAL BT_UUID_ASCS_ASE_CP_VAL
/*!< Broadcast Audio Scan Service Scan State value */
#define ESP_BLE_AUDIO_UUID_BASS_CONTROL_POINT_VAL BT_UUID_BASS_CONTROL_POINT_VAL
/*!< Broadcast Audio Scan Service Receive State value */
#define ESP_BLE_AUDIO_UUID_BASS_RECV_STATE_VAL BT_UUID_BASS_RECV_STATE_VAL
/*!< Set Identity Resolving Key value */
#define ESP_BLE_AUDIO_UUID_CSIS_SIRK_VAL BT_UUID_CSIS_SIRK_VAL
/*!< Set size value */
#define ESP_BLE_AUDIO_UUID_CSIS_SET_SIZE_VAL BT_UUID_CSIS_SET_SIZE_VAL
/*!< Set lock value */
#define ESP_BLE_AUDIO_UUID_CSIS_SET_LOCK_VAL BT_UUID_CSIS_SET_LOCK_VAL
/*!< Rank value */
#define ESP_BLE_AUDIO_UUID_CSIS_RANK_VAL BT_UUID_CSIS_RANK_VAL
/*!< Gaming Audio Profile Role UUID value */
#define ESP_BLE_AUDIO_UUID_GMAP_ROLE_VAL BT_UUID_GMAP_ROLE_VAL
/*!< Gaming Audio Profile Unicast Game Gateway Features UUID value */
#define ESP_BLE_AUDIO_UUID_GMAP_UGG_FEAT_VAL BT_UUID_GMAP_UGG_FEAT_VAL
/*!< Gaming Audio Profile Unicast Game Terminal Features UUID value */
#define ESP_BLE_AUDIO_UUID_GMAP_UGT_FEAT_VAL BT_UUID_GMAP_UGT_FEAT_VAL
/*!< Gaming Audio Profile Broadcast Game Sender Features UUID value */
#define ESP_BLE_AUDIO_UUID_GMAP_BGS_FEAT_VAL BT_UUID_GMAP_BGS_FEAT_VAL
/*!< Gaming Audio Profile Broadcast Game Receiver Features UUID value */
#define ESP_BLE_AUDIO_UUID_GMAP_BGR_FEAT_VAL BT_UUID_GMAP_BGR_FEAT_VAL
/*!< Hearing Aid Features Characteristic value */
#define ESP_BLE_AUDIO_UUID_HAS_HEARING_AID_FEATURES_VAL BT_UUID_HAS_HEARING_AID_FEATURES_VAL
/*!< Hearing Aid Preset Control Point Characteristic value */
#define ESP_BLE_AUDIO_UUID_HAS_PRESET_CONTROL_POINT_VAL BT_UUID_HAS_PRESET_CONTROL_POINT_VAL
/*!< Hearing Aid Active Preset Index Characteristic value */
#define ESP_BLE_AUDIO_UUID_HAS_ACTIVE_PRESET_INDEX_VAL BT_UUID_HAS_ACTIVE_PRESET_INDEX_VAL
/*!< Media player name value */
#define ESP_BLE_AUDIO_UUID_MCS_PLAYER_NAME_VAL BT_UUID_MCS_PLAYER_NAME_VAL
/*!< Media Icon Object ID value */
#define ESP_BLE_AUDIO_UUID_MCS_ICON_OBJ_ID_VAL BT_UUID_MCS_ICON_OBJ_ID_VAL
/*!< Media Icon URL value */
#define ESP_BLE_AUDIO_UUID_MCS_ICON_URL_VAL BT_UUID_MCS_ICON_URL_VAL
/*!< Track Changed value */
#define ESP_BLE_AUDIO_UUID_MCS_TRACK_CHANGED_VAL BT_UUID_MCS_TRACK_CHANGED_VAL
/*!< Track Title value */
#define ESP_BLE_AUDIO_UUID_MCS_TRACK_TITLE_VAL BT_UUID_MCS_TRACK_TITLE_VAL
/*!< Track Duration value */
#define ESP_BLE_AUDIO_UUID_MCS_TRACK_DURATION_VAL BT_UUID_MCS_TRACK_DURATION_VAL
/*!< Track Position value */
#define ESP_BLE_AUDIO_UUID_MCS_TRACK_POSITION_VAL BT_UUID_MCS_TRACK_POSITION_VAL
/*!< Playback Speed value */
#define ESP_BLE_AUDIO_UUID_MCS_PLAYBACK_SPEED_VAL BT_UUID_MCS_PLAYBACK_SPEED_VAL
/*!< Seeking Speed value */
#define ESP_BLE_AUDIO_UUID_MCS_SEEKING_SPEED_VAL BT_UUID_MCS_SEEKING_SPEED_VAL
/*!< Track Segments Object ID value */
#define ESP_BLE_AUDIO_UUID_MCS_TRACK_SEGMENTS_OBJ_ID_VAL BT_UUID_MCS_TRACK_SEGMENTS_OBJ_ID_VAL
/*!< Current Track Object ID value */
#define ESP_BLE_AUDIO_UUID_MCS_CURRENT_TRACK_OBJ_ID_VAL BT_UUID_MCS_CURRENT_TRACK_OBJ_ID_VAL
/*!< Next Track Object ID value */
#define ESP_BLE_AUDIO_UUID_MCS_NEXT_TRACK_OBJ_ID_VAL BT_UUID_MCS_NEXT_TRACK_OBJ_ID_VAL
/*!< Parent Group Object ID value */
#define ESP_BLE_AUDIO_UUID_MCS_PARENT_GROUP_OBJ_ID_VAL BT_UUID_MCS_PARENT_GROUP_OBJ_ID_VAL
/*!< Group Object ID value */
#define ESP_BLE_AUDIO_UUID_MCS_CURRENT_GROUP_OBJ_ID_VAL BT_UUID_MCS_CURRENT_GROUP_OBJ_ID_VAL
/*!< Playing Order value */
#define ESP_BLE_AUDIO_UUID_MCS_PLAYING_ORDER_VAL BT_UUID_MCS_PLAYING_ORDER_VAL
/*!< Playing Orders supported value */
#define ESP_BLE_AUDIO_UUID_MCS_PLAYING_ORDERS_VAL BT_UUID_MCS_PLAYING_ORDERS_VAL
/*!< Media State value */
#define ESP_BLE_AUDIO_UUID_MCS_MEDIA_STATE_VAL BT_UUID_MCS_MEDIA_STATE_VAL
/*!< Media Control Point value */
#define ESP_BLE_AUDIO_UUID_MCS_MEDIA_CONTROL_POINT_VAL BT_UUID_MCS_MEDIA_CONTROL_POINT_VAL
/*!< Media control opcodes supported value */
#define ESP_BLE_AUDIO_UUID_MCS_MEDIA_CONTROL_OPCODES_VAL BT_UUID_MCS_MEDIA_CONTROL_OPCODES_VAL
/*!< Search result object ID value */
#define ESP_BLE_AUDIO_UUID_MCS_SEARCH_RESULTS_OBJ_ID_VAL BT_UUID_MCS_SEARCH_RESULTS_OBJ_ID_VAL
/*!< Search control point value */
#define ESP_BLE_AUDIO_UUID_MCS_SEARCH_CONTROL_POINT_VAL BT_UUID_MCS_SEARCH_CONTROL_POINT_VAL
/*!< Microphone Control Service Mute value */
#define ESP_BLE_AUDIO_UUID_MICS_MUTE_VAL BT_UUID_MICS_MUTE_VAL
/*!< Sink PAC Characteristic value */
#define ESP_BLE_AUDIO_UUID_PACS_SNK_VAL BT_UUID_PACS_SNK_VAL
/*!< Sink PAC Locations Characteristic value */
#define ESP_BLE_AUDIO_UUID_PACS_SNK_LOC_VAL BT_UUID_PACS_SNK_LOC_VAL
/*!< Source PAC Characteristic value */
#define ESP_BLE_AUDIO_UUID_PACS_SRC_VAL BT_UUID_PACS_SRC_VAL
/*!< Source PAC Locations Characteristic value */
#define ESP_BLE_AUDIO_UUID_PACS_SRC_LOC_VAL BT_UUID_PACS_SRC_LOC_VAL
/*!< Available Audio Contexts Characteristic value */
#define ESP_BLE_AUDIO_UUID_PACS_AVAILABLE_CONTEXT_VAL BT_UUID_PACS_AVAILABLE_CONTEXT_VAL
/*!< Supported Audio Context Characteristic value */
#define ESP_BLE_AUDIO_UUID_PACS_SUPPORTED_CONTEXT_VAL BT_UUID_PACS_SUPPORTED_CONTEXT_VAL
/*!< Bearer Provider Name value */
#define ESP_BLE_AUDIO_UUID_TBS_PROVIDER_NAME_VAL BT_UUID_TBS_PROVIDER_NAME_VAL
/*!< Bearer UCI value */
#define ESP_BLE_AUDIO_UUID_TBS_UCI_VAL BT_UUID_TBS_UCI_VAL
/*!< Bearer Technology value */
#define ESP_BLE_AUDIO_UUID_TBS_TECHNOLOGY_VAL BT_UUID_TBS_TECHNOLOGY_VAL
/*!< Bearer URI Prefixes Supported List value */
#define ESP_BLE_AUDIO_UUID_TBS_URI_LIST_VAL BT_UUID_TBS_URI_LIST_VAL
/*!< Bearer Signal Strength value */
#define ESP_BLE_AUDIO_UUID_TBS_SIGNAL_STRENGTH_VAL BT_UUID_TBS_SIGNAL_STRENGTH_VAL
/*!< Bearer Signal Strength Reporting Interval value */
#define ESP_BLE_AUDIO_UUID_TBS_SIGNAL_INTERVAL_VAL BT_UUID_TBS_SIGNAL_INTERVAL_VAL
/*!< Bearer List Current Calls value */
#define ESP_BLE_AUDIO_UUID_TBS_LIST_CURRENT_CALLS_VAL BT_UUID_TBS_LIST_CURRENT_CALLS_VAL
/*!< Status flags value */
#define ESP_BLE_AUDIO_UUID_TBS_STATUS_FLAGS_VAL BT_UUID_TBS_STATUS_FLAGS_VAL
/*!< Incoming Call Target Caller ID value */
#define ESP_BLE_AUDIO_UUID_TBS_INCOMING_URI_VAL BT_UUID_TBS_INCOMING_URI_VAL
/*!< Call State value */
#define ESP_BLE_AUDIO_UUID_TBS_CALL_STATE_VAL BT_UUID_TBS_CALL_STATE_VAL
/*!< Call Control Point value */
#define ESP_BLE_AUDIO_UUID_TBS_CALL_CONTROL_POINT_VAL BT_UUID_TBS_CALL_CONTROL_POINT_VAL
/*!< Optional Opcodes value */
#define ESP_BLE_AUDIO_UUID_TBS_OPTIONAL_OPCODES_VAL BT_UUID_TBS_OPTIONAL_OPCODES_VAL
/*!< Terminate reason value */
#define ESP_BLE_AUDIO_UUID_TBS_TERMINATE_REASON_VAL BT_UUID_TBS_TERMINATE_REASON_VAL
/*!< Incoming Call value */
#define ESP_BLE_AUDIO_UUID_TBS_INCOMING_CALL_VAL BT_UUID_TBS_INCOMING_CALL_VAL
/*!< Incoming Call Friendly name value */
#define ESP_BLE_AUDIO_UUID_TBS_FRIENDLY_NAME_VAL BT_UUID_TBS_FRIENDLY_NAME_VAL
/*!< Volume Control Setting value */
#define ESP_BLE_AUDIO_UUID_VCS_STATE_VAL BT_UUID_VCS_STATE_VAL
/*!< Volume Control Control point value */
#define ESP_BLE_AUDIO_UUID_VCS_CONTROL_VAL BT_UUID_VCS_CONTROL_VAL
/*!< Volume Control Flags value */
#define ESP_BLE_AUDIO_UUID_VCS_FLAGS_VAL BT_UUID_VCS_FLAGS_VAL
/*!< Volume Offset State value */
#define ESP_BLE_AUDIO_UUID_VOCS_STATE_VAL BT_UUID_VOCS_STATE_VAL
/*!< Audio Location value */
#define ESP_BLE_AUDIO_UUID_VOCS_LOCATION_VAL BT_UUID_VOCS_LOCATION_VAL
/*!< Volume Offset Control Point value */
#define ESP_BLE_AUDIO_UUID_VOCS_CONTROL_VAL BT_UUID_VOCS_CONTROL_VAL
/*!< Volume Offset Audio Output Description value */
#define ESP_BLE_AUDIO_UUID_VOCS_DESCRIPTION_VAL BT_UUID_VOCS_DESCRIPTION_VAL
/*!< Content Control ID value */
#define ESP_BLE_AUDIO_UUID_CCID_VAL BT_UUID_CCID_VAL
/*!< OTS Feature Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_FEATURE_VAL BT_UUID_OTS_FEATURE_VAL
/*!< OTS Object Name Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_NAME_VAL BT_UUID_OTS_NAME_VAL
/*!< OTS Object Type Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_TYPE_VAL BT_UUID_OTS_TYPE_VAL
/*!< OTS Object Size Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_SIZE_VAL BT_UUID_OTS_SIZE_VAL
/*!< OTS Object First-Created Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_FIRST_CREATED_VAL BT_UUID_OTS_FIRST_CREATED_VAL
/*!< OTS Object Last-Modified Characteristic UUI value */
#define ESP_BLE_AUDIO_UUID_OTS_LAST_MODIFIED_VAL BT_UUID_OTS_LAST_MODIFIED_VAL
/*!< OTS Object ID Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_ID_VAL BT_UUID_OTS_ID_VAL
/*!< OTS Object Properties Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_PROPERTIES_VAL BT_UUID_OTS_PROPERTIES_VAL
/*!< OTS Object Action Control Point Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_ACTION_CP_VAL BT_UUID_OTS_ACTION_CP_VAL
/*!< OTS Object List Control Point Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_LIST_CP_VAL BT_UUID_OTS_LIST_CP_VAL
/*!< OTS Object List Filter Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_LIST_FILTER_VAL BT_UUID_OTS_LIST_FILTER_VAL
/*!< OTS Object Changed Characteristic UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_CHANGED_VAL BT_UUID_OTS_CHANGED_VAL
/*!< OTS Unspecified Object Type UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_TYPE_UNSPECIFIED_VAL BT_UUID_OTS_TYPE_UNSPECIFIED_VAL
/*!< OTS Directory Listing UUID value */
#define ESP_BLE_AUDIO_UUID_OTS_DIRECTORY_LISTING_VAL BT_UUID_OTS_DIRECTORY_LISTING_VAL
/*!< OTS Media Player Icon Object Type value */
#define ESP_BLE_AUDIO_UUID_OTS_TYPE_MPL_ICON_VAL BT_UUID_OTS_TYPE_MPL_ICON_VAL
/*!< OTS Track Segments Object Type value */
#define ESP_BLE_AUDIO_UUID_OTS_TYPE_TRACK_SEGMENT_VAL BT_UUID_OTS_TYPE_TRACK_SEGMENT_VAL
/*!< OTS Track Object Type value */
#define ESP_BLE_AUDIO_UUID_OTS_TYPE_TRACK_VAL BT_UUID_OTS_TYPE_TRACK_VAL
/*!< OTS Group Object Type value */
#define ESP_BLE_AUDIO_UUID_OTS_TYPE_GROUP_VAL BT_UUID_OTS_TYPE_GROUP_VAL
/*!< Generic Audio Sink */
#define ESP_BLE_AUDIO_APPEARANCE_GENERIC_AUDIO_SINK BT_APPEARANCE_GENERIC_AUDIO_SINK
/*!< Standalone Speaker */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SINK_STANDALONE_SPEAKER BT_APPEARANCE_AUDIO_SINK_STANDALONE_SPEAKER
/*!< Soundbar */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SINK_SOUNDBAR BT_APPEARANCE_AUDIO_SINK_SOUNDBAR
/*!< Bookshelf Speaker */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SINK_BOOKSHELF_SPEAKER BT_APPEARANCE_AUDIO_SINK_BOOKSHELF_SPEAKER
/*!< Standmounted Speaker */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SINK_STANDMOUNTED_SPEAKER BT_APPEARANCE_AUDIO_SINK_STANDMOUNTED_SPEAKER
/*!< Speakerphone */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SINK_SPEAKERPHONE BT_APPEARANCE_AUDIO_SINK_SPEAKERPHONE
/*!< Generic Audio Source */
#define ESP_BLE_AUDIO_APPEARANCE_GENERIC_AUDIO_SOURCE BT_APPEARANCE_GENERIC_AUDIO_SOURCE
/*!< Microphone */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_MICROPHONE BT_APPEARANCE_AUDIO_SOURCE_MICROPHONE
/*!< Alarm */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_ALARM BT_APPEARANCE_AUDIO_SOURCE_ALARM
/*!< Bell */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_BELL BT_APPEARANCE_AUDIO_SOURCE_BELL
/*!< Horn */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_HORN BT_APPEARANCE_AUDIO_SOURCE_HORN
/*!< Broadcasting Device */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_BROADCASTING_DEVICE BT_APPEARANCE_AUDIO_SOURCE_BROADCASTING_DEVICE
/*!< Service Desk */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_SERVICE_DESK BT_APPEARANCE_AUDIO_SOURCE_SERVICE_DESK
/*!< Kiosk */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_KIOSK BT_APPEARANCE_AUDIO_SOURCE_KIOSK
/*!< Broadcasting Room */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_BROADCASTING_ROOM BT_APPEARANCE_AUDIO_SOURCE_BROADCASTING_ROOM
/*!< Auditorium */
#define ESP_BLE_AUDIO_APPEARANCE_AUDIO_SOURCE_AUDITORIUM BT_APPEARANCE_AUDIO_SOURCE_AUDITORIUM
/*!< Generic Wearable Audio Device */
#define ESP_BLE_AUDIO_APPEARANCE_GENERIC_WEARABLE_AUDIO_DEVICE BT_APPEARANCE_GENERIC_WEARABLE_AUDIO_DEVICE
/*!< Earbud */
#define ESP_BLE_AUDIO_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD BT_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD
/*!< Headset */
#define ESP_BLE_AUDIO_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADSET BT_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADSET
/*!< Headphones */
#define ESP_BLE_AUDIO_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADPHONES BT_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADPHONES
/*!< Neck Band */
#define ESP_BLE_AUDIO_APPEARANCE_WEARABLE_AUDIO_DEVICE_NECK_BAND BT_APPEARANCE_WEARABLE_AUDIO_DEVICE_NECK_BAND
/*!< Generic Hearing aid */
#define ESP_BLE_AUDIO_APPEARANCE_GENERIC_HEARING_AID BT_APPEARANCE_GENERIC_HEARING_AID
/*!< In-ear hearing aid */
#define ESP_BLE_AUDIO_APPEARANCE_HEARING_AID_IN_EAR BT_APPEARANCE_HEARING_AID_IN_EAR
/*!< Behind-ear hearing aid */
#define ESP_BLE_AUDIO_APPEARANCE_HEARING_AID_BEHIND_EAR BT_APPEARANCE_HEARING_AID_BEHIND_EAR
/*!< Cochlear Implant */
#define ESP_BLE_AUDIO_APPEARANCE_HEARING_AID_COCHLEAR_IMPLANT BT_APPEARANCE_HEARING_AID_COCHLEAR_IMPLANT
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_DEFS_H_ */
@@ -0,0 +1,134 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_GMAP_API_H_
#define ESP_BLE_AUDIO_GMAP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/gmap.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< Gaming Role Unicast Game Gateway */
#define ESP_BLE_AUDIO_GMAP_ROLE_UGG BT_GMAP_ROLE_UGG
/*!< Gaming Role Unicast Game Terminal */
#define ESP_BLE_AUDIO_GMAP_ROLE_UGT BT_GMAP_ROLE_UGT
/*!< Gaming Role Broadcast Game Sender */
#define ESP_BLE_AUDIO_GMAP_ROLE_BGS BT_GMAP_ROLE_BGS
/*!< Gaming Role Broadcast Game Receiver */
#define ESP_BLE_AUDIO_GMAP_ROLE_BGR BT_GMAP_ROLE_BGR
/** Gaming Role bitfield */
typedef enum bt_gmap_role esp_ble_audio_gmap_role_t;
/*!< Support transmitting multiple LC3 codec frames per block in an SDU */
#define ESP_BLE_AUDIO_GMAP_UGG_FEAT_MULTIPLEX BT_GMAP_UGG_FEAT_MULTIPLEX
/*!< 96 kbps source support */
#define ESP_BLE_AUDIO_GMAP_UGG_FEAT_96KBPS_SOURCE BT_GMAP_UGG_FEAT_96KBPS_SOURCE
/*!< Support for receiving at least two channels of audio, each in a separate CIS */
#define ESP_BLE_AUDIO_GMAP_UGG_FEAT_MULTISINK BT_GMAP_UGG_FEAT_MULTISINK
/** Unicast Game Gateway Feature bitfield */
typedef enum bt_gmap_ugg_feat esp_ble_audio_gmap_ugg_feat_t;
/*!< Source support */
#define ESP_BLE_AUDIO_GMAP_UGT_FEAT_SOURCE BT_GMAP_UGT_FEAT_SOURCE
/*!< 80 kbps source support */
#define ESP_BLE_AUDIO_GMAP_UGT_FEAT_80KBPS_SOURCE BT_GMAP_UGT_FEAT_80KBPS_SOURCE
/*!< Sink support */
#define ESP_BLE_AUDIO_GMAP_UGT_FEAT_SINK BT_GMAP_UGT_FEAT_SINK
/*!< 64 kbps sink support */
#define ESP_BLE_AUDIO_GMAP_UGT_FEAT_64KBPS_SINK BT_GMAP_UGT_FEAT_64KBPS_SINK
/*!< Support for receiving multiple LC3 codec frames per block in an SDU */
#define ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTIPLEX BT_GMAP_UGT_FEAT_MULTIPLEX
/*!< Support for receiving at least two audio channels, each in a separate CIS */
#define ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISINK BT_GMAP_UGT_FEAT_MULTISINK
/*!< Support for sending at least two audio channels, each in a separate CIS */
#define ESP_BLE_AUDIO_GMAP_UGT_FEAT_MULTISOURCE BT_GMAP_UGT_FEAT_MULTISOURCE
/** Unicast Game Terminal Feature bitfield */
typedef enum bt_gmap_ugt_feat esp_ble_audio_gmap_ugt_feat_t;
/*!< 96 kbps support */
#define ESP_BLE_AUDIO_GMAP_BGS_FEAT_96KBPS BT_GMAP_BGS_FEAT_96KBPS
/** Broadcast Game Receiver Feature bitfield */
typedef enum bt_gmap_bgs_feat esp_ble_audio_gmap_bgs_feat_t;
/*!< Support for receiving at least two audio channels, each in a separate BIS */
#define ESP_BLE_AUDIO_GMAP_BGR_FEAT_MULTISINK BT_GMAP_BGR_FEAT_MULTISINK
/*!< Support for receiving multiple LC3 codec frames per block in an SDU */
#define ESP_BLE_AUDIO_GMAP_BGR_FEAT_MULTIPLEX BT_GMAP_BGR_FEAT_MULTIPLEX
/** Broadcast Game Receiver Feature bitfield */
typedef enum bt_gmap_bgr_feat esp_ble_audio_gmap_bgr_feat_t;
/** Hearing Access Service Client callback structure */
typedef struct bt_gmap_cb esp_ble_audio_gmap_cb_t;
/** Broadcast Game Receiver Feature bitfield */
typedef struct bt_gmap_feat esp_ble_audio_gmap_feat_t;
/**
* @brief Registers the callbacks used by the Gaming Audio Profile.
*
* @param cb The callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_gmap_cb_register(const esp_ble_audio_gmap_cb_t *cb);
/**
* @brief Discover Gaming Service on a remote device.
*
* Procedure to find a Gaming Service on a server identified by @p conn_handle.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_gmap_discover(uint16_t conn_handle);
/**
* @brief Adds GMAS instance to database and sets the received Gaming Audio Profile role(s).
*
* @param role Gaming Audio Profile role(s) of the device (one or multiple).
* @param features Features of the roles. If a role is not in the @p role parameter, then
* the feature value for that role is simply ignored.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_gmap_register(esp_ble_audio_gmap_role_t role,
esp_ble_audio_gmap_feat_t features);
/**
* @brief Set one or multiple Gaming Audio Profile roles and features dynamically.
*
* Previously registered value will be overwritten. If there is a role change, this will trigger
* a Gaming Audio Service (GMAS) service change. If there is only a feature change, no service
* change will happen.
*
* @param role Gaming Audio Profile role(s).
* @param features Features of the roles. If a role is not in the @p role parameter, then
* the feature value for that role is simply ignored.
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_gmap_set_role(esp_ble_audio_gmap_role_t role,
esp_ble_audio_gmap_feat_t features);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_GMAP_API_H_ */
@@ -0,0 +1,324 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFS_H_
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFS_H_
#include <zephyr/bluetooth/audio/gmap_lc3_preset.h>
#include "esp_ble_audio_bap_lc3_preset_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Base macro for defining GMAP LC3 presets.
*
* @param _name Preset name.
* @param _freq Sampling frequency (16, 32, or 48 kHz).
* @param _duration Frame duration (7.5 or 10 ms).
* @param _loc Audio channel location.
* @param _len Frame length in bytes.
* @param _frames_per_sdu Number of frames per SDU.
* @param _stream_context Stream context type.
* @param _interval Interval between packets in microseconds.
* @param _sdu SDU size in bytes.
* @param _rtn Maximum number of retransmissions.
* @param _latency Maximum latency in milliseconds.
* @param _pd Presentation delay in microseconds.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, _freq, _duration, _loc, _len, \
_frames_per_sdu, _stream_context, \
_interval, _sdu, _rtn, _latency, _pd) \
static uint8_t codec_cfg_data_##_name[] = \
ESP_BLE_AUDIO_CODEC_CFG_LC3_DATA(_freq, _duration, _loc, _len, _frames_per_sdu); \
static uint8_t codec_cfg_meta_##_name[] = \
ESP_BLE_AUDIO_CODEC_CFG_LC3_META(_stream_context); \
static esp_ble_audio_bap_lc3_preset_t _name = \
ESP_BLE_AUDIO_BAP_LC3_PRESET(ESP_BLE_AUDIO_CODEC_CFG_LC3(codec_cfg_data_##_name, \
codec_cfg_meta_##_name), \
ESP_BLE_AUDIO_BAP_QOS_CFG_UNFRAMED(_interval, _sdu, _rtn, \
_latency, _pd));
/**
* @brief Gaming Reliable (GR) preset at 32kHz, 7.5ms frame duration.
*
* Optimized for reliable gaming audio with low latency (15ms) and standard presentation delay (10ms).
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_32_1_GR_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 60U, 1, \
_stream_context, \
7500u, 60U, 1U, 15U, 10000U)
/**
* @brief Gaming Reliable (GR) preset at 32kHz, 10ms frame duration.
*
* Higher quality variant with increased frame duration for better audio quality.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_32_2_GR_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 80U, 1, \
_stream_context, \
10000u, 80U, 1U, 20U, 10000U)
/**
* @brief Gaming Reliable (GR) preset at 48kHz, 7.5ms frame duration.
*
* High-quality gaming audio with minimal latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_1_GR_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 75U, 1, \
_stream_context, \
7500u, 75U, 1U, 15U, 10000U)
/**
* @brief Gaming Reliable (GR) preset at 48kHz, 10ms frame duration.
*
* High-quality gaming audio with balanced latency and quality.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_2_GR_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 100U, 1, \
_stream_context, \
10000u, 100U, 1U, 20U, 10000U)
/**
* @brief Gaming Reliable (GR) preset at 48kHz, 7.5ms frame duration, higher bitrate.
*
* Enhanced quality gaming audio with minimal latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_3_GR_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 90U, 1, \
_stream_context, \
7500u, 90U, 1U, 15U, 10000U)
/**
* @brief Gaming Reliable (GR) preset at 48kHz, 10ms frame duration, higher bitrate.
*
* Premium quality gaming audio with balanced latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_4_GR_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 120u, 1, \
_stream_context, \
10000u, 120U, 1U, 20U, 10000U)
/**
* @brief Gaming Standard (GS) preset at 16kHz, 7.5ms frame duration.
*
* Basic gaming audio with longer presentation delay (60ms).
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_16_1_GS_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 30U, 1, \
_stream_context, \
7500u, 30U, 1U, 15U, 60000U)
/**
* @brief Gaming Standard (GS) preset at 16kHz, 10ms frame duration.
*
* Basic gaming audio with better quality and longer presentation delay.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_16_2_GS_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 40U, 1, \
_stream_context, \
10000u, 40U, 1U, 20U, 60000U)
/**
* @brief Gaming Standard (GS) preset at 32kHz, 7.5ms frame duration.
*
* Medium quality gaming audio with standard latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_32_1_GS_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 60U, 1, \
_stream_context, \
7500u, 60U, 1U, 15U, 60000U)
/**
* @brief Gaming Standard (GS) preset at 32kHz, 10ms frame duration.
*
* Enhanced medium quality gaming audio.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_32_2_GS_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_32KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 80U, 1, \
_stream_context, \
10000u, 80U, 1U, 20U, 60000U)
/**
* @brief Gaming Standard (GS) preset at 48kHz, 7.5ms frame duration.
*
* High quality gaming audio with standard latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_1_GS_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 75U, 1, \
_stream_context, \
7500u, 75U, 1U, 15U, 60000U)
/**
* @brief Gaming Standard (GS) preset at 48kHz, 10ms frame duration.
*
* Premium quality gaming audio with standard latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_2_GS_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 100U, 1, \
_stream_context, \
10000u, 100U, 1U, 20U, 60000U)
/**
* @brief Generic Gaming (G) preset at 48kHz, 7.5ms frame duration.
*
* High quality gaming audio with ultra-low latency (8ms).
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_1_G_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 75U, 1, \
_stream_context, \
7500u, 75U, 1U, 8U, 10000U)
/**
* @brief Generic Gaming (G) preset at 48kHz, 10ms frame duration.
*
* High quality gaming audio with very low latency (10ms).
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_2_G_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 100U, 1, \
_stream_context, \
10000u, 100U, 1U, 10U, 10000U)
/**
* @brief Generic Gaming (G) preset at 48kHz, 7.5ms frame duration, higher bitrate.
*
* Premium quality gaming audio with ultra-low latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_3_G_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_7_5, \
_loc, 90U, 1, \
_stream_context, \
7500u, 90U, 1U, 8U, 10000U)
/**
* @brief Generic Gaming (G) preset at 48kHz, 10ms frame duration, higher bitrate.
*
* Highest quality gaming audio with very low latency.
*
* @param _name Preset name.
* @param _loc Audio channel location.
* @param _stream_context Stream context type.
*/
#define ESP_BLE_AUDIO_GMAP_LC3_PRESET_48_4_G_DEFINE(_name, _loc, _stream_context) \
ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFINE(_name, \
BT_AUDIO_CODEC_CFG_FREQ_48KHZ, \
BT_AUDIO_CODEC_CFG_DURATION_10, \
_loc, 120u, 1, \
_stream_context, \
10000u, 120U, 1U, 10U, 10000U)
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_GMAP_LC3_PRESET_DEFS_H_ */
@@ -0,0 +1,267 @@
/*
* SPDX-FileCopyrightText: 2022 Codecoup
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_HAS_API_H_
#define ESP_BLE_AUDIO_HAS_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/audio/has.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< No index */
#define ESP_BLE_AUDIO_HAS_PRESET_INDEX_NONE BT_HAS_PRESET_INDEX_NONE
/*!< First preset index */
#define ESP_BLE_AUDIO_HAS_PRESET_INDEX_FIRST BT_HAS_PRESET_INDEX_FIRST
/*!< Last preset index */
#define ESP_BLE_AUDIO_HAS_PRESET_INDEX_LAST BT_HAS_PRESET_INDEX_LAST
/*!< Preset name minimum length */
#define ESP_BLE_AUDIO_HAS_PRESET_NAME_MIN BT_HAS_PRESET_NAME_MIN
/*!< Preset name maximum length */
#define ESP_BLE_AUDIO_HAS_PRESET_NAME_MAX BT_HAS_PRESET_NAME_MAX
/*!< No properties set */
#define ESP_BLE_AUDIO_HAS_PROP_NONE BT_HAS_PROP_NONE
/*!< Preset name can be written by the client */
#define ESP_BLE_AUDIO_HAS_PROP_WRITABLE BT_HAS_PROP_WRITABLE
/*!< Preset availability */
#define ESP_BLE_AUDIO_HAS_PROP_AVAILABLE BT_HAS_PROP_AVAILABLE
/** Preset Properties values */
typedef enum bt_has_properties esp_ble_audio_has_properties_t;
/*!< Indicate support for presets */
#define ESP_BLE_AUDIO_HAS_PRESET_SUPPORT BT_HAS_PRESET_SUPPORT
/** Hearing Aid device capabilities */
typedef enum bt_has_capabilities esp_ble_audio_has_capabilities_t;
/**
* Two hearing aids that form a Coordinated Set, one for the right ear and one for the left
* ear of the user. Typically used by a user with bilateral hearing loss.
*/
#define ESP_BLE_AUDIO_HAS_HEARING_AID_TYPE_BINAURAL BT_HAS_HEARING_AID_TYPE_BINAURAL
/**
* A single hearing aid for the left or the right ear. Typically used by a user with
* unilateral hearing loss.
*/
#define ESP_BLE_AUDIO_HAS_HEARING_AID_TYPE_MONAURAL BT_HAS_HEARING_AID_TYPE_MONAURAL
/**
* Two hearing aids with a connection to one another that expose a single Bluetooth radio
* interface.
*/
#define ESP_BLE_AUDIO_HAS_HEARING_AID_TYPE_BANDED BT_HAS_HEARING_AID_TYPE_BANDED
/** Hearing Aid device type */
typedef enum bt_has_hearing_aid_type esp_ble_audio_has_hearing_aid_type_t;
/** Hearing Access Service object */
typedef struct bt_has esp_ble_audio_has_t;
/** Hearing Access Service Client callback structure */
typedef struct bt_has_client_cb esp_ble_audio_has_client_cb_t;
/** Structure for registering features of a Hearing Access Service instance */
typedef struct bt_has_features_param esp_ble_audio_has_features_param_t;
/** Preset operations structure */
typedef struct bt_has_preset_ops esp_ble_audio_has_preset_ops_t;
/** Preset record definition */
typedef struct bt_has_preset_record esp_ble_audio_has_preset_record_t;
/** Register structure for preset */
typedef struct bt_has_preset_register_param esp_ble_audio_has_preset_register_param_t;
/**
* @brief Registers the callbacks used by the Hearing Access Service client.
*
* @param cb The callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_client_cb_register(const esp_ble_audio_has_client_cb_t *cb);
/**
* @brief Discover Hearing Access Service on a remote device.
*
* Client method to find a Hearing Access Service on a server identified by @p conn_handle.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_client_discover(uint16_t conn_handle);
/**
* @brief Read Preset Records.
*
* Client method to read up to @p max_count presets starting from given @p index.
*
* @param has Pointer to the Hearing Access Service object.
* @param index The index to start with.
* @param max_count Maximum number of presets to read.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_client_presets_read(esp_ble_audio_has_t *has,
uint8_t index,
uint8_t max_count);
/**
* @brief Set Active Preset.
*
* Client procedure to set preset identified by @p index as active.
*
* @param has Pointer to the Hearing Access Service object.
* @param index Preset index to activate.
* @param sync Request active preset synchronization in set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_client_preset_set(esp_ble_audio_has_t *has,
uint8_t index, bool sync);
/**
* @brief Activate Next Preset.
*
* Client procedure to set next available preset as active.
*
* @param has Pointer to the Hearing Access Service object.
* @param sync Request active preset synchronization in set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_client_preset_next(esp_ble_audio_has_t *has, bool sync);
/**
* @brief Activate Previous Preset.
*
* Client procedure to set previous available preset as active.
*
* @param has Pointer to the Hearing Access Service object.
* @param sync Request active preset synchronization in set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_client_preset_prev(esp_ble_audio_has_t *has, bool sync);
/**
* @brief Register the Hearing Access Service instance.
*
* @param features Hearing Access Service register parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_register(const esp_ble_audio_has_features_param_t *features);
/**
* @brief Register preset.
*
* Register preset. The preset will be added to the list of exposed preset records.
*
* @param param Preset registration parameter.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_preset_register(const esp_ble_audio_has_preset_register_param_t *param);
/**
* @brief Unregister Preset.
*
* Unregister preset. The preset will be removed from the list of preset records.
*
* @param index The index of preset that's being requested to unregister.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_preset_unregister(uint8_t index);
/**
* @brief Set the preset as available.
*
* This will notify preset availability to peer devices. Only available preset can
* be selected as active preset.
*
* @param index The index of preset that's became available.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_preset_available(uint8_t index);
/**
* @brief Set the preset as unavailable.
*
* This will notify preset availability to peer devices. Unavailable preset cannot
* be selected as active preset.
*
* @param index The index of preset that's became unavailable.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_preset_unavailable(uint8_t index);
/**
* @brief Set active preset.
*
* Function used to set the preset identified by the @p index as the active preset.
* The preset index will be notified to peer devices.
*
* @param index Preset index.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_preset_active_set(uint8_t index);
/**
* @brief Get active preset.
*
* Function used to get the currently active preset index.
*
* @return Active preset index.
*/
uint8_t esp_ble_audio_has_preset_active_get(void);
/**
* @brief Change the Preset Name.
*
* Change the name of the preset identified by @p index.
*
* @param index The index of the preset to change the name of.
* @param name Name to write.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_preset_name_change(uint8_t index, const char *name);
/**
* @brief Change the Hearing Aid Features.
*
* Change the hearing aid features.
*
* @param features The features to be set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_has_features_set(const esp_ble_audio_has_features_param_t *features);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_HAS_API_H_ */
@@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2020 Intel Corporation
* SPDX-FileCopyrightText: 2022-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_LC3_DEFS_H_
#define ESP_BLE_AUDIO_LC3_DEFS_H_
#include <zephyr/bluetooth/audio/lc3.h>
#include "esp_ble_audio_codec_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Helper to declare LC3 codec capability.
*
* @param _freq Supported Sampling Frequencies bitfield.
* @param _duration Supported Frame Durations bitfield.
* @param _chan_count Supported channels.
* @param _len_min Minimum number of octets supported per codec frame.
* @param _len_max Maximum number of octets supported per codec frame.
* @param _max_frames_per_sdu Supported maximum codec frames per SDU.
* Optional and will be included only if != 1.
*/
#define ESP_BLE_AUDIO_CODEC_CAP_LC3_DATA(_freq, _duration, _chan_count, \
_len_min, _len_max, \
_max_frames_per_sdu) \
BT_AUDIO_CODEC_CAP_LC3_DATA(_freq, _duration, _chan_count, \
_len_min, _len_max, \
_max_frames_per_sdu)
/**
* @brief Helper to declare LC3 codec metadata.
*
* @param _prefer_context Preferred contexts.
*/
#define ESP_BLE_AUDIO_CODEC_CAP_LC3_META(_prefer_context) \
BT_AUDIO_CODEC_CAP_LC3_META(_prefer_context)
/**
* @brief Helper to declare LC3 codec capability.
*
* @param _data LC3 codec capability data.
* @param _meta LC3 codec capability metadata.
*/
#define ESP_BLE_AUDIO_CODEC_CAP_LC3(_data, _meta) \
ESP_BLE_AUDIO_CODEC_CAP(ESP_BLE_ISO_CODING_FORMAT_LC3, 0x0000, 0x0000, _data, _meta)
/**
* @brief Helper to declare LC3 codec data configuration.
*
* @param _freq Sampling frequency.
* @param _duration Frame duration.
* @param _loc Audio channel location bitfield.
* @param _len Octets per frame (16-bit integer).
* @param _frames_per_sdu Frames per SDU (8-bit integer). This value is
* optional and will be included only if != 1.
*/
#define ESP_BLE_AUDIO_CODEC_CFG_LC3_DATA(_freq, _duration, _loc, _len, _frames_per_sdu) \
BT_AUDIO_CODEC_CFG_LC3_DATA(_freq, _duration, _loc, _len, _frames_per_sdu)
/**
* @brief Helper to declare LC3 codec metadata configuration.
*
* @param _stream_context Stream context.
*/
#define ESP_BLE_AUDIO_CODEC_CFG_LC3_META(_stream_context) \
BT_AUDIO_CODEC_CFG_LC3_META(_stream_context)
/**
* @brief Helper to declare LC3 codec configuration.
*
* @param _data LC3 codec configuration data.
* @param _meta LC3 codec configuration metadata.
*/
#define ESP_BLE_AUDIO_CODEC_CFG_LC3(_data, _meta) \
ESP_BLE_AUDIO_CODEC_CFG(ESP_BLE_ISO_CODING_FORMAT_LC3, 0x0000, 0x0000, _data, _meta)
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_LC3_DEFS_H_ */
@@ -0,0 +1,393 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_MCC_API_H_
#define ESP_BLE_AUDIO_MCC_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/services/ots.h>
#include <zephyr/bluetooth/audio/mcc.h>
#include "common/init.h"
#include "common/host.h"
#include "esp_ble_audio_media_proxy_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Media control client callbacks */
typedef struct bt_mcc_cb esp_ble_audio_mcc_cb_t;
/**
* @brief Initialize Media Control Client.
*
* @param cb Callbacks to be used.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_init(esp_ble_audio_mcc_cb_t *cb);
/**
* @brief Discover Media Control Service.
*
* Discover Media Control Service (MCS) on the server given by the connection
* Optionally subscribe to notifications.
*
* Shall be called once, after media control client initialization and before
* using other media control client functionality.
*
* @param conn_handle Connection handle.
* @param subscribe Whether to subscribe to notifications.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_discover_mcs(uint16_t conn_handle, bool subscribe);
/**
* @brief Read Media Player Name.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_player_name(uint16_t conn_handle);
/**
* @brief Read Icon Object ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_icon_obj_id(uint16_t conn_handle);
/**
* @brief Read Icon Object URL.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_icon_url(uint16_t conn_handle);
/**
* @brief Read Track Title.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_track_title(uint16_t conn_handle);
/**
* @brief Read Track Duration.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_track_duration(uint16_t conn_handle);
/**
* @brief Read Track Position.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_track_position(uint16_t conn_handle);
/**
* @brief Set Track position.
*
* @param conn_handle Connection handle.
* @param pos Track position.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_set_track_position(uint16_t conn_handle, int32_t pos);
/**
* @brief Read Playback speed.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_playback_speed(uint16_t conn_handle);
/**
* @brief Set Playback Speed.
*
* @param conn_handle Connection handle.
* @param speed Playback speed.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_set_playback_speed(uint16_t conn_handle, int8_t speed);
/**
* @brief Read Seeking speed.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_seeking_speed(uint16_t conn_handle);
/**
* @brief Read Track Segments Object ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_segments_obj_id(uint16_t conn_handle);
/**
* @brief Read Current Track Object ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_current_track_obj_id(uint16_t conn_handle);
/**
* @brief Set Current Track Object ID.
*
* Set the Current Track to the track given by the @p id parameter.
*
* @param conn_handle Connection handle.
* @param id Object Transfer Service ID (UINT48) of the track to set as the current track.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_set_current_track_obj_id(uint16_t conn_handle, uint64_t id);
/**
* @brief Read Next Track Object ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_next_track_obj_id(uint16_t conn_handle);
/**
* @brief Set Next Track Object ID.
*
* @param conn_handle Connection handle.
* @param id Object Transfer Service ID (UINT48) of the track to set as the next track.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_set_next_track_obj_id(uint16_t conn_handle, uint64_t id);
/**
* @brief Read Current Group Object ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_current_group_obj_id(uint16_t conn_handle);
/**
* @brief Set Current Group Object ID.
*
* @param conn_handle Connection handle.
* @param id Object Transfer Service ID (UINT48) of the group to set as the current group.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_set_current_group_obj_id(uint16_t conn_handle, uint64_t id);
/**
* @brief Read Parent Group Object ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_parent_group_obj_id(uint16_t conn_handle);
/**
* @brief Read Playing Order.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_playing_order(uint16_t conn_handle);
/**
* @brief Set Playing Order.
*
* @param conn_handle Connection handle.
* @param order Playing order.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_set_playing_order(uint16_t conn_handle, uint8_t order);
/**
* @brief Read Playing Orders Supported.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_playing_orders_supported(uint16_t conn_handle);
/**
* @brief Read Media State.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_media_state(uint16_t conn_handle);
/**
* @brief Send a command.
*
* Write a command (e.g. "play", "pause") to the server's media control point.
*
* @param conn_handle Connection handle.
* @param cmd The command to send.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_send_cmd(uint16_t conn_handle,
const esp_ble_audio_mpl_cmd_t *cmd);
/**
* @brief Read Opcodes Supported.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_opcodes_supported(uint16_t conn_handle);
/**
* @brief Send a Search command.
*
* Write a search to the server's search control point.
*
* @param conn_handle Connection handle.
* @param search The search.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_send_search(uint16_t conn_handle,
const esp_ble_audio_mpl_search_t *search);
/**
* @brief Search Results Group Object ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_search_results_obj_id(uint16_t conn_handle);
/**
* @brief Read Content Control ID.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_read_content_control_id(uint16_t conn_handle);
/**
* @brief Read the current object metadata.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_otc_read_object_metadata(uint16_t conn_handle);
/**
* @brief Read the Icon Object.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_otc_read_icon_object(uint16_t conn_handle);
/**
* @brief Read the Track Segments Object.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_otc_read_track_segments_object(uint16_t conn_handle);
/**
* @brief Read the Current Track Object.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_otc_read_current_track_object(uint16_t conn_handle);
/**
* @brief Read the Next Track Object.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_otc_read_next_track_object(uint16_t conn_handle);
/**
* @brief Read the Current Group Object.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_otc_read_current_group_object(uint16_t conn_handle);
/**
* @brief Read the Parent Group Object.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_mcc_otc_read_parent_group_object(uint16_t conn_handle);
/**
* @brief Look up MCC OTC instance.
*
* @param conn_handle Connection handle.
*
* @return Pointer to a MCC OTC instance if found else NULL.
*/
struct bt_ots_client *esp_ble_audio_mcc_otc_inst(uint16_t conn_handle);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_MCC_API_H_ */
@@ -0,0 +1,268 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_MCS_DEFS_H_
#define ESP_BLE_AUDIO_MCS_DEFS_H_
#include <zephyr/bluetooth/audio/mcs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!< Minimum playback speed, resulting in 25% speed */
#define ESP_BLE_AUDIO_MCS_PLAYBACK_SPEED_MIN BT_MCS_PLAYBACK_SPEED_MIN
/*!< Quarter playback speed, resulting in 25% speed */
#define ESP_BLE_AUDIO_MCS_PLAYBACK_SPEED_QUARTER BT_MCS_PLAYBACK_SPEED_QUARTER
/*!< Half playback speed, resulting in 50% speed */
#define ESP_BLE_AUDIO_MCS_PLAYBACK_SPEED_HALF BT_MCS_PLAYBACK_SPEED_HALF
/*!< Unity playback speed, resulting in 100% speed */
#define ESP_BLE_AUDIO_MCS_PLAYBACK_SPEED_UNITY BT_MCS_PLAYBACK_SPEED_UNITY
/*!< Double playback speed, resulting in 200% speed */
#define ESP_BLE_AUDIO_MCS_PLAYBACK_SPEED_DOUBLE BT_MCS_PLAYBACK_SPEED_DOUBLE
/*!< Max playback speed, resulting in 395.7% speed (nearly 400%) */
#define ESP_BLE_AUDIO_MCS_PLAYBACK_SPEED_MAX BT_MCS_PLAYBACK_SPEED_MAX
/*!< Maximum seeking speed - Can be negated */
#define ESP_BLE_AUDIO_MCS_SEEKING_SPEED_FACTOR_MAX BT_MCS_SEEKING_SPEED_FACTOR_MAX
/*!< Minimum seeking speed - Can be negated */
#define ESP_BLE_AUDIO_MCS_SEEKING_SPEED_FACTOR_MIN BT_MCS_SEEKING_SPEED_FACTOR_MIN
/*!< No seeking */
#define ESP_BLE_AUDIO_MCS_SEEKING_SPEED_FACTOR_ZERO BT_MCS_SEEKING_SPEED_FACTOR_ZERO
/*!< A single track is played once; there is no next track. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_SINGLE_ONCE BT_MCS_PLAYING_ORDER_SINGLE_ONCE
/*!< A single track is played repeatedly; the next track is the current track. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_SINGLE_REPEAT BT_MCS_PLAYING_ORDER_SINGLE_REPEAT
/*!< The tracks within a group are played once in track order. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_INORDER_ONCE BT_MCS_PLAYING_ORDER_INORDER_ONCE
/*!< The tracks within a group are played in track order repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_INORDER_REPEAT BT_MCS_PLAYING_ORDER_INORDER_REPEAT
/*!< The tracks within a group are played once only from the oldest first. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_OLDEST_ONCE BT_MCS_PLAYING_ORDER_OLDEST_ONCE
/*!< The tracks within a group are played from the oldest first repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_OLDEST_REPEAT BT_MCS_PLAYING_ORDER_OLDEST_REPEAT
/*!< The tracks within a group are played once only from the newest first. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_NEWEST_ONCE BT_MCS_PLAYING_ORDER_NEWEST_ONCE
/*!< The tracks within a group are played from the newest first repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_NEWEST_REPEAT BT_MCS_PLAYING_ORDER_NEWEST_REPEAT
/*!< The tracks within a group are played in random order once. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_SHUFFLE_ONCE BT_MCS_PLAYING_ORDER_SHUFFLE_ONCE
/*!< The tracks within a group are played in random order repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDER_SHUFFLE_REPEAT BT_MCS_PLAYING_ORDER_SHUFFLE_REPEAT
/*!< The current track is invalid, and no track has been selected. */
#define ESP_BLE_AUDIO_MCS_MEDIA_STATE_INACTIVE BT_MCS_MEDIA_STATE_INACTIVE
/*!< The media player is playing the current track. */
#define ESP_BLE_AUDIO_MCS_MEDIA_STATE_PLAYING BT_MCS_MEDIA_STATE_PLAYING
/*!< The current track is paused. The media player has a current track, but it is not being played */
#define ESP_BLE_AUDIO_MCS_MEDIA_STATE_PAUSED BT_MCS_MEDIA_STATE_PAUSED
/*!< The current track is fast forwarding or fast rewinding. */
#define ESP_BLE_AUDIO_MCS_MEDIA_STATE_SEEKING BT_MCS_MEDIA_STATE_SEEKING
/*!< Start playing the current track. */
#define ESP_BLE_AUDIO_MCS_OPC_PLAY BT_MCS_OPC_PLAY
/*!< Pause playing the current track. */
#define ESP_BLE_AUDIO_MCS_OPC_PAUSE BT_MCS_OPC_PAUSE
/*!< Fast rewind the current track. */
#define ESP_BLE_AUDIO_MCS_OPC_FAST_REWIND BT_MCS_OPC_FAST_REWIND
/*!< Fast forward the current track. */
#define ESP_BLE_AUDIO_MCS_OPC_FAST_FORWARD BT_MCS_OPC_FAST_FORWARD
/**
* Stop current activity and return to the paused state and set
* the current track position to the start of the current track.
*/
#define ESP_BLE_AUDIO_MCS_OPC_STOP BT_MCS_OPC_STOP
/*!< Set a new current track position relative to the current track position. */
#define ESP_BLE_AUDIO_MCS_OPC_MOVE_RELATIVE BT_MCS_OPC_MOVE_RELATIVE
/**
* Set the current track position to the starting position of
* the previous segment of the current track.
*/
#define ESP_BLE_AUDIO_MCS_OPC_PREV_SEGMENT BT_MCS_OPC_PREV_SEGMENT
/**
* Set the current track position to the starting position of
* the next segment of the current track.
*/
#define ESP_BLE_AUDIO_MCS_OPC_NEXT_SEGMENT BT_MCS_OPC_NEXT_SEGMENT
/**
* Set the current track position to the starting position of
* the first segment of the current track.
*/
#define ESP_BLE_AUDIO_MCS_OPC_FIRST_SEGMENT BT_MCS_OPC_FIRST_SEGMENT
/**
* Set the current track position to the starting position of
* the last segment of the current track.
*/
#define ESP_BLE_AUDIO_MCS_OPC_LAST_SEGMENT BT_MCS_OPC_LAST_SEGMENT
/**
* Set the current track position to the starting position of
* the nth segment of the current track.
*/
#define ESP_BLE_AUDIO_MCS_OPC_GOTO_SEGMENT BT_MCS_OPC_GOTO_SEGMENT
/*!< Set the current track to the previous track based on the playing order. */
#define ESP_BLE_AUDIO_MCS_OPC_PREV_TRACK BT_MCS_OPC_PREV_TRACK
/*!< Set the current track to the next track based on the playing order. */
#define ESP_BLE_AUDIO_MCS_OPC_NEXT_TRACK BT_MCS_OPC_NEXT_TRACK
/*!< Set the current track to the first track based on the playing order. */
#define ESP_BLE_AUDIO_MCS_OPC_FIRST_TRACK BT_MCS_OPC_FIRST_TRACK
/*!< Set the current track to the last track based on the playing order. */
#define ESP_BLE_AUDIO_MCS_OPC_LAST_TRACK BT_MCS_OPC_LAST_TRACK
/*!< Set the current track to the nth track based on the playing order. */
#define ESP_BLE_AUDIO_MCS_OPC_GOTO_TRACK BT_MCS_OPC_GOTO_TRACK
/*!< Set the current group to the previous group in the sequence of groups. */
#define ESP_BLE_AUDIO_MCS_OPC_PREV_GROUP BT_MCS_OPC_PREV_GROUP
/*!< Set the current group to the next group in the sequence of groups. */
#define ESP_BLE_AUDIO_MCS_OPC_NEXT_GROUP BT_MCS_OPC_NEXT_GROUP
/*!< Set the current group to the first group in the sequence of groups. */
#define ESP_BLE_AUDIO_MCS_OPC_FIRST_GROUP BT_MCS_OPC_FIRST_GROUP
/*!< Set the current group to the last group in the sequence of groups. */
#define ESP_BLE_AUDIO_MCS_OPC_LAST_GROUP BT_MCS_OPC_LAST_GROUP
/*!< Set the current group to the nth group in the sequence of groups. */
#define ESP_BLE_AUDIO_MCS_OPC_GOTO_GROUP BT_MCS_OPC_GOTO_GROUP
/*!< Media control point supported opcodes length */
#define ESP_BLE_AUDIO_MCS_OPCODES_SUPPORTED_LEN BT_MCS_OPCODES_SUPPORTED_LEN
/*!< Support the Play opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_PLAY BT_MCS_OPC_SUP_PLAY
/*!< Support the Pause opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_PAUSE BT_MCS_OPC_SUP_PAUSE
/*!< Support the Fast Rewind opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_FAST_REWIND BT_MCS_OPC_SUP_FAST_REWIND
/*!< Support the Fast Forward opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_FAST_FORWARD BT_MCS_OPC_SUP_FAST_FORWARD
/*!< Support the Stop opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_STOP BT_MCS_OPC_SUP_STOP
/*!< Support the Move Relative opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_MOVE_RELATIVE BT_MCS_OPC_SUP_MOVE_RELATIVE
/*!< Support the Previous Segment opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_PREV_SEGMENT BT_MCS_OPC_SUP_PREV_SEGMENT
/*!< Support the Next Segment opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_NEXT_SEGMENT BT_MCS_OPC_SUP_NEXT_SEGMENT
/*!< Support the First Segment opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_FIRST_SEGMENT BT_MCS_OPC_SUP_FIRST_SEGMENT
/*!< Support the Last Segment opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_LAST_SEGMENT BT_MCS_OPC_SUP_LAST_SEGMENT
/*!< Support the Goto Segment opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_GOTO_SEGMENT BT_MCS_OPC_SUP_GOTO_SEGMENT
/*!< Support the Previous Track opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_PREV_TRACK BT_MCS_OPC_SUP_PREV_TRACK
/*!< Support the Next Track opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_NEXT_TRACK BT_MCS_OPC_SUP_NEXT_TRACK
/*!< Support the First Track opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_FIRST_TRACK BT_MCS_OPC_SUP_FIRST_TRACK
/*!< Support the Last Track opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_LAST_TRACK BT_MCS_OPC_SUP_LAST_TRACK
/*!< Support the Goto Track opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_GOTO_TRACK BT_MCS_OPC_SUP_GOTO_TRACK
/*!< Support the Previous Group opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_PREV_GROUP BT_MCS_OPC_SUP_PREV_GROUP
/*!< Support the Next Group opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_NEXT_GROUP BT_MCS_OPC_SUP_NEXT_GROUP
/*!< Support the First Group opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_FIRST_GROUP BT_MCS_OPC_SUP_FIRST_GROUP
/*!< Support the Last Group opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_LAST_GROUP BT_MCS_OPC_SUP_LAST_GROUP
/*!< Support the Goto Group opcode */
#define ESP_BLE_AUDIO_MCS_OPC_SUP_GOTO_GROUP BT_MCS_OPC_SUP_GOTO_GROUP
/** Action requested by the opcode write was completed successfully. */
#define ESP_BLE_AUDIO_MCS_OPC_NTF_SUCCESS BT_MCS_OPC_NTF_SUCCESS
/** An invalid or unsupported opcode was used for the Media Control Point write. */
#define ESP_BLE_AUDIO_MCS_OPC_NTF_NOT_SUPPORTED BT_MCS_OPC_NTF_NOT_SUPPORTED
/**
* The Media Player State characteristic value is Inactive when the opcode is
* received or the result of the requested action of the opcode results in the
* Media Player State characteristic being set to Inactive.
*/
#define ESP_BLE_AUDIO_MCS_OPC_NTF_PLAYER_INACTIVE BT_MCS_OPC_NTF_PLAYER_INACTIVE
/**
* The requested action of any Media Control Point write cannot be completed
* successfully because of a condition within the player.
*/
#define ESP_BLE_AUDIO_MCS_OPC_NTF_CANNOT_BE_COMPLETED BT_MCS_OPC_NTF_CANNOT_BE_COMPLETED
/*!< Search for Track Name */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_TRACK_NAME BT_MCS_SEARCH_TYPE_TRACK_NAME
/*!< Search for Artist Name */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_ARTIST_NAME BT_MCS_SEARCH_TYPE_ARTIST_NAME
/*!< Search for Album Name */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_ALBUM_NAME BT_MCS_SEARCH_TYPE_ALBUM_NAME
/*!< Search for Group Name */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_GROUP_NAME BT_MCS_SEARCH_TYPE_GROUP_NAME
/*!< Search for Earliest Year */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_EARLIEST_YEAR BT_MCS_SEARCH_TYPE_EARLIEST_YEAR
/*!< Search for Latest Year */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_LATEST_YEAR BT_MCS_SEARCH_TYPE_LATEST_YEAR
/*!< Search for Genre */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_GENRE BT_MCS_SEARCH_TYPE_GENRE
/*!< Search for Tracks only */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_ONLY_TRACKS BT_MCS_SEARCH_TYPE_ONLY_TRACKS
/*!< Search for Groups only */
#define ESP_BLE_AUDIO_MCS_SEARCH_TYPE_ONLY_GROUPS BT_MCS_SEARCH_TYPE_ONLY_GROUPS
/*!< Search control point minimum length */
#define ESP_BLE_AUDIO_SEARCH_LEN_MIN SEARCH_LEN_MIN
/*!< Search control point maximum length */
#define ESP_BLE_AUDIO_SEARCH_LEN_MAX SEARCH_LEN_MAX
/*!< Search control point item (SCI) minimum length */
#define ESP_BLE_AUDIO_SEARCH_SCI_LEN_MIN SEARCH_SCI_LEN_MIN
/*!< Search parameters maximum length */
#define ESP_BLE_AUDIO_SEARCH_PARAM_MAX SEARCH_PARAM_MAX
/*!< Search request was accepted; search has started. */
#define ESP_BLE_AUDIO_MCS_SCP_NTF_SUCCESS BT_MCS_SCP_NTF_SUCCESS
/*!< Search request was invalid; no search started. */
#define ESP_BLE_AUDIO_MCS_SCP_NTF_FAILURE BT_MCS_SCP_NTF_FAILURE
/*!< Group object type is track */
#define ESP_BLE_AUDIO_MCS_GROUP_OBJECT_TRACK_TYPE BT_MCS_GROUP_OBJECT_TRACK_TYPE
/*!< Group object type is group */
#define ESP_BLE_AUDIO_MCS_GROUP_OBJECT_GROUP_TYPE BT_MCS_GROUP_OBJECT_GROUP_TYPE
/*!< A single track is played once; there is no next track. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_SINGLE_ONCE BT_MCS_PLAYING_ORDERS_SUPPORTED_SINGLE_ONCE
/*!< A single track is played repeatedly; the next track is the current track. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_SINGLE_REPEAT BT_MCS_PLAYING_ORDERS_SUPPORTED_SINGLE_REPEAT
/*!< The tracks within a group are played once in track order. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_INORDER_ONCE BT_MCS_PLAYING_ORDERS_SUPPORTED_INORDER_ONCE
/*!< The tracks within a group are played in track order repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_INORDER_REPEAT BT_MCS_PLAYING_ORDERS_SUPPORTED_INORDER_REPEAT
/*!< The tracks within a group are played once only from the oldest first. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_OLDEST_ONCE BT_MCS_PLAYING_ORDERS_SUPPORTED_OLDEST_ONCE
/*!< The tracks within a group are played from the oldest first repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_OLDEST_REPEAT BT_MCS_PLAYING_ORDERS_SUPPORTED_OLDEST_REPEAT
/*!< The tracks within a group are played once only from the newest first. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_NEWEST_ONCE BT_MCS_PLAYING_ORDERS_SUPPORTED_NEWEST_ONCE
/*!< The tracks within a group are played from the newest first repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_NEWEST_REPEAT BT_MCS_PLAYING_ORDERS_SUPPORTED_NEWEST_REPEAT
/*!< The tracks within a group are played in random order once. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_SHUFFLE_ONCE BT_MCS_PLAYING_ORDERS_SUPPORTED_SHUFFLE_ONCE
/*!< The tracks within a group are played in random order repeatedly. */
#define ESP_BLE_AUDIO_MCS_PLAYING_ORDERS_SUPPORTED_SHUFFLE_REPEAT BT_MCS_PLAYING_ORDERS_SUPPORTED_SHUFFLE_REPEAT
/**
* Check if an Object ID is valid for MCS.
* This differs from BT_OTS_VALID_OBJ_ID as MCS does not use the directory list object.
*/
#define ESP_BLE_AUDIO_MCS_VALID_OBJ_ID(id) \
(IN_RANGE((id), BT_OTS_OBJ_ID_MIN, BT_OTS_OBJ_ID_MAX))
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_MCS_DEFS_H_ */
@@ -0,0 +1,743 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_MEDIA_PROXY_API_H_
#define ESP_BLE_AUDIO_MEDIA_PROXY_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/services/ots.h>
#include <zephyr/bluetooth/audio/media_proxy.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< Minimum playback speed, resulting in 25% speed */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYBACK_SPEED_MIN MEDIA_PROXY_PLAYBACK_SPEED_MIN
/*!< Quarter playback speed, resulting in 25% speed */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYBACK_SPEED_QUARTER MEDIA_PROXY_PLAYBACK_SPEED_QUARTER
/*!< Half playback speed, resulting in 50% speed */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYBACK_SPEED_HALF MEDIA_PROXY_PLAYBACK_SPEED_HALF
/*!< Unity playback speed, resulting in 100% speed */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYBACK_SPEED_UNITY MEDIA_PROXY_PLAYBACK_SPEED_UNITY
/*!< Double playback speed, resulting in 200% speed */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYBACK_SPEED_DOUBLE MEDIA_PROXY_PLAYBACK_SPEED_DOUBLE
/*!< Max playback speed, resulting in 395.7% speed (nearly 400%) */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYBACK_SPEED_MAX MEDIA_PROXY_PLAYBACK_SPEED_MAX
/*!< The current track is invalid, and no track has been selected. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_STATE_INACTIVE MEDIA_PROXY_STATE_INACTIVE
/*!< The media player is playing the current track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_STATE_PLAYING MEDIA_PROXY_STATE_PLAYING
/*!< The current track is paused. The media player has a current track, but it is not being played */
#define ESP_BLE_AUDIO_MEDIA_PROXY_STATE_PAUSED MEDIA_PROXY_STATE_PAUSED
/*!< The current track is fast forwarding or fast rewinding. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_STATE_SEEKING MEDIA_PROXY_STATE_SEEKING
/*!< Used internally as the last state value */
#define ESP_BLE_AUDIO_MEDIA_PROXY_STATE_LAST MEDIA_PROXY_STATE_LAST
/*!< Start playing the current track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_PLAY MEDIA_PROXY_OP_PLAY
/*!< Pause playing the current track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_PAUSE MEDIA_PROXY_OP_PAUSE
/*!< Fast rewind the current track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_FAST_REWIND MEDIA_PROXY_OP_FAST_REWIND
/*!< Fast forward the current track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_FAST_FORWARD MEDIA_PROXY_OP_FAST_FORWARD
/**
* Stop current activity and return to the paused state and set
* the current track position to the start of the current track.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_STOP MEDIA_PROXY_OP_STOP
/*!< Set a new current track position relative to the current track position. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_MOVE_RELATIVE MEDIA_PROXY_OP_MOVE_RELATIVE
/**
* Set the current track position to the starting position of
* the previous segment of the current track.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_PREV_SEGMENT MEDIA_PROXY_OP_PREV_SEGMENT
/**
* Set the current track position to the starting position of
* the next segment of the current track.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_NEXT_SEGMENT MEDIA_PROXY_OP_NEXT_SEGMENT
/**
* Set the current track position to the starting position of
* the first segment of the current track.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_FIRST_SEGMENT MEDIA_PROXY_OP_FIRST_SEGMENT
/**
* Set the current track position to the starting position of
* the last segment of the current track.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_LAST_SEGMENT MEDIA_PROXY_OP_LAST_SEGMENT
/**
* Set the current track position to the starting position of
* the nth segment of the current track.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_GOTO_SEGMENT MEDIA_PROXY_OP_GOTO_SEGMENT
/*!< Set the current track to the previous track based on the playing order. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_PREV_TRACK MEDIA_PROXY_OP_PREV_TRACK
/*!< Set the current track to the next track based on the playing order. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_NEXT_TRACK MEDIA_PROXY_OP_NEXT_TRACK
/*!< Set the current track to the first track based on the playing order. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_FIRST_TRACK MEDIA_PROXY_OP_FIRST_TRACK
/*!< Set the current track to the last track based on the playing order. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_LAST_TRACK MEDIA_PROXY_OP_LAST_TRACK
/*!< Set the current track to the nth track based on the playing order. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_GOTO_TRACK MEDIA_PROXY_OP_GOTO_TRACK
/*!< Set the current group to the previous group in the sequence of groups. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_PREV_GROUP MEDIA_PROXY_OP_PREV_GROUP
/*!< Set the current group to the next group in the sequence of groups. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_NEXT_GROUP MEDIA_PROXY_OP_NEXT_GROUP
/*!< Set the current group to the first group in the sequence of groups. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_FIRST_GROUP MEDIA_PROXY_OP_FIRST_GROUP
/*!< Set the current group to the last group in the sequence of groups. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_LAST_GROUP MEDIA_PROXY_OP_LAST_GROUP
/*!< Set the current group to the nth group in the sequence of groups. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_GOTO_GROUP MEDIA_PROXY_OP_GOTO_GROUP
/*!< Media player supported opcodes length */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OPCODES_SUPPORTED_LEN MEDIA_PROXY_OPCODES_SUPPORTED_LEN
/*!< Support the Play opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_PLAY MEDIA_PROXY_OP_SUP_PLAY
/*!< Support the Pause opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_PAUSE MEDIA_PROXY_OP_SUP_PAUSE
/*!< Support the Fast Rewind opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_FAST_REWIND MEDIA_PROXY_OP_SUP_FAST_REWIND
/*!< Support the Fast Forward opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_FAST_FORWARD MEDIA_PROXY_OP_SUP_FAST_FORWARD
/*!< Support the Stop opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_STOP MEDIA_PROXY_OP_SUP_STOP
/*!< Support the Move Relative opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_MOVE_RELATIVE MEDIA_PROXY_OP_SUP_MOVE_RELATIVE
/*!< Support the Previous Segment opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_PREV_SEGMENT MEDIA_PROXY_OP_SUP_PREV_SEGMENT
/*!< Support the Next Segment opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_NEXT_SEGMENT MEDIA_PROXY_OP_SUP_NEXT_SEGMENT
/*!< Support the First Segment opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_FIRST_SEGMENT MEDIA_PROXY_OP_SUP_FIRST_SEGMENT
/*!< Support the Last Segment opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_LAST_SEGMENT MEDIA_PROXY_OP_SUP_LAST_SEGMENT
/*!< Support the Goto Segment opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_GOTO_SEGMENT MEDIA_PROXY_OP_SUP_GOTO_SEGMENT
/*!< Support the Previous Track opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_PREV_TRACK MEDIA_PROXY_OP_SUP_PREV_TRACK
/*!< Support the Next Track opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_NEXT_TRACK MEDIA_PROXY_OP_SUP_NEXT_TRACK
/*!< Support the First Track opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_FIRST_TRACK MEDIA_PROXY_OP_SUP_FIRST_TRACK
/*!< Support the Last Track opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_LAST_TRACK MEDIA_PROXY_OP_SUP_LAST_TRACK
/*!< Support the Goto Track opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_GOTO_TRACK MEDIA_PROXY_OP_SUP_GOTO_TRACK
/*!< Support the Previous Group opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_PREV_GROUP MEDIA_PROXY_OP_SUP_PREV_GROUP
/*!< Support the Next Group opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_NEXT_GROUP MEDIA_PROXY_OP_SUP_NEXT_GROUP
/*!< Support the First Group opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_FIRST_GROUP MEDIA_PROXY_OP_SUP_FIRST_GROUP
/*!< Support the Last Group opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_LAST_GROUP MEDIA_PROXY_OP_SUP_LAST_GROUP
/*!< Support the Goto Group opcode */
#define ESP_BLE_AUDIO_MEDIA_PROXY_OP_SUP_GOTO_GROUP MEDIA_PROXY_OP_SUP_GOTO_GROUP
/*!< Action requested by the opcode write was completed successfully. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_CMD_SUCCESS MEDIA_PROXY_CMD_SUCCESS
/*!< An invalid or unsupported opcode was used for the Media Control Point write. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_CMD_NOT_SUPPORTED MEDIA_PROXY_CMD_NOT_SUPPORTED
/**
* The Media Player State characteristic value is Inactive when the opcode
* is received or the result of the requested action of the opcode results
* in the Media Player State characteristic being set to Inactive.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_CMD_PLAYER_INACTIVE MEDIA_PROXY_CMD_PLAYER_INACTIVE
/**
* The requested action of any Media Control Point write cannot be completed
* successfully because of a condition within the player.
*/
#define ESP_BLE_AUDIO_MEDIA_PROXY_CMD_CANNOT_BE_COMPLETED MEDIA_PROXY_CMD_CANNOT_BE_COMPLETED
/*!< Search for Track Name */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_TRACK_NAME MEDIA_PROXY_SEARCH_TYPE_TRACK_NAME
/*!< Search for Artist Name */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_ARTIST_NAME MEDIA_PROXY_SEARCH_TYPE_ARTIST_NAME
/*!< Search for Album Name */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_ALBUM_NAME MEDIA_PROXY_SEARCH_TYPE_ALBUM_NAME
/*!< Search for Group Name */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_GROUP_NAME MEDIA_PROXY_SEARCH_TYPE_GROUP_NAME
/*!< Search for Earliest Year */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_EARLIEST_YEAR MEDIA_PROXY_SEARCH_TYPE_EARLIEST_YEAR
/*!< Search for Latest Year */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_LATEST_YEAR MEDIA_PROXY_SEARCH_TYPE_LATEST_YEAR
/*!< Search for Genre */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_GENRE MEDIA_PROXY_SEARCH_TYPE_GENRE
/*!< Search for Tracks only */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_ONLY_TRACKS MEDIA_PROXY_SEARCH_TYPE_ONLY_TRACKS
/*!< Search for Groups only */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_TYPE_ONLY_GROUPS MEDIA_PROXY_SEARCH_TYPE_ONLY_GROUPS
/*!< Search request was accepted; search has started. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_SUCCESS MEDIA_PROXY_SEARCH_SUCCESS
/*!< Search request was invalid; no search started. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEARCH_FAILURE MEDIA_PROXY_SEARCH_FAILURE
/*!< Group object type is track */
#define ESP_BLE_AUDIO_MEDIA_PROXY_GROUP_OBJECT_TRACK_TYPE MEDIA_PROXY_GROUP_OBJECT_TRACK_TYPE
/*!< Group object type is group */
#define ESP_BLE_AUDIO_MEDIA_PROXY_GROUP_OBJECT_GROUP_TYPE MEDIA_PROXY_GROUP_OBJECT_GROUP_TYPE
/*!< Maximum seeking speed - Can be negated */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEEKING_SPEED_FACTOR_MAX MEDIA_PROXY_SEEKING_SPEED_FACTOR_MAX
/*!< Minimum seeking speed - Can be negated */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEEKING_SPEED_FACTOR_MIN MEDIA_PROXY_SEEKING_SPEED_FACTOR_MIN
/*!< No seeking */
#define ESP_BLE_AUDIO_MEDIA_PROXY_SEEKING_SPEED_FACTOR_ZERO MEDIA_PROXY_SEEKING_SPEED_FACTOR_ZERO
/*!< A single track is played once; there is no next track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_SINGLE_ONCE MEDIA_PROXY_PLAYING_ORDER_SINGLE_ONCE
/*!< A single track is played repeatedly; the next track is the current track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_SINGLE_REPEAT MEDIA_PROXY_PLAYING_ORDER_SINGLE_REPEAT
/*!< The tracks within a group are played once in track order. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_INORDER_ONCE MEDIA_PROXY_PLAYING_ORDER_INORDER_ONCE
/*!< The tracks within a group are played in track order repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_INORDER_REPEAT MEDIA_PROXY_PLAYING_ORDER_INORDER_REPEAT
/*!< The tracks within a group are played once only from the oldest first. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_OLDEST_ONCE MEDIA_PROXY_PLAYING_ORDER_OLDEST_ONCE
/*!< The tracks within a group are played from the oldest first repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_OLDEST_REPEAT MEDIA_PROXY_PLAYING_ORDER_OLDEST_REPEAT
/*!< The tracks within a group are played once only from the newest first. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_NEWEST_ONCE MEDIA_PROXY_PLAYING_ORDER_NEWEST_ONCE
/*!< The tracks within a group are played from the newest first repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_NEWEST_REPEAT MEDIA_PROXY_PLAYING_ORDER_NEWEST_REPEAT
/*!< The tracks within a group are played in random order once. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_SHUFFLE_ONCE MEDIA_PROXY_PLAYING_ORDER_SHUFFLE_ONCE
/*!< The tracks within a group are played in random order repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDER_SHUFFLE_REPEAT MEDIA_PROXY_PLAYING_ORDER_SHUFFLE_REPEAT
/*!< A single track is played once; there is no next track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SINGLE_ONCE MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SINGLE_ONCE
/*!< A single track is played repeatedly; the next track is the current track. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SINGLE_REPEAT MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SINGLE_REPEAT
/*!< The tracks within a group are played once in track order. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_INORDER_ONCE MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_INORDER_ONCE
/*!< The tracks within a group are played in track order repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_INORDER_REPEAT MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_INORDER_REPEAT
/*!< The tracks within a group are played once only from the oldest first. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_OLDEST_ONCE MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_OLDEST_ONCE
/*!< The tracks within a group are played from the oldest first repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_OLDEST_REPEAT MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_OLDEST_REPEAT
/*!< The tracks within a group are played once only from the newest first. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_NEWEST_ONCE MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_NEWEST_ONCE
/*!< The tracks within a group are played from the newest first repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_NEWEST_REPEAT MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_NEWEST_REPEAT
/*!< The tracks within a group are played in random order once. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SHUFFLE_ONCE MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SHUFFLE_ONCE
/*!< The tracks within a group are played in random order repeatedly. */
#define ESP_BLE_AUDIO_MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SHUFFLE_REPEAT MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SHUFFLE_REPEAT
/** Media player command */
typedef struct mpl_cmd esp_ble_audio_mpl_cmd_t;
/** Media command notification */
typedef struct mpl_cmd_ntf esp_ble_audio_mpl_cmd_ntf_t;
/** Search control item */
typedef struct mpl_sci esp_ble_audio_mpl_sci_t;
/** Search */
typedef struct mpl_search esp_ble_audio_mpl_search_t;
/** Media player instance */
typedef struct media_player esp_ble_audio_media_player_t;
/** Callbacks to a controller, from the media proxy */
typedef struct media_proxy_ctrl_cbs esp_ble_audio_media_proxy_ctrl_cbs_t;
/** Available calls in a player, that the media proxy can call */
typedef struct media_proxy_pl_calls esp_ble_audio_media_proxy_pl_calls_t;
/**
* @brief Register a controller with the media_proxy.
*
* @param ctrl_cbs Callbacks to the controller.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_register(esp_ble_audio_media_proxy_ctrl_cbs_t *ctrl_cbs);
/**
* @brief Discover a remote media player.
*
* Discover a remote media player instance.
* The remote player instance will be discovered, and accessed, using Bluetooth,
* via the media control client and a remote media control service.
* This call will start a GATT discovery of the Media Control Service on the peer,
* and setup handles and subscriptions.
*
* This shall be called once before any other actions can be executed for the
* remote player. The remote player instance will be returned in the
* discover_player() callback.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_discover_player(uint16_t conn_handle);
/**
* @brief Read Media Player Name.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_player_name(esp_ble_audio_media_player_t *player);
/**
* @brief Read Icon Object ID.
*
* Get an ID (48 bit) that can be used to retrieve the Icon
* Object from an Object Transfer Service.
*
* See the Media Control Service spec v1.0 sections 3.2 and
* 4.1 for a description of the Icon Object.
*
* Requires Object Transfer Service
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_icon_id(esp_ble_audio_media_player_t *player);
/**
* @brief Read Icon URL.
*
* Get a URL to the media player's icon.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_icon_url(esp_ble_audio_media_player_t *player);
/**
* @brief Read Track Title.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_title(esp_ble_audio_media_player_t *player);
/**
* @brief Read Track Duration.
*
* The duration of a track is measured in hundredths of a second.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_duration(esp_ble_audio_media_player_t *player);
/**
* @brief Read Track Position.
*
* The position of the player (the playing position) is measured
* in hundredths of a second from the beginning of the track.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_position(esp_ble_audio_media_player_t *player);
/**
* @brief Set Track Position.
*
* Set the playing position of the media player in the current
* track. The position is given in hundredths of a second,
* from the beginning of the track of the track for positive
* values, and (backwards) from the end of the track for
* negative values.
*
* @param player Media player instance pointer.
* @param position The track position to set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_set_track_position(esp_ble_audio_media_player_t *player,
int32_t position);
/**
* @brief Get Playback Speed.
*
* The playback speed parameter is related to the actual
* playback speed as follows:
* actual playback speed = 2^(speed_parameter/64)
*
* A speed parameter of 0 corresponds to unity speed playback
* (i.e. playback at "normal" speed). A speed parameter of
* -128 corresponds to playback at one fourth of normal speed,
* 127 corresponds to playback at almost four times the normal
* speed.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_playback_speed(esp_ble_audio_media_player_t *player);
/**
* @brief Set Playback Speed.
*
* See the get_playback_speed() function for an explanation of
* the playback speed parameter.
*
* Note that the media player may not support all possible
* values of the playback speed parameter. If the value given
* is not supported, and is higher than the current value, the
* player should set the playback speed to the next higher
* supported value. (And correspondingly to the next lower
* supported value for given values lower than the current
* value.)
*
* @param player Media player instance pointer.
* @param speed The playback speed parameter to set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_set_playback_speed(esp_ble_audio_media_player_t *player,
int8_t speed);
/**
* @brief Get Seeking Speed.
*
* The seeking speed gives the speed with which the player is
* seeking. It is a factor, relative to real-time playback
* speed - a factor four means seeking happens at four times
* the real-time playback speed. Positive values are for
* forward seeking, negative values for backwards seeking.
*
* The seeking speed is not settable - a non-zero seeking speed
* is the result of "fast rewind" of "fast forward" commands.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_seeking_speed(esp_ble_audio_media_player_t *player);
/**
* @brief Read Current Track Segments Object ID.
*
* Get an ID (48 bit) that can be used to retrieve the Current
* Track Segments Object from an Object Transfer Service.
*
* See the Media Control Service spec v1.0 sections 3.10 and
* 4.2 for a description of the Track Segments Object.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_track_segments_id(esp_ble_audio_media_player_t *player);
/**
* @brief Read Current Track Object ID.
*
* Get an ID (48 bit) that can be used to retrieve the Current
* Track Object from an Object Transfer Service.
*
* See the Media Control Service spec v1.0 sections 3.11 and
* 4.3 for a description of the Current Track Object.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_current_track_id(esp_ble_audio_media_player_t *player);
/**
* @brief Set Current Track Object ID.
*
* Change the player's current track to the track given by the ID.
* (Behaves similarly to the goto track command.)
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
* @param id The ID of a track object.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_set_current_track_id(esp_ble_audio_media_player_t *player,
uint64_t id);
/**
* @brief Read Next Track Object ID.
*
* Get an ID (48 bit) that can be used to retrieve the Next
* Track Object from an Object Transfer Service.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_next_track_id(esp_ble_audio_media_player_t *player);
/**
* @brief Set Next Track Object ID.
*
* Change the player's next track to the track given by the ID.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
* @param id The ID of a track object.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_set_next_track_id(esp_ble_audio_media_player_t *player,
uint64_t id);
/**
* @brief Read Parent Group Object ID.
*
* Get an ID (48 bit) that can be used to retrieve the Parent
* Track Object from an Object Transfer Service.
*
* The parent group is the parent of the current group.
*
* See the Media Control Service spec v1.0 sections 3.14 and
* 4.4 for a description of the Current Track Object.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_parent_group_id(esp_ble_audio_media_player_t *player);
/**
* @brief Read Current Group Object ID.
*
* Get an ID (48 bit) that can be used to retrieve the Current
* Track Object from an Object Transfer Service
*
* See the Media Control Service spec v1.0 sections 3.14 and
* 4.4 for a description of the Current Group Object.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_current_group_id(esp_ble_audio_media_player_t *player);
/**
* @brief Set Current Group Object ID.
*
* Change the player's current group to the group given by the
* ID, and the current track to the first track in that group.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
* @param id The ID of a group object.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_set_current_group_id(esp_ble_audio_media_player_t *player,
uint64_t id);
/**
* @brief Read Playing Order.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_playing_order(esp_ble_audio_media_player_t *player);
/**
* @brief Set Playing Order.
*
* Set the media player's playing order.
*
* @param player Media player instance pointer.
* @param order The playing order to set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_set_playing_order(esp_ble_audio_media_player_t *player,
uint8_t order);
/**
* @brief Read Playing Orders Supported.
*
* Read a bitmap containing the media player's supported playing orders.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_playing_orders_supported(esp_ble_audio_media_player_t *player);
/**
* @brief Read Media State.
*
* Read the media player's state.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_media_state(esp_ble_audio_media_player_t *player);
/**
* @brief Send Command.
*
* Send a command to the media player.
* Commands may cause the media player to change its state.
* May result in two callbacks - one for the actual sending of the command
* to the player, one for the result of the command from the player.
*
* @param player Media player instance pointer.
* @param command The command to send.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_send_command(esp_ble_audio_media_player_t *player,
const esp_ble_audio_mpl_cmd_t *command);
/**
* @brief Read Commands Supported.
*
* Read a bitmap containing the media player's supported command opcodes.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_commands_supported(esp_ble_audio_media_player_t *player);
/**
* @brief Set Search.
*
* Write a search to the media player.
* If the search is successful, the search results will be available as
* a group object in the Object Transfer Service (OTS).
*
* May result in up to three callbacks:
* - one for the actual sending of the search to the player;
* - one for the result code for the search from the player;
* - if the search is successful, one for the search results object ID
* in the OTs.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
* @param search The search to write.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_send_search(esp_ble_audio_media_player_t *player,
const esp_ble_audio_mpl_search_t *search);
/**
* @brief Read Search Results Object ID.
*
* Get an ID (48 bit) that can be used to retrieve the Search
* Results Object from an Object Transfer Service.
*
* The search results object is a group object.
* The search results object only exists if a successful
* search operation has been done.
*
* Requires Object Transfer Service.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_search_results_id(esp_ble_audio_media_player_t *player);
/**
* @brief Read Content Control ID.
*
* The content control ID identifies a content control service
* on a device, and links it to the corresponding audio stream.
*
* @param player Media player instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_ctrl_get_content_ctrl_id(esp_ble_audio_media_player_t *player);
/**
* @brief Register a player with the media proxy.
*
* Register a player with the media proxy module, for use by media
* controllers.
*
* The media proxy may call any non-NULL function pointers in the
* supplied media_proxy_pl_calls structure.
*
* @param pl_calls Function pointers to the media player's calls.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_pl_register(esp_ble_audio_media_proxy_pl_calls_t *pl_calls);
/**
* @brief Initialize player.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_media_proxy_pl_init(void);
/**
* @brief Get the pointer of the Object Transfer Service used by the Media Control Service.
*
* @return Pointer to an OTS instance if found else NULL.
*/
struct bt_ots *esp_ble_audio_mcs_get_ots(void);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_MEDIA_PROXY_API_H_ */
@@ -0,0 +1,184 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_MICP_API_H_
#define ESP_BLE_AUDIO_MICP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/micp.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< The microphone state is unmuted */
#define ESP_BLE_AUDIO_MICP_MUTE_UNMUTED BT_MICP_MUTE_UNMUTED
/*!< The microphone state is muted */
#define ESP_BLE_AUDIO_MICP_MUTE_MUTED BT_MICP_MUTE_MUTED
/*!< The microphone state is disabled and cannot be muted or unmuted */
#define ESP_BLE_AUDIO_MICP_MUTE_DISABLED BT_MICP_MUTE_DISABLED
/** Microphone Controller instance */
typedef struct bt_micp_mic_ctlr esp_ble_audio_micp_mic_ctlr_t;
/** Struct to hold the Microphone Controller callbacks */
typedef struct bt_micp_mic_ctlr_cb esp_ble_audio_micp_mic_ctlr_cb_t;
/** Struct to hold the Microphone Device callbacks */
typedef struct bt_micp_mic_dev_cb esp_ble_audio_micp_mic_dev_cb_t;
/** Register parameters structure for Microphone Control Service */
typedef struct bt_micp_mic_dev_register_param esp_ble_audio_micp_mic_dev_register_param_t;
/** Microphone Control Profile included services */
typedef struct bt_micp_included esp_ble_audio_micp_included_t;
/**
* @brief Initialize the Microphone Control Profile Microphone Device.
*
* This will enable the Microphone Control Service instance and make it
* discoverable by Microphone Controllers.
*
* @param param Pointer to an initialization structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_dev_register(esp_ble_audio_micp_mic_dev_register_param_t *param);
/**
* @brief Get Microphone Device included services.
*
* Returns a pointer to a struct that contains information about the
* Microphone Device included Audio Input Control Service instances.
*
* @param included Pointer to store the result in.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_dev_included_get(esp_ble_audio_micp_included_t *included);
/**
* @brief Unmute the Microphone Device.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_dev_unmute(void);
/**
* @brief Mute the Microphone Device.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_dev_mute(void);
/**
* @brief Disable the mute functionality on the Microphone Device.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_dev_mute_disable(void);
/**
* @brief Read the mute state on the Microphone Device.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_dev_mute_get(void);
/**
* @brief Get Microphone Control Profile included services.
*
* Returns a pointer to a struct that contains information about the
* Microphone Control Profile included services instances, such as
* pointers to the Audio Input Control Service instances.
*
* @param mic_ctlr Microphone Controller instance pointer.
* @param included Pointer to store the result in.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_ctlr_included_get(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr,
esp_ble_audio_micp_included_t *included);
/**
* @brief Get the Microphone controller from a connection pointer.
*
* Only Microphone controllers that have been initiated can be retrieved.
*
* @param conn_handle Connection handle.
*
* @return Pointer to a Microphone controller instance or NULL if not found.
*/
esp_ble_audio_micp_mic_ctlr_t *esp_ble_audio_micp_mic_ctlr_get_by_conn(uint16_t conn_handle);
/**
* @brief Discover Microphone Control Service.
*
* This will start a GATT discovery and setup handles and subscriptions.
* This shall be called once before any other actions can be executed
* for the peer device.
*
* @param conn_handle Connection handle.
* @param mic_ctlr Valid remote instance object on success.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_ctlr_discover(uint16_t conn_handle,
esp_ble_audio_micp_mic_ctlr_t **mic_ctlr);
/**
* @brief Unmute a remote Microphone Device.
*
* @param mic_ctlr Microphone Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_ctlr_unmute(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr);
/**
* @brief Mute a remote Microphone Device.
*
* @param mic_ctlr Microphone Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_ctlr_mute(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr);
/**
* @brief Read the mute state of a remote Microphone Device.
*
* @param mic_ctlr Microphone Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_ctlr_mute_get(esp_ble_audio_micp_mic_ctlr_t *mic_ctlr);
/**
* @brief Registers the callbacks used by Microphone Controller.
*
* This can only be done as the client.
*
* @param cb The callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_micp_mic_ctlr_cb_register(esp_ble_audio_micp_mic_ctlr_cb_t *cb);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_MICP_API_H_ */
@@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: 2021 Intel Corporation
* SPDX-FileCopyrightText: 2021-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_PACS_API_H_
#define ESP_BLE_AUDIO_PACS_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/pacs.h>
#include "common/init.h"
#include "common/host.h"
#include "esp_ble_audio_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Structure for registering PACS */
typedef struct bt_pacs_register_param esp_ble_audio_pacs_register_param_t;
/** Published Audio Capability structure. */
typedef struct bt_pacs_cap esp_ble_audio_pacs_cap_t;
/**
* @brief Register the Published Audio Capability Service instance.
*
* @param param PACS register parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_register(const esp_ble_audio_pacs_register_param_t *param);
/**
* @brief Unregister the Published Audio Capability Service instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_unregister(void);
/**
* @brief Register Published Audio Capability.
*
* Register Audio Local Capability.
*
* @param dir Direction of the endpoint to register capability for.
* @param cap Capability structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_cap_register(esp_ble_audio_dir_t dir,
esp_ble_audio_pacs_cap_t *cap);
/**
* @brief Unregister Published Audio Capability.
*
* Unregister Audio Local Capability.
*
* @param dir Direction of the endpoint to unregister capability for.
* @param cap Capability structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_cap_unregister(esp_ble_audio_dir_t dir,
esp_ble_audio_pacs_cap_t *cap);
/**
* @brief Set the location for an endpoint type.
*
* @param dir Direction of the endpoints to change location for.
* @param location The location to be set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_set_location(esp_ble_audio_dir_t dir,
esp_ble_audio_location_t location);
/**
* @brief Set the available contexts for an endpoint type.
*
* @param dir Direction of the endpoints to change available contexts for.
* @param contexts The contexts to be set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_set_available_contexts(esp_ble_audio_dir_t dir,
esp_ble_audio_context_t contexts);
/**
* @brief Get the available contexts for an endpoint type.
*
* @param dir Direction of the endpoints to get contexts for.
*
* @return Bitmask of available contexts.
*/
esp_ble_audio_context_t esp_ble_audio_pacs_get_available_contexts(esp_ble_audio_dir_t dir);
/**
* @brief Set the available contexts for a given connection.
*
* This function sets the available contexts value for a given connection.
* The Available Context Value is reset to default on ACL disconnection.
*
* @param conn_handle Connection handle.
* @param dir Direction of the endpoints to change available contexts for.
* @param contexts The contexts to be set or NULL to reset to default.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_conn_set_available_contexts_for_conn(uint16_t conn_handle,
esp_ble_audio_dir_t dir,
esp_ble_audio_context_t *contexts);
/**
* @brief Get the available contexts for a given connection.
*
* This server function returns the available contexts value for a given connection.
*
* @param conn_handle Connection handle.
* @param dir Direction of the endpoints to get contexts for.
*
* @return Bitmask of available contexts.
*/
esp_ble_audio_context_t esp_ble_audio_pacs_get_available_contexts_for_conn(uint16_t conn_handle,
esp_ble_audio_dir_t dir);
/**
* @brief Set the supported contexts for an endpoint type.
*
* @param dir Direction of the endpoints to change available contexts for.
* @param contexts The contexts to be set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pacs_set_supported_contexts(esp_ble_audio_dir_t dir,
esp_ble_audio_context_t contexts);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_PACS_API_H_ */
@@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2023 NXP
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_PBP_API_H_
#define ESP_BLE_AUDIO_PBP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/pbp.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Minimum size of the Public Broadcast Announcement */
#define ESP_BLE_AUDIO_PBP_MIN_PBA_SIZE BT_PBP_MIN_PBA_SIZE
/*!< Broadcast Streams encryption status */
#define ESP_BLE_AUDIO_PBP_ANNOUNCEMENT_FEATURE_ENCRYPTION BT_PBP_ANNOUNCEMENT_FEATURE_ENCRYPTION
/*!< Standard Quality Public Broadcast Audio configuration */
#define ESP_BLE_AUDIO_PBP_ANNOUNCEMENT_FEATURE_STANDARD_QUALITY BT_PBP_ANNOUNCEMENT_FEATURE_STANDARD_QUALITY
/*!< High Quality Public Broadcast Audio configuration */
#define ESP_BLE_AUDIO_PBP_ANNOUNCEMENT_FEATURE_HIGH_QUALITY BT_PBP_ANNOUNCEMENT_FEATURE_HIGH_QUALITY
/** Public Broadcast Announcement features */
typedef enum bt_pbp_announcement_feature esp_ble_audio_pbp_announcement_feature_t;
/**
* @brief Creates a Public Broadcast Announcement based on the information received
* in the features parameter.
*
* @param meta Metadata to be included in the advertising data.
* @param meta_len Size of the metadata fields to be included in the advertising data.
* @param features Public Broadcast Announcement features.
* @param pba_data_buf Pointer to store the PBA advertising data. Buffer size needs to be
* meta_len + ESP_BLE_AUDIO_PBP_MIN_PBA_SIZE.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pbp_get_announcement(const uint8_t meta[], size_t meta_len,
esp_ble_audio_pbp_announcement_feature_t features,
struct net_buf_simple *pba_data_buf);
/**
* @brief Parses the received advertising data corresponding to a Public Broadcast
* Announcement.
* Returns the advertised Public Broadcast Announcement features and metadata.
*
* @param data_type Type of advertising data to be checked.
* @param data Pointer of advertising data to be checked.
* @param data_len Length of advertising data to be checked.
* @param features Pointer to public broadcast source features to store the parsed features in.
* @param meta Pointer to the metadata present in the advertising data.
* @param meta_len Size of the metadata fields to be included in the advertising data.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_pbp_parse_announcement(uint8_t data_type, const uint8_t *data, uint8_t data_len,
esp_ble_audio_pbp_announcement_feature_t *features,
uint8_t **meta, uint8_t *meta_len);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_PBP_API_H_ */
@@ -0,0 +1,635 @@
/*
* SPDX-FileCopyrightText: 2020 Bose Corporation
* SPDX-FileCopyrightText: 2021 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_TBS_API_H_
#define ESP_BLE_AUDIO_TBS_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/tbs.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The GTBS index denotes whenever a callback is from a Generic Telephone
* Bearer Service (GTBS) instance, or whenever the client should perform
* on action on the GTBS instance of the server, rather than any of the
* specific Telephone Bearer Service instances.
*/
#define ESP_BLE_AUDIO_TBS_GTBS_INDEX BT_TBS_GTBS_INDEX
/*!< A remote party is calling (incoming call). */
#define ESP_BLE_AUDIO_TBS_CALL_STATE_INCOMING BT_TBS_CALL_STATE_INCOMING
/**
* The process to call the remote party has started on the server, but the
* remote party is not being alerted (outgoing call).
*/
#define ESP_BLE_AUDIO_TBS_CALL_STATE_DIALING BT_TBS_CALL_STATE_DIALING
/*!< A remote party is being alerted (outgoing call). */
#define ESP_BLE_AUDIO_TBS_CALL_STATE_ALERTING BT_TBS_CALL_STATE_ALERTING
/*!< The call is in an active conversation. */
#define ESP_BLE_AUDIO_TBS_CALL_STATE_ACTIVE BT_TBS_CALL_STATE_ACTIVE
/**
* The call is connected but held locally. Locally Held implies that either
* the server or the client can affect the state.
*/
#define ESP_BLE_AUDIO_TBS_CALL_STATE_LOCALLY_HELD BT_TBS_CALL_STATE_LOCALLY_HELD
/**
* The call is connected but held remotely. Remotely Held means that the state
* is controlled by the remote party of a call.
*/
#define ESP_BLE_AUDIO_TBS_CALL_STATE_REMOTELY_HELD BT_TBS_CALL_STATE_REMOTELY_HELD
/*!< The call is connected but held both locally and remotely. */
#define ESP_BLE_AUDIO_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD
/*!< The URI value used to originate a call was formed improperly. */
#define ESP_BLE_AUDIO_TBS_REASON_BAD_REMOTE_URI BT_TBS_REASON_BAD_REMOTE_URI
/*!< The call failed. */
#define ESP_BLE_AUDIO_TBS_REASON_CALL_FAILED BT_TBS_REASON_CALL_FAILED
/*!< The remote party ended the call. */
#define ESP_BLE_AUDIO_TBS_REASON_REMOTE_ENDED_CALL BT_TBS_REASON_REMOTE_ENDED_CALL
/*!< The call ended from the server. */
#define ESP_BLE_AUDIO_TBS_REASON_SERVER_ENDED_CALL BT_TBS_REASON_SERVER_ENDED_CALL
/*!< The line was busy. */
#define ESP_BLE_AUDIO_TBS_REASON_LINE_BUSY BT_TBS_REASON_LINE_BUSY
/*!< Network congestion. */
#define ESP_BLE_AUDIO_TBS_REASON_NETWORK_CONGESTED BT_TBS_REASON_NETWORK_CONGESTED
/*!< The client terminated the call. */
#define ESP_BLE_AUDIO_TBS_REASON_CLIENT_TERMINATED BT_TBS_REASON_CLIENT_TERMINATED
/*!< No service. */
#define ESP_BLE_AUDIO_TBS_REASON_NO_SERVICE BT_TBS_REASON_NO_SERVICE
/*!< No answer. */
#define ESP_BLE_AUDIO_TBS_REASON_NO_ANSWER BT_TBS_REASON_NO_ANSWER
/*!< Unspecified. */
#define ESP_BLE_AUDIO_TBS_REASON_UNSPECIFIED BT_TBS_REASON_UNSPECIFIED
/*!< The opcode write was successful. */
#define ESP_BLE_AUDIO_TBS_RESULT_CODE_SUCCESS BT_TBS_RESULT_CODE_SUCCESS
/*!< An invalid opcode was used for the Call Control Point write. */
#define ESP_BLE_AUDIO_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED
/*!< The requested operation cannot be completed. */
#define ESP_BLE_AUDIO_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE
/*!< The Call Index used for the Call Control Point write is invalid. */
#define ESP_BLE_AUDIO_TBS_RESULT_CODE_INVALID_CALL_INDEX BT_TBS_RESULT_CODE_INVALID_CALL_INDEX
/**
* The opcode written to the Call Control Point was received when the current
* Call State for the Call Index was not in the expected state.
*/
#define ESP_BLE_AUDIO_TBS_RESULT_CODE_STATE_MISMATCH BT_TBS_RESULT_CODE_STATE_MISMATCH
/*!< Lack of internal resources to complete the requested action. */
#define ESP_BLE_AUDIO_TBS_RESULT_CODE_OUT_OF_RESOURCES BT_TBS_RESULT_CODE_OUT_OF_RESOURCES
/*!< The Outgoing URI is incorrect or invalid when an Originate opcode is sent. */
#define ESP_BLE_AUDIO_TBS_RESULT_CODE_INVALID_URI BT_TBS_RESULT_CODE_INVALID_URI
/*!< Local Hold and Local Retrieve Call Control Point Opcodes supported */
#define ESP_BLE_AUDIO_TBS_FEATURE_HOLD BT_TBS_FEATURE_HOLD
/*!< Join Call Control Point Opcode supported */
#define ESP_BLE_AUDIO_TBS_FEATURE_JOIN BT_TBS_FEATURE_JOIN
/*!< All Control Point Opcodes supported */
#define ESP_BLE_AUDIO_TBS_FEATURE_ALL BT_TBS_FEATURE_ALL
/*!< No service */
#define ESP_BLE_AUDIO_TBS_SIGNAL_STRENGTH_NO_SERVICE BT_TBS_SIGNAL_STRENGTH_NO_SERVICE
/*!< Maximum signal strength */
#define ESP_BLE_AUDIO_TBS_SIGNAL_STRENGTH_MAX BT_TBS_SIGNAL_STRENGTH_MAX
/*!< Signal strength is unknown */
#define ESP_BLE_AUDIO_TBS_SIGNAL_STRENGTH_UNKNOWN BT_TBS_SIGNAL_STRENGTH_UNKNOWN
/*!< 3G */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_3G BT_TBS_TECHNOLOGY_3G
/*!< 4G */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_4G BT_TBS_TECHNOLOGY_4G
/*!< Long-term evolution (LTE) */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_LTE BT_TBS_TECHNOLOGY_LTE
/*!< Wifi */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_WIFI BT_TBS_TECHNOLOGY_WIFI
/*!< 5G */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_5G BT_TBS_TECHNOLOGY_5G
/*!< Global System for Mobile Communications (GSM) */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_GSM BT_TBS_TECHNOLOGY_GSM
/*!< Code-Division Multiple Access (CDMA) */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_CDMA BT_TBS_TECHNOLOGY_CDMA
/*!< 2G */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_2G BT_TBS_TECHNOLOGY_2G
/*!< Wideband Code-Division Multiple Access (WCDMA) */
#define ESP_BLE_AUDIO_TBS_TECHNOLOGY_WCDMA BT_TBS_TECHNOLOGY_WCDMA
/*!< Inband ringtone enabled */
#define ESP_BLE_AUDIO_TBS_STATUS_FLAG_INBAND_RINGTONE BT_TBS_STATUS_FLAG_INBAND_RINGTONE
/*!< Server is in silent mod */
#define ESP_BLE_AUDIO_TBS_STATUS_FLAG_SILENT_MOD BT_TBS_STATUS_FLAG_SILENT_MOD
/*!< If set, call is outgoing else incoming */
#define ESP_BLE_AUDIO_TBS_CALL_FLAG_OUTGOING BT_TBS_CALL_FLAG_OUTGOING
/*!< If set call is withheld, else not withheld */
#define ESP_BLE_AUDIO_TBS_CALL_FLAG_WITHHELD BT_TBS_CALL_FLAG_WITHHELD
/*!< If set call is withheld by network, else provided by network */
#define ESP_BLE_AUDIO_TBS_CALL_FLAG_WITHHELD_BY_NETWORK BT_TBS_CALL_FLAG_WITHHELD_BY_NETWORK
/** Struct to hold the Telephone Bearer Service callbacks */
typedef struct bt_tbs_cb esp_ble_audio_tbs_cb_t;
/** Telephone Bearer Service instance */
typedef struct bt_tbs_instance esp_ble_audio_tbs_instance_t;
/** Struct to hold the parameters to initialize the bearer */
typedef struct bt_tbs_register_param esp_ble_audio_tbs_register_param_t;
/** Struct to hold the Telephone Bearer Service client callbacks */
typedef struct bt_tbs_client_cb esp_ble_audio_tbs_client_cb_t;
/** Struct to hold a call as the Telephone Bearer Service client */
typedef struct bt_tbs_client_call esp_ble_audio_tbs_client_call_t;
/** Struct to hold a call state */
typedef struct bt_tbs_client_call_state esp_ble_audio_tbs_client_call_state_t;
/**
* @brief Accept an alerting call.
*
* @param call_index The index of the call that will be accepted.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_accept(uint8_t call_index);
/**
* @brief Hold a call.
*
* @param call_index The index of the call that will be held.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_hold(uint8_t call_index);
/**
* @brief Retrieve a call.
*
* @param call_index The index of the call that will be retrieved.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_retrieve(uint8_t call_index);
/**
* @brief Terminate a call.
*
* @param call_index The index of the call that will be terminated.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_terminate(uint8_t call_index);
/**
* @brief Originate a call.
*
* @param bearer_index The index of the Telephone Bearer.
* @param uri The remote URI.
* @param call_index Pointer to a value where the new call_index will be stored.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_originate(uint8_t bearer_index,
char *uri,
uint8_t *call_index);
/**
* @brief Join calls.
*
* @param call_index_cnt The number of call indexes to join.
* @param call_indexes Array of call indexes to join.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_join(uint8_t call_index_cnt, uint8_t *call_indexes);
/**
* @brief Notify the server that the remote party answered the call.
*
* @param call_index The index of the call that was answered.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_remote_answer(uint8_t call_index);
/**
* @brief Notify the server that the remote party held the call.
*
* @param call_index The index of the call that was held.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_remote_hold(uint8_t call_index);
/**
* @brief Notify the server that the remote party retrieved the call.
*
* @param call_index The index of the call that was retrieved.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_remote_retrieve(uint8_t call_index);
/**
* @brief Notify the server that the remote party terminated the call.
*
* @param call_index The index of the call that was terminated.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_remote_terminate(uint8_t call_index);
/**
* @brief Notify the server of an incoming call.
*
* @param bearer_index The index of the Telephone Bearer.
* @param to The URI that is receiving the call.
* @param from The URI of the remote caller.
* @param friendly_name The friendly name of the remote caller.
* @param call_index The call index on success.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_remote_incoming(uint8_t bearer_index,
const char *to,
const char *from,
const char *friendly_name,
uint8_t *call_index);
/**
* @brief Set a new bearer provider.
*
* @param bearer_index The index of the Telephone Bearer or
* ESP_BLE_AUDIO_TBS_GTBS_INDEX for GTBS.
* @param name The new bearer provider name.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_set_bearer_provider_name(uint8_t bearer_index, const char *name);
/**
* @brief Set a new bearer technology.
*
* @param bearer_index The index of the Telephone Bearer or
* ESP_BLE_AUDIO_TBS_GTBS_INDEX for GTBS.
* @param new_technology The new bearer technology.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_set_bearer_technology(uint8_t bearer_index, uint8_t new_technology);
/**
* @brief Update the signal strength reported by the server.
*
* @param bearer_index The index of the Telephone Bearer or
* ESP_BLE_AUDIO_TBS_GTBS_INDEX for GTBS.
* @param new_signal_strength The new signal strength.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_set_signal_strength(uint8_t bearer_index, uint8_t new_signal_strength);
/**
* @brief Sets the feature and status value.
*
* @param bearer_index The index of the Telephone Bearer or
* ESP_BLE_AUDIO_TBS_GTBS_INDEX for GTBS.
* @param status_flags The new feature and status value.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_set_status_flags(uint8_t bearer_index, uint16_t status_flags);
/**
* @brief Sets the URI scheme list of a bearer.
*
* @param bearer_index The index of the Telephone Bearer.
* @param uri_list List of URI prefixes (e.g. {"skype", "tel"}).
* @param uri_count Number of URI prefixes in @p uri_list.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_set_uri_scheme_list(uint8_t bearer_index,
const char **uri_list,
uint8_t uri_count);
/**
* @brief Register the callbacks for TBS.
*
* @param cbs Pointer to the callback structure.
*/
void esp_ble_audio_tbs_register_cb(esp_ble_audio_tbs_cb_t *cbs);
/**
* @brief Register a Telephone Bearer.
*
* This will register a Telephone Bearer Service (TBS) (or a Generic Telephone
* Bearer service (GTBS)) with the provided parameters.
*
* As per the TBS specification, the GTBS shall be instantiated for the feature,
* and as such a GTBS shall always be registered before any TBS can be registered.
*
* @param param The parameters to initialize the bearer.
* @param bearer_index The registered bearer index on success.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_register_bearer(const esp_ble_audio_tbs_register_param_t *param,
uint8_t *bearer_index);
/**
* @brief Unregister a Telephone Bearer.
*
* This will unregister a Telephone Bearer Service (TBS) (or a Generic Telephone
* Bearer service (GTBS)) with the provided parameters.
*
* Similarly, all TBS shall be unregistered before the GTBS can be unregistered with.
*
* @param bearer_index The index of the bearer to unregister.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_unregister_bearer(uint8_t bearer_index);
/**
* @brief Discover TBS for a connection. This will start a GATT
* discover and setup handles and subscriptions.
*
* @param conn_handle Connection handle.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_discover(uint16_t conn_handle);
/**
* @brief Set the signal strength reporting interval for a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
* @param interval The interval to write (0-255 seconds).
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_set_signal_strength_interval(uint16_t conn_handle,
uint8_t inst_index,
uint8_t interval);
/**
* @brief Request to originate a call.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
* @param uri The URI of the callee.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_originate_call(uint16_t conn_handle,
uint8_t inst_index,
const char *uri);
/**
* @brief Request to terminate a call.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
* @param call_index The call index to terminate.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_terminate_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index);
/**
* @brief Request to hold a call.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
* @param call_index The call index to place on hold.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_hold_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index);
/**
* @brief Accept an incoming call.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
* @param call_index The call index to accept.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_accept_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index);
/**
* @brief Retrieve call from (local) hold.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
* @param call_index The call index to retrieve.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_retrieve_call(uint16_t conn_handle,
uint8_t inst_index,
uint8_t call_index);
/**
* @brief Join multiple calls.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
* @param call_indexes Array of call indexes.
* @param count Number of call indexes in the call_indexes array.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_join_calls(uint16_t conn_handle,
uint8_t inst_index,
const uint8_t *call_indexes,
uint8_t count);
/**
* @brief Read the bearer provider name of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_bearer_provider_name(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the UCI of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_bearer_uci(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the technology of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_technology(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the URI schemes list of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_uri_list(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the current signal strength of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_signal_strength(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the signal strength reporting interval of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_signal_interval(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the list of current calls of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_current_calls(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the content ID of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_ccid(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the call target URI of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_call_uri(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the feature and status value of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_status_flags(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the states of the current calls of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_call_state(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the remote URI of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_remote_uri(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the friendly name of a call for a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_friendly_name(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Read the supported opcode of a TBS instance.
*
* @param conn_handle Connection handle.
* @param inst_index The index of the TBS instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_read_optional_opcodes(uint16_t conn_handle, uint8_t inst_index);
/**
* @brief Register the callbacks for CCP.
*
* @param cbs Pointer to the callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tbs_client_register_cb(esp_ble_audio_tbs_client_cb_t *cbs);
/**
* @brief Look up Telephone Bearer Service instance by CCID.
*
* @param conn_handle Connection handle.
* @param ccid The CCID to lookup a service instance for.
*
* @return Pointer to TBS instance if found, NULL otherwise.
*/
esp_ble_audio_tbs_instance_t *esp_ble_audio_tbs_client_get_by_ccid(uint16_t conn_handle, uint8_t ccid);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_TBS_API_H_ */
@@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 2023 NXP
* SPDX-FileCopyrightText: 2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_TMAP_API_H_
#define ESP_BLE_AUDIO_TMAP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/tmap.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< TMAP Call Gateway role */
#define ESP_BLE_AUDIO_TMAP_ROLE_CG BT_TMAP_ROLE_CG
/*!< TMAP Call Terminal role */
#define ESP_BLE_AUDIO_TMAP_ROLE_CT BT_TMAP_ROLE_CT
/*!< TMAP Unicast Media Sender role */
#define ESP_BLE_AUDIO_TMAP_ROLE_UMS BT_TMAP_ROLE_UMS
/*!< TMAP Unicast Media Receiver role */
#define ESP_BLE_AUDIO_TMAP_ROLE_UMR BT_TMAP_ROLE_UMR
/*!< TMAP Broadcast Media Sender role */
#define ESP_BLE_AUDIO_TMAP_ROLE_BMS BT_TMAP_ROLE_BMS
/*!< TMAP Broadcast Media Receiver role */
#define ESP_BLE_AUDIO_TMAP_ROLE_BMR BT_TMAP_ROLE_BMR
/** TMAP Role characteristic */
typedef enum bt_tmap_role esp_ble_audio_tmap_role_t;
/** TMAP callback structure */
typedef struct bt_tmap_cb esp_ble_audio_tmap_cb_t;
/**
* @brief Adds TMAS instance to database and sets the received TMAP role(s).
*
* @param role TMAP role(s) of the device (one or multiple).
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tmap_register(esp_ble_audio_tmap_role_t role);
/**
* @brief Perform service discovery as TMAP Client.
*
* @param conn_handle Connection handle.
* @param tmap_cb Pointer to struct of TMAP callbacks.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_tmap_discover(uint16_t conn_handle,
const esp_ble_audio_tmap_cb_t *tmap_cb);
/**
* @brief Set one or multiple TMAP roles dynamically.
* Previously registered value will be overwritten.
*
* @param role TMAP role(s).
*/
void esp_ble_audio_tmap_set_role(esp_ble_audio_tmap_role_t role);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_TMAP_API_H_ */
@@ -0,0 +1,299 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_VCP_API_H_
#define ESP_BLE_AUDIO_VCP_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/vcp.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< The volume state is unmuted */
#define ESP_BLE_AUDIO_VCP_STATE_UNMUTED BT_VCP_STATE_UNMUTED
/*!< The volume state is muted */
#define ESP_BLE_AUDIO_VCP_STATE_MUTED BT_VCP_STATE_MUTED
/** Volume Control Service included services */
typedef struct bt_vcp_included esp_ble_audio_vcp_included_t;
/** Volume Control Service instance */
typedef struct bt_vcp_vol_ctlr esp_ble_audio_vcp_vol_ctlr_t;
/** Struct to hold the Volume Controller callbacks */
typedef struct bt_vcp_vol_ctlr_cb esp_ble_audio_vcp_vol_ctlr_cb_t;
/** Struct to hold the Volume Renderer callbacks */
typedef struct bt_vcp_vol_rend_cb esp_ble_audio_vcp_vol_rend_cb_t;
/** Register structure for Volume Control Service */
typedef struct bt_vcp_vol_rend_register_param esp_ble_audio_vcp_vol_rend_register_param_t;
/**
* @brief Get Volume Control Service included services.
*
* Returns a pointer to a struct that contains information about the
* Volume Control Service included service instances, such as pointers
* to the Volume Offset Control Service (Volume Offset Control Service)
* or Audio Input Control Service (AICS) instances.
*
* @param included Pointer to store the result in.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_included_get(esp_ble_audio_vcp_included_t *included);
/**
* @brief Register the Volume Control Service.
*
* This will register and enable the service and make it discoverable by
* clients.
*
* @param param Volume Control Service register parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_register(esp_ble_audio_vcp_vol_rend_register_param_t *param);
/**
* @brief Set the Volume Control Service volume step size.
*
* This can only be done as the server.
*
* @param volume_step The volume step size (1-255).
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_set_step(uint8_t volume_step);
/**
* @brief Get the Volume Control Service volume state.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_get_state(void);
/**
* @brief Get the Volume Control Service flags.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_get_flags(void);
/**
* @brief Turn the volume down by one step on the server.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_vol_down(void);
/**
* @brief Turn the volume up by one step on the server.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_vol_up(void);
/**
* @brief Turn the volume down and unmute the server.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_unmute_vol_down(void);
/**
* @brief Turn the volume up and unmute the server.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_unmute_vol_up(void);
/**
* @brief Set the volume on the server.
*
* @param volume The absolute volume to set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_set_vol(uint8_t volume);
/**
* @brief Unmute the server.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_unmute(void);
/**
* @brief Mute the server.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_rend_mute(void);
/**
* @brief Registers the callbacks used by the Volume Controller.
*
* @param cb The callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_cb_register(esp_ble_audio_vcp_vol_ctlr_cb_t *cb);
/**
* @brief Unregisters the callbacks used by the Volume Controller.
*
* @param cb The callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_cb_unregister(esp_ble_audio_vcp_vol_ctlr_cb_t *cb);
/**
* @brief Discover Volume Control Service and included services.
*
* This will start a GATT discovery and setup handles and subscriptions.
* This shall be called once before any other actions can be executed
* for the peer device.
*
* This shall only be done as the client,
*
* @param conn_handle Connection handle.
* @param vol_ctlr Valid remote instance object on success.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_discover(uint16_t conn_handle,
esp_ble_audio_vcp_vol_ctlr_t **vol_ctlr);
/**
* @brief Get the volume controller from a connection pointer
*
* Get the Volume Control Profile Volume Controller pointer from a connection.
* Only volume controllers that have been initiated can be retrieved.
*
* @param conn_handle Connection handle.
*
* @return Pointer to a Volume Control Profile Volume Controller instance.
* NULL if the connection has not been found has not done discovery yet.
*/
esp_ble_audio_vcp_vol_ctlr_t *esp_ble_audio_vcp_vol_ctlr_get_by_conn(uint16_t conn_handle);
/**
* @brief Get Volume Control Service included services.
*
* Returns a pointer to a struct that contains information about the
* Volume Control Service included service instances, such as pointers
* to the Volume Offset Control Service (Volume Offset Control Service)
* or Audio Input Control Service (AICS) instances.
*
* @param vol_ctlr Volume Controller instance pointer.
* @param included Pointer to store the result in.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_included_get(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr,
esp_ble_audio_vcp_included_t *included);
/**
* @brief Read the volume state of a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_read_state(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
/**
* @brief Read the volume flags of a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_read_flags(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
/**
* @brief Turn the volume down one step on a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_vol_down(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
/**
* @brief Turn the volume up one step on a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_vol_up(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
/**
* @brief Turn the volume down one step and unmute on a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_unmute_vol_down(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
/**
* @brief Turn the volume up one step and unmute on a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_unmute_vol_up(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
/**
* @brief Set the absolute volume on a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
* @param volume The absolute volume to set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_set_vol(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr, uint8_t volume);
/**
* @brief Unmute a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_unmute(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
/**
* @brief Mute a remote Volume Renderer.
*
* @param vol_ctlr Volume Controller instance pointer.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vcp_vol_ctlr_mute(esp_ble_audio_vcp_vol_ctlr_t *vol_ctlr);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_VCP_API_H_ */
@@ -0,0 +1,168 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_AUDIO_VOCS_API_H_
#define ESP_BLE_AUDIO_VOCS_API_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/audio/vocs.h>
#include "common/init.h"
#include "common/host.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!< Minimum offset value */
#define ESP_BLE_AUDIO_VOCS_MIN_OFFSET BT_VOCS_MIN_OFFSET
/*!< Maximum offset value */
#define ESP_BLE_AUDIO_VOCS_MAX_OFFSET BT_VOCS_MAX_OFFSET
/** Volume Offset Control Service instance */
typedef struct bt_vocs esp_ble_audio_vocs_t;
/** Struct to hold the Volume Offset Control Service callbacks */
typedef struct bt_vocs_cb esp_ble_audio_vocs_cb_t;
/** Structure for registering a Volume Offset Control Service instance */
typedef struct bt_vocs_register_param esp_ble_audio_vocs_register_param_t;
/** Structure for discovering a Volume Offset Control Service instance */
typedef struct bt_vocs_discover_param esp_ble_audio_vocs_discover_param_t;
/**
* @brief Get a free service instance of Volume Offset Control Service from the pool.
*
* @return Volume Offset Control Service instance in case of success or NULL in case of error.
*/
esp_ble_audio_vocs_t *esp_ble_audio_vocs_free_instance_get(void);
/**
* @brief Get the service declaration attribute.
*
* The first service attribute returned can be included in any other GATT service.
*
* @param vocs Volume Offset Control Service instance.
*
* @return Pointer to the attributes of the service.
*/
void *esp_ble_audio_vocs_svc_decl_get(esp_ble_audio_vocs_t *vocs);
/**
* @brief Register the Volume Offset Control Service instance.
*
* @param vocs Volume Offset Control Service instance.
* @param param Volume Offset Control Service register parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_register(esp_ble_audio_vocs_t *vocs,
const esp_ble_audio_vocs_register_param_t *param);
/**
* @brief Read the Volume Offset Control Service offset state.
*
* @param inst Pointer to the Volume Offset Control Service instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_state_get(esp_ble_audio_vocs_t *inst);
/**
* @brief Set the Volume Offset Control Service offset state.
*
* @param inst Pointer to the Volume Offset Control Service instance.
* @param offset The offset to set (-255 to 255).
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_state_set(esp_ble_audio_vocs_t *inst, int16_t offset);
/**
* @brief Read the Volume Offset Control Service location.
*
* @param inst Pointer to the Volume Offset Control Service instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_location_get(esp_ble_audio_vocs_t *inst);
/**
* @brief Set the Volume Offset Control Service location.
*
* @param inst Pointer to the Volume Offset Control Service instance.
* @param location The location to set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_location_set(esp_ble_audio_vocs_t *inst, uint32_t location);
/**
* @brief Read the Volume Offset Control Service output description.
*
* @param inst Pointer to the Volume Offset Control Service instance.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_description_get(esp_ble_audio_vocs_t *inst);
/**
* @brief Set the Volume Offset Control Service description.
*
* @param inst Pointer to the Volume Offset Control Service instance.
* @param description The UTF-8 encoded string description to set.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_description_set(esp_ble_audio_vocs_t *inst,
const char *description);
/**
* @brief Registers the callbacks for the Volume Offset Control Service client.
*
* @param inst Pointer to the Volume Offset Control Service client instance.
* @param cb Pointer to the callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_client_cb_register(esp_ble_audio_vocs_t *inst,
esp_ble_audio_vocs_cb_t *cb);
/**
* @brief Returns a pointer to a Volume Offset Control Service client instance.
*
* @return Pointer to the instance, or NULL if no free instances are left.
*/
esp_ble_audio_vocs_t *esp_ble_audio_vocs_client_free_instance_get(void);
/**
* @brief Discover a Volume Offset Control Service.
*
* Attempts to discover a Volume Offset Control Service on a server given the @p param.
*
* @param conn_handle Connection handle.
* @param inst Pointer to the Volume Offset Control Service client instance.
* @param param Pointer to the parameters.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_audio_vocs_discover(uint16_t conn_handle,
esp_ble_audio_vocs_t *inst,
const esp_ble_audio_vocs_discover_param_t *param);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_AUDIO_VOCS_API_H_ */
@@ -0,0 +1,432 @@
/*
* SPDX-FileCopyrightText: 2020 Intel Corporation
* SPDX-FileCopyrightText: 2021-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_ble_iso_common_api.h"
esp_err_t esp_ble_iso_data_parse(const uint8_t ltv[], size_t size,
bool (*func)(uint8_t type,
const uint8_t *data,
uint8_t data_len,
void *user_data),
void *user_data)
{
if (ltv == NULL || func == NULL) {
return ESP_ERR_INVALID_ARG;
}
for (size_t i = 0; i < size;) {
const size_t remaining = size - i;
const uint8_t len = ltv[i];
uint8_t data_len;
uint8_t type;
/* LTV item format: [len][type][value...], total item size is len + 1.
* len includes type and value, but excludes itself.
*/
if (len < sizeof(uint8_t) || len > (remaining - 1)) {
return ESP_ERR_INVALID_SIZE;
}
type = ltv[i + 1];
data_len = len - sizeof(uint8_t);
/* Skip empty value entries in strict parsing mode. */
if (data_len == 0) {
i += (size_t)len + 1;
continue;
}
if (func(type, &ltv[i + 2], data_len, user_data) == false) {
return ESP_OK;
}
i += (size_t)len + 1;
}
return ESP_OK;
}
#if CONFIG_BT_ISO_UNICAST
#if CONFIG_BT_ISO_PERIPHERAL
esp_err_t esp_ble_iso_server_register(esp_ble_iso_server_t *server)
{
int err;
err = bt_iso_server_register_safe(server);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_server_unregister(esp_ble_iso_server_t *server)
{
int err;
err = bt_iso_server_unregister_safe(server);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_ISO_PERIPHERAL */
#if CONFIG_BT_ISO_CENTRAL
esp_err_t esp_ble_iso_cig_create(esp_ble_iso_cig_param_t *param,
esp_ble_iso_cig_t **out_cig)
{
int err;
err = bt_iso_cig_create_safe(param, out_cig);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_cig_reconfigure(esp_ble_iso_cig_t *cig,
esp_ble_iso_cig_param_t *param)
{
int err;
err = bt_iso_cig_reconfigure_safe(cig, param);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_cig_terminate(esp_ble_iso_cig_t *cig)
{
int err;
err = bt_iso_cig_terminate_safe(cig);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_chan_connect(esp_ble_iso_connect_param_t *param,
uint16_t conn_handle, size_t count)
{
esp_err_t ret = ESP_OK;
void *conn;
int err;
if (param == NULL || count == 0) {
return ESP_ERR_INVALID_ARG;
}
bt_le_host_lock();
conn = bt_le_acl_conn_find(conn_handle);
if (conn == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
for (size_t i = 0; i < count; i++) {
param[i].acl = conn;
}
err = bt_iso_chan_connect(param, count);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_ISO_CENTRAL */
esp_err_t esp_ble_iso_chan_disconnect(esp_ble_iso_chan_t *chan)
{
int err;
err = bt_iso_chan_disconnect_safe(chan);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_ISO_UNICAST */
static inline bool valid_dir(uint8_t dir)
{
if (dir != ESP_BLE_ISO_DATA_PATH_DIR_INPUT &&
dir != ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT) {
return false;
}
return true;
}
esp_err_t esp_ble_iso_setup_data_path(const esp_ble_iso_chan_t *chan, uint8_t dir,
const esp_ble_iso_chan_path_t *path)
{
int err;
if (chan == NULL || path == NULL || valid_dir(dir) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_iso_setup_data_path_safe(chan, dir, path);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_remove_data_path(const esp_ble_iso_chan_t *chan, uint8_t dir)
{
int err;
if (chan == NULL || valid_dir(dir) == false) {
return ESP_ERR_INVALID_ARG;
}
err = bt_iso_remove_data_path_safe(chan, dir);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_ISO_BROADCAST
esp_err_t esp_ble_iso_big_register_cb(esp_ble_iso_big_cb_t *cb)
{
int err;
if (cb == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_iso_big_register_cb_safe(cb);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_ISO_BROADCASTER
esp_err_t esp_ble_iso_big_ext_adv_add(esp_ble_iso_ext_adv_info_t *info)
{
int err;
if (info == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_le_ext_adv_new_safe(info->adv_handle);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_big_ext_adv_delete(esp_ble_iso_ext_adv_info_t *info)
{
int err;
if (info == NULL) {
return ESP_ERR_INVALID_ARG;
}
err = bt_le_ext_adv_delete_safe(info->adv_handle);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_big_create(uint8_t adv_handle,
esp_ble_iso_big_create_param_t *param,
esp_ble_iso_big_t **out_big)
{
esp_err_t ret = ESP_OK;
void *adv;
int err;
bt_le_host_lock();
adv = bt_le_ext_adv_find(adv_handle);
if (adv == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto unlock;
}
err = bt_iso_big_create(adv, param, out_big);
if (err) {
ret = ESP_FAIL;
}
unlock:
bt_le_host_unlock();
return ret;
}
#endif /* CONFIG_BT_ISO_BROADCASTER */
#if CONFIG_BT_ISO_SYNC_RECEIVER
esp_err_t esp_ble_iso_big_sync(uint16_t sync_handle,
esp_ble_iso_big_sync_param_t *param,
esp_ble_iso_big_t **out_big)
{
void *per_adv_sync;
int err;
per_adv_sync = bt_le_per_adv_sync_find_safe(sync_handle);
if (per_adv_sync == NULL) {
return ESP_ERR_NOT_FOUND;
}
err = bt_iso_big_sync_safe(per_adv_sync, param, out_big);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
esp_err_t esp_ble_iso_big_terminate(esp_ble_iso_big_t *big)
{
int err;
err = bt_iso_big_terminate_safe(big);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_ISO_BROADCAST */
esp_err_t esp_ble_iso_chan_get_info(esp_ble_iso_chan_t *chan,
esp_ble_iso_info_t *info)
{
int err;
err = bt_iso_chan_get_info_safe(chan, info);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#if CONFIG_BT_ISO_TX
esp_err_t esp_ble_iso_chan_get_tx_sync(esp_ble_iso_chan_t *chan,
esp_ble_iso_tx_info_t *info)
{
int err;
err = bt_iso_chan_get_tx_sync_safe(chan, info);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_chan_send(esp_ble_iso_chan_t *chan,
const uint8_t *sdu,
uint16_t sdu_len,
uint16_t seq_num)
{
struct net_buf buf = {
/* Note: only data and len are used */
.data = (void *)sdu,
.len = sdu_len,
};
int err;
if (chan == NULL || (!sdu ^ !sdu_len)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_iso_chan_send_safe(chan, &buf, seq_num);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_ble_iso_chan_send_ts(esp_ble_iso_chan_t *chan,
const uint8_t *sdu,
uint16_t sdu_len,
uint16_t seq_num,
uint32_t ts)
{
struct net_buf buf = {
/* Note: only data and len are used */
.data = (void *)sdu,
.len = sdu_len,
};
int err;
if (chan == NULL || (!sdu ^ !sdu_len)) {
return ESP_ERR_INVALID_ARG;
}
err = bt_iso_chan_send_ts_safe(chan, &buf, seq_num, ts);
if (err) {
return ESP_FAIL;
}
return ESP_OK;
}
#endif /* CONFIG_BT_ISO_TX */
void esp_ble_iso_gap_app_post_event(uint8_t type, void *param)
{
bt_le_gap_app_post_event(type, param);
}
esp_err_t esp_ble_iso_common_init(esp_ble_iso_init_info_t *info)
{
bool gap_cb_registered = false;
int err;
if (info) {
if (info->gap_cb) {
err = bt_le_gap_app_cb_register(info->gap_cb);
if (err) {
return ESP_FAIL;
}
gap_cb_registered = true;
}
}
err = bt_le_host_init();
if (err) {
goto unregister_gap;
}
return ESP_OK;
unregister_gap:
if (gap_cb_registered) {
bt_le_gap_app_cb_unregister();
}
return ESP_FAIL;
}
@@ -0,0 +1,594 @@
/*
* SPDX-FileCopyrightText: 2020 Intel Corporation
* SPDX-FileCopyrightText: 2021-2024 Nordic Semiconductor ASA
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_BLE_ISO_COMMON_API_H_
#define ESP_BLE_ISO_COMMON_API_H_
#include <stdint.h>
#include <string.h>
#include <stddef.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/iso.h>
#include <../host/conn_internal.h>
#include "common/host.h"
#include "common/app/gap.h"
#include "common/app/gatt.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Convert BIS index to bit
*
* The BIS indexes start from 0x01, so the lowest allowed bit is
* BIT(0) that represents index 0x01. To synchronize to e.g. BIS
* indexes 0x01 and 0x02, the bitfield value should be BIT(0) | BIT(1).
* As a general notation, to sync to BIS index N use BIT(N - 1).
*/
#define ESP_BLE_ISO_BIS_INDEX_BIT(x) BT_ISO_BIS_INDEX_BIT(x)
/*!< The minimum value for vendor specific data path ID */
#define ESP_BLE_ISO_DATA_PATH_VS_ID_MIN BT_ISO_DATA_PATH_VS_ID_MIN
/*!< The maximum value for vendor specific data path ID */
#define ESP_BLE_ISO_DATA_PATH_VS_ID_MAX BT_ISO_DATA_PATH_VS_ID_MAX
/*!< Minimum controller delay in microseconds */
#define ESP_BLE_ISO_CONTROLLER_DELAY_MIN BT_ISO_CONTROLLER_DELAY_MIN
/*!< Maximum controller delay in microseconds */
#define ESP_BLE_ISO_CONTROLLER_DELAY_MAX BT_ISO_CONTROLLER_DELAY_MAX
/*!< Unknown SDU interval */
#define ESP_BLE_ISO_SDU_INTERVAL_UNKNOWN BT_ISO_SDU_INTERVAL_UNKNOWN
/*!< Minimum interval value in microseconds */
#define ESP_BLE_ISO_SDU_INTERVAL_MIN BT_ISO_SDU_INTERVAL_MIN
/*!< Maximum interval value in microseconds */
#define ESP_BLE_ISO_SDU_INTERVAL_MAX BT_ISO_SDU_INTERVAL_MAX
/*!< Minimum ISO interval (N * 1.25 ms) */
#define ESP_BLE_ISO_ISO_INTERVAL_MIN BT_ISO_ISO_INTERVAL_MIN
/*!< Maximum ISO interval (N * 1.25 ms) */
#define ESP_BLE_ISO_ISO_INTERVAL_MAX BT_ISO_ISO_INTERVAL_MAX
/*!< Minimum latency value in milliseconds */
#define ESP_BLE_ISO_LATENCY_MIN BT_ISO_LATENCY_MIN
/*!< Maximum latency value in milliseconds */
#define ESP_BLE_ISO_LATENCY_MAX BT_ISO_LATENCY_MAX
/*!< Packets will be sent sequentially between the channels in the group */
#define ESP_BLE_ISO_PACKING_SEQUENTIAL BT_ISO_PACKING_SEQUENTIAL
/*!< Packets will be sent interleaved between the channels in the group */
#define ESP_BLE_ISO_PACKING_INTERLEAVED BT_ISO_PACKING_INTERLEAVED
/*!< Packets may be framed or unframed */
#define ESP_BLE_ISO_FRAMING_UNFRAMED BT_ISO_FRAMING_UNFRAMED
/*!< Packets are always framed */
#define ESP_BLE_ISO_FRAMING_FRAMED BT_ISO_FRAMING_FRAMED
/*!< Maximum number of isochronous channels in a single group */
#define ESP_BLE_ISO_MAX_GROUP_ISO_COUNT BT_ISO_MAX_GROUP_ISO_COUNT
/*!< Minimum SDU size */
#define ESP_BLE_ISO_MIN_SDU BT_ISO_MIN_SDU
/*!< Maximum SDU size */
#define ESP_BLE_ISO_MAX_SDU BT_ISO_MAX_SDU
/*!< Minimum PDU size */
#define ESP_BLE_ISO_CONNECTED_PDU_MIN BT_ISO_CONNECTED_PDU_MIN
/*!< Minimum PDU size */
#define ESP_BLE_ISO_BROADCAST_PDU_MIN BT_ISO_BROADCAST_PDU_MIN
/*!< Maximum PDU size */
#define ESP_BLE_ISO_PDU_MAX BT_ISO_PDU_MAX
/*!< Minimum burst number */
#define ESP_BLE_ISO_BN_MIN BT_ISO_BN_MIN
/*!< Maximum burst number */
#define ESP_BLE_ISO_BN_MAX BT_ISO_BN_MAX
/*!< Minimum flush timeout */
#define ESP_BLE_ISO_FT_MIN BT_ISO_FT_MIN
/*!< Maximum flush timeout */
#define ESP_BLE_ISO_FT_MAX BT_ISO_FT_MAX
/*!< Minimum number of subevents */
#define ESP_BLE_ISO_NSE_MIN BT_ISO_NSE_MIN
/*!< Maximum number of subevents */
#define ESP_BLE_ISO_NSE_MAX BT_ISO_NSE_MAX
/*!< Minimum BIG sync timeout value (N * 10 ms) */
#define ESP_BLE_ISO_SYNC_TIMEOUT_MIN BT_ISO_SYNC_TIMEOUT_MIN
/*!< Maximum BIG sync timeout value (N * 10 ms) */
#define ESP_BLE_ISO_SYNC_TIMEOUT_MAX BT_ISO_SYNC_TIMEOUT_MAX
/*!< Controller controlled maximum subevent count value */
#define ESP_BLE_ISO_SYNC_MSE_ANY BT_ISO_SYNC_MSE_ANY
/*!< Minimum BIG sync maximum subevent count value */
#define ESP_BLE_ISO_SYNC_MSE_MIN BT_ISO_SYNC_MSE_MIN
/*!< Maximum BIG sync maximum subevent count value */
#define ESP_BLE_ISO_SYNC_MSE_MAX BT_ISO_SYNC_MSE_MAX
/*!< Minimum connected ISO retransmission value */
#define ESP_BLE_ISO_CONNECTED_RTN_MIN BT_ISO_CONNECTED_RTN_MIN
/*!< Maximum connected ISO retransmission value */
#define ESP_BLE_ISO_CONNECTED_RTN_MAX BT_ISO_CONNECTED_RTN_MAX
/*!< Minimum broadcast ISO retransmission value */
#define ESP_BLE_ISO_BROADCAST_RTN_MIN BT_ISO_BROADCAST_RTN_MIN
/*!< Maximum broadcast ISO retransmission value */
#define ESP_BLE_ISO_BROADCAST_RTN_MAX BT_ISO_BROADCAST_RTN_MAX
/*!< Broadcast code size */
#define ESP_BLE_ISO_BROADCAST_CODE_SIZE BT_ISO_BROADCAST_CODE_SIZE
/*!< Lowest BIS index */
#define ESP_BLE_ISO_BIS_INDEX_MIN BT_ISO_BIS_INDEX_MIN
/*!< Highest BIS index */
#define ESP_BLE_ISO_BIS_INDEX_MAX BT_ISO_BIS_INDEX_MAX
/*!< Minimum Immediate Repetition Count */
#define ESP_BLE_ISO_IRC_MIN BT_ISO_IRC_MIN
/*!< Maximum Immediate Repetition Count */
#define ESP_BLE_ISO_IRC_MAX BT_ISO_IRC_MAX
/*!< Minimum pre-transmission offset */
#define ESP_BLE_ISO_PTO_MIN BT_ISO_PTO_MIN
/*!< Maximum pre-transmission offset */
#define ESP_BLE_ISO_PTO_MAX BT_ISO_PTO_MAX
/*!< No subinterval */
#define ESP_BLE_ISO_SUBINTERVAL_NONE BT_ISO_SUBINTERVAL_NONE
/*!< Unknown subinterval */
#define ESP_BLE_ISO_SUBINTERVAL_UNKNOWN BT_ISO_SUBINTERVAL_UNKNOWN
/*!< Minimum subinterval in microseconds */
#define ESP_BLE_ISO_SUBINTERVAL_MIN BT_ISO_SUBINTERVAL_MIN
/*!< Maximum subinterval in microseconds */
#define ESP_BLE_ISO_SUBINTERVAL_MAX BT_ISO_SUBINTERVAL_MAX
/*!< Audio Input (Host to Controller) Data Path Direction */
#define ESP_BLE_ISO_DATA_PATH_DIR_INPUT BT_HCI_DATAPATH_DIR_HOST_TO_CTLR
/*!< Audio Output (Controller to Host) Data Path Direction */
#define ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT BT_HCI_DATAPATH_DIR_CTLR_TO_HOST
/*!< Value to set the ISO data path over HCI */
#define ESP_BLE_ISO_DATA_PATH_HCI BT_ISO_DATA_PATH_HCI
/*!< Transparent Coding Format */
#define ESP_BLE_ISO_CODING_FORMAT_TRANSPARENT BT_HCI_CODING_FORMAT_TRANSPARENT
/*!< LC3 Coding Format */
#define ESP_BLE_ISO_CODING_FORMAT_LC3 BT_HCI_CODING_FORMAT_LC3
/*!< The ISO packet is valid */
#define ESP_BLE_ISO_FLAGS_VALID BT_ISO_FLAGS_VALID
/*!< The ISO packet may possibly contain errors */
#define ESP_BLE_ISO_FLAGS_ERROR BT_ISO_FLAGS_ERROR
/*!< The ISO packet was lost */
#define ESP_BLE_ISO_FLAGS_LOST BT_ISO_FLAGS_LOST
/*!< Timestamp is valid */
#define ESP_BLE_ISO_FLAGS_TS BT_ISO_FLAGS_TS
/*!< LE 1M PHY */
#define ESP_BLE_ISO_PHY_1M BT_GAP_LE_PHY_1M
/*!< LE 2M PHY */
#define ESP_BLE_ISO_PHY_2M BT_GAP_LE_PHY_2M
/*!< LE Coded PHY, coding scheme not specified */
#define ESP_BLE_ISO_PHY_CODED BT_GAP_LE_PHY_CODED
/*!< Unknown */
#define ESP_BLE_ISO_SCA_UNKNOWN BT_GAP_SCA_UNKNOWN
/*!< 251 ppm to 500 ppm */
#define ESP_BLE_ISO_SCA_251_500 BT_GAP_SCA_251_500
/*!< 151 ppm to 250 ppm */
#define ESP_BLE_ISO_SCA_151_250 BT_GAP_SCA_151_250
/*!< 101 ppm to 150 ppm */
#define ESP_BLE_ISO_SCA_101_150 BT_GAP_SCA_101_150
/*!< 76 ppm to 100 ppm */
#define ESP_BLE_ISO_SCA_76_100 BT_GAP_SCA_76_100
/*!< 51 ppm to 75 ppm */
#define ESP_BLE_ISO_SCA_51_75 BT_GAP_SCA_51_75
/*!< 31 ppm to 50 ppm */
#define ESP_BLE_ISO_SCA_31_50 BT_GAP_SCA_31_50
/*!< 21 ppm to 30 ppm */
#define ESP_BLE_ISO_SCA_21_30 BT_GAP_SCA_21_30
/*!< 0 ppm to 20 ppm */
#define ESP_BLE_ISO_SCA_0_20 BT_GAP_SCA_0_20
/*!< Security Level 1: No encryption and no authentication */
#define ESP_BLE_ISO_SECURITY_NONE BT_SECURITY_L1
/*!< Security Level 2: Encryption and no authentication (no MITM) */
#define ESP_BLE_ISO_SECURITY_NO_MITM BT_SECURITY_L2
/*!< Security Level 3: Encryption and authentication (MITM) */
#define ESP_BLE_ISO_SECURITY_MITM BT_SECURITY_L3
/** Connection structure. */
typedef struct bt_conn esp_ble_conn_t;
/** ISO Channel structure. */
typedef struct bt_iso_chan esp_ble_iso_chan_t;
/** ISO Channel operations structure. */
typedef struct bt_iso_chan_ops esp_ble_iso_chan_ops_t;
/** ISO Channel QoS structure. */
typedef struct bt_iso_chan_qos esp_ble_iso_chan_qos_t;
/** ISO Channel IO QoS structure. */
typedef struct bt_iso_chan_io_qos esp_ble_iso_chan_io_qos_t;
/** ISO Channel Data Path structure. */
typedef struct bt_iso_chan_path esp_ble_iso_chan_path_t;
/** Connected Isochronous Group (CIG). */
typedef struct bt_iso_cig esp_ble_iso_cig_t;
/** Connected Isochronous Group (CIG) parameters. */
typedef struct bt_iso_cig_param esp_ble_iso_cig_param_t;
/** ISO connection parameters structure. */
typedef struct bt_iso_connect_param esp_ble_iso_connect_param_t;
/** ISO Accept Info Structure. */
typedef struct bt_iso_accept_info esp_ble_iso_accept_info_t;
/** ISO Server structure. */
typedef struct bt_iso_server esp_ble_iso_server_t;
/** ISO Unicast Info Structure. */
typedef struct bt_iso_unicast_info esp_ble_iso_unicast_info_t;
/** ISO Unicast TX Info Structure. */
typedef struct bt_iso_unicast_tx_info esp_ble_iso_unicast_tx_info_t;
/** ISO Broadcast callbacks */
typedef struct bt_iso_big_cb esp_ble_iso_big_cb_t;
/** Broadcast Isochronous Group (BIG). */
typedef struct bt_iso_big esp_ble_iso_big_t;
/** Broadcast Isochronous Group (BIG) creation parameters. */
typedef struct bt_iso_big_create_param esp_ble_iso_big_create_param_t;
/** Broadcast Isochronous Group (BIG) Sync Parameters. */
typedef struct bt_iso_big_sync_param esp_ble_iso_big_sync_param_t;
/** Broadcast Isochronous Group (BIG) information. */
typedef struct bt_iso_biginfo esp_ble_iso_biginfo_t;
/** ISO Broadcaster Info Structure. */
typedef struct bt_iso_broadcaster_info esp_ble_iso_broadcaster_info_t;
/** ISO Synchronized Receiver Info Structure. */
typedef struct bt_iso_sync_receiver_info esp_ble_iso_sync_receiver_info_t;
/** ISO channel Info Structure. */
typedef struct bt_iso_info esp_ble_iso_info_t;
/** ISO Meta Data structure for received ISO packets. */
typedef struct bt_iso_recv_info esp_ble_iso_recv_info_t;
/** ISO Meta Data structure for transmitted ISO packets. */
typedef struct bt_iso_tx_info esp_ble_iso_tx_info_t;
/** ISO Unicast & Broadcast TX Callback Info Structure. */
typedef struct bt_iso_tx_cb_info esp_ble_iso_tx_cb_info_t;
/** Extended advertising information structure */
typedef struct {
uint8_t adv_handle; /*!< Handle for the advertising set */
} esp_ble_iso_ext_adv_info_t;
/**
* @brief Helper for parsing length-type-value data.
*
* @param ltv Length-type-value (LTV) encoded data.
* @param size Size of the @p ltv data.
* @param func Callback function which will be called for each element
* that's found in the data. The callback should return
* true to continue parsing, or false to stop parsing.
* @param user_data User data to be passed to the callback.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_data_parse(const uint8_t ltv[], size_t size,
bool (*func)(uint8_t type,
const uint8_t *data,
uint8_t data_len,
void *user_data),
void *user_data);
/**
* @brief Register an ISO server.
*
* @param server Pointer to the ISO server structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_server_register(esp_ble_iso_server_t *server);
/**
* @brief Unregister an ISO server.
*
* @param server Pointer to the ISO server structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_server_unregister(esp_ble_iso_server_t *server);
/**
* @brief Create a Connected ISO Group (CIG).
*
* @param param Parameters for CIG creation.
* @param out_cig Pointer to store created CIG.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_cig_create(esp_ble_iso_cig_param_t *param,
esp_ble_iso_cig_t **out_cig);
/**
* @brief Reconfigure a Connected ISO Group.
*
* @param cig Pointer to the CIG to reconfigure.
* @param param New parameters for the CIG.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_cig_reconfigure(esp_ble_iso_cig_t *cig,
esp_ble_iso_cig_param_t *param);
/**
* @brief Terminate a Connected ISO Group.
*
* @param cig Pointer to the CIG to terminate.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_cig_terminate(esp_ble_iso_cig_t *cig);
/**
* @brief Connect ISO channels.
*
* @param param Connection parameters.
* @param conn_handle Connection handle.
* @param count Number of channels to connect.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_chan_connect(esp_ble_iso_connect_param_t *param,
uint16_t conn_handle, size_t count);
/**
* @brief Disconnect an ISO channel.
*
* @param chan Pointer to the ISO channel.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_chan_disconnect(esp_ble_iso_chan_t *chan);
/**
* @brief Set up the ISO data path for an ISO channel.
*
* The channel must be associated with a BIS or CIS handle first which it is when the
* esp_ble_iso_chan_ops_t.connected() callback is called.
*
* @param chan The channel to setup the ISO data path for.
* @param dir The direction to setup, either ESP_BLE_ISO_DATA_PATH_DIR_INPUT
* or ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT.
* For ISO broadcast channels this can only be
* ESP_BLE_ISO_DATA_PATH_DIR_INPUT, and for ISO sync receiver
* channels this can only be ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT.
* @param path The data path.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_setup_data_path(const esp_ble_iso_chan_t *chan, uint8_t dir,
const esp_ble_iso_chan_path_t *path);
/**
* @brief Removes the ISO data path for an ISO channel.
*
* Removes the ISO data path configured by esp_ble_iso_setup_data_path() for the provided
* @p dir.
*
* The data paths of CIS for Peripherals are deleted by the controller, and thus it is not
* necessary (or possible) to remove data paths of CIS after they have disconnected for a
* Peripheral, as per Bluetooth Core specification 6.0, Vol 4, Part E, Section 7.7.5.
* The data paths for CIS for a Central remain valid, even after a disconnection, and thus
* a Central device should call bt_iso_remove_data_path() on disconnect if it no longer
* wants to use that CIS.
* All data paths created by a Central are removed when the CIG is removed with
* esp_ble_iso_cig_terminate().
*
* Any data paths associated with an ISO Sync Receiver BIG are removed by the controller
* when the BIG sync is lost or terminated, and thus it is not necessary (or possible) to
* remove data paths of ISO channels associated with a BIG for a Sync Receiver, as per
* Bluetooth Core specification 6.0, Vol 4, Part E, Section 7.7.65.30.
*
* All data paths associated with an ISO Broadcaster BIG are removed when the BIG is
* terminated by esp_ble_iso_big_terminate(), and thus it is not necessary (or possible)
* to remove data paths of ISO channels associated with a BIG for a Broadcaster,
* as per Bluetooth Core specification 6.0, Vol 4, Part E, Section 7.8.105.
*
* @param chan The channel to setup the ISO data path for.
* @param dir The direction to setup, either ESP_BLE_ISO_DATA_PATH_DIR_INPUT or
* ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT. For ISO broadcast channels this
* can only be ESP_BLE_ISO_DATA_PATH_DIR_INPUT, and for ISO sync
* receiver channels this can only be ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT.
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_remove_data_path(const esp_ble_iso_chan_t *chan, uint8_t dir);
/**
* @brief Registers callbacks for Broadcast Sources.
*
* @param cb Pointer to the callback structure.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_big_register_cb(esp_ble_iso_big_cb_t *cb);
/**
* @brief Add extended advertising for BIG.
*
* @param info Extended advertising information.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_big_ext_adv_add(esp_ble_iso_ext_adv_info_t *info);
/**
* @brief Delete extended advertising for BIG.
*
* @param info Extended advertising information.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_big_ext_adv_delete(esp_ble_iso_ext_adv_info_t *info);
/**
* @brief Create a Broadcast ISO Group (BIG).
*
* @param adv_handle Advertising handle.
* @param param Parameters for BIG creation.
* @param out_big Pointer to store created BIG.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_big_create(uint8_t adv_handle,
esp_ble_iso_big_create_param_t *param,
esp_ble_iso_big_t **out_big);
/**
* @brief Synchronize with a Broadcast ISO Group.
*
* @param sync_handle Sync handle.
* @param param Sync parameters.
* @param out_big Pointer to store synchronized BIG.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_big_sync(uint16_t sync_handle,
esp_ble_iso_big_sync_param_t *param,
esp_ble_iso_big_t **out_big);
/**
* @brief Terminate a Broadcast ISO Group.
*
* @param big Pointer to the BIG to terminate.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_big_terminate(esp_ble_iso_big_t *big);
/**
* @brief Get ISO channel information.
*
* @param chan Pointer to the ISO channel.
* @param info Pointer to store channel information.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_chan_get_info(esp_ble_iso_chan_t *chan,
esp_ble_iso_info_t *info);
/**
* @brief Get TX sync information for an ISO channel.
*
* @param chan Pointer to the ISO channel.
* @param info Pointer to store TX sync information.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_chan_get_tx_sync(esp_ble_iso_chan_t *chan,
esp_ble_iso_tx_info_t *info);
/**
* @brief Send data over an ISO channel.
*
* @param chan Pointer to the ISO channel.
* @param sdu Pointer to the SDU data.
* @param sdu_len Length of the SDU.
* @param seq_num Sequence number.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_chan_send(esp_ble_iso_chan_t *chan,
const uint8_t *sdu,
uint16_t sdu_len,
uint16_t seq_num);
/**
* @brief Send timestamped data over an ISO channel.
*
* @param chan Pointer to the ISO channel.
* @param sdu Pointer to the SDU data.
* @param sdu_len Length of the SDU.
* @param seq_num Sequence number.
* @param ts Timestamp.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_chan_send_ts(esp_ble_iso_chan_t *chan,
const uint8_t *sdu,
uint16_t sdu_len,
uint16_t seq_num,
uint32_t ts);
/*!< ISO GAP Extended Scan Recv event */
#define ESP_BLE_ISO_GAP_EVENT_EXT_SCAN_RECV BT_LE_GAP_APP_EVENT_EXT_SCAN_RECV
/*!< ISO GAP Periodic Sync Established event */
#define ESP_BLE_ISO_GAP_EVENT_PA_SYNC BT_LE_GAP_APP_EVENT_PA_SYNC
/*!< ISO GAP Periodic Sync Lost event */
#define ESP_BLE_ISO_GAP_EVENT_PA_SYNC_LOST BT_LE_GAP_APP_EVENT_PA_SYNC_LOST
/*!< ISO GAP Connection Complete event */
#define ESP_BLE_ISO_GAP_EVENT_ACL_CONNECT BT_LE_GAP_APP_EVENT_ACL_CONNECT
/*!< ISO GAP Disconnection Complete event */
#define ESP_BLE_ISO_GAP_EVENT_ACL_DISCONNECT BT_LE_GAP_APP_EVENT_ACL_DISCONNECT
/*!< ISO GAP Security Changed event */
#define ESP_BLE_ISO_GAP_EVENT_SECURITY_CHANGE BT_LE_GAP_APP_EVENT_SECURITY_CHANGE
/*!< ISO GAP BIGInfo Adv Report event */
#define ESP_BLE_ISO_GAP_EVENT_BIGINFO_RECV BT_LE_GAP_APP_EVENT_BIGINFO_RECV
/** ISO GAP application event structure */
typedef struct bt_le_gap_app_event esp_ble_iso_gap_app_event_t;
/** ISO initialization information structure */
typedef struct {
bt_le_gap_app_cb gap_cb; /*!< GAP event callbacks */
} esp_ble_iso_init_info_t;
/**
* @brief Post an application-layer GAP event for ISO internal usage.
*
* @note This function is only needed while using NimBLE Host.
*
* @param type Event type.
* @param param Event parameters.
*/
void esp_ble_iso_gap_app_post_event(uint8_t type, void *param);
/**
* @brief Initialize ISO common functionality.
*
* @param info Initialization information.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t esp_ble_iso_common_init(esp_ble_iso_init_info_t *info);
#ifdef __cplusplus
}
#endif
#endif /* ESP_BLE_ISO_COMMON_API_H_ */