diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-03-28 14:32:49 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-03-28 14:32:49 +1100 |
| commit | ee29c25b29eaa4fac4e897442634b69ecc8d8125 (patch) | |
| tree | 8c5f1a140463f20f104316fa3492984e191154e9 /lib/bt/host/bluedroid/api | |
| parent | 239e6d89507a24c849385f4bfa93ac4ad58e5de5 (diff) | |
| download | tangara-fw-ee29c25b29eaa4fac4e897442634b69ecc8d8125.tar.gz | |
Fork ESP-IDF's bluetooth component
i want better sbc encoding, and no cla will stop me
Diffstat (limited to 'lib/bt/host/bluedroid/api')
37 files changed, 17452 insertions, 0 deletions
diff --git a/lib/bt/host/bluedroid/api/esp_a2dp_api.c b/lib/bt/host/bluedroid/api/esp_a2dp_api.c new file mode 100644 index 00000000..be8adcf2 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_a2dp_api.c @@ -0,0 +1,353 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common/bt_target.h" +#include <string.h> +#include "esp_err.h" +#include "esp_a2dp_api.h" +#include "esp_bt_main.h" +#include "btc/btc_manage.h" +#include "btc_av.h" + +#if BTC_AV_INCLUDED + +#if BTC_AV_SINK_INCLUDED +esp_err_t esp_a2d_sink_init(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_init || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_INIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_sink_deinit(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_DEINIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_REG_DATA_CB_EVT; + + btc_av_args_t arg; + memset(&arg, 0, sizeof(btc_av_args_t)); + arg.data_cb = callback; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_av_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_CONNECT_EVT; + + memset(&arg, 0, sizeof(btc_av_args_t)); + + /* Switch to BTC context */ + memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_av_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_DISCONNECT_EVT; + + /* Switch to BTC context */ + memcpy(&(arg.disconn), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_av_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_SET_DELAY_VALUE_EVT; + + memset(&arg, 0, sizeof(btc_av_args_t)); + arg.delay_value = delay_value; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_sink_get_delay_value(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_GET_DELAY_VALUE_EVT; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} +#endif /* BTC_AV_SINK_INCLUDED */ + +esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_sink_ongoing_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_A2DP, callback); + return ESP_OK; +} + +esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + if (ctrl == ESP_A2D_MEDIA_CTRL_STOP) { + LOG_WARN("ESP_A2D_MEDIA_CTRL_STOP is deprecated, using ESP_A2D_MEDIA_CTRL_SUSPEND instead.\n"); + ctrl = ESP_A2D_MEDIA_CTRL_SUSPEND; + } + + bt_status_t stat; + btc_av_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_API_MEDIA_CTRL_EVT; + + memset(&arg, 0, sizeof(btc_av_args_t)); + + /* Switch to BTC context */ + arg.ctrl = ctrl; + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +#if BTC_AV_SRC_INCLUDED +esp_err_t esp_a2d_source_init(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_init || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SRC_API_INIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_source_deinit(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SRC_API_DEINIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_av_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SRC_API_CONNECT_EVT; + + memset(&arg, 0, sizeof(btc_av_args_t)); + + /* Switch to BTC context */ + memcpy(&(arg.src_connect), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_av_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SRC_API_DISCONNECT_EVT; + + memset(&arg, 0, sizeof(btc_av_args_t)); + + /* Switch to BTC context */ + memcpy(&(arg.src_disconn), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SRC_API_REG_DATA_CB_EVT; + + btc_av_args_t arg; + memset(&arg, 0, sizeof(btc_av_args_t)); + arg.src_data_cb = callback; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +#endif /* BTC_AV_SRC_INCLUDED */ + +#endif /* #if BTC_AV_INCLUDED */ diff --git a/lib/bt/host/bluedroid/api/esp_avrc_api.c b/lib/bt/host/bluedroid/api/esp_avrc_api.c new file mode 100644 index 00000000..2d3e1532 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_avrc_api.c @@ -0,0 +1,477 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common/bt_target.h" +#include <string.h> +#include "esp_err.h" +#include "esp_avrc_api.h" +#include "esp_bt_main.h" +#include "btc/btc_manage.h" +#include "btc_avrc.h" + +#if BTC_AV_INCLUDED + +esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (callback == NULL) { + return ESP_ERR_INVALID_ARG; + } + + btc_profile_cb_set(BTC_PID_AVRC_CT, callback); + return ESP_OK; +} + +esp_err_t esp_avrc_ct_init(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_CT_API_INIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_ct_deinit(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_CT_API_DEINIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (tl > ESP_AVRC_TRANS_LABEL_MAX || attr_id > ESP_AVRC_PS_MAX_ATTR - 1) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_CTRL_API_SND_SET_PLAYER_SETTING_EVT; + + btc_avrc_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_args_t)); + + arg.ps_cmd.tl = tl; + arg.ps_cmd.attr_id = attr_id; + arg.ps_cmd.value_id = value_id; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_ct_send_get_rn_capabilities_cmd(uint8_t tl) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (tl > ESP_AVRC_TRANS_LABEL_MAX) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT; + + btc_avrc_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_args_t)); + + arg.get_caps_cmd.tl = tl; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (tl > ESP_AVRC_TRANS_LABEL_MAX || event_id > ESP_AVRC_RN_MAX_EVT - 1) { + return ESP_ERR_INVALID_ARG; + } + + if (!btc_avrc_ct_rn_evt_supported(event_id)) { + return ESP_ERR_NOT_SUPPORTED; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT; + + btc_avrc_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_args_t)); + + arg.rn_cmd.tl = tl; + arg.rn_cmd.event_id = event_id; + arg.rn_cmd.event_parameter = event_parameter; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_ct_send_set_absolute_volume_cmd(uint8_t tl, uint8_t volume) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (tl > ESP_AVRC_TRANS_LABEL_MAX) { + return ESP_ERR_INVALID_ARG; + } + + if (volume > BTC_AVRC_MAX_VOLUME) { + return ESP_ERR_INVALID_ARG; + } + + if (!btc_avrc_ct_rn_evt_supported(ESP_AVRC_RN_VOLUME_CHANGE)) { + return ESP_ERR_NOT_SUPPORTED; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_CTRL_API_SND_SET_ABSOLUTE_VOLUME_EVT; + + btc_avrc_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_args_t)); + + arg.set_abs_vol_cmd.tl = tl; + arg.set_abs_vol_cmd.volume = volume; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (tl > ESP_AVRC_TRANS_LABEL_MAX) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_STATUS_API_SND_META_EVT; + + btc_avrc_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_args_t)); + + arg.md_cmd.tl = tl; + arg.md_cmd.attr_mask = attr_mask; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (tl > ESP_AVRC_TRANS_LABEL_MAX || key_state > ESP_AVRC_PT_CMD_STATE_RELEASED) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_CT; + msg.act = BTC_AVRC_CTRL_API_SND_PTCMD_EVT; + + btc_avrc_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_args_t)); + + arg.pt_cmd.tl = tl; + arg.pt_cmd.key_code = key_code; + arg.pt_cmd.key_state = key_state; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +/*********************************************************************************************/ +/** following is the API of AVRCP target role **/ +/*********************************************************************************************/ + +esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (callback == NULL) { + return ESP_ERR_INVALID_ARG; + } + + btc_profile_cb_set(BTC_PID_AVRC_TG, callback); + return ESP_OK; +} + +esp_err_t esp_avrc_tg_init(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_TG; + msg.act = BTC_AVRC_TG_API_INIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_avrc_tg_deinit(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_TG; + msg.act = BTC_AVRC_TG_API_DEINIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_bit_mask_t *psth, + esp_avrc_pt_cmd_t cmd) +{ + if (!psth || + cmd > ESP_AVRC_PT_CMD_VENDOR) { + return false; + } + + uint16_t *p = &psth->bits[(uint8_t)cmd >> 4]; + uint16_t mask = (uint16_t)1 << ((uint8_t)cmd & 0x0F); + switch (op) { + case ESP_AVRC_BIT_MASK_OP_SET: + *p |= mask; + break; + case ESP_AVRC_BIT_MASK_OP_CLEAR: + *p &= ~mask; + break; + case ESP_AVRC_BIT_MASK_OP_TEST: + return (*p & mask); + default: + return false; + } + + return true; +} + +esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avrc_psth_bit_mask_t *cmd_set) +{ + if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) || + (! btc_avrc_tg_init_p())) { + return ESP_ERR_INVALID_STATE; + } + if (filter >= ESP_AVRC_PSTH_FILTER_SUPPORT_MAX || + cmd_set == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (filter == ESP_AVRC_PSTH_FILTER_ALLOWED_CMD) { + const uint16_t *allowed_cmd_set = btc_avrc_tg_get_allowed_command(); + memcpy(cmd_set, allowed_cmd_set, sizeof(esp_avrc_psth_bit_mask_t)); + } else if (filter == ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD) { + const uint16_t *supported_cmd_set = btc_avrc_tg_get_supported_command(); + memcpy(cmd_set, supported_cmd_set, sizeof(esp_avrc_psth_bit_mask_t)); + } else { + } + + return ESP_OK; +} + +esp_err_t esp_avrc_tg_set_psth_cmd_filter(esp_avrc_psth_filter_t filter, const esp_avrc_psth_bit_mask_t *cmd_set) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (filter >= ESP_AVRC_PSTH_FILTER_SUPPORT_MAX || + cmd_set == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (filter == ESP_AVRC_PSTH_FILTER_ALLOWED_CMD) { + return ESP_ERR_NOT_SUPPORTED; + } + if (filter == ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD) { + bool allowed = btc_avrc_tg_check_supported_command(cmd_set->bits); + if (!allowed) { + return ESP_ERR_NOT_SUPPORTED; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_TG; + msg.act = BTC_AVRC_TG_API_SET_PSTH_SUPPORTED_CMD_EVT; + + btc_avrc_tg_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_tg_args_t)); + arg.set_psth_cmd = (uint16_t *)cmd_set->bits; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t), + btc_avrc_tg_arg_deep_copy, btc_avrc_tg_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; + } else { + return ESP_FAIL; + } +} + +esp_err_t esp_avrc_tg_get_rn_evt_cap(esp_avrc_rn_evt_cap_t cap, esp_avrc_rn_evt_cap_mask_t *evt_set) +{ + if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) || + (! btc_avrc_tg_init_p())) { + return ESP_ERR_INVALID_STATE; + } + if (cap >= ESP_AVRC_RN_CAP_MAX || + evt_set == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (cap == ESP_AVRC_RN_CAP_ALLOWED_EVT) { + evt_set->bits = btc_avrc_tg_get_rn_allowed_evt(); + } else if (cap == ESP_AVRC_RN_CAP_SUPPORTED_EVT) { + evt_set->bits = btc_avrc_tg_get_rn_supported_evt(); + } else { + } + + return ESP_OK; +} + +esp_err_t esp_avrc_tg_set_rn_evt_cap(const esp_avrc_rn_evt_cap_mask_t *evt_set) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (evt_set == NULL) { + return ESP_ERR_INVALID_ARG; + } + + bool allowed = btc_avrc_tg_check_rn_supported_evt(evt_set->bits); + if (!allowed) { + return ESP_ERR_NOT_SUPPORTED; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_TG; + msg.act = BTC_AVRC_TG_API_SET_RN_SUPPORTED_EVT; + + btc_avrc_tg_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_tg_args_t)); + + arg.set_rn_evt = evt_set->bits; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_evt_cap_mask_t *events, + esp_avrc_rn_event_ids_t event_id) +{ + if (!events || + event_id >= ESP_AVRC_RN_MAX_EVT) { + return false; + } + + uint16_t *p = &events->bits; + uint16_t mask = (uint16_t)1 << ((uint8_t)event_id & 0x0F); + switch (op) { + case ESP_AVRC_BIT_MASK_OP_SET: + *p |= mask; + break; + case ESP_AVRC_BIT_MASK_OP_CLEAR: + *p &= ~mask; + break; + case ESP_AVRC_BIT_MASK_OP_TEST: + return (*p & mask); + default: + return false; + } + + return true; +} + +esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp, + esp_avrc_rn_param_t *param) +{ + if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) || + (! btc_avrc_tg_connected_p())) { + return ESP_ERR_INVALID_STATE; + } + + if ( ! btc_avrc_tg_rn_evt_supported((uint8_t)event_id)) { + return ESP_ERR_NOT_SUPPORTED; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_AVRC_TG; + msg.act = BTC_AVRC_TG_API_SEND_RN_RSP_EVT; + + btc_avrc_tg_args_t arg; + memset(&arg, 0, sizeof(btc_avrc_tg_args_t)); + + arg.rn_rsp.event_id = event_id; + arg.rn_rsp.rsp = rsp; + memcpy(&arg.rn_rsp.param, param, sizeof(esp_avrc_rn_param_t)); + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; + +} + +#endif /* #if BTC_AV_INCLUDED */ diff --git a/lib/bt/host/bluedroid/api/esp_bluedroid_hci.c b/lib/bt/host/bluedroid/api/esp_bluedroid_hci.c new file mode 100644 index 00000000..892f6790 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_bluedroid_hci.c @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> +#include "esp_log.h" +#include "esp_bluedroid_hci.h" +#include "common/bt_target.h" +#include "hci/hci_trans_int.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) +#include "esp_bt.h" +#endif + +#define LOG_TAG "HCI_API" + +static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 }; + +esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops) +{ + if (!p_ops) { + ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__); + return ESP_FAIL; + } + + s_hci_driver_ops.send = p_ops->send; + s_hci_driver_ops.check_send_available = p_ops->check_send_available; + s_hci_driver_ops.register_host_callback = p_ops->register_host_callback; + + return ESP_OK; +} + +esp_err_t esp_bluedroid_detach_hci_driver(void) +{ + s_hci_driver_ops.send = NULL; + s_hci_driver_ops.check_send_available = NULL; + s_hci_driver_ops.register_host_callback = NULL; + + return ESP_OK; +} + +/**************************************************************** + * INTERNAL USE * + ****************************************************************/ + +bool hci_host_check_send_available(void) +{ + bool can_send = false; +#if (BT_CONTROLLER_INCLUDED == TRUE) + can_send = esp_vhci_host_check_send_available(); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.check_send_available) { + can_send = s_hci_driver_ops.check_send_available(); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ + return can_send; +} + +void hci_host_send_packet(uint8_t *data, uint16_t len) +{ +#if (BT_CONTROLLER_INCLUDED == TRUE) + esp_vhci_host_send_packet(data, len); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.send) { + s_hci_driver_ops.send(data, len); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ +} + +esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t *callback) +{ + esp_err_t ret = ESP_FAIL; + + if (!callback) { + ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__); + return ESP_FAIL; + } + +#if (BT_CONTROLLER_INCLUDED == TRUE) + ret = esp_vhci_host_register_callback((esp_vhci_host_callback_t *)callback); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.register_host_callback) { + ret = s_hci_driver_ops.register_host_callback(callback); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ + + return ret; +} diff --git a/lib/bt/host/bluedroid/api/esp_bt_device.c b/lib/bt/host/bluedroid/api/esp_bt_device.c new file mode 100644 index 00000000..c37b9adb --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_bt_device.c @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <stdlib.h> +#include <string.h> +#include "esp_bt_device.h" +#include "esp_bt_main.h" +#include "device/controller.h" +#include "btc/btc_task.h" +#include "btc/btc_dev.h" +#include "btc/btc_config.h" + +const uint8_t *esp_bt_dev_get_address(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return NULL; + } + return controller_get_interface()->get_address()->address; +} + +esp_err_t esp_bt_dev_set_device_name(const char *name) +{ + btc_msg_t msg = {0}; + btc_dev_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (!name){ + return ESP_ERR_INVALID_ARG; + } + if (strlen(name) > BTC_MAX_LOC_BD_NAME_LEN) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_DEV; + msg.act = BTC_DEV_ACT_SET_DEVICE_NAME; + arg.set_dev_name.device_name = (char *)osi_malloc((BTC_MAX_LOC_BD_NAME_LEN + 1) * sizeof(char)); + if (!arg.set_dev_name.device_name) { + return ESP_ERR_NO_MEM; + } + + strcpy(arg.set_dev_name.device_name, name); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_dev_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#if (ESP_COEX_VSC_INCLUDED == TRUE) +esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_coex_op_t op, uint8_t status) +{ + btc_msg_t msg = {0}; + btc_dev_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_DEV; + msg.act = BTC_DEV_ACT_CFG_COEX_STATUS; + arg.cfg_coex_status.type = type; + arg.cfg_coex_status.op = op; + arg.cfg_coex_status.status = status; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_dev_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif + +esp_err_t esp_bt_config_file_path_update(const char *file_path) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_UNINITIALIZED); + + return btc_config_file_path_update(file_path); +} diff --git a/lib/bt/host/bluedroid/api/esp_bt_main.c b/lib/bt/host/bluedroid/api/esp_bt_main.c new file mode 100644 index 00000000..497ba769 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_bt_main.c @@ -0,0 +1,230 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include "common/bt_target.h" +#include "esp_bt_main.h" +#include "btc/btc_task.h" +#include "btc/btc_main.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) +#include "esp_bt.h" +#endif +#include "osi/future.h" +#include "osi/allocator.h" +#include "config/stack_config.h" + +static bool bd_already_enable = false; +static bool bd_already_init = false; + +esp_bluedroid_status_t esp_bluedroid_get_status(void) +{ + if (bd_already_init) { + if (bd_already_enable) { + return ESP_BLUEDROID_STATUS_ENABLED; + } else { + return ESP_BLUEDROID_STATUS_INITIALIZED; + } + } else { + return ESP_BLUEDROID_STATUS_UNINITIALIZED; + } +} + +esp_err_t esp_bluedroid_enable(void) +{ + btc_msg_t msg; + future_t **future_p; + + if (!bd_already_init) { + LOG_ERROR("Bludroid not initialised\n"); + return ESP_ERR_INVALID_STATE; + } + + if (bd_already_enable) { + LOG_ERROR("Bluedroid already enabled\n"); + return ESP_ERR_INVALID_STATE; + } + + future_p = btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE); + *future_p = future_new(); + if (*future_p == NULL) { + LOG_ERROR("Bluedroid enable failed\n"); + return ESP_ERR_NO_MEM; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_MAIN_INIT; + msg.act = BTC_MAIN_ACT_ENABLE; + + if (btc_transfer_context(&msg, NULL, 0, NULL, NULL) != BT_STATUS_SUCCESS) { + LOG_ERROR("Bluedroid enable failed\n"); + return ESP_FAIL; + } + + if (future_await(*future_p) == FUTURE_FAIL) { + LOG_ERROR("Bluedroid enable failed\n"); + return ESP_FAIL; + } + + bd_already_enable = true; + + return ESP_OK; +} + +esp_err_t esp_bluedroid_disable(void) +{ + btc_msg_t msg; + future_t **future_p; + + if (!bd_already_enable) { + LOG_ERROR("Bluedroid already disabled\n"); + return ESP_ERR_INVALID_STATE; + } + + future_p = btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE); + *future_p = future_new(); + if (*future_p == NULL) { + LOG_ERROR("Bluedroid disable failed\n"); + return ESP_ERR_NO_MEM; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_MAIN_INIT; + msg.act = BTC_MAIN_ACT_DISABLE; + + if (btc_transfer_context(&msg, NULL, 0, NULL, NULL) != BT_STATUS_SUCCESS) { + LOG_ERROR("Bluedroid disable failed\n"); + return ESP_FAIL; + } + + if (future_await(*future_p) == FUTURE_FAIL) { + LOG_ERROR("Bluedroid disable failed\n"); + return ESP_FAIL; + } + + bd_already_enable = false; + + return ESP_OK; +} + +esp_err_t esp_bluedroid_init(void) +{ + esp_bluedroid_config_t cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); + return esp_bluedroid_init_with_cfg(&cfg); +} + +esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) +{ + btc_msg_t msg; + future_t **future_p; + bt_status_t ret; + + if (!cfg) { + LOG_ERROR("%s cfg is NULL", __func__); + return ESP_ERR_INVALID_ARG; + } + +#if (BT_CONTROLLER_INCLUDED == TRUE) + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + LOG_ERROR("Controller not initialised\n"); + return ESP_ERR_INVALID_STATE; + } +#endif + + if (bd_already_init) { + LOG_ERROR("Bluedroid already initialised\n"); + return ESP_ERR_INVALID_STATE; + } + +#if HEAP_MEMORY_DEBUG + osi_mem_dbg_init(); +#endif + + ret = bluedriod_config_init(cfg); + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("Bluedroid stack initialize fail, ret:%d", ret); + return ESP_FAIL; + } + + /* + * BTC Init + */ + ret = btc_init(); + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("Bluedroid Initialize Fail"); + return ESP_FAIL; + } + + future_p = btc_main_get_future_p(BTC_MAIN_INIT_FUTURE); + *future_p = future_new(); + if (*future_p == NULL) { + LOG_ERROR("Bluedroid Initialize Fail!"); + return ESP_ERR_NO_MEM; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_MAIN_INIT; + msg.act = BTC_MAIN_ACT_INIT; + + if (btc_transfer_context(&msg, NULL, 0, NULL, NULL) != BT_STATUS_SUCCESS) { + LOG_ERROR("Bluedroid Initialize Fail"); + return ESP_FAIL; + } + + if (future_await(*future_p) == FUTURE_FAIL) { + LOG_ERROR("Bluedroid Initialize Fail"); + return ESP_FAIL; + } + + bd_already_init = true; + + return ESP_OK; +} + + +esp_err_t esp_bluedroid_deinit(void) +{ + btc_msg_t msg; + future_t **future_p; + + if (!bd_already_init) { + LOG_ERROR("Bluedroid already de-initialised\n"); + return ESP_ERR_INVALID_STATE; + } + + if (bd_already_enable) { + LOG_ERROR("Bludroid already enabled, do disable first\n"); + return ESP_ERR_INVALID_STATE; + } + + future_p = btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE); + *future_p = future_new(); + if (*future_p == NULL) { + LOG_ERROR("Bluedroid de-initialise failed\n"); + return ESP_ERR_NO_MEM; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_MAIN_INIT; + msg.act = BTC_MAIN_ACT_DEINIT; + + if (btc_transfer_context(&msg, NULL, 0, NULL, NULL) != BT_STATUS_SUCCESS) { + LOG_ERROR("Bluedroid de-initialise failed\n"); + return ESP_FAIL; + } + + if (future_await(*future_p) == FUTURE_FAIL) { + LOG_ERROR("Bluedroid de-initialise failed\n"); + return ESP_FAIL; + } + + btc_deinit(); + + bluedriod_config_deinit(); + + bd_already_init = false; + + return ESP_OK; +} diff --git a/lib/bt/host/bluedroid/api/esp_gap_ble_api.c b/lib/bt/host/bluedroid/api/esp_gap_ble_api.c new file mode 100644 index 00000000..5db7b629 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -0,0 +1,1601 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> +#include "esp_bt_device.h" +#include "esp_bt_main.h" +#include "esp_gap_ble_api.h" +#include "bta/bta_api.h" +#include "common/bt_trace.h" +#include "btc/btc_manage.h" +#include "btc_gap_ble.h" +#include "btc/btc_ble_storage.h" + + +esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL); +} + +esp_gap_ble_cb_t esp_ble_gap_get_callback(void) +{ + return (esp_gap_ble_cb_t) btc_profile_cb_get(BTC_PID_GAP_BLE); +} + +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (adv_data == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (adv_data->service_uuid_len & 0xf) { //not 16*n + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CFG_ADV_DATA; + memcpy(&arg.cfg_adv_data.adv_data, adv_data, sizeof(esp_ble_adv_data_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free)== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (scan_params == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_SET_SCAN_PARAM; + memcpy(&arg.set_scan_param.scan_params, scan_params, sizeof(esp_ble_scan_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_start_scanning(uint32_t duration) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_START_SCAN; + arg.start_scan.duration = duration; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gap_stop_scanning(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_STOP_SCAN; + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_START_ADV; + memcpy(&arg.start_adv.adv_params, adv_params, sizeof(esp_ble_adv_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_stop_advertising(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_STOP_ADV; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_clear_advertising(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CLEAR_ADV; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if(!params) { + LOG_ERROR("%s,params is NULL", __func__); + return ESP_FAIL; + } + + if (ESP_BLE_IS_VALID_PARAM(params->min_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(params->max_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(params->timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && + (params->latency <= ESP_BLE_CONN_LATENCY_MAX) && + ((params->timeout * 10) >= ((1 + params->latency) * ((params->max_int * 5) >> 1))) && params->min_int <= params->max_int) { + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM; + memcpy(&arg.conn_update_params.conn_params, params, sizeof(esp_ble_conn_update_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + } else { + LOG_ERROR("%s,invalid connection params:min_int = %d, max_int = %d, latency = %d, timeout = %d",\ + __func__, params->min_int, params->max_int, params->latency, params->timeout); + return ESP_FAIL; + } +} + +esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_data_length) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN; + arg.set_pkt_data_len.tx_data_length = tx_data_length; + memcpy(arg.set_pkt_data_len.remote_device, remote_device, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_SET_RAND_ADDRESS; + memcpy(arg.set_rand_addr.rand_addr, rand_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_clear_rand_addr(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CLEAR_RAND_ADDRESS; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY; + arg.cfg_local_privacy.privacy_enable = privacy_enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_config_local_icon (uint16_t icon) +{ + esp_err_t ret; + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + switch (icon) { + case ESP_BLE_APPEARANCE_GENERIC_PHONE: + case ESP_BLE_APPEARANCE_GENERIC_COMPUTER: + case ESP_BLE_APPEARANCE_GENERIC_REMOTE: + case ESP_BLE_APPEARANCE_GENERIC_THERMOMETER: + case ESP_BLE_APPEARANCE_THERMOMETER_EAR: + case ESP_BLE_APPEARANCE_GENERIC_HEART_RATE: + case ESP_BLE_APPEARANCE_HEART_RATE_BELT: + case ESP_BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE: + case ESP_BLE_APPEARANCE_BLOOD_PRESSURE_ARM: + case ESP_BLE_APPEARANCE_BLOOD_PRESSURE_WRIST: + case ESP_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER: + case ESP_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP: + case ESP_BLE_APPEARANCE_PULSE_OXIMETER_WRIST: + case ESP_BLE_APPEARANCE_GENERIC_GLUCOSE: + case ESP_BLE_APPEARANCE_GENERIC_WEIGHT: + case ESP_BLE_APPEARANCE_GENERIC_WALKING: + case ESP_BLE_APPEARANCE_WALKING_IN_SHOE: + case ESP_BLE_APPEARANCE_WALKING_ON_SHOE: + case ESP_BLE_APPEARANCE_WALKING_ON_HIP: + case ESP_BLE_APPEARANCE_GENERIC_WATCH: + case ESP_BLE_APPEARANCE_SPORTS_WATCH: + case ESP_BLE_APPEARANCE_GENERIC_EYEGLASSES: + case ESP_BLE_APPEARANCE_GENERIC_DISPLAY: + case ESP_BLE_APPEARANCE_GENERIC_MEDIA_PLAYER: + case ESP_BLE_APPEARANCE_GENERIC_BARCODE_SCANNER: + case ESP_BLE_APPEARANCE_HID_BARCODE_SCANNER: + case ESP_BLE_APPEARANCE_GENERIC_HID: + case ESP_BLE_APPEARANCE_HID_KEYBOARD: + case ESP_BLE_APPEARANCE_HID_MOUSE: + case ESP_BLE_APPEARANCE_HID_JOYSTICK: + case ESP_BLE_APPEARANCE_HID_GAMEPAD: + case ESP_BLE_APPEARANCE_HID_DIGITIZER_TABLET: + case ESP_BLE_APPEARANCE_HID_CARD_READER: + case ESP_BLE_APPEARANCE_HID_DIGITAL_PEN: + case ESP_BLE_APPEARANCE_UNKNOWN: + case ESP_BLE_APPEARANCE_GENERIC_CLOCK: + case ESP_BLE_APPEARANCE_GENERIC_TAG: + case ESP_BLE_APPEARANCE_GENERIC_KEYRING: + case ESP_BLE_APPEARANCE_GENERIC_CYCLING: + case ESP_BLE_APPEARANCE_CYCLING_COMPUTER: + case ESP_BLE_APPEARANCE_CYCLING_SPEED: + case ESP_BLE_APPEARANCE_CYCLING_CADENCE: + case ESP_BLE_APPEARANCE_CYCLING_POWER: + case ESP_BLE_APPEARANCE_CYCLING_SPEED_CADENCE: + case ESP_BLE_APPEARANCE_GENERIC_PERSONAL_MOBILITY_DEVICE: + case ESP_BLE_APPEARANCE_POWERED_WHEELCHAIR: + case ESP_BLE_APPEARANCE_MOBILITY_SCOOTER: + case ESP_BLE_APPEARANCE_GENERIC_CONTINUOUS_GLUCOSE_MONITOR: + case ESP_BLE_APPEARANCE_GENERIC_INSULIN_PUMP: + case ESP_BLE_APPEARANCE_INSULIN_PUMP_DURABLE_PUMP: + case ESP_BLE_APPEARANCE_INSULIN_PUMP_PATCH_PUMP: + case ESP_BLE_APPEARANCE_INSULIN_PEN: + case ESP_BLE_APPEARANCE_GENERIC_MEDICATION_DELIVERY: + case ESP_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS: + case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION: + case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV: + case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD: + case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV: + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON; + arg.cfg_local_icon.icon = icon; + ret = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + break; + default: + ret = ESP_ERR_INVALID_ARG; + break; + } + return ret; +} + +esp_err_t esp_ble_gap_update_whitelist(bool add_remove, esp_bd_addr_t remote_bda, esp_ble_wl_addr_type_t wl_addr_type) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (!remote_bda){ + return ESP_ERR_INVALID_SIZE; + } + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_UPDATE_WHITE_LIST; + arg.update_white_list.add_remove = add_remove; + arg.update_white_list.wl_addr_type = wl_addr_type; + memcpy(arg.update_white_list.remote_bda, remote_bda, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_clear_whitelist(void) +{ + btc_msg_t msg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CLEAR_WHITE_LIST; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_get_whitelist_size(uint16_t *length) +{ + if (length == NULL) { + return ESP_FAIL; + } + btc_get_whitelist_size(length); + + return ESP_OK; +} +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gap_set_prefer_conn_params(esp_bd_addr_t bd_addr, + uint16_t min_conn_int, uint16_t max_conn_int, + uint16_t slave_latency, uint16_t supervision_tout) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (ESP_BLE_IS_VALID_PARAM(min_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(max_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(supervision_tout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && + (slave_latency <= ESP_BLE_CONN_LATENCY_MAX) && + ((supervision_tout * 10) >= ((1 + slave_latency) * ((max_conn_int * 5) >> 1))) && min_conn_int <= max_conn_int) { + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_SET_CONN_PARAMS; + arg.set_conn_params.min_conn_int = min_conn_int; + arg.set_conn_params.max_conn_int = max_conn_int; + arg.set_conn_params.slave_latency = slave_latency; + arg.set_conn_params.supervision_tout = supervision_tout; + memcpy(arg.set_conn_params.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + } else { + LOG_ERROR("%s,invalid connection params:min_int = %d, max_int = %d, latency = %d, timeout = %d",\ + __func__, min_conn_int, max_conn_int, slave_latency, supervision_tout); + return ESP_FAIL; + } +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +esp_err_t esp_ble_gap_set_device_name(const char *name) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + return esp_bt_dev_set_device_name(name); +} + +esp_err_t esp_ble_gap_get_device_name(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_GET_DEV_NAME; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t * addr_type) +{ + if(esp_bluedroid_get_status() != (ESP_BLUEDROID_STATUS_ENABLED)) { + LOG_ERROR("%s, bluedroid status error", __func__); + return ESP_FAIL; + } + if(!BTM_BleGetCurrentAddress(local_used_addr, addr_type)) { + return ESP_FAIL; + } + return ESP_OK; +} + +uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length) +{ + if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) && + (type != ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE)) { + LOG_ERROR("the eir type not define, type = %x\n", type); + return NULL; + } + + if (adv_data == NULL) { + LOG_ERROR("Invalid p_eir data.\n"); + return NULL; + } + + return (BTM_CheckAdvData( adv_data, type, length)); +} +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if ((raw_data_len != 0 && raw_data == NULL) || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW; + arg.cfg_adv_data_raw.raw_adv = raw_data; + arg.cfg_adv_data_raw.raw_adv_len = raw_data_len; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_READ_RSSI; + memcpy(arg.read_rssi.remote_addr, remote_addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if ((raw_data_len != 0 && raw_data == NULL) || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW; + arg.cfg_scan_rsp_data_raw.raw_scan_rsp = raw_data; + arg.cfg_scan_rsp_data_raw.raw_scan_rsp_len = raw_data_len; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (!device_info && type <= ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID) { + return ESP_ERR_INVALID_SIZE; + } + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST; + arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD; + arg.update_duplicate_exceptional_list.info_type = type; + if (device_info) { + memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t)); + } + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (!device_info && type <= ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID) { + return ESP_ERR_INVALID_SIZE; + } + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST; + arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_REMOVE; + arg.update_duplicate_exceptional_list.info_type = type; + if (device_info) { + memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t)); + } + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_clean_duplicate_scan_exceptional_list(esp_duplicate_scan_exceptional_list_type_t list_type) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST; + arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN; + arg.update_duplicate_exceptional_list.info_type = list_type; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) +#if (SMP_INCLUDED == TRUE) +esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type, + void *value, uint8_t len) +{ + if(param_type >= ESP_BLE_SM_MAX_PARAM) { + return ESP_ERR_INVALID_ARG; + } + if((param_type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY) && ( value == NULL || len < sizeof(uint8_t) || len > sizeof(uint32_t))) { + return ESP_ERR_INVALID_ARG; + } + if(param_type == ESP_BLE_SM_SET_STATIC_PASSKEY) { + uint32_t passkey = 0; + for(uint8_t i = 0; i < len; i++) + { + passkey += (((uint8_t *)value)[i]<<(8*i)); + } + if(passkey > 999999) { + return ESP_ERR_INVALID_ARG; + } + } + if (param_type == ESP_BLE_APP_ENC_KEY_SIZE) { + LOG_ERROR("ESP_BLE_APP_ENC_KEY_SIZE is deprecated, use ESP_GATT_PERM_ENCRYPT_KEY_SIZE in characteristic definition"); + return ESP_ERR_NOT_SUPPORTED; + } + if (param_type == ESP_BLE_SM_MAX_KEY_SIZE || param_type == ESP_BLE_SM_MIN_KEY_SIZE) { + if (((uint8_t *)value)[0] > 16 || ((uint8_t *)value)[0] < 7) { + return ESP_ERR_INVALID_ARG; + } + } + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_SECURITY_PARAM_EVT; + arg.set_security_param.param_type = param_type; + arg.set_security_param.len = len; + arg.set_security_param.value = value; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_act) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_ENCRYPTION_EVT; + arg.set_encryption.sec_act = sec_act; + memcpy(arg.set_encryption.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_security_rsp(esp_bd_addr_t bd_addr, bool accept) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SECURITY_RSP_EVT; + arg.sec_rsp.accept = accept; + memcpy(arg.sec_rsp.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PASSKEY_REPLY_EVT; + arg.enc_passkey_replay.accept = accept; + arg.enc_passkey_replay.passkey = passkey; + memcpy(arg.enc_passkey_replay.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CONFIRM_REPLY_EVT; + arg.enc_comfirm_replay.accept = accept; + memcpy(arg.enc_comfirm_replay.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_REMOVE_BOND_DEV_EVT; + memcpy(arg.remove_bond_device.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +int esp_ble_get_bond_device_num(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_FAIL; + } + + return btc_storage_get_num_ble_bond_devices(); +} + +esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list) +{ + int ret; + int dev_num_total; + + if (dev_num == NULL || dev_list == NULL) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + dev_num_total = btc_storage_get_num_ble_bond_devices(); + if (*dev_num > dev_num_total) { + *dev_num = dev_num_total; + } + + ret = btc_storage_get_bonded_ble_devices_list(dev_list, *dev_num); + + return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len) +{ + if(len != ESP_BT_OCTET16_LEN) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_OOB_REQ_REPLY_EVT; + memcpy(arg.oob_req_reply.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + arg.oob_req_reply.len = len; + arg.oob_req_reply.p_value = TK; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8_t p_r[16]) +{ + if (!p_c || !p_r) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT; + memcpy(arg.sc_oob_req_reply.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + arg.sc_oob_req_reply.p_c = p_c; + arg.sc_oob_req_reply.p_r = p_r; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_create_sc_oob_data(void) +{ + btc_msg_t msg = {0}; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SC_CR_OOB_DATA_EVT; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif /* #if (SMP_INCLUDED == TRUE) */ + +esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DISCONNECT_EVT; + memcpy(arg.disconnect.remote_device, remote_device, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_get_current_conn_params(esp_bd_addr_t bd_addr, esp_gap_conn_params_t *conn_params) +{ + if(!bd_addr || !conn_params) { + return ESP_ERR_INVALID_ARG; + } + if(BTM_GetCurrentConnParams(bd_addr, &conn_params->interval, &conn_params->latency, &conn_params->timeout)) { + return ESP_OK; + } + return ESP_ERR_NOT_FOUND; +} + +esp_err_t esp_gap_ble_set_channels(esp_gap_ble_channels channels) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_AFH_CHANNELS; + + memcpy(&arg.set_channels.channels, channels, ESP_GAP_BLE_CHANNELS_LEN); + arg.set_channels.channels[ESP_GAP_BLE_CHANNELS_LEN -1] &= 0x1F; + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_gap_ble_set_authorization(esp_bd_addr_t bd_addr, bool authorize) +{ + if (!bd_addr) { + return ESP_ERR_INVALID_ARG; + } + if (BTM_Ble_Authorization(bd_addr, authorize)) { + return ESP_OK; + } + return ESP_FAIL; +} + +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_dtm_tx_start(const esp_ble_dtm_tx_t *tx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!tx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_TX_START; + + memcpy(&arg.dtm_tx_start, tx_params, sizeof(esp_ble_dtm_tx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!rx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_RX_START; + + memcpy(&arg.dtm_rx_start, rx_params, sizeof(esp_ble_dtm_rx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (!tx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_ENH_TX_START; + + memcpy(&arg.dtm_enh_tx_start, tx_params, sizeof(esp_ble_dtm_enh_tx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (!rx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_ENH_RX_START; + + memcpy(&arg.dtm_enh_rx_start, rx_params, sizeof(esp_ble_dtm_enh_rx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +esp_err_t esp_ble_dtm_stop(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_STOP; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#if (BLE_50_FEATURE_SUPPORT == TRUE) + +esp_err_t esp_ble_gap_read_phy(esp_bd_addr_t bd_addr) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_READ_PHY; + + memcpy(arg.read_phy.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_preferred_default_phy(esp_ble_gap_phy_mask_t tx_phy_mask, + esp_ble_gap_phy_mask_t rx_phy_mask) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PREFERED_DEF_PHY; + arg.set_perf_def_phy.tx_phy_mask = tx_phy_mask; + arg.set_perf_def_phy.rx_phy_mask = rx_phy_mask; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_preferred_phy(esp_bd_addr_t bd_addr, + esp_ble_gap_all_phys_t all_phys_mask, + esp_ble_gap_phy_mask_t tx_phy_mask, + esp_ble_gap_phy_mask_t rx_phy_mask, + esp_ble_gap_prefer_phy_options_t phy_options) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_DEF_PHY; + memcpy(arg.set_def_phy.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + arg.set_def_phy.all_phys_mask = all_phys_mask; + arg.set_def_phy.tx_phy_mask = tx_phy_mask; + arg.set_def_phy.rx_phy_mask = rx_phy_mask; + arg.set_def_phy.phy_options = phy_options; + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_ext_adv_set_rand_addr(uint8_t instance, esp_bd_addr_t rand_addr) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_EXT_ADV_RAND_ADDR; + arg.ext_adv_set_rand_addr.instance = instance; + memcpy(arg.ext_adv_set_rand_addr.rand_addr, rand_addr, BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_ext_adv_set_params(uint8_t instance, + const esp_ble_gap_ext_adv_params_t *params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_EXT_ADV_PARAMS; + + if (ESP_BLE_IS_VALID_PARAM(params->interval_min, ESP_BLE_PRIM_ADV_INT_MIN, ESP_BLE_PRIM_ADV_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(params->interval_max, ESP_BLE_PRIM_ADV_INT_MIN, ESP_BLE_PRIM_ADV_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(params->peer_addr_type, BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_RANDOM) && + ESP_BLE_IS_VALID_PARAM(params->own_addr_type, BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_RPA_RANDOM) && + ESP_BLE_IS_VALID_PARAM(params->filter_policy, ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST) && + (params->interval_min <= params->interval_max) && (params->channel_map > 0) && (params->channel_map <= ADV_CHNL_ALL) && + ((params->primary_phy == ESP_BLE_GAP_PRI_PHY_1M) || (params->primary_phy == ESP_BLE_GAP_PRI_PHY_CODED)) && + ((params->secondary_phy == ESP_BLE_GAP_PHY_1M) || (params->secondary_phy == ESP_BLE_GAP_PHY_2M) || + (params->secondary_phy == ESP_BLE_GAP_PHY_CODED))){ + memcpy(&arg.ext_adv_set_params.params, params, sizeof(esp_ble_gap_ext_adv_params_t)); + } else { + LOG_ERROR("%s,invalid ext adv params", __func__); + return ESP_ERR_INVALID_ARG; + } + + arg.ext_adv_set_params.instance = instance; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_config_ext_adv_data_raw(uint8_t instance, uint16_t length, + const uint8_t *data) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW; + + arg.ext_adv_cfg_data.instance = instance; + arg.ext_adv_cfg_data.length = length; + arg.ext_adv_cfg_data.data = (uint8_t *)data; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_config_ext_scan_rsp_data_raw(uint8_t instance, uint16_t length, + const uint8_t *scan_rsp_data) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CFG_EXT_SCAN_RSP_DATA_RAW; + + arg.cfg_scan_rsp.instance = instance; + arg.cfg_scan_rsp.length = length; + arg.cfg_scan_rsp.data = (uint8_t *)scan_rsp_data; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_ext_adv_start(uint8_t num_adv, const esp_ble_gap_ext_adv_t *ext_adv) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_EXT_ADV_START; + + arg.ext_adv_start.num_adv = num_adv; + arg.ext_adv_start.ext_adv = (esp_ble_gap_ext_adv_t *)ext_adv; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_ext_adv_stop(uint8_t num_adv, const uint8_t *ext_adv_inst) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_EXT_ADV_STOP; + arg.ext_adv_stop.num_adv = num_adv; + arg.ext_adv_stop.ext_adv_inst = (uint8_t *)ext_adv_inst; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_ext_adv_set_remove(uint8_t instance) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_EXT_ADV_SET_REMOVE; + arg.ext_adv_set_remove.instance = instance; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_ext_adv_set_clear(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_EXT_ADV_SET_CLEAR; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_set_params(uint8_t instance, const esp_ble_gap_periodic_adv_params_t *params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PERIODIC_ADV_PARAMS; + + arg.peridic_adv_set_params.instance = instance; + memcpy(&arg.peridic_adv_set_params.params, params, sizeof(esp_ble_gap_periodic_adv_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, + const uint8_t *data, bool only_update_did) +#else +esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, + const uint8_t *data) +#endif +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CFG_PERIODIC_ADV_DATA_RAW; + + arg.periodic_adv_cfg_data.instance = instance; + arg.periodic_adv_cfg_data.len = length; + arg.periodic_adv_cfg_data.data = (uint8_t *)data; +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) + arg.periodic_adv_cfg_data.only_update_did = only_update_did; +#else + arg.periodic_adv_cfg_data.only_update_did = false; +#endif + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance,bool include_adi) +#else +esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance) +#endif +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_START; + + #if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) + arg.periodic_adv_start.include_adi = include_adi; + #else + arg.periodic_adv_start.include_adi = false; + #endif + arg.periodic_adv_start.instance = instance; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_periodic_adv_stop(uint8_t instance) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_STOP; + + arg.periodic_adv_stop.instance = instance; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_periodic_adv_create_sync(const esp_ble_gap_periodic_adv_sync_params_t *params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_CREATE_SYNC; + + memcpy(&arg.periodic_adv_create_sync.params, params, sizeof(esp_ble_gap_periodic_adv_sync_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_periodic_adv_sync_cancel(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_periodic_adv_sync_terminate(uint16_t sync_handle) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE; + + arg.periodic_adv_sync_term.sync_handle = sync_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_add_dev_to_list(esp_ble_addr_type_t addr_type, + esp_bd_addr_t addr, + uint8_t sid) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_ADD_DEV_TO_LIST; + + arg.periodic_adv_add_dev.addr_type = addr_type; + arg.periodic_adv_add_dev.sid = sid; + + + memcpy(arg.periodic_adv_add_dev.addr, addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_periodic_adv_remove_dev_from_list(esp_ble_addr_type_t addr_type, + esp_bd_addr_t addr, + uint8_t sid) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_REMOVE_ADD_DEV_FROM_LIST; + + arg.periodic_adv_remove_dev.addr_type = addr_type; + arg.periodic_adv_remove_dev.sid = sid; + + + memcpy(arg.periodic_adv_remove_dev.addr, addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_periodic_adv_clear_dev(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_CLEAR_DEV; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +esp_err_t esp_ble_gap_set_ext_scan_params(const esp_ble_ext_scan_params_t *params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + if (!params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_EXT_SCAN_PARAMS; + + memcpy(&arg.set_ext_scan_params.params, params, sizeof(esp_ble_ext_scan_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_start_ext_scan(uint32_t duration, uint16_t period) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_START_EXT_SCAN; + + arg.start_ext_scan.duration = duration; + arg.start_ext_scan.period = period; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_stop_ext_scan(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_STOP_EXT_SCAN; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, + esp_ble_gap_phy_mask_t phy_mask, + const esp_ble_gap_conn_params_t *phy_1m_conn_params, + const esp_ble_gap_conn_params_t *phy_2m_conn_params, + const esp_ble_gap_conn_params_t *phy_coded_conn_params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_EXT_PEFER_CONNET_PARAMS; + + arg.set_ext_conn_params.phy_mask = phy_mask; + if (phy_mask & ESP_BLE_GAP_PHY_1M_PREF_MASK) { + if (!phy_1m_conn_params) { + return BT_STATUS_PARM_INVALID; + } + + if (ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && + (phy_1m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && + ((phy_1m_conn_params->supervision_timeout * 10) >= ((1 + phy_1m_conn_params->latency) * ((phy_1m_conn_params->interval_max * 5) >> 1))) && + (phy_1m_conn_params->interval_min <= phy_1m_conn_params->interval_max)) { + + memcpy(&arg.set_ext_conn_params.phy_1m_conn_params, phy_1m_conn_params, sizeof(esp_ble_gap_conn_params_t)); + } else { + LOG_ERROR("%s,invalid connection params:min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__, + phy_1m_conn_params->interval_min, + phy_1m_conn_params->interval_max, + phy_1m_conn_params->latency, + phy_1m_conn_params->supervision_timeout); + + return ESP_ERR_INVALID_ARG; + } + } + + if (phy_mask & ESP_BLE_GAP_PHY_2M_PREF_MASK) { + if (!phy_2m_conn_params) { + return BT_STATUS_PARM_INVALID; + } + + if (ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && + (phy_2m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && + ((phy_2m_conn_params->supervision_timeout * 10) >= ((1 + phy_2m_conn_params->latency) * ((phy_2m_conn_params->interval_max * 5) >> 1))) && + (phy_2m_conn_params->interval_min <= phy_2m_conn_params->interval_max)) { + + memcpy(&arg.set_ext_conn_params.phy_2m_conn_params, phy_2m_conn_params, sizeof(esp_ble_gap_conn_params_t)); + } else { + LOG_ERROR("%s,invalid connection params:min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__, + phy_2m_conn_params->interval_min, + phy_2m_conn_params->interval_max, + phy_2m_conn_params->latency, + phy_2m_conn_params->supervision_timeout); + + return ESP_ERR_INVALID_ARG; + } + } + + if (phy_mask & ESP_BLE_GAP_PHY_CODED_PREF_MASK) { + if (!phy_coded_conn_params) { + return BT_STATUS_PARM_INVALID; + } + + if (ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && + (phy_coded_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && + ((phy_coded_conn_params->supervision_timeout * 10) >= ((1 + phy_coded_conn_params->latency) * ((phy_coded_conn_params->interval_max * 5) >> 1))) && + (phy_coded_conn_params->interval_min <= phy_coded_conn_params->interval_max)) { + + memcpy(&arg.set_ext_conn_params.phy_coded_conn_params, phy_coded_conn_params, sizeof(esp_ble_gap_conn_params_t)); + } else { + LOG_ERROR("%s,invalid connection params:min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__, + phy_coded_conn_params->interval_min, + phy_coded_conn_params->interval_max, + phy_coded_conn_params->latency, + phy_coded_conn_params->supervision_timeout); + + return ESP_ERR_INVALID_ARG; + } + } + + memcpy(arg.set_ext_conn_params.addr, addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + +#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +esp_err_t esp_ble_gap_periodic_adv_recv_enable(uint16_t sync_handle, uint8_t enable) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE; + + arg.periodic_adv_recv_en.sync_handle = sync_handle; + arg.periodic_adv_recv_en.enable = enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_sync_trans(esp_bd_addr_t addr, uint16_t service_data, uint16_t sync_handle) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (addr == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS; + + memcpy(arg.periodic_adv_sync_trans.addr, addr, sizeof(esp_bd_addr_t)); + arg.periodic_adv_sync_trans.service_data = service_data; + arg.periodic_adv_sync_trans.sync_handle = sync_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_set_info_trans(esp_bd_addr_t addr, uint16_t service_data, uint8_t adv_handle) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (addr == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS; + + memcpy(arg.periodic_adv_set_info_trans.addr, addr, sizeof(esp_bd_addr_t)); + arg.periodic_adv_set_info_trans.service_data = service_data; + arg.periodic_adv_set_info_trans.adv_handle = adv_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, const esp_ble_gap_past_params_t *params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS; + + if (addr) { + memcpy(arg.set_periodic_adv_sync_trans_params.addr, addr, sizeof(esp_bd_addr_t)); + } else { + memset(arg.set_periodic_adv_sync_trans_params.addr, 0, sizeof(esp_bd_addr_t)); + } + memcpy(&arg.set_periodic_adv_sync_trans_params.params, params, sizeof(esp_ble_gap_past_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/lib/bt/host/bluedroid/api/esp_gap_bt_api.c b/lib/bt/host/bluedroid/api/esp_gap_bt_api.c new file mode 100644 index 00000000..3e58847d --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_gap_bt_api.c @@ -0,0 +1,497 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common/bt_target.h" +#include <string.h> +#include "esp_bt_main.h" +#include "esp_gap_bt_api.h" +#include "esp_log.h" +#include "common/bt_trace.h" +#include "bta/bta_api.h" +#include "btc/btc_manage.h" +#include "btc_gap_bt.h" +#include "btc/btc_storage.h" +#include "config/stack_config.h" + +#if (BTC_GAP_BT_INCLUDED == TRUE) + +#define TAG "BT_GAP" + +esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_GAP_BT, callback); + return ESP_OK; +} + +esp_err_t esp_bt_gap_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discovery_mode_t d_mode) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_SCAN_MODE; + arg.set_scan_mode.c_mode = c_mode; + arg.set_scan_mode.d_mode = d_mode; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, uint8_t num_rsps) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (mode != ESP_BT_INQ_MODE_GENERAL_INQUIRY && + mode != ESP_BT_INQ_MODE_LIMITED_INQUIRY) { + return ESP_ERR_INVALID_ARG; + } + + if (inq_len < ESP_BT_GAP_MIN_INQ_LEN || + inq_len > ESP_BT_GAP_MAX_INQ_LEN) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_START_DISCOVERY; + + arg.start_disc.mode = mode; + arg.start_disc.inq_len = inq_len; + arg.start_disc.num_rsps = num_rsps; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_cancel_discovery(void) +{ + btc_msg_t msg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_CANCEL_DISCOVERY; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_GET_REMOTE_SERVICES; + + memcpy(&arg.bda, remote_bda, sizeof(bt_bdaddr_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda, esp_bt_uuid_t *uuid) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD; + + memcpy(&arg.get_rmt_srv_rcd.bda, remote_bda, sizeof(bt_bdaddr_t)); + memcpy(&arg.get_rmt_srv_rcd.uuid, uuid, sizeof(esp_bt_uuid_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8_t *length) +{ + if (!eir) { + return NULL; + } + + return BTM_CheckEirData(eir, type, length); +} + +esp_err_t esp_bt_gap_config_eir_data(esp_bt_eir_data_t *eir_data) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (eir_data == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (eir_data->manufacturer_len > ESP_BT_EIR_MAX_LEN + || eir_data->url_len > ESP_BT_EIR_MAX_LEN) { + return ESP_ERR_INVALID_ARG; + } + + if ((eir_data->manufacturer_len > 0 && eir_data->p_manufacturer_data == NULL) + || (eir_data->url_len > 0 && eir_data->p_url == NULL)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_CONFIG_EIR; + + memcpy(&arg.config_eir, eir_data, sizeof(esp_bt_eir_data_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy, + btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + switch (mode) { + case ESP_BT_SET_COD_MAJOR_MINOR: + case ESP_BT_SET_COD_SERVICE_CLASS: + case ESP_BT_CLR_COD_SERVICE_CLASS: + case ESP_BT_SET_COD_ALL: + case ESP_BT_INIT_COD: + break; + default: + return ESP_ERR_INVALID_ARG; + break; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_COD; + + arg.set_cod.mode = mode; + memcpy(&arg.set_cod.cod, &cod, sizeof(esp_bt_cod_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod) +{ + return btc_gap_bt_get_cod(cod); +} + + +esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_READ_RSSI_DELTA; + memcpy(arg.read_rssi_delta.bda.address, remote_addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE; + + memcpy(arg.rm_bond_device.bda.address, bd_addr, sizeof(esp_bd_addr_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +int esp_bt_gap_get_bond_device_num(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + return btc_storage_get_num_bt_bond_devices(); +} + +esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list) +{ + int ret; + + if (dev_num == NULL || dev_list == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + ret = btc_storage_get_bonded_bt_devices_list((bt_bdaddr_t *)dev_list, dev_num); + + return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, esp_bt_pin_code_t pin_code) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_PIN_TYPE; + arg.set_pin_type.pin_type = pin_type; + if (pin_type == ESP_BT_PIN_TYPE_FIXED){ + arg.set_pin_type.pin_code_len = pin_code_len; + memcpy(arg.set_pin_type.pin_code, pin_code, pin_code_len); + } else { + arg.set_pin_type.pin_code_len = 0; + memset(arg.set_pin_type.pin_code, 0, ESP_BT_PIN_CODE_LEN); + } + + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy, + btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_code_len, esp_bt_pin_code_t pin_code) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_PIN_REPLY; + arg.pin_reply.accept = accept; + arg.pin_reply.pin_code_len = pin_code_len; + memcpy(arg.pin_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t)); + memcpy(arg.pin_reply.pin_code, pin_code, pin_code_len); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy, + btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type, + void *value, uint8_t len) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!(bluedriod_config_get()->get_ssp_enabled())) { + ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__); + return ESP_ERR_NOT_SUPPORTED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_SECURITY_PARAM; + arg.set_security_param.param_type = param_type; + arg.set_security_param.len = len; + arg.set_security_param.value = value; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy, + btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!(bluedriod_config_get()->get_ssp_enabled())) { + ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__); + return ESP_ERR_NOT_SUPPORTED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_PASSKEY_REPLY; + arg.passkey_reply.accept = accept; + arg.passkey_reply.passkey = passkey; + memcpy(arg.passkey_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy, + btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!(bluedriod_config_get()->get_ssp_enabled())) { + ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__); + return ESP_ERR_NOT_SUPPORTED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_CONFIRM_REPLY; + arg.confirm_reply.accept = accept; + memcpy(arg.confirm_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy, + btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_AFH_CHANNELS; + + memcpy(&arg.set_afh_channels.channels, channels, ESP_BT_GAP_AFH_CHANNELS_LEN); + arg.set_afh_channels.channels[ESP_BT_GAP_AFH_CHANNELS_LEN -1] &= 0x7F; + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_READ_REMOTE_NAME; + + memcpy(&arg.rmt_name_bda, remote_bda, sizeof(bt_bdaddr_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (t_poll < ESP_BT_GAP_TPOLL_MIN || t_poll > ESP_BT_GAP_TPOLL_MAX) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_QOS; + + memcpy(&arg.set_qos.bda, remote_bda, sizeof(bt_bdaddr_t)); + arg.set_qos.t_poll = t_poll; + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_set_page_timeout(uint16_t page_to) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (page_to < HCI_MIN_PAGE_TOUT) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_PAGE_TIMEOUT; + + arg.set_page_to.page_to = page_to; + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_get_page_timeout(void) +{ + btc_msg_t msg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_GET_PAGE_TIMEOUT; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, uint16_t pkt_types) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES; + + memcpy(&arg.set_acl_pkt_types.bda, remote_bda, sizeof(bt_bdaddr_t)); + arg.set_acl_pkt_types.pkt_types = pkt_types; + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#endif /* #if BTC_GAP_BT_INCLUDED == TRUE */ diff --git a/lib/bt/host/bluedroid/api/esp_gatt_common_api.c b/lib/bt/host/bluedroid/api/esp_gatt_common_api.c new file mode 100644 index 00000000..d0f3b0e0 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_gatt_common_api.c @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> +#include "esp_gatt_common_api.h" +#include "esp_bt_main.h" +#include "esp_gatt_defs.h" +#include "btc_gatt_common.h" + +/** + * @brief This function is called to set local MTU, + * the function is called before BLE connection. + * + * @param[in] mtu: the size of MTU. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu) +{ + btc_msg_t msg = {0}; + btc_ble_gatt_com_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if ((mtu < ESP_GATT_DEF_BLE_MTU_SIZE) || (mtu > ESP_GATT_MAX_MTU_SIZE)) { + return ESP_ERR_INVALID_SIZE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATT_COMMON; + msg.act = BTC_GATT_ACT_SET_LOCAL_MTU; + arg.set_mtu.mtu = mtu; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatt_com_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#if (BLE_INCLUDED == TRUE) +extern UINT16 L2CA_GetFreePktBufferNum_LE(void); + +/** + * @brief This function is called to get currently sendable packets number on controller, + * the function is called only in BLE running core and single connection now. + * + * @return + * sendable packets number on controller + * + */ + +uint16_t esp_ble_get_sendable_packets_num (void) +{ + return L2CA_GetFreePktBufferNum_LE(); +} + +/** + * @brief This function is used to query the number of available buffers for the current connection. + * When you need to query the current available buffer number, it is recommended to use this API. + * @param[in] conn_id: current connection id. + * + * @return + * Number of available buffers for the current connection + * + */ + +extern UINT16 L2CA_GetCurFreePktBufferNum_LE(UINT16 conn_id); +uint16_t esp_ble_get_cur_sendable_packets_num (uint16_t connid) +{ + return L2CA_GetCurFreePktBufferNum_LE(connid); +} +#endif diff --git a/lib/bt/host/bluedroid/api/esp_gattc_api.c b/lib/bt/host/bluedroid/api/esp_gattc_api.c new file mode 100644 index 00000000..5f078b28 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_gattc_api.c @@ -0,0 +1,786 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "esp_gattc_api.h" +#include "esp_bt_main.h" +#include "btc/btc_manage.h" +#include "btc_gattc.h" +#include "btc_gatt_util.h" +#include "stack/l2cdefs.h" +#include "stack/l2c_api.h" +#include "gatt_int.h" + + +#if (GATTC_INCLUDED == TRUE) +esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_GATTC, callback); + return ESP_OK; +} + +esp_gattc_cb_t esp_ble_gattc_get_callback(void) +{ + return (esp_gattc_cb_t) btc_profile_cb_get(BTC_PID_GATTC); +} + +esp_err_t esp_ble_gattc_app_register(uint16_t app_id) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (app_id > ESP_APP_ID_MAX) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_APP_REGISTER; + arg.app_reg.app_id = app_id; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_APP_UNREGISTER; + arg.app_unreg.gattc_if = gattc_if; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_OPEN; + arg.open.gattc_if = gattc_if; + memcpy(arg.open.remote_bda, remote_bda, ESP_BD_ADDR_LEN); + arg.open.remote_addr_type = remote_addr_type; + arg.open.is_direct = is_direct; + arg.open.is_aux = false; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gattc_aux_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct) +{ + btc_msg_t msg; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_AUX_OPEN; + arg.open.gattc_if = gattc_if; + memcpy(arg.open.remote_bda, remote_bda, ESP_BD_ADDR_LEN); + arg.open.remote_addr_type = remote_addr_type; + arg.open.is_direct = is_direct; + arg.open.is_aux = true; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_CLOSE; + arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_send_mtu_req (esp_gatt_if_t gattc_if, uint16_t conn_id) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_CFG_MTU; + arg.cfg_mtu.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *filter_uuid) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_SEARCH_SERVICE; + arg.search_srvc.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + + if (filter_uuid) { + arg.search_srvc.filter_uuid_enable = true; + memcpy(&arg.search_srvc.filter_uuid, filter_uuid, sizeof(esp_bt_uuid_t)); + } else { + arg.search_srvc.filter_uuid_enable = false; + } + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *svc_uuid, + esp_gattc_service_elem_t *result, uint16_t *count, uint16_t offset) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (result == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_service(conn_hdl, svc_uuid, result, count, offset); +} + + +esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_gattc_char_elem_t *result, + uint16_t *count, uint16_t offset) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if ((start_handle == 0) && (end_handle == 0)) { + *count = 0; + return ESP_GATT_INVALID_HANDLE; + } + + if (result == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_all_char(conn_hdl, start_handle, end_handle, result, count, offset); +} + +esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t char_handle, + esp_gattc_descr_elem_t *result, + uint16_t *count, uint16_t offset) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (char_handle == 0) { + return ESP_GATT_INVALID_HANDLE; + } + + if (result == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_all_descr(conn_hdl, char_handle, result, count, offset); +} + +esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t char_uuid, + esp_gattc_char_elem_t *result, + uint16_t *count) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (start_handle == 0 && end_handle == 0) { + *count = 0; + return ESP_GATT_INVALID_HANDLE; + } + + if (result == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if,conn_id); + return btc_ble_gattc_get_char_by_uuid(conn_hdl, start_handle, end_handle, char_uuid, result, count); +} + + +esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t char_uuid, + esp_bt_uuid_t descr_uuid, + esp_gattc_descr_elem_t *result, + uint16_t *count) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (result == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_descr_by_uuid(conn_hdl, start_handle, end_handle, char_uuid, descr_uuid, result, count); +} + +esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t char_handle, + esp_bt_uuid_t descr_uuid, + esp_gattc_descr_elem_t *result, + uint16_t *count) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (char_handle == 0) { + *count = 0; + return ESP_GATT_INVALID_HANDLE; + } + + if (result == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_descr_by_char_handle(conn_hdl, char_handle, descr_uuid, result, count); +} + +esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t *incl_uuid, + esp_gattc_incl_svc_elem_t *result, + uint16_t *count) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (start_handle == 0 && end_handle == 0) { + *count = 0; + return ESP_GATT_INVALID_HANDLE; + } + + if (result == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_include_service(conn_hdl, start_handle, end_handle, incl_uuid, result, count); +} + +esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if, + uint16_t conn_id, + esp_gatt_db_attr_type_t type, + uint16_t start_handle, + uint16_t end_handle, + uint16_t char_handle, + uint16_t *count) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if ((start_handle == 0 && end_handle == 0) && (type != ESP_GATT_DB_DESCRIPTOR)) { + *count = 0; + return ESP_GATT_INVALID_HANDLE; + } + + if (count == NULL) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_attr_count(conn_hdl, type, start_handle, end_handle, char_handle, count); +} + +esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, + esp_gattc_db_elem_t *db, uint16_t *count) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (start_handle == 0 && end_handle == 0) { + *count = 0; + return ESP_GATT_INVALID_HANDLE; + } + + if (db == NULL || count == NULL || *count == 0) { + return ESP_GATT_INVALID_PDU; + } + + uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + return btc_ble_gattc_get_db(conn_hdl, start_handle, end_handle, db, count); +} + + +esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if, + uint16_t conn_id, uint16_t handle, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_READ_CHAR; + arg.read_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.read_char.handle = handle; + arg.read_char.auth_req = auth_req; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_read_by_type (esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t *uuid, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (uuid == NULL) { + return ESP_GATT_ILLEGAL_PARAMETER; + } + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_READ_BY_TYPE; + arg.read_by_type.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.read_by_type.s_handle = start_handle; + arg.read_by_type.e_handle = end_handle; + arg.read_by_type.auth_req = auth_req; + memcpy(&(arg.read_by_type.uuid), uuid, sizeof(esp_bt_uuid_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_READ_MULTIPLE_CHAR; + arg.read_multiple.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.read_multiple.num_attr = read_multi->num_attr; + arg.read_multiple.auth_req = auth_req; + + if (read_multi->num_attr > 0) { + memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t)*read_multi->num_attr); + } else { + LOG_ERROR("%s(), the num_attr should not be 0.", __func__); + return ESP_FAIL; + } + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_READ_MULTIPLE_VARIABLE_CHAR; + arg.read_multiple.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.read_multiple.num_attr = read_multi->num_attr; + arg.read_multiple.auth_req = auth_req; + + if (read_multi->num_attr > 0) { + memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t)*read_multi->num_attr); + } else { + LOG_ERROR("%s(), the num_attr should not be 0.", __func__); + return ESP_FAIL; + } + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if, + uint16_t conn_id, uint16_t handle, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_READ_CHAR_DESCR; + arg.read_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.read_descr.handle = handle; + arg.read_descr.auth_req = auth_req; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_write_char(esp_gatt_if_t gattc_if, + uint16_t conn_id, uint16_t handle, + uint16_t value_len, + uint8_t *value, + esp_gatt_write_type_t write_type, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_WRITE_CHAR; + arg.write_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.write_char.handle = handle; + arg.write_char.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; + arg.write_char.value = value; + arg.write_char.write_type = write_type; + arg.write_char.auth_req = auth_req; + if(write_type == ESP_GATT_WRITE_TYPE_NO_RSP){ + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL); + } + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy, + btc_gattc_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if, + uint16_t conn_id, uint16_t handle, + uint16_t value_len, + uint8_t *value, + esp_gatt_write_type_t write_type, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR; + arg.write_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.write_descr.handle = handle; + arg.write_descr.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; + arg.write_descr.value = value; + arg.write_descr.write_type = write_type; + arg.write_descr.auth_req = auth_req; + if(write_type == ESP_GATT_WRITE_TYPE_NO_RSP){ + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL); + } + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy, + btc_gattc_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if, + uint16_t conn_id, uint16_t handle, + uint16_t offset, + uint16_t value_len, + uint8_t *value, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_PREPARE_WRITE; + arg.prep_write.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.prep_write.handle = handle; + arg.prep_write.offset = offset; + arg.prep_write.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; // length check ? + arg.prep_write.value = value; + arg.prep_write.auth_req = auth_req; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy, + btc_gattc_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if, + uint16_t conn_id, uint16_t handle, + uint16_t offset, + uint16_t value_len, + uint8_t *value, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR; + arg.prep_write_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.prep_write_descr.handle = handle; + arg.prep_write_descr.offset = offset; + arg.prep_write_descr.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; // length check ? + arg.prep_write_descr.value = value; + arg.prep_write_descr.auth_req = auth_req; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy, + btc_gattc_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, bool is_execute) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_EXECUTE_WRITE; + arg.exec_write.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.exec_write.is_execute = is_execute; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, + esp_bd_addr_t server_bda, uint16_t handle) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_REG_FOR_NOTIFY; + arg.reg_for_notify.gattc_if = gattc_if; + memcpy(arg.reg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t)); + arg.reg_for_notify.handle = handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if, + esp_bd_addr_t server_bda, uint16_t handle) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_UNREG_FOR_NOTIFY; + arg.unreg_for_notify.gattc_if = gattc_if; + arg.unreg_for_notify.handle = handle; + memcpy(arg.unreg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_CACHE_REFRESH; + memcpy(arg.cache_refresh.remote_bda, remote_bda, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_cache_clean(esp_bd_addr_t remote_bda) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_CACHE_CLEAN; + memcpy(arg.cache_clean.remote_bda, remote_bda, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_cache_assoc(esp_gatt_if_t gattc_if, esp_bd_addr_t src_addr, esp_bd_addr_t assoc_addr, bool is_assoc) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_CACHE_ASSOC; + arg.cache_assoc.is_assoc = is_assoc; + arg.cache_assoc.gattc_if = gattc_if; + memcpy(arg.cache_assoc.src_addr, src_addr, sizeof(esp_bd_addr_t)); + memcpy(arg.cache_assoc.assoc_addr, assoc_addr, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gattc_cache_get_addr_list(esp_gatt_if_t gattc_if) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ATC_CACHE_GET_ADDR_LIST; + arg.get_addr_list.gattc_if = gattc_if; + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#endif ///GATTC_INCLUDED == TRUE diff --git a/lib/bt/host/bluedroid/api/esp_gatts_api.c b/lib/bt/host/bluedroid/api/esp_gatts_api.c new file mode 100644 index 00000000..66fa5c66 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_gatts_api.c @@ -0,0 +1,442 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "string.h" +#include "esp_gatt_defs.h" +#include "esp_gatts_api.h" +#include "esp_bt_main.h" +#include "btc/btc_manage.h" +#include "btc_gatts.h" +#include "btc_gatt_util.h" +#include "common/bt_target.h" +#include "stack/l2cdefs.h" +#include "stack/l2c_api.h" +#include "gatt_int.h" + +#if (GATTS_INCLUDED == TRUE) +#define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type)) + +static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_val, esp_attr_control_t *control); + + +esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL); +} + +esp_gatts_cb_t esp_ble_gatts_get_callback(void) +{ + return (esp_gatts_cb_t) btc_profile_cb_get(BTC_PID_GATTS); +} + +esp_err_t esp_ble_gatts_app_register(uint16_t app_id) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + //if (app_id < ESP_APP_ID_MIN || app_id > ESP_APP_ID_MAX) { + if (app_id > ESP_APP_ID_MAX) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_APP_REGISTER; + arg.app_reg.app_id = app_id; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_APP_UNREGISTER; + arg.app_unreg.gatts_if = gatts_if; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if, + esp_gatt_srvc_id_t *service_id, uint16_t num_handle) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_CREATE_SERVICE; + arg.create_srvc.gatts_if = gatts_if; + arg.create_srvc.num_handle = num_handle; + memcpy(&arg.create_srvc.service_id, service_id, sizeof(esp_gatt_srvc_id_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db, + esp_gatt_if_t gatts_if, + uint16_t max_nb_attr, + uint8_t srvc_inst_id) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (max_nb_attr > ESP_GATT_ATTR_HANDLE_MAX) { + LOG_ERROR("The number of attribute should not be greater than CONFIG_BT_GATT_MAX_SR_ATTRIBUTES\n"); + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_CREATE_ATTR_TAB; + arg.create_attr_tab.gatts_if = gatts_if; + arg.create_attr_tab.max_nb_attr = max_nb_attr; + arg.create_attr_tab.srvc_inst_id = srvc_inst_id; + arg.create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *)gatts_attr_db; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy, + btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_ADD_INCLUDE_SERVICE; + arg.add_incl_srvc.service_handle = service_handle; + arg.add_incl_srvc.included_service_handle = included_service_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid, + esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val, + esp_attr_control_t *control) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + esp_err_t status; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + /* parameter validation check */ + status = esp_ble_gatts_add_char_desc_param_check(char_val, control); + if (status != ESP_OK){ + return status; + } + + memset(&arg, 0, sizeof(btc_ble_gatts_args_t)); + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_ADD_CHAR; + arg.add_char.service_handle = service_handle; + arg.add_char.perm = perm; + arg.add_char.property = property; + if (char_val != NULL) { + arg.add_char.char_val.attr_max_len = char_val->attr_max_len; + arg.add_char.char_val.attr_len = char_val->attr_len; + arg.add_char.char_val.attr_value = char_val->attr_value; + } + + if (control != NULL) { + arg.add_char.attr_control.auto_rsp = control->auto_rsp; + } + memcpy(&arg.add_char.char_uuid, char_uuid, sizeof(esp_bt_uuid_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy, + btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle, + esp_bt_uuid_t *descr_uuid, + esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val, + esp_attr_control_t *control) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + esp_err_t status; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + /* parameter validation check */ + status = esp_ble_gatts_add_char_desc_param_check(char_descr_val, control); + if (status != ESP_OK){ + return status; + } + + memset(&arg, 0, sizeof(btc_ble_gatts_args_t)); + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR; + arg.add_descr.service_handle = service_handle; + arg.add_descr.perm = perm; + + if (char_descr_val != NULL) { + arg.add_descr.descr_val.attr_max_len = char_descr_val->attr_max_len; + arg.add_descr.descr_val.attr_len = char_descr_val->attr_len; + arg.add_descr.descr_val.attr_value = char_descr_val->attr_value; + } + + if (control != NULL) { + arg.add_descr.attr_control.auto_rsp = control->auto_rsp; + } + memcpy(&arg.add_descr.descr_uuid, descr_uuid, sizeof(esp_bt_uuid_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy, + btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_DELETE_SERVICE; + arg.delete_srvc.service_handle = service_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_start_service(uint16_t service_handle) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_START_SERVICE; + arg.start_srvc.service_handle = service_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_STOP_SERVICE; + arg.stop_srvc.service_handle = service_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, uint16_t attr_handle, + uint16_t value_len, uint8_t *value, bool need_confirm) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_SEND_INDICATE; + arg.send_ind.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id); + arg.send_ind.attr_handle = attr_handle; + arg.send_ind.need_confirm = need_confirm; + arg.send_ind.value_len = value_len; + arg.send_ind.value = value; + if(need_confirm == false){ + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL); + } + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy, + btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id, + esp_gatt_status_t status, esp_gatt_rsp_t *rsp) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_SEND_RESPONSE; + arg.send_rsp.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id); + arg.send_rsp.trans_id = trans_id; + arg.send_rsp.status = status; + arg.send_rsp.rsp = rsp; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy, + btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_SET_ATTR_VALUE; + arg.set_attr_val.handle = attr_handle; + arg.set_attr_val.length = length; + arg.set_attr_val.value = (uint8_t *)value; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy, + btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) { + *length = 0; + return ESP_GATT_INVALID_HANDLE; + } + + return btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value); +} + +esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_OPEN; + arg.open.gatts_if = gatts_if; + arg.open.is_direct = is_direct; + memcpy(&arg.open.remote_bda, remote_bda, sizeof(esp_bd_addr_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_CLOSE; + arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda) +{ + btc_msg_t msg = {0}; + btc_ble_gatts_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_SEND_SERVICE_CHANGE; + arg.send_service_change.gatts_if = gatts_if; + if(remote_bda) { + memcpy(&arg.send_service_change.remote_bda, remote_bda, sizeof(esp_bd_addr_t)); + } else { + memset(arg.send_service_change.remote_bda, 0, sizeof(esp_bd_addr_t)); + } + + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_val, esp_attr_control_t *control) +{ + if ((control != NULL) && ((control->auto_rsp != ESP_GATT_AUTO_RSP) && (control->auto_rsp != ESP_GATT_RSP_BY_APP))){ + LOG_ERROR("Error in %s, line=%d, control->auto_rsp should be set to ESP_GATT_AUTO_RSP or ESP_GATT_RSP_BY_APP\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + + if ((control != NULL) && (control->auto_rsp == ESP_GATT_AUTO_RSP)){ + if (char_val == NULL){ + LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_val should not be NULL here\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } else if (char_val->attr_max_len == 0){ + LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + } + + return ESP_OK; +} + +esp_err_t esp_ble_gatts_show_local_database(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_SHOW_LOCAL_DATABASE; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#endif ///GATTS_INCLUDED diff --git a/lib/bt/host/bluedroid/api/esp_hf_ag_api.c b/lib/bt/host/bluedroid/api/esp_hf_ag_api.c new file mode 100644 index 00000000..6eb6a6b5 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_hf_ag_api.c @@ -0,0 +1,578 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include "bt_common.h" +#include "btc/btc_common.h" +#include "btc/btc_dm.h" +#include "btc_hf_ag.h" +#include "btc/btc_profile_queue.h" +#include "btc/btc_manage.h" +#include "btc/btc_util.h" +#include "bta/bta_ag_api.h" +#include "bta/bta_api.h" +#include "common/bt_target.h" +#include "common/bt_defs.h" +#include "device/bdaddr.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) +#include "esp_bt.h" +#endif +#include "esp_hf_ag_api.h" +#include "esp_err.h" +#include "esp_bt_main.h" +#include "osi/allocator.h" + +#if (BTC_HF_INCLUDED == TRUE) +esp_err_t esp_hf_ag_register_callback(esp_hf_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (callback == NULL) { + return ESP_FAIL; + } + btc_profile_cb_set(BTC_PID_HF, callback); + return ESP_OK; +} + +esp_err_t esp_hf_ag_init(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_INIT_EVT; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_deinit(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_DEINIT_EVT; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_slc_connect(esp_bd_addr_t remote_addr) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CONNECT_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.connect), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_slc_disconnect(esp_bd_addr_t remote_addr) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_DISCONNECT_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.disconnect), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_audio_connect(esp_bd_addr_t remote_addr) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CONNECT_AUDIO_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.connect_audio), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_audio_disconnect(esp_bd_addr_t remote_addr) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_DISCONNECT_AUDIO_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.disconnect_audio), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_vra_control(esp_bd_addr_t remote_addr, esp_hf_vr_state_t value) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_VRA_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + arg.vra_rep.value = value; + memcpy(&(arg.volcon.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_volume_control(esp_bd_addr_t remote_addr, esp_hf_volume_control_target_t type, int volume) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (volume < 0 || volume > 15) { + return ESP_ERR_INVALID_ARG; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_VOLUME_CONTROL_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + arg.volcon.target_type = type; + arg.volcon.volume = volume; + memcpy(&(arg.volcon.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_unknown_at_send(esp_bd_addr_t remote_addr, char *unat) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_UNAT_RESPONSE_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + arg.unat_rep.unat = unat; + memcpy(&(arg.unat_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_cmee_send(esp_bd_addr_t remote_addr, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CME_ERR_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + arg.ext_at.response_code = response_code; + arg.ext_at.error_code = error_code; + memcpy(&(arg.ext_at.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_devices_status_indchange(esp_bd_addr_t remote_addr, + esp_hf_call_status_t call_state, + esp_hf_call_setup_status_t call_setup_state, + esp_hf_network_state_t ntk_state, int signal) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (signal < 0 || signal > 5) { + return ESP_ERR_INVALID_ARG; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_IND_NOTIFICATION_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.ind_change.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.ind_change.call_state = call_state; + arg.ind_change.call_setup_state = call_setup_state; + arg.ind_change.ntk_state = ntk_state; + arg.ind_change.signal = signal; + + /* Switch to BTC context */ + bt_status_t state = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (state == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_ciev_report(esp_bd_addr_t remote_addr, esp_hf_ciev_report_type_t ind_type, int value) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CIEV_REPORT_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.ciev_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.ciev_rep.ind.type = ind_type; + arg.ciev_rep.ind.value = value; + + /* Switch to BTC context */ + bt_status_t state = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (state == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_cind_response(esp_bd_addr_t remote_addr, + esp_hf_call_status_t call_state, + esp_hf_call_setup_status_t call_setup_state, + esp_hf_network_state_t ntk_state, int signal, esp_hf_roaming_status_t roam, int batt_lev, + esp_hf_call_held_status_t call_held_status) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (signal < 0 || signal > 5 || batt_lev < 0 || batt_lev > 5) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CIND_RESPONSE_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.cind_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.cind_rep.call_state = call_state; + arg.cind_rep.call_setup_state = call_setup_state; + arg.cind_rep.ntk_state = ntk_state; + arg.cind_rep.signal = signal; + arg.cind_rep.roam = roam; + arg.cind_rep.batt_lev = batt_lev; + arg.cind_rep.call_held_state = call_held_status; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_cops_response(esp_bd_addr_t remote_addr, char *name) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_COPS_RESPONSE_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.cops_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.cops_rep.name = name; //deep_copy + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_current_call_direction_t dir, + esp_hf_current_call_status_t current_call_state, esp_hf_current_call_mode_t mode, + esp_hf_current_call_mpty_type_t mpty, char *number, esp_hf_call_addr_type_t type) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CLCC_RESPONSE_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.clcc_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + //mandatory args + arg.clcc_rep.index = index; + arg.clcc_rep.dir = dir; + arg.clcc_rep.current_call_state = current_call_state; + arg.clcc_rep.mode = mode; + arg.clcc_rep.mpty = mpty; + // option args + arg.clcc_rep.number = number; //deep_copy + arg.clcc_rep.type = type; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, int number_type, esp_hf_subscriber_service_type_t service_type) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (number == NULL || number_type < 128 || number_type > 175) { + return ESP_ERR_INVALID_ARG; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CNUM_RESPONSE_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.cnum_rep), remote_addr, sizeof(esp_bd_addr_t)); + arg.cnum_rep.number = number; //deep_copy + arg.cnum_rep.number_type = number_type; + arg.cnum_rep.service_type = service_type; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t state) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_INBAND_RING_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.bsir.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.bsir.state = state; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_answer_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_AC_INCALL_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.phone.num_active = num_active; + arg.phone.num_held = num_held; + arg.phone.call_state = call_state; + arg.phone.call_setup_state = call_setup_state; + arg.phone.number = number; //deep_copy + arg.phone.call_addr_type = call_addr_type; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_reject_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_RJ_INCALL_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.phone.num_active = num_active; + arg.phone.num_held = num_held; + arg.phone.call_state = call_state; + arg.phone.call_setup_state = call_setup_state; + arg.phone.number = number; //deep_copy + arg.phone.call_addr_type = call_addr_type; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_end_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_END_CALL_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.phone.num_active = num_active; + arg.phone.num_held = num_held; + arg.phone.call_state = call_state; + arg.phone.call_setup_state = call_setup_state; + arg.phone.number = number; //deep_copy + arg.phone.call_addr_type = call_addr_type; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_out_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_OUT_CALL_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.phone.num_active = num_active; + arg.phone.num_held = num_held; + arg.phone.call_state = call_state; + arg.phone.call_setup_state = call_setup_state; + arg.phone.number = number; //deep_copy + arg.phone.call_addr_type = call_addr_type; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), + btc_hf_arg_deep_copy, btc_hf_arg_deep_free); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_REGISTER_DATA_CALLBACK_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + arg.reg_data_cb.recv = recv; + arg.reg_data_cb.send = send; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +#if (BTM_SCO_HCI_INCLUDED == TRUE) +esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_REQUEST_PKT_STAT_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + arg.pkt_sync_hd.sync_conn_handle = sync_conn_handle; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +void esp_hf_ag_outgoing_data_ready(void) +{ + btc_hf_ci_sco_data(); +} +#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */ + +#endif // BTC_HF_INCLUDED diff --git a/lib/bt/host/bluedroid/api/esp_hf_client_api.c b/lib/bt/host/bluedroid/api/esp_hf_client_api.c new file mode 100644 index 00000000..9909f442 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_hf_client_api.c @@ -0,0 +1,561 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common/bt_target.h" +#include <string.h> +#include "esp_err.h" +#include "esp_hf_client_api.h" +#include "esp_bt_main.h" +#include "btc/btc_manage.h" +#include "btc_hf_client.h" +#include "bta/bta_api.h" +#include "bta/bta_hf_client_api.h" + +#if BTC_HF_CLIENT_INCLUDED +esp_err_t esp_hf_client_register_callback(esp_hf_client_cb_t callback) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_HF_CLIENT, callback); + return ESP_OK; +} + +esp_err_t esp_hf_client_init(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_INIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_deinit(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_DEINIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_connect(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_hf_client_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_CONNECT_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + + /* Switch to BTC context */ + memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_disconnect(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_hf_client_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_DISCONNECT_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + + /* Switch to BTC context */ + memcpy(&(arg.disconnect), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_connect_audio(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_hf_client_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_CONNECT_AUDIO_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + + /* Switch to BTC context */ + memcpy(&(arg.connect_audio), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_disconnect_audio(esp_bd_addr_t remote_bda) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + bt_status_t stat; + btc_hf_client_args_t arg; + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_DISCONNECT_AUDIO_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + + /* Switch to BTC context */ + memcpy(&(arg.disconnect_audio), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + + +esp_err_t esp_hf_client_start_voice_recognition(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_START_VOICE_RECOGNITION_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_stop_voice_recognition(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_STOP_VOICE_RECOGNITION_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_volume_update(esp_hf_volume_control_target_t type, int volume) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_VOLUME_UPDATE_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.volume_update.type = type; + arg.volume_update.volume = volume; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_dial(const char *number) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + if (number != NULL && strlen(number) > ESP_BT_HF_CLIENT_NUMBER_LEN) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_DIAL_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + if (number != NULL) { + strcpy(arg.dial.number, number); + } else { + arg.dial.number[0] = '\0'; + } + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_dial_memory(int location) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_DIAL_MEMORY_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.dial_memory.location = location; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_send_chld_cmd(esp_hf_chld_type_t chld, int idx) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_SEND_CHLD_CMD_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.chld.type = chld; + arg.chld.idx = idx; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_send_btrh_cmd(esp_hf_btrh_cmd_t btrh) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_SEND_BTRH_CMD_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.btrh.cmd = btrh; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_answer_call(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_ANSWER_CALL_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_reject_call(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_REJECT_CALL_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_query_current_calls(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_QUERY_CURRENT_CALLS_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_query_current_operator_name(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_QUERY_CURRENT_OPERATOR_NAME_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_retrieve_subscriber_info(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_RETRIEVE_SUBSCRIBER_INFO_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_send_dtmf(char code) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_SEND_DTMF_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.send_dtmf.code = code; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_send_xapl(char *information, uint32_t features) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (information == NULL || strlen(information) != ESP_BT_HF_AT_SEND_XAPL_LEN) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_SEND_XAPL_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + strcpy(arg.send_xapl.information, information); + arg.send_xapl.features = features; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_send_iphoneaccev(uint32_t bat_level, bool docked) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (bat_level > 9) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + btc_hf_client_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_SEND_IPHONEACCEV_EVT; + + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.send_iphoneaccev.bat_level = bat_level; + arg.send_iphoneaccev.docked = docked; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + + +esp_err_t esp_hf_client_request_last_voice_tag_number(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_REQUEST_LAST_VOICE_TAG_NUMBER_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_send_nrec(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_SEND_NREC_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv, + esp_hf_client_outgoing_data_cb_t send) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT; + + btc_hf_client_args_t arg; + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.reg_data_cb.recv = recv; + arg.reg_data_cb.send = send; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +#if (BTM_SCO_HCI_INCLUDED == TRUE) +esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_REQUEST_PKT_STAT_EVT; + + btc_hf_client_args_t arg; + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.pkt_sync_hd.sync_conn_handle = sync_conn_handle; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +void esp_hf_client_outgoing_data_ready(void) +{ + BTA_HfClientCiData(); +} + +void esp_hf_client_pcm_resample_init(uint32_t src_sps, uint32_t bits, uint32_t channels) +{ + BTA_DmPcmInitSamples(src_sps, bits, channels); +} + +void esp_hf_client_pcm_resample_deinit(void) +{ + BTA_DmPcmDeinitSamples(); +} + +int32_t esp_hf_client_pcm_resample(void *src, uint32_t in_bytes, void *dst) +{ + return BTA_DmPcmResample(src, in_bytes, dst); +} + +#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */ + +#endif /* BTC_HF_CLIENT_INCLUDED */ diff --git a/lib/bt/host/bluedroid/api/esp_hidd_api.c b/lib/bt/host/bluedroid/api/esp_hidd_api.c new file mode 100644 index 00000000..2906e7a8 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_hidd_api.c @@ -0,0 +1,170 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: Blake Felt + */ + +#include <string.h> +#include "esp_err.h" +#include "esp_bt_main.h" +#include "btc/btc_manage.h" +#include "btc_hd.h" +#include "esp_hidd_api.h" + +#if (defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE) + +esp_err_t esp_bt_hid_device_register_callback(esp_hd_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_HD, callback); + return ESP_OK; +} + +esp_err_t esp_bt_hid_device_init(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_INIT_EVT; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_deinit(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_DEINIT_EVT; + + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t* app_param, esp_hidd_qos_param_t* in_qos, esp_hidd_qos_param_t* out_qos) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + btc_hidd_args_t args; + memset(&args, 0, sizeof(btc_hidd_args_t)); + args.register_app.app_param = app_param; + args.register_app.in_qos = in_qos; + args.register_app.out_qos = out_qos; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_REGISTER_APP_EVT; + + bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_unregister_app(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_UNREGISTER_APP_EVT; + + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + btc_hidd_args_t args; + memset(&args, 0, sizeof(btc_hidd_args_t)); + memcpy(args.connect.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_CONNECT_EVT; + + bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_disconnect(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_DISCONNECT_EVT; + + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t* data) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_SEND_REPORT_EVT; + + btc_hidd_args_t args; + memset(&args, 0, sizeof(btc_hidd_args_t)); + args.send_report.type = type; + args.send_report.id = id; + args.send_report.len = len; + args.send_report.data = data; + + bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), + btc_hd_arg_deep_copy, btc_hd_cb_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_REPORT_ERROR_EVT; + + btc_hidd_args_t args; + memset(&args, 0, sizeof(btc_hidd_args_t)); + args.error = error; + + bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_device_virtual_cable_unplug(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HD; + msg.act = BTC_HD_UNPLUG_EVT; + + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +#endif /* defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE */ diff --git a/lib/bt/host/bluedroid/api/esp_hidh_api.c b/lib/bt/host/bluedroid/api/esp_hidh_api.c new file mode 100644 index 00000000..f9959c39 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_hidh_api.c @@ -0,0 +1,250 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: Blake Felt + */ + +#include "btc/btc_manage.h" +#include "btc_hh.h" +#include "esp_bt_main.h" +#include "esp_err.h" +#include "esp_hidh_api.h" +#include <string.h> + +#if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE) + +esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_HH, callback); + return ESP_OK; +} + +esp_err_t esp_bt_hid_host_init(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_INIT_EVT; + + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_deinit(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_DEINIT_EVT; + + bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_CONNECT_EVT; + + memcpy(arg.connect.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_DISCONNECT_EVT; + + memcpy(arg.disconnect.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_UNPLUG_EVT; + + memcpy(arg.unplug.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_SET_INFO_EVT; + + memcpy(arg.set_info.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + arg.set_info.hid_info = hid_info; + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), + btc_hh_arg_deep_copy, btc_hh_cb_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_GET_PROTO_EVT; + + memcpy(arg.get_protocol.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_SET_PROTO_EVT; + + memcpy(arg.set_protocol.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + arg.set_protocol.protocol_mode = protocol_mode; + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_GET_IDLE_EVT; + + memcpy(arg.get_idle.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_SET_IDLE_EVT; + + memcpy(arg.set_idle.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + arg.set_idle.idle_time = idle_time; + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t report_id, + int buffer_size) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_GET_REPORT_EVT; + + memcpy(arg.get_report.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + arg.get_report.report_type = report_type; + arg.get_report.report_id = report_id; + arg.get_report.buffer_size = buffer_size; + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t *report, + size_t len) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_SET_REPORT_EVT; + + memcpy(arg.set_report.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + arg.set_report.report_type = report_type; + arg.set_report.len = len; + arg.set_report.report = report; + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), + btc_hh_arg_deep_copy, btc_hh_cb_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + btc_msg_t msg; + btc_hidh_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HH; + msg.act = BTC_HH_SEND_DATA_EVT; + + memcpy(arg.send_data.bd_addr, bd_addr, sizeof(esp_bd_addr_t)); + arg.send_data.len = len; + arg.send_data.data = data; + + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), + btc_hh_arg_deep_copy, btc_hh_cb_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +#endif /* defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE */ diff --git a/lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c b/lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c new file mode 100644 index 00000000..c78d6f8d --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "esp_bt_main.h" +#include "btc/btc_manage.h" + +#include "btc_l2cap.h" +#include "esp_l2cap_bt_api.h" +#include "common/bt_target.h" + +#if (defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE) + +esp_err_t esp_bt_l2cap_register_callback(esp_bt_l2cap_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_L2CAP, callback); + return ESP_OK; +} + +esp_err_t esp_bt_l2cap_init(void) +{ + btc_msg_t msg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_INIT; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_l2cap_deinit(void) +{ + btc_msg_t msg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_UNINIT; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_l2cap_connect(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t remote_psm, esp_bd_addr_t peer_bd_addr) +{ + btc_msg_t msg; + btc_l2cap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_CONNECT; + + arg.connect.sec_mask = (cntl_flag & 0xffff); + arg.connect.remote_psm = remote_psm; + memcpy(arg.connect.peer_bd_addr, peer_bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_l2cap_start_srv(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t local_psm) +{ + btc_msg_t msg; + btc_l2cap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_START_SRV; + + arg.start_srv.sec_mask = (cntl_flag & 0xffff); + arg.start_srv.local_psm = local_psm; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_l2cap_stop_all_srv(void) +{ + btc_msg_t msg; + btc_l2cap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_STOP_SRV; + + arg.stop_srv.psm = BTC_L2CAP_INVALID_PSM; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm) +{ + btc_msg_t msg; + btc_l2cap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_STOP_SRV; + + arg.stop_srv.psm = local_psm; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_bt_l2cap_vfs_register(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + return btc_l2cap_vfs_register(); +} + +esp_err_t esp_bt_l2cap_vfs_unregister(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + return btc_l2cap_vfs_unregister(); +} + +#endif ///defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE diff --git a/lib/bt/host/bluedroid/api/esp_sdp_api.c b/lib/bt/host/bluedroid/api/esp_sdp_api.c new file mode 100644 index 00000000..c47c5ba5 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_sdp_api.c @@ -0,0 +1,130 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "esp_bt_main.h" +#include "btc/btc_manage.h" + +#include "btc_sdp.h" +#include "esp_sdp_api.h" +#include "common/bt_target.h" + +#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE) + +esp_err_t esp_sdp_register_callback(esp_sdp_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_SDP, callback); + return ESP_OK; +} + +esp_err_t esp_sdp_init(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + bt_status_t stat; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SDP; + msg.act = BTC_SDP_ACT_INIT; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_sdp_deinit(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + bt_status_t stat; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SDP; + msg.act = BTC_SDP_ACT_DEINIT; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_sdp_search_record(esp_bd_addr_t bd_addr, esp_bt_uuid_t uuid) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + bt_status_t stat; + btc_sdp_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SDP; + msg.act = BTC_SDP_ACT_SEARCH; + + memset(&arg, 0, sizeof(btc_sdp_args_t)); + memcpy(arg.search.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + arg.search.sdp_uuid.len = uuid.len; + memcpy(&arg.search.sdp_uuid.uu, &uuid.uuid, sizeof(uuid.uuid)); + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (record == NULL || record->hdr.service_name_length > ESP_SDP_SERVER_NAME_MAX + || strlen(record->hdr.service_name)+1 != record->hdr.service_name_length) { + LOG_ERROR("Invalid server name!\n"); + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + bt_status_t stat; + btc_sdp_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SDP; + msg.act = BTC_SDP_ACT_CREATE_RECORD; + + memset(&arg, 0, sizeof(btc_sdp_args_t)); + arg.creat_record.record = (bluetooth_sdp_record *)record; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), + btc_sdp_arg_deep_copy, btc_sdp_arg_deep_free); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_sdp_remove_record(int record_handle) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + btc_msg_t msg; + bt_status_t stat; + btc_sdp_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SDP; + msg.act = BTC_SDP_ACT_REMOVE_RECORD; + + arg.remove_record.record_handle = record_handle; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE diff --git a/lib/bt/host/bluedroid/api/esp_spp_api.c b/lib/bt/host/bluedroid/api/esp_spp_api.c new file mode 100644 index 00000000..fce84be0 --- /dev/null +++ b/lib/bt/host/bluedroid/api/esp_spp_api.c @@ -0,0 +1,255 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <string.h> + +#include "esp_bt_main.h" +#include "btc/btc_manage.h" + +#include "btc_spp.h" +#include "esp_spp_api.h" +#include "common/bt_target.h" + +#if (defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE) + +static const uint8_t UUID_SPP[16] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB + }; +static tSDP_UUID sdp_uuid; + +esp_err_t esp_spp_register_callback(esp_spp_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (callback == NULL) { + return ESP_FAIL; + } + + btc_profile_cb_set(BTC_PID_SPP, callback); + return ESP_OK; +} + + +esp_err_t esp_spp_init(esp_spp_mode_t mode) +{ + esp_spp_cfg_t bt_spp_cfg = { + .mode = mode, + .enable_l2cap_ertm = true, + .tx_buffer_size = ESP_SPP_MAX_TX_BUFFER_SIZE, + }; + + return esp_spp_enhanced_init(&bt_spp_cfg); +} + +esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (cfg->mode == ESP_SPP_MODE_VFS && (cfg->tx_buffer_size < ESP_SPP_MIN_TX_BUFFER_SIZE || + cfg->tx_buffer_size > ESP_SPP_MAX_TX_BUFFER_SIZE)) { + LOG_WARN("Invalid tx buffer size"); + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_INIT; + + arg.init.mode = cfg->mode; + arg.init.enable_l2cap_ertm = cfg->enable_l2cap_ertm; + arg.init.tx_buffer_size = cfg->tx_buffer_size; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_spp_deinit(void) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_UNINIT; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr) +{ + sdp_uuid.len = 16; + memcpy(sdp_uuid.uu.uuid128, UUID_SPP, sizeof(sdp_uuid.uu.uuid128)); + + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_START_DISCOVERY; + + memcpy(arg.start_discovery.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + arg.start_discovery.num_uuid = 1; + arg.start_discovery.p_uuid_list = &sdp_uuid; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), + btc_spp_arg_deep_copy, btc_spp_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask, + esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (sec_mask != ESP_SPP_SEC_NONE && + sec_mask != ESP_SPP_SEC_AUTHENTICATE && + sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) { + LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHENTICATE" + "or (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) only\n"); + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_CONNECT; + + arg.connect.sec_mask = sec_mask; + arg.connect.role = role; + arg.connect.remote_scn = remote_scn; + memcpy(arg.connect.peer_bd_addr, peer_bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_spp_disconnect(uint32_t handle) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_DISCONNECT; + + arg.disconnect.handle = handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, + esp_spp_role_t role, uint8_t local_scn, const char *name) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (name == NULL || strlen(name) > ESP_SPP_SERVER_NAME_MAX) { + LOG_ERROR("Invalid server name!\n"); + return ESP_ERR_INVALID_ARG; + } + + if (sec_mask != ESP_SPP_SEC_NONE && + sec_mask != ESP_SPP_SEC_AUTHENTICATE && + sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) && + sec_mask != ESP_SPP_SEC_IN_16_DIGITS && + sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) && + sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) { + LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHENTICATE," + "(ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)," + "ESP_SPP_SEC_IN_16_DIGITS, (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE), or" + "(ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) only\n"); + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_START_SRV; + + arg.start_srv.sec_mask = sec_mask; + arg.start_srv.role = role; + arg.start_srv.local_scn = local_scn; + arg.start_srv.max_session = ESP_SPP_MAX_SESSION; + strcpy(arg.start_srv.name, name); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_spp_stop_srv(void) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_STOP_SRV; + arg.stop_srv.scn = BTC_SPP_INVALID_SCN; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_spp_stop_srv_scn(uint8_t scn) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if ((scn == 0) || (scn >= PORT_MAX_RFC_PORTS)) { + LOG_ERROR("Invalid SCN!\n"); + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_STOP_SRV; + arg.stop_srv.scn = scn; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (len <= 0 || p_data == NULL) { + LOG_ERROR("Invalid data or len!\n"); + return ESP_ERR_INVALID_ARG; + } + + return spp_send_data_to_btc(handle, len, p_data, ESP_SPP_MODE_CB); +} + +esp_err_t esp_spp_vfs_register(void) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_VFS_REGISTER; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_spp_vfs_unregister(void) +{ + btc_msg_t msg; + btc_spp_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_SPP; + msg.act = BTC_SPP_ACT_VFS_UNREGISTER; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE diff --git a/lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h b/lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h new file mode 100644 index 00000000..7020750c --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h @@ -0,0 +1,463 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_A2DP_API_H__ +#define __ESP_A2DP_API_H__ + +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Media codec types supported by A2DP. + */ +#define ESP_A2D_MCT_SBC (0) /*!< SBC */ +#define ESP_A2D_MCT_M12 (0x01) /*!< MPEG-1, 2 Audio */ +#define ESP_A2D_MCT_M24 (0x02) /*!< MPEG-2, 4 AAC */ +#define ESP_A2D_MCT_ATRAC (0x04) /*!< ATRAC family */ +#define ESP_A2D_MCT_NON_A2DP (0xff) /*!< NON-A2DP */ +typedef uint8_t esp_a2d_mct_t; + +/** + * @brief Protocol service capabilities. This value is a mask. + */ +#define ESP_A2D_PSC_DELAY_RPT (1<<0) /*!< Delay Report */ +typedef uint16_t esp_a2d_psc_t; + +/** + * @brief A2DP media codec capabilities union + */ +typedef struct { + esp_a2d_mct_t type; /*!< A2DP media codec type */ +#define ESP_A2D_CIE_LEN_SBC (4) +#define ESP_A2D_CIE_LEN_M12 (4) +#define ESP_A2D_CIE_LEN_M24 (6) +#define ESP_A2D_CIE_LEN_ATRAC (7) + union { + uint8_t sbc[ESP_A2D_CIE_LEN_SBC]; /*!< SBC codec capabilities */ + uint8_t m12[ESP_A2D_CIE_LEN_M12]; /*!< MPEG-1,2 audio codec capabilities */ + uint8_t m24[ESP_A2D_CIE_LEN_M24]; /*!< MPEG-2, 4 AAC audio codec capabilities */ + uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC]; /*!< ATRAC family codec capabilities */ + } cie; /*!< A2DP codec information element */ +} __attribute__((packed)) esp_a2d_mcc_t; + +/** + * @brief Bluetooth A2DP connection states + */ +typedef enum { + ESP_A2D_CONNECTION_STATE_DISCONNECTED = 0, /*!< connection released */ + ESP_A2D_CONNECTION_STATE_CONNECTING, /*!< connecting remote device */ + ESP_A2D_CONNECTION_STATE_CONNECTED, /*!< connection established */ + ESP_A2D_CONNECTION_STATE_DISCONNECTING /*!< disconnecting remote device */ +} esp_a2d_connection_state_t; + +/** + * @brief Bluetooth A2DP disconnection reason + */ +typedef enum { + ESP_A2D_DISC_RSN_NORMAL = 0, /*!< Finished disconnection that is initiated by local or remote device */ + ESP_A2D_DISC_RSN_ABNORMAL /*!< Abnormal disconnection caused by signal loss */ +} esp_a2d_disc_rsn_t; + +/** + * @brief Bluetooth A2DP datapath states + */ +typedef enum { + ESP_A2D_AUDIO_STATE_SUSPEND = 0, /*!< audio stream datapath suspended by remote device */ + ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */ + ESP_A2D_AUDIO_STATE_STOPPED = ESP_A2D_AUDIO_STATE_SUSPEND, /*!< @note Deprecated */ + ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = ESP_A2D_AUDIO_STATE_SUSPEND, /*!< @note Deprecated */ +} esp_a2d_audio_state_t; + +/** + * @brief A2DP media control command acknowledgement code + */ +typedef enum { + ESP_A2D_MEDIA_CTRL_ACK_SUCCESS = 0, /*!< media control command is acknowledged with success */ + ESP_A2D_MEDIA_CTRL_ACK_FAILURE, /*!< media control command is acknowledged with failure */ + ESP_A2D_MEDIA_CTRL_ACK_BUSY, /*!< media control command is rejected, as previous command is not yet acknowledged */ +} esp_a2d_media_ctrl_ack_t; + +/** + * @brief A2DP media control commands + */ +typedef enum { + ESP_A2D_MEDIA_CTRL_NONE = 0, /*!< Not for application use, use inside stack only. */ + ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY, /*!< check whether AVDTP is connected, only used in A2DP source */ + ESP_A2D_MEDIA_CTRL_START, /*!< command to set up media transmission channel */ + ESP_A2D_MEDIA_CTRL_SUSPEND, /*!< command to suspend media transmission */ + ESP_A2D_MEDIA_CTRL_STOP, /*!< @note Deprecated, Please use ESP_A2D_MEDIA_CTRL_SUSPEND */ +} esp_a2d_media_ctrl_t; + +/** + * @brief Bluetooth A2DP Initiation states + */ +typedef enum { + ESP_A2D_DEINIT_SUCCESS = 0, /*!< A2DP profile deinit successful event */ + ESP_A2D_INIT_SUCCESS /*!< A2DP profile deinit successful event */ +} esp_a2d_init_state_t; + +/** + * @brief Bluetooth A2DP set delay report value states + */ +typedef enum { + ESP_A2D_SET_SUCCESS = 0, /*!< A2DP profile set delay report value successful */ + ESP_A2D_SET_INVALID_PARAMS /*!< A2DP profile set delay report value is invalid parameter */ +} esp_a2d_set_delay_value_state_t; + +/** + * @brief A2DP callback events + */ +typedef enum { + ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */ + ESP_A2D_AUDIO_STATE_EVT, /*!< audio stream transmission state changed event */ + ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured, only used for A2DP SINK */ + ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */ + ESP_A2D_PROF_STATE_EVT, /*!< indicate a2dp init&deinit complete */ + ESP_A2D_SNK_PSC_CFG_EVT, /*!< protocol service capabilities configured,only used for A2DP SINK */ + ESP_A2D_SNK_SET_DELAY_VALUE_EVT, /*!< indicate a2dp sink set delay report value complete, only used for A2DP SINK */ + ESP_A2D_SNK_GET_DELAY_VALUE_EVT, /*!< indicate a2dp sink get delay report value complete, only used for A2DP SINK */ + ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT, /*!< report delay value, only used for A2DP SRC */ +} esp_a2d_cb_event_t; + +/** + * @brief A2DP state callback parameters + */ +typedef union { + /** + * @brief ESP_A2D_CONNECTION_STATE_EVT + */ + struct a2d_conn_stat_param { + esp_a2d_connection_state_t state; /*!< one of values from esp_a2d_connection_state_t */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + esp_a2d_disc_rsn_t disc_rsn; /*!< reason of disconnection for "DISCONNECTED" */ + } conn_stat; /*!< A2DP connection status */ + + /** + * @brief ESP_A2D_AUDIO_STATE_EVT + */ + struct a2d_audio_stat_param { + esp_a2d_audio_state_t state; /*!< one of the values from esp_a2d_audio_state_t */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + } audio_stat; /*!< audio stream playing state */ + + /** + * @brief ESP_A2D_AUDIO_CFG_EVT + */ + struct a2d_audio_cfg_param { + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */ + } audio_cfg; /*!< media codec configuration information */ + + /** + * @brief ESP_A2D_MEDIA_CTRL_ACK_EVT + */ + struct media_ctrl_stat_param { + esp_a2d_media_ctrl_t cmd; /*!< media control commands to acknowledge */ + esp_a2d_media_ctrl_ack_t status; /*!< acknowledgement to media control commands */ + } media_ctrl_stat; /*!< status in acknowledgement to media control commands */ + + /** + * @brief ESP_A2D_PROF_STATE_EVT + */ + struct a2d_prof_stat_param { + esp_a2d_init_state_t init_state; /*!< a2dp profile state param */ + } a2d_prof_stat; /*!< status to indicate a2d prof init or deinit */ + + /** + * @brief ESP_A2D_SNK_PSC_CFG_EVT + */ + struct a2d_psc_cfg_param { + esp_a2d_psc_t psc_mask; /*!< protocol service capabilities configured */ + } a2d_psc_cfg_stat; /*!< status to indicate protocol service capabilities configured */ + + /** + * @brief ESP_A2D_SNK_SET_DELAY_VALUE_EVT + */ + struct a2d_set_stat_param { + esp_a2d_set_delay_value_state_t set_state; /*!< a2dp profile state param */ + uint16_t delay_value; /*!< delay report value */ + } a2d_set_delay_value_stat; /*!< A2DP sink set delay report value status */ + + /** + * @brief ESP_A2D_SNK_GET_DELAY_VALUE_EVT + */ + struct a2d_get_stat_param { + uint16_t delay_value; /*!< delay report value */ + } a2d_get_delay_value_stat; /*!< A2DP sink get delay report value status */ + + /** + * @brief ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT + */ + struct a2d_report_delay_stat_param { + uint16_t delay_value; /*!< delay report value */ + } a2d_report_delay_value_stat; /*!< A2DP source received sink report value status */ + +} esp_a2d_cb_param_t; + +/** + * @brief A2DP profile callback function type + * + * @param event : Event type + * + * @param param : Pointer to callback parameter + */ +typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); + +/** + * @brief A2DP sink data callback function + * + * @param[in] buf : pointer to the data received from A2DP source device and is PCM format decoded from SBC decoder; + * buf references to a static memory block and can be overwritten by upcoming data + * + * @param[in] len : size(in bytes) in buf + */ +typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len); + +/** + * @brief A2DP source data read callback function + * + * @param[in] buf : buffer to be filled with PCM data stream from higher layer + * + * @param[in] len : size(in bytes) of data block to be copied to buf. -1 is an indication to user + * that data buffer shall be flushed + * + * @return size of bytes read successfully, if the argument len is -1, this value is ignored. + * + */ +typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len); + +/** + * @brief Register application callback function to A2DP module. This function should be called + * only after esp_bluedroid_enable() completes successfully, used by both A2DP source + * and sink. + * + * @param[in] callback: A2DP event callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: if callback is a NULL function pointer + * + */ +esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback); + + +/** + * @brief Register A2DP sink data output function; For now the output is PCM data stream decoded + * from SBC format. This function should be called only after esp_bluedroid_enable() + * completes successfully, used only by A2DP sink. The callback is invoked in the context + * of A2DP sink task whose stack size is configurable through menuconfig. + * + * @param[in] callback: A2DP sink data callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: if callback is a NULL function pointer + * + */ +esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback); + + +/** + * + * @brief Initialize the bluetooth A2DP sink module. This function should be called + * after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT + * with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently. + * If you want to use AVRC together, you should initiate AVRC first. This + * function should be called after esp_bluedroid_enable() completes successfully. + * + * @return + * - ESP_OK: if the initialization request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_init(void); + + +/** + * + * @brief De-initialize for A2DP sink module. This function + * should be called only after esp_bluedroid_enable() completes successfully, + * and ESP_A2D_PROF_STATE_EVT with ESP_A2D_DEINIT_SUCCESS will reported to APP layer. + * + * @return + * - ESP_OK: if the deinitialization request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_deinit(void); + + +/** + * + * @brief Connect to remote bluetooth A2DP source device. This API must be called after + * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: connect request is sent to lower layer successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda); + + +/** + * + * @brief Disconnect from the remote A2DP source device. This API must be called after + * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: disconnect request is sent to lower layer successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda); + +/** + * + * @brief Set delay reporting value. The delay value of sink is caused by buffering (including + * protocol stack and application layer), decoding and rendering. The default delay + * value is 120ms, if the set value is less than 120ms, the setting will fail. This API + * must be called after esp_a2d_sink_init() and before esp_a2d_sink_deinit(). + * + * @param[in] delay_value: reporting value is in 1/10 millisecond + * + * @return + * - ESP_OK: delay value is sent to lower layer successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value); + +/** + * + * @brief Get delay reporting value. This API must be called after + * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). + * + * @return + * - ESP_OK: if the request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_get_delay_value(void); + + +/** + * + * @brief Media control commands. This API can be used for both A2DP sink and source + * and must be called after esp_a2d_sink_init() and before esp_a2d_sink_deinit(). + * + * @param[in] ctrl: control commands for A2DP data channel + * + * @return + * - ESP_OK: control command is sent to lower layer successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl); + + +/** + * + * @brief Initialize the bluetooth A2DP source module. A2DP can work independently. + * If you want to use AVRC together, you should initiate AVRC first. This function should be called + * after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT + * with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently. + * If you want to use AVRC together, you should initiate AVRC first. + * + * @return + * - ESP_OK: if the initialization request is sent to lower layer successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_source_init(void); + + +/** + * + * @brief De-initialize for A2DP source module. This function + * should be called only after esp_bluedroid_enable() completes successfully, + * and ESP_A2D_PROF_STATE_EVT with ESP_A2D_DEINIT_SUCCESS will reported to APP layer. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_source_deinit(void); + + +/** + * @brief Register A2DP source data input function. For now, the input shoule be PCM data stream. + * This function should be called only after esp_bluedroid_enable() completes + * successfully. The callback is invoked in the context of A2DP source task whose + * stack size is configurable through menuconfig. + * + * @param[in] callback: A2DP source data callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: if callback is a NULL function pointer + * + */ +esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback); + + +/** + * + * @brief Connect to remote A2DP sink device. This API must be called + * after esp_a2d_source_init() and before esp_a2d_source_deinit(). + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: connect request is sent to lower layer successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda); + + +/** + * + * @brief Disconnect from the remote A2DP sink device. This API must be called + * after esp_a2d_source_init() and before esp_a2d_source_deinit(). + * + * @param[in] remote_bda: remote bluetooth device address + * @return + * - ESP_OK: disconnect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda); + +#ifdef __cplusplus +} +#endif + + +#endif /* __ESP_A2DP_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h b/lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h new file mode 100644 index 00000000..f226577e --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h @@ -0,0 +1,736 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_AVRC_API_H__ +#define __ESP_AVRC_API_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_AVRC_TRANS_LABEL_MAX 15 /*!< max transaction label */ + +/// AVRC feature bit mask +typedef enum { + ESP_AVRC_FEAT_RCTG = 0x0001, /*!< remote control target */ + ESP_AVRC_FEAT_RCCT = 0x0002, /*!< remote control controller */ + ESP_AVRC_FEAT_VENDOR = 0x0008, /*!< remote control vendor dependent commands */ + ESP_AVRC_FEAT_BROWSE = 0x0010, /*!< use browsing channel */ + ESP_AVRC_FEAT_META_DATA = 0x0040, /*!< remote control metadata transfer command/response */ + ESP_AVRC_FEAT_ADV_CTRL = 0x0200, /*!< remote control advanced control command/response */ +} esp_avrc_features_t; + +/// AVRC supported features flag retrieved in SDP record +typedef enum { + ESP_AVRC_FEAT_FLAG_CAT1 = 0x0001, /*!< category 1 */ + ESP_AVRC_FEAT_FLAG_CAT2 = 0x0002, /*!< category 2 */ + ESP_AVRC_FEAT_FLAG_CAT3 = 0x0004, /*!< category 3 */ + ESP_AVRC_FEAT_FLAG_CAT4 = 0x0008, /*!< category 4 */ + ESP_AVRC_FEAT_FLAG_BROWSING = 0x0040, /*!< browsing */ + ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE_PROP = 0x0080, /*!< Cover Art GetImageProperties */ + ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE = 0x0100, /*!< Cover Art GetImage */ + ESP_AVRC_FEAT_FLAG_COVER_ART_GET_LINKED_THUMBNAIL = 0x0200, /*!< Cover Art GetLinkedThumbnail */ +} esp_avrc_feature_flag_t; + +/// AVRC passthrough command code +typedef enum { + ESP_AVRC_PT_CMD_SELECT = 0x00, /*!< select */ + ESP_AVRC_PT_CMD_UP = 0x01, /*!< up */ + ESP_AVRC_PT_CMD_DOWN = 0x02, /*!< down */ + ESP_AVRC_PT_CMD_LEFT = 0x03, /*!< left */ + ESP_AVRC_PT_CMD_RIGHT = 0x04, /*!< right */ + ESP_AVRC_PT_CMD_RIGHT_UP = 0x05, /*!< right-up */ + ESP_AVRC_PT_CMD_RIGHT_DOWN = 0x06, /*!< right-down */ + ESP_AVRC_PT_CMD_LEFT_UP = 0x07, /*!< left-up */ + ESP_AVRC_PT_CMD_LEFT_DOWN = 0x08, /*!< left-down */ + ESP_AVRC_PT_CMD_ROOT_MENU = 0x09, /*!< root menu */ + ESP_AVRC_PT_CMD_SETUP_MENU = 0x0A, /*!< setup menu */ + ESP_AVRC_PT_CMD_CONT_MENU = 0x0B, /*!< contents menu */ + ESP_AVRC_PT_CMD_FAV_MENU = 0x0C, /*!< favorite menu */ + ESP_AVRC_PT_CMD_EXIT = 0x0D, /*!< exit */ + ESP_AVRC_PT_CMD_0 = 0x20, /*!< 0 */ + ESP_AVRC_PT_CMD_1 = 0x21, /*!< 1 */ + ESP_AVRC_PT_CMD_2 = 0x22, /*!< 2 */ + ESP_AVRC_PT_CMD_3 = 0x23, /*!< 3 */ + ESP_AVRC_PT_CMD_4 = 0x24, /*!< 4 */ + ESP_AVRC_PT_CMD_5 = 0x25, /*!< 5 */ + ESP_AVRC_PT_CMD_6 = 0x26, /*!< 6 */ + ESP_AVRC_PT_CMD_7 = 0x27, /*!< 7 */ + ESP_AVRC_PT_CMD_8 = 0x28, /*!< 8 */ + ESP_AVRC_PT_CMD_9 = 0x29, /*!< 9 */ + ESP_AVRC_PT_CMD_DOT = 0x2A, /*!< dot */ + ESP_AVRC_PT_CMD_ENTER = 0x2B, /*!< enter */ + ESP_AVRC_PT_CMD_CLEAR = 0x2C, /*!< clear */ + ESP_AVRC_PT_CMD_CHAN_UP = 0x30, /*!< channel up */ + ESP_AVRC_PT_CMD_CHAN_DOWN = 0x31, /*!< channel down */ + ESP_AVRC_PT_CMD_PREV_CHAN = 0x32, /*!< previous channel */ + ESP_AVRC_PT_CMD_SOUND_SEL = 0x33, /*!< sound select */ + ESP_AVRC_PT_CMD_INPUT_SEL = 0x34, /*!< input select */ + ESP_AVRC_PT_CMD_DISP_INFO = 0x35, /*!< display information */ + ESP_AVRC_PT_CMD_HELP = 0x36, /*!< help */ + ESP_AVRC_PT_CMD_PAGE_UP = 0x37, /*!< page up */ + ESP_AVRC_PT_CMD_PAGE_DOWN = 0x38, /*!< page down */ + ESP_AVRC_PT_CMD_POWER = 0x40, /*!< power */ + ESP_AVRC_PT_CMD_VOL_UP = 0x41, /*!< volume up */ + ESP_AVRC_PT_CMD_VOL_DOWN = 0x42, /*!< volume down */ + ESP_AVRC_PT_CMD_MUTE = 0x43, /*!< mute */ + ESP_AVRC_PT_CMD_PLAY = 0x44, /*!< play */ + ESP_AVRC_PT_CMD_STOP = 0x45, /*!< stop */ + ESP_AVRC_PT_CMD_PAUSE = 0x46, /*!< pause */ + ESP_AVRC_PT_CMD_RECORD = 0x47, /*!< record */ + ESP_AVRC_PT_CMD_REWIND = 0x48, /*!< rewind */ + ESP_AVRC_PT_CMD_FAST_FORWARD = 0x49, /*!< fast forward */ + ESP_AVRC_PT_CMD_EJECT = 0x4A, /*!< eject */ + ESP_AVRC_PT_CMD_FORWARD = 0x4B, /*!< forward */ + ESP_AVRC_PT_CMD_BACKWARD = 0x4C, /*!< backward */ + ESP_AVRC_PT_CMD_ANGLE = 0x50, /*!< angle */ + ESP_AVRC_PT_CMD_SUBPICT = 0x51, /*!< subpicture */ + ESP_AVRC_PT_CMD_F1 = 0x71, /*!< F1 */ + ESP_AVRC_PT_CMD_F2 = 0x72, /*!< F2 */ + ESP_AVRC_PT_CMD_F3 = 0x73, /*!< F3 */ + ESP_AVRC_PT_CMD_F4 = 0x74, /*!< F4 */ + ESP_AVRC_PT_CMD_F5 = 0x75, /*!< F5 */ + ESP_AVRC_PT_CMD_VENDOR = 0x7E, /*!< vendor unique */ +} esp_avrc_pt_cmd_t; + +/// AVRC passthrough command filter +typedef enum { + ESP_AVRC_PSTH_FILTER_ALLOWED_CMD = 0, /*!< all of the PASSTHROUGH commands that can possibly be used, immutable */ + ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD = 1, /*!< PASSTHROUGH commands selectively supported according to the current configuration */ + ESP_AVRC_PSTH_FILTER_SUPPORT_MAX, +} esp_avrc_psth_filter_t; + +/// AVRC passthrough command bit mask +typedef struct { + uint16_t bits[8]; /*!< bit mask representation of PASSTHROUGH commands */ +} esp_avrc_psth_bit_mask_t; + +typedef enum { + ESP_AVRC_BIT_MASK_OP_TEST = 0, /*!< operation code to test a specific bit */ + ESP_AVRC_BIT_MASK_OP_SET = 1, /*!< operation code to set a specific bit */ + ESP_AVRC_BIT_MASK_OP_CLEAR = 2, /*!< operation code to clear a specific bit */ +} esp_avrc_bit_mask_op_t; + +/// AVRC passthrough command state +typedef enum { + ESP_AVRC_PT_CMD_STATE_PRESSED = 0, /*!< key pressed */ + ESP_AVRC_PT_CMD_STATE_RELEASED = 1 /*!< key released */ +} esp_avrc_pt_cmd_state_t; + +/// AVRC Controller callback events +typedef enum { + ESP_AVRC_CT_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */ + ESP_AVRC_CT_PASSTHROUGH_RSP_EVT = 1, /*!< passthrough response event */ + ESP_AVRC_CT_METADATA_RSP_EVT = 2, /*!< metadata response event */ + ESP_AVRC_CT_PLAY_STATUS_RSP_EVT = 3, /*!< play status response event */ + ESP_AVRC_CT_CHANGE_NOTIFY_EVT = 4, /*!< notification event */ + ESP_AVRC_CT_REMOTE_FEATURES_EVT = 5, /*!< feature of remote device indication event */ + ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT = 6, /*!< supported notification events capability of peer device */ + ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT = 7, /*!< set absolute volume response event */ +} esp_avrc_ct_cb_event_t; + +/// AVRC Target callback events +typedef enum { + ESP_AVRC_TG_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */ + ESP_AVRC_TG_REMOTE_FEATURES_EVT = 1, /*!< feature of remote device indication event */ + ESP_AVRC_TG_PASSTHROUGH_CMD_EVT = 2, /*!< passthrough command event */ + ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT = 3, /*!< set absolute volume command from remote device */ + ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT = 4, /*!< register notification event */ + ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT = 5, /*!< set application attribute value, attribute refer to esp_avrc_ps_attr_ids_t */ +} esp_avrc_tg_cb_event_t; + +/// AVRC metadata attribute mask +typedef enum { + ESP_AVRC_MD_ATTR_TITLE = 0x1, /*!< title of the playing track */ + ESP_AVRC_MD_ATTR_ARTIST = 0x2, /*!< track artist */ + ESP_AVRC_MD_ATTR_ALBUM = 0x4, /*!< album name */ + ESP_AVRC_MD_ATTR_TRACK_NUM = 0x8, /*!< track position on the album */ + ESP_AVRC_MD_ATTR_NUM_TRACKS = 0x10, /*!< number of tracks on the album */ + ESP_AVRC_MD_ATTR_GENRE = 0x20, /*!< track genre */ + ESP_AVRC_MD_ATTR_PLAYING_TIME = 0x40 /*!< total album playing time in miliseconds */ +} esp_avrc_md_attr_mask_t; + +/// AVRC event notification ids +typedef enum { + ESP_AVRC_RN_PLAY_STATUS_CHANGE = 0x01, /*!< track status change, eg. from playing to paused */ + ESP_AVRC_RN_TRACK_CHANGE = 0x02, /*!< new track is loaded */ + ESP_AVRC_RN_TRACK_REACHED_END = 0x03, /*!< current track reached end */ + ESP_AVRC_RN_TRACK_REACHED_START = 0x04, /*!< current track reached start position */ + ESP_AVRC_RN_PLAY_POS_CHANGED = 0x05, /*!< track playing position changed */ + ESP_AVRC_RN_BATTERY_STATUS_CHANGE = 0x06, /*!< battery status changed */ + ESP_AVRC_RN_SYSTEM_STATUS_CHANGE = 0x07, /*!< system status changed */ + ESP_AVRC_RN_APP_SETTING_CHANGE = 0x08, /*!< application settings changed */ + ESP_AVRC_RN_NOW_PLAYING_CHANGE = 0x09, /*!< now playing content changed */ + ESP_AVRC_RN_AVAILABLE_PLAYERS_CHANGE = 0x0a, /*!< available players changed */ + ESP_AVRC_RN_ADDRESSED_PLAYER_CHANGE = 0x0b, /*!< the addressed player changed */ + ESP_AVRC_RN_UIDS_CHANGE = 0x0c, /*!< UIDs changed */ + ESP_AVRC_RN_VOLUME_CHANGE = 0x0d, /*!< volume changed locally on TG */ + ESP_AVRC_RN_MAX_EVT +} esp_avrc_rn_event_ids_t; + +/// AVRC target notification event notification capability +typedef enum { + ESP_AVRC_RN_CAP_ALLOWED_EVT = 0, /*!< all of the notification events that can possibly be supported, immutable */ + ESP_AVRC_RN_CAP_SUPPORTED_EVT = 1, /*!< notification events selectively supported according to the current configuration */ + ESP_AVRC_RN_CAP_MAX, +} esp_avrc_rn_evt_cap_t; + +/// AVRC target notification event capability bit mask +typedef struct { + uint16_t bits; /*!< bit mask representation of PASSTHROUGH commands */ +} esp_avrc_rn_evt_cap_mask_t; + +/// AVRC notification response type +typedef enum { + ESP_AVRC_RN_RSP_INTERIM = 13, /*!< initial response to RegisterNotification, should be sent T_mtp(1000ms) from receiving the command */ + ESP_AVRC_RN_RSP_CHANGED = 15, /*!< final response to RegisterNotification command */ +} esp_avrc_rn_rsp_t; + +/// AVRC player setting ids +typedef enum { + ESP_AVRC_PS_EQUALIZER = 0x01, /*!< equalizer, on or off */ + ESP_AVRC_PS_REPEAT_MODE = 0x02, /*!< repeat mode */ + ESP_AVRC_PS_SHUFFLE_MODE = 0x03, /*!< shuffle mode */ + ESP_AVRC_PS_SCAN_MODE = 0x04, /*!< scan mode on or off */ + ESP_AVRC_PS_MAX_ATTR +} esp_avrc_ps_attr_ids_t; + +/// AVRC equalizer modes +typedef enum { + ESP_AVRC_PS_EQUALIZER_OFF = 0x1, /*!< equalizer OFF */ + ESP_AVRC_PS_EQUALIZER_ON = 0x2 /*!< equalizer ON */ +} esp_avrc_ps_eq_value_ids_t; + +/// AVRC repeat modes +typedef enum { + ESP_AVRC_PS_REPEAT_OFF = 0x1, /*!< repeat mode off */ + ESP_AVRC_PS_REPEAT_SINGLE = 0x2, /*!< single track repeat */ + ESP_AVRC_PS_REPEAT_GROUP = 0x3 /*!< group repeat */ +} esp_avrc_ps_rpt_value_ids_t; + + +/// AVRC shuffle modes +typedef enum { + ESP_AVRC_PS_SHUFFLE_OFF = 0x1, /*<! shuffle off */ + ESP_AVRC_PS_SHUFFLE_ALL = 0x2, /*<! shuffle all tracks */ + ESP_AVRC_PS_SHUFFLE_GROUP = 0x3 /*<! group shuffle */ +} esp_avrc_ps_shf_value_ids_t; + +/// AVRC scan modes +typedef enum { + ESP_AVRC_PS_SCAN_OFF = 0x1, /*!< scan off */ + ESP_AVRC_PS_SCAN_ALL = 0x2, /*!< all tracks scan */ + ESP_AVRC_PS_SCAN_GROUP = 0x3 /*!< group scan */ +} esp_avrc_ps_scn_value_ids_t; + +/// AVCTP response codes +typedef enum { + ESP_AVRC_RSP_NOT_IMPL = 8, /*!< not implemented */ + ESP_AVRC_RSP_ACCEPT = 9, /*!< accept */ + ESP_AVRC_RSP_REJECT = 10, /*!< reject */ + ESP_AVRC_RSP_IN_TRANS = 11, /*!< in transition */ + ESP_AVRC_RSP_IMPL_STBL = 12, /*!< implemented/stable */ + ESP_AVRC_RSP_CHANGED = 13, /*!< changed */ + ESP_AVRC_RSP_INTERIM = 15, /*!< interim */ +} esp_avrc_rsp_t; + +/// AVRCP battery status +typedef enum { + ESP_AVRC_BATT_NORMAL = 0, /*!< normal state */ + ESP_AVRC_BATT_WARNING = 1, /*!< unable to operate soon */ + ESP_AVRC_BATT_CRITICAL = 2, /*!< cannot operate any more */ + ESP_AVRC_BATT_EXTERNAL = 3, /*!< plugged to external power supply */ + ESP_AVRC_BATT_FULL_CHARGE = 4, /*!< when completely charged from external power supply */ +} esp_avrc_batt_stat_t; + +/// AVRCP current status of playback +typedef enum { + ESP_AVRC_PLAYBACK_STOPPED = 0, /*!< stopped */ + ESP_AVRC_PLAYBACK_PLAYING = 1, /*!< playing */ + ESP_AVRC_PLAYBACK_PAUSED = 2, /*!< paused */ + ESP_AVRC_PLAYBACK_FWD_SEEK = 3, /*!< forward seek */ + ESP_AVRC_PLAYBACK_REV_SEEK = 4, /*!< reverse seek */ + ESP_AVRC_PLAYBACK_ERROR = 0xFF, /*!< error */ +} esp_avrc_playback_stat_t; + +/// AVRCP notification parameters +typedef union +{ + uint8_t volume; /*!< response data for ESP_AVRC_RN_VOLUME_CHANGE, ranges 0..127 */ + esp_avrc_playback_stat_t playback; /*!< response data for ESP_AVRC_RN_PLAY_STATUS_CHANGE */ + uint8_t elm_id[8]; /*!< response data for ESP_AVRC_RN_TRACK_CHANGE */ + uint32_t play_pos; /*!< response data for ESP_AVRC_RN_PLAY_POS_CHANGED, in millisecond */ + esp_avrc_batt_stat_t batt; /*!< response data for ESP_AVRC_RN_BATTERY_STATUS_CHANGE */ +} esp_avrc_rn_param_t; + +/// AVRCP set app value parameters +typedef struct { + uint8_t attr_id; /*!< player application attribute id */ + uint8_t attr_val; /*!< player application attribute value */ +} esp_avrc_set_app_value_param_t; + +/// AVRC controller callback parameters +typedef union { + /** + * @brief ESP_AVRC_CT_CONNECTION_STATE_EVT + */ + struct avrc_ct_conn_stat_param { + bool connected; /*!< whether AVRC connection is set up */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + } conn_stat; /*!< AVRC connection status */ + + /** + * @brief ESP_AVRC_CT_PASSTHROUGH_RSP_EVT + */ + struct avrc_ct_psth_rsp_param { + uint8_t tl; /*!< transaction label, 0 to 15 */ + uint8_t key_code; /*!< passthrough command code */ + uint8_t key_state; /*!< 0 for PRESSED, 1 for RELEASED */ + esp_avrc_rsp_t rsp_code; /*!< response code */ + } psth_rsp; /*!< passthrough command response */ + + /** + * @brief ESP_AVRC_CT_METADATA_RSP_EVT + */ + struct avrc_ct_meta_rsp_param { + uint8_t attr_id; /*!< id of metadata attribute */ + uint8_t *attr_text; /*!< attribute itself */ + int attr_length; /*!< attribute character length */ + } meta_rsp; /*!< metadata attributes response */ + + /** + * @brief ESP_AVRC_CT_CHANGE_NOTIFY_EVT + */ + struct avrc_ct_change_notify_param { + uint8_t event_id; /*!< id of AVRC event notification */ + esp_avrc_rn_param_t event_parameter; /*!< event notification parameter */ + } change_ntf; /*!< notifications */ + + /** + * @brief ESP_AVRC_CT_REMOTE_FEATURES_EVT + */ + struct avrc_ct_rmt_feats_param { + uint32_t feat_mask; /*!< AVRC feature mask of remote device */ + uint16_t tg_feat_flag; /*!< feature flag of remote device as TG */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + } rmt_feats; /*!< AVRC features discovered from remote SDP server */ + + /** + * @brief ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT + */ + struct avrc_ct_get_rn_caps_rsp_param { + uint8_t cap_count; /*!< number of items provided in event or company_id according to cap_id used */ + esp_avrc_rn_evt_cap_mask_t evt_set; /*!< supported event_ids represented in bit-mask */ + } get_rn_caps_rsp; /*!< get supported event capabilities response from AVRCP target */ + + /** + * @brief ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT + */ + struct avrc_ct_set_volume_rsp_param { + uint8_t volume; /*!< the volume which has actually been set, range is 0 to 0x7f, means 0% to 100% */ + } set_volume_rsp; /*!< set absolute volume response event */ +} esp_avrc_ct_cb_param_t; + +/// AVRC target callback parameters +typedef union { + /** + * @brief ESP_AVRC_TG_CONNECTION_STATE_EVT + */ + struct avrc_tg_conn_stat_param { + bool connected; /*!< whether AVRC connection is set up */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + } conn_stat; /*!< AVRC connection status */ + + /** + * @brief ESP_AVRC_TG_REMOTE_FEATURES_EVT + */ + struct avrc_tg_rmt_feats_param { + uint32_t feat_mask; /*!< AVRC feature mask of remote device */ + uint16_t ct_feat_flag; /*!< feature flag of remote device as CT */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + } rmt_feats; /*!< AVRC features discovered through SDP */ + + /** + * @brief ESP_AVRC_TG_PASSTHROUGH_CMD_EVT + */ + struct avrc_tg_psth_cmd_param { + uint8_t key_code; /*!< passthrough command code */ + uint8_t key_state; /*!< 0 for PRESSED, 1 for RELEASED */ + } psth_cmd; /*!< passthrough command */ + + /** + * @brief ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT + */ + struct avrc_tg_set_abs_vol_param { + uint8_t volume; /*!< volume ranges from 0 to 127 */ + } set_abs_vol; /*!< set absolute volume command targeted on audio sink */ + + /** + * @brief ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT + */ + struct avrc_tg_reg_ntf_param { + uint8_t event_id; /*!< event id of AVRC RegisterNotification */ + uint32_t event_parameter; /*!< event notification parameter */ + } reg_ntf; /*!< register notification */ + + /** + * @brief ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT + */ + struct avrc_tg_set_app_value_param { + uint8_t num_val; /*!< attribute num */ + esp_avrc_set_app_value_param_t *p_vals; /*!< point to the id and value of player application attribute */ + } set_app_value; /*!< set player application value */ + +} esp_avrc_tg_cb_param_t; + +/** + * @brief AVRCP controller callback function type + * + * @param event : Event type + * + * @param param : Pointer to callback parameter union + */ +typedef void (* esp_avrc_ct_cb_t)(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); + +/** + * @brief AVRCP target callback function type + * + * @param event : Event type + * + * @param param : Pointer to callback parameter union + */ +typedef void (* esp_avrc_tg_cb_t)(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param); + + +/** + * @brief Register application callbacks to AVRCP module. This function should be + * called after esp_bluedroid_enable() completes successfully. + * + * @param[in] callback: AVRCP controller callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback); + +/** + * + * @brief Initialize the bluetooth AVRCP controller module, This function should be called + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be initialized before A2DP. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_avrc_ct_init(void); + +/** + * + * @brief De-initialize AVRCP controller module. This function should be called after + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_ct_deinit(void); + +/** + * + * @brief Send player application settings command to AVRCP target. This function should be called + * after ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established. + * + * @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values + * + * @param[in] attr_id : player application setting attribute IDs from one of esp_avrc_ps_attr_ids_t + * + * @param[in] value_id : attribute value defined for the specific player application setting attribute + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id); + +/** + * @brief Send GetCapabilities PDU to AVRCP target to retrieve remote device's supported + * notification event_ids. This function should be called after + * ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established. + * + * @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_ct_send_get_rn_capabilities_cmd(uint8_t tl); + +/** + * @brief Send register notification command to AVRCP target. This function should be called after + * ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established. + * + * @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values. + * + * @param[in] event_id : id of events, e.g. ESP_AVRC_RN_PLAY_STATUS_CHANGE, ESP_AVRC_RN_TRACK_CHANGE, etc. + * + * @param[in] event_parameter : playback interval for ESP_AVRC_RN_PLAY_POS_CHANGED; + * For other events , value of this parameter is ignored. + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_NOT_SUPPORTED: if the event_id is not supported in current implementation + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter); + +/** + * @brief Send set absolute volume command to AVRCP target. This function should be called after + * ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established. + * + * @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values + * + * @param[in] volume : volume, 0 to 0x7f, means 0% to 100% + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_NOT_SUPPORTED: if the event_id is not supported in current implementation + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_ct_send_set_absolute_volume_cmd(uint8_t tl, uint8_t volume); + +/** + * @brief Send metadata command to AVRCP target. This function should be called after + * ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established. + * + * @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values. + * + * @param[in] attr_mask : mask of attributes, e.g. ESP_AVRC_MD_ATTR_ID_TITLE | ESP_AVRC_MD_ATTR_ID_ARTIST. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask); + + +/** + * @brief Send passthrough command to AVRCP target. This function should be called after + * ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established. + * + * @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values. + * + * @param[in] key_code : passthrough command code, e.g. ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STOP, etc. + * + * @param[in] key_state : passthrough command key state, ESP_AVRC_PT_CMD_STATE_PRESSED or + * ESP_AVRC_PT_CMD_STATE_RELEASED + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state); + + +/** + * @brief Register application callbacks to AVRCP target module. This function should be + * called after esp_bluedroid_enable() completes successfully. + * + * @param[in] callback: AVRCP target callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback); + +/** + * + * @brief Initialize the bluetooth AVRCP target module, This function should be called + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be initialized before A2DP. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_avrc_tg_init(void); + +/** + * + * @brief De-initialize AVRCP target module. This function should be called after + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_avrc_tg_deinit(void); + +/** + * + * @brief Get the current filter of remote passthrough commands on AVRC target. Filter is given by + * filter type and bit mask for the passthrough commands. This function should be called + * after esp_avrc_tg_init(). + * For filter type ESP_AVRC_PSTH_FILTER_ALLOWED_CMD, the retrieved command set is constant and + * it covers all of the passthrough commands that can possibly be supported. + * For filter type ESP_AVRC_PSTH_FILTER_SUPPORT_COMMANDS, the retrieved command set covers the + * passthrough commands selected to be supported according to current configuration. The + * configuration can be changed using esp_avrc_tg_set_psth_cmd_filter(). + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC TG is not initialized + * - ESP_ERR_INVALID_ARG: if filter type is invalid or cmd_set is NULL + * - ESP_FAIL: otherwise + */ +esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avrc_psth_bit_mask_t *cmd_set); + +/** + * + * @brief Set the filter of remote passthrough commands on AVRC target. Filter is given by + * filter type and bit mask for the passthrough commands. This function should be called + * after esp_avrc_tg_init(). + * + * If filter type is ESP_AVRC_PSTH_FILTER_SUPPORT_CMD, the passthrough commands which + * are set "1" as given in cmd_set will generate ESP_AVRC_CT_PASSTHROUGH_RSP_EVT callback + * event and are auto-accepted in the protocol stack, other commands are replied with response + * type "NOT IMPLEMENTED" (8). The set of supported commands should be a subset of allowed + * command set. The allowed command set can be retrieved using esp_avrc_tg_get_psth_cmd_filter() + * with filter type "ESP_AVRC_PSTH_FILTER_ALLOWED_CMD". + * + * Filter type "ESP_AVRC_PSTH_FILTER_ALLOWED_CMD" does not apply to this function. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled + * - ESP_ERR_INVALID_ARG: if filter type is invalid or cmd_set is NULL + * - ESP_ERR_NOT_SUPPORTED:: if filter type is ESP_AVRC_PSTH_FILTER_ALLOWED_CMD, or cmd_set + * includes commands that are not allowed + * + */ +esp_err_t esp_avrc_tg_set_psth_cmd_filter(esp_avrc_psth_filter_t filter, const esp_avrc_psth_bit_mask_t *cmd_set); + +/** + * @brief Operate on the type esp_avrc_psth_bit_mask_t with regard to a specific PASSTHROUGH command. + * + * @param[in] op: operation requested on the bit mask field + * + * @param[in] psth: pointer to passthrough command bit mask structure + * + * @param[in] cmd: passthrough command code + * + * @return For operation ESP_AVRC_BIT_MASK_OP_SET or ESP_AVRC_BIT_MASK_OP_CLEAR, return + * true for a successful operation, otherwise return false. + * For operation ESP_AVRC_BIT_MASK_OP_TEST, return true if the corresponding bit + * is set, otherwise false. + * + */ +bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_bit_mask_t *psth, esp_avrc_pt_cmd_t cmd); + +/** + * + * @brief Get the requested event notification capabilies on local AVRC target. The capability is returned + * in a bit mask representation in evt_set. This function should be called after esp_avrc_tg_init(). + * + * For capability type "ESP_AVRC_RN_CAP_ALLOWED_EVT, the retrieved event set is constant and + * it covers all of the notifcation events that can possibly be supported with current + * implementation. + * + * For capability type ESP_AVRC_RN_CAP_SUPPORTED_EVT, the event set covers the notification + * events selected to be supported under current configuration, The configuration can be + * changed using esp_avrc_tg_set_rn_evt_cap(). + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC TG is not initialized + * - ESP_ERR_INVALID_ARG: if cap is invalid or evt_set is NULL + * - ESP_FAIL: otherwise + */ +esp_err_t esp_avrc_tg_get_rn_evt_cap(esp_avrc_rn_evt_cap_t cap, esp_avrc_rn_evt_cap_mask_t *evt_set); + +/** + * + * @brief Set the event notification capabilities on local AVRCP target. The capability is given in a + * bit mask representation in evt_set and must be a subset of allowed event IDs with current + * implementation. This function should be called after esp_avrc_tg_init(). + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled + * - ESP_ERR_INVALID_ARG: if evt_set is NULL + * + */ +esp_err_t esp_avrc_tg_set_rn_evt_cap(const esp_avrc_rn_evt_cap_mask_t *evt_set); + +/** + * @brief Operate on the type esp_avrc_rn_evt_cap_mask_t with regard to a specific event. + * + * @param[in] op: operation requested on the bit mask field + * + * @param[in] events: pointer to event notification capability bit mask structure + * + * @param[in] event_id: notification event code + * + * @return For operation ESP_AVRC_BIT_MASK_OP_SET or ESP_AVRC_BIT_MASK_OP_CLEAR, return + * true for a successful operation, otherwise return false. + * + * For operation ESP_AVRC_BIT_MASK_OP_TEST, return true if the corresponding bit + * is set, otherwise false. + * + */ +bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_evt_cap_mask_t *events, + esp_avrc_rn_event_ids_t event_id); + +/** + * + * @brief Send RegisterNotification Response to remote AVRCP controller. Local event notification + * capability can be set using esp_avrc_tg_set_rn_evt_cap(), in a bit mask representation + * in evt_set. This function should be called after esp_avrc_tg_init(). + * + * @param[in] event_id: notification event ID that remote AVRCP CT registers + * + * @param[in] rsp: notification response code + * + * @param[in] param: parameters included in the specific notification + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC TG is not initialized + * - ESP_ERR_INVALID_ARG: if evt_set is NULL + * + */ +esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp, + esp_avrc_rn_param_t *param); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_AVRC_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h b/lib/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h new file mode 100644 index 00000000..0004072c --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BLUEDROID_HCI_H__ +#define __ESP_BLUEDROID_HCI_H__ + +#include <stdbool.h> +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* HCI driver callbacks */ +typedef struct esp_bluedroid_hci_driver_callbacks { + /** + * @brief callback used to notify that the host can send packet to controller + */ + void (*notify_host_send_available)(void); + + /** + * @brief callback used to notify that the controller has a packet to send to the host + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + * + * @return 0 received successfully, failed otherwise + */ + int (*notify_host_recv)(uint8_t *data, uint16_t len); +} esp_bluedroid_hci_driver_callbacks_t; + +/* HCI driver operations */ +typedef struct esp_bluedroid_hci_driver_operations { + /** + * @brief send data from host to controller + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + */ + void (*send)(uint8_t *data, uint16_t len); + + /** + * @brief host checks whether it can send data to controller + * + * @return true if host can send data, false otherwise + */ + bool (*check_send_available)(void); + + /** + * @brief register host callback + * + * @param[in] callback HCI driver callbacks + */ + esp_err_t (* register_host_callback)(const esp_bluedroid_hci_driver_callbacks_t *callback); +} esp_bluedroid_hci_driver_operations_t; + +/** + * @brief get the operations of HCI transport layer. This API should only be used in + * Bluedroid Host-only mode before Bluedroid initialization. + * + * @param[in] ops struct containing operations of HCI transport layer + * + * @return ESP_OK if get successfully, ESP_FAIL otherwise + */ +esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *ops); + +/** + * @brief remove the operations of HCI transport layer. This API should only be used in + * Bluedroid Host-only mode before Bluedroid initialization. + * + * @param[in] ops struct containing operations of HCI transport layer + * + * @return ESP_OK if get successfully, ESP_FAIL otherwise + */ +esp_err_t esp_bluedroid_detach_hci_driver(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_BLUEDROID_HCI_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h b/lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h new file mode 100644 index 00000000..19419014 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h @@ -0,0 +1,205 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BT_DEFS_H__ +#define __ESP_BT_DEFS_H__ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_BLUEDROID_STATUS_CHECK(status) \ + if (esp_bluedroid_get_status() != (status)) { \ + return ESP_ERR_INVALID_STATE; \ + } + +#define ESP_BT_STATUS_BASE_FOR_HCI_ERR 0X0100 /* base for coverting HCI error code to ESP status */ + +/* relate to BT_STATUS_xxx in bt_def.h */ +/// Status Return Value +typedef enum { + ESP_BT_STATUS_SUCCESS = 0, /* relate to BT_STATUS_SUCCESS in bt_def.h */ + ESP_BT_STATUS_FAIL, /* relate to BT_STATUS_FAIL in bt_def.h */ + ESP_BT_STATUS_NOT_READY, /* relate to BT_STATUS_NOT_READY in bt_def.h */ + ESP_BT_STATUS_NOMEM, /* relate to BT_STATUS_NOMEM in bt_def.h */ + ESP_BT_STATUS_BUSY, /* relate to BT_STATUS_BUSY in bt_def.h */ + ESP_BT_STATUS_DONE = 5, /* relate to BT_STATUS_DONE in bt_def.h */ + ESP_BT_STATUS_UNSUPPORTED, /* relate to BT_STATUS_UNSUPPORTED in bt_def.h */ + ESP_BT_STATUS_PARM_INVALID, /* relate to BT_STATUS_PARM_INVALID in bt_def.h */ + ESP_BT_STATUS_UNHANDLED, /* relate to BT_STATUS_UNHANDLED in bt_def.h */ + ESP_BT_STATUS_AUTH_FAILURE, /* relate to BT_STATUS_AUTH_FAILURE in bt_def.h */ + ESP_BT_STATUS_RMT_DEV_DOWN = 10, /* relate to BT_STATUS_RMT_DEV_DOWN in bt_def.h */ + ESP_BT_STATUS_AUTH_REJECTED, /* relate to BT_STATUS_AUTH_REJECTED in bt_def.h */ + ESP_BT_STATUS_INVALID_STATIC_RAND_ADDR, /* relate to BT_STATUS_INVALID_STATIC_RAND_ADDR in bt_def.h */ + ESP_BT_STATUS_PENDING, /* relate to BT_STATUS_PENDING in bt_def.h */ + ESP_BT_STATUS_UNACCEPT_CONN_INTERVAL, /* relate to BT_UNACCEPT_CONN_INTERVAL in bt_def.h */ + ESP_BT_STATUS_PARAM_OUT_OF_RANGE, /* relate to BT_PARAM_OUT_OF_RANGE in bt_def.h */ + ESP_BT_STATUS_TIMEOUT, /* relate to BT_STATUS_TIMEOUT in bt_def.h */ + ESP_BT_STATUS_PEER_LE_DATA_LEN_UNSUPPORTED, /* relate to BTM_PEER_LE_DATA_LEN_UNSUPPORTED in stack/btm_api.h */ + ESP_BT_STATUS_CONTROL_LE_DATA_LEN_UNSUPPORTED,/* relate to BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED in stack/btm_api.h */ + ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT, /* relate to HCI_ERR_ILLEGAL_PARAMETER_FMT in stack/hcidefs.h */ + ESP_BT_STATUS_MEMORY_FULL = 20, /* relate to BT_STATUS_MEMORY_FULL in bt_def.h */ + ESP_BT_STATUS_EIR_TOO_LARGE, /* relate to BT_STATUS_EIR_TOO_LARGE in bt_def.h */ + ESP_BT_STATUS_HCI_SUCCESS = ESP_BT_STATUS_BASE_FOR_HCI_ERR, + ESP_BT_STATUS_HCI_ILLEGAL_COMMAND, + ESP_BT_STATUS_HCI_NO_CONNECTION, + ESP_BT_STATUS_HCI_HW_FAILURE, + ESP_BT_STATUS_HCI_PAGE_TIMEOUT, + ESP_BT_STATUS_HCI_AUTH_FAILURE, + ESP_BT_STATUS_HCI_KEY_MISSING, + ESP_BT_STATUS_HCI_MEMORY_FULL, + ESP_BT_STATUS_HCI_CONNECTION_TOUT, + ESP_BT_STATUS_HCI_MAX_NUM_OF_CONNECTIONS, + ESP_BT_STATUS_HCI_MAX_NUM_OF_SCOS, + ESP_BT_STATUS_HCI_CONNECTION_EXISTS, + ESP_BT_STATUS_HCI_COMMAND_DISALLOWED, + ESP_BT_STATUS_HCI_HOST_REJECT_RESOURCES, + ESP_BT_STATUS_HCI_HOST_REJECT_SECURITY, + ESP_BT_STATUS_HCI_HOST_REJECT_DEVICE, + ESP_BT_STATUS_HCI_HOST_TIMEOUT, + ESP_BT_STATUS_HCI_UNSUPPORTED_VALUE, + ESP_BT_STATUS_HCI_ILLEGAL_PARAMETER_FMT, + ESP_BT_STATUS_HCI_PEER_USER, + ESP_BT_STATUS_HCI_PEER_LOW_RESOURCES, + ESP_BT_STATUS_HCI_PEER_POWER_OFF, + ESP_BT_STATUS_HCI_CONN_CAUSE_LOCAL_HOST, + ESP_BT_STATUS_HCI_REPEATED_ATTEMPTS, + ESP_BT_STATUS_HCI_PAIRING_NOT_ALLOWED, + ESP_BT_STATUS_HCI_UNKNOWN_LMP_PDU, + ESP_BT_STATUS_HCI_UNSUPPORTED_REM_FEATURE, + ESP_BT_STATUS_HCI_SCO_OFFSET_REJECTED, + ESP_BT_STATUS_HCI_SCO_INTERVAL_REJECTED, + ESP_BT_STATUS_HCI_SCO_AIR_MODE, + ESP_BT_STATUS_HCI_INVALID_LMP_PARAM, + ESP_BT_STATUS_HCI_UNSPECIFIED, + ESP_BT_STATUS_HCI_UNSUPPORTED_LMP_PARAMETERS, + ESP_BT_STATUS_HCI_ROLE_CHANGE_NOT_ALLOWED, + ESP_BT_STATUS_HCI_LMP_RESPONSE_TIMEOUT, + ESP_BT_STATUS_HCI_LMP_ERR_TRANS_COLLISION, + ESP_BT_STATUS_HCI_LMP_PDU_NOT_ALLOWED, + ESP_BT_STATUS_HCI_ENCRY_MODE_NOT_ACCEPTABLE, + ESP_BT_STATUS_HCI_UNIT_KEY_USED, + ESP_BT_STATUS_HCI_QOS_NOT_SUPPORTED, + ESP_BT_STATUS_HCI_INSTANT_PASSED, + ESP_BT_STATUS_HCI_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED, + ESP_BT_STATUS_HCI_DIFF_TRANSACTION_COLLISION, + ESP_BT_STATUS_HCI_UNDEFINED_0x2B, + ESP_BT_STATUS_HCI_QOS_UNACCEPTABLE_PARAM, + ESP_BT_STATUS_HCI_QOS_REJECTED, + ESP_BT_STATUS_HCI_CHAN_CLASSIF_NOT_SUPPORTED, + ESP_BT_STATUS_HCI_INSUFFCIENT_SECURITY, + ESP_BT_STATUS_HCI_PARAM_OUT_OF_RANGE, + ESP_BT_STATUS_HCI_UNDEFINED_0x31, + ESP_BT_STATUS_HCI_ROLE_SWITCH_PENDING, + ESP_BT_STATUS_HCI_UNDEFINED_0x33, + ESP_BT_STATUS_HCI_RESERVED_SLOT_VIOLATION, + ESP_BT_STATUS_HCI_ROLE_SWITCH_FAILED, + ESP_BT_STATUS_HCI_INQ_RSP_DATA_TOO_LARGE, + ESP_BT_STATUS_HCI_SIMPLE_PAIRING_NOT_SUPPORTED, + ESP_BT_STATUS_HCI_HOST_BUSY_PAIRING, + ESP_BT_STATUS_HCI_REJ_NO_SUITABLE_CHANNEL, + ESP_BT_STATUS_HCI_CONTROLLER_BUSY, + ESP_BT_STATUS_HCI_UNACCEPT_CONN_INTERVAL, + ESP_BT_STATUS_HCI_DIRECTED_ADVERTISING_TIMEOUT, + ESP_BT_STATUS_HCI_CONN_TOUT_DUE_TO_MIC_FAILURE, + ESP_BT_STATUS_HCI_CONN_FAILED_ESTABLISHMENT, + ESP_BT_STATUS_HCI_MAC_CONNECTION_FAILED, +} esp_bt_status_t; + + +/*Define the bt octet 16 bit size*/ +#define ESP_BT_OCTET16_LEN 16 +typedef uint8_t esp_bt_octet16_t[ESP_BT_OCTET16_LEN]; /* octet array: size 16 */ + +#define ESP_BT_OCTET8_LEN 8 +typedef uint8_t esp_bt_octet8_t[ESP_BT_OCTET8_LEN]; /* octet array: size 8 */ + +typedef uint8_t esp_link_key[ESP_BT_OCTET16_LEN]; /* Link Key */ + +/// Default GATT interface id +#define ESP_DEFAULT_GATT_IF 0xff + +#if BLE_HIGH_DUTY_ADV_INTERVAL +#define ESP_BLE_PRIM_ADV_INT_MIN 0x000008 /*!< Minimum advertising interval for undirected and low duty cycle directed advertising */ +#else +#define ESP_BLE_PRIM_ADV_INT_MIN 0x000020 /*!< Minimum advertising interval for undirected and low duty cycle directed advertising */ +#endif +#define ESP_BLE_PRIM_ADV_INT_MAX 0xFFFFFF /*!< Maximum advertising interval for undirected and low duty cycle directed advertising */ +#define ESP_BLE_CONN_INT_MIN 0x0006 /*!< relate to BTM_BLE_CONN_INT_MIN in stack/btm_ble_api.h */ +#define ESP_BLE_CONN_INT_MAX 0x0C80 /*!< relate to BTM_BLE_CONN_INT_MAX in stack/btm_ble_api.h */ +#define ESP_BLE_CONN_LATENCY_MAX 499 /*!< relate to ESP_BLE_CONN_LATENCY_MAX in stack/btm_ble_api.h */ +#define ESP_BLE_CONN_SUP_TOUT_MIN 0x000A /*!< relate to BTM_BLE_CONN_SUP_TOUT_MIN in stack/btm_ble_api.h */ +#define ESP_BLE_CONN_SUP_TOUT_MAX 0x0C80 /*!< relate to ESP_BLE_CONN_SUP_TOUT_MAX in stack/btm_ble_api.h */ + +/// Check the param is valid or not +#define ESP_BLE_IS_VALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) ) + +/// UUID type +typedef struct { +#define ESP_UUID_LEN_16 2 +#define ESP_UUID_LEN_32 4 +#define ESP_UUID_LEN_128 16 + uint16_t len; /*!< UUID length, 16bit, 32bit or 128bit */ + union { + uint16_t uuid16; /*!< 16bit UUID */ + uint32_t uuid32; /*!< 32bit UUID */ + uint8_t uuid128[ESP_UUID_LEN_128]; /*!< 128bit UUID */ + } uuid; /*!< UUID */ +} __attribute__((packed)) esp_bt_uuid_t; + +/// Bluetooth device type +typedef enum { + ESP_BT_DEVICE_TYPE_BREDR = 0x01, + ESP_BT_DEVICE_TYPE_BLE = 0x02, + ESP_BT_DEVICE_TYPE_DUMO = 0x03, +} esp_bt_dev_type_t; + +/// Bluetooth address length +#define ESP_BD_ADDR_LEN 6 + +/// Bluetooth device address +typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]; + +/// BLE device address type +typedef enum { + BLE_ADDR_TYPE_PUBLIC = 0x00, /*!< Public Device Address */ + BLE_ADDR_TYPE_RANDOM = 0x01, /*!< Random Device Address. To set this address, use the function esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr) */ + BLE_ADDR_TYPE_RPA_PUBLIC = 0x02, /*!< Resolvable Private Address (RPA) with public identity address */ + BLE_ADDR_TYPE_RPA_RANDOM = 0x03, /*!< Resolvable Private Address (RPA) with random identity address. To set this address, use the function esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr) */ +} esp_ble_addr_type_t; + +/// white list address type +typedef enum { + BLE_WL_ADDR_TYPE_PUBLIC = 0x00, + BLE_WL_ADDR_TYPE_RANDOM = 0x01, +} esp_ble_wl_addr_type_t; + +/// Used to exchange the encryption key in the init key & response key +#define ESP_BLE_ENC_KEY_MASK (1 << 0) /* relate to BTM_BLE_ENC_KEY_MASK in stack/btm_api.h */ +/// Used to exchange the IRK key in the init key & response key +#define ESP_BLE_ID_KEY_MASK (1 << 1) /* relate to BTM_BLE_ID_KEY_MASK in stack/btm_api.h */ +/// Used to exchange the CSRK key in the init key & response key +#define ESP_BLE_CSR_KEY_MASK (1 << 2) /* relate to BTM_BLE_CSR_KEY_MASK in stack/btm_api.h */ +/// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key +#define ESP_BLE_LINK_KEY_MASK (1 << 3) /* relate to BTM_BLE_LINK_KEY_MASK in stack/btm_api.h */ +typedef uint8_t esp_ble_key_mask_t; /* the key mask type */ + +/// Minimum of the application id +#define ESP_APP_ID_MIN 0x0000 +/// Maximum of the application id +#define ESP_APP_ID_MAX 0x7fff + +#define ESP_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define ESP_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_BT_DEFS_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_bt_device.h b/lib/bt/host/bluedroid/api/include/api/esp_bt_device.h new file mode 100644 index 00000000..5c00c456 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_bt_device.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BT_DEVICE_H__ +#define __ESP_BT_DEVICE_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// coexist status for MESH +#define ESP_BT_DEV_COEX_BLE_ST_MESH_CONFIG 0x08 +#define ESP_BT_DEV_COEX_BLE_ST_MESH_TRAFFIC 0x10 +#define ESP_BT_DEV_COEX_BLE_ST_MESH_STANDBY 0x20 +// coexist status for A2DP +#define ESP_BT_DEV_COEX_BT_ST_A2DP_STREAMING 0x10 +#define ESP_BT_DEV_COEX_BT_ST_A2DP_PAUSED 0x20 + +// coexist operation +#define ESP_BT_DEV_COEX_OP_CLEAR 0x00 +#define ESP_BT_DEV_COEX_OP_SET 0x01 +typedef uint8_t esp_bt_dev_coex_op_t; + +/** + * @brief Bluetooth device coex type + */ +typedef enum { + ESP_BT_DEV_COEX_TYPE_BLE = 1, + ESP_BT_DEV_COEX_TYPE_BT, +} esp_bt_dev_coex_type_t; + +/** + * + * @brief Get bluetooth device address. Must use after "esp_bluedroid_enable". + * + * @return bluetooth device address (six bytes), or NULL if bluetooth stack is not enabled + */ +const uint8_t *esp_bt_dev_get_address(void); + + +/** + * @brief Set bluetooth device name. This function should be called after esp_bluedroid_enable() + * completes successfully. + * + * A BR/EDR/LE device type shall have a single Bluetooth device name which shall be + * identical irrespective of the physical channel used to perform the name discovery procedure. + * + * @param[in] name : device name to be set + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_ARG : if name is NULL pointer or empty, or string length out of limit + * - ESP_ERR_INVALID_STATE : if bluetooth stack is not yet enabled + * - ESP_FAIL : others + */ +esp_err_t esp_bt_dev_set_device_name(const char *name); + +/** + * @brief Config bluetooth device coexis status. This function should be called after esp_bluedroid_enable() + * completes successfully. + * + * @param[in] type : coexist type to operate on + * @param[in] op : clear or set coexist status + * @param[in] status : coexist status to be configured + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_ARG : if name is NULL pointer or empty, or string length out of limit + * - ESP_ERR_INVALID_STATE : if bluetooth stack is not yet enabled + * - ESP_FAIL : others + */ +esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_coex_op_t op, uint8_t status); + +/** + * @brief This function is used to update the path name of bluetooth bond keys saved in the NVS module + * and need to be called before esp_bluedroid_init(). + * @param[in] file_path: the name of config file path, the length of file_path should be less than NVS_NS_NAME_MAX_SIZE + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_bt_config_file_path_update(const char *file_path); + +#ifdef __cplusplus +} +#endif + + +#endif /* __ESP_BT_DEVICE_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_bt_main.h b/lib/bt/host/bluedroid/api/include/api/esp_bt_main.h new file mode 100644 index 00000000..db6826e3 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_bt_main.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BT_MAIN_H__ +#define __ESP_BT_MAIN_H__ + +#include <stdbool.h> +#include <stdint.h> + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Bluetooth stack status type, to indicate whether the bluetooth stack is ready. + */ +typedef enum { + ESP_BLUEDROID_STATUS_UNINITIALIZED = 0, /*!< Bluetooth not initialized */ + ESP_BLUEDROID_STATUS_INITIALIZED, /*!< Bluetooth initialized but not enabled */ + ESP_BLUEDROID_STATUS_ENABLED /*!< Bluetooth initialized and enabled */ +} esp_bluedroid_status_t; + +/** + * @brief Bluetooth stack configuration + */ +typedef struct { + bool ssp_en; /*!< Whether SSP(secure simple pairing) or legacy pairing is used for Classic Bluetooth */ +} esp_bluedroid_config_t; + +#define BT_BLUEDROID_INIT_CONFIG_DEFAULT() \ + { \ + .ssp_en = true, \ + } + +/** + * @brief Get bluetooth stack status + * + * @return Bluetooth stack status + * + */ +esp_bluedroid_status_t esp_bluedroid_get_status(void); + +/** + * @brief Enable bluetooth, must after esp_bluedroid_init()/esp_bluedroid_init_with_cfg(). + * + * @return + * - ESP_OK : Succeed + * - Other : Failed + */ +esp_err_t esp_bluedroid_enable(void); + +/** + * @brief Disable bluetooth, must prior to esp_bluedroid_deinit(). + * + * @return + * - ESP_OK : Succeed + * - Other : Failed + */ +esp_err_t esp_bluedroid_disable(void); + +/** + * @brief Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff. + * + * @return + * - ESP_OK : Succeed + * - Other : Failed + */ +esp_err_t esp_bluedroid_init(void) __attribute__((deprecated("Please use esp_bluedroid_init_with_cfg"))); + +/** + * @brief Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff. + * + * @param cfg Initial configuration of ESP Bluedroid stack. + * + * @return + * - ESP_OK : Succeed + * - Other : Failed + */ +esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg); + +/** + * @brief Deinit and free the resource for bluetooth, must be after every bluetooth stuff. + * + * @return + * - ESP_OK : Succeed + * - Other : Failed + */ +esp_err_t esp_bluedroid_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_BT_MAIN_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h new file mode 100644 index 00000000..e3904d6d --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -0,0 +1,2547 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_GAP_BLE_API_H__ +#define __ESP_GAP_BLE_API_H__ + +#include <stdint.h> +#include <stdbool.h> + +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief BLE_ADV_DATA_FLAG data flag bit definition used for advertising data flag + */ +#define ESP_BLE_ADV_FLAG_LIMIT_DISC (0x01 << 0) +#define ESP_BLE_ADV_FLAG_GEN_DISC (0x01 << 1) +#define ESP_BLE_ADV_FLAG_BREDR_NOT_SPT (0x01 << 2) +#define ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT (0x01 << 3) +#define ESP_BLE_ADV_FLAG_DMT_HOST_SPT (0x01 << 4) +#define ESP_BLE_ADV_FLAG_NON_LIMIT_DISC (0x00 ) + + +/// relate to BTM_LE_KEY_xxx in stack/btm_api.h +#define ESP_LE_KEY_NONE 0 /*!< No encryption key */ +#define ESP_LE_KEY_PENC (1 << 0) /*!< encryption key, encryption information of peer device */ +#define ESP_LE_KEY_PID (1 << 1) /*!< identity key of the peer device */ +#define ESP_LE_KEY_PCSRK (1 << 2) /*!< peer SRK */ +#define ESP_LE_KEY_PLK (1 << 3) /*!< Link key*/ +#define ESP_LE_KEY_LLK (ESP_LE_KEY_PLK << 4) /*!< peer link key*/ +#define ESP_LE_KEY_LENC (ESP_LE_KEY_PENC << 4) /*!< master role security information:div */ +#define ESP_LE_KEY_LID (ESP_LE_KEY_PID << 4) /*!< master device ID key */ +#define ESP_LE_KEY_LCSRK (ESP_LE_KEY_PCSRK << 4) /*!< local CSRK has been deliver to peer */ +typedef uint8_t esp_ble_key_type_t; + +/// relate to BTM_LE_AUTH_xxx in stack/btm_api.h +#define ESP_LE_AUTH_NO_BOND 0x00 /*!< 0 no bondingv*/ +#define ESP_LE_AUTH_BOND 0x01 /*!< 1 << 0 device in the bonding with peer */ +#define ESP_LE_AUTH_REQ_MITM (1 << 2) /*!< 1 << 2 man in the middle attack */ +#define ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM) /*!< 0101 banding with man in the middle attack */ +#define ESP_LE_AUTH_REQ_SC_ONLY (1 << 3) /*!< 1 << 3 secure connection */ +#define ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1001 secure connection with band*/ +#define ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1100 secure conn with MITM */ +#define ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND) /*!< 1101 SC with MITM and Bonding*/ +typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit pattern */ + +#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE 0 /*!< authentication disable*/ +#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE 1 /*!< authentication enable*/ + +#define ESP_BLE_OOB_DISABLE 0 /*!< disbale the out of bond*/ +#define ESP_BLE_OOB_ENABLE 1 /*!< enable the out of bond*/ + +/// relate to BTM_IO_CAP_xxx in stack/btm_api.h +#define ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ +#define ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ +#define ESP_IO_CAP_IN 2 /*!< KeyboardOnly */ +#define ESP_IO_CAP_NONE 3 /*!< NoInputNoOutput */ +#define ESP_IO_CAP_KBDISP 4 /*!< Keyboard display */ + +#define ESP_BLE_APPEARANCE_UNKNOWN 0x0000 /*!< relate to BTM_BLE_APPEARANCE_UNKNOWN in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_PHONE 0x0040 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_PHONE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_COMPUTER 0x0080 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_COMPUTER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_WATCH 0x00C0 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_WATCH in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_SPORTS_WATCH 0x00C1 /*!< relate to BTM_BLE_APPEARANCE_SPORTS_WATCH in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_CLOCK 0x0100 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_CLOCK in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_DISPLAY 0x0140 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_DISPLAY in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_REMOTE 0x0180 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_REMOTE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_EYEGLASSES 0x01C0 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_EYEGLASSES in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_TAG 0x0200 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_TAG in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_KEYRING 0x0240 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_KEYRING in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 0x0280 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_MEDIA_PLAYER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 0x02C0 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_BARCODE_SCANNER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_THERMOMETER 0x0300 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_THERMOMETER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_THERMOMETER_EAR 0x0301 /*!< relate to BTM_BLE_APPEARANCE_THERMOMETER_EAR in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_HEART_RATE 0x0340 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_HEART_RATE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HEART_RATE_BELT 0x0341 /*!< relate to BTM_BLE_APPEARANCE_HEART_RATE_BELT in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 0x0380 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_BLOOD_PRESSURE_ARM 0x0381 /*!< relate to BTM_BLE_APPEARANCE_BLOOD_PRESSURE_ARM in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 0x0382 /*!< relate to BTM_BLE_APPEARANCE_BLOOD_PRESSURE_WRIST in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_HID 0x03C0 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_HID in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_KEYBOARD 0x03C1 /*!< relate to BTM_BLE_APPEARANCE_HID_KEYBOARD in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_MOUSE 0x03C2 /*!< relate to BTM_BLE_APPEARANCE_HID_MOUSE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_JOYSTICK 0x03C3 /*!< relate to BTM_BLE_APPEARANCE_HID_JOYSTICK in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_GAMEPAD 0x03C4 /*!< relate to BTM_BLE_APPEARANCE_HID_GAMEPAD in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_DIGITIZER_TABLET 0x03C5 /*!< relate to BTM_BLE_APPEARANCE_HID_DIGITIZER_TABLET in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_CARD_READER 0x03C6 /*!< relate to BTM_BLE_APPEARANCE_HID_CARD_READER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_DIGITAL_PEN 0x03C7 /*!< relate to BTM_BLE_APPEARANCE_HID_DIGITAL_PEN in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_HID_BARCODE_SCANNER 0x03C8 /*!< relate to BTM_BLE_APPEARANCE_HID_BARCODE_SCANNER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_GLUCOSE 0x0400 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_GLUCOSE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_WALKING 0x0440 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_WALKING in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_WALKING_IN_SHOE 0x0441 /*!< relate to BTM_BLE_APPEARANCE_WALKING_IN_SHOE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_WALKING_ON_SHOE 0x0442 /*!< relate to BTM_BLE_APPEARANCE_WALKING_ON_SHOE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_WALKING_ON_HIP 0x0443 /*!< relate to BTM_BLE_APPEARANCE_WALKING_ON_HIP in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_CYCLING 0x0480 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_CYCLING in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_CYCLING_COMPUTER 0x0481 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_COMPUTER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_CYCLING_SPEED 0x0482 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_SPEED in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_CYCLING_CADENCE 0x0483 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_CADENCE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_CYCLING_POWER 0x0484 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_POWER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_CYCLING_SPEED_CADENCE 0x0485 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 0x0C40 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 0x0C41 /*!< relate to BTM_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_PULSE_OXIMETER_WRIST 0x0C42 /*!< relate to BTM_BLE_APPEARANCE_PULSE_OXIMETER_WRIST in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_WEIGHT 0x0C80 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_WEIGHT in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_PERSONAL_MOBILITY_DEVICE 0x0CC0 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_PERSONAL_MOBILITY_DEVICE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_POWERED_WHEELCHAIR 0x0CC1 /*!< relate to BTM_BLE_APPEARANCE_POWERED_WHEELCHAIR in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_MOBILITY_SCOOTER 0x0CC2 /*!< relate to BTM_BLE_APPEARANCE_MOBILITY_SCOOTER in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_CONTINUOUS_GLUCOSE_MONITOR 0x0D00 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_CONTINUOUS_GLUCOSE_MONITOR in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_INSULIN_PUMP 0x0D40 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_INSULIN_PUMP in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_INSULIN_PUMP_DURABLE_PUMP 0x0D41 /*!< relate to BTM_BLE_APPEARANCE_INSULIN_PUMP_DURABLE_PUMP in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_INSULIN_PUMP_PATCH_PUMP 0x0D44 /*!< relate to BTM_BLE_APPEARANCE_INSULIN_PUMP_PATCH_PUMP in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_INSULIN_PEN 0x0D48 /*!< relate to BTM_BLE_APPEARANCE_INSULIN_PEN in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_MEDICATION_DELIVERY 0x0D80 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_MEDICATION_DELIVERY in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS 0x1440 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION 0x1441 /*!< relate to BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV 0x1442 /*!< relate to BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD 0x1443 /*!< relate to BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV 0x1444 /*!< relate to BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV in stack/btm_ble_api.h */ + +typedef uint8_t esp_ble_io_cap_t; /*!< combination of the io capability */ + +#define BLE_DTM_PKT_PAYLOAD_0x00 0x00 /*!< PRBS9 sequence ‘11111111100000111101...’ (in transmission order) as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x01 0x01 /*!< Repeated ‘11110000’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x02 0x02 /*!< Repeated ‘10101010’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x03 0x03 /*!< PRBS15 sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x04 0x04 /*!< Repeated ‘11111111’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x05 0x05 /*!< Repeated ‘00000000’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x06 0x06 /*!< Repeated ‘00001111’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x07 0x07 /*!< Repeated ‘01010101’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_MAX 0x08 /*!< 0x08 ~ 0xFF, Reserved for future use */ + +typedef uint8_t esp_ble_dtm_pkt_payload_t; + +/// GAP BLE callback event type +typedef enum { + //BLE_42_FEATURE_SUPPORT + ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT = 0, /*!< When advertising data set complete, the event comes */ + ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT, /*!< When scan response data set complete, the event comes */ + ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, /*!< When scan parameters set complete, the event comes */ + ESP_GAP_BLE_SCAN_RESULT_EVT, /*!< When one scan result ready, the event comes each time */ + ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */ + ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw scan response data set complete, the event comes */ + ESP_GAP_BLE_ADV_START_COMPLETE_EVT, /*!< When start advertising complete, the event comes */ + ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, /*!< When start scan complete, the event comes */ + //BLE_INCLUDED + ESP_GAP_BLE_AUTH_CMPL_EVT = 8, /*!< Authentication complete indication. */ + ESP_GAP_BLE_KEY_EVT, /*!< BLE key event for peer device keys */ + ESP_GAP_BLE_SEC_REQ_EVT, /*!< BLE security request */ + ESP_GAP_BLE_PASSKEY_NOTIF_EVT, /*!< passkey notification event */ + ESP_GAP_BLE_PASSKEY_REQ_EVT, /*!< passkey request event */ + ESP_GAP_BLE_OOB_REQ_EVT, /*!< OOB request event */ + ESP_GAP_BLE_LOCAL_IR_EVT, /*!< BLE local IR (identity Root 128-bit random static value used to generate Long Term Key) event */ + ESP_GAP_BLE_LOCAL_ER_EVT, /*!< BLE local ER (Encryption Root vakue used to genrate identity resolving key) event */ + ESP_GAP_BLE_NC_REQ_EVT, /*!< Numeric Comparison request event */ + //BLE_42_FEATURE_SUPPORT + ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT, /*!< When stop adv complete, the event comes */ + ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT, /*!< When stop scan complete, the event comes */ + //BLE_INCLUDED + ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT = 19, /*!< When set the static rand address complete, the event comes */ + ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, /*!< When update connection parameters complete, the event comes */ + ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt length complete, the event comes */ + ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, /*!< When Enable/disable privacy on the local device complete, the event comes */ + ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< When remove the bond device complete, the event comes */ + ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT, /*!< When clear the bond device clear complete, the event comes */ + ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT, /*!< When get the bond device list complete, the event comes */ + ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT, /*!< When read the rssi complete, the event comes */ + ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT, /*!< When add or remove whitelist complete, the event comes */ + //BLE_42_FEATURE_SUPPORT + ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT, /*!< When update duplicate exceptional list complete, the event comes */ + //BLE_INCLUDED + ESP_GAP_BLE_SET_CHANNELS_EVT = 29, /*!< When setting BLE channels complete, the event comes */ + //BLE_50_FEATURE_SUPPORT + ESP_GAP_BLE_READ_PHY_COMPLETE_EVT, /*!< when reading phy complete, this event comes */ + ESP_GAP_BLE_SET_PREFERRED_DEFAULT_PHY_COMPLETE_EVT, /*!< when preferred default phy complete, this event comes */ + ESP_GAP_BLE_SET_PREFERRED_PHY_COMPLETE_EVT, /*!< when preferred phy complete , this event comes */ + ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, /*!< when extended set random address complete, the event comes */ + ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, /*!< when extended advertising parameter complete, the event comes */ + ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, /*!< when extended advertising data complete, the event comes */ + ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, /*!< when extended scan response data complete, the event comes */ + ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, /*!< when extended advertising start complete, the event comes */ + ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, /*!< when extended advertising stop complete, the event comes */ + ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT, /*!< when extended advertising set remove complete, the event comes */ + ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT, /*!< when extended advertising set clear complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, /*!< when periodic advertising parameter complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, /*!< when periodic advertising data complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT, /*!< when periodic advertising start complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT, /*!< when periodic advertising stop complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, /*!< when periodic advertising create sync complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT, /*!< when extended advertising sync cancel complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT, /*!< when extended advertising sync terminate complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT, /*!< when extended advertising add device complete , the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT, /*!< when extended advertising remove device complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT, /*!< when extended advertising clear device, the event comes */ + ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT, /*!< when extended scan parameter complete, the event comes */ + ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT, /*!< when extended scan start complete, the event comes */ + ESP_GAP_BLE_EXT_SCAN_STOP_COMPLETE_EVT, /*!< when extended scan stop complete, the event comes */ + ESP_GAP_BLE_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT, /*!< when extended prefer connection parameter set complete, the event comes */ + ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT, /*!< when ble phy update complete, the event comes */ + ESP_GAP_BLE_EXT_ADV_REPORT_EVT, /*!< when extended advertising report complete, the event comes */ + ESP_GAP_BLE_SCAN_TIMEOUT_EVT, /*!< when scan timeout complete, the event comes */ + ESP_GAP_BLE_ADV_TERMINATED_EVT, /*!< when advertising terminate data complete, the event comes */ + ESP_GAP_BLE_SCAN_REQ_RECEIVED_EVT, /*!< when scan req received complete, the event comes */ + ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT, /*!< when channel select algorithm complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT, /*!< when periodic report advertising complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT, /*!< when periodic advertising sync lost complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT, /*!< when periodic advertising sync establish complete, the event comes */ + //BLE_INCLUDED + ESP_GAP_BLE_SC_OOB_REQ_EVT, /*!< Secure Connection OOB request event */ + ESP_GAP_BLE_SC_CR_LOC_OOB_EVT, /*!< Secure Connection create OOB data complete event */ + ESP_GAP_BLE_GET_DEV_NAME_COMPLETE_EVT, /*!< When getting BT device name complete, the event comes */ + //BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER + ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT, /*!< when set periodic advertising receive enable complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT, /*!< when periodic advertising sync transfer complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT, /*!< when periodic advertising set info transfer complete, the event comes */ + ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT, /*!< when set periodic advertising sync transfer params complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, /*!< when periodic advertising sync transfer received, the event comes */ + // DTM + ESP_GAP_BLE_DTM_TEST_UPDATE_EVT, /*!< when direct test mode state changes, the event comes */ + // BLE_INCLUDED + ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT, /*!< When clear advertising complete, the event comes */ + ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ +} esp_gap_ble_cb_event_t; + +#define ESP_GAP_BLE_CHANNELS_LEN 5 /*!< channel length*/ +typedef uint8_t esp_gap_ble_channels[ESP_GAP_BLE_CHANNELS_LEN]; + +/// This is the old name, just for backwards compatibility +#define ESP_GAP_BLE_ADD_WHITELIST_COMPLETE_EVT ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT + +/// Advertising data maximum length +#define ESP_BLE_ADV_DATA_LEN_MAX 31 +/// Scan response data maximum length +#define ESP_BLE_SCAN_RSP_DATA_LEN_MAX 31 + +/* relate to BTM_BLE_AD_TYPE_xxx in stack/btm_ble_api.h */ +/// The type of advertising data(not adv_type) +typedef enum { + ESP_BLE_AD_TYPE_FLAG = 0x01, /* relate to BTM_BLE_AD_TYPE_FLAG in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_16SRV_PART = 0x02, /* relate to BTM_BLE_AD_TYPE_16SRV_PART in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_16SRV_CMPL = 0x03, /* relate to BTM_BLE_AD_TYPE_16SRV_CMPL in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_32SRV_PART = 0x04, /* relate to BTM_BLE_AD_TYPE_32SRV_PART in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_32SRV_CMPL = 0x05, /* relate to BTM_BLE_AD_TYPE_32SRV_CMPL in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_128SRV_PART = 0x06, /* relate to BTM_BLE_AD_TYPE_128SRV_PART in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_128SRV_CMPL = 0x07, /* relate to BTM_BLE_AD_TYPE_128SRV_CMPL in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_NAME_SHORT = 0x08, /* relate to BTM_BLE_AD_TYPE_NAME_SHORT in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_NAME_CMPL = 0x09, /* relate to BTM_BLE_AD_TYPE_NAME_CMPL in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_TX_PWR = 0x0A, /* relate to BTM_BLE_AD_TYPE_TX_PWR in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_DEV_CLASS = 0x0D, /* relate to BTM_BLE_AD_TYPE_DEV_CLASS in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_SM_TK = 0x10, /* relate to BTM_BLE_AD_TYPE_SM_TK in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_SM_OOB_FLAG = 0x11, /* relate to BTM_BLE_AD_TYPE_SM_OOB_FLAG in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_INT_RANGE = 0x12, /* relate to BTM_BLE_AD_TYPE_INT_RANGE in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_SOL_SRV_UUID = 0x14, /* relate to BTM_BLE_AD_TYPE_SOL_SRV_UUID in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_128SOL_SRV_UUID = 0x15, /* relate to BTM_BLE_AD_TYPE_128SOL_SRV_UUID in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_SERVICE_DATA = 0x16, /* relate to BTM_BLE_AD_TYPE_SERVICE_DATA in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_PUBLIC_TARGET = 0x17, /* relate to BTM_BLE_AD_TYPE_PUBLIC_TARGET in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_RANDOM_TARGET = 0x18, /* relate to BTM_BLE_AD_TYPE_RANDOM_TARGET in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_APPEARANCE = 0x19, /* relate to BTM_BLE_AD_TYPE_APPEARANCE in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_ADV_INT = 0x1A, /* relate to BTM_BLE_AD_TYPE_ADV_INT in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_LE_DEV_ADDR = 0x1b, /* relate to BTM_BLE_AD_TYPE_LE_DEV_ADDR in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_LE_ROLE = 0x1c, /* relate to BTM_BLE_AD_TYPE_LE_ROLE in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_SPAIR_C256 = 0x1d, /* relate to BTM_BLE_AD_TYPE_SPAIR_C256 in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_SPAIR_R256 = 0x1e, /* relate to BTM_BLE_AD_TYPE_SPAIR_R256 in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_32SOL_SRV_UUID = 0x1f, /* relate to BTM_BLE_AD_TYPE_32SOL_SRV_UUID in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_32SERVICE_DATA = 0x20, /* relate to BTM_BLE_AD_TYPE_32SERVICE_DATA in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_128SERVICE_DATA = 0x21, /* relate to BTM_BLE_AD_TYPE_128SERVICE_DATA in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_LE_SECURE_CONFIRM = 0x22, /* relate to BTM_BLE_AD_TYPE_LE_SECURE_CONFIRM in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_LE_SECURE_RANDOM = 0x23, /* relate to BTM_BLE_AD_TYPE_LE_SECURE_RANDOM in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_URI = 0x24, /* relate to BTM_BLE_AD_TYPE_URI in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_INDOOR_POSITION = 0x25, /* relate to BTM_BLE_AD_TYPE_INDOOR_POSITION in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_TRANS_DISC_DATA = 0x26, /* relate to BTM_BLE_AD_TYPE_TRANS_DISC_DATA in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_LE_SUPPORT_FEATURE = 0x27, /* relate to BTM_BLE_AD_TYPE_LE_SUPPORT_FEATURE in stack/btm_ble_api.h */ + ESP_BLE_AD_TYPE_CHAN_MAP_UPDATE = 0x28, /* relate to BTM_BLE_AD_TYPE_CHAN_MAP_UPDATE in stack/btm_ble_api.h */ + ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE = 0xFF, /* relate to BTM_BLE_AD_MANUFACTURER_SPECIFIC_TYPE in stack/btm_ble_api.h */ +} esp_ble_adv_data_type; + +/// Advertising mode +typedef enum { + ADV_TYPE_IND = 0x00, + ADV_TYPE_DIRECT_IND_HIGH = 0x01, + ADV_TYPE_SCAN_IND = 0x02, + ADV_TYPE_NONCONN_IND = 0x03, + ADV_TYPE_DIRECT_IND_LOW = 0x04, +} esp_ble_adv_type_t; + +/// Advertising channel mask +typedef enum { + ADV_CHNL_37 = 0x01, + ADV_CHNL_38 = 0x02, + ADV_CHNL_39 = 0x04, + ADV_CHNL_ALL = 0x07, +} esp_ble_adv_channel_t; + +typedef enum { + ///Allow both scan and connection requests from anyone + ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY = 0x00, + ///Allow both scan req from White List devices only and connection req from anyone + ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY, + ///Allow both scan req from anyone and connection req from White List devices only + ADV_FILTER_ALLOW_SCAN_ANY_CON_WLST, + ///Allow scan and connection requests from White List devices only + ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST, + ///Enumeration end value for advertising filter policy value check +} esp_ble_adv_filter_t; + + +/* relate to BTA_DM_BLE_SEC_xxx in bta/bta_api.h */ +typedef enum { + ESP_BLE_SEC_ENCRYPT = 1, /*!< relate to BTA_DM_BLE_SEC_ENCRYPT in bta/bta_api.h. If the device has already + bonded, the stack will used Long Term Key (LTK) to encrypt with the remote device directly. + Else if the device hasn't bonded, the stack will used the default authentication request + used the esp_ble_gap_set_security_param function set by the user. */ + ESP_BLE_SEC_ENCRYPT_NO_MITM, /*!< relate to BTA_DM_BLE_SEC_ENCRYPT_NO_MITM in bta/bta_api.h. If the device has been already + bonded, the stack will check the LTK (Long Term Key) Whether the authentication request has been met, and if met, use the LTK + to encrypt with the remote device directly, else re-pair with the remote device. + Else if the device hasn't been bonded, the stack will use NO MITM authentication request in the current link instead of + using the authreq in the esp_ble_gap_set_security_param function set by the user. */ + ESP_BLE_SEC_ENCRYPT_MITM, /*!< relate to BTA_DM_BLE_SEC_ENCRYPT_MITM in bta/bta_api.h. If the device has been already + bonded, the stack will check the LTK (Long Term Key) whether the authentication request has been met, and if met, use the LTK + to encrypt with the remote device directly, else re-pair with the remote device. + Else if the device hasn't been bonded, the stack will use MITM authentication request in the current link instead of + using the authreq in the esp_ble_gap_set_security_param function set by the user. */ +}esp_ble_sec_act_t; + +typedef enum { + ESP_BLE_SM_PASSKEY = 0, + /*!< Authentication requirements of local device */ + ESP_BLE_SM_AUTHEN_REQ_MODE, + /*!< The IO capability of local device */ + ESP_BLE_SM_IOCAP_MODE, + /*!< Initiator Key Distribution/Generation */ + ESP_BLE_SM_SET_INIT_KEY, + /*!< Responder Key Distribution/Generation */ + ESP_BLE_SM_SET_RSP_KEY, + /*!< Maximum Encryption key size to support */ + ESP_BLE_SM_MAX_KEY_SIZE, + /*!< Minimum Encryption key size requirement from Peer */ + ESP_BLE_SM_MIN_KEY_SIZE, + /*!< Set static Passkey */ + ESP_BLE_SM_SET_STATIC_PASSKEY, + /*!< Reset static Passkey */ + ESP_BLE_SM_CLEAR_STATIC_PASSKEY, + /*!< Accept only specified SMP Authentication requirement */ + ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, + /*!< Enable/Disable OOB support */ + ESP_BLE_SM_OOB_SUPPORT, + /*!< Appl encryption key size */ + ESP_BLE_APP_ENC_KEY_SIZE, + /*!< authentication max param */ + ESP_BLE_SM_MAX_PARAM, +} esp_ble_sm_param_t; + +typedef enum { + /// DTM TX start event + DTM_TX_START_EVT = 0x00, + ///DTM RX start event + DTM_RX_START_EVT, + ///DTM test end event + DTM_TEST_STOP_EVT, +} esp_ble_dtm_update_evt_t; + +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/** +* @brief DTM TX parameters +*/ +typedef struct +{ + uint8_t tx_channel; /*!< channel for sending test data, tx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + uint8_t len_of_data; /*!< length in bytes of payload data in each packet */ + esp_ble_dtm_pkt_payload_t pkt_payload; /*!< packet payload type. value range: 0x00-0x07 */ +} esp_ble_dtm_tx_t; +/** +* @brief DTM RX parameters +*/ +typedef struct +{ + uint8_t rx_channel; /*!< channel for test data reception, rx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ +} esp_ble_dtm_rx_t; + +/// Advertising parameters +typedef struct { + uint16_t adv_int_min; /*!< Minimum advertising interval for + undirected and low duty cycle directed advertising. + Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second) + Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec */ + uint16_t adv_int_max; /*!< Maximum advertising interval for + undirected and low duty cycle directed advertising. + Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second) + Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec Advertising max interval */ + esp_ble_adv_type_t adv_type; /*!< Advertising type */ + esp_ble_addr_type_t own_addr_type; /*!< Owner bluetooth device address type */ + esp_bd_addr_t peer_addr; /*!< Peer device bluetooth device address */ + esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type, only support public address type and random address type */ + esp_ble_adv_channel_t channel_map; /*!< Advertising channel map */ + esp_ble_adv_filter_t adv_filter_policy; /*!< Advertising filter policy */ +} esp_ble_adv_params_t; + +/// Advertising data content, according to "Supplement to the Bluetooth Core Specification" +typedef struct { + bool set_scan_rsp; /*!< Set this advertising data as scan response or not*/ + bool include_name; /*!< Advertising data include device name or not */ + bool include_txpower; /*!< Advertising data include TX power */ + int min_interval; /*!< Advertising data show slave preferred connection min interval. + The connection interval in the following manner: + connIntervalmin = Conn_Interval_Min * 1.25 ms + Conn_Interval_Min range: 0x0006 to 0x0C80 + Value of 0xFFFF indicates no specific minimum. + Values not defined above are reserved for future use.*/ + + int max_interval; /*!< Advertising data show slave preferred connection max interval. + The connection interval in the following manner: + connIntervalmax = Conn_Interval_Max * 1.25 ms + Conn_Interval_Max range: 0x0006 to 0x0C80 + Conn_Interval_Max shall be equal to or greater than the Conn_Interval_Min. + Value of 0xFFFF indicates no specific maximum. + Values not defined above are reserved for future use.*/ + + int appearance; /*!< External appearance of device */ + uint16_t manufacturer_len; /*!< Manufacturer data length */ + uint8_t *p_manufacturer_data; /*!< Manufacturer data point */ + uint16_t service_data_len; /*!< Service data length */ + uint8_t *p_service_data; /*!< Service data point */ + uint16_t service_uuid_len; /*!< Service uuid length */ + uint8_t *p_service_uuid; /*!< Service uuid array point */ + uint8_t flag; /*!< Advertising flag of discovery mode, see BLE_ADV_DATA_FLAG detail */ +} esp_ble_adv_data_t; + +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +/// Ble scan type +typedef enum { + BLE_SCAN_TYPE_PASSIVE = 0x0, /*!< Passive scan */ + BLE_SCAN_TYPE_ACTIVE = 0x1, /*!< Active scan */ +} esp_ble_scan_type_t; + +/// Ble scan filter type +typedef enum { + BLE_SCAN_FILTER_ALLOW_ALL = 0x0, /*!< Accept all : + 1. advertisement packets except directed advertising packets not addressed to this device (default). */ + BLE_SCAN_FILTER_ALLOW_ONLY_WLST = 0x1, /*!< Accept only : + 1. advertisement packets from devices where the advertiser’s address is in the White list. + 2. Directed advertising packets which are not addressed for this device shall be ignored. */ + BLE_SCAN_FILTER_ALLOW_UND_RPA_DIR = 0x2, /*!< Accept all : + 1. undirected advertisement packets, and + 2. directed advertising packets where the initiator address is a resolvable private address, and + 3. directed advertising packets addressed to this device. */ + BLE_SCAN_FILTER_ALLOW_WLIST_RPA_DIR = 0x3, /*!< Accept all : + 1. advertisement packets from devices where the advertiser’s address is in the White list, and + 2. directed advertising packets where the initiator address is a resolvable private address, and + 3. directed advertising packets addressed to this device.*/ +} esp_ble_scan_filter_t; + +/// Ble scan duplicate type +typedef enum { + BLE_SCAN_DUPLICATE_DISABLE = 0x0, /*!< the Link Layer should generate advertising reports to the host for each packet received */ + BLE_SCAN_DUPLICATE_ENABLE = 0x1, /*!< the Link Layer should filter out duplicate advertising reports to the Host */ + #if (BLE_50_FEATURE_SUPPORT == TRUE) + BLE_SCAN_DUPLICATE_ENABLE_RESET, /*!< Duplicate filtering enabled, reset for each scan period, only supported in BLE 5.0. */ + #endif + BLE_SCAN_DUPLICATE_MAX /*!< Reserved for future use. */ +} esp_ble_scan_duplicate_t; +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/// Ble scan parameters +typedef struct { + esp_ble_scan_type_t scan_type; /*!< Scan type */ + esp_ble_addr_type_t own_addr_type; /*!< Owner address type */ + esp_ble_scan_filter_t scan_filter_policy; /*!< Scan filter policy */ + uint16_t scan_interval; /*!< Scan interval. This is defined as the time interval from + when the Controller started its last LE scan until it begins the subsequent LE scan. + Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms) + Time = N * 0.625 msec + Time Range: 2.5 msec to 10.24 seconds*/ + uint16_t scan_window; /*!< Scan window. The duration of the LE scan. LE_Scan_Window + shall be less than or equal to LE_Scan_Interval + Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms) + Time = N * 0.625 msec + Time Range: 2.5 msec to 10240 msec */ + esp_ble_scan_duplicate_t scan_duplicate; /*!< The Scan_Duplicates parameter controls whether the Link Layer should filter out + duplicate advertising reports (BLE_SCAN_DUPLICATE_ENABLE) to the Host, or if the Link Layer should generate + advertising reports for each packet received */ +} esp_ble_scan_params_t; +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) +/// connection parameters information +typedef struct { + uint16_t interval; /*!< connection interval */ + uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */ + uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80. + Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec + Time Range: 100 msec to 32 seconds */ +} esp_gap_conn_params_t; + +/// Connection update parameters +typedef struct { + esp_bd_addr_t bda; /*!< Bluetooth device address */ + uint16_t min_int; /*!< Min connection interval */ + uint16_t max_int; /*!< Max connection interval */ + uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */ + uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80. + Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec + Time Range: 100 msec to 32 seconds */ +} esp_ble_conn_update_params_t; + +/** +* @brief BLE pkt date length keys +*/ +typedef struct +{ + uint16_t rx_len; /*!< pkt rx data length value */ + uint16_t tx_len; /*!< pkt tx data length value */ +} esp_ble_pkt_data_length_params_t; + +/** +* @brief BLE encryption keys +*/ +typedef struct +{ + esp_bt_octet16_t ltk; /*!< The long term key*/ + esp_bt_octet8_t rand; /*!< The random number*/ + uint16_t ediv; /*!< The ediv value*/ + uint8_t sec_level; /*!< The security level of the security link*/ + uint8_t key_size; /*!< The key size(7~16) of the security link*/ +} esp_ble_penc_keys_t; /*!< The key type*/ + +/** +* @brief BLE CSRK keys +*/ +typedef struct +{ + uint32_t counter; /*!< The counter */ + esp_bt_octet16_t csrk; /*!< The csrk key */ + uint8_t sec_level; /*!< The security level */ +} esp_ble_pcsrk_keys_t; /*!< The pcsrk key type */ + +/** +* @brief BLE pid keys +*/ +typedef struct +{ + esp_bt_octet16_t irk; /*!< The irk value */ + esp_ble_addr_type_t addr_type; /*!< The address type */ + esp_bd_addr_t static_addr; /*!< The static address */ +} esp_ble_pid_keys_t; /*!< The pid key type */ + +/** +* @brief BLE Encryption reproduction keys +*/ +typedef struct +{ + esp_bt_octet16_t ltk; /*!< The long term key */ + uint16_t div; /*!< The div value */ + uint8_t key_size; /*!< The key size of the security link */ + uint8_t sec_level; /*!< The security level of the security link */ +} esp_ble_lenc_keys_t; /*!< The key type */ + +/** +* @brief BLE SRK keys +*/ +typedef struct +{ + uint32_t counter; /*!< The counter value */ + uint16_t div; /*!< The div value */ + uint8_t sec_level; /*!< The security level of the security link */ + esp_bt_octet16_t csrk; /*!< The csrk key value */ +} esp_ble_lcsrk_keys; /*!< The csrk key type */ + +/** +* @brief Structure associated with ESP_KEY_NOTIF_EVT +*/ +typedef struct +{ + esp_bd_addr_t bd_addr; /*!< peer address */ + uint32_t passkey; /*!< the numeric value for comparison. If just_works, do not show this number to UI */ +} esp_ble_sec_key_notif_t; /*!< BLE key notify type*/ + +/** +* @brief Structure of the security request +*/ +typedef struct +{ + esp_bd_addr_t bd_addr; /*!< peer address */ +} esp_ble_sec_req_t; /*!< BLE security request type*/ + +/** +* @brief union type of the security key value +*/ +typedef union +{ + esp_ble_penc_keys_t penc_key; /*!< received peer encryption key */ + esp_ble_pcsrk_keys_t pcsrk_key; /*!< received peer device SRK */ + esp_ble_pid_keys_t pid_key; /*!< peer device ID key */ + esp_ble_lenc_keys_t lenc_key; /*!< local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ + esp_ble_lcsrk_keys lcsrk_key; /*!< local device CSRK = d1(ER,DIV,1)*/ +} esp_ble_key_value_t; /*!< ble key value type*/ + +/** +* @brief struct type of the bond key information value +*/ +typedef struct +{ + esp_ble_key_mask_t key_mask; /*!< the key mask to indicate witch key is present */ + esp_ble_penc_keys_t penc_key; /*!< received peer encryption key */ + esp_ble_pcsrk_keys_t pcsrk_key; /*!< received peer device SRK */ + esp_ble_pid_keys_t pid_key; /*!< peer device ID key */ +} esp_ble_bond_key_info_t; /*!< ble bond key information value type */ + +/** +* @brief struct type of the bond device value +*/ +typedef struct +{ + esp_bd_addr_t bd_addr; /*!< peer address */ + esp_ble_bond_key_info_t bond_key; /*!< the bond key information */ +} esp_ble_bond_dev_t; /*!< the ble bond device type */ + + +/** +* @brief union type of the security key value +*/ +typedef struct +{ + esp_bd_addr_t bd_addr; /*!< peer address */ + esp_ble_key_type_t key_type; /*!< key type of the security link */ + esp_ble_key_value_t p_key_value; /*!< the pointer to the key value */ +} esp_ble_key_t; /*!< the union to the ble key value type*/ + +/** +* @brief structure type of the ble local id keys value +*/ +typedef struct { + esp_bt_octet16_t ir; /*!< the 16 bits of the ir value */ + esp_bt_octet16_t irk; /*!< the 16 bits of the ir key value */ + esp_bt_octet16_t dhk; /*!< the 16 bits of the dh key value */ +} esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/ + +/** +* @brief structure type of the ble local oob data value +*/ +typedef struct { + esp_bt_octet16_t oob_c; /*!< the 128 bits of confirmation value */ + esp_bt_octet16_t oob_r; /*!< the 128 bits of randomizer value */ +} esp_ble_local_oob_data_t; + +/** + * @brief Structure associated with ESP_AUTH_CMPL_EVT + */ +typedef struct +{ + esp_bd_addr_t bd_addr; /*!< BD address peer device. */ + bool key_present; /*!< Valid link key value in key element */ + esp_link_key key; /*!< Link key associated with peer device. */ + uint8_t key_type; /*!< The type of Link Key */ + bool success; /*!< TRUE of authentication succeeded, FALSE if failed. */ + uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */ + esp_ble_addr_type_t addr_type; /*!< Peer device address type */ + esp_bt_dev_type_t dev_type; /*!< Device type */ + esp_ble_auth_req_t auth_mode; /*!< authentication mode */ +} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */ + +/** + * @brief union associated with ble security + */ +typedef union +{ + esp_ble_sec_key_notif_t key_notif; /*!< passkey notification */ + esp_ble_sec_req_t ble_req; /*!< BLE SMP related request */ + esp_ble_key_t ble_key; /*!< BLE SMP keys used when pairing */ + esp_ble_local_id_keys_t ble_id_keys; /*!< BLE IR event */ + esp_ble_local_oob_data_t oob_data; /*!< BLE SMP secure connection OOB data */ + esp_ble_auth_cmpl_t auth_cmpl; /*!< Authentication complete indication. */ +} esp_ble_sec_t; /*!< BLE security type */ +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT +typedef enum { + ESP_GAP_SEARCH_INQ_RES_EVT = 0, /*!< Inquiry result for a peer device. */ + ESP_GAP_SEARCH_INQ_CMPL_EVT = 1, /*!< Inquiry complete. */ + ESP_GAP_SEARCH_DISC_RES_EVT = 2, /*!< Discovery result for a peer device. */ + ESP_GAP_SEARCH_DISC_BLE_RES_EVT = 3, /*!< Discovery result for BLE GATT based service on a peer device. */ + ESP_GAP_SEARCH_DISC_CMPL_EVT = 4, /*!< Discovery complete. */ + ESP_GAP_SEARCH_DI_DISC_CMPL_EVT = 5, /*!< Discovery complete. */ + ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT = 6, /*!< Search cancelled */ + ESP_GAP_SEARCH_INQ_DISCARD_NUM_EVT = 7, /*!< The number of pkt discarded by flow control */ +} esp_gap_search_evt_t; +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) +/** + * @brief Ble scan result event type, to indicate the + * result is scan response or advertising data or other + */ +typedef enum { + ESP_BLE_EVT_CONN_ADV = 0x00, /*!< Connectable undirected advertising (ADV_IND) */ + ESP_BLE_EVT_CONN_DIR_ADV = 0x01, /*!< Connectable directed advertising (ADV_DIRECT_IND) */ + ESP_BLE_EVT_DISC_ADV = 0x02, /*!< Scannable undirected advertising (ADV_SCAN_IND) */ + ESP_BLE_EVT_NON_CONN_ADV = 0x03, /*!< Non connectable undirected advertising (ADV_NONCONN_IND) */ + ESP_BLE_EVT_SCAN_RSP = 0x04, /*!< Scan Response (SCAN_RSP) */ +} esp_ble_evt_type_t; + +typedef enum{ + ESP_BLE_WHITELIST_REMOVE = 0X00, /*!< remove mac from whitelist */ + ESP_BLE_WHITELIST_ADD = 0X01, /*!< add address to whitelist */ + ESP_BLE_WHITELIST_CLEAR = 0x02, /*!< clear all device in whitelist */ +} esp_ble_wl_operation_t; +#if (BLE_42_FEATURE_SUPPORT == TRUE) +typedef enum { + ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD = 0, /*!< Add device info into duplicate scan exceptional list */ + ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_REMOVE, /*!< Remove device info from duplicate scan exceptional list */ + ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN, /*!< Clean duplicate scan exceptional list */ +} esp_bt_duplicate_exceptional_subcode_type_t; +#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) + +#define BLE_BIT(n) (1UL<<(n)) +#if (BLE_42_FEATURE_SUPPORT == TRUE) +typedef enum { + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR = 0, /*!< BLE advertising address , device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID, /*!< BLE mesh link ID, it is for BLE mesh, device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_BEACON_TYPE, /*!< BLE mesh beacon AD type, the format is | Len | 0x2B | Beacon Type | Beacon Data | */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROV_SRV_ADV, /*!< BLE mesh provisioning service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1827 | .... |` */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SRV_ADV, /*!< BLE mesh adv with proxy service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1828 | .... |` */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SOLIC_ADV, /*!< BLE mesh adv with proxy service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1859 | .... |` */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_URI_ADV, /*!< BLE mesh URI adv, the format is ...| Len | 0x24 | data |... */ +} esp_ble_duplicate_exceptional_info_type_t; + +typedef enum { + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST = BLE_BIT(0), /*!< duplicate scan exceptional addr list */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST = BLE_BIT(1), /*!< duplicate scan exceptional mesh link ID list */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_BEACON_TYPE_LIST = BLE_BIT(2), /*!< duplicate scan exceptional mesh beacon type list */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROV_SRV_ADV_LIST = BLE_BIT(3), /*!< duplicate scan exceptional mesh adv with provisioning service uuid */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROXY_SRV_ADV_LIST = BLE_BIT(4), /*!< duplicate scan exceptional mesh adv with proxy service uuid */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROXY_SOLIC_ADV_LIST = BLE_BIT(5), /*!< duplicate scan exceptional mesh adv with proxy solicitation PDU uuid */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_URI_ADV_LIST = BLE_BIT(6), /*!< duplicate scan exceptional URI list */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ALL_LIST = 0xFFFF, /*!< duplicate scan exceptional all list */ +} esp_duplicate_scan_exceptional_list_type_t; + +typedef uint8_t esp_duplicate_info_t[ESP_BD_ADDR_LEN]; + +#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_NONCONN_NONSCANNABLE_UNDIRECTED (0 << 0) /*!< Non-Connectable and Non-Scannable Undirected advertising */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE (1 << 0) /*!< Connectable advertising */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE (1 << 1) /*!< Scannable advertising */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_DIRECTED (1 << 2) /*!< Directed advertising */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_HD_DIRECTED (1 << 3) /*!< High Duty Cycle Directed Connectable advertising (<= 3.75 ms Advertising Interval) */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY (1 << 4) /*!< Use legacy advertising PDUs */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_ANON_ADV (1 << 5) /*!< Omit advertiser's address from all PDUs ("anonymous advertising") */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_INCLUDE_TX_PWR (1 << 6) /*!< Include TxPower in the extended header of the advertising PDU */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_MASK (0x7F) /*!< Reserved for future use */ + +/*!< If extended advertising PDU types are being used (bit 4 = 0) then: + The advertisement shall not be both connectable and scannable. + High duty cycle directed connectable advertising (<= 3.75 ms advertising interval) shall not be used (bit 3 = 0) +*/ +/*!< ADV_IND */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\ + ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\ + ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE) +/*!< ADV_DIRECT_IND (low duty cycle) */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_LD_DIR (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\ + ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\ + ESP_BLE_GAP_SET_EXT_ADV_PROP_DIRECTED) +/*!< ADV_DIRECT_IND (high duty cycle) */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_HD_DIR (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\ + ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\ + ESP_BLE_GAP_SET_EXT_ADV_PROP_HD_DIRECTED) +/*!< ADV_SCAN_IND */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_SCAN (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\ + ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE) +/*!< ADV_NONCONN_IND */ +#define ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY) +typedef uint16_t esp_ble_ext_adv_type_mask_t; + +#define ESP_BLE_GAP_PHY_1M 1 /*!< Secondery Advertisement PHY is LE1M */ +#define ESP_BLE_GAP_PHY_2M 2 /*!< Secondery Advertisement PHY is LE2M */ +#define ESP_BLE_GAP_PHY_CODED 3 /*!< Secondery Advertisement PHY is LE Coded */ +typedef uint8_t esp_ble_gap_phy_t; + +#define ESP_BLE_GAP_NO_PREFER_TRANSMIT_PHY (1<<0) /*!< No Prefer TX PHY supported by controller */ +#define ESP_BLE_GAP_NO_PREFER_RECEIVE_PHY (1<<1) /*!< No Prefer RX PHY supported by controller */ +typedef uint8_t esp_ble_gap_all_phys_t; + +/// Primary phy only support 1M and LE coded phy +#define ESP_BLE_GAP_PRI_PHY_1M ESP_BLE_GAP_PHY_1M /*!< Primary Phy is LE1M */ +#define ESP_BLE_GAP_PRI_PHY_CODED ESP_BLE_GAP_PHY_CODED /*!< Primary Phy is LE CODED */ +typedef uint8_t esp_ble_gap_pri_phy_t; // primary phy + +#define ESP_BLE_GAP_PHY_1M_PREF_MASK (1 << 0) /*!< The Host prefers use the LE1M transmitter or reciever PHY */ +#define ESP_BLE_GAP_PHY_2M_PREF_MASK (1 << 1) /*!< The Host prefers use the LE2M transmitter or reciever PHY */ +#define ESP_BLE_GAP_PHY_CODED_PREF_MASK (1 << 2) /*!< The Host prefers use the LE CODED transmitter or reciever PHY */ +typedef uint8_t esp_ble_gap_phy_mask_t; + +#define ESP_BLE_GAP_PHY_OPTIONS_NO_PREF 0 /*!< The Host has no preferred coding when transmitting on the LE Coded PHY */ +#define ESP_BLE_GAP_PHY_OPTIONS_PREF_S2_CODING 1 /*!< The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY */ +#define ESP_BLE_GAP_PHY_OPTIONS_PREF_S8_CODING 2 /*!< The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY */ +typedef uint16_t esp_ble_gap_prefer_phy_options_t; + +#define ESP_BLE_GAP_EXT_SCAN_CFG_UNCODE_MASK 0x01 /*!< Scan Advertisements on the LE1M PHY */ +#define ESP_BLE_GAP_EXT_SCAN_CFG_CODE_MASK 0x02 /*!< Scan advertisements on the LE coded PHY */ +typedef uint8_t esp_ble_ext_scan_cfg_mask_t; + +/// Advertising data +#define ESP_BLE_GAP_EXT_ADV_DATA_COMPLETE 0x00 /*!< extended advertising data compete */ +#define ESP_BLE_GAP_EXT_ADV_DATA_INCOMPLETE 0x01 /*!< extended advertising data incomplete */ +#define ESP_BLE_GAP_EXT_ADV_DATA_TRUNCATED 0x02 /*!< extended advertising data truncated mode */ +typedef uint8_t esp_ble_gap_ext_adv_data_status_t; + +/// Advertising SYNC policy +#define ESP_BLE_GAP_SYNC_POLICY_BY_ADV_INFO 0 /*!< sync policy by advertising info */ +#define ESP_BLE_GAP_SYNC_POLICY_BY_PERIODIC_LIST 1 /*!< periodic advertising sync policy */ +typedef uint8_t esp_ble_gap_sync_t; + +/// Advertising report +#define ESP_BLE_ADV_REPORT_EXT_ADV_IND (1<<0) /*!< advertising report with extended advertising indication type */ +#define ESP_BLE_ADV_REPORT_EXT_SCAN_IND (1<<1) /*!< advertising report with extended scan indication type */ +#define ESP_BLE_ADV_REPORT_EXT_DIRECT_ADV (1<<2) /*!< advertising report with extended direct advertising indication type */ +#define ESP_BLE_ADV_REPORT_EXT_SCAN_RSP (1<<3) /*!< advertising report with extended scan response indication type */ + +/*!< Bluetooth 5.0, Vol 2, Part E, 7.7.65.13 */ +#define ESP_BLE_LEGACY_ADV_TYPE_IND (0x13) /*!< advertising report with legacy advertising indication type */ +#define ESP_BLE_LEGACY_ADV_TYPE_DIRECT_IND (0x15) /*!< advertising report with legacy direct indication type */ +#define ESP_BLE_LEGACY_ADV_TYPE_SCAN_IND (0x12) /*!< advertising report with legacy scan indication type */ +#define ESP_BLE_LEGACY_ADV_TYPE_NONCON_IND (0x10) /*!< advertising report with legacy non connectable indication type */ +#define ESP_BLE_LEGACY_ADV_TYPE_SCAN_RSP_TO_ADV_IND (0x1b) /*!< advertising report with legacy scan response indication type */ +#define ESP_BLE_LEGACY_ADV_TYPE_SCAN_RSP_TO_ADV_SCAN_IND (0x1a) /*!< advertising report with legacy advertising with scan response indication type */ + +typedef uint8_t esp_ble_gap_adv_type_t; + +/// Extend advertising tx power, range: [-127, +126] dBm +#define EXT_ADV_TX_PWR_NO_PREFERENCE (127) /*!< host has no preference for tx power */ + +/** +* @brief ext adv parameters +*/ +typedef struct { + esp_ble_ext_adv_type_mask_t type; /*!< ext adv type */ + uint32_t interval_min; /*!< ext adv minimum interval */ + uint32_t interval_max; /*!< ext adv maximum interval */ + esp_ble_adv_channel_t channel_map; /*!< ext adv channel map */ + esp_ble_addr_type_t own_addr_type; /*!< ext adv own address type */ + esp_ble_addr_type_t peer_addr_type; /*!< ext adv peer address type */ + esp_bd_addr_t peer_addr; /*!< ext adv peer address */ + esp_ble_adv_filter_t filter_policy; /*!< ext adv filter policy */ + int8_t tx_power; /*!< ext adv tx power */ + esp_ble_gap_pri_phy_t primary_phy; /*!< ext adv primary phy */ + uint8_t max_skip; /*!< ext adv maximum skip */ + esp_ble_gap_phy_t secondary_phy; /*!< ext adv secondary phy */ + uint8_t sid; /*!< ext adv sid */ + bool scan_req_notif; /*!< ext adv scan request event notify */ +} esp_ble_gap_ext_adv_params_t; + +/** +* @brief ext scan config +*/ +typedef struct { + esp_ble_scan_type_t scan_type; /*!< ext scan type */ + uint16_t scan_interval; /*!< ext scan interval */ + uint16_t scan_window; /*!< ext scan window */ +} esp_ble_ext_scan_cfg_t; + +/** +* @brief ext scan parameters +*/ +typedef struct { + esp_ble_addr_type_t own_addr_type; /*!< ext scan own address type */ + esp_ble_scan_filter_t filter_policy; /*!< ext scan filter policy */ + esp_ble_scan_duplicate_t scan_duplicate; /*!< ext scan duplicate scan */ + esp_ble_ext_scan_cfg_mask_t cfg_mask; /*!< ext scan config mask */ + esp_ble_ext_scan_cfg_t uncoded_cfg; /*!< ext scan uncoded config parameters */ + esp_ble_ext_scan_cfg_t coded_cfg; /*!< ext scan coded config parameters */ +} esp_ble_ext_scan_params_t; + +/** +* @brief create extend connection parameters +*/ +typedef struct { + uint16_t scan_interval; /*!< init scan interval */ + uint16_t scan_window; /*!< init scan window */ + uint16_t interval_min; /*!< minimum interval */ + uint16_t interval_max; /*!< maximum interval */ + uint16_t latency; /*!< ext scan type */ + uint16_t supervision_timeout; /*!< connection supervision timeout */ + uint16_t min_ce_len; /*!< minimum ce length */ + uint16_t max_ce_len; /*!< maximum ce length */ +} esp_ble_gap_conn_params_t; + +/** +* @brief extend adv enable parameters +*/ +typedef struct { + uint8_t instance; /*!< advertising handle */ + int duration; /*!< advertising duration */ + int max_events; /*!< maximum number of extended advertising events */ +} esp_ble_gap_ext_adv_t; + +/** +* @brief periodic adv parameters +*/ +typedef struct { + uint16_t interval_min; /*!< periodic advertising minimum interval */ + uint16_t interval_max; /*!< periodic advertising maximum interval */ + uint8_t properties; /*!< periodic advertising properties */ +} esp_ble_gap_periodic_adv_params_t; + +/** +* @brief periodic adv sync parameters +*/ +typedef struct { + esp_ble_gap_sync_t filter_policy; /*!< Configures the filter policy for periodic advertising sync: + 0: Use Advertising SID, Advertiser Address Type, and Advertiser Address parameters to determine the advertiser to listen to. + 1: Use the Periodic Advertiser List to determine the advertiser to listen to. */ + #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) + esp_ble_gap_sync_t reports_disabled; /*!< Supported only by esp32c2, esp32c6, and esp32h2; can be set by menuconfig: + 0: Reporting initially enabled. + 1: Reporting initially disabled. */ + esp_ble_gap_sync_t filter_duplicates; /*!< Supported only by esp32c2, esp32c6, and esp32h2; can be set by menuconfig: + 0: Duplicate filtering initially disabled. + 1: Duplicate filtering initially enabled. */ + #endif + uint8_t sid; /*!< SID of the periodic advertising */ + esp_ble_addr_type_t addr_type; /*!< Address type of the periodic advertising */ + esp_bd_addr_t addr; /*!< Address of the periodic advertising */ + uint16_t skip; /*!< Maximum number of periodic advertising events that can be skipped */ + uint16_t sync_timeout; /*!< Synchronization timeout */ +} esp_ble_gap_periodic_adv_sync_params_t; + +/** +* @brief extend adv report parameters +*/ +typedef struct { + // uint8_t props; + // uint8_t legacy_event_type; + esp_ble_gap_adv_type_t event_type; /*!< extend advertising type */ + uint8_t addr_type; /*!< extend advertising address type */ + esp_bd_addr_t addr; /*!< extend advertising address */ + esp_ble_gap_pri_phy_t primary_phy; /*!< extend advertising primary phy */ + esp_ble_gap_phy_t secondly_phy; /*!< extend advertising secondary phy */ + uint8_t sid; /*!< extend advertising sid */ + uint8_t tx_power; /*!< extend advertising tx power */ + int8_t rssi; /*!< extend advertising rssi */ + uint16_t per_adv_interval; /*!< periodic advertising interval */ + uint8_t dir_addr_type; /*!< direct address type */ + esp_bd_addr_t dir_addr; /*!< direct address */ + esp_ble_gap_ext_adv_data_status_t data_status; /*!< data type */ + uint8_t adv_data_len; /*!< extend advertising data length */ + uint8_t adv_data[251]; /*!< extend advertising data */ +} esp_ble_gap_ext_adv_reprot_t; + +/** +* @brief periodic adv report parameters +*/ +typedef struct { + uint16_t sync_handle; /*!< periodic advertising train handle */ + uint8_t tx_power; /*!< periodic advertising tx power*/ + int8_t rssi; /*!< periodic advertising rssi */ + esp_ble_gap_ext_adv_data_status_t data_status; /*!< periodic advertising data type*/ + uint8_t data_length; /*!< periodic advertising data length */ + uint8_t data[251]; /*!< periodic advertising data */ +} esp_ble_gap_periodic_adv_report_t; + +/** +* @brief perodic adv sync establish parameters +*/ +typedef struct { + uint8_t status; /*!< periodic advertising sync status */ + uint16_t sync_handle; /*!< periodic advertising train handle */ + uint8_t sid; /*!< periodic advertising sid */ + esp_ble_addr_type_t addr_type; /*!< periodic advertising address type */ + esp_bd_addr_t adv_addr; /*!< periodic advertising address */ + esp_ble_gap_phy_t adv_phy; /*!< periodic advertising adv phy type */ + uint16_t period_adv_interval; /*!< periodic advertising interval */ + uint8_t adv_clk_accuracy; /*!< periodic advertising clock accuracy */ +} esp_ble_gap_periodic_adv_sync_estab_t; + +/** +* @brief DTM TX parameters +*/ +typedef struct +{ + uint8_t tx_channel; /*!< channel for sending test data, tx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + uint8_t len_of_data; /*!< length in bytes of payload data in each packet */ + esp_ble_dtm_pkt_payload_t pkt_payload; /*!< packet payload type. value range: 0x00-0x07 */ + esp_ble_gap_phy_t phy; /*!< the phy type used by the transmitter, coded phy with S=2:0x04 */ +} esp_ble_dtm_enh_tx_t; + +/** +* @brief DTM RX parameters +*/ +typedef struct +{ + uint8_t rx_channel; /*!< channel for test data reception, rx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + esp_ble_gap_phy_t phy; /*!< the phy type used by the receiver, 1M phy: 0x01, 2M phy:0x02, coded phy:0x03 */ + uint8_t modulation_idx; /*!< modulation index, 0x00:standard modulation index, 0x01:stable modulation index */ +} esp_ble_dtm_enh_rx_t; + +#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +/// Periodic advertising sync trans mode +#define ESP_BLE_GAP_PAST_MODE_NO_SYNC_EVT (0x00) /*!< No attempt is made to sync and no periodic adv sync transfer received event */ +#define ESP_BLE_GAP_PAST_MODE_NO_REPORT_EVT (0x01) /*!< An periodic adv sync transfer received event and no periodic adv report events */ +#define ESP_BLE_GAP_PAST_MODE_DUP_FILTER_DISABLED (0x02) /*!< Periodic adv report events will be enabled with duplicate filtering disabled */ +#define ESP_BLE_GAP_PAST_MODE_DUP_FILTER_ENABLED (0x03) /*!< Periodic adv report events will be enabled with duplicate filtering enabled */ +typedef uint8_t esp_ble_gap_past_mode_t; + +/** +* @brief periodic adv sync transfer parameters +*/ +typedef struct { + esp_ble_gap_past_mode_t mode; /*!< periodic advertising sync transfer mode */ + uint16_t skip; /*!< the number of periodic advertising packets that can be skipped */ + uint16_t sync_timeout; /*!< synchronization timeout for the periodic advertising train */ + uint8_t cte_type; /*!< periodic advertising sync transfer CET type */ +} esp_ble_gap_past_params_t; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +/** + * @brief Gap callback parameters union + */ +typedef union { + /** + * @brief ESP_GAP_BLE_GET_DEV_NAME_COMPLETE_EVT + */ + struct ble_get_dev_name_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the get device name success status */ + char *name; /*!< Name of bluetooth device */ + } get_dev_name_cmpl; /*!< Event parameter of ESP_GAP_BLE_GET_DEV_NAME_COMPLETE_EVT */ +#if (BLE_42_FEATURE_SUPPORT == TRUE) + /** + * @brief ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT + */ + struct ble_adv_data_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set advertising data operation success status */ + } adv_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT + */ + struct ble_scan_rsp_data_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set scan response data operation success status */ + } scan_rsp_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT + */ + struct ble_scan_param_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set scan param operation success status */ + } scan_param_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_RESULT_EVT + */ + struct ble_scan_result_evt_param { + esp_gap_search_evt_t search_evt; /*!< Search event type */ + esp_bd_addr_t bda; /*!< Bluetooth device address which has been searched */ + esp_bt_dev_type_t dev_type; /*!< Device type */ + esp_ble_addr_type_t ble_addr_type; /*!< Ble device address type */ + esp_ble_evt_type_t ble_evt_type; /*!< Ble scan result event type */ + int rssi; /*!< Searched device's RSSI */ + uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX]; /*!< Received EIR */ + int flag; /*!< Advertising data flag bit */ + int num_resps; /*!< Scan result number */ + uint8_t adv_data_len; /*!< Adv data length */ + uint8_t scan_rsp_len; /*!< Scan response length */ + uint32_t num_dis; /*!< The number of discard packets */ + } scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT + */ + struct ble_adv_data_raw_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set raw advertising data operation success status */ + } adv_data_raw_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT + */ + struct ble_scan_rsp_data_raw_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set raw advertising data operation success status */ + } scan_rsp_data_raw_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_START_COMPLETE_EVT + */ + struct ble_adv_start_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate advertising start operation success status */ + } adv_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_START_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_START_COMPLETE_EVT + */ + struct ble_scan_start_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate scan start operation success status */ + } scan_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_START_COMPLETE_EVT */ +#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) + esp_ble_sec_t ble_security; /*!< ble gap security union type */ +#if (BLE_42_FEATURE_SUPPORT == TRUE) + /** + * @brief ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT + */ + struct ble_scan_stop_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate scan stop operation success status */ + } scan_stop_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT + */ + struct ble_adv_stop_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate adv stop operation success status */ + } adv_stop_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT + */ + struct ble_adv_clear_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate adv clear operation success status */ + } adv_clear_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT */ +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + /** + * @brief ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT + */ + struct ble_set_rand_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate set static rand address operation success status */ + } set_rand_addr_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT */ + /** + * @brief ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT + */ + struct ble_update_conn_params_evt_param { + esp_bt_status_t status; /*!< Indicate update connection parameters success status */ + esp_bd_addr_t bda; /*!< Bluetooth device address */ + uint16_t min_int; /*!< Min connection interval */ + uint16_t max_int; /*!< Max connection interval */ + uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */ + uint16_t conn_int; /*!< Current connection interval */ + uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80. + Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec */ + } update_conn_params; /*!< Event parameter of ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT + */ + struct ble_pkt_data_length_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set pkt data length operation success status */ + esp_ble_pkt_data_length_params_t params; /*!< pkt data length value */ + } pkt_data_length_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT + */ + struct ble_local_privacy_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set local privacy operation success status */ + } local_privacy_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT + */ + struct ble_remove_bond_dev_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */ + esp_bd_addr_t bd_addr; /*!< The device address which has been remove from the bond list */ + } remove_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT + */ + struct ble_clear_bond_dev_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the clear bond device operation success status */ + } clear_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT + */ + struct ble_get_bond_dev_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the get bond device operation success status */ + uint8_t dev_num; /*!< Indicate the get number device in the bond list */ + esp_ble_bond_dev_t *bond_dev; /*!< the pointer to the bond device Structure */ + } get_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT + */ + struct ble_read_rssi_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the read adv tx power operation success status */ + int8_t rssi; /*!< The ble remote device rssi value, the range is from -127 to 20, the unit is dbm, + if the RSSI cannot be read, the RSSI metric shall be set to 127. */ + esp_bd_addr_t remote_addr; /*!< The remote device address */ + } read_rssi_cmpl; /*!< Event parameter of ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT + */ + struct ble_update_whitelist_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the add or remove whitelist operation success status */ + esp_ble_wl_operation_t wl_operation; /*!< The value is ESP_BLE_WHITELIST_ADD if add address to whitelist operation success, ESP_BLE_WHITELIST_REMOVE if remove address from the whitelist operation success */ + } update_whitelist_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT */ +#if (BLE_42_FEATURE_SUPPORT == TRUE) + /** + * @brief ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT + */ + struct ble_update_duplicate_exceptional_list_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate update duplicate scan exceptional list operation success status */ + uint8_t subcode; /*!< Define in esp_bt_duplicate_exceptional_subcode_type_t */ + uint16_t length; /*!< The length of device_info */ + esp_duplicate_info_t device_info; /*!< device information, when subcode is ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN, the value is invalid */ + } update_duplicate_exceptional_list_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT */ +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + /** + * @brief ESP_GAP_BLE_SET_CHANNELS_EVT + */ + struct ble_set_channels_evt_param { + esp_bt_status_t stat; /*!< BLE set channel status */ + } ble_set_channels; /*!< Event parameter of ESP_GAP_BLE_SET_CHANNELS_EVT */ + +#if (BLE_50_FEATURE_SUPPORT == TRUE) + /** + * @brief ESP_GAP_BLE_READ_PHY_COMPLETE_EVT + */ + struct ble_read_phy_cmpl_evt_param { + esp_bt_status_t status; /*!< read phy complete status */ + esp_bd_addr_t bda; /*!< read phy address */ + esp_ble_gap_phy_t tx_phy; /*!< tx phy type */ + esp_ble_gap_phy_t rx_phy; /*!< rx phy type */ + } read_phy; /*!< Event parameter of ESP_GAP_BLE_READ_PHY_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PREFERRED_DEFAULT_PHY_COMPLETE_EVT + */ + struct ble_set_perf_def_phy_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate perf default phy set status */ + } set_perf_def_phy; /*!< Event parameter of ESP_GAP_BLE_SET_PREFERRED_DEFAULT_PHY_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PREFERRED_PHY_COMPLETE_EVT + */ + struct ble_set_perf_phy_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate perf phy set status */ + } set_perf_phy; /*!< Event parameter of ESP_GAP_BLE_SET_PREFERRED_PHY_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT + */ + struct ble_ext_adv_set_rand_addr_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate extend advertising random address set status */ + } ext_adv_set_rand_addr; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT + */ + struct ble_ext_adv_set_params_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate extend advertising parameters set status */ + } ext_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT + */ + struct ble_ext_adv_data_set_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate extend advertising data set status */ + } ext_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT + */ + struct ble_ext_adv_scan_rsp_set_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate extend advertising scan response data set status */ + } scan_rsp_set; /*!< Event parameter of ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT + */ + struct ble_ext_adv_start_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate advertising start operation success status */ + } ext_adv_start; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT + */ + struct ble_ext_adv_stop_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + } ext_adv_stop; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT + */ + struct ble_ext_adv_set_remove_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + } ext_adv_remove; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT + */ + struct ble_ext_adv_set_clear_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + } ext_adv_clear; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT + */ + struct ble_periodic_adv_set_params_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertisingparameters set status */ + } peroid_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT + */ + struct ble_periodic_adv_data_set_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising data set status */ + } period_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT + */ + struct ble_periodic_adv_start_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising start status */ + } period_adv_start; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT + */ + struct ble_periodic_adv_stop_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising stop status */ + } period_adv_stop; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT + */ + struct ble_period_adv_create_sync_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising create sync status */ + } period_adv_create_sync; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT + */ + struct ble_period_adv_sync_cancel_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising sync cancel status */ + } period_adv_sync_cancel; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT + */ + struct ble_period_adv_sync_terminate_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising sync terminate status */ + } period_adv_sync_term; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT + */ + struct ble_period_adv_add_dev_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising device list add status */ + } period_adv_add_dev; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT + */ + struct ble_period_adv_remove_dev_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising device list remove status */ + } period_adv_remove_dev; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT + */ + struct ble_period_adv_clear_dev_cmpl_param { + esp_bt_status_t status; /*!< Indicate periodic advertising device list clean status */ + } period_adv_clear_dev; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT + */ + struct ble_set_ext_scan_params_cmpl_param { + esp_bt_status_t status; /*!< Indicate extend advertising parameters set status */ + } set_ext_scan_params; /*!< Event parameter of ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT + */ + struct ble_ext_scan_start_cmpl_param { + esp_bt_status_t status; /*!< Indicate extend advertising start status */ + } ext_scan_start; /*!< Event parameter of ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_SCAN_STOP_COMPLETE_EVT + */ + struct ble_ext_scan_stop_cmpl_param { + esp_bt_status_t status; /*!< Indicate extend advertising stop status */ + } ext_scan_stop; /*!< Event parameter of ESP_GAP_BLE_EXT_SCAN_STOP_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT + */ + struct ble_ext_conn_params_set_cmpl_param { + esp_bt_status_t status; /*!< Indicate extend connection parameters set status */ + } ext_conn_params_set; /*!< Event parameter of ESP_GAP_BLE_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_TERMINATED_EVT + */ + struct ble_adv_terminate_param { + uint8_t status; /*!< Indicate adv terminate status */ + /* status 0x3c indicates that advertising for a fixed duration completed or, + for directed advertising, that advertising completed without a connection + being created; + status 0x00 indicates that advertising successfully ended with a connection being created. + */ + uint8_t adv_instance; /*!< extend advertising handle */ + uint16_t conn_idx; /*!< connection index */ + uint8_t completed_event; /*!< the number of completed extend advertising events */ + } adv_terminate; /*!< Event parameter of ESP_GAP_BLE_ADV_TERMINATED_EVT */ + /** + * @brief ESP_GAP_BLE_SCAN_REQ_RECEIVED_EVT + */ + struct ble_scan_req_received_param { + uint8_t adv_instance; /*!< extend advertising handle */ + esp_ble_addr_type_t scan_addr_type; /*!< scanner address type */ + esp_bd_addr_t scan_addr; /*!< scanner address */ + } scan_req_received; /*!< Event parameter of ESP_GAP_BLE_SCAN_REQ_RECEIVED_EVT */ + /** + * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT + */ + struct ble_channel_sel_alg_param { + uint16_t conn_handle; /*!< connection handle */ + uint8_t channel_sel_alg; /*!< channel selection algorithm */ + } channel_sel_alg; /*!< Event parameter of ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT + */ + struct ble_periodic_adv_sync_lost_param { + uint16_t sync_handle; /*!< sync handle */ + } periodic_adv_sync_lost; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_LOST_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT + */ + struct ble_periodic_adv_sync_estab_param { + uint8_t status; /*!< periodic advertising sync status */ + uint16_t sync_handle; /*!< periodic advertising sync handle */ + uint8_t sid; /*!< periodic advertising sid */ + esp_ble_addr_type_t adv_addr_type; /*!< periodic advertising address type */ + esp_bd_addr_t adv_addr; /*!< periodic advertising address */ + esp_ble_gap_phy_t adv_phy; /*!< periodic advertising phy type */ + uint16_t period_adv_interval; /*!< periodic advertising interval */ + uint8_t adv_clk_accuracy; /*!< periodic advertising clock accuracy */ + } periodic_adv_sync_estab; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT */ + /** + * @brief ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT + */ + struct ble_phy_update_cmpl_param { + esp_bt_status_t status; /*!< phy update status */ + esp_bd_addr_t bda; /*!< address */ + esp_ble_gap_phy_t tx_phy; /*!< tx phy type */ + esp_ble_gap_phy_t rx_phy; /*!< rx phy type */ + } phy_update; /*!< Event parameter of ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_EXT_ADV_REPORT_EVT + */ + struct ble_ext_adv_report_param { + esp_ble_gap_ext_adv_reprot_t params; /*!< extend advertising report parameters */ + } ext_adv_report; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_REPORT_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT + */ + struct ble_periodic_adv_report_param { + esp_ble_gap_periodic_adv_report_t params; /*!< periodic advertising report parameters */ + } period_adv_report; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT */ +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT + */ + struct ble_periodic_adv_recv_enable_cmpl_param { + esp_bt_status_t status; /*!< Set periodic advertising receive enable status */ + } period_adv_recv_enable; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT + */ + struct ble_periodic_adv_sync_trans_cmpl_param { + esp_bt_status_t status; /*!< Periodic advertising sync transfer status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } period_adv_sync_trans; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT + */ + struct ble_periodic_adv_set_info_trans_cmpl_param { + esp_bt_status_t status; /*!< Periodic advertising set info transfer status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } period_adv_set_info_trans; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT + */ + struct ble_set_past_params_cmpl_param { + esp_bt_status_t status; /*!< Set periodic advertising sync transfer params status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } set_past_params; /*!< Event parameter of ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT + */ + struct ble_periodic_adv_sync_trans_recv_param { + esp_bt_status_t status; /*!< Periodic advertising sync transfer received status */ + esp_bd_addr_t bda; /*!< The remote device address */ + uint16_t service_data; /*!< The value provided by the peer device */ + uint16_t sync_handle; /*!< Periodic advertising sync handle */ + uint8_t adv_sid; /*!< Periodic advertising set id */ + uint8_t adv_addr_type; /*!< Periodic advertiser address type */ + esp_bd_addr_t adv_addr; /*!< Periodic advertiser address */ + esp_ble_gap_phy_t adv_phy; /*!< Periodic advertising PHY */ + uint16_t adv_interval; /*!< Periodic advertising interval */ + uint8_t adv_clk_accuracy; /*!< Periodic advertising clock accuracy */ + } past_received; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT */ +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /** + * @brief ESP_GAP_BLE_DTM_TEST_UPDATE_EVT + */ + struct ble_dtm_state_update_evt_param { + esp_bt_status_t status; /*!< Indicate DTM operation success status */ + esp_ble_dtm_update_evt_t update_evt; /*!< DTM state change event, 0x00: DTM TX start, 0x01: DTM RX start, 0x02:DTM end */ + uint16_t num_of_pkt; /*!< number of packets received, only valid if update_evt is DTM_TEST_STOP_EVT and shall be reported as 0 for a transmitter */ + } dtm_state_update; /*!< Event parameter of ESP_GAP_BLE_DTM_TEST_UPDATE_EVT */ +} esp_ble_gap_cb_param_t; + +/** + * @brief GAP callback function type + * @param event : Event type + * @param param : Point to callback parameter, currently is union type + */ +typedef void (* esp_gap_ble_cb_t)(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); + +/** + * @brief This function is called to occur gap event, such as scan result + * + * @param[in] callback: callback function + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback); + +/** + * @brief This function is called to get the current gap callback + * + * @return + * - esp_gap_ble_cb_t : callback function + * + */ +esp_gap_ble_cb_t esp_ble_gap_get_callback(void); + +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/** + * @brief This function is called to override the BTA default ADV parameters. + * + * @param[in] adv_data: Pointer to User defined ADV data structure. This + * memory space can not be freed until callback of config_adv_data + * is received. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_config_adv_data (esp_ble_adv_data_t *adv_data); + + + +/** + * @brief This function is called to set scan parameters + * + * @param[in] scan_params: Pointer to User defined scan_params data structure. This + * memory space can not be freed until callback of set_scan_params + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params); + + +/** + * @brief This procedure keep the device scanning the peer device which advertising on the air + * + * @param[in] duration: Keeping the scanning time, the unit is second. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_start_scanning(uint32_t duration); + + +/** + * @brief This function call to stop the device scanning the peer device which advertising on the air + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_stop_scanning(void); + +/** + * @brief This function is called to start advertising. + * + * @param[in] adv_params: pointer to User defined adv_params data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_start_advertising (esp_ble_adv_params_t *adv_params); + + + +/** + * @brief This function is called to stop advertising. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_stop_advertising(void); +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + + +/** + * @brief Update connection parameters, can only be used when connection is up. + * + * @param[in] params - connection update parameters + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params); + + +/** + * @brief This function is to set maximum LE data packet size + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_data_length); + +/** + * @brief This function allows configuring either a Non-Resolvable Private Address or a Static Random Address + * + * @param[in] rand_addr: The address to be configured. Refer to the table below for possible address subtypes: + * + * | address [47:46] | Address Type | + * |-----------------|--------------------------| + * | 0b00 | Non-Resolvable Private | + * | | Address | + * |-----------------|--------------------------| + * | 0b11 | Static Random Address | + * |-----------------|--------------------------| + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr); + +/** + * @brief This function clears the random address for the application + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_clear_rand_addr(void); + + + +/** + * @brief Enable/disable privacy (including address resolution) on the local device + * + * @param[in] privacy_enable - enable/disable privacy on remote device. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable); + +/** + * @brief set local gap appearance icon + * + * + * @param[in] icon - External appearance value, these values are defined by the Bluetooth SIG, please refer to + * https://www.bluetooth.com/specifications/assigned-numbers/ + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_config_local_icon (uint16_t icon); + +/** +* @brief Add or remove device from white list +* +* @param[in] add_remove: the value is true if added the ble device to the white list, and false remove to the white list. +* @param[in] remote_bda: the remote device address add/remove from the white list. +* @param[in] wl_addr_type: whitelist address type +* @return +* - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_update_whitelist(bool add_remove, esp_bd_addr_t remote_bda, esp_ble_wl_addr_type_t wl_addr_type); + +/** +* @brief Clear all white list +* +* @return +* - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_clear_whitelist(void); + +/** +* @brief Get the whitelist size in the controller +* +* @param[out] length: the white list length. +* @return +* - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_get_whitelist_size(uint16_t *length); +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/** +* @brief This function is called to set the preferred connection +* parameters when default connection parameter is not desired before connecting. +* This API can only be used in the master role. +* +* @param[in] bd_addr: BD address of the peripheral +* @param[in] min_conn_int: minimum preferred connection interval +* @param[in] max_conn_int: maximum preferred connection interval +* @param[in] slave_latency: preferred slave latency +* @param[in] supervision_tout: preferred supervision timeout +* +* @return +* - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_prefer_conn_params(esp_bd_addr_t bd_addr, + uint16_t min_conn_int, uint16_t max_conn_int, + uint16_t slave_latency, uint16_t supervision_tout); +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) +/** + * @brief Set device name to the local device + * Note: This API don't affect the advertising data + * + * @param[in] name - device name. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_set_device_name(const char *name); + +/** + * @brief Get device name of the local device + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_get_device_name(void); + +/** + * @brief This function is called to get local used address and address type. + * uint8_t *esp_bt_dev_get_address(void) get the public address + * + * @param[in] local_used_addr - current local used ble address (six bytes) + * @param[in] addr_type - ble address type + * + * @return - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t * addr_type); +/** + * @brief This function is called to get ADV data for a specific type. + * + * @param[in] adv_data - pointer of ADV data which to be resolved + * @param[in] type - finding ADV data type + * @param[out] length - return the length of ADV data not including type + * + * @return pointer of ADV data + * + */ +uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length); +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/** + * @brief This function is called to set raw advertising data. User need to fill + * ADV data by self. + * + * @param[in] raw_data : raw advertising data with the format: [Length 1][Data Type 1][Data 1][Length 2][Data Type 2][Data 2] ... + * @param[in] raw_data_len : raw advertising data length , less than 31 bytes + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len); + +/** + * @brief This function is called to set raw scan response data. User need to fill + * scan response data by self. + * + * @param[in] raw_data : raw scan response data + * @param[in] raw_data_len : raw scan response data length , less than 31 bytes + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len); +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +/** + * @brief This function is called to read the RSSI of remote device. + * The address of link policy results are returned in the gap callback function with + * ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT event. + * + * @param[in] remote_addr : The remote connection device address. + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr); +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/** + * @brief This function is called to add a device info into the duplicate scan exceptional list. + * + * + * @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t + * when type is MESH_BEACON_TYPE, MESH_PROV_SRV_ADV or MESH_PROXY_SRV_ADV , device_info is invalid. + * @param[in] device_info: the device information. + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info); + +/** + * @brief This function is called to remove a device info from the duplicate scan exceptional list. + * + * + * @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t + * when type is MESH_BEACON_TYPE, MESH_PROV_SRV_ADV or MESH_PROXY_SRV_ADV , device_info is invalid. + * @param[in] device_info: the device information. + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info); + +/** + * @brief This function is called to clean the duplicate scan exceptional list. + * This API will delete all device information in the duplicate scan exceptional list. + * + * + * @param[in] list_type: duplicate scan exceptional list type, the value can be one or more of esp_duplicate_scan_exceptional_list_type_t. + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_clean_duplicate_scan_exceptional_list(esp_duplicate_scan_exceptional_list_type_t list_type); +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (SMP_INCLUDED == TRUE) +/** +* @brief Set a GAP security parameter value. Overrides the default value. +* +* Secure connection is highly recommended to avoid some major +* vulnerabilities like 'Impersonation in the Pin Pairing Protocol' +* (CVE-2020-26555) and 'Authentication of the LE Legacy Pairing +* Protocol'. +* +* To accept only `secure connection mode`, it is necessary do as following: +* +* 1. Set bit `ESP_LE_AUTH_REQ_SC_ONLY` (`param_type` is +* `ESP_BLE_SM_AUTHEN_REQ_MODE`), bit `ESP_LE_AUTH_BOND` and bit +* `ESP_LE_AUTH_REQ_MITM` is optional as required. +* +* 2. Set to `ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE` (`param_type` is +* `ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH`). +* +* @param[in] param_type : the type of the param which to be set +* @param[in] value : the param value +* @param[in] len : the length of the param value +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type, + void *value, uint8_t len); + +/** +* @brief Grant security request access. +* +* @param[in] bd_addr : BD address of the peer +* @param[in] accept : accept the security request or not +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_security_rsp(esp_bd_addr_t bd_addr, bool accept); + + +/** +* @brief Set a gap parameter value. Use this function to change +* the default GAP parameter values. +* +* @param[in] bd_addr : the address of the peer device need to encryption +* @param[in] sec_act : This is the security action to indicate +* what kind of BLE security level is required for +* the BLE link if the BLE is supported +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_act); + +/** +* @brief Reply the key value to the peer device in the legacy connection stage. +* +* @param[in] bd_addr : BD address of the peer +* @param[in] accept : passkey entry successful or declined. +* @param[in] passkey : passkey value, must be a 6 digit number, +* can be lead by 0. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey); + + +/** +* @brief Reply the confirm value to the peer device in the secure connection stage. +* +* @param[in] bd_addr : BD address of the peer device +* @param[in] accept : numbers to compare are the same or different. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept); + +/** +* @brief Removes a device from the security database list of +* peer device. It manages unpairing event while connected. +* +* @param[in] bd_addr : BD address of the peer device +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr); + +/** +* @brief Get the device number from the security database list of peer device. +* It will return the device bonded number immediately. +* +* @return - >= 0 : bonded devices number. +* - ESP_FAIL : failed +* +*/ +int esp_ble_get_bond_device_num(void); + + +/** +* @brief Get the device from the security database list of peer device. +* It will return the device bonded information immediately. +* @param[inout] dev_num: Indicate the dev_list array(buffer) size as input. +* If dev_num is large enough, it means the actual number as output. +* Suggest that dev_num value equal to esp_ble_get_bond_device_num(). +* +* @param[out] dev_list: an array(buffer) of `esp_ble_bond_dev_t` type. Use for storing the bonded devices address. +* The dev_list should be allocated by who call this API. +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list); + +/** +* @brief This function is called to provide the OOB data for +* SMP in response to ESP_GAP_BLE_OOB_REQ_EVT +* +* @param[in] bd_addr: BD address of the peer device. +* @param[in] TK: Temporary Key value, the TK value shall be a 128-bit random number +* @param[in] len: length of temporary key, should always be 128-bit +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len); + +/** +* @brief This function is called to provide the OOB data for +* SMP in response to ESP_GAP_BLE_SC_OOB_REQ_EVT +* +* @param[in] bd_addr: BD address of the peer device. +* @param[in] p_c: Confirmation value, it shall be a 128-bit random number +* @param[in] p_r: Randomizer value, it should be a 128-bit random number +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8_t p_r[16]); + +/** +* @brief This function is called to create the OOB data for +* SMP when secure connection +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_create_sc_oob_data(void); +#endif /* #if (SMP_INCLUDED == TRUE) */ + +/** +* @brief This function is to disconnect the physical connection of the peer device +* gattc may have multiple virtual GATT server connections when multiple app_id registered. +* esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id) only close one virtual GATT server connection. +* if there exist other virtual GATT server connections, it does not disconnect the physical connection. +* esp_ble_gap_disconnect(esp_bd_addr_t remote_device) disconnect the physical connection directly. +* +* +* +* @param[in] remote_device : BD address of the peer device +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device); + +/** +* @brief This function is called to read the connection +* parameters information of the device +* +* @param[in] bd_addr: BD address of the peer device. +* @param[out] conn_params: the connection parameters information +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_get_current_conn_params(esp_bd_addr_t bd_addr, esp_gap_conn_params_t *conn_params); + +/** +* @brief BLE set channels +* +* @param[in] channels : The n th such field (in the range 0 to 36) contains the value for the link layer channel index n. +* 0 means channel n is bad. +* 1 means channel n is unknown. +* The most significant bits are reserved and shall be set to 0. +* At least one channel shall be marked as unknown. +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +* +*/ +esp_err_t esp_gap_ble_set_channels(esp_gap_ble_channels channels); + +/** +* @brief This function is called to authorized a link after Authentication(MITM protection) +* +* @param[in] bd_addr: BD address of the peer device. +* @param[out] authorize: Authorized the link or not. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_gap_ble_set_authorization(esp_bd_addr_t bd_addr, bool authorize); + +#if (BLE_50_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to read the current transmitter PHY +* and receiver PHY on the connection identified by remote address. +* +* @param[in] bd_addr : BD address of the peer device +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_read_phy(esp_bd_addr_t bd_addr); + +/** +* @brief This function is used to allows the Host to specify its preferred values +* for the transmitter PHY and receiver PHY to be used for all subsequent connections +* over the LE transport. +* +* @param[in] tx_phy_mask : indicates the transmitter PHYs that the Host prefers the Controller to use +* @param[in] rx_phy_mask : indicates the receiver PHYs that the Host prefers the Controller to use +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_preferred_default_phy(esp_ble_gap_phy_mask_t tx_phy_mask, esp_ble_gap_phy_mask_t rx_phy_mask); +/** +* @brief This function is used to set the PHY preferences for the connection identified by the remote address. +* The Controller might not be able to make the change (e.g. because the peer does not support the requested PHY) +* or may decide that the current PHY is preferable. +* +* @param[in] bd_addr : remote address +* @param[in] all_phys_mask : a bit field that allows the Host to specify +* @param[in] tx_phy_mask : a bit field that indicates the transmitter PHYs that the Host prefers the Controller to use +* @param[in] rx_phy_mask : a bit field that indicates the receiver PHYs that the Host prefers the Controller to use +* @param[in] phy_options : a bit field that allows the Host to specify options for PHYs +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_preferred_phy(esp_bd_addr_t bd_addr, + esp_ble_gap_all_phys_t all_phys_mask, + esp_ble_gap_phy_mask_t tx_phy_mask, + esp_ble_gap_phy_mask_t rx_phy_mask, + esp_ble_gap_prefer_phy_options_t phy_options); + +/** +* @brief This function is used by the Host to set the random device address specified by the Random_Address parameter. +* +* @param[in] instance : Used to identify an advertising set +* @param[in] rand_addr : Random Device Address +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_ext_adv_set_rand_addr(uint8_t instance, esp_bd_addr_t rand_addr); + +/** +* @brief This function is used by the Host to set the advertising parameters. +* +* @param[in] instance : identifies the advertising set whose parameters are being configured. +* @param[in] params : advertising parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_ext_adv_set_params(uint8_t instance, const esp_ble_gap_ext_adv_params_t *params); + +/** +* @brief This function is used to set the data used in advertising PDUs that have a data field +* +* @param[in] instance : identifies the advertising set whose data are being configured +* @param[in] length : data length +* @param[in] data : data information +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_config_ext_adv_data_raw(uint8_t instance, uint16_t length, const uint8_t *data); + +/** +* @brief This function is used to provide scan response data used in scanning response PDUs +* +* @param[in] instance : identifies the advertising set whose response data are being configured. +* @param[in] length : responsedata length +* @param[in] scan_rsp_data : response data information +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_config_ext_scan_rsp_data_raw(uint8_t instance, uint16_t length, + const uint8_t *scan_rsp_data); +/** +* @brief This function is used to request the Controller to enable one or more +* advertising sets using the advertising sets identified by the instance parameter. +* +* @param[in] num_adv : Number of advertising sets to enable or disable +* @param[in] ext_adv : adv parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_ext_adv_start(uint8_t num_adv, const esp_ble_gap_ext_adv_t *ext_adv); + +/** +* @brief This function is used to request the Controller to disable one or more +* advertising sets using the advertising sets identified by the instance parameter. +* +* @param[in] num_adv : Number of advertising sets to enable or disable +* @param[in] ext_adv_inst : ext adv instance +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_ext_adv_stop(uint8_t num_adv, const uint8_t *ext_adv_inst); + +/** +* @brief This function is used to remove an advertising set from the Controller. +* +* @param[in] instance : Used to identify an advertising set +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_ext_adv_set_remove(uint8_t instance); + +/** +* @brief This function is used to remove all existing advertising sets from the Controller. +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_ext_adv_set_clear(void); + +/** +* @brief This function is used by the Host to set the parameters for periodic advertising. +* +* @param[in] instance : identifies the advertising set whose periodic advertising parameters are being configured. +* @param[in] params : periodic adv parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_set_params(uint8_t instance, const esp_ble_gap_periodic_adv_params_t *params); + +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +/** +* @brief This function is used to set the data used in periodic advertising PDUs. +* +* @param[in] instance : identifies the advertising set whose periodic advertising parameters are being configured. +* @param[in] length : the length of periodic data +* @param[in] data : periodic data information +* @param[in] only_update_did : If true, only the Advertising DID of the periodic advertising will be updated, and the length and data parameters will be ignored. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, + const uint8_t *data, bool only_update_did); +#else +/** +* @brief This function is used to set the data used in periodic advertising PDUs. +* +* @param[in] instance : identifies the advertising set whose periodic advertising parameters are being configured. +* @param[in] length : the length of periodic data +* @param[in] data : periodic data information +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, + const uint8_t *data); +#endif + +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +/** +* @brief This function is used to request the Controller to enable the periodic advertising for the advertising set specified +* +* @param[in] instance : Used to identify an advertising set +* @param[in] include_adi : If true, the ADI (Advertising Data Info) field will be included in AUX_SYNC_IND PDUs +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance,bool include_adi); +#else +/** +* @brief This function is used to request the Controller to enable the periodic advertising for the advertising set specified +* +* @param[in] instance : Used to identify an advertising set +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance); +#endif + +/** +* @brief This function is used to request the Controller to disable the periodic advertising for the advertising set specified +* +* @param[in] instance : Used to identify an advertising set +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_stop(uint8_t instance); + +/** +* @brief This function is used to set the extended scan parameters to be used on the advertising channels. +* +* @param[in] params : scan parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_ext_scan_params(const esp_ble_ext_scan_params_t *params); + +/** +* @brief This function is used to enable scanning. +* +* @param[in] duration Scan duration time, where Time = N * 10 ms. Range: 0x0001 to 0xFFFF. +* @param[in] period Time interval from when the Controller started its last Scan Duration until it begins the subsequent Scan Duration. +* Time = N * 1.28 sec. Range: 0x0001 to 0xFFFF. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_start_ext_scan(uint32_t duration, uint16_t period); + +/** +* @brief This function is used to disable scanning. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_stop_ext_scan(void); + +/** +* @brief This function is used to synchronize with periodic advertising from an advertiser and begin receiving periodic advertising packets. +* +* @param[in] params : sync parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_create_sync(const esp_ble_gap_periodic_adv_sync_params_t *params); + +/** +* @brief This function is used to cancel the LE_Periodic_Advertising_Create_Sync command while it is pending. +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_sync_cancel(void); + +/** +* @brief This function is used to stop reception of the periodic advertising identified by the Sync Handle parameter. +* +* @param[in] sync_handle : identify the periodic advertiser +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_sync_terminate(uint16_t sync_handle); + +/** +* @brief This function is used to add a single device to the Periodic Advertiser list stored in the Controller +* +* @param[in] addr_type : address type +* @param[in] addr : Device Address +* @param[in] sid : Advertising SID subfield in the ADI field used to identify the Periodic Advertising +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_add_dev_to_list(esp_ble_addr_type_t addr_type, + esp_bd_addr_t addr, + uint8_t sid); + +/** +* @brief This function is used to remove one device from the list of Periodic Advertisers stored in the Controller. +* Removals from the Periodic Advertisers List take effect immediately. +* +* @param[in] addr_type : address type +* @param[in] addr : Device Address +* @param[in] sid : Advertising SID subfield in the ADI field used to identify the Periodic Advertising +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_remove_dev_from_list(esp_ble_addr_type_t addr_type, + esp_bd_addr_t addr, + uint8_t sid); +/** +* @brief This function is used to remove all devices from the list of Periodic Advertisers in the Controller. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_clear_dev(void); + +/** +* @brief This function is used to set aux connection parameters +* +* @param[in] addr : device address +* @param[in] phy_mask : indicates the PHY(s) on which the advertising packets should be received on the primary advertising channel and the PHYs for which connection parameters have been specified. +* @param[in] phy_1m_conn_params : Scan connectable advertisements on the LE 1M PHY. Connection parameters for the LE 1M PHY are provided. +* @param[in] phy_2m_conn_params : Connection parameters for the LE 2M PHY are provided. +* @param[in] phy_coded_conn_params : Scan connectable advertisements on the LE Coded PHY. Connection parameters for the LE Coded PHY are provided. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, + esp_ble_gap_phy_mask_t phy_mask, + const esp_ble_gap_conn_params_t *phy_1m_conn_params, + const esp_ble_gap_conn_params_t *phy_2m_conn_params, + const esp_ble_gap_conn_params_t *phy_coded_conn_params); + +#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +/** +* @brief This function is used to set periodic advertising receive enable +* +* @param[in] sync_handle : Handle of periodic advertising sync +* @param[in] enable : Determines whether reporting and duplicate filtering are enabled or disabled +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_recv_enable(uint16_t sync_handle, uint8_t enable); + +/** +* @brief This function is used to transfer periodic advertising sync +* +* @param[in] addr : Peer device address +* @param[in] service_data : Service data used by Host +* @param[in] sync_handle : Handle of periodic advertising sync +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_sync_trans(esp_bd_addr_t addr, + uint16_t service_data, uint16_t sync_handle); + +/** +* @brief This function is used to transfer periodic advertising set info +* +* @param[in] addr : Peer device address +* @param[in] service_data : Service data used by Host +* @param[in] adv_handle : Handle of advertising set +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_set_info_trans(esp_bd_addr_t addr, + uint16_t service_data, uint8_t adv_handle); + +/** +* @brief This function is used to set periodic advertising sync transfer params +* +* @param[in] addr : Peer device address +* @param[in] params : Params of periodic advertising sync transfer +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, + const esp_ble_gap_past_params_t *params); +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +#if (BLE_42_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to start a test where the DUT generates reference packets +* at a fixed interval. +* +* @param[in] tx_params : DTM Transmitter parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_tx_start(const esp_ble_dtm_tx_t *tx_params); + +/** +* @brief This function is used to start a test where the DUT receives test reference packets +* at a fixed interval. +* +* @param[in] rx_params : DTM Receiver parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params); +#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to start a test where the DUT generates reference packets +* at a fixed interval. +* +* @param[in] tx_params : DTM Transmitter parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params); + +/** +* @brief This function is used to start a test where the DUT receives test reference packets +* at a fixed interval. +* +* @param[in] rx_params : DTM Receiver parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to stop any test which is in progress +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_stop(void); + +/** +* @brief This function is used to clear legacy advertising +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_clear_advertising(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_GAP_BLE_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h new file mode 100644 index 00000000..6396534f --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h @@ -0,0 +1,916 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_GAP_BT_API_H__ +#define __ESP_GAP_BT_API_H__ + +#include <stdint.h> +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// RSSI threshold +#define ESP_BT_GAP_RSSI_HIGH_THRLD -20 /*!< High RSSI threshold */ +#define ESP_BT_GAP_RSSI_LOW_THRLD -45 /*!< Low RSSI threshold */ + +/// Class of device +typedef struct { + uint32_t reserved_2: 2; /*!< undefined */ + uint32_t minor: 6; /*!< minor class */ + uint32_t major: 5; /*!< major class */ + uint32_t service: 11; /*!< service class */ + uint32_t reserved_8: 8; /*!< undefined */ +} esp_bt_cod_t; + +/// class of device settings +typedef enum { + ESP_BT_SET_COD_MAJOR_MINOR = 0x01, /*!< overwrite major, minor class */ + ESP_BT_SET_COD_SERVICE_CLASS = 0x02, /*!< set the bits in the input, the current bit will remain */ + ESP_BT_CLR_COD_SERVICE_CLASS = 0x04, /*!< clear the bits in the input, others will remain */ + ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class */ + ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class */ +} esp_bt_cod_mode_t; + +#define ESP_BT_GAP_AFH_CHANNELS_LEN 10 +typedef uint8_t esp_bt_gap_afh_channels[ESP_BT_GAP_AFH_CHANNELS_LEN]; + + +/// Discoverability and Connectability mode +typedef enum { + ESP_BT_NON_CONNECTABLE, /*!< Non-connectable */ + ESP_BT_CONNECTABLE, /*!< Connectable */ +} esp_bt_connection_mode_t; + +typedef enum { + ESP_BT_NON_DISCOVERABLE, /*!< Non-discoverable */ + ESP_BT_LIMITED_DISCOVERABLE, /*!< Limited Discoverable */ + ESP_BT_GENERAL_DISCOVERABLE, /*!< General Discoverable */ +} esp_bt_discovery_mode_t; + +/// Bluetooth Device Property type +typedef enum { + ESP_BT_GAP_DEV_PROP_BDNAME = 1, /*!< Bluetooth device name, value type is int8_t [] */ + ESP_BT_GAP_DEV_PROP_COD, /*!< Class of Device, value type is uint32_t */ + ESP_BT_GAP_DEV_PROP_RSSI, /*!< Received Signal strength Indication, value type is int8_t, ranging from -128 to 127 */ + ESP_BT_GAP_DEV_PROP_EIR, /*!< Extended Inquiry Response, value type is uint8_t [] */ +} esp_bt_gap_dev_prop_type_t; + +/// Maximum bytes of Bluetooth device name +#define ESP_BT_GAP_MAX_BDNAME_LEN (248) + +/// Maximum size of EIR Significant part +#define ESP_BT_GAP_EIR_DATA_LEN (240) + +/// Bluetooth Device Property Descriptor +typedef struct { + esp_bt_gap_dev_prop_type_t type; /*!< Device property type */ + int len; /*!< Device property value length */ + void *val; /*!< Device property value */ +} esp_bt_gap_dev_prop_t; + +/// Extended Inquiry Response data type +#define ESP_BT_EIR_TYPE_FLAGS 0x01 /*!< Flag with information such as BR/EDR and LE support */ +#define ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID 0x02 /*!< Incomplete list of 16-bit service UUIDs */ +#define ESP_BT_EIR_TYPE_CMPL_16BITS_UUID 0x03 /*!< Complete list of 16-bit service UUIDs */ +#define ESP_BT_EIR_TYPE_INCMPL_32BITS_UUID 0x04 /*!< Incomplete list of 32-bit service UUIDs */ +#define ESP_BT_EIR_TYPE_CMPL_32BITS_UUID 0x05 /*!< Complete list of 32-bit service UUIDs */ +#define ESP_BT_EIR_TYPE_INCMPL_128BITS_UUID 0x06 /*!< Incomplete list of 128-bit service UUIDs */ +#define ESP_BT_EIR_TYPE_CMPL_128BITS_UUID 0x07 /*!< Complete list of 128-bit service UUIDs */ +#define ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME 0x08 /*!< Shortened Local Name */ +#define ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME 0x09 /*!< Complete Local Name */ +#define ESP_BT_EIR_TYPE_TX_POWER_LEVEL 0x0a /*!< Tx power level, value is 1 octet ranging from -127 to 127, unit is dBm*/ +#define ESP_BT_EIR_TYPE_URL 0x24 /*!< Uniform resource identifier */ +#define ESP_BT_EIR_TYPE_MANU_SPECIFIC 0xff /*!< Manufacturer specific data */ +#define ESP_BT_EIR_TYPE_MAX_NUM 12 /*!< MAX number of EIR type */ + +typedef uint8_t esp_bt_eir_type_t; + +/* ACL Packet Types */ +#define ESP_BT_ACL_PKT_TYPES_MASK_DM1 0x0008 +#define ESP_BT_ACL_PKT_TYPES_MASK_DH1 0x0010 +#define ESP_BT_ACL_PKT_TYPES_MASK_DM3 0x0400 +#define ESP_BT_ACL_PKT_TYPES_MASK_DH3 0x0800 +#define ESP_BT_ACL_PKT_TYPES_MASK_DM5 0x4000 +#define ESP_BT_ACL_PKT_TYPES_MASK_DH5 0x8000 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 0x0002 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 0x0004 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 0x0100 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 0x0200 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 0x1000 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 0x2000 + +// DM1 cann not be disabled. All options are mandatory to include DM1. +#define ESP_BT_ACL_DM1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM1 | 0x330e) /* 0x330e */ +#define ESP_BT_ACL_DH1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH1 | 0x330e) /* 0x331e */ +#define ESP_BT_ACL_DM3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM3 | 0x330e) /* 0x370e */ +#define ESP_BT_ACL_DH3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH3 | 0x330e) /* 0x3b0e */ +#define ESP_BT_ACL_DM5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM5 | 0x330e) /* 0x730e */ +#define ESP_BT_ACL_DH5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH5 | 0x330e) /* 0xb30e */ +#define ESP_BT_ACL_2_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 & 0x330e) /* 0x330c */ +#define ESP_BT_ACL_3_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 & 0x330e) /* 0x330a */ +#define ESP_BT_ACL_2_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 & 0x330e) /* 0x320e */ +#define ESP_BT_ACL_3_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 & 0x330e) /* 0x310e */ +#define ESP_BT_ACL_2_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 & 0x330e) /* 0x230e */ +#define ESP_BT_ACL_3_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 & 0x330e) /* 0x130e */ + +typedef uint16_t esp_bt_acl_pkt_type_t; + +/* ESP_BT_EIR_FLAG bit definition */ +#define ESP_BT_EIR_FLAG_LIMIT_DISC (0x01 << 0) +#define ESP_BT_EIR_FLAG_GEN_DISC (0x01 << 1) +#define ESP_BT_EIR_FLAG_BREDR_NOT_SPT (0x01 << 2) +#define ESP_BT_EIR_FLAG_DMT_CONTROLLER_SPT (0x01 << 3) +#define ESP_BT_EIR_FLAG_DMT_HOST_SPT (0x01 << 4) + +#define ESP_BT_EIR_MAX_LEN 240 +/// EIR data content, according to "Supplement to the Bluetooth Core Specification" +typedef struct { + bool fec_required; /*!< FEC is required or not, true by default */ + bool include_txpower; /*!< EIR data include TX power, false by default */ + bool include_uuid; /*!< EIR data include UUID, false by default */ + bool include_name; /*!< EIR data include device name, true by default */ + uint8_t flag; /*!< EIR flags, see ESP_BT_EIR_FLAG for details, EIR will not include flag if it is 0, 0 by default */ + uint16_t manufacturer_len; /*!< Manufacturer data length, 0 by default */ + uint8_t *p_manufacturer_data; /*!< Manufacturer data point */ + uint16_t url_len; /*!< URL length, 0 by default */ + uint8_t *p_url; /*!< URL point */ +} esp_bt_eir_data_t; + +/// Major service class field of Class of Device, mutiple bits can be set +typedef enum { + ESP_BT_COD_SRVC_NONE = 0, /*!< None indicates an invalid value */ + ESP_BT_COD_SRVC_LMTD_DISCOVER = 0x1, /*!< Limited Discoverable Mode */ + ESP_BT_COD_SRVC_POSITIONING = 0x8, /*!< Positioning (Location identification) */ + ESP_BT_COD_SRVC_NETWORKING = 0x10, /*!< Networking, e.g. LAN, Ad hoc */ + ESP_BT_COD_SRVC_RENDERING = 0x20, /*!< Rendering, e.g. Printing, Speakers */ + ESP_BT_COD_SRVC_CAPTURING = 0x40, /*!< Capturing, e.g. Scanner, Microphone */ + ESP_BT_COD_SRVC_OBJ_TRANSFER = 0x80, /*!< Object Transfer, e.g. v-Inbox, v-Folder */ + ESP_BT_COD_SRVC_AUDIO = 0x100, /*!< Audio, e.g. Speaker, Microphone, Headset service */ + ESP_BT_COD_SRVC_TELEPHONY = 0x200, /*!< Telephony, e.g. Cordless telephony, Modem, Headset service */ + ESP_BT_COD_SRVC_INFORMATION = 0x400, /*!< Information, e.g., WEB-server, WAP-server */ +} esp_bt_cod_srvc_t; + +typedef enum{ + ESP_BT_PIN_TYPE_VARIABLE = 0, /*!< Refer to BTM_PIN_TYPE_VARIABLE */ + ESP_BT_PIN_TYPE_FIXED = 1, /*!< Refer to BTM_PIN_TYPE_FIXED */ +} esp_bt_pin_type_t; + +#define ESP_BT_PIN_CODE_LEN 16 /*!< Max pin code length */ +typedef uint8_t esp_bt_pin_code_t[ESP_BT_PIN_CODE_LEN]; /*!< Pin Code (upto 128 bits) MSB is 0 */ + +typedef enum { + ESP_BT_SP_IOCAP_MODE = 0, /*!< Set IO mode */ + //ESP_BT_SP_OOB_DATA, //TODO /*!< Set OOB data */ +} esp_bt_sp_param_t; + +/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */ +#define ESP_BT_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */ +#define ESP_BT_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */ +#define ESP_BT_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in stack/btm_api.h */ +#define ESP_BT_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */ +typedef uint8_t esp_bt_io_cap_t; /*!< Combination of the IO Capability */ + + +/* BTM Power manager modes */ +#define ESP_BT_PM_MD_ACTIVE 0x00 /*!< Active mode */ +#define ESP_BT_PM_MD_HOLD 0x01 /*!< Hold mode */ +#define ESP_BT_PM_MD_SNIFF 0x02 /*!< Sniff mode */ +#define ESP_BT_PM_MD_PARK 0x03 /*!< Park state */ +typedef uint8_t esp_bt_pm_mode_t; + + + +/// Bits of major service class field +#define ESP_BT_COD_SRVC_BIT_MASK (0xffe000) /*!< Major service bit mask */ +#define ESP_BT_COD_SRVC_BIT_OFFSET (13) /*!< Major service bit offset */ + +/// Major device class field of Class of Device +typedef enum { + ESP_BT_COD_MAJOR_DEV_MISC = 0, /*!< Miscellaneous */ + ESP_BT_COD_MAJOR_DEV_COMPUTER = 1, /*!< Computer */ + ESP_BT_COD_MAJOR_DEV_PHONE = 2, /*!< Phone(cellular, cordless, pay phone, modem */ + ESP_BT_COD_MAJOR_DEV_LAN_NAP = 3, /*!< LAN, Network Access Point */ + ESP_BT_COD_MAJOR_DEV_AV = 4, /*!< Audio/Video(headset, speaker, stereo, video display, VCR */ + ESP_BT_COD_MAJOR_DEV_PERIPHERAL = 5, /*!< Peripheral(mouse, joystick, keyboard) */ + ESP_BT_COD_MAJOR_DEV_IMAGING = 6, /*!< Imaging(printer, scanner, camera, display */ + ESP_BT_COD_MAJOR_DEV_WEARABLE = 7, /*!< Wearable */ + ESP_BT_COD_MAJOR_DEV_TOY = 8, /*!< Toy */ + ESP_BT_COD_MAJOR_DEV_HEALTH = 9, /*!< Health */ + ESP_BT_COD_MAJOR_DEV_UNCATEGORIZED = 31, /*!< Uncategorized: device not specified */ +} esp_bt_cod_major_dev_t; + +/// Bits of major device class field +#define ESP_BT_COD_MAJOR_DEV_BIT_MASK (0x1f00) /*!< Major device bit mask */ +#define ESP_BT_COD_MAJOR_DEV_BIT_OFFSET (8) /*!< Major device bit offset */ + +/// Bits of minor device class field +#define ESP_BT_COD_MINOR_DEV_BIT_MASK (0xfc) /*!< Minor device bit mask */ +#define ESP_BT_COD_MINOR_DEV_BIT_OFFSET (2) /*!< Minor device bit offset */ + +/// Bits of format type +#define ESP_BT_COD_FORMAT_TYPE_BIT_MASK (0x03) /*!< Format type bit mask */ +#define ESP_BT_COD_FORMAT_TYPE_BIT_OFFSET (0) /*!< Format type bit offset */ + +/// Class of device format type 1 +#define ESP_BT_COD_FORMAT_TYPE_1 (0x00) + +/** Bluetooth Device Discovery state */ +typedef enum { + ESP_BT_GAP_DISCOVERY_STOPPED, /*!< Device discovery stopped */ + ESP_BT_GAP_DISCOVERY_STARTED, /*!< Device discovery started */ +} esp_bt_gap_discovery_state_t; + +/// Type of link key +#define ESP_BT_LINK_KEY_COMB (0x00) /*!< Combination Key */ +#define ESP_BT_LINK_KEY_DBG_COMB (0x03) /*!< Debug Combination Key */ +#define ESP_BT_LINK_KEY_UNAUTHED_COMB_P192 (0x04) /*!< Unauthenticated Combination Key generated from P-192 */ +#define ESP_BT_LINK_KEY_AUTHED_COMB_P192 (0x05) /*!< Authenticated Combination Key generated from P-192 */ +#define ESP_BT_LINK_KEY_CHG_COMB (0x06) /*!< Changed Combination Key */ +#define ESP_BT_LINK_KEY_UNAUTHED_COMB_P256 (0x07) /*!< Unauthenticated Combination Key generated from P-256 */ +#define ESP_BT_LINK_KEY_AUTHED_COMB_P256 (0x08) /*!< Authenticated Combination Key generated from P-256 */ +typedef uint8_t esp_bt_link_key_type_t; + +/// Type of encryption +#define ESP_BT_ENC_MODE_OFF (0x00) /*!< Link Level Encryption is OFF */ +#define ESP_BT_ENC_MODE_E0 (0x01) /*!< Link Level Encryption is ON with E0 */ +#define ESP_BT_ENC_MODE_AES (0x02) /*!< Link Level Encryption is ON with AES-CCM */ +typedef uint8_t esp_bt_enc_mode_t; + +/// BT GAP callback events +typedef enum { + ESP_BT_GAP_DISC_RES_EVT = 0, /*!< Device discovery result event */ + ESP_BT_GAP_DISC_STATE_CHANGED_EVT, /*!< Discovery state changed event */ + ESP_BT_GAP_RMT_SRVCS_EVT, /*!< Get remote services event */ + ESP_BT_GAP_RMT_SRVC_REC_EVT, /*!< Get remote service record event */ + ESP_BT_GAP_AUTH_CMPL_EVT, /*!< Authentication complete event */ + ESP_BT_GAP_PIN_REQ_EVT, /*!< Legacy Pairing Pin code request */ + ESP_BT_GAP_CFM_REQ_EVT, /*!< Security Simple Pairing User Confirmation request. */ + ESP_BT_GAP_KEY_NOTIF_EVT, /*!< Security Simple Pairing Passkey Notification */ + ESP_BT_GAP_KEY_REQ_EVT, /*!< Security Simple Pairing Passkey request */ + ESP_BT_GAP_READ_RSSI_DELTA_EVT, /*!< Read rssi event */ + ESP_BT_GAP_CONFIG_EIR_DATA_EVT, /*!< Config EIR data event */ + ESP_BT_GAP_SET_AFH_CHANNELS_EVT, /*!< Set AFH channels event */ + ESP_BT_GAP_READ_REMOTE_NAME_EVT, /*!< Read Remote Name event */ + ESP_BT_GAP_MODE_CHG_EVT, + ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< remove bond device complete event */ + ESP_BT_GAP_QOS_CMPL_EVT, /*!< QOS complete event */ + ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT, /*!< ACL connection complete status event */ + ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT, /*!< ACL disconnection complete status event */ + ESP_BT_GAP_SET_PAGE_TO_EVT, /*!< Set page timeout event */ + ESP_BT_GAP_GET_PAGE_TO_EVT, /*!< Get page timeout event */ + ESP_BT_GAP_ACL_PKT_TYPE_CHANGED_EVT, /*!< Set ACL packet types event */ + ESP_BT_GAP_ENC_CHG_EVT, /*!< Encryption change event */ + ESP_BT_GAP_EVT_MAX, +} esp_bt_gap_cb_event_t; + +/** Inquiry Mode */ +typedef enum { + ESP_BT_INQ_MODE_GENERAL_INQUIRY, /*!< General inquiry mode */ + ESP_BT_INQ_MODE_LIMITED_INQUIRY, /*!< Limited inquiry mode */ +} esp_bt_inq_mode_t; + +/** Minimum and Maximum inquiry length*/ +#define ESP_BT_GAP_MIN_INQ_LEN (0x01) /*!< Minimum inquiry duration, unit is 1.28s */ +#define ESP_BT_GAP_MAX_INQ_LEN (0x30) /*!< Maximum inquiry duration, unit is 1.28s */ + +/** Minimum, Default and Maximum poll interval **/ +#define ESP_BT_GAP_TPOLL_MIN (0x0006) /*!< Minimum poll interval, unit is 625 microseconds */ +#define ESP_BT_GAP_TPOLL_DFT (0x0028) /*!< Default poll interval, unit is 625 microseconds */ +#define ESP_BT_GAP_TPOLL_MAX (0x1000) /*!< Maximum poll interval, unit is 625 microseconds */ + +/// GAP state callback parameters +typedef union { + /** + * @brief ESP_BT_GAP_DISC_RES_EVT + */ + struct disc_res_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + int num_prop; /*!< number of properties got */ + esp_bt_gap_dev_prop_t *prop; /*!< properties discovered from the new device */ + } disc_res; /*!< discovery result parameter struct */ + + /** + * @brief ESP_BT_GAP_DISC_STATE_CHANGED_EVT + */ + struct disc_state_changed_param { + esp_bt_gap_discovery_state_t state; /*!< discovery state */ + } disc_st_chg; /*!< discovery state changed parameter struct */ + + /** + * @brief ESP_BT_GAP_RMT_SRVCS_EVT + */ + struct rmt_srvcs_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_status_t stat; /*!< service search status */ + int num_uuids; /*!< number of UUID in uuid_list */ + esp_bt_uuid_t *uuid_list; /*!< list of service UUIDs of remote device */ + } rmt_srvcs; /*!< services of remote device parameter struct */ + + /** + * @brief ESP_BT_GAP_RMT_SRVC_REC_EVT + */ + struct rmt_srvc_rec_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_status_t stat; /*!< service search status */ + } rmt_srvc_rec; /*!< specific service record from remote device parameter struct */ + + /** + * @brief ESP_BT_GAP_READ_RSSI_DELTA_EVT * + */ + struct read_rssi_delta_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_status_t stat; /*!< read rssi status */ + int8_t rssi_delta; /*!< rssi delta value range -128 ~127, The value zero indicates that the RSSI is inside the Golden Receive Power Range, the Golden Receive Power Range is from ESP_BT_GAP_RSSI_LOW_THRLD to ESP_BT_GAP_RSSI_HIGH_THRLD */ + } read_rssi_delta; /*!< read rssi parameter struct */ + + /** + * @brief ESP_BT_GAP_CONFIG_EIR_DATA_EVT * + */ + struct config_eir_data_param { + esp_bt_status_t stat; /*!< config EIR status: + ESP_BT_STATUS_SUCCESS: config success + ESP_BT_STATUS_EIR_TOO_LARGE: the EIR data is more than 240B. The EIR may not contain the whole data. + others: failed + */ + uint8_t eir_type_num; /*!< the number of EIR types in EIR type */ + esp_bt_eir_type_t eir_type[ESP_BT_EIR_TYPE_MAX_NUM]; /*!< EIR types in EIR type */ + } config_eir_data; /*!< config EIR data */ + + /** + * @brief ESP_BT_GAP_AUTH_CMPL_EVT + */ + struct auth_cmpl_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_status_t stat; /*!< authentication complete status */ + esp_bt_link_key_type_t lk_type; /*!< type of link key generated */ + uint8_t device_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< device name */ + } auth_cmpl; /*!< authentication complete parameter struct */ + + /** + * @brief ESP_BT_GAP_ENC_CHG_EVT + */ + struct enc_chg_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_enc_mode_t enc_mode; /*!< encryption mode */ + } enc_chg; /*!< encryption change parameter struct */ + + /** + * @brief ESP_BT_GAP_PIN_REQ_EVT + */ + struct pin_req_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + bool min_16_digit; /*!< TRUE if the pin returned must be at least 16 digits */ + } pin_req; /*!< pin request parameter struct */ + + /** + * @brief ESP_BT_GAP_CFM_REQ_EVT + */ + struct cfm_req_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + uint32_t num_val; /*!< the numeric value for comparison. */ + } cfm_req; /*!< confirm request parameter struct */ + + /** + * @brief ESP_BT_GAP_KEY_NOTIF_EVT + */ + struct key_notif_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + uint32_t passkey; /*!< the numeric value for passkey entry. */ + } key_notif; /*!< passkey notif parameter struct */ + + /** + * @brief ESP_BT_GAP_KEY_REQ_EVT + */ + struct key_req_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + } key_req; /*!< passkey request parameter struct */ + + /** + * @brief ESP_BT_GAP_SET_AFH_CHANNELS_EVT + */ + struct set_afh_channels_param { + esp_bt_status_t stat; /*!< set AFH channel status */ + } set_afh_channels; /*!< set AFH channel parameter struct */ + + /** + * @brief ESP_BT_GAP_READ_REMOTE_NAME_EVT + */ + struct read_rmt_name_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_status_t stat; /*!< read Remote Name status */ + uint8_t rmt_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< Remote device name */ + } read_rmt_name; /*!< read Remote Name parameter struct */ + + /** + * @brief ESP_BT_GAP_MODE_CHG_EVT + */ + struct mode_chg_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_pm_mode_t mode; /*!< PM mode*/ + } mode_chg; /*!< mode change event parameter struct */ + + /** + * @brief ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT + */ + struct bt_remove_bond_dev_cmpl_evt_param { + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */ + }remove_bond_dev_cmpl; /*!< Event parameter of ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT */ + + /** + * @brief ESP_BT_GAP_QOS_CMPL_EVT + */ + struct qos_cmpl_param { + esp_bt_status_t stat; /*!< QoS status */ + esp_bd_addr_t bda; /*!< remote bluetooth device address*/ + uint32_t t_poll; /*!< poll interval, the maximum time between transmissions + which from the master to a particular slave on the ACL + logical transport. unit is 0.625ms. */ + } qos_cmpl; /*!< QoS complete parameter struct */ + + /** + * @brief ESP_BT_GAP_SET_PAGE_TO_EVT + */ + struct page_to_set_param { + esp_bt_status_t stat; /*!< set page timeout status*/ + } set_page_timeout; /*!< set page timeout parameter struct */ + + /** + * @brief ESP_BT_GAP_GET_PAGE_TO_EVT + */ + struct page_to_get_param { + esp_bt_status_t stat; /*!< get page timeout status*/ + uint16_t page_to; /*!< page_timeout value to be set, unit is 0.625ms. */ + } get_page_timeout; /*!< get page timeout parameter struct */ + + /** + * @brief ESP_BT_GAP_ACL_PKT_TYPE_CHANGED_EVT + */ + struct set_acl_pkt_types_param { + esp_bt_status_t status; /*!< set ACL packet types status */ + esp_bd_addr_t bda; /*!< remote bluetooth device address */ + uint16_t pkt_types; /*!< packet types successfully set */ + } set_acl_pkt_types; /*!< set ACL packet types parameter struct */ + + /** + * @brief ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT + */ + struct acl_conn_cmpl_stat_param { + esp_bt_status_t stat; /*!< ACL connection status */ + uint16_t handle; /*!< ACL connection handle */ + esp_bd_addr_t bda; /*!< remote bluetooth device address */ + } acl_conn_cmpl_stat; /*!< ACL connection complete status parameter struct */ + + /** + * @brief ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT + */ + struct acl_disconn_cmpl_stat_param { + esp_bt_status_t reason; /*!< ACL disconnection reason */ + uint16_t handle; /*!< ACL connection handle */ + esp_bd_addr_t bda; /*!< remote bluetooth device address */ + } acl_disconn_cmpl_stat; /*!< ACL disconnection complete status parameter struct */ +} esp_bt_gap_cb_param_t; + +/** + * @brief bluetooth GAP callback function type + * + * @param event : Event type + * + * @param param : Pointer to callback parameter + */ +typedef void (* esp_bt_gap_cb_t)(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); + +/** + * @brief get major service field of COD + * + * @param[in] cod: Class of Device + * + * @return major service bits + */ +static inline uint32_t esp_bt_gap_get_cod_srvc(uint32_t cod) +{ + return (cod & ESP_BT_COD_SRVC_BIT_MASK) >> ESP_BT_COD_SRVC_BIT_OFFSET; +} + +/** + * @brief get major device field of COD + * + * @param[in] cod: Class of Device + * + * @return major device bits + */ +static inline uint32_t esp_bt_gap_get_cod_major_dev(uint32_t cod) +{ + return (cod & ESP_BT_COD_MAJOR_DEV_BIT_MASK) >> ESP_BT_COD_MAJOR_DEV_BIT_OFFSET; +} + +/** + * @brief get minor service field of COD + * + * @param[in] cod: Class of Device + * + * @return minor service bits + */ +static inline uint32_t esp_bt_gap_get_cod_minor_dev(uint32_t cod) +{ + return (cod & ESP_BT_COD_MINOR_DEV_BIT_MASK) >> ESP_BT_COD_MINOR_DEV_BIT_OFFSET; +} + +/** + * @brief get format type of COD + * + * @param[in] cod: Class of Device + * + * @return format type + */ +static inline uint32_t esp_bt_gap_get_cod_format_type(uint32_t cod) +{ + return (cod & ESP_BT_COD_FORMAT_TYPE_BIT_MASK); +} + +/** + * @brief decide the integrity of COD + * + * @param[in] cod: Class of Device + * + * @return + * - true if cod is valid + * - false otherise + */ +static inline bool esp_bt_gap_is_valid_cod(uint32_t cod) +{ + if (esp_bt_gap_get_cod_format_type(cod) == ESP_BT_COD_FORMAT_TYPE_1 && + esp_bt_gap_get_cod_srvc(cod) != ESP_BT_COD_SRVC_NONE) { + return true; + } + + return false; +} + +/** + * @brief register callback function. This function should be called after esp_bluedroid_enable() completes successfully + * + * @return + * - ESP_OK : Succeed + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback); + +/** + * @brief Set discoverability and connectability mode for legacy bluetooth. This function should + * be called after esp_bluedroid_enable() completes successfully + * + * @param[in] c_mode : one of the enums of esp_bt_connection_mode_t + * + * @param[in] d_mode : one of the enums of esp_bt_discovery_mode_t + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_ARG: if argument invalid + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discovery_mode_t d_mode); + +/** + * @brief This function starts Inquiry and Name Discovery. This function should be called after esp_bluedroid_enable() completes successfully. + * When Inquiry is halted and cached results do not contain device name, then Name Discovery will connect to the peer target to get the device name. + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_STATE_CHANGED_EVT when Inquiry is started or Name Discovery is completed. + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_RES_EVT each time the two types of discovery results are got. + * + * @param[in] mode - Inquiry mode + * + * @param[in] inq_len - Inquiry duration in 1.28 sec units, ranging from 0x01 to 0x30. This parameter only specifies the total duration of the Inquiry process, + * - when this time expires, Inquiry will be halted. + * + * @param[in] num_rsps - Number of responses that can be received before the Inquiry is halted, value 0 indicates an unlimited number of responses. + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if invalid parameters are provided + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, uint8_t num_rsps); + +/** + * @brief Cancel Inquiry and Name Discovery. This function should be called after esp_bluedroid_enable() completes successfully. + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_STATE_CHANGED_EVT if Inquiry or Name Discovery is cancelled by + * calling this function. + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_cancel_discovery(void); + +/** + * @brief Start SDP to get remote services. This function should be called after esp_bluedroid_enable() completes successfully. + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_RMT_SRVCS_EVT after service discovery ends. + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda); + +/** + * @brief Start SDP to look up the service matching uuid on the remote device. This function should be called after + * esp_bluedroid_enable() completes successfully. + * + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_RMT_SRVC_REC_EVT after service discovery ends + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda, esp_bt_uuid_t *uuid); + +/** + * @brief This function is called to get EIR data for a specific type. + * + * @param[in] eir - pointer of raw eir data to be resolved + * @param[in] type - specific EIR data type + * @param[out] length - return the length of EIR data excluding fields of length and data type + * + * @return pointer of starting position of eir data excluding eir data type, NULL if not found + * + */ +uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8_t *length); + +/** + * @brief This function is called to config EIR data. + * + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_CONFIG_EIR_DATA_EVT after config EIR ends. + * + * @param[in] eir_data - pointer of EIR data content + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if param is invalid + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_config_eir_data(esp_bt_eir_data_t *eir_data); + +/** + * @brief This function is called to set class of device. + * The structure esp_bt_gap_cb_t will be called with ESP_BT_GAP_SET_COD_EVT after set COD ends. + * This function should be called after Bluetooth profiles are initialized, otherwise the user configured + * class of device can be overwritten. + * Some profiles have special restrictions on class of device, and changes may make these profiles unable to work. + * + * @param[in] cod - class of device + * @param[in] mode - setting mode + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if param is invalid + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode); + +/** + * @brief This function is called to get class of device. + * + * @param[out] cod - class of device + * + * @return + * - ESP_OK : Succeed + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod); + +/** + * @brief This function is called to read RSSI delta by address after connected. The RSSI value returned by ESP_BT_GAP_READ_RSSI_DELTA_EVT. + * + * + * @param[in] remote_addr - remote device address, corresponding to a certain connection handle + * @return + * - ESP_OK : Succeed + * - ESP_FAIL: others + * + */ +esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr); + +/** +* @brief Removes a device from the security database list of +* peer device. +* +* @param[in] bd_addr : BD address of the peer device +* +* @return - ESP_OK : success +* - ESP_FAIL : failed +* +*/ +esp_err_t esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr); + +/** +* @brief Get the device number from the security database list of peer device. +* It will return the device bonded number immediately. +* +* @return - >= 0 : bonded devices number +* - ESP_FAIL : failed +* +*/ +int esp_bt_gap_get_bond_device_num(void); + +/** +* @brief Get the device from the security database list of peer device. +* It will return the device bonded information immediately. +* +* @param[inout] dev_num: Indicate the dev_list array(buffer) size as input. +* If dev_num is large enough, it means the actual number as output. +* Suggest that dev_num value equal to esp_ble_get_bond_device_num(). +* +* @param[out] dev_list: an array(buffer) of `esp_bd_addr_t` type. Use for storing the bonded devices address. +* The dev_list should be allocated by who call this API. +* +* @return +* - ESP_OK : Succeed +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - ESP_FAIL: others +*/ +esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list); + +/** +* @brief Set pin type and default pin code for legacy pairing. +* +* @param[in] pin_type: Use variable or fixed pin. +* If pin_type is ESP_BT_PIN_TYPE_VARIABLE, pin_code and pin_code_len +* will be ignored, and ESP_BT_GAP_PIN_REQ_EVT will come when control +* requests for pin code. +* Else, will use fixed pin code and not callback to users. +* +* @param[in] pin_code_len: Length of pin_code +* +* @param[in] pin_code: Pin_code +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +*/ +esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, esp_bt_pin_code_t pin_code); + +/** +* @brief Reply the pin_code to the peer device for legacy pairing +* when ESP_BT_GAP_PIN_REQ_EVT is coming. +* +* @param[in] bd_addr: BD address of the peer +* +* @param[in] accept: Pin_code reply successful or declined. +* +* @param[in] pin_code_len: Length of pin_code +* +* @param[in] pin_code: Pin_code +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +*/ +esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_code_len, esp_bt_pin_code_t pin_code); + +/** +* @brief Set a GAP security parameter value. Overrides the default value. +* +* @param[in] param_type : the type of the param which is to be set +* +* @param[in] value : the param value +* +* @param[in] len : the length of the param value +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +* +*/ +esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type, + void *value, uint8_t len); + +/** +* @brief Reply the key value to the peer device in the legacy connection stage. +* +* @param[in] bd_addr : BD address of the peer +* +* @param[in] accept : passkey entry successful or declined. +* +* @param[in] passkey : passkey value, must be a 6 digit number, can be lead by 0. +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +* +*/ +esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey); + + +/** +* @brief Reply the confirm value to the peer device in the legacy connection stage. +* +* @param[in] bd_addr : BD address of the peer device +* +* @param[in] accept : numbers to compare are the same or different +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +* +*/ +esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept); + +/** +* @brief Set the AFH channels +* +* @param[in] channels : The n th such field (in the range 0 to 78) contains the value for channel n : +* 0 means channel n is bad. +* 1 means channel n is unknown. +* The most significant bit is reserved and shall be set to 0. +* At least 20 channels shall be marked as unknown. +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +* +*/ +esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels); + +/** +* @brief Read the remote device name +* +* @param[in] remote_bda: The remote device's address +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +* +*/ +esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda); + +/** +* @brief Config Quality of service +* +* @param[in] remote_bda: The remote device's address +* @param[in] t_poll: Poll interval, the maximum time between transmissions + which from the master to a particular slave on the ACL + logical transport. unit is 0.625ms +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled +* - other : failed +* +*/ +esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll); + +/** + * @brief Set the page timeout + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_SET_PAGE_TO_EVT + * after set page timeout ends. The value to be set will not be effective util the + * next page procedure, it's suggested to set the page timeout before initiating + * a connection. + * + * @param[in] page_to: Page timeout, the maximum time the master will wait for a + Base-band page response from the remote device at a locally + initiated connection attempt. The valid range is 0x0016 ~ 0xffff, + the default value is 0x2000, unit is 0.625ms. + * + * @return - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - other: failed + */ +esp_err_t esp_bt_gap_set_page_timeout(uint16_t page_to); + +/** + * @brief Get the page timeout + * esp_bt_gap_cb_t will be called with ESP_BT_GAP_GET_PAGE_TO_EVT + * after get page timeout ends + * + * @return - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - other: failed + */ +esp_err_t esp_bt_gap_get_page_timeout(void); + +/** + * @brief Set ACL packet types + * An ESP_BT_GAP_SET_ACL_PPKT_TYPES_EVT event will reported to + * the APP layer. + * + * @return - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - other: failed + */ +esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, esp_bt_acl_pkt_type_t pkt_types); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_GAP_BT_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h new file mode 100644 index 00000000..1a4a59e1 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_GATT_COMMON_API_H__ +#define __ESP_GATT_COMMON_API_H__ + +#include <stdint.h> +#include <stdbool.h> + +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Maximum Transmission Unit used in GATT +#define ESP_GATT_DEF_BLE_MTU_SIZE 23 /* relate to GATT_DEF_BLE_MTU_SIZE in stack/gatt_api.h */ + +// Maximum Transmission Unit allowed in GATT +#define ESP_GATT_MAX_MTU_SIZE 517 /* relate to GATT_MAX_MTU_SIZE in stack/gatt_api.h */ + +/** + * @brief This function is called to set local MTU, + * the function is called before BLE connection. + * + * @param[in] mtu: the size of MTU. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +extern esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu); + +#if (BLE_INCLUDED == TRUE) +extern uint16_t esp_ble_get_sendable_packets_num (void); +extern uint16_t esp_ble_get_cur_sendable_packets_num (uint16_t connid); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_GATT_COMMON_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h b/lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h new file mode 100644 index 00000000..f2d658a2 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h @@ -0,0 +1,485 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_GATT_DEFS_H__ +#define __ESP_GATT_DEFS_H__ + +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// GATT INVALID UUID +#define ESP_GATT_ILLEGAL_UUID 0 +/// GATT INVALID HANDLE +#define ESP_GATT_ILLEGAL_HANDLE 0 +/// GATT attribute max handle +#define ESP_GATT_ATTR_HANDLE_MAX UC_CONFIG_BT_GATT_MAX_SR_ATTRIBUTES +#define ESP_GATT_MAX_READ_MULTI_HANDLES 10 /* Max attributes to read in one request */ + + +/**@{ + * All "ESP_GATT_UUID_xxx" is attribute types + */ +#define ESP_GATT_UUID_IMMEDIATE_ALERT_SVC 0x1802 /* Immediate alert Service*/ +#define ESP_GATT_UUID_LINK_LOSS_SVC 0x1803 /* Link Loss Service*/ +#define ESP_GATT_UUID_TX_POWER_SVC 0x1804 /* TX Power Service*/ +#define ESP_GATT_UUID_CURRENT_TIME_SVC 0x1805 /* Current Time Service Service*/ +#define ESP_GATT_UUID_REF_TIME_UPDATE_SVC 0x1806 /* Reference Time Update Service*/ +#define ESP_GATT_UUID_NEXT_DST_CHANGE_SVC 0x1807 /* Next DST Change Service*/ +#define ESP_GATT_UUID_GLUCOSE_SVC 0x1808 /* Glucose Service*/ +#define ESP_GATT_UUID_HEALTH_THERMOM_SVC 0x1809 /* Health Thermometer Service*/ +#define ESP_GATT_UUID_DEVICE_INFO_SVC 0x180A /* Device Information Service*/ +#define ESP_GATT_UUID_HEART_RATE_SVC 0x180D /* Heart Rate Service*/ +#define ESP_GATT_UUID_PHONE_ALERT_STATUS_SVC 0x180E /* Phone Alert Status Service*/ +#define ESP_GATT_UUID_BATTERY_SERVICE_SVC 0x180F /* Battery Service*/ +#define ESP_GATT_UUID_BLOOD_PRESSURE_SVC 0x1810 /* Blood Pressure Service*/ +#define ESP_GATT_UUID_ALERT_NTF_SVC 0x1811 /* Alert Notification Service*/ +#define ESP_GATT_UUID_HID_SVC 0x1812 /* HID Service*/ +#define ESP_GATT_UUID_SCAN_PARAMETERS_SVC 0x1813 /* Scan Parameters Service*/ +#define ESP_GATT_UUID_RUNNING_SPEED_CADENCE_SVC 0x1814 /* Running Speed and Cadence Service*/ +#define ESP_GATT_UUID_Automation_IO_SVC 0x1815 /* Automation IO Service*/ +#define ESP_GATT_UUID_CYCLING_SPEED_CADENCE_SVC 0x1816 /* Cycling Speed and Cadence Service*/ +#define ESP_GATT_UUID_CYCLING_POWER_SVC 0x1818 /* Cycling Power Service*/ +#define ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC 0x1819 /* Location and Navigation Service*/ +#define ESP_GATT_UUID_ENVIRONMENTAL_SENSING_SVC 0x181A /* Environmental Sensing Service*/ +#define ESP_GATT_UUID_BODY_COMPOSITION 0x181B /* Body Composition Service*/ +#define ESP_GATT_UUID_USER_DATA_SVC 0x181C /* User Data Service*/ +#define ESP_GATT_UUID_WEIGHT_SCALE_SVC 0x181D /* Weight Scale Service*/ +#define ESP_GATT_UUID_BOND_MANAGEMENT_SVC 0x181E /* Bond Management Service*/ +#define ESP_GATT_UUID_CONT_GLUCOSE_MONITOR_SVC 0x181F /* Continuous Glucose Monitoring Service*/ + +#define ESP_GATT_UUID_PRI_SERVICE 0x2800 +#define ESP_GATT_UUID_SEC_SERVICE 0x2801 +#define ESP_GATT_UUID_INCLUDE_SERVICE 0x2802 +#define ESP_GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/ + +#define ESP_GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */ +#define ESP_GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/ +#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */ +#define ESP_GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */ +#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/ +#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/ +#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */ +#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907 /* External Report Reference */ +#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908 /* Report Reference */ +#define ESP_GATT_UUID_NUM_DIGITALS_DESCR 0x2909 /* Number of Digitals */ +#define ESP_GATT_UUID_VALUE_TRIGGER_DESCR 0x290A /* Value Trigger Setting */ +#define ESP_GATT_UUID_ENV_SENSING_CONFIG_DESCR 0x290B /* Environmental Sensing Configuration */ +#define ESP_GATT_UUID_ENV_SENSING_MEASUREMENT_DESCR 0x290C /* Environmental Sensing Measurement */ +#define ESP_GATT_UUID_ENV_SENSING_TRIGGER_DESCR 0x290D /* Environmental Sensing Trigger Setting */ +#define ESP_GATT_UUID_TIME_TRIGGER_DESCR 0x290E /* Time Trigger Setting */ + +/* GAP Profile Attributes */ +#define ESP_GATT_UUID_GAP_DEVICE_NAME 0x2A00 +#define ESP_GATT_UUID_GAP_ICON 0x2A01 +#define ESP_GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04 +#define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6 + +/* Attribute Profile Attribute UUID */ +#define ESP_GATT_UUID_GATT_SRV_CHGD 0x2A05 + +/* Link ESP_Loss Service */ +#define ESP_GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */ +#define ESP_GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */ + +/* Current Time Service */ +#define ESP_GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */ +#define ESP_GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */ +#define ESP_GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */ + +/* Network availability Profile */ +#define ESP_GATT_UUID_NW_STATUS 0x2A18 /* network availability status */ +#define ESP_GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */ + +/* Phone alert */ +#define ESP_GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */ +#define ESP_GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */ +#define ESP_GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */ + +/* Glucose Service */ +#define ESP_GATT_UUID_GM_MEASUREMENT 0x2A18 +#define ESP_GATT_UUID_GM_CONTEXT 0x2A34 +#define ESP_GATT_UUID_GM_CONTROL_POINT 0x2A52 +#define ESP_GATT_UUID_GM_FEATURE 0x2A51 + +/* device information characteristic */ +#define ESP_GATT_UUID_SYSTEM_ID 0x2A23 +#define ESP_GATT_UUID_MODEL_NUMBER_STR 0x2A24 +#define ESP_GATT_UUID_SERIAL_NUMBER_STR 0x2A25 +#define ESP_GATT_UUID_FW_VERSION_STR 0x2A26 +#define ESP_GATT_UUID_HW_VERSION_STR 0x2A27 +#define ESP_GATT_UUID_SW_VERSION_STR 0x2A28 +#define ESP_GATT_UUID_MANU_NAME 0x2A29 +#define ESP_GATT_UUID_IEEE_DATA 0x2A2A +#define ESP_GATT_UUID_PNP_ID 0x2A50 + +/* HID characteristics */ +#define ESP_GATT_UUID_HID_INFORMATION 0x2A4A +#define ESP_GATT_UUID_HID_REPORT_MAP 0x2A4B +#define ESP_GATT_UUID_HID_CONTROL_POINT 0x2A4C +#define ESP_GATT_UUID_HID_REPORT 0x2A4D +#define ESP_GATT_UUID_HID_PROTO_MODE 0x2A4E +#define ESP_GATT_UUID_HID_BT_KB_INPUT 0x2A22 +#define ESP_GATT_UUID_HID_BT_KB_OUTPUT 0x2A32 +#define ESP_GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33 + + /// Heart Rate Measurement +#define ESP_GATT_HEART_RATE_MEAS 0x2A37 +/// Body Sensor Location +#define ESP_GATT_BODY_SENSOR_LOCATION 0x2A38 +/// Heart Rate Control Point +#define ESP_GATT_HEART_RATE_CNTL_POINT 0x2A39 + +/* Battery Service characteristics */ +#define ESP_GATT_UUID_BATTERY_LEVEL 0x2A19 + +/* Sensor Service */ +#define ESP_GATT_UUID_SC_CONTROL_POINT 0x2A55 +#define ESP_GATT_UUID_SENSOR_LOCATION 0x2A5D + +/* Runners speed and cadence service */ +#define ESP_GATT_UUID_RSC_MEASUREMENT 0x2A53 +#define ESP_GATT_UUID_RSC_FEATURE 0x2A54 + +/* Cycling speed and cadence service */ +#define ESP_GATT_UUID_CSC_MEASUREMENT 0x2A5B +#define ESP_GATT_UUID_CSC_FEATURE 0x2A5C + +/* Scan ESP_Parameter characteristics */ +#define ESP_GATT_UUID_SCAN_INT_WINDOW 0x2A4F +#define ESP_GATT_UUID_SCAN_REFRESH 0x2A31 +/** + * @} + */ + +/* relate to BTA_GATT_PREP_WRITE_xxx in bta/bta_gatt_api.h */ +/// Attribute write data type from the client +typedef enum { + ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */ /* relate to BTA_GATT_PREP_WRITE_CANCEL in bta/bta_gatt_api.h */ + ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute */ /* relate to BTA_GATT_PREP_WRITE_EXEC in bta/bta_gatt_api.h */ +} esp_gatt_prep_write_type; + +/* relate to BTA_GATT_xxx in bta/bta_gatt_api.h */ +/** + * @brief GATT success code and error codes + */ +typedef enum { + ESP_GATT_OK = 0x0, /* relate to BTA_GATT_OK in bta/bta_gatt_api.h */ + ESP_GATT_INVALID_HANDLE = 0x01, /* 0x0001 */ /* relate to BTA_GATT_INVALID_HANDLE in bta/bta_gatt_api.h */ + ESP_GATT_READ_NOT_PERMIT = 0x02, /* 0x0002 */ /* relate to BTA_GATT_READ_NOT_PERMIT in bta/bta_gatt_api.h */ + ESP_GATT_WRITE_NOT_PERMIT = 0x03, /* 0x0003 */ /* relate to BTA_GATT_WRITE_NOT_PERMIT in bta/bta_gatt_api.h */ + ESP_GATT_INVALID_PDU = 0x04, /* 0x0004 */ /* relate to BTA_GATT_INVALID_PDU in bta/bta_gatt_api.h */ + ESP_GATT_INSUF_AUTHENTICATION = 0x05, /* 0x0005 */ /* relate to BTA_GATT_INSUF_AUTHENTICATION in bta/bta_gatt_api.h */ + ESP_GATT_REQ_NOT_SUPPORTED = 0x06, /* 0x0006 */ /* relate to BTA_GATT_REQ_NOT_SUPPORTED in bta/bta_gatt_api.h */ + ESP_GATT_INVALID_OFFSET = 0x07, /* 0x0007 */ /* relate to BTA_GATT_INVALID_OFFSET in bta/bta_gatt_api.h */ + ESP_GATT_INSUF_AUTHORIZATION = 0x08, /* 0x0008 */ /* relate to BTA_GATT_INSUF_AUTHORIZATION in bta/bta_gatt_api.h */ + ESP_GATT_PREPARE_Q_FULL = 0x09, /* 0x0009 */ /* relate to BTA_GATT_PREPARE_Q_FULL in bta/bta_gatt_api.h */ + ESP_GATT_NOT_FOUND = 0x0a, /* 0x000a */ /* relate to BTA_GATT_NOT_FOUND in bta/bta_gatt_api.h */ + ESP_GATT_NOT_LONG = 0x0b, /* 0x000b */ /* relate to BTA_GATT_NOT_LONG in bta/bta_gatt_api.h */ + ESP_GATT_INSUF_KEY_SIZE = 0x0c, /* 0x000c */ /* relate to BTA_GATT_INSUF_KEY_SIZE in bta/bta_gatt_api.h */ + ESP_GATT_INVALID_ATTR_LEN = 0x0d, /* 0x000d */ /* relate to BTA_GATT_INVALID_ATTR_LEN in bta/bta_gatt_api.h */ + ESP_GATT_ERR_UNLIKELY = 0x0e, /* 0x000e */ /* relate to BTA_GATT_ERR_UNLIKELY in bta/bta_gatt_api.h */ + ESP_GATT_INSUF_ENCRYPTION = 0x0f, /* 0x000f */ /* relate to BTA_GATT_INSUF_ENCRYPTION in bta/bta_gatt_api.h */ + ESP_GATT_UNSUPPORT_GRP_TYPE = 0x10, /* 0x0010 */ /* relate to BTA_GATT_UNSUPPORT_GRP_TYPE in bta/bta_gatt_api.h */ + ESP_GATT_INSUF_RESOURCE = 0x11, /* 0x0011 */ /* relate to BTA_GATT_INSUF_RESOURCE in bta/bta_gatt_api.h */ + + ESP_GATT_NO_RESOURCES = 0x80, /* 0x80 */ /* relate to BTA_GATT_NO_RESOURCES in bta/bta_gatt_api.h */ + ESP_GATT_INTERNAL_ERROR = 0x81, /* 0x81 */ /* relate to BTA_GATT_INTERNAL_ERROR in bta/bta_gatt_api.h */ + ESP_GATT_WRONG_STATE = 0x82, /* 0x82 */ /* relate to BTA_GATT_WRONG_STATE in bta/bta_gatt_api.h */ + ESP_GATT_DB_FULL = 0x83, /* 0x83 */ /* relate to BTA_GATT_DB_FULL in bta/bta_gatt_api.h */ + ESP_GATT_BUSY = 0x84, /* 0x84 */ /* relate to BTA_GATT_BUSY in bta/bta_gatt_api.h */ + ESP_GATT_ERROR = 0x85, /* 0x85 */ /* relate to BTA_GATT_ERROR in bta/bta_gatt_api.h */ + ESP_GATT_CMD_STARTED = 0x86, /* 0x86 */ /* relate to BTA_GATT_CMD_STARTED in bta/bta_gatt_api.h */ + ESP_GATT_ILLEGAL_PARAMETER = 0x87, /* 0x87 */ /* relate to BTA_GATT_ILLEGAL_PARAMETER in bta/bta_gatt_api.h */ + ESP_GATT_PENDING = 0x88, /* 0x88 */ /* relate to BTA_GATT_PENDING in bta/bta_gatt_api.h */ + ESP_GATT_AUTH_FAIL = 0x89, /* 0x89 */ /* relate to BTA_GATT_AUTH_FAIL in bta/bta_gatt_api.h */ + ESP_GATT_MORE = 0x8a, /* 0x8a */ /* relate to BTA_GATT_MORE in bta/bta_gatt_api.h */ + ESP_GATT_INVALID_CFG = 0x8b, /* 0x8b */ /* relate to BTA_GATT_INVALID_CFG in bta/bta_gatt_api.h */ + ESP_GATT_SERVICE_STARTED = 0x8c, /* 0x8c */ /* relate to BTA_GATT_SERVICE_STARTED in bta/bta_gatt_api.h */ + ESP_GATT_ENCRYPTED_MITM = ESP_GATT_OK, /* relate to BTA_GATT_ENCRYPED_MITM in bta/bta_gatt_api.h */ + ESP_GATT_ENCRYPTED_NO_MITM = 0x8d, /* 0x8d */ /* relate to BTA_GATT_ENCRYPED_NO_MITM in bta/bta_gatt_api.h */ + ESP_GATT_NOT_ENCRYPTED = 0x8e, /* 0x8e */ /* relate to BTA_GATT_NOT_ENCRYPTED in bta/bta_gatt_api.h */ + ESP_GATT_CONGESTED = 0x8f, /* 0x8f */ /* relate to BTA_GATT_CONGESTED in bta/bta_gatt_api.h */ + ESP_GATT_DUP_REG = 0x90, /* 0x90 */ /* relate to BTA_GATT_DUP_REG in bta/bta_gatt_api.h */ + ESP_GATT_ALREADY_OPEN = 0x91, /* 0x91 */ /* relate to BTA_GATT_ALREADY_OPEN in bta/bta_gatt_api.h */ + ESP_GATT_CANCEL = 0x92, /* 0x92 */ /* relate to BTA_GATT_CANCEL in bta/bta_gatt_api.h */ + /* 0xE0 ~ 0xFC reserved for future use */ + ESP_GATT_STACK_RSP = 0xe0, /* 0xe0 */ /* relate to BTA_GATT_STACK_RSP in bta/bta_gatt_api.h */ + ESP_GATT_APP_RSP = 0xe1, /* 0xe1 */ /* relate to BTA_GATT_APP_RSP in bta/bta_gatt_api.h */ + //Error caused by customer application or stack bug + ESP_GATT_UNKNOWN_ERROR = 0xef, /* 0xef */ /* relate to BTA_GATT_UNKNOWN_ERROR in bta/bta_gatt_api.h */ + ESP_GATT_CCC_CFG_ERR = 0xfd, /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */ /* relate to BTA_GATT_CCC_CFG_ERR in bta/bta_gatt_api.h */ + ESP_GATT_PRC_IN_PROGRESS = 0xfe, /* 0xFE Procedure Already in progress */ /* relate to BTA_GATT_PRC_IN_PROGRESS in bta/bta_gatt_api.h */ + ESP_GATT_OUT_OF_RANGE = 0xff, /* 0xFF Attribute value out of range */ /* relate to BTA_GATT_OUT_OF_RANGE in bta/bta_gatt_api.h */ +} esp_gatt_status_t; + +/* relate to BTA_GATT_CONN_xxx in bta/bta_gatt_api.h */ +/** + * @brief Gatt Connection reason enum + */ +typedef enum { + ESP_GATT_CONN_UNKNOWN = 0, /*!< Gatt connection unknown */ /* relate to BTA_GATT_CONN_UNKNOWN in bta/bta_gatt_api.h */ + ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */ /* relate to BTA_GATT_CONN_L2C_FAILURE in bta/bta_gatt_api.h */ + ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */ /* relate to BTA_GATT_CONN_TIMEOUT in bta/bta_gatt_api.h */ + ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */ /* relate to BTA_GATT_CONN_TERMINATE_PEER_USER in bta/bta_gatt_api.h */ + ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connection terminated by local host */ /* relate to BTA_GATT_CONN_TERMINATE_LOCAL_HOST in bta/bta_gatt_api.h */ + ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */ /* relate to BTA_GATT_CONN_FAIL_ESTABLISH in bta/bta_gatt_api.h */ + ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */ /* relate to BTA_GATT_CONN_LMP_TIMEOUT in bta/bta_gatt_api.h */ + ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */ /* relate to BTA_GATT_CONN_CONN_CANCEL in bta/bta_gatt_api.h */ + ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel */ /* relate to BTA_GATT_CONN_NONE in bta/bta_gatt_api.h */ +} esp_gatt_conn_reason_t; + +/** + * @brief Gatt id, include uuid and instance id + */ +typedef struct { + esp_bt_uuid_t uuid; /*!< UUID */ + uint8_t inst_id; /*!< Instance id */ +} __attribute__((packed)) esp_gatt_id_t; + +/** + * @brief Gatt service id, include id + * (uuid and instance id) and primary flag + */ +typedef struct { + esp_gatt_id_t id; /*!< Gatt id, include uuid and instance */ + bool is_primary; /*!< This service is primary or not */ +} __attribute__((packed)) esp_gatt_srvc_id_t; + +/* relate to BTA_GATT_AUTH_REQ_xxx in bta/bta_gatt_api.h */ +/** + * @brief Gatt authentication request type + */ +typedef enum { + ESP_GATT_AUTH_REQ_NONE = 0, /* relate to BTA_GATT_AUTH_REQ_NONE in bta/bta_gatt_api.h */ + ESP_GATT_AUTH_REQ_NO_MITM = 1, /* unauthenticated encryption */ /* relate to BTA_GATT_AUTH_REQ_NO_MITM in bta/bta_gatt_api.h */ + ESP_GATT_AUTH_REQ_MITM = 2, /* authenticated encryption */ /* relate to BTA_GATT_AUTH_REQ_MITM in bta/bta_gatt_api.h */ + ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /* relate to BTA_GATT_AUTH_REQ_SIGNED_NO_MITM in bta/bta_gatt_api.h */ + ESP_GATT_AUTH_REQ_SIGNED_MITM = 4, /* relate to BTA_GATT_AUTH_REQ_SIGNED_MITM in bta/bta_gatt_api.h */ +} esp_gatt_auth_req_t; + +/* relate to BTA_GATT_PERM_xxx in bta/bta_gatt_api.h */ +/** + * @brief Attribute permissions + */ +#define ESP_GATT_PERM_READ (1 << 0) /* bit 0 - 0x0001 */ /* relate to BTA_GATT_PERM_READ in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 - 0x0002 */ /* relate to BTA_GATT_PERM_READ_ENCRYPTED in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 - 0x0004 */ /* relate to BTA_GATT_PERM_READ_ENC_MITM in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_WRITE (1 << 4) /* bit 4 - 0x0010 */ /* relate to BTA_GATT_PERM_WRITE in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 - 0x0020 */ /* relate to BTA_GATT_PERM_WRITE_ENCRYPTED in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 - 0x0040 */ /* relate to BTA_GATT_PERM_WRITE_ENC_MITM in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 - 0x0080 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 - 0x0100 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED_MITM in bta/bta_gatt_api.h */ +#define ESP_GATT_PERM_READ_AUTHORIZATION (1 << 9) /* bit 9 - 0x0200 */ +#define ESP_GATT_PERM_WRITE_AUTHORIZATION (1 << 10) /* bit 10 - 0x0400 */ +#define ESP_GATT_PERM_ENCRYPT_KEY_SIZE(keysize) (((keysize - 6) & 0xF) << 12) /* bit 12:15 - 0xF000 */ +typedef uint16_t esp_gatt_perm_t; + +/* relate to BTA_GATT_CHAR_PROP_BIT_xxx in bta/bta_gatt_api.h */ +/* definition of characteristic properties */ +#define ESP_GATT_CHAR_PROP_BIT_BROADCAST (1 << 0) /* 0x01 */ /* relate to BTA_GATT_CHAR_PROP_BIT_BROADCAST in bta/bta_gatt_api.h */ +#define ESP_GATT_CHAR_PROP_BIT_READ (1 << 1) /* 0x02 */ /* relate to BTA_GATT_CHAR_PROP_BIT_READ in bta/bta_gatt_api.h */ +#define ESP_GATT_CHAR_PROP_BIT_WRITE_NR (1 << 2) /* 0x04 */ /* relate to BTA_GATT_CHAR_PROP_BIT_WRITE_NR in bta/bta_gatt_api.h */ +#define ESP_GATT_CHAR_PROP_BIT_WRITE (1 << 3) /* 0x08 */ /* relate to BTA_GATT_CHAR_PROP_BIT_WRITE in bta/bta_gatt_api.h */ +#define ESP_GATT_CHAR_PROP_BIT_NOTIFY (1 << 4) /* 0x10 */ /* relate to BTA_GATT_CHAR_PROP_BIT_NOTIFY in bta/bta_gatt_api.h */ +#define ESP_GATT_CHAR_PROP_BIT_INDICATE (1 << 5) /* 0x20 */ /* relate to BTA_GATT_CHAR_PROP_BIT_INDICATE in bta/bta_gatt_api.h */ +#define ESP_GATT_CHAR_PROP_BIT_AUTH (1 << 6) /* 0x40 */ /* relate to BTA_GATT_CHAR_PROP_BIT_AUTH in bta/bta_gatt_api.h */ +#define ESP_GATT_CHAR_PROP_BIT_EXT_PROP (1 << 7) /* 0x80 */ /* relate to BTA_GATT_CHAR_PROP_BIT_EXT_PROP in bta/bta_gatt_api.h */ +typedef uint8_t esp_gatt_char_prop_t; + +/// GATT maximum attribute length +#define ESP_GATT_MAX_ATTR_LEN 600 //as same as GATT_MAX_ATTR_LEN + +typedef enum { + ESP_GATT_SERVICE_FROM_REMOTE_DEVICE = 0, /* relate to BTA_GATTC_SERVICE_INFO_FROM_REMOTE_DEVICE in bta_gattc_int.h */ + ESP_GATT_SERVICE_FROM_NVS_FLASH = 1, /* relate to BTA_GATTC_SERVICE_INFO_FROM_NVS_FLASH in bta_gattc_int.h */ + ESP_GATT_SERVICE_FROM_UNKNOWN = 2, /* relate to BTA_GATTC_SERVICE_INFO_FROM_UNKNOWN in bta_gattc_int.h */ +} esp_service_source_t; + +/** + * @brief Attribute description (used to create database) + */ + typedef struct + { + uint16_t uuid_length; /*!< UUID length */ + uint8_t *uuid_p; /*!< UUID value */ + uint16_t perm; /*!< Attribute permission */ + uint16_t max_length; /*!< Maximum length of the element*/ + uint16_t length; /*!< Current length of the element*/ + uint8_t *value; /*!< Element value array*/ + } esp_attr_desc_t; + + +/** + * @brief attribute auto response flag + */ +typedef struct +{ +#define ESP_GATT_RSP_BY_APP 0 +#define ESP_GATT_AUTO_RSP 1 + /** + * @brief if auto_rsp set to ESP_GATT_RSP_BY_APP, means the response of Write/Read operation will by replied by application. + if auto_rsp set to ESP_GATT_AUTO_RSP, means the response of Write/Read operation will be replied by GATT stack automatically. + */ + uint8_t auto_rsp; +} esp_attr_control_t; + + +/** + * @brief attribute type added to the gatt server database + */ +typedef struct +{ + esp_attr_control_t attr_control; /*!< The attribute control type */ + esp_attr_desc_t att_desc; /*!< The attribute type */ +} esp_gatts_attr_db_t; + + +/** + * @brief set the attribute value type + */ +typedef struct +{ + uint16_t attr_max_len; /*!< attribute max value length */ + uint16_t attr_len; /*!< attribute current value length */ + uint8_t *attr_value; /*!< the pointer to attribute value */ +} esp_attr_value_t; + + +/** + * @brief Gatt include service entry element + */ +typedef struct +{ + uint16_t start_hdl; /*!< Gatt start handle value of included service */ + uint16_t end_hdl; /*!< Gatt end handle value of included service */ + uint16_t uuid; /*!< Gatt attribute value UUID of included service */ +} esp_gatts_incl_svc_desc_t; /*!< Gatt include service entry element */ + +/** + * @brief Gatt include 128 bit service entry element + */ +typedef struct +{ + uint16_t start_hdl; /*!< Gatt start handle value of included 128 bit service */ + uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */ +} esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */ + +/// Gatt attribute value +typedef struct { + uint8_t value[ESP_GATT_MAX_ATTR_LEN]; /*!< Gatt attribute value */ + uint16_t handle; /*!< Gatt attribute handle */ + uint16_t offset; /*!< Gatt attribute value offset */ + uint16_t len; /*!< Gatt attribute value length */ + uint8_t auth_req; /*!< Gatt authentication request */ +} esp_gatt_value_t; + +/// GATT remote read request response type +typedef union { + esp_gatt_value_t attr_value; /*!< Gatt attribute structure */ + uint16_t handle; /*!< Gatt attribute handle */ +} esp_gatt_rsp_t; + +/** + * @brief Gatt write type + */ +typedef enum { + ESP_GATT_WRITE_TYPE_NO_RSP = 1, /*!< Gatt write attribute need no response */ + ESP_GATT_WRITE_TYPE_RSP, /*!< Gatt write attribute need remote response */ +} esp_gatt_write_type_t; + +/** + * @brief Connection parameters information + */ +typedef struct { + uint16_t interval; /*!< connection interval */ + uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */ + uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80. + Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec + Time Range: 100 msec to 32 seconds */ +} esp_gatt_conn_params_t; + +#define ESP_GATT_IF_NONE 0xff /*!< If callback report gattc_if/gatts_if as this macro, means this event is not correspond to any app */ + +typedef uint8_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */ + +/** + * @brief the type of attribute element + */ +typedef enum { + ESP_GATT_DB_PRIMARY_SERVICE, /*!< Gattc primary service attribute type in the cache */ + ESP_GATT_DB_SECONDARY_SERVICE, /*!< Gattc secondary service attribute type in the cache */ + ESP_GATT_DB_CHARACTERISTIC, /*!< Gattc characteristic attribute type in the cache */ + ESP_GATT_DB_DESCRIPTOR, /*!< Gattc characteristic descriptor attribute type in the cache */ + ESP_GATT_DB_INCLUDED_SERVICE, /*!< Gattc include service attribute type in the cache */ + ESP_GATT_DB_ALL, /*!< Gattc all the attribute (primary service & secondary service & include service & char & descriptor) type in the cache */ +} esp_gatt_db_attr_type_t; /*!< Gattc attribute type element */ + +/** + * @brief read multiple attribute + */ +typedef struct { + uint8_t num_attr; /*!< The number of the attribute */ + uint16_t handles[ESP_GATT_MAX_READ_MULTI_HANDLES]; /*!< The handles list */ +} esp_gattc_multi_t; /*!< The gattc multiple read element */ + +/** + * @brief data base attribute element + */ +typedef struct { + esp_gatt_db_attr_type_t type; /*!< The attribute type */ + uint16_t attribute_handle; /*!< The attribute handle, it's valid for all of the type */ + uint16_t start_handle; /*!< The service start handle, it's valid only when the type = ESP_GATT_DB_PRIMARY_SERVICE or ESP_GATT_DB_SECONDARY_SERVICE */ + uint16_t end_handle; /*!< The service end handle, it's valid only when the type = ESP_GATT_DB_PRIMARY_SERVICE or ESP_GATT_DB_SECONDARY_SERVICE */ + esp_gatt_char_prop_t properties; /*!< The characteristic properties, it's valid only when the type = ESP_GATT_DB_CHARACTERISTIC */ + esp_bt_uuid_t uuid; /*!< The attribute uuid, it's valid for all of the type */ +} esp_gattc_db_elem_t; /*!< The gattc service data base element in the cache */ + +/** + * @brief service element + */ +typedef struct { + bool is_primary; /*!< The service flag, true if the service is primary service, else is secondary service */ + uint16_t start_handle; /*!< The start handle of the service */ + uint16_t end_handle; /*!< The end handle of the service */ + esp_bt_uuid_t uuid; /*!< The uuid of the service */ +} esp_gattc_service_elem_t; /*!< The gattc service element */ + +/** + * @brief characteristic element + */ +typedef struct { + uint16_t char_handle; /*!< The characteristic handle */ + esp_gatt_char_prop_t properties; /*!< The characteristic properties */ + esp_bt_uuid_t uuid; /*!< The characteristic uuid */ +} esp_gattc_char_elem_t; /*!< The gattc characteristic element */ + +/** + * @brief descriptor element + */ +typedef struct { + uint16_t handle; /*!< The characteristic descriptor handle */ + esp_bt_uuid_t uuid; /*!< The characteristic descriptor uuid */ +} esp_gattc_descr_elem_t; /*!< The gattc descriptor type element */ + +/** + * @brief include service element + */ +typedef struct { + uint16_t handle; /*!< The include service current attribute handle */ + uint16_t incl_srvc_s_handle; /*!< The start handle of the service which has been included */ + uint16_t incl_srvc_e_handle; /*!< The end handle of the service which has been included */ + esp_bt_uuid_t uuid; /*!< The include service uuid */ +} esp_gattc_incl_svc_elem_t; /*!< The gattc include service element */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_GATT_DEFS_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h new file mode 100644 index 00000000..13bf16a3 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h @@ -0,0 +1,913 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_GATTC_API_H__ +#define __ESP_GATTC_API_H__ + +#include "esp_bt_defs.h" +#include "esp_gatt_defs.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// GATT Client callback function events +typedef enum { + ESP_GATTC_REG_EVT = 0, /*!< When GATT client is registered, the event comes */ + ESP_GATTC_UNREG_EVT = 1, /*!< When GATT client is unregistered, the event comes */ + ESP_GATTC_OPEN_EVT = 2, /*!< When GATT virtual connection is set up, the event comes */ + ESP_GATTC_READ_CHAR_EVT = 3, /*!< When GATT characteristic is read, the event comes */ + ESP_GATTC_WRITE_CHAR_EVT = 4, /*!< When GATT characteristic write operation completes, the event comes */ + ESP_GATTC_CLOSE_EVT = 5, /*!< When GATT virtual connection is closed, the event comes */ + ESP_GATTC_SEARCH_CMPL_EVT = 6, /*!< When GATT service discovery is completed, the event comes */ + ESP_GATTC_SEARCH_RES_EVT = 7, /*!< When GATT service discovery result is got, the event comes */ + ESP_GATTC_READ_DESCR_EVT = 8, /*!< When GATT characteristic descriptor read completes, the event comes */ + ESP_GATTC_WRITE_DESCR_EVT = 9, /*!< When GATT characteristic descriptor write completes, the event comes */ + ESP_GATTC_NOTIFY_EVT = 10, /*!< When GATT notification or indication arrives, the event comes */ + ESP_GATTC_PREP_WRITE_EVT = 11, /*!< When GATT prepare-write operation completes, the event comes */ + ESP_GATTC_EXEC_EVT = 12, /*!< When write execution completes, the event comes */ + ESP_GATTC_ACL_EVT = 13, /*!< When ACL connection is up, the event comes */ + ESP_GATTC_CANCEL_OPEN_EVT = 14, /*!< When GATT client ongoing connection is cancelled, the event comes */ + ESP_GATTC_SRVC_CHG_EVT = 15, /*!< When "service changed" occurs, the event comes */ + ESP_GATTC_ENC_CMPL_CB_EVT = 17, /*!< When encryption procedure completes, the event comes */ + ESP_GATTC_CFG_MTU_EVT = 18, /*!< When configuration of MTU completes, the event comes */ + ESP_GATTC_ADV_DATA_EVT = 19, /*!< When advertising of data, the event comes */ + ESP_GATTC_MULT_ADV_ENB_EVT = 20, /*!< When multi-advertising is enabled, the event comes */ + ESP_GATTC_MULT_ADV_UPD_EVT = 21, /*!< When multi-advertising parameters are updated, the event comes */ + ESP_GATTC_MULT_ADV_DATA_EVT = 22, /*!< When multi-advertising data arrives, the event comes */ + ESP_GATTC_MULT_ADV_DIS_EVT = 23, /*!< When multi-advertising is disabled, the event comes */ + ESP_GATTC_CONGEST_EVT = 24, /*!< When GATT connection congestion comes, the event comes */ + ESP_GATTC_BTH_SCAN_ENB_EVT = 25, /*!< When batch scan is enabled, the event comes */ + ESP_GATTC_BTH_SCAN_CFG_EVT = 26, /*!< When batch scan storage is configured, the event comes */ + ESP_GATTC_BTH_SCAN_RD_EVT = 27, /*!< When Batch scan read event is reported, the event comes */ + ESP_GATTC_BTH_SCAN_THR_EVT = 28, /*!< When Batch scan threshold is set, the event comes */ + ESP_GATTC_BTH_SCAN_PARAM_EVT = 29, /*!< When Batch scan parameters are set, the event comes */ + ESP_GATTC_BTH_SCAN_DIS_EVT = 30, /*!< When Batch scan is disabled, the event comes */ + ESP_GATTC_SCAN_FLT_CFG_EVT = 31, /*!< When Scan filter configuration completes, the event comes */ + ESP_GATTC_SCAN_FLT_PARAM_EVT = 32, /*!< When Scan filter parameters are set, the event comes */ + ESP_GATTC_SCAN_FLT_STATUS_EVT = 33, /*!< When Scan filter status is reported, the event comes */ + ESP_GATTC_ADV_VSC_EVT = 34, /*!< When advertising vendor spec content event is reported, the event comes */ + ESP_GATTC_REG_FOR_NOTIFY_EVT = 38, /*!< When register for notification of a service completes, the event comes */ + ESP_GATTC_UNREG_FOR_NOTIFY_EVT = 39, /*!< When unregister for notification of a service completes, the event comes */ + ESP_GATTC_CONNECT_EVT = 40, /*!< When the ble physical connection is set up, the event comes */ + ESP_GATTC_DISCONNECT_EVT = 41, /*!< When the ble physical connection disconnected, the event comes */ + ESP_GATTC_READ_MULTIPLE_EVT = 42, /*!< When the ble characteristic or descriptor multiple complete, the event comes */ + ESP_GATTC_QUEUE_FULL_EVT = 43, /*!< When the gattc command queue full, the event comes */ + ESP_GATTC_SET_ASSOC_EVT = 44, /*!< When the ble gattc set the associated address complete, the event comes */ + ESP_GATTC_GET_ADDR_LIST_EVT = 45, /*!< When the ble get gattc address list in cache finish, the event comes */ + ESP_GATTC_DIS_SRVC_CMPL_EVT = 46, /*!< When the ble discover service complete, the event comes */ + ESP_GATTC_READ_MULTI_VAR_EVT = 47, /*!< When read multiple variable characteristic complete, the event comes */ +} esp_gattc_cb_event_t; + + +/** + * @brief Gatt client callback parameters union + */ +typedef union { + /** + * @brief ESP_GATTC_REG_EVT + */ + struct gattc_reg_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t app_id; /*!< Application id which input in register API */ + } reg; /*!< Gatt client callback param of ESP_GATTC_REG_EVT */ + + /** + * @brief ESP_GATTC_OPEN_EVT + */ + struct gattc_open_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + uint16_t mtu; /*!< MTU size */ + } open; /*!< Gatt client callback param of ESP_GATTC_OPEN_EVT */ + + /** + * @brief ESP_GATTC_CLOSE_EVT + */ + struct gattc_close_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + esp_gatt_conn_reason_t reason; /*!< The reason of gatt connection close */ + } close; /*!< Gatt client callback param of ESP_GATTC_CLOSE_EVT */ + + /** + * @brief ESP_GATTC_CFG_MTU_EVT + */ + struct gattc_cfg_mtu_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + uint16_t mtu; /*!< MTU size */ + } cfg_mtu; /*!< Gatt client callback param of ESP_GATTC_CFG_MTU_EVT */ + + /** + * @brief ESP_GATTC_SEARCH_CMPL_EVT + */ + struct gattc_search_cmpl_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + esp_service_source_t searched_service_source; /*!< The source of the service information */ + } search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */ + + /** + * @brief ESP_GATTC_SEARCH_RES_EVT + */ + struct gattc_search_res_evt_param { + uint16_t conn_id; /*!< Connection id */ + uint16_t start_handle; /*!< Service start handle */ + uint16_t end_handle; /*!< Service end handle */ + esp_gatt_id_t srvc_id; /*!< Service id, include service uuid and other information */ + bool is_primary; /*!< True if this is the primary service */ + } search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */ + + /** + * @brief ESP_GATTC_READ_CHAR_EVT, ESP_GATTC_READ_DESCR_EVT, ESP_GATTC_READ_MULTIPLE_EVT, ESP_GATTC_READ_MULTI_VAR_EVT + */ + struct gattc_read_char_evt_param { + + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + uint16_t handle; /*!< Characteristic handle */ + uint8_t *value; /*!< Characteristic value */ + uint16_t value_len; /*!< Characteristic value length */ + } read; /*!< Gatt client callback param of ESP_GATTC_READ_CHAR_EVT */ + + /** + * @brief ESP_GATTC_WRITE_CHAR_EVT, ESP_GATTC_PREP_WRITE_EVT, ESP_GATTC_WRITE_DESCR_EVT + */ + struct gattc_write_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + uint16_t handle; /*!< The Characteristic or descriptor handle */ + uint16_t offset; /*!< The prepare write offset, this value is valid only when prepare write */ + } write; /*!< Gatt client callback param of ESP_GATTC_WRITE_DESCR_EVT */ + + /** + * @brief ESP_GATTC_EXEC_EVT + */ + struct gattc_exec_cmpl_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + } exec_cmpl; /*!< Gatt client callback param of ESP_GATTC_EXEC_EVT */ + + /** + * @brief ESP_GATTC_NOTIFY_EVT + */ + struct gattc_notify_evt_param { + uint16_t conn_id; /*!< Connection id */ + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + uint16_t handle; /*!< The Characteristic or descriptor handle */ + uint16_t value_len; /*!< Notify attribute value */ + uint8_t *value; /*!< Notify attribute value */ + bool is_notify; /*!< True means notify, false means indicate */ + } notify; /*!< Gatt client callback param of ESP_GATTC_NOTIFY_EVT */ + + /** + * @brief ESP_GATTC_SRVC_CHG_EVT + */ + struct gattc_srvc_chg_evt_param { + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + } srvc_chg; /*!< Gatt client callback param of ESP_GATTC_SRVC_CHG_EVT */ + + /** + * @brief ESP_GATTC_CONGEST_EVT + */ + struct gattc_congest_evt_param { + uint16_t conn_id; /*!< Connection id */ + bool congested; /*!< Congested or not */ + } congest; /*!< Gatt client callback param of ESP_GATTC_CONGEST_EVT */ + /** + * @brief ESP_GATTC_REG_FOR_NOTIFY_EVT + */ + struct gattc_reg_for_notify_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t handle; /*!< The characteristic or descriptor handle */ + } reg_for_notify; /*!< Gatt client callback param of ESP_GATTC_REG_FOR_NOTIFY_EVT */ + + /** + * @brief ESP_GATTC_UNREG_FOR_NOTIFY_EVT + */ + struct gattc_unreg_for_notify_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t handle; /*!< The characteristic or descriptor handle */ + } unreg_for_notify; /*!< Gatt client callback param of ESP_GATTC_UNREG_FOR_NOTIFY_EVT */ + + /** + * @brief ESP_GATTC_CONNECT_EVT + */ + struct gattc_connect_evt_param { + uint16_t conn_id; /*!< Connection id */ + uint8_t link_role; /*!< Link role : master role = 0 ; slave role = 1*/ + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + esp_gatt_conn_params_t conn_params; /*!< current connection parameters */ + esp_ble_addr_type_t ble_addr_type; /*!< Remote BLE device address type */ + uint16_t conn_handle; /*!< HCI connection handle */ + } connect; /*!< Gatt client callback param of ESP_GATTC_CONNECT_EVT */ + + /** + * @brief ESP_GATTC_DISCONNECT_EVT + */ + struct gattc_disconnect_evt_param { + esp_gatt_conn_reason_t reason; /*!< disconnection reason */ + uint16_t conn_id; /*!< Connection id */ + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + } disconnect; /*!< Gatt client callback param of ESP_GATTC_DISCONNECT_EVT */ + /** + * @brief ESP_GATTC_SET_ASSOC_EVT + */ + struct gattc_set_assoc_addr_cmp_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + } set_assoc_cmp; /*!< Gatt client callback param of ESP_GATTC_SET_ASSOC_EVT */ + /** + * @brief ESP_GATTC_GET_ADDR_LIST_EVT + */ + struct gattc_get_addr_list_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint8_t num_addr; /*!< The number of address in the gattc cache address list */ + esp_bd_addr_t *addr_list; /*!< The pointer to the address list which has been get from the gattc cache */ + } get_addr_list; /*!< Gatt client callback param of ESP_GATTC_GET_ADDR_LIST_EVT */ + + /** + * @brief ESP_GATTC_QUEUE_FULL_EVT + */ + struct gattc_queue_full_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + bool is_full; /*!< The gattc command queue is full or not */ + } queue_full; /*!< Gatt client callback param of ESP_GATTC_QUEUE_FULL_EVT */ + + /** + * @brief ESP_GATTC_DIS_SRVC_CMPL_EVT + */ + struct gattc_dis_srvc_cmpl_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + } dis_srvc_cmpl; /*!< Gatt client callback param of ESP_GATTC_DIS_SRVC_CMPL_EVT */ + +} esp_ble_gattc_cb_param_t; /*!< GATT client callback parameter union type */ + +/** + * @brief GATT Client callback function type + * @param event : Event type + * @param gattc_if : GATT client access interface, normally + * different gattc_if correspond to different profile + * @param param : Point to callback parameter, currently is union type + */ +typedef void (* esp_gattc_cb_t)(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); + +/** + * @brief This function is called to register application callbacks + * with GATTC module. + * + * @param[in] callback : pointer to the application callback function. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback); + +/** + * @brief This function is called to get the current application callbacks + * with BTA GATTC module. + * + * @return + * - esp_gattC_cb_t : current callback + * + */ +esp_gattc_cb_t esp_ble_gattc_get_callback(void); + +/** + * @brief This function is called to register application callbacks + * with GATTC module. + * + * @param[in] app_id : Application Identify (UUID), for different application + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_app_register(uint16_t app_id); + + +/** + * @brief This function is called to unregister an application + * from GATTC module. + * + * @param[in] gattc_if: Gatt client access interface. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if); + +#if (BLE_42_FEATURE_SUPPORT == TRUE) +/** + * @brief Open a direct connection or add a background auto connection + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] remote_bda: remote device bluetooth device address. + * @param[in] remote_addr_type: remote device bluetooth device the address type. + * @param[in] is_direct: direct connection or background auto connection(by now, background auto connection is not supported). + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct); +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_gattc_aux_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +/** + * @brief Close the virtual connection to the GATT server. gattc may have multiple virtual GATT server connections when multiple app_id registered, + * this API only close one virtual GATT server connection. if there exist other virtual GATT server connections, + * it does not disconnect the physical connection. + * if you want to disconnect the physical connection directly, you can use esp_ble_gap_disconnect(esp_bd_addr_t remote_device). + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID to be closed. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id); + + +/** + * @brief Configure the MTU size in the GATT channel. This can be done + * only once per connection. Before using, use esp_ble_gatt_set_local_mtu() + * to configure the local MTU size. + * + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_send_mtu_req (esp_gatt_if_t gattc_if, uint16_t conn_id); + + +/** + * @brief This function is called to get service from local cache. + * This function report service search result by a callback + * event, and followed by a service search complete event. + * Note: 128-bit base UUID will automatically be converted to a 16-bit UUID in the search results. Other types of UUID remain unchanged. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID. + * @param[in] filter_uuid: a UUID of the service application is interested in. + * If Null, discover for all services. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *filter_uuid); + +/** + * @brief Find all the service with the given service uuid in the gattc cache, if the svc_uuid is NULL, find all the service. + * Note: It just get service from local cache, won't get from remote devices. If want to get it from remote device, need + * to used the esp_ble_gattc_cache_refresh, then call esp_ble_gattc_get_service again. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] svc_uuid: the pointer to the service uuid. + * @param[out] result: The pointer to the service which has been found in the gattc cache. + * @param[inout] count: input the number of service want to find, + * it will output the number of service has been found in the gattc cache with the given service uuid. + * @param[in] offset: Offset of the service position to get. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *svc_uuid, + esp_gattc_service_elem_t *result, uint16_t *count, uint16_t offset); + +/** + * @brief Find all the characteristic with the given service in the gattc cache + * Note: It just get characteristic from local cache, won't get from remote devices. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] start_handle: the attribute start handle. + * @param[in] end_handle: the attribute end handle + * @param[out] result: The pointer to the characteristic in the service. + * @param[inout] count: input the number of characteristic want to find, + * it will output the number of characteristic has been found in the gattc cache with the given service. + * @param[in] offset: Offset of the characteristic position to get. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_gattc_char_elem_t *result, + uint16_t *count, uint16_t offset); + +/** + * @brief Find all the descriptor with the given characteristic in the gattc cache + * Note: It just get descriptor from local cache, won't get from remote devices. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] char_handle: the given characteristic handle + * @param[out] result: The pointer to the descriptor in the characteristic. + * @param[inout] count: input the number of descriptor want to find, + * it will output the number of descriptor has been found in the gattc cache with the given characteristic. + * @param[in] offset: Offset of the descriptor position to get. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t char_handle, + esp_gattc_descr_elem_t *result, + uint16_t *count, uint16_t offset); + + +/** + * @brief Find the characteristic with the given characteristic uuid in the gattc cache + * Note: It just get characteristic from local cache, won't get from remote devices. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] start_handle: the attribute start handle + * @param[in] end_handle: the attribute end handle + * @param[in] char_uuid: the characteristic uuid + * @param[out] result: The pointer to the characteristic in the service. + * @param[inout] count: input the number of characteristic want to find, + * it will output the number of characteristic has been found in the gattc cache with the given service. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t char_uuid, + esp_gattc_char_elem_t *result, + uint16_t *count); + +/** + * @brief Find the descriptor with the given characteristic uuid in the gattc cache + * Note: It just get descriptor from local cache, won't get from remote devices. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] start_handle: the attribute start handle + * @param[in] end_handle: the attribute end handle + * @param[in] char_uuid: the characteristic uuid. + * @param[in] descr_uuid: the descriptor uuid. + * @param[out] result: The pointer to the descriptor in the given characteristic. + * @param[inout] count: input the number of descriptor want to find, + * it will output the number of descriptor has been found in the gattc cache with the given characteristic. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t char_uuid, + esp_bt_uuid_t descr_uuid, + esp_gattc_descr_elem_t *result, + uint16_t *count); + +/** + * @brief Find the descriptor with the given characteristic handle in the gattc cache + * Note: It just get descriptor from local cache, won't get from remote devices. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] char_handle: the characteristic handle. + * @param[in] descr_uuid: the descriptor uuid. + * @param[out] result: The pointer to the descriptor in the given characteristic. + * @param[inout] count: input the number of descriptor want to find, + * it will output the number of descriptor has been found in the gattc cache with the given characteristic. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t char_handle, + esp_bt_uuid_t descr_uuid, + esp_gattc_descr_elem_t *result, + uint16_t *count); + +/** + * @brief Find the include service with the given service handle in the gattc cache + * Note: It just get include service from local cache, won't get from remote devices. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] start_handle: the attribute start handle + * @param[in] end_handle: the attribute end handle + * @param[in] incl_uuid: the include service uuid + * @param[out] result: The pointer to the include service in the given service. + * @param[inout] count: input the number of include service want to find, + * it will output the number of include service has been found in the gattc cache with the given service. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t *incl_uuid, + esp_gattc_incl_svc_elem_t *result, + uint16_t *count); + + +/** + * @brief Find the attribute count with the given service or characteristic in the gattc cache + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id: connection ID which identify the server. + * @param[in] type: the attribute type. + * @param[in] start_handle: the attribute start handle, if the type is ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore + * @param[in] end_handle: the attribute end handle, if the type is ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore + * @param[in] char_handle: the characteristic handle, this parameter valid when the type is ESP_GATT_DB_DESCRIPTOR. If the type + * isn't ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore. + * @param[out] count: output the number of attribute has been found in the gattc cache with the given attribute type. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if, + uint16_t conn_id, + esp_gatt_db_attr_type_t type, + uint16_t start_handle, + uint16_t end_handle, + uint16_t char_handle, + uint16_t *count); + +/** + * @brief This function is called to get the GATT database. + * Note: It just get attribute data base from local cache, won't get from remote devices. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] start_handle: the attribute start handle + * @param[in] end_handle: the attribute end handle + * @param[in] conn_id: connection ID which identify the server. + * @param[in] db: output parameter which will contain the GATT database copy. + * Caller is responsible for freeing it. + * @param[in] count: number of elements in database. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, + esp_gattc_db_elem_t *db, uint16_t *count); + +/** + * @brief This function is called to read a service's characteristics of + * the given characteristic handle + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] handle : characteritic handle to read. + * @param[in] auth_req : authenticate request type + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t handle, + esp_gatt_auth_req_t auth_req); + +/** + * @brief This function is called to read a service's characteristics of + * the given characteristic UUID + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] start_handle : the attribute start handle. + * @param[in] end_handle : the attribute end handle + * @param[in] uuid : The UUID of attribute which will be read. + * @param[in] auth_req : authenticate request type + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_read_by_type (esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + esp_bt_uuid_t *uuid, + esp_gatt_auth_req_t auth_req); + +/** + * @brief This function is called to read multiple characteristic or + * characteristic descriptors. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] read_multi : pointer to the read multiple parameter. + * @param[in] auth_req : authenticate request type + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req); + +/** + * @brief This function is called to read multiple variable length characteristic or + * characteristic descriptors. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] read_multi : pointer to the read multiple parameter. + * @param[in] auth_req : authenticate request type + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req); + +/** + * @brief This function is called to read a characteristics descriptor. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] handle : descriptor handle to read. + * @param[in] auth_req : authenticate request type + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t handle, + esp_gatt_auth_req_t auth_req); + + +/** + * @brief This function is called to write characteristic value. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] handle : characteristic handle to write. + * @param[in] value_len: length of the value to be written. + * @param[in] value : the value to be written. + * @param[in] write_type : the type of attribute write operation. + * @param[in] auth_req : authentication request. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t handle, + uint16_t value_len, + uint8_t *value, + esp_gatt_write_type_t write_type, + esp_gatt_auth_req_t auth_req); + + +/** + * @brief This function is called to write characteristic descriptor value. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID + * @param[in] handle : descriptor handle to write. + * @param[in] value_len: length of the value to be written. + * @param[in] value : the value to be written. + * @param[in] write_type : the type of attribute write operation. + * @param[in] auth_req : authentication request. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t handle, + uint16_t value_len, + uint8_t *value, + esp_gatt_write_type_t write_type, + esp_gatt_auth_req_t auth_req); + + +/** + * @brief This function is called to prepare write a characteristic value. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] handle : characteristic handle to prepare write. + * @param[in] offset : offset of the write value. + * @param[in] value_len: length of the value to be written. + * @param[in] value : the value to be written. + * @param[in] auth_req : authentication request. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t handle, + uint16_t offset, + uint16_t value_len, + uint8_t *value, + esp_gatt_auth_req_t auth_req); + + +/** + * @brief This function is called to prepare write a characteristic descriptor value. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] handle : characteristic descriptor handle to prepare write. + * @param[in] offset : offset of the write value. + * @param[in] value_len: length of the value to be written. + * @param[in] value : the value to be written. + * @param[in] auth_req : authentication request. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if, + uint16_t conn_id, + uint16_t handle, + uint16_t offset, + uint16_t value_len, + uint8_t *value, + esp_gatt_auth_req_t auth_req); + + +/** + * @brief This function is called to execute write a prepare write sequence. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] is_execute : execute or cancel. + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, bool is_execute); + + +/** + * @brief This function is called to register for notification of a service. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] server_bda : target GATT server. + * @param[in] handle : GATT characteristic handle. + * + * @return + * - ESP_OK: registration succeeds + * - other: failed + * + */ +esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, + esp_bd_addr_t server_bda, + uint16_t handle); + + +/** + * @brief This function is called to de-register for notification of a service. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] server_bda : target GATT server. + * @param[in] handle : GATT characteristic handle. + * + * @return + * - ESP_OK: unregister succeeds + * - other: failed + * + */ +esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if, + esp_bd_addr_t server_bda, + uint16_t handle); + + +/** +* @brief Refresh the server cache store in the gattc stack of the remote device. If +* the device is connected, this API will restart the discovery of service information of the remote device +* +* @param[in] remote_bda: remote device BD address. +* +* @return +* - ESP_OK: success +* - other: failed +* +*/ +esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda); + +/** +* @brief Add or delete the associated address with the source address. +* Note: The role of this API is mainly when the client side has stored a server-side database, +* when it needs to connect another device, but the device's attribute database is the same +* as the server database stored on the client-side, calling this API can use the database +* that the device has stored used as the peer server database to reduce the attribute +* database search and discovery process and speed up the connection time. +* The associated address mains that device want to used the database has stored in the local cache. +* The source address mains that device want to share the database to the associated address device. +* +* @param[in] gattc_if: Gatt client access interface. +* @param[in] src_addr: the source address which provide the attribute table. +* @param[in] assoc_addr: the associated device address which went to share the attribute table with the source address. +* @param[in] is_assoc: true add the associated device address, false remove the associated device address. +* @return +* - ESP_OK: success +* - other: failed +* +*/ +esp_err_t esp_ble_gattc_cache_assoc(esp_gatt_if_t gattc_if, esp_bd_addr_t src_addr, + esp_bd_addr_t assoc_addr, bool is_assoc); +/** +* @brief Get the address list which has store the attribute table in the gattc cache. There will +* callback ESP_GATTC_GET_ADDR_LIST_EVT event when get address list complete. +* +* @param[in] gattc_if: Gatt client access interface. +* @return +* - ESP_OK: success +* - other: failed +* +*/ +esp_err_t esp_ble_gattc_cache_get_addr_list(esp_gatt_if_t gattc_if); + +/** +* @brief Clean the service cache of this device in the gattc stack, +* +* @param[in] remote_bda: remote device BD address. +* +* @return +* - ESP_OK: success +* - other: failed +* +*/ +esp_err_t esp_ble_gattc_cache_clean(esp_bd_addr_t remote_bda); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_GATTC_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h new file mode 100644 index 00000000..0eb7ddd9 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h @@ -0,0 +1,600 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_GATTS_API_H__ +#define __ESP_GATTS_API_H__ + +#include "esp_bt_defs.h" +#include "esp_gatt_defs.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// GATT Server callback function events +typedef enum { + ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */ + ESP_GATTS_READ_EVT = 1, /*!< When gatt client request read operation, the event comes */ + ESP_GATTS_WRITE_EVT = 2, /*!< When gatt client request write operation, the event comes */ + ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< When gatt client request execute write, the event comes */ + ESP_GATTS_MTU_EVT = 4, /*!< When set mtu complete, the event comes */ + ESP_GATTS_CONF_EVT = 5, /*!< When receive confirm, the event comes */ + ESP_GATTS_UNREG_EVT = 6, /*!< When unregister application id, the event comes */ + ESP_GATTS_CREATE_EVT = 7, /*!< When create service complete, the event comes */ + ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< When add included service complete, the event comes */ + ESP_GATTS_ADD_CHAR_EVT = 9, /*!< When add characteristic complete, the event comes */ + ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< When add descriptor complete, the event comes */ + ESP_GATTS_DELETE_EVT = 11, /*!< When delete service complete, the event comes */ + ESP_GATTS_START_EVT = 12, /*!< When start service complete, the event comes */ + ESP_GATTS_STOP_EVT = 13, /*!< When stop service complete, the event comes */ + ESP_GATTS_CONNECT_EVT = 14, /*!< When gatt client connect, the event comes */ + ESP_GATTS_DISCONNECT_EVT = 15, /*!< When gatt client disconnect, the event comes */ + ESP_GATTS_OPEN_EVT = 16, /*!< When connect to peer, the event comes */ + ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< When disconnect from peer, the event comes */ + ESP_GATTS_CLOSE_EVT = 18, /*!< When gatt server close, the event comes */ + ESP_GATTS_LISTEN_EVT = 19, /*!< When gatt listen to be connected the event comes */ + ESP_GATTS_CONGEST_EVT = 20, /*!< When congest happen, the event comes */ + /* following is extra event */ + ESP_GATTS_RESPONSE_EVT = 21, /*!< When gatt send response complete, the event comes */ + ESP_GATTS_CREAT_ATTR_TAB_EVT = 22, /*!< When gatt create table complete, the event comes */ + ESP_GATTS_SET_ATTR_VAL_EVT = 23, /*!< When gatt set attr value complete, the event comes */ + ESP_GATTS_SEND_SERVICE_CHANGE_EVT = 24, /*!< When gatt send service change indication complete, the event comes */ +} esp_gatts_cb_event_t; + +/** + * @brief Gatt server callback parameters union + */ +typedef union { + /** + * @brief ESP_GATTS_REG_EVT + */ + struct gatts_reg_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t app_id; /*!< Application id which input in register API */ + } reg; /*!< Gatt server callback param of ESP_GATTS_REG_EVT */ + + /** + * @brief ESP_GATTS_READ_EVT + */ + struct gatts_read_evt_param { + uint16_t conn_id; /*!< Connection id */ + uint32_t trans_id; /*!< Transfer id */ + esp_bd_addr_t bda; /*!< The bluetooth device address which been read */ + uint16_t handle; /*!< The attribute handle */ + uint16_t offset; /*!< Offset of the value, if the value is too long */ + bool is_long; /*!< The value is too long or not */ + bool need_rsp; /*!< The read operation need to do response */ + } read; /*!< Gatt server callback param of ESP_GATTS_READ_EVT */ + + + /** + * @brief ESP_GATTS_WRITE_EVT + */ + struct gatts_write_evt_param { + uint16_t conn_id; /*!< Connection id */ + uint32_t trans_id; /*!< Transfer id */ + esp_bd_addr_t bda; /*!< The bluetooth device address which been written */ + uint16_t handle; /*!< The attribute handle */ + uint16_t offset; /*!< Offset of the value, if the value is too long */ + bool need_rsp; /*!< The write operation need to do response */ + bool is_prep; /*!< This write operation is prepare write */ + uint16_t len; /*!< The write attribute value length */ + uint8_t *value; /*!< The write attribute value */ + } write; /*!< Gatt server callback param of ESP_GATTS_WRITE_EVT */ + + /** + * @brief ESP_GATTS_EXEC_WRITE_EVT + */ + struct gatts_exec_write_evt_param { + uint16_t conn_id; /*!< Connection id */ + uint32_t trans_id; /*!< Transfer id */ + esp_bd_addr_t bda; /*!< The bluetooth device address which been written */ +#define ESP_GATT_PREP_WRITE_CANCEL 0x00 /*!< Prepare write flag to indicate cancel prepare write */ +#define ESP_GATT_PREP_WRITE_EXEC 0x01 /*!< Prepare write flag to indicate execute prepare write */ + uint8_t exec_write_flag; /*!< Execute write flag */ + } exec_write; /*!< Gatt server callback param of ESP_GATTS_EXEC_WRITE_EVT */ + + /** + * @brief ESP_GATTS_MTU_EVT + */ + struct gatts_mtu_evt_param { + uint16_t conn_id; /*!< Connection id */ + uint16_t mtu; /*!< MTU size */ + } mtu; /*!< Gatt server callback param of ESP_GATTS_MTU_EVT */ + + /** + * @brief ESP_GATTS_CONF_EVT + */ + struct gatts_conf_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + uint16_t handle; /*!< attribute handle */ + uint16_t len; /*!< The indication or notification value length, len is valid when send notification or indication failed */ + uint8_t *value; /*!< The indication or notification value , value is valid when send notification or indication failed */ + } conf; /*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */ + + /** + * @brief ESP_GATTS_UNREG_EVT + */ + + /** + * @brief ESP_GATTS_CREATE_EVT + */ + struct gatts_create_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t service_handle; /*!< Service attribute handle */ + esp_gatt_srvc_id_t service_id; /*!< Service id, include service uuid and other information */ + } create; /*!< Gatt server callback param of ESP_GATTS_CREATE_EVT */ + + /** + * @brief ESP_GATTS_ADD_INCL_SRVC_EVT + */ + struct gatts_add_incl_srvc_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t attr_handle; /*!< Included service attribute handle */ + uint16_t service_handle; /*!< Service attribute handle */ + } add_incl_srvc; /*!< Gatt server callback param of ESP_GATTS_ADD_INCL_SRVC_EVT */ + + /** + * @brief ESP_GATTS_ADD_CHAR_EVT + */ + struct gatts_add_char_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t attr_handle; /*!< Characteristic attribute handle */ + uint16_t service_handle; /*!< Service attribute handle */ + esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */ + } add_char; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_EVT */ + + /** + * @brief ESP_GATTS_ADD_CHAR_DESCR_EVT + */ + struct gatts_add_char_descr_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t attr_handle; /*!< Descriptor attribute handle */ + uint16_t service_handle; /*!< Service attribute handle */ + esp_bt_uuid_t descr_uuid; /*!< Characteristic descriptor uuid */ + } add_char_descr; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_DESCR_EVT */ + + /** + * @brief ESP_GATTS_DELETE_EVT + */ + struct gatts_delete_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t service_handle; /*!< Service attribute handle */ + } del; /*!< Gatt server callback param of ESP_GATTS_DELETE_EVT */ + + /** + * @brief ESP_GATTS_START_EVT + */ + struct gatts_start_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t service_handle; /*!< Service attribute handle */ + } start; /*!< Gatt server callback param of ESP_GATTS_START_EVT */ + + /** + * @brief ESP_GATTS_STOP_EVT + */ + struct gatts_stop_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t service_handle; /*!< Service attribute handle */ + } stop; /*!< Gatt server callback param of ESP_GATTS_STOP_EVT */ + + /** + * @brief ESP_GATTS_CONNECT_EVT + */ + struct gatts_connect_evt_param { + uint16_t conn_id; /*!< Connection id */ + uint8_t link_role; /*!< Link role : master role = 0 ; slave role = 1*/ + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + esp_gatt_conn_params_t conn_params; /*!< current Connection parameters */ + esp_ble_addr_type_t ble_addr_type; /*!< Remote BLE device address type */ + uint16_t conn_handle; /*!< HCI connection handle */ + } connect; /*!< Gatt server callback param of ESP_GATTS_CONNECT_EVT */ + + /** + * @brief ESP_GATTS_DISCONNECT_EVT + */ + struct gatts_disconnect_evt_param { + uint16_t conn_id; /*!< Connection id */ + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + esp_gatt_conn_reason_t reason; /*!< Indicate the reason of disconnection */ + } disconnect; /*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */ + + /** + * @brief ESP_GATTS_OPEN_EVT + */ + struct gatts_open_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + } open; /*!< Gatt server callback param of ESP_GATTS_OPEN_EVT */ + + /** + * @brief ESP_GATTS_CANCEL_OPEN_EVT + */ + struct gatts_cancel_open_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + } cancel_open; /*!< Gatt server callback param of ESP_GATTS_CANCEL_OPEN_EVT */ + + /** + * @brief ESP_GATTS_CLOSE_EVT + */ + struct gatts_close_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t conn_id; /*!< Connection id */ + } close; /*!< Gatt server callback param of ESP_GATTS_CLOSE_EVT */ + + /** + * @brief ESP_GATTS_LISTEN_EVT + */ + /** + * @brief ESP_GATTS_CONGEST_EVT + */ + struct gatts_congest_evt_param { + uint16_t conn_id; /*!< Connection id */ + bool congested; /*!< Congested or not */ + } congest; /*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */ + + /** + * @brief ESP_GATTS_RESPONSE_EVT + */ + struct gatts_rsp_evt_param { + esp_gatt_status_t status; /*!< Operation status */ + uint16_t handle; /*!< Attribute handle which send response */ + } rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */ + + /** + * @brief ESP_GATTS_CREAT_ATTR_TAB_EVT + */ + struct gatts_add_attr_tab_evt_param{ + esp_gatt_status_t status; /*!< Operation status */ + esp_bt_uuid_t svc_uuid; /*!< Service uuid type */ + uint8_t svc_inst_id; /*!< Service id */ + uint16_t num_handle; /*!< The number of the attribute handle to be added to the gatts database */ + uint16_t *handles; /*!< The number to the handles */ + } add_attr_tab; /*!< Gatt server callback param of ESP_GATTS_CREAT_ATTR_TAB_EVT */ + + + /** + * @brief ESP_GATTS_SET_ATTR_VAL_EVT + */ + struct gatts_set_attr_val_evt_param{ + uint16_t srvc_handle; /*!< The service handle */ + uint16_t attr_handle; /*!< The attribute handle */ + esp_gatt_status_t status; /*!< Operation status*/ + } set_attr_val; /*!< Gatt server callback param of ESP_GATTS_SET_ATTR_VAL_EVT */ + + /** + * @brief ESP_GATTS_SEND_SERVICE_CHANGE_EVT + */ + struct gatts_send_service_change_evt_param{ + esp_gatt_status_t status; /*!< Operation status*/ + } service_change; /*!< Gatt server callback param of ESP_GATTS_SEND_SERVICE_CHANGE_EVT */ + +} esp_ble_gatts_cb_param_t; + +/** + * @brief GATT Server callback function type + * @param event : Event type + * @param gatts_if : GATT server access interface, normally + * different gatts_if correspond to different profile + * @param param : Point to callback parameter, currently is union type + */ +typedef void (* esp_gatts_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); + +/** + * @brief This function is called to register application callbacks + * with BTA GATTS module. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback); + +/** + * @brief This function is called to get the current application callbacks + * with BTA GATTS module. + * + * @return + * - esp_gatts_cb_t : current callback + * + */ +esp_gatts_cb_t esp_ble_gatts_get_callback(void); + +/** + * @brief This function is called to register application identifier + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_app_register(uint16_t app_id); + + + +/** + * @brief unregister with GATT Server. + * + * @param[in] gatts_if: GATT server access interface + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if); + + +/** + * @brief Create a service. When service creation is done, a callback + * event ESP_GATTS_CREATE_EVT is called to report status + * and service ID to the profile. The service ID obtained in + * the callback function needs to be used when adding included + * service and characteristics/descriptors into the service. + * + * @param[in] gatts_if: GATT server access interface + * @param[in] service_id: service ID. + * @param[in] num_handle: number of handle requested for this service. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if, + esp_gatt_srvc_id_t *service_id, uint16_t num_handle); + + +/** + * @brief Create a service attribute tab. + * @param[in] gatts_attr_db: the pointer to the service attr tab + * @param[in] gatts_if: GATT server access interface + * @param[in] max_nb_attr: the number of attribute to be added to the service database. + * @param[in] srvc_inst_id: the instance id of the service + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db, + esp_gatt_if_t gatts_if, + uint16_t max_nb_attr, + uint8_t srvc_inst_id); +/** + * @brief This function is called to add an included service. This function have to be called between + * 'esp_ble_gatts_create_service' and 'esp_ble_gatts_add_char'. After included + * service is included, a callback event ESP_GATTS_ADD_INCL_SRVC_EVT + * is reported the included service ID. + * + * @param[in] service_handle: service handle to which this included service is to + * be added. + * @param[in] included_service_handle: the service ID to be included. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle); + + + +/** + * @brief This function is called to add a characteristic into a service. + * + * @param[in] service_handle: service handle to which this included service is to + * be added. + * @param[in] char_uuid : Characteristic UUID. + * @param[in] perm : Characteristic value declaration attribute permission. + * @param[in] property : Characteristic Properties + * @param[in] char_val : Characteristic value + * @param[in] control : attribute response control byte + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid, + esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val, + esp_attr_control_t *control); + + +/** + * @brief This function is called to add characteristic descriptor. When + * it's done, a callback event ESP_GATTS_ADD_DESCR_EVT is called + * to report the status and an ID number for this descriptor. + * + * @param[in] service_handle: service handle to which this characteristic descriptor is to + * be added. + * @param[in] perm: descriptor access permission. + * @param[in] descr_uuid: descriptor UUID. + * @param[in] char_descr_val : Characteristic descriptor value + * @param[in] control : attribute response control byte + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle, + esp_bt_uuid_t *descr_uuid, + esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val, + esp_attr_control_t *control); + + + +/** + * @brief This function is called to delete a service. When this is done, + * a callback event ESP_GATTS_DELETE_EVT is report with the status. + * + * @param[in] service_handle: service_handle to be deleted. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle); + + + +/** + * @brief This function is called to start a service. + * + * @param[in] service_handle: the service handle to be started. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_start_service(uint16_t service_handle); + + + +/** + * @brief This function is called to stop a service. + * + * @param[in] service_handle - service to be topped. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle); + + + +/** + * @brief Send indicate or notify to GATT client. + * Set param need_confirm as false will send notification, otherwise indication. + * Note: the size of indicate or notify data need less than MTU size,see "esp_ble_gattc_send_mtu_req". + * + * @param[in] gatts_if: GATT server access interface + * @param[in] conn_id - connection id to indicate. + * @param[in] attr_handle - attribute handle to indicate. + * @param[in] value_len - indicate value length. + * @param[in] value: value to indicate. + * @param[in] need_confirm - Whether a confirmation is required. + * false sends a GATT notification, true sends a GATT indication. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, uint16_t attr_handle, + uint16_t value_len, uint8_t *value, bool need_confirm); + + +/** + * @brief This function is called to send a response to a request. + * + * @param[in] gatts_if: GATT server access interface + * @param[in] conn_id - connection identifier. + * @param[in] trans_id - transfer id + * @param[in] status - response status + * @param[in] rsp - response data. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id, + esp_gatt_status_t status, esp_gatt_rsp_t *rsp); + + +/** + * @brief This function is called to set the attribute value by the application + * + * @param[in] attr_handle: the attribute handle which to be set + * @param[in] length: the value length + * @param[in] value: the pointer to the attribute value + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value); + +/** + * @brief Retrieve attribute value + * + * @param[in] attr_handle: Attribute handle. + * @param[out] length: pointer to the attribute value length + * @param[out] value: Pointer to attribute value payload, the value cannot be modified by user + * + * @return + * - ESP_GATT_OK : success + * - other : failed + * + */ +esp_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value); + + +/** + * @brief Open a direct open connection or add a background auto connection + * + * @param[in] gatts_if: GATT server access interface + * @param[in] remote_bda: remote device bluetooth device address. + * @param[in] is_direct: direct connection or background auto connection + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct); + +/** + * @brief Close a connection a remote device. + * + * @param[in] gatts_if: GATT server access interface + * @param[in] conn_id: connection ID to be closed. + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id); + +/** + * @brief Send service change indication + * + * @param[in] gatts_if: GATT server access interface + * @param[in] remote_bda: remote device bluetooth device address. + * If remote_bda is NULL then it will send service change + * indication to all the connected devices and if not then + * to a specific device + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda); + +/** + * @brief Print local database (GATT service table) + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_show_local_database(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_GATTS_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h new file mode 100644 index 00000000..84086118 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h @@ -0,0 +1,716 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_HF_AG_API_H__ +#define __ESP_HF_AG_API_H__ + +#include "esp_err.h" +#include "esp_bt_defs.h" +#include "esp_hf_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* features masks of HF AG */ +#define ESP_HF_PEER_FEAT_3WAY 0x01 /* Three-way calling */ +#define ESP_HF_PEER_FEAT_ECNR 0x02 /* Echo cancellation and/or noise reduction */ +#define ESP_HF_PEER_FEAT_VREC 0x04 /* Voice recognition */ +#define ESP_HF_PEER_FEAT_INBAND 0x08 /* In-band ring tone */ +#define ESP_HF_PEER_FEAT_VTAG 0x10 /* Attach a phone number to a voice tag */ +#define ESP_HF_PEER_FEAT_REJECT 0x20 /* Ability to reject incoming call */ +#define ESP_HF_PEER_FEAT_ECS 0x40 /* Enhanced Call Status */ +#define ESP_HF_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */ +#define ESP_HF_PEER_FEAT_EXTERR 0x100 /* Extended error codes */ +#define ESP_HF_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */ +/* HFP 1.7+ */ +#define ESP_HF_PEER_FEAT_HF_IND 0x400 /* HF Indicators */ +#define ESP_HF_PEER_FEAT_ESCO_S4 0x800 /* eSCO S4 Setting Supported */ + + +/* CHLD feature masks of HF AG */ +#define ESP_HF_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */ +#define ESP_HF_CHLD_FEAT_REL_ACC 0x02 /* 1 Release active calls and accept other waiting or held call */ +#define ESP_HF_CHLD_FEAT_REL_X 0x04 /* 1x Release specified active call only */ +#define ESP_HF_CHLD_FEAT_HOLD_ACC 0x08 /* 2 Active calls on hold and accept other waiting or held call */ +#define ESP_HF_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold) */ +#define ESP_HF_CHLD_FEAT_MERGE 0x20 /* 3 Add held call to multiparty */ +#define ESP_HF_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnect from multiparty) */ + +/// HF callback events +typedef enum +{ + ESP_HF_CONNECTION_STATE_EVT = 0, /*!< Connection state changed event */ + ESP_HF_AUDIO_STATE_EVT, /*!< Audio connection state change event */ + ESP_HF_BVRA_RESPONSE_EVT, /*!< Voice recognition state change event */ + ESP_HF_VOLUME_CONTROL_EVT, /*!< Audio volume control command from HF Client, provided by +VGM or +VGS message */ + + ESP_HF_UNAT_RESPONSE_EVT, /*!< Unknown AT cmd Response*/ + ESP_HF_IND_UPDATE_EVT, /*!< Indicator Update Event*/ + ESP_HF_CIND_RESPONSE_EVT, /*!< Call And Device Indicator Response*/ + ESP_HF_COPS_RESPONSE_EVT, /*!< Current operator information */ + ESP_HF_CLCC_RESPONSE_EVT, /*!< List of current calls notification */ + ESP_HF_CNUM_RESPONSE_EVT, /*!< Subscriber information response from HF Client */ + ESP_HF_VTS_RESPONSE_EVT, /*!< Enable or not DTMF */ + ESP_HF_NREC_RESPONSE_EVT, /*!< Enable or not NREC */ + + ESP_HF_ATA_RESPONSE_EVT, /*!< Answer an Incoming Call */ + ESP_HF_CHUP_RESPONSE_EVT, /*!< Reject an Incoming Call */ + ESP_HF_DIAL_EVT, /*!< Origin an outgoing call with specific number or the dial the last number */ + ESP_HF_WBS_RESPONSE_EVT, /*!< Codec Status */ + ESP_HF_BCS_RESPONSE_EVT, /*!< Final Codec Choice */ + ESP_HF_PKT_STAT_NUMS_GET_EVT, /*!< Request number of packet different status */ +} esp_hf_cb_event_t; + +/// Dial type of ESP_HF_DIAL_EVT +typedef enum +{ + ESP_HF_DIAL_NUM = 0, /*!< Dial with a phone number */ + ESP_HF_DIAL_VOIP, /*!< Dial with VoIP */ + ESP_HF_DIAL_MEM, /*!< Dial with a memory position */ +} esp_hf_dial_type_t; + +/// HFP AG callback parameters +typedef union +{ + /** + * @brief ESP_HF_CONNECTION_STATE_EVT + */ + struct hf_conn_stat_param { + esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + esp_hf_connection_state_t state; /*!< Connection state */ + uint32_t peer_feat; /*!< HF supported features */ + uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */ + } conn_stat; /*!< AG callback param of ESP_HF_CONNECTION_STATE_EVT */ + + /** + * @brief ESP_HF_AUDIO_STATE_EVT + */ + struct hf_audio_stat_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + esp_hf_audio_state_t state; /*!< Audio connection state */ + uint16_t sync_conn_handle; /*!< (e)SCO connection handle */ + } audio_stat; /*!< AG callback param of ESP_HF_AUDIO_STATE_EVT */ + + /** + * @brief ESP_HF_BVRA_RESPONSE_EVT + */ + struct hf_vra_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + esp_hf_vr_state_t value; /*!< Voice recognition state */ + } vra_rep; /*!< AG callback param of ESP_HF_BVRA_RESPONSE_EVT */ + + /** + * @brief ESP_HF_VOLUME_CONTROL_EVT + */ + struct hf_volume_control_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + esp_hf_volume_type_t type; /*!< Volume control target, speaker or microphone */ + int volume; /*!< Gain, ranges from 0 to 15 */ + } volume_control; /*!< AG callback param of ESP_HF_VOLUME_CONTROL_EVT */ + + /** + * @brief ESP_HF_UNAT_RESPONSE_EVT + */ + struct hf_unat_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + char *unat; /*!< Unknown AT command string */ + } unat_rep; /*!< AG callback param of ESP_HF_UNAT_RESPONSE_EVT */ + + /** + * @brief ESP_HF_DIAL_EVT + */ + struct hf_out_call_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + esp_hf_dial_type_t type; /*!< dial type */ + char *num_or_loc; /*!< location in phone memory */ + } out_call; /*!< AG callback param of ESP_HF_DIAL_EVT */ + + /** + * @brief ESP_HF_IND_UPDATE_EVT + */ + struct hf_ind_upd_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } ind_upd; /*!< AG callback param of ESP_HF_IND_UPDATE_EVT */ + + /** + * @brief ESP_HF_CIND_RESPONSE_EVT + */ + struct hf_cind_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } cind_rep; /*!< AG callback param of ESP_HF_CIND_RESPONSE_EVT */ + + /** + * @brief ESP_HF_COPS_RESPONSE_EVT + */ + struct hf_cops_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } cops_rep; /*!< AG callback param of ESP_HF_COPS_RESPONSE_EVT */ + + /** + * @brief ESP_HF_CLCC_RESPONSE_EVT + */ + struct hf_clcc_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } clcc_rep; /*!< AG callback param of ESP_HF_CLCC_RESPONSE_EVT */ + + /** + * @brief ESP_HF_CNUM_RESPONSE_EVT + */ + struct hf_cnum_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } cnum_rep; /*!< AG callback param of ESP_HF_CNUM_RESPONSE_EVT */ + + /** + * @brief ESP_HF_VTS_RESPONSE_EVT + */ + struct hf_vts_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + char *code; /*!< MTF code from HF Client */ + } vts_rep; /*!< AG callback param of ESP_HF_VTS_RESPONSE_EVT */ + + /** + * @brief ESP_HF_NREC_RESPONSE_EVT + */ + struct hf_nrec_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + esp_hf_nrec_t state; /*!< NREC enabled or disabled */ + } nrec; /*!< AG callback param of ESP_HF_NREC_RESPONSE_EVT */ + + /** + * @brief ESP_HF_ATA_RESPONSE_EVT + */ + struct hf_ata_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } ata_rep; /*!< AG callback param of ESP_HF_ATA_RESPONSE_EVT */ + + /** + * @brief ESP_HF_CHUP_RESPONSE_EVT + */ + struct hf_chup_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } chup_rep; /*!< AG callback param of ESP_HF_CHUP_RESPONSE_EVT */ + + /** + * @brief ESP_HF_WBS_RESPONSE_EVT + */ + struct hf_wbs_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + esp_hf_wbs_config_t codec; /*!< codec mode CVSD or mSBC */ + } wbs_rep; /*!< AG callback param of ESP_HF_WBS_RESPONSE_EVT */ + + /** + * @brief ESP_HF_BCS_RESPONSE_EVT + */ + struct hf_bcs_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + esp_hf_wbs_config_t mode; /*!< codec mode CVSD or mSBC */ + } bcs_rep; /*!< AG callback param of ESP_HF_BCS_RESPONSE_EVT */ + + /** + * @brief ESP_HF_PKT_STAT_NUMS_GET_EVT + */ + struct ag_pkt_status_nums { + uint32_t rx_total; /*!< the total number of packets received */ + uint32_t rx_correct; /*!< the total number of packets data correctly received */ + uint32_t rx_err; /*!< the total number of packets data with possible invalid */ + uint32_t rx_none; /*!< the total number of packets data no received */ + uint32_t rx_lost; /*!< the total number of packets data partially lost */ + uint32_t tx_total; /*!< the total number of packets send */ + uint32_t tx_discarded; /*!< the total number of packets send lost */ + } pkt_nums; /*!< AG callback param of ESP_HF_PKT_STAT_NUMS_GET_EVT */ + +} esp_hf_cb_param_t; /*!< HFP AG callback param compound*/ + +/** + * @brief AG incoming data callback function, the callback is useful in case of + * Voice Over HCI. + * + * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the + * buffer is allocated inside bluetooth protocol stack and will be released after + * invoke of the callback is finished. + * + * @param[in] len : size(in bytes) in buf + */ +typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len); + +/** + * @brief AG outgoing data callback function, the callback is useful in case of + * Voice Over HCI. Once audio connection is set up and the application layer has + * prepared data to send, the lower layer will call this function to read data + * and then send. This callback is supposed to be implemented as non-blocking, + * and if data is not enough, return value 0 is supposed. + * + * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the + * buffer is allocated inside bluetooth protocol stack and will be released after + * invoke of the callback is finished. + * + * @param[in] len : size(in bytes) in buf + * + * @return length of data successfully read + */ +typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len); + +/** + * @brief HF AG callback function type + * + * @param event : Event type + * + * @param param : Pointer to callback parameter + */ +typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param); + +/************************************************************************************ +** ESP HF API +************************************************************************************/ +/** + * @brief Register application callback function to HFP AG module. + * This function should be called only after esp_bluedroid_enable() completes successfully. + * + * @param[in] callback: HFP AG event callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: if callback is a NULL function pointer + * + */ +esp_err_t esp_hf_ag_register_callback(esp_hf_cb_t callback); + +/** + * + * @brief Initialize the bluetooth HF AG module. + * This function should be called after esp_bluedroid_enable() completes successfully. + * + * @return + * - ESP_OK: if the initialization request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_init(void); + +/** + * + * @brief De-initialize for HF AG module. + * This function should be called only after esp_bluedroid_enable() completes successfully. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_deinit(void); + +/** + * + * @brief To establish a Service Level Connection to remote bluetooth HFP client device. + * This function must be called after esp_hf_ag_init() and before esp_hf_ag_deinit(). + * + * @param[in] remote_bda: remote bluetooth HFP client device address + * + * @return + * - ESP_OK: connect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_slc_connect(esp_bd_addr_t remote_bda); + +/** + * + * @brief Disconnect from the remote HFP client. This function must be called + * after esp_hf_ag_init() and before esp_hf_ag_deinit(). + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: disconnect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_slc_disconnect(esp_bd_addr_t remote_bda); + +/** + * + * @brief Create audio connection with remote HFP client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: audio connect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_audio_connect(esp_bd_addr_t remote_bda); + +/** + * + * @brief Release the established audio connection with remote HFP client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: audio disconnect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_audio_disconnect(esp_bd_addr_t remote_bda); + +/** + * + * @brief Response of Volume Recognition Command(AT+VRA) from HFP client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_bda: the device address of voice recognition initiator + * + * @param[in] value: 0 - voice recognition disabled, 1- voice recognition enabled + * + * @return + * - ESP_OK: response of volume recognition is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_vra_control(esp_bd_addr_t remote_bda, esp_hf_vr_state_t value); + +/** + * + * @brief Volume synchronization with HFP client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_bda: remote bluetooth device address + * + * @param[in] type: volume control target, speaker or microphone + * + * @param[in] volume: gain of the speaker of microphone, ranges 0 to 15 + * + * @return + * - ESP_OK: volume synchronization control is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if arguments are invalid + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_volume_control(esp_bd_addr_t remote_bda, esp_hf_volume_control_target_t type, int volume); + +/** + * + * @brief Handle Unknown AT command from HFP Client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * + * @param[in] unat: User AT command response to HF Client. + * It will response "ERROR" by default if unat is NULL. + * @return + * - ESP_OK: response of unknown AT command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_unknown_at_send(esp_bd_addr_t remote_addr, char *unat); + +/** + * + * @brief Unsolicited send extend AT error code to HFP Client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_bda: remote bluetooth device address + * @param[in] response_code: AT command response code + * @param[in] error_code: CME error code + * @return + * - ESP_OK: extend error code is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_cmee_send(esp_bd_addr_t remote_bda, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code); + +/** + * + * @brief Unsolicited send device status notification to HFP Client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] call_state: call state + * @param[in] call_setup_state: call setup state + * @param[in] ntk_state: network service state + * @param[in] signal: signal strength from 0 to 5 + * @return + * - ESP_OK: device status notification is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if arguments are invalid + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_devices_status_indchange(esp_bd_addr_t remote_addr, esp_hf_call_status_t call_state, + esp_hf_call_setup_status_t call_setup_state, + esp_hf_network_state_t ntk_state, int signal) __attribute__(( + deprecated("Please use esp_hf_ag_ciev_report") + )); + +/** + * + * @brief Send indicator report "+CIEV: <ind> <value>" to HFP Client. "CIEV" means “indicator events reporting", + * and all indicator types can be sent one type at a time. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] ind_type: indicator type + * @param[in] value: indicator value + * @return + * - ESP_OK: indicator report is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_ciev_report(esp_bd_addr_t remote_addr, esp_hf_ciev_report_type_t ind_type, int value); + +/** + * + * @brief Response to device individual indicators to HFP Client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] call_state: call state + * @param[in] call_setup_state: call setup state + * @param[in] ntk_state: network service state + * @param[in] signal: signal strength from 0 to 5 + * @param[in] roam: roam state + * @param[in] batt_lev: battery level from 0 to 5 + * @param[in] call_held_status: call held status + * @return + * - ESP_OK: response to device individual indicators is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if the arguments are invalid + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_cind_response(esp_bd_addr_t remote_addr, + esp_hf_call_status_t call_state, + esp_hf_call_setup_status_t call_setup_state, + esp_hf_network_state_t ntk_state, int signal, esp_hf_roaming_status_t roam, int batt_lev, + esp_hf_call_held_status_t call_held_status); + +/** + * + * @brief Reponse for AT+COPS command from HF Client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] name: current operator name + * @return + * - ESP_OK: reponse for AT+COPS command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_cops_response(esp_bd_addr_t remote_addr, char *name); + +/** + * + * @brief Response to AT+CLCC command from HFP Client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] index: the index of current call, starting with 1, finishing response with 0 (send OK) + * @param[in] dir: call direction (incoming/outgoing) + * @param[in] current_call_state: current call state + * @param[in] mode: current call mode (voice/data/fax) + * @param[in] mpty: single or multi type + * @param[in] number: current call number + * @param[in] type: international type or unknow + * @return + * - ESP_OK: response to AT+CLCC command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_current_call_direction_t dir, + esp_hf_current_call_status_t current_call_state, esp_hf_current_call_mode_t mode, + esp_hf_current_call_mpty_type_t mpty, char *number, esp_hf_call_addr_type_t type); + +/** + * + * @brief Response for AT+CNUM command from HF Client. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] number: registration number + * @param[in] number_type: value of number type from + * 128-143: national or international, may contain prefix and/or escape digits + * 144-159: international, includes country code prefix, add "+" if needed + * 160-175: national, but no prefix nor escape digits + * @param[in] service_type: service type (unknown/voice/fax) + * @return + * - ESP_OK: response for AT+CNUM command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, int number_type, esp_hf_subscriber_service_type_t service_type); + +/** + * + * @brief Inform HF Client that AG Provided in-band ring tone or not. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] state: in-band ring tone state + * @return + * - ESP_OK: information of in-band ring tone is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if arguments are invalid + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t state); + +/** + * + * @brief Answer Incoming Call from AG. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] num_active: the number of active call + * @param[in] num_held: the number of held call + * @param[in] call_state: call state + * @param[in] call_setup_state: call setup state + * @param[in] number: number of the incoming call + * @param[in] call_addr_type: call address type + * @return + * - ESP_OK: answer incoming call is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_answer_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type); + +/** + * + * @brief Reject Incoming Call from AG. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] num_active: the number of active call + * @param[in] num_held: the number of held call + * @param[in] call_state: call state + * @param[in] call_setup_state: call setup state + * @param[in] number: number of the incoming call + * @param[in] call_addr_type: call address type + * @return + * - ESP_OK: reject incoming call is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_reject_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type); + +/** + * + * @brief Initiate a call from AG. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * If the AG is driven by the HF to call esp_hf_ag_out_call, it needs to response an OK or ERROR + * to HF. But if the AG is actively calling esp_hf_ag_out_call, it does not need to take a response + * to HF. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] num_active: the number of active call + * @param[in] num_held: the number of held call + * @param[in] call_state: call state + * @param[in] call_setup_state: call setup state + * @param[in] number: number of the outgoing call + * @param[in] call_addr_type: call address type + * @return + * - ESP_OK: a call initiation is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_out_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type); + +/** + * + * @brief End an ongoing call. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] num_active: the number of active call + * @param[in] num_held: the number of held call + * @param[in] call_state: call state + * @param[in] call_setup_state: call setup state + * @param[in] number: number of the call + * @param[in] call_addr_type: call address type + * @return + * - ESP_OK: end an ongoing call is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_end_call(esp_bd_addr_t remote_addr, int num_active, int num_held, + esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, + char *number, esp_hf_call_addr_type_t call_addr_type); + +/** + * @brief Register AG data output function. + * The callback is only used in the case that Voice Over HCI is enabled. + * + * @param[in] recv: HFP client incoming data callback function + * @param[in] send: HFP client outgoing data callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: if callback is a NULL function pointer + * + */ +esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send); + +/** + * + * @brief Get the number of packets received and sent + * + * This function is only used in the case that Voice Over HCI is enabled and the audio state is connected. + * When the operation is completed, the callback function will be called with ESP_HF_PKT_STAT_NUMS_GET_EVT. + * + * @param[in] sync_conn_handle: the (e)SCO connection handle + * + * @return + * - ESP_OK: if the request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle); + +/** + * @brief Trigger the lower-layer to fetch and send audio data. + * + * This function is only used in the case that Voice Over HCI is enabled. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * After this function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data + * + */ +void esp_hf_ag_outgoing_data_ready(void); + +#ifdef __cplusplus +} +#endif + +#endif //__ESP_HF_AG_API_H__ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h new file mode 100644 index 00000000..9353fc03 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h @@ -0,0 +1,736 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_HF_CLIENT_API_H__ +#define __ESP_HF_CLIENT_API_H__ + +#include "esp_err.h" +#include "esp_bt_defs.h" +#include "esp_hf_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_BT_HF_CLIENT_NUMBER_LEN (32) +#define ESP_BT_HF_CLIENT_OPERATOR_NAME_LEN (16) +#define ESP_BT_HF_AT_SEND_XAPL_LEN (14) + +/// Bluetooth HFP RFCOMM connection and service level connection status +typedef enum { + ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTED = 0, /*!< RFCOMM data link channel released */ + ESP_HF_CLIENT_CONNECTION_STATE_CONNECTING, /*!< connecting remote device on the RFCOMM data link*/ + ESP_HF_CLIENT_CONNECTION_STATE_CONNECTED, /*!< RFCOMM connection established */ + ESP_HF_CLIENT_CONNECTION_STATE_SLC_CONNECTED, /*!< service level connection established */ + ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTING, /*!< disconnecting with remote device on the RFCOMM dat link*/ +} esp_hf_client_connection_state_t; + +/// Bluetooth HFP audio connection status +typedef enum { + ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED = 0, /*!< audio connection released */ + ESP_HF_CLIENT_AUDIO_STATE_CONNECTING, /*!< audio connection has been initiated */ + ESP_HF_CLIENT_AUDIO_STATE_CONNECTED, /*!< audio connection is established */ + ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */ +} esp_hf_client_audio_state_t; + +/// in-band ring tone state +typedef enum { + ESP_HF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED = 0, + ESP_HF_CLIENT_IN_BAND_RINGTONE_PROVIDED, +} esp_hf_client_in_band_ring_state_t; + +/* features masks of AG */ +#define ESP_HF_CLIENT_PEER_FEAT_3WAY 0x01 /* Three-way calling */ +#define ESP_HF_CLIENT_PEER_FEAT_ECNR 0x02 /* Echo cancellation and/or noise reduction */ +#define ESP_HF_CLIENT_PEER_FEAT_VREC 0x04 /* Voice recognition */ +#define ESP_HF_CLIENT_PEER_FEAT_INBAND 0x08 /* In-band ring tone */ +#define ESP_HF_CLIENT_PEER_FEAT_VTAG 0x10 /* Attach a phone number to a voice tag */ +#define ESP_HF_CLIENT_PEER_FEAT_REJECT 0x20 /* Ability to reject incoming call */ +#define ESP_HF_CLIENT_PEER_FEAT_ECS 0x40 /* Enhanced Call Status */ +#define ESP_HF_CLIENT_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */ +#define ESP_HF_CLIENT_PEER_FEAT_EXTERR 0x100 /* Extended error codes */ +#define ESP_HF_CLIENT_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */ +/* HFP 1.7+ */ +#define ESP_HF_CLIENT_PEER_FEAT_HF_IND 0x400 /* HF Indicators */ +#define ESP_HF_CLIENT_PEER_FEAT_ESCO_S4 0x800 /* eSCO S4 Setting Supported */ + +/* CHLD feature masks of AG */ +#define ESP_HF_CLIENT_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */ +#define ESP_HF_CLIENT_CHLD_FEAT_REL_ACC 0x02 /* 1 Release active calls and accept other waiting or held call */ +#define ESP_HF_CLIENT_CHLD_FEAT_REL_X 0x04 /* 1x Release specified active call only */ +#define ESP_HF_CLIENT_CHLD_FEAT_HOLD_ACC 0x08 /* 2 Active calls on hold and accept other waiting or held call */ +#define ESP_HF_CLIENT_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold) */ +#define ESP_HF_CLIENT_CHLD_FEAT_MERGE 0x20 /* 3 Add held call to multiparty */ +#define ESP_HF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnect from multiparty) */ + +/* XAPL feature masks*/ +#define ESP_HF_CLIENT_XAPL_FEAT_RESERVED 0x01 /* reserved */ +#define ESP_HF_CLIENT_XAPL_FEAT_BATTERY_REPORT 0x02 /* The accessory supports battery reporting (reserved only for battery operated accessories) */ +#define ESP_HF_CLIENT_XAPL_FEAT_DOCKED 0x04 /* The accessory is docked or powered (reserved only for battery operated accessories). */ +#define ESP_HF_CLIENT_XAPL_FEAT_SIRI_STATUS_REPORT 0x08 /* The accessory supports Siri status reporting */ +#define ESP_HF_CLIENT_XAPL_NR_STATUS_REPORT 0x10 /* the accessory supports noise reduction (NR) status reporting */ + +/// HF CLIENT callback events +typedef enum { + ESP_HF_CLIENT_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */ + ESP_HF_CLIENT_AUDIO_STATE_EVT, /*!< audio connection state change event */ + ESP_HF_CLIENT_BVRA_EVT, /*!< voice recognition state change event */ + ESP_HF_CLIENT_CIND_CALL_EVT, /*!< call indication */ + ESP_HF_CLIENT_CIND_CALL_SETUP_EVT, /*!< call setup indication */ + ESP_HF_CLIENT_CIND_CALL_HELD_EVT, /*!< call held indication */ + ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT, /*!< network service availability indication */ + ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT, /*!< signal strength indication */ + ESP_HF_CLIENT_CIND_ROAMING_STATUS_EVT, /*!< roaming status indication */ + ESP_HF_CLIENT_CIND_BATTERY_LEVEL_EVT, /*!< battery level indication */ + ESP_HF_CLIENT_COPS_CURRENT_OPERATOR_EVT, /*!< current operator information */ + ESP_HF_CLIENT_BTRH_EVT, /*!< call response and hold event */ + ESP_HF_CLIENT_CLIP_EVT, /*!< Calling Line Identification notification */ + ESP_HF_CLIENT_CCWA_EVT, /*!< call waiting notification */ + ESP_HF_CLIENT_CLCC_EVT, /*!< list of current calls notification */ + ESP_HF_CLIENT_VOLUME_CONTROL_EVT, /*!< audio volume control command from AG, provided by +VGM or +VGS message */ + ESP_HF_CLIENT_AT_RESPONSE_EVT, /*!< AT command response event */ + ESP_HF_CLIENT_CNUM_EVT, /*!< subscriber information response from AG */ + ESP_HF_CLIENT_BSIR_EVT, /*!< setting of in-band ring tone */ + ESP_HF_CLIENT_BINP_EVT, /*!< requested number of last voice tag from AG */ + ESP_HF_CLIENT_RING_IND_EVT, /*!< ring indication event */ + ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT, /*!< requested number of packet different status */ +} esp_hf_client_cb_event_t; + +/// HFP client callback parameters +typedef union { + /** + * @brief ESP_HF_CLIENT_CONNECTION_STATE_EVT + */ + struct hf_client_conn_stat_param { + esp_hf_client_connection_state_t state; /*!< HF connection state */ + uint32_t peer_feat; /*!< AG supported features */ + uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + } conn_stat; /*!< HF callback param of ESP_HF_CLIENT_CONNECTION_STATE_EVT */ + + /** + * @brief ESP_HF_CLIENT_AUDIO_STATE_EVT + */ + struct hf_client_audio_stat_param { + esp_hf_client_audio_state_t state; /*!< audio connection state */ + esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + uint16_t sync_conn_handle; /*!< (e)SCO connection handle */ + } audio_stat; /*!< HF callback param of ESP_HF_CLIENT_AUDIO_STATE_EVT */ + + /** + * @brief ESP_HF_CLIENT_BVRA_EVT + */ + struct hf_client_bvra_param { + esp_hf_vr_state_t value; /*!< voice recognition state */ + } bvra; /*!< HF callback param of ESP_HF_CLIENT_BVRA_EVT */ + + /** + * @brief ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT + */ + struct hf_client_service_availability_param { + esp_hf_network_state_t status; /*!< service availability status */ + } service_availability; /*!< HF callback param of ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT */ + + /** + * @brief ESP_HF_CLIENT_CIND_ROAMING_STATUS_EVT + */ + struct hf_client_network_roaming_param { + esp_hf_roaming_status_t status; /*!< roaming status */ + } roaming; /*!< HF callback param of ESP_HF_CLIENT_CIND_ROAMING_STATUS_EVT */ + + /** + * @brief ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT + */ + struct hf_client_signal_strength_ind_param { + int value; /*!< signal strength value, ranges from 0 to 5 */ + } signal_strength; /*!< HF callback param of ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT */ + + /** + * @brief ESP_HF_CLIENT_CIND_BATTERY_LEVEL_EVT + */ + struct hf_client_battery_level_ind_param { + int value; /*!< battery charge value, ranges from 0 to 5 */ + } battery_level; /*!< HF callback param of ESP_HF_CLIENT_CIND_BATTERY_LEVEL_EVT */ + + /** + * @brief ESP_HF_CLIENT_COPS_CURRENT_OPERATOR_EVT + */ + struct hf_client_current_operator_param { + const char *name; /*!< name of the network operator */ + } cops; /*!< HF callback param of ESP_HF_CLIENT_COPS_CURRENT_OPERATOR_EVT */ + + /** + * @brief ESP_HF_CLIENT_CIND_CALL_EVT + */ + struct hf_client_call_ind_param { + esp_hf_call_status_t status; /*!< call status indicator */ + } call; /*!< HF callback param of ESP_HF_CLIENT_CIND_CALL_EVT */ + + /** + * @brief ESP_HF_CLIENT_CIND_CALL_SETUP_EVT + */ + struct hf_client_call_setup_ind_param { + esp_hf_call_setup_status_t status; /*!< call setup status indicator */ + } call_setup; /*!< HF callback param of ESP_HF_CLIENT_BVRA_EVT */ + + /** + * @brief ESP_HF_CLIENT_CIND_CALL_HELD_EVT + */ + struct hf_client_call_held_ind_param { + esp_hf_call_held_status_t status; /*!< bluetooth proprietary call hold status indicator */ + } call_held; /*!< HF callback param of ESP_HF_CLIENT_CIND_CALL_HELD_EVT */ + + /** + * @brief ESP_HF_CLIENT_BTRH_EVT + */ + struct hf_client_btrh_param { + esp_hf_btrh_status_t status; /*!< call hold and response status result code */ + } btrh; /*!< HF callback param of ESP_HF_CLIENT_BRTH_EVT */ + + /** + * @brief ESP_HF_CLIENT_CLIP_EVT + */ + struct hf_client_clip_param { + const char *number; /*!< phone number string of call */ + } clip; /*!< HF callback param of ESP_HF_CLIENT_CLIP_EVT */ + + /** + * @brief ESP_HF_CLIENT_CCWA_EVT + */ + struct hf_client_ccwa_param { + const char *number; /*!< phone number string of waiting call */ + } ccwa; /*!< HF callback param of ESP_HF_CLIENT_BVRA_EVT */ + + /** + * @brief ESP_HF_CLIENT_CLCC_EVT + */ + struct hf_client_clcc_param { + int idx; /*!< numbering(starting with 1) of the call */ + esp_hf_current_call_direction_t dir; /*!< direction of the call */ + esp_hf_current_call_status_t status; /*!< status of the call */ + esp_hf_current_call_mpty_type_t mpty; /*!< multi-party flag */ + char *number; /*!< phone number(optional) */ + } clcc; /*!< HF callback param of ESP_HF_CLIENT_CLCC_EVT */ + + /** + * @brief ESP_HF_CLIENT_VOLUME_CONTROL_EVT + */ + struct hf_client_volume_control_param { + esp_hf_volume_control_target_t type; /*!< volume control target, speaker or microphone */ + int volume; /*!< gain, ranges from 0 to 15 */ + } volume_control; /*!< HF callback param of ESP_HF_CLIENT_VOLUME_CONTROL_EVT */ + + /** + * @brief ESP_HF_CLIENT_AT_RESPONSE_EVT + */ + struct hf_client_at_response_param { + esp_hf_at_response_code_t code; /*!< AT response code */ + esp_hf_cme_err_t cme; /*!< Extended Audio Gateway Error Result Code */ + } at_response; /*!< HF callback param of ESP_HF_CLIENT_AT_RESPONSE_EVT */ + + /** + * @brief ESP_HF_CLIENT_CNUM_EVT + */ + struct hf_client_cnum_param { + const char *number; /*!< phone number string */ + esp_hf_subscriber_service_type_t type; /*!< service type that the phone number relates to */ + } cnum; /*!< HF callback param of ESP_HF_CLIENT_CNUM_EVT */ + + /** + * @brief ESP_HF_CLIENT_BSIR_EVT + */ + struct hf_client_bsirparam { + esp_hf_client_in_band_ring_state_t state; /*!< setting state of in-band ring tone */ + } bsir; /*!< HF callback param of ESP_HF_CLIENT_BSIR_EVT */ + + /** + * @brief ESP_HF_CLIENT_BINP_EVT + */ + struct hf_client_binp_param { + const char *number; /*!< phone number corresponding to the last voice tag in the HF */ + } binp; /*!< HF callback param of ESP_HF_CLIENT_BINP_EVT */ + + /** + * @brief ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT + */ + struct hf_client_pkt_status_nums { + uint32_t rx_total; /*!< the total number of packets received */ + uint32_t rx_correct; /*!< the total number of packets data correctly received */ + uint32_t rx_err; /*!< the total number of packets data with possible invalid */ + uint32_t rx_none; /*!< the total number of packets data no received */ + uint32_t rx_lost; /*!< the total number of packets data partially lost */ + uint32_t tx_total; /*!< the total number of packets send */ + uint32_t tx_discarded; /*!< the total number of packets send lost */ + } pkt_nums; /*!< HF callback param of ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT */ + +} esp_hf_client_cb_param_t; /*!< HFP client callback parameters */ + +/** + * @brief HFP client incoming data callback function, the callback is useful in case of + * Voice Over HCI. + * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the + * buffer is allocated inside bluetooth protocol stack and will be released after + * invoke of the callback is finished. + * @param[in] len : size(in bytes) in buf + */ +typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t len); + +/** + * @brief HFP client outgoing data callback function, the callback is useful in case of + * Voice Over HCI. Once audio connection is set up and the application layer has + * prepared data to send, the lower layer will call this function to read data + * and then send. This callback is supposed to be implemented as non-blocking, + * and if data is not enough, return value 0 is supposed. + * + * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the + * buffer is allocated inside bluetooth protocol stack and will be released after + * invoke of the callback is finished. + * + * @param[in] len : size(in bytes) in buf + * + * @return length of data successfully read + * + */ +typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len); + +/** + * @brief HFP client callback function type + * + * @param event : Event type + * + * @param param : Pointer to callback parameter + */ +typedef void (* esp_hf_client_cb_t)(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_t *param); + +/** + * @brief Register application callback function to HFP client module. + * This function should be called only after esp_bluedroid_enable() completes successfully. + * + * @param[in] callback: HFP client event callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: if callback is a NULL function pointer + * + */ +esp_err_t esp_hf_client_register_callback(esp_hf_client_cb_t callback); + +/** + * + * @brief Initialize the bluetooth HFP client module. + * This function should be called after esp_bluedroid_enable() completes successfully. + * + * @return + * - ESP_OK: if the initialization request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_init(void); + +/** + * + * @brief De-initialize for HFP client module. + * This function should be called only after esp_bluedroid_enable() completes successfully. + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_deinit(void); + +/** + * + * @brief Establish a Service Level Connection to remote bluetooth HFP audio gateway(AG) device. + * This function must be called after esp_hf_client_init() and before esp_hf_client_deinit(). + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: connect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_connect(esp_bd_addr_t remote_bda); + +/** + * + * @brief Disconnect from the remote HFP audio gateway. + * This function must be called after esp_hf_client_init() and before esp_hf_client_deinit(). + * + * @param[in] remote_bda: remote bluetooth device address + * + * @return + * - ESP_OK: disconnect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_disconnect(esp_bd_addr_t remote_bda); + +/** + * + * @brief Create audio connection with remote HFP AG. + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] remote_bda: remote bluetooth device address + * @return + * - ESP_OK: connect audio request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_connect_audio(esp_bd_addr_t remote_bda); + +/** + * + * @brief Release the established audio connection with remote HFP AG. + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] remote_bda: remote bluetooth device address + * @return + * - ESP_OK: disconnect audio request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_disconnect_audio(esp_bd_addr_t remote_bda); + +/** + * + * @brief Enable voice recognition in the AG. + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @return + * - ESP_OK: starting voice recognition is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_start_voice_recognition(void); + +/** + * + * @brief Disable voice recognition in the AG. + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @return + * - ESP_OK: stoping voice recognition is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_stop_voice_recognition(void); + +/** + * + * @brief Volume synchronization with AG. + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] type: volume control target, speaker or microphone + * @param[in] volume: gain of the speaker of microphone, ranges 0 to 15 + * + * @return + * - ESP_OK: volume update is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_volume_update(esp_hf_volume_control_target_t type, int volume); + +/** + * + * @brief Place a call with a specified number, if number is NULL, last called number is called. + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] number: number string of the call. If NULL, the last number is called(aka re-dial) + * + * @return + * - ESP_OK: a call placing is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_dial(const char *number); + +/** + * + * @brief Place a call with number specified by location(speed dial). + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] location: location of the number in the memory + * + * @return + * - ESP_OK: a memory call placing is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ + +esp_err_t esp_hf_client_dial_memory(int location); + +/** + * + * @brief Send call hold and multiparty commands, or enhanced call control commands(Use AT+CHLD). + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] chld: AT+CHLD call hold and multiparty handling AT command. + * @param[in] idx: used in Enhanced Call Control Mechanisms, used if chld is + * ESP_HF_CHLD_TYPE_REL_X or ESP_HF_CHLD_TYPE_PRIV_X + * + * @return + * - ESP_OK: command AT+CHLD is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_send_chld_cmd(esp_hf_chld_type_t chld, int idx); + +/** + * + * @brief Send response and hold action command(Send AT+BTRH command) + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] btrh: response and hold action to send + * + * @return + * - ESP_OK: command AT+BTRH is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_send_btrh_cmd(esp_hf_btrh_cmd_t btrh); + +/** + * + * @brief Answer an incoming call(send ATA command). + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @return + * - ESP_OK: a call answering is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_answer_call(void); + +/** + * + * @brief Reject an incoming call or terminate an ongoing call(send AT+CHUP command). + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @return + * - ESP_OK: the call rejecting is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_reject_call(void); + +/** + * + * @brief Query list of current calls in AG(send AT+CLCC command). + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @return + * - ESP_OK: query of current calls is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_query_current_calls(void); + +/** + * + * @brief Query the name of currently selected network operator in AG(use AT+COPS commands). + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @return + * - ESP_OK: query of current operator name is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_query_current_operator_name(void); + +/** + * + * @brief Get subscriber information number from AG(send AT+CNUM command) + * As a precondition to use this API, Service Level Connection shall exist with AG + * + * @return + * - ESP_OK: the retrieving of subscriber information is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_retrieve_subscriber_info(void); + +/** + * + * @brief Transmit DTMF codes during an ongoing call(use AT+VTS commands) + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @param[in] code: dtmf code, single ascii character in the set 0-9, #, *, A-D + * + * @return + * - ESP_OK: the DTMF codes are sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_send_dtmf(char code); + +/** + * + * @brief Send command to enable Vendor specific feature to indicate battery level + * and docker status + * This is Apple-specific commands, but used by most device, including Android and Windows + * + * @param[in] information: XAPL vendorID-productID-version, such as "0505-1995-0610" + * vendorID: A string representation of the hex value of the vendor ID from the manufacturer, without the 0x prefix. + * productID: A string representation of the hex value of the product ID from the manufacturer, without the 0x prefix. + * version: The revision of the software + * @param[in] features: A base-10 representation of a bit field. such as ESP_HF_CLIENT_XAPL_FEAT_BATTERY_REPORT + * + * @return + * - ESP_OK: Feature enable request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_send_xapl(char *information, uint32_t features); + +/** + * + * @brief Send Battery level and docker status + * Enable this feature using XAPL command first + * This is Apple-specific commands, but used by most device, including Android and Windows + * + * + * @param[in] bat_level: Battery Level: value between 0 and 9 + * @param[in] docked: Dock State: false = undocked, true = docked + * + * @return + * - ESP_OK: battery level is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_send_iphoneaccev(uint32_t bat_level, bool docked); + +/** + * + * @brief Request a phone number from AG corresponding to last voice tag recorded (send AT+BINP command). + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + * @return + * - ESP_OK: the phone number request corresponding to last voice tag recorded is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_request_last_voice_tag_number(void); + +/** + * + * @brief Disable echo cancellation and noise reduction in the AG (use AT+NREC=0 command). + * As a precondition to use this API, Service Level Connection shall exist with AG + * + * @return + * - ESP_OK: NREC=0 request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_send_nrec(void); + + +/** + * @brief Register HFP client data output function; the callback is only used in + * the case that Voice Over HCI is enabled. + * + * @param[in] recv: HFP client incoming data callback function + * + * @param[in] send: HFP client outgoing data callback function + * + * @return + * - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: if callback is a NULL function pointer + * + */ +esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv, + esp_hf_client_outgoing_data_cb_t send); + +/** + * + * @brief Get the number of packets received and sent + * This function is only used in the case that Voice Over HCI is enabled and the audio state is connected. + * When the operation is completed, the callback function will be called with ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT. + * + * @param[in] sync_conn_handle: the (e)SCO connection handle + * + * @return + * - ESP_OK: if the request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle); + +/** + * @brief Trigger the lower-layer to fetch and send audio data. + * This function is only only used in the case that Voice Over HCI is enabled. After this + * function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data. + * + * As a precondition to use this API, Service Level Connection shall exist with AG. + * + */ +void esp_hf_client_outgoing_data_ready(void); + + +/** + * @brief Initialize the down sampling converter. This is a utility function that can + * only be used in the case that Voice Over HCI is enabled. + * + * @param[in] src_sps: original samples per second(source audio data, i.e. 48000, 32000, + * 16000, 44100, 22050, 11025) + * @param[in] bits: number of bits per pcm sample (16) + * + * @param[in] channels: number of channels (i.e. mono(1), stereo(2)...) + */ +void esp_hf_client_pcm_resample_init(uint32_t src_sps, uint32_t bits, uint32_t channels); + +/** + * @brief Deinitialize the down sampling converter. + */ +void esp_hf_client_pcm_resample_deinit(void); + +/** + * @brief Down sampling utility to convert high sampling rate into 8K/16bits 1-channel mode PCM + * samples. This can only be used in the case that Voice Over HCI is enabled. + * + * @param[in] src: pointer to the buffer where the original sampling PCM are stored + * + * @param[in] in_bytes: length of the input PCM sample buffer in byte + * + * @param[in] dst: pointer to the buffer which is to be used to store the converted PCM samples + * + * @return number of samples converted + */ +int32_t esp_hf_client_pcm_resample(void *src, uint32_t in_bytes, void *dst); + +#ifdef __cplusplus +} +#endif + + +#endif /* __ESP_HF_CLIENT_API_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h new file mode 100644 index 00000000..b7671ff1 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h @@ -0,0 +1,246 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_HF_DEFS_H__ +#define __ESP_HF_DEFS_H__ + +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// in-band ring tone state +typedef enum { + ESP_HF_IN_BAND_RINGTONE_NOT_PROVIDED = 0, + ESP_HF_IN_BAND_RINGTONE_PROVIDED, +} esp_hf_in_band_ring_state_t; + +/// voice recognition state +typedef enum { + ESP_HF_VR_STATE_DISABLED = 0, /*!< voice recognition disabled */ + ESP_HF_VR_STATE_ENABLED, /*!< voice recognition enabled */ +} esp_hf_vr_state_t; + +/// Bluetooth HFP audio volume control target +typedef enum { + ESP_HF_VOLUME_CONTROL_TARGET_SPK = 0, /*!< speaker */ + ESP_HF_VOLUME_CONTROL_TARGET_MIC, /*!< microphone */ +} esp_hf_volume_control_target_t; + +/// Bluetooth HFP audio connection status +typedef enum { + ESP_HF_AUDIO_STATE_DISCONNECTED = 0, /*!< audio connection released */ + ESP_HF_AUDIO_STATE_CONNECTING, /*!< audio connection has been initiated */ + ESP_HF_AUDIO_STATE_CONNECTED, /*!< audio connection is established */ + ESP_HF_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */ +} esp_hf_audio_state_t; + +typedef enum { + ESP_HF_VOLUME_TYPE_SPK = 0, + ESP_HF_VOLUME_TYPE_MIC +} esp_hf_volume_type_t; + +/// +CIND network service availability status +typedef enum +{ + ESP_HF_NETWORK_STATE_NOT_AVAILABLE = 0, + ESP_HF_NETWORK_STATE_AVAILABLE +} esp_hf_network_state_t; + +/// +CIEV report type +typedef enum { + ESP_HF_IND_TYPE_CALL = 1, /*!< position of call indicator */ + ESP_HF_IND_TYPE_CALLSETUP, /*!< position of callsetup indicator */ + ESP_HF_IND_TYPE_SERVICE, /*!< position of service indicator */ + ESP_HF_IND_TYPE_SIGNAL, /*!< position of signal strength indicator, range: 0-5 */ + ESP_HF_IND_TYPE_ROAM, /*!< position of roaming indicator */ + ESP_HF_IND_TYPE_BATTCHG, /*!< position of battery charge indicator, range: 0-5 */ + ESP_HF_IND_TYPE_CALLHELD /*!< position of callheld indicator */ +} esp_hf_ciev_report_type_t; + +/** +CIEV Service type */ +typedef enum +{ + ESP_HF_SERVICE_TYPE_HOME = 0, + ESP_HF_SERVICE_TYPE_ROAMING +} esp_hf_service_type_t; + +/// +CIND call status indicator values +typedef enum { + ESP_HF_CALL_STATUS_NO_CALLS = 0, /*!< no call in progress */ + ESP_HF_CALL_STATUS_CALL_IN_PROGRESS = 1, /*!< call is present(active or held) */ +} esp_hf_call_status_t; + +/// +CIND call setup status indicator values +typedef enum { + ESP_HF_CALL_SETUP_STATUS_IDLE = 0, /*!< no call setup in progress */ + ESP_HF_CALL_SETUP_STATUS_INCOMING = 1, /*!< incoming call setup in progress */ + ESP_HF_CALL_SETUP_STATUS_OUTGOING_DIALING = 2, /*!< outgoing call setup in dialing state */ + ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING = 3, /*!< outgoing call setup in alerting state */ +} esp_hf_call_setup_status_t; + +/// +CIND roaming status indicator values +typedef enum { + ESP_HF_ROAMING_STATUS_INACTIVE = 0, /*!< roaming is not active */ + ESP_HF_ROAMING_STATUS_ACTIVE, /*!< a roaming is active */ +} esp_hf_roaming_status_t; + +/// +CIND call held indicator values +typedef enum { + ESP_HF_CALL_HELD_STATUS_NONE = 0, /*!< no calls held */ + ESP_HF_CALL_HELD_STATUS_HELD_AND_ACTIVE = 1, /*!< both active and held call */ + ESP_HF_CALL_HELD_STATUS_HELD = 2, /*!< call on hold, no active call*/ +} esp_hf_call_held_status_t; + +/// +CLCC status of the call +typedef enum { + ESP_HF_CURRENT_CALL_STATUS_ACTIVE = 0, /*!< active */ + ESP_HF_CURRENT_CALL_STATUS_HELD = 1, /*!< held */ + ESP_HF_CURRENT_CALL_STATUS_DIALING = 2, /*!< dialing (outgoing calls only) */ + ESP_HF_CURRENT_CALL_STATUS_ALERTING = 3, /*!< alerting (outgoing calls only) */ + ESP_HF_CURRENT_CALL_STATUS_INCOMING = 4, /*!< incoming (incoming calls only) */ + ESP_HF_CURRENT_CALL_STATUS_WAITING = 5, /*!< waiting (incoming calls only) */ + ESP_HF_CURRENT_CALL_STATUS_HELD_BY_RESP_HOLD = 6, /*!< call held by response and hold */ +} esp_hf_current_call_status_t; + +/// +CLCC direction of the call +typedef enum { + ESP_HF_CURRENT_CALL_DIRECTION_OUTGOING = 0, /*!< outgoing */ + ESP_HF_CURRENT_CALL_DIRECTION_INCOMING = 1, /*!< incoming */ +} esp_hf_current_call_direction_t; + +/// +CLCC multi-party call flag +typedef enum { + ESP_HF_CURRENT_CALL_MPTY_TYPE_SINGLE = 0, /*!< not a member of a multi-party call */ + ESP_HF_CURRENT_CALL_MPTY_TYPE_MULTI = 1, /*!< member of a multi-party call */ +} esp_hf_current_call_mpty_type_t; + +/// +CLCC call mode +typedef enum { + ESP_HF_CURRENT_CALL_MODE_VOICE = 0, + ESP_HF_CURRENT_CALL_MODE_DATA = 1, + ESP_HF_CURRENT_CALL_MODE_FAX = 2, +} esp_hf_current_call_mode_t; + +/// +CLCC address type +typedef enum { + ESP_HF_CALL_ADDR_TYPE_UNKNOWN = 0x81, /*!< unkown address type */ + ESP_HF_CALL_ADDR_TYPE_INTERNATIONAL = 0x91, /*!< international address */ +} esp_hf_call_addr_type_t; + +/// +CNUM service type of the phone number +typedef enum { + ESP_HF_SUBSCRIBER_SERVICE_TYPE_UNKNOWN = 0, /*!< unknown */ + ESP_HF_SUBSCRIBER_SERVICE_TYPE_VOICE = 4, /*!< voice service */ + ESP_HF_SUBSCRIBER_SERVICE_TYPE_FAX, /*!< fax service */ +} esp_hf_subscriber_service_type_t; + +/// +BTRH response and hold result code +typedef enum { + ESP_HF_BTRH_STATUS_HELD = 0, /*!< incoming call is put on held in AG */ + ESP_HF_BTRH_STATUS_ACCEPTED, /*!< held incoming call is accepted in AG */ + ESP_HF_BTRH_STATUS_REJECTED, /*!< held incoming call is rejected in AG */ +} esp_hf_btrh_status_t; + +/// AT+BTRH response and hold action code +typedef enum { + ESP_HF_BTRH_CMD_HOLD = 0, /*!< put the incoming call on hold */ + ESP_HF_BTRH_CMD_ACCEPT = 1, /*!< accept a held incoming call */ + ESP_HF_BTRH_CMD_REJECT = 2, /*!< reject a held incoming call */ +} esp_hf_btrh_cmd_t; + +/* +NREC */ +typedef enum +{ + ESP_HF_NREC_STOP = 0, + ESP_HF_NREC_START +} esp_hf_nrec_t; + +///+CCWA resposne status +typedef enum { + ESP_HF_CALL_WAITING_INACTIVE, + ESP_HF_CALL_WAITING_ACTIVE, +} esp_hf_call_waiting_status_t; + +/* WBS codec setting */ +typedef enum +{ + ESP_HF_WBS_NONE, + ESP_HF_WBS_NO, + ESP_HF_WBS_YES +}esp_hf_wbs_config_t; + +/// Bluetooth HFP RFCOMM connection and service level connection status +typedef enum { + ESP_HF_CONNECTION_STATE_DISCONNECTED = 0, /*!< RFCOMM data link channel released */ + ESP_HF_CONNECTION_STATE_CONNECTING, /*!< connecting remote device on the RFCOMM data link*/ + ESP_HF_CONNECTION_STATE_CONNECTED, /*!< RFCOMM connection established */ + ESP_HF_CONNECTION_STATE_SLC_CONNECTED, /*!< service level connection established */ + ESP_HF_CONNECTION_STATE_DISCONNECTING, /*!< disconnecting with remote device on the RFCOMM data link*/ +} esp_hf_connection_state_t; + +/// AT+CHLD command values +typedef enum { + ESP_HF_CHLD_TYPE_REL = 0, /*!< <0>, Terminate all held or set UDUB("busy") to a waiting call */ + ESP_HF_CHLD_TYPE_REL_ACC, /*!< <1>, Terminate all active calls and accepts a waiting/held call */ + ESP_HF_CHLD_TYPE_HOLD_ACC, /*!< <2>, Hold all active calls and accepts a waiting/held call */ + ESP_HF_CHLD_TYPE_MERGE, /*!< <3>, Add all held calls to a conference */ + ESP_HF_CHLD_TYPE_MERGE_DETACH, /*!< <4>, connect the two calls and disconnects the subscriber from both calls */ + ESP_HF_CHLD_TYPE_REL_X, /*!< <1x>, releases specified calls only */ + ESP_HF_CHLD_TYPE_PRIV_X, /*!< <2x>, request private consultation mode with specified call */ +} esp_hf_chld_type_t; + +/* AT response code - OK/Error */ +typedef enum { + ESP_HF_AT_RESPONSE_CODE_OK = 0, /*!< acknowledges execution of a command line */ + ESP_HF_AT_RESPONSE_CODE_ERR, /*!< command not accepted */ + ESP_HF_AT_RESPONSE_CODE_NO_CARRIER, /*!< connection terminated */ + ESP_HF_AT_RESPONSE_CODE_BUSY, /*!< busy signal detected */ + ESP_HF_AT_RESPONSE_CODE_NO_ANSWER, /*!< connection completion timeout */ + ESP_HF_AT_RESPONSE_CODE_DELAYED, /*!< delayed */ + ESP_HF_AT_RESPONSE_CODE_BLACKLISTED, /*!< blacklisted */ + ESP_HF_AT_RESPONSE_CODE_CME, /*!< CME error */ +} esp_hf_at_response_code_t; + +/* AT response code - OK/Error */ +typedef enum { + ESP_HF_AT_RESPONSE_ERROR = 0, + ESP_HF_AT_RESPONSE_OK +} esp_hf_at_response_t; + +/// Extended Audio Gateway Error Result Code Response +typedef enum { + ESP_HF_CME_AG_FAILURE = 0, /*!< ag failure */ + ESP_HF_CME_NO_CONNECTION_TO_PHONE = 1, /*!< no connection to phone */ + ESP_HF_CME_OPERATION_NOT_ALLOWED = 3, /*!< operation not allowed */ + ESP_HF_CME_OPERATION_NOT_SUPPORTED = 4, /*!< operation not supported */ + ESP_HF_CME_PH_SIM_PIN_REQUIRED = 5, /*!< PH-SIM PIN Required */ + ESP_HF_CME_SIM_NOT_INSERTED = 10, /*!< SIM not inserted */ + ESP_HF_CME_SIM_PIN_REQUIRED = 11, /*!< SIM PIN required */ + ESP_HF_CME_SIM_PUK_REQUIRED = 12, /*!< SIM PUK required */ + ESP_HF_CME_SIM_FAILURE = 13, /*!< SIM failure */ + ESP_HF_CME_SIM_BUSY = 14, /*!< SIM busy */ + ESP_HF_CME_INCORRECT_PASSWORD = 16, /*!< incorrect password */ + ESP_HF_CME_SIM_PIN2_REQUIRED = 17, /*!< SIM PIN2 required */ + ESP_HF_CME_SIM_PUK2_REQUIRED = 18, /*!< SIM PUK2 required */ + ESP_HF_CME_MEMORY_FULL = 20, /*!< memory full */ + ESP_HF_CME_INVALID_INDEX = 21, /*!< invalid index */ + ESP_HF_CME_MEMORY_FAILURE = 23, /*!< memory failure */ + ESP_HF_CME_TEXT_STRING_TOO_LONG = 24, /*!< test string too long */ + ESP_HF_CME_INVALID_CHARACTERS_IN_TEXT_STRING = 25, /*!< invalid characters in text string */ + ESP_HF_CME_DIAL_STRING_TOO_LONG = 26, /*!< dial string too long*/ + ESP_HF_CME_INVALID_CHARACTERS_IN_DIAL_STRING = 27, /*!< invalid characters in dial string */ + ESP_HF_CME_NO_NETWORK_SERVICE = 30, /*!< no network service */ + ESP_HF_CME_NETWORK_TIMEOUT = 31, /*!< network timeout */ + ESP_HF_CME_NETWORK_NOT_ALLOWED = 32, /*!< network not allowed --emergency calls only */ +} esp_hf_cme_err_t; + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_HF_DEFS_H__ */ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h new file mode 100644 index 00000000..a2af1659 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h @@ -0,0 +1,413 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: Blake Felt + */ + +#ifndef __ESP_HIDD_API_H__ +#define __ESP_HIDD_API_H__ + +#include "esp_bt_defs.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// subclass of hid device +#define ESP_HID_CLASS_UNKNOWN (0x00<<2) /*!< unknown HID device subclass */ +#define ESP_HID_CLASS_JOS (0x01<<2) /*!< joystick */ +#define ESP_HID_CLASS_GPD (0x02<<2) /*!< game pad */ +#define ESP_HID_CLASS_RMC (0x03<<2) /*!< remote control */ +#define ESP_HID_CLASS_SED (0x04<<2) /*!< sensing device */ +#define ESP_HID_CLASS_DGT (0x05<<2) /*!< digitizer tablet */ +#define ESP_HID_CLASS_CDR (0x06<<2) /*!< card reader */ +#define ESP_HID_CLASS_KBD (0x10<<2) /*!< keyboard */ +#define ESP_HID_CLASS_MIC (0x20<<2) /*!< pointing device */ +#define ESP_HID_CLASS_COM (0x30<<2) /*!< combo keyboard/pointing */ + +/** + * @brief HIDD handshake result code + */ +typedef enum { + ESP_HID_PAR_HANDSHAKE_RSP_SUCCESS = 0, /*!< successful */ + ESP_HID_PAR_HANDSHAKE_RSP_NOT_READY = 1, /*!< not ready, device is too busy to accept data */ + ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID = 2, /*!< invalid report ID */ + ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ = 3, /*!< device does not support the request */ + ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM = 4, /*!< parameter value is out of range or inappropriate */ + ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN = 14, /*!< device could not identify the error condition */ + ESP_HID_PAR_HANDSHAKE_RSP_ERR_FATAL = 15, /*!< restart is essential to resume functionality */ +} esp_hidd_handshake_error_t; + +/** + * @brief HIDD report types + */ +typedef enum { + ESP_HIDD_REPORT_TYPE_OTHER = 0, /*!< unknown report type */ + ESP_HIDD_REPORT_TYPE_INPUT, /*!< input report */ + ESP_HIDD_REPORT_TYPE_OUTPUT, /*!< output report */ + ESP_HIDD_REPORT_TYPE_FEATURE, /*!< feature report */ + ESP_HIDD_REPORT_TYPE_INTRDATA, /*!< special value for reports to be sent on interrupt channel, INPUT is assumed */ +} esp_hidd_report_type_t; + +/** + * @brief HIDD connection state + */ +typedef enum { + ESP_HIDD_CONN_STATE_CONNECTED, /*!< HID connection established */ + ESP_HIDD_CONN_STATE_CONNECTING, /*!< connection to remote Bluetooth device */ + ESP_HIDD_CONN_STATE_DISCONNECTED, /*!< connection released */ + ESP_HIDD_CONN_STATE_DISCONNECTING, /*!< disconnecting to remote Bluetooth device*/ + ESP_HIDD_CONN_STATE_UNKNOWN, /*!< unknown connection state */ +} esp_hidd_connection_state_t; + +/** + * @brief HID device protocol modes + */ +typedef enum { + ESP_HIDD_REPORT_MODE = 0x00, /*!< Report Protocol Mode */ + ESP_HIDD_BOOT_MODE = 0x01, /*!< Boot Protocol Mode */ + ESP_HIDD_UNSUPPORTED_MODE = 0xff, /*!< unsupported */ +} esp_hidd_protocol_mode_t; + +/** + * @brief HID Boot Protocol report IDs + */ +typedef enum { + ESP_HIDD_BOOT_REPORT_ID_KEYBOARD = 1, /*!< report ID of Boot Protocol keyboard report */ + ESP_HIDD_BOOT_REPORT_ID_MOUSE = 2, /*!< report ID of Boot Protocol mouse report */ +} esp_hidd_boot_report_id_t; + +/** + * @brief HID Boot Protocol report size including report ID + */ +enum { + ESP_HIDD_BOOT_REPORT_SIZE_KEYBOARD = 9, /*!< report size of Boot Protocol keyboard report */ + ESP_HIDD_BOOT_REPORT_SIZE_MOUSE = 4, /*!< report size of Boot Protocol mouse report */ +}; + +/** + * @brief HID device characteristics for SDP server + */ +typedef struct { + const char *name; /*!< service name */ + const char *description; /*!< service description */ + const char *provider; /*!< provider name */ + uint8_t subclass; /*!< HID device subclass */ + uint8_t *desc_list; /*!< HID descriptor list */ + int desc_list_len; /*!< size in bytes of HID descriptor list */ +} esp_hidd_app_param_t; + +/** + * @brief HIDD Quality of Service parameters negotiated over L2CAP + */ +typedef struct { + uint8_t service_type; /*!< the level of service, 0 indicates no traffic */ + uint32_t token_rate; /*!< token rate in bytes per second, 0 indicates "don't care" */ + uint32_t token_bucket_size; /*!< limit on the burstness of the application data */ + uint32_t peak_bandwidth; /*!< bytes per second, value 0 indicates "don't care" */ + uint32_t access_latency; /*!< maximum acceptable delay in microseconds */ + uint32_t delay_variation; /*!< the difference in microseconds between the max and min delay */ +} esp_hidd_qos_param_t; + +/** + * @brief HID device callback function events + */ +typedef enum { + ESP_HIDD_INIT_EVT = 0, /*!< When HID device is initialized, the event comes */ + ESP_HIDD_DEINIT_EVT, /*!< When HID device is deinitialized, the event comes */ + ESP_HIDD_REGISTER_APP_EVT, /*!< When HID device application registered, the event comes */ + ESP_HIDD_UNREGISTER_APP_EVT, /*!< When HID device application unregistered, the event comes */ + ESP_HIDD_OPEN_EVT, /*!< When HID device connection to host opened, the event comes */ + ESP_HIDD_CLOSE_EVT, /*!< When HID device connection to host closed, the event comes */ + ESP_HIDD_SEND_REPORT_EVT, /*!< When HID device send report to lower layer, the event comes */ + ESP_HIDD_REPORT_ERR_EVT, /*!< When HID device report handshanke error to lower layer, the event comes */ + ESP_HIDD_GET_REPORT_EVT, /*!< When HID device receives GET_REPORT request from host, the event comes */ + ESP_HIDD_SET_REPORT_EVT, /*!< When HID device receives SET_REPORT request from host, the event comes */ + ESP_HIDD_SET_PROTOCOL_EVT, /*!< When HID device receives SET_PROTOCOL request from host, the event comes */ + ESP_HIDD_INTR_DATA_EVT, /*!< When HID device receives DATA from host on intr, the event comes */ + ESP_HIDD_VC_UNPLUG_EVT, /*!< When HID device initiates Virtual Cable Unplug, the event comes */ + ESP_HIDD_API_ERR_EVT /*!< When HID device has API error, the event comes */ +} esp_hidd_cb_event_t; + +typedef enum { + ESP_HIDD_SUCCESS, + ESP_HIDD_ERROR, /*!< general ESP HD error */ + ESP_HIDD_NO_RES, /*!< out of system resources */ + ESP_HIDD_BUSY, /*!< Temporarily can not handle this request. */ + ESP_HIDD_NO_DATA, /*!< No data. */ + ESP_HIDD_NEED_INIT, /*!< HIDD module shall init first */ + ESP_HIDD_NEED_DEINIT, /*!< HIDD module shall deinit first */ + ESP_HIDD_NEED_REG, /*!< HIDD module shall register first */ + ESP_HIDD_NEED_DEREG, /*!< HIDD module shall deregister first */ + ESP_HIDD_NO_CONNECTION, /*!< connection may have been closed */ +} esp_hidd_status_t; + +/** + * @brief HID device callback parameters union + */ +typedef union { + /** + * @brief ESP_HIDD_INIT_EVT + */ + struct hidd_init_evt_param { + esp_hidd_status_t status; /*!< operation status */ + } init; /*!< HIDD callback param of ESP_HIDD_INIT_EVT */ + + /** + * @brief ESP_HIDD_DEINIT_EVT + */ + struct hidd_deinit_evt_param { + esp_hidd_status_t status; /*!< operation status */ + } deinit; /*!< HIDD callback param of ESP_HIDD_DEINIT_EVT */ + + /** + * @brief ESP_HIDD_REGISTER_APP_EVT + */ + struct hidd_register_app_evt_param { + esp_hidd_status_t status; /*!< operation status */ + bool in_use; /*!< indicate whether use virtual cable plug host address */ + esp_bd_addr_t bd_addr; /*!< host address */ + } register_app; /*!< HIDD callback param of ESP_HIDD_REGISTER_APP_EVT */ + + /** + * @brief ESP_HIDD_UNREGISTER_APP_EVT + */ + struct hidd_unregister_app_evt_param { + esp_hidd_status_t status; /*!< operation status */ + } unregister_app; /*!< HIDD callback param of ESP_HIDD_UNREGISTER_APP_EVT */ + + /** + * @brief ESP_HIDD_OPEN_EVT + */ + struct hidd_open_evt_param { + esp_hidd_status_t status; /*!< operation status */ + esp_hidd_connection_state_t conn_status; /*!< connection status */ + esp_bd_addr_t bd_addr; /*!< host address */ + } open; /*!< HIDD callback param of ESP_HIDD_OPEN_EVT */ + + /** + * @brief ESP_HIDD_CLOSE_EVT + */ + struct hidd_close_evt_param { + esp_hidd_status_t status; /*!< operation status */ + esp_hidd_connection_state_t conn_status; /*!< connection status */ + } close; /*!< HIDD callback param of ESP_HIDD_CLOSE_EVT */ + + /** + * @brief ESP_HIDD_SEND_REPORT_EVT + */ + struct hidd_send_report_evt_param { + esp_hidd_status_t status; /*!< operation status */ + uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */ + esp_hidd_report_type_t report_type; /*!< report type */ + uint8_t report_id; /*!< report id */ + } send_report; /*!< HIDD callback param of ESP_HIDD_SEND_REPORT_EVT */ + + /** + * @brief ESP_HIDD_REPORT_ERR_EVT + */ + struct hidd_report_err_evt_param { + esp_hidd_status_t status; /*!< operation status */ + uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */ + } report_err; /*!< HIDD callback param of ESP_HIDD_REPORT_ERR_EVT */ + + /** + * @brief ESP_HIDD_GET_REPORT_EVT + */ + struct hidd_get_report_evt_param { + esp_hidd_report_type_t report_type; /*!< report type */ + uint8_t report_id; /*!< report id */ + uint16_t buffer_size; /*!< buffer size */ + } get_report; /*!< HIDD callback param of ESP_HIDD_GET_REPORT_EVT */ + + /** + * @brief ESP_HIDD_SET_REPORT_EVT + */ + struct hidd_set_report_evt_param { + esp_hidd_report_type_t report_type; /*!< report type */ + uint8_t report_id; /*!< report id */ + uint16_t len; /*!< set_report data length */ + uint8_t *data; /*!< set_report data pointer */ + } set_report; /*!< HIDD callback param of ESP_HIDD_SET_REPORT_EVT */ + + /** + * @brief ESP_HIDD_SET_PROTOCOL_EVT + */ + struct hidd_set_protocol_evt_param { + esp_hidd_protocol_mode_t protocol_mode; /*!< protocol mode */ + } set_protocol; /*!< HIDD callback param of ESP_HIDD_SET_PROTOCOL_EVT */ + + /** + * @brief ESP_HIDD_INTR_DATA_EVT + */ + struct hidd_intr_data_evt_param { + uint8_t report_id; /*!< interrupt channel report id */ + uint16_t len; /*!< interrupt channel report data length */ + uint8_t *data; /*!< interrupt channel report data pointer */ + } intr_data; /*!< HIDD callback param of ESP_HIDD_INTR_DATA_EVT */ + + /** + * @brief ESP_HIDD_VC_UNPLUG_EVT + */ + struct hidd_vc_unplug_param { + esp_hidd_status_t status; /*!< operation status */ + esp_hidd_connection_state_t conn_status; /*!< connection status */ + } vc_unplug; /*!< HIDD callback param of ESP_HIDD_VC_UNPLUG_EVT */ +} esp_hidd_cb_param_t; + +/** + * @brief HID device callback function type. + * @param event: Event type + * @param param: Point to callback parameter, currently is union type + */ +typedef void (*esp_hd_cb_t)(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param); + +/** + * @brief This function is called to init callbacks with HID device module. + * + * @param[in] callback: pointer to the init callback function. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_register_callback(esp_hd_cb_t callback); + +/** + * @brief Initializes HIDD interface. This function should be called after + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, and should be + * called after esp_bt_hid_device_register_callback. When the operation is complete, the callback + * function will be called with ESP_HIDD_INIT_EVT. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_init(void); + +/** + * @brief De-initializes HIDD interface. This function should be called after + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, and should be + * called after esp_bt_hid_device_init(). When the operation is complete, the callback function will be + * called with ESP_HIDD_DEINIT_EVT. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_deinit(void); + +/** + * @brief Registers HIDD parameters with SDP and sets l2cap Quality of Service. This function should be + * called after esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, + * and should be called after esp_bt_hid_device_init(). When the operation is complete, the callback + * function will be called with ESP_HIDD_REGISTER_APP_EVT. + * + * @param[in] app_param: HIDD parameters + * @param[in] in_qos: incoming QoS parameters + * @param[in] out_qos: outgoing QoS parameters + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t *app_param, esp_hidd_qos_param_t *in_qos, + esp_hidd_qos_param_t *out_qos); + +/** + * @brief Removes HIDD parameters from SDP and resets l2cap Quality of Service. This function should be + * called after esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, + * and should be called after esp_bt_hid_device_init(). When the operation is complete, the callback + * function will be called with ESP_HIDD_UNREGISTER_APP_EVT. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_unregister_app(void); + +/** + * @brief Connects to the peer HID Host with virtual cable. This function should be called after + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, and should be + * called after esp_bt_hid_device_init(). When the operation is complete, the callback function will + * be called with ESP_HIDD_OPEN_EVT. + * + * @param[in] bd_addr: Remote host bluetooth device address. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr); + +/** + * @brief Disconnects from the currently connected HID Host. This function should be called after + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, and should be + * called after esp_bt_hid_device_init(). When the operation is complete, the callback function will + * be called with ESP_HIDD_CLOSE_EVT. + * + * @note The disconnect operation will not remove the virtually cabled device. If the connect request from the + * different HID Host, it will reject the request. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_disconnect(void); + +/** + * @brief Sends HID report to the currently connected HID Host. This function should be called after + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, and should be + * called after esp_bt_hid_device_init(). When the operation is complete, the callback function will + * be called with ESP_HIDD_SEND_REPORT_EVT. + * + * @param[in] type: type of report + * @param[in] id: report id as defined by descriptor + * @param[in] len: length of report + * @param[in] data: report data + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t *data); + +/** + * @brief Sends HID Handshake with error info for invalid set_report to the currently connected HID Host. + * This function should be called after esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and + * esp_bluedroid_enable() success, and should be called after esp_bt_hid_device_init(). When the + * operation is complete, the callback function will be called with ESP_HIDD_REPORT_ERR_EVT. + * + * @param[in] error: type of error + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error); + +/** + * @brief Remove the virtually cabled device. This function should be called after + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() and esp_bluedroid_enable() success, and should be + * called after esp_bt_hid_device_init(). When the operation is complete, the callback function will be + * called with ESP_HIDD_VC_UNPLUG_EVT. + * + * @note If the connection exists, then HID Device will send a `VIRTUAL_CABLE_UNPLUG` control command to + * the peer HID Host, and the connection will be destroyed. If the connection does not exist, then HID + * Device will only unplug on it's single side. Once the unplug operation is success, the related + * pairing and bonding information will be removed, then the HID Device can accept connection request + * from the different HID Host, + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_device_virtual_cable_unplug(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h new file mode 100644 index 00000000..46f8a15b --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h @@ -0,0 +1,482 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: Blake Felt + */ + +#ifndef __ESP_HIDH_API_H__ +#define __ESP_HIDH_API_H__ + +#include "esp_bt_defs.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// maximum size of HID Device report descriptor +#define BTHH_MAX_DSC_LEN 884 + +/** + * @brief HID host connection state + */ +typedef enum { + ESP_HIDH_CONN_STATE_CONNECTED = 0, /*!< connected state */ + ESP_HIDH_CONN_STATE_CONNECTING, /*!< connecting state */ + ESP_HIDH_CONN_STATE_DISCONNECTED, /*!< disconnected state */ + ESP_HIDH_CONN_STATE_DISCONNECTING, /*!< disconnecting state */ + ESP_HIDH_CONN_STATE_UNKNOWN /*!< unknown state (initial state) */ +} esp_hidh_connection_state_t; + +/** + * @brief HID handshake error code and vendor-defined result code + */ +typedef enum { + ESP_HIDH_OK, /*!< successful */ + ESP_HIDH_HS_HID_NOT_READY, /*!< handshake error: device not ready */ + ESP_HIDH_HS_INVALID_RPT_ID, /*!< handshake error: invalid report ID */ + ESP_HIDH_HS_TRANS_NOT_SPT, /*!< handshake error: HID device does not support the request */ + ESP_HIDH_HS_INVALID_PARAM, /*!< handshake error: parameter value does not meet the expected criteria of called function or API */ + ESP_HIDH_HS_ERROR, /*!< handshake error: HID device could not identify the error condition */ + ESP_HIDH_ERR, /*!< general ESP HID Host error */ + ESP_HIDH_ERR_SDP, /*!< SDP error */ + ESP_HIDH_ERR_PROTO, /*!< SET_PROTOCOL error, only used in ESP_HIDH_OPEN_EVT callback */ + ESP_HIDH_ERR_DB_FULL, /*!< device database full, used in ESP_HIDH_OPEN_EVT/ESP_HIDH_ADD_DEV_EVT */ + ESP_HIDH_ERR_TOD_UNSPT, /*!< type of device not supported */ + ESP_HIDH_ERR_NO_RES, /*!< out of system resources */ + ESP_HIDH_ERR_AUTH_FAILED, /*!< authentication fail */ + ESP_HIDH_ERR_HDL, /*!< connection handle error */ + ESP_HIDH_ERR_SEC, /*!< encryption error */ + ESP_HIDH_BUSY, /*!< vendor-defined: temporarily can not handle this request */ + ESP_HIDH_NO_DATA, /*!< vendor-defined: no data. */ + ESP_HIDH_NEED_INIT, /*!< vendor-defined: HIDH module shall initialize first */ + ESP_HIDH_NEED_DEINIT, /*!< vendor-defined: HIDH module shall de-deinitialize first */ + ESP_HIDH_NO_CONNECTION, /*!< vendor-defined: connection may have been closed */ +} esp_hidh_status_t; + +/** + * @brief HID host protocol modes + */ +typedef enum { + ESP_HIDH_BOOT_MODE = 0x00, /*!< boot protocol mode */ + ESP_HIDH_REPORT_MODE = 0x01, /*!< report protocol mode */ + ESP_HIDH_UNSUPPORTED_MODE = 0xff /*!< unsupported protocol mode */ +} esp_hidh_protocol_mode_t; + +/** + * @brief HID host report types + */ +typedef enum { + ESP_HIDH_REPORT_TYPE_OTHER = 0, /*!< unsupported report type */ + ESP_HIDH_REPORT_TYPE_INPUT, /*!< input report type */ + ESP_HIDH_REPORT_TYPE_OUTPUT, /*!< output report type */ + ESP_HIDH_REPORT_TYPE_FEATURE, /*!< feature report type */ +} esp_hidh_report_type_t; + +/** + * @brief HID host callback function events + */ +typedef enum { + ESP_HIDH_INIT_EVT = 0, /*!< when HID host is initialized, the event comes */ + ESP_HIDH_DEINIT_EVT, /*!< when HID host is deinitialized, the event comes */ + ESP_HIDH_OPEN_EVT, /*!< when HID host connection opened, the event comes */ + ESP_HIDH_CLOSE_EVT, /*!< when HID host connection closed, the event comes */ + ESP_HIDH_GET_RPT_EVT, /*!< when Get_Report command is called, the event comes */ + ESP_HIDH_SET_RPT_EVT, /*!< when Set_Report command is called, the event comes */ + ESP_HIDH_GET_PROTO_EVT, /*!< when Get_Protocol command is called, the event comes */ + ESP_HIDH_SET_PROTO_EVT, /*!< when Set_Protocol command is called, the event comes */ + ESP_HIDH_GET_IDLE_EVT, /*!< when Get_Idle command is called, the event comes */ + ESP_HIDH_SET_IDLE_EVT, /*!< when Set_Idle command is called, the event comes */ + ESP_HIDH_GET_DSCP_EVT, /*!< when HIDH is initialized, the event comes */ + ESP_HIDH_ADD_DEV_EVT, /*!< when a device is added, the event comes */ + ESP_HIDH_RMV_DEV_EVT, /*!< when a device is removed, the event comes */ + ESP_HIDH_VC_UNPLUG_EVT, /*!< when virtually unplugged, the event comes */ + ESP_HIDH_DATA_EVT, /*!< when send data on interrupt channel, the event comes */ + ESP_HIDH_DATA_IND_EVT, /*!< when receive data on interrupt channel, the event comes */ + ESP_HIDH_SET_INFO_EVT /*!< when set the HID device descriptor, the event comes */ +} esp_hidh_cb_event_t; + +/** + * @brief HID device information from HID Device Service Record and Device ID Service Record + */ +typedef enum { + ESP_HIDH_DEV_ATTR_VIRTUAL_CABLE = 0x0001, /*!< whether Virtual Cables is supported */ + ESP_HIDH_DEV_ATTR_NORMALLY_CONNECTABLE = 0x0002, /*!< whether device is in Page Scan mode when there is no active connection */ + ESP_HIDH_DEV_ATTR_RECONNECT_INITIATE = 0x0004, /*!< whether the HID device inititates the reconnection process */ +} esp_hidh_dev_attr_t; + +/** + * @brief application ID(non-zero) for each type of device + */ +typedef enum { + ESP_HIDH_APP_ID_MOUSE = 1, /*!< pointing device */ + ESP_HIDH_APP_ID_KEYBOARD = 2, /*!< keyboard */ + ESP_HIDH_APP_ID_REMOTE_CONTROL = 3, /*!< remote control */ + ESP_HIDH_APP_ID_JOYSTICK = 5, /*!< joystick */ + ESP_HIDH_APP_ID_GAMEPAD = 6, /*!< gamepad*/ +} esp_hidh_dev_app_id_t; + +/** + * @brief HID device information from HID Device Service Record and Device ID Service Record + */ +typedef struct { + int attr_mask; /*!< device attribute bit mask, refer to esp_hidh_dev_attr_t */ + uint8_t sub_class; /*!< HID device subclass */ + uint8_t app_id; /*!< application ID, refer to esp_hidh_dev_app_id_t */ + int vendor_id; /*!< Device ID information: vendor ID */ + int product_id; /*!< Device ID information: product ID */ + int version; /*!< Device ID information: version */ + uint8_t ctry_code; /*!< SDP attrbutes of HID devices: HID country code (https://www.usb.org/sites/default/files/hid1_11.pdf) */ + int dl_len; /*!< SDP attrbutes of HID devices: HID device descriptor length */ + uint8_t dsc_list[BTHH_MAX_DSC_LEN]; /*!< SDP attrbutes of HID devices: HID device descriptor definition */ +} esp_hidh_hid_info_t; + +/** + * @brief HID host callback parameters union + */ +typedef union { + /** + * @brief ESP_HIDH_INIT_EVT + */ + struct hidh_init_evt_param { + esp_hidh_status_t status; /*!< status */ + } init; /*!< HIDH callback param of ESP_HIDH_INIT_EVT */ + + /** + * @brief ESP_HIDH_DEINIT_EVT + */ + struct hidh_uninit_evt_param { + esp_hidh_status_t status; /*!< status */ + } deinit; /*!< HIDH callback param of ESP_HIDH_DEINIT_EVT */ + + /** + * @brief ESP_HIDH_OPEN_EVT + */ + struct hidh_open_evt_param { + esp_hidh_status_t status; /*!< operation status */ + esp_hidh_connection_state_t conn_status; /*!< connection status */ + bool is_orig; /*!< indicate if host intiate the connection */ + uint8_t handle; /*!< device handle */ + esp_bd_addr_t bd_addr; /*!< device address */ + } open; /*!< HIDH callback param of ESP_HIDH_OPEN_EVT */ + + /** + * @brief ESP_HIDH_CLOSE_EVT + */ + struct hidh_close_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */ + esp_hidh_connection_state_t conn_status; /*!< connection status */ + uint8_t handle; /*!< device handle */ + } close; /*!< HIDH callback param of ESP_HIDH_CLOSE_EVT */ + + /** + * @brief ESP_HIDH_VC_UNPLUG_EVT + */ + struct hidh_unplug_evt_param { + esp_hidh_status_t status; /*!< operation status */ + esp_hidh_connection_state_t conn_status; /*!< connection status */ + uint8_t handle; /*!< device handle */ + } unplug; /*!< HIDH callback param of ESP_HIDH_VC_UNPLUG_EVT */ + + /** + * @brief ESP_HIDH_GET_PROTO_EVT + */ + struct hidh_get_proto_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode */ + } get_proto; /*!< HIDH callback param of ESP_HIDH_GET_PROTO_EVT */ + + /** + * @brief ESP_HIDH_SET_PROTO_EVT + */ + struct hidh_set_proto_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + } set_proto; /*!< HIDH callback param of ESP_HIDH_SET_PROTO_EVT */ + + /** + * @brief ESP_HIDH_GET_RPT_EVT + */ + struct hidh_get_rpt_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + uint16_t len; /*!< data length */ + uint8_t *data; /*!< data pointer */ + } get_rpt; /*!< HIDH callback param of ESP_HIDH_GET_RPT_EVT */ + + /** + * @brief ESP_HIDH_SET_RPT_EVT + */ + struct hidh_set_rpt_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + } set_rpt; /*!< HIDH callback param of ESP_HIDH_SET_RPT_EVT */ + + /** + * @brief ESP_HIDH_DATA_EVT + */ + struct hidh_send_data_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */ + } send_data; /*!< HIDH callback param of ESP_HIDH_DATA_EVT */ + + /** + * @brief ESP_HIDH_GET_IDLE_EVT + */ + struct hidh_get_idle_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + uint8_t idle_rate; /*!< idle rate */ + } get_idle; /*!< HIDH callback param of ESP_HIDH_GET_IDLE_EVT */ + + /** + * @brief ESP_HIDH_SET_IDLE_EVT + */ + struct hidh_set_idle_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + } set_idle; /*!< HIDH callback param of ESP_HIDH_SET_IDLE_EVT */ + + /** + * @brief ESP_HIDH_DATA_IND_EVT + */ + struct hidh_data_ind_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode */ + uint16_t len; /*!< data length */ + uint8_t *data; /*!< data pointer */ + } data_ind; /*!< HIDH callback param of ESP_HIDH_DATA_IND_EVT */ + + /** + * @brief ESP_HIDH_ADD_DEV_EVT + */ + struct hidh_add_dev_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + esp_bd_addr_t bd_addr; /*!< device address */ + } add_dev; /*!< HIDH callback param of ESP_HIDH_ADD_DEV_EVT */ + + /** + * @brief ESP_HIDH_RMV_DEV_EVT + */ + struct hidh_rmv_dev_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + esp_bd_addr_t bd_addr; /*!< device address */ + } rmv_dev; /*!< HIDH callback param of ESP_HIDH_RMV_DEV_EVT */ + + /** + * @brief ESP_HIDH_GET_DSCP_EVT + */ + struct hidh_get_dscp_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + bool added; /*!< Indicate if added */ + uint16_t vendor_id; /*!< Vendor ID */ + uint16_t product_id; /*!< Product ID */ + uint16_t version; /*!< Version */ + uint16_t ssr_max_latency; /*!< SSR max latency in slots */ + uint16_t ssr_min_tout; /*!< SSR min timeout in slots */ + uint8_t ctry_code; /*!< Country Code */ + uint16_t dl_len; /*!< Device descriptor length */ + uint8_t *dsc_list; /*!< Device descriptor pointer */ + } dscp; /*!< HIDH callback param of ESP_HIDH_GET_DSCP_EVT */ + + /** + * @brief ESP_HIDH_SET_INFO_EVT + */ + struct hidh_set_info_evt_param { + esp_hidh_status_t status; /*!< operation status */ + uint8_t handle; /*!< device handle */ + esp_bd_addr_t bd_addr; /*!< device address */ + } set_info; /*!< HIDH callback param of ESP_HIDH_SET_INFO_EVT */ +} esp_hidh_cb_param_t; + +/** + * @brief HID host callback function type + * @param event: Event type + * @param param: Point to callback parameter, currently is union type + */ +typedef void (*esp_hh_cb_t)(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param); + +/** + * @brief This function is called to init callbacks with HID host module. + * + * @param[in] callback: pointer to the init callback function. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t callback); + +/** + * @brief This function initializes HID host. This function should be called after esp_bluedroid_enable() and + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() success, and should be called after + * esp_bt_hid_host_register_callback(). When the operation is complete the callback function will be called + * with ESP_HIDH_INIT_EVT. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_init(void); + +/** + * @brief Closes the interface. This function should be called after esp_bluedroid_enable() and + * esp_bluedroid_init()/esp_bluedroid_init_with_cfg() success, and should be called after esp_bt_hid_host_init(). + * When the operation is complete the callback function will be called with ESP_HIDH_DEINIT_EVT. + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_deinit(void); + +/** + * @brief Connect to HID device. When the operation is complete the callback + * function will be called with ESP_HIDH_OPEN_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr); + +/** + * @brief Disconnect from HID device. When the operation is complete the callback + * function will be called with ESP_HIDH_CLOSE_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr); + +/** + * @brief Virtual UnPlug (VUP) the specified HID device. When the operation is complete the callback + * function will be called with ESP_HIDH_VC_UNPLUG_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr); + +/** + * @brief Set the HID device descriptor for the specified HID device. When the operation is complete the callback + * function will be called with ESP_HIDH_SET_INFO_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * @param[in] hid_info: HID device descriptor structure. + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info); + +/** + * @brief Get the HID proto mode. When the operation is complete the callback + * function will be called with ESP_HIDH_GET_PROTO_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr); + +/** + * @brief Set the HID proto mode. When the operation is complete the callback + * function will be called with ESP_HIDH_SET_PROTO_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * @param[in] protocol_mode: Protocol mode type. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode); + +/** + * @brief Get the HID Idle Time. When the operation is complete the callback + * function will be called with ESP_HIDH_GET_IDLE_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr); + +/** + * @brief Set the HID Idle Time. When the operation is complete the callback + * function will be called with ESP_HIDH_SET_IDLE_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * @param[in] idle_time: Idle time rate + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time); + +/** + * @brief Send a GET_REPORT to HID device. When the operation is complete the callback + * function will be called with ESP_HIDH_GET_RPT_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * @param[in] report_type: Report type + * @param[in] report_id: Report id + * @param[in] buffer_size: Buffer size + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t report_id, + int buffer_size); + +/** + * @brief Send a SET_REPORT to HID device. When the operation is complete the callback + * function will be called with ESP_HIDH_SET_RPT_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * @param[in] report_type: Report type + * @param[in] report: Report data pointer + * @param[in] len: Report data length + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t *report, + size_t len); + +/** + * @brief Send data to HID device. When the operation is complete the callback + * function will be called with ESP_HIDH_DATA_EVT. + * + * @param[in] bd_addr: Remote device bluetooth device address. + * @param[in] data: Data pointer + * @param[in] len: Data length + * + * @return - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h b/lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h new file mode 100644 index 00000000..f11c932f --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h @@ -0,0 +1,251 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_L2CAP_BT_API_H__ +#define __ESP_L2CAP_BT_API_H__ + +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief L2CAP operation success and failure codes + */ +typedef enum { + ESP_BT_L2CAP_SUCCESS = 0, /*!< Successful operation. */ + ESP_BT_L2CAP_FAILURE, /*!< Generic failure. */ + ESP_BT_L2CAP_BUSY, /*!< Temporarily can not handle this request. */ + ESP_BT_L2CAP_NO_RESOURCE, /*!< No more resource */ + ESP_BT_L2CAP_NEED_INIT, /*!< L2CAP module shall init first */ + ESP_BT_L2CAP_NEED_DEINIT, /*!< L2CAP module shall deinit first */ + ESP_BT_L2CAP_NO_CONNECTION, /*!< Connection may have been closed */ + ESP_BT_L2CAP_NO_SERVER, /*!< No server */ +} esp_bt_l2cap_status_t; + +/** + * @brief Security Setting Mask. Use these three mask mode: + * 1. ESP_BT_L2CAP_SEC_NONE + * 2. ESP_BT_L2CAP_SEC_AUTHENTICATE + * 3. (ESP_BT_L2CAP_SEC_ENCRYPT|ESP_BT_L2CAP_SEC_AUTHENTICATE) + */ +#define ESP_BT_L2CAP_SEC_NONE 0x0000 /*!< No security */ +#define ESP_BT_L2CAP_SEC_AUTHORIZE 0x0001 /*!< Authorization required */ +#define ESP_BT_L2CAP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required */ +#define ESP_BT_L2CAP_SEC_ENCRYPT 0x0024 /*!< Encryption required */ +typedef uint32_t esp_bt_l2cap_cntl_flags_t; + +/** + * @brief L2CAP callback function events + */ +typedef enum { + ESP_BT_L2CAP_INIT_EVT = 0, /*!< When L2CAP is initialized, the event comes */ + ESP_BT_L2CAP_UNINIT_EVT = 1, /*!< When L2CAP is deinitialized, the event comes */ + ESP_BT_L2CAP_OPEN_EVT = 16, /*!< When L2CAP Client connection open, the event comes */ + ESP_BT_L2CAP_CLOSE_EVT = 17, /*!< When L2CAP connection closed, the event comes */ + ESP_BT_L2CAP_START_EVT = 18, /*!< When L2CAP server started, the event comes */ + ESP_BT_L2CAP_CL_INIT_EVT = 19, /*!< When L2CAP client initiated a connection, the event comes */ + ESP_BT_L2CAP_SRV_STOP_EVT = 36, /*!< When L2CAP server stopped, the event comes */ +} esp_bt_l2cap_cb_event_t; + +/** + * @brief L2CAP callback parameters union + */ +typedef union { + /** + * @brief ESP_BT_L2CAP_INIT_EVT + */ + struct l2cap_init_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + } init; /*!< L2CAP callback param of ESP_BT_L2CAP_INIT_EVT */ + + /** + * @brief ESP_BT_L2CAP_UNINIT_EVT + */ + struct l2cap_uninit_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + } uninit; /*!< L2CAP callback param of ESP_BT_L2CAP_UNINIT_EVT */ + + /** + * @brief ESP_BT_L2CAP_OPEN_EVT + */ + struct l2cap_open_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + int fd; /*!< File descriptor */ + esp_bd_addr_t rem_bda; /*!< The peer address */ + int32_t tx_mtu; /*!< The transmit MTU */ + } open; /*!< L2CAP callback param of ESP_BT_L2CAP_OPEN_EVT */ + + /** + * @brief ESP_BT_L2CAP_CLOSE_EVT + */ + struct l2cap_close_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + bool async; /*!< FALSE, if local initiates disconnect */ + } close; /*!< L2CAP callback param of ESP_BT_L2CAP_CLOSE_EVT */ + + /** + * @brief ESP_BT_L2CAP_START_EVT + */ + struct l2cap_start_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + uint8_t sec_id; /*!< security ID used by this server */ + } start; /*!< L2CAP callback param of ESP_BT_L2CAP_START_EVT */ + + /** + * @brief ESP_BT_L2CAP_CL_INIT_EVT + */ + struct l2cap_cl_init_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + uint8_t sec_id; /*!< security ID used by this server */ + } cl_init; /*!< L2CAP callback param of ESP_BT_L2CAP_CL_INIT_EVT */ + + /** + * @brief ESP_BT_L2CAP_SRV_STOP_EVT + */ + struct l2cap_srv_stop_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + uint8_t psm; /*!< local psm */ + } srv_stop; /*!< L2CAP callback param of ESP_BT_L2CAP_SRV_STOP_EVT */ + +} esp_bt_l2cap_cb_param_t; + +/** + * @brief L2CAP callback function type. + * + * @param event: Event type + * @param param: Point to callback parameter, currently is union type + */ +typedef void (* esp_bt_l2cap_cb_t)(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param_t *param); + +/** + * @brief This function is called to init callbacks with L2CAP module. + * + * @param[in] callback: pointer to the init callback function. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_register_callback(esp_bt_l2cap_cb_t callback); + +/** + * @brief This function is called to init L2CAP module. + * When the operation is completed, the callback function will be called with ESP_BT_L2CAP_INIT_EVT. + * This function should be called after esp_bluedroid_enable() completes successfully. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_init(void); + +/** + * @brief This function is called to uninit l2cap module. + * The operation will close all active L2CAP connection first, then the callback function will be called + * with ESP_BT_L2CAP_CLOSE_EVT, and the number of ESP_BT_L2CAP_CLOSE_EVT is equal to the number of connection. + * When the operation is completed, the callback function will be called with ESP_BT_L2CAP_UNINIT_EVT. + * This function should be called after esp_bt_l2cap_init() completes successfully. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_deinit(void); + +/** + * @brief This function makes an L2CAP connection to a remote BD Address. + * When the connection is initiated or failed to initiate, the callback is called with ESP_BT_L2CAP_CL_INIT_EVT. + * When the connection is established or failed, the callback is called with ESP_BT_L2CAP_OPEN_EVT. + * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). + * + * @param[in] cntl_flag: Lower 16-bit security settings mask. + * @param[in] remote_psm: Remote device bluetooth Profile PSM. + * @param[in] peer_bd_addr: Remote device bluetooth device address. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_connect(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t remote_psm, esp_bd_addr_t peer_bd_addr); + +/** + * @brief This function create a L2CAP server and starts listening for an + * L2CAP connection request from a remote Bluetooth device. + * When the server is started successfully, the callback is called with ESP_BT_L2CAP_START_EVT. + * When the connection is established, the callback is called with ESP_BT_L2CAP_OPEN_EVT. + * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). + * + * @param[in] cntl_flag: Lower 16-bit security settings mask. + * @param[in] local_psm: Dynamic PSM. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_start_srv(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t local_psm); + +/** + * @brief This function stops all L2CAP servers. + * The operation will close all active L2CAP connection first, then the callback function will be called + * with ESP_BT_L2CAP_CLOSE_EVT, and the number of ESP_BT_L2CAP_CLOSE_EVT is equal to the number of connection. + * When the operation is completed, the callback is called with ESP_BT_L2CAP_SRV_STOP_EVT. + * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). + * + * @return + * - ESP_OK: success + * - other: failed + */ + +esp_err_t esp_bt_l2cap_stop_all_srv(void); + +/** + * @brief This function stops a specific L2CAP server. + * The operation will close all active L2CAP connection first on the specific L2CAP server, then the callback function will + * be called with ESP_BT_L2CAP_CLOSE_EVT, and the number of ESP_BT_L2CAP_CLOSE_EVT is equal to the number of connection. + * When the operation is completed, the callback is called with ESP_BT_L2CAP_SRV_STOP_EVT. + * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). + * + * @param[in] local_psm: Dynamic PSM. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm); + +/** + * @brief This function is used to register VFS. + * Only supports write, read and close. + * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_vfs_register(void); + +/** + * @brief This function is used to unregister VFS. + * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_bt_l2cap_vfs_unregister(void); + +#ifdef __cplusplus +} +#endif + +#endif ///__ESP_L2CAP_BT_API_H__ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h b/lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h new file mode 100644 index 00000000..14741e74 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h @@ -0,0 +1,271 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_SDP_API_H__ +#define __ESP_SDP_API_H__ + +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_SDP_SERVER_NAME_MAX 32 /*!< Service name max length */ +#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 /*!< OPP supported format list maximum length */ + +typedef enum { + ESP_SDP_SUCCESS = 0, /*!< Successful operation. */ + ESP_SDP_FAILURE, /*!< Generic failure. */ + ESP_SDP_NO_RESOURCE, /*!< No more resource */ + ESP_SDP_NEED_INIT, /*!< SDP module shall init first */ + ESP_SDP_NEED_DEINIT, /*!< SDP module shall deinit first */ + ESP_SDP_NO_CREATE_RECORD, /*!< No record created */ +} esp_sdp_status_t; + +/** + * @brief SDP callback function events + */ +typedef enum { + ESP_SDP_INIT_EVT = 0, /*!< When SDP is initialized, the event comes */ + ESP_SDP_DEINIT_EVT = 1, /*!< When SDP is deinitialized, the event comes */ + ESP_SDP_SEARCH_COMP_EVT = 2, /*!< When SDP search complete, the event comes */ + ESP_SDP_CREATE_RECORD_COMP_EVT = 3, /*!< When create SDP records complete, the event comes */ + ESP_SDP_REMOVE_RECORD_COMP_EVT = 4, /*!< When remove a SDP record complete, the event comes */ +} esp_sdp_cb_event_t; + +/** + * @brief SDP record type + */ +typedef enum { + ESP_SDP_TYPE_RAW, /*!< Used to carry raw SDP search data for unknown UUIDs */ + ESP_SDP_TYPE_MAP_MAS, /*!< Message Access Profile - Server */ + ESP_SDP_TYPE_MAP_MNS, /*!< Message Access Profile - Client (Notification Server) */ + ESP_SDP_TYPE_PBAP_PSE, /*!< Phone Book Profile - Server */ + ESP_SDP_TYPE_PBAP_PCE, /*!< Phone Book Profile - Client */ + ESP_SDP_TYPE_OPP_SERVER, /*!< Object Push Profile */ + ESP_SDP_TYPE_SAP_SERVER /*!< SIM Access Profile */ +} esp_bluetooth_sdp_types_t; + +/** + * @brief Some signals need additional pointers, hence we introduce a + * generic way to handle these pointers. + */ +typedef struct bluetooth_sdp_hdr_overlay { + esp_bluetooth_sdp_types_t type; /*!< SDP type */ + esp_bt_uuid_t uuid; /*!< UUID type, include uuid and uuid length */ + uint32_t service_name_length; /*!< Service name length */ + char *service_name; /*!< service name */ + int32_t rfcomm_channel_number; /*!< rfcomm channel number, if not used set to -1*/ + int32_t l2cap_psm; /*!< l2cap psm, if not used set to -1 */ + int32_t profile_version; /*!< profile version */ + + // User pointers, only used for some signals - see esp_bluetooth_sdp_ops_record_t + int user1_ptr_len; /*!< see esp_bluetooth_sdp_ops_record_t */ + uint8_t *user1_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */ + int user2_ptr_len; /*!< see esp_bluetooth_sdp_ops_record_t */ + uint8_t *user2_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */ +} esp_bluetooth_sdp_hdr_overlay_t; + +/** + * @brief Message Access Profile - Server parameters + */ +typedef struct bluetooth_sdp_mas_record { + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + uint32_t mas_instance_id; /*!< MAS Instance ID */ + uint32_t supported_features; /*!< Map supported features */ + uint32_t supported_message_types; /*!< Supported message types */ +} esp_bluetooth_sdp_mas_record_t; + +/** + * @brief Message Access Profile - Client (Notification Server) parameters + */ +typedef struct bluetooth_sdp_mns_record { + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + uint32_t supported_features; /*!< Supported features */ +} esp_bluetooth_sdp_mns_record_t; + +/** + * @brief Phone Book Profile - Server parameters + */ +typedef struct bluetooth_sdp_pse_record { + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + uint32_t supported_features; /*!< Pbap Supported Features */ + uint32_t supported_repositories; /*!< Supported Repositories */ +} esp_bluetooth_sdp_pse_record_t; + +/** + * @brief Phone Book Profile - Client parameters + */ +typedef struct bluetooth_sdp_pce_record { + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ +} esp_bluetooth_sdp_pce_record_t; + +/** + * @brief Object Push Profile parameters + */ +typedef struct bluetooth_sdp_ops_record { + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + int supported_formats_list_len; /*!< Supported formats list length */ + uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; /*!< Supported formats list */ +} esp_bluetooth_sdp_ops_record_t; + +/** + * @brief SIM Access Profile parameters + */ +typedef struct bluetooth_sdp_sap_record { + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ +} esp_bluetooth_sdp_sap_record_t; + +/** + * @brief SDP record parameters union + */ +typedef union { + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + esp_bluetooth_sdp_mas_record_t mas; /*!< Message Access Profile - Server */ + esp_bluetooth_sdp_mns_record_t mns; /*!< Message Access Profile - Client (Notification Server) */ + esp_bluetooth_sdp_pse_record_t pse; /*!< Phone Book Profile - Server */ + esp_bluetooth_sdp_pce_record_t pce; /*!< Phone Book Profile - Client */ + esp_bluetooth_sdp_ops_record_t ops; /*!< Object Push Profile */ + esp_bluetooth_sdp_sap_record_t sap; /*!< SIM Access Profile */ +} esp_bluetooth_sdp_record_t; + +/** + * @brief SDP callback parameters union + */ +typedef union { + /** + * @brief ESP_SDP_INIT_EVT + */ + struct sdp_init_evt_param { + esp_sdp_status_t status; /*!< status */ + } init; /*!< SDP callback param of ESP_SDP_INIT_EVT */ + + /** + * @brief ESP_SDP_DEINIT_EVT + */ + struct sdp_deinit_evt_param { + esp_sdp_status_t status; /*!< status */ + } deinit; /*!< SDP callback param of ESP_SDP_DEINIT_EVT */ + + /** + * @brief ESP_SDP_SEARCH_COMP_EVT + */ + struct sdp_search_evt_param { + esp_sdp_status_t status; /*!< status */ + esp_bd_addr_t remote_addr; /*!< remote device address */ + esp_bt_uuid_t sdp_uuid; /*!< service uuid */ + int record_count; /*!< Number of SDP records */ + esp_bluetooth_sdp_record_t *records;/*!< SDP records */ + } search; /*!< SDP callback param of ESP_SDP_SEARCH_COMP_EVT */ + + /** + * @brief ESP_SDP_CREATE_RECORD_COMP_EVT + */ + struct sdp_crate_record_evt_param { + esp_sdp_status_t status; /*!< status */ + int record_handle; /*!< SDP record handle */ + } create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */ + + /** + * @brief ESP_SDP_REMOVE_RECORD_COMP_EVT + */ + struct sdp_remove_record_evt_param { + esp_sdp_status_t status; /*!< status */ + } remove_record; /*!< SDP callback param of ESP_SDP_REMOVE_RECORD_COMP_EVT */ + +} esp_sdp_cb_param_t; /*!< SDP callback parameter union type */ + + +/** + * @brief SDP callback function type. + * + * @param event: Event type + * @param param: Point to callback parameter, currently is union type + */ +typedef void (* esp_sdp_cb_t)(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param); + +/** + * @brief This function is called to init callbacks with SDP module. + * + * @param[in] callback: pointer to the init callback function. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_sdp_register_callback(esp_sdp_cb_t callback); + +/** + * @brief This function is called to init SDP module. + * When the operation is completed, the callback function will be called with ESP_SDP_INIT_EVT. + * This function should be called after esp_bluedroid_enable() completes successfully. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_sdp_init(void); + +/** + * @brief This function is called to de-initialize SDP module. + * The operation will remove all SDP records, then the callback function will be called + * with ESP_SDP_REMOVE_RECORD_COMP_EVT, and the number of ESP_SDP_REMOVE_RECORD_COMP_EVT is + * equal to the number of SDP records.When the operation is completed, the callback function + * will be called with ESP_SDP_DEINIT_EVT. This function should be called after esp_sdp_init() + * completes successfully. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_sdp_deinit(void); + +/** + * @brief This function is called to performs service discovery for the services provided by the given peer device. + * When the operation is completed, the callback function will be called with ESP_SDP_SEARCH_COMP_EVT. + * This function must be called after esp_sdp_init() successful and before esp_sdp_deinit(). + * + * @param[in] bd_addr: Remote device bluetooth device address. + * @param[in] uuid: Service UUID of the remote device. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_sdp_search_record(esp_bd_addr_t bd_addr, esp_bt_uuid_t uuid); + +/** + * @brief This function is called to create SDP records. + * When the operation is completed, the callback function will be called with ESP_SDP_CREATE_RECORD_COMP_EVT. + * This function must be called after esp_sdp_init() successful and before esp_sdp_deinit(). + * + * @param[in] record: The SDP record to create. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record); + +/** + * @brief This function is called to remove a SDP record. + * When the operation is completed, the callback function will be called with ESP_SDP_REMOVE_RECORD_COMP_EVT. + * This function must be called after esp_sdp_init() successful and before esp_sdp_deinit(). + * + * @param[in] record_handle: The SDP record handle. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_sdp_remove_record(int record_handle); + +#ifdef __cplusplus +} +#endif + +#endif ///__ESP_SDP_API_H__ diff --git a/lib/bt/host/bluedroid/api/include/api/esp_spp_api.h b/lib/bt/host/bluedroid/api/include/api/esp_spp_api.h new file mode 100644 index 00000000..d2a0e090 --- /dev/null +++ b/lib/bt/host/bluedroid/api/include/api/esp_spp_api.h @@ -0,0 +1,439 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_SPP_API_H__ +#define __ESP_SPP_API_H__ + +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_SPP_MAX_MTU (3*330) /*!< SPP max MTU */ +#define ESP_SPP_MAX_SCN 31 /*!< SPP max SCN */ +#define ESP_SPP_MIN_TX_BUFFER_SIZE 100 /*!< SPP min tx buffer */ +#define ESP_SPP_MAX_TX_BUFFER_SIZE (ESP_SPP_MAX_MTU * 10) /*!< SPP max tx buffer size */ + +/** + * @brief SPP default configuration + */ +#define BT_SPP_DEFAULT_CONFIG() { \ + .mode = ESP_SPP_MODE_VFS, \ + .enable_l2cap_ertm = true, \ + .tx_buffer_size = ESP_SPP_MAX_TX_BUFFER_SIZE, \ +} + +/* Security Setting Mask +Use these three mask modes on both sides: +1. ESP_SPP_SEC_NONE +2. ESP_SPP_SEC_AUTHENTICATE +3. (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) +Use these three mask modes only on acceptor side: +1. ESP_SPP_SEC_IN_16_DIGITS +2. (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) +3. (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) +Due to certain limitations, do not use these mask modes: +1. ESP_SPP_SEC_AUTHORIZE +2. ESP_SPP_SEC_MODE4_LEVEL4 +3. ESP_SPP_SEC_MITM +*/ +#define ESP_SPP_SEC_NONE 0x0000 /*!< No security. relate to BTA_SEC_NONE in bta/bta_api.h */ +#define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta/bta_api.h*/ +#define ESP_SPP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required. relate to BTA_SEC_AUTHENTICATE in bta/bta_api.h*/ +#define ESP_SPP_SEC_ENCRYPT 0x0024 /*!< Encryption required. relate to BTA_SEC_ENCRYPT in bta/bta_api.h*/ +#define ESP_SPP_SEC_MODE4_LEVEL4 0x0040 /*!< Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption relate to BTA_SEC_MODE4_LEVEL4 in bta/bta_api.h*/ +#define ESP_SPP_SEC_MITM 0x3000 /*!< Man-In-The_Middle protection relate to BTA_SEC_MITM in bta/bta_api.h*/ +#define ESP_SPP_SEC_IN_16_DIGITS 0x4000 /*!< Min 16 digit for pin code relate to BTA_SEC_IN_16_DIGITS in bta/bta_api.h*/ +typedef uint16_t esp_spp_sec_t; + +typedef enum { + ESP_SPP_SUCCESS = 0, /*!< Successful operation. */ + ESP_SPP_FAILURE, /*!< Generic failure. */ + ESP_SPP_BUSY, /*!< Temporarily can not handle this request. */ + ESP_SPP_NO_DATA, /*!< No data */ + ESP_SPP_NO_RESOURCE, /*!< No more resource */ + ESP_SPP_NEED_INIT, /*!< SPP module shall init first */ + ESP_SPP_NEED_DEINIT, /*!< SPP module shall deinit first */ + ESP_SPP_NO_CONNECTION, /*!< Connection may have been closed */ + ESP_SPP_NO_SERVER, /*!< No SPP server */ +} esp_spp_status_t; + +typedef enum { + ESP_SPP_ROLE_MASTER = 0, /*!< Role: master */ + ESP_SPP_ROLE_SLAVE = 1, /*!< Role: slave */ +} esp_spp_role_t; + +typedef enum { + ESP_SPP_MODE_CB = 0, /*!< When data is coming, a callback will come with data */ + ESP_SPP_MODE_VFS = 1, /*!< Use VFS to write/read data */ +} esp_spp_mode_t; + +/** + * @brief SPP configuration parameters + */ +typedef struct { + esp_spp_mode_t mode; /*!< Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. */ + bool enable_l2cap_ertm; /*!< Enable/disable Logical Link Control and Adaptation Layer Protocol enhanced retransmission mode. */ + uint16_t tx_buffer_size; /*!< Tx buffer size for a new SPP channel. A smaller setting can save memory, but may incur a decrease in throughput. Only for ESP_SPP_MODE_VFS mode. */ +} esp_spp_cfg_t; + +/** + * @brief SPP callback function events + */ +typedef enum { + ESP_SPP_INIT_EVT = 0, /*!< When SPP is initialized, the event comes */ + ESP_SPP_UNINIT_EVT = 1, /*!< When SPP is deinitialized, the event comes */ + ESP_SPP_DISCOVERY_COMP_EVT = 8, /*!< When SDP discovery complete, the event comes */ + ESP_SPP_OPEN_EVT = 26, /*!< When SPP Client connection open, the event comes */ + ESP_SPP_CLOSE_EVT = 27, /*!< When SPP connection closed, the event comes */ + ESP_SPP_START_EVT = 28, /*!< When SPP server started, the event comes */ + ESP_SPP_CL_INIT_EVT = 29, /*!< When SPP client initiated a connection, the event comes */ + ESP_SPP_DATA_IND_EVT = 30, /*!< When SPP connection received data, the event comes, only for ESP_SPP_MODE_CB */ + ESP_SPP_CONG_EVT = 31, /*!< When SPP connection congestion status changed, the event comes, only for ESP_SPP_MODE_CB */ + ESP_SPP_WRITE_EVT = 33, /*!< When SPP write operation completes, the event comes, only for ESP_SPP_MODE_CB */ + ESP_SPP_SRV_OPEN_EVT = 34, /*!< When SPP Server connection open, the event comes */ + ESP_SPP_SRV_STOP_EVT = 35, /*!< When SPP server stopped, the event comes */ + ESP_SPP_VFS_REGISTER_EVT = 36, /*!< When SPP VFS register, the event comes */ + ESP_SPP_VFS_UNREGISTER_EVT = 37, /*!< When SPP VFS unregister, the event comes */ +} esp_spp_cb_event_t; + + +/** + * @brief SPP callback parameters union + */ +typedef union { + /** + * @brief SPP_INIT_EVT + */ + struct spp_init_evt_param { + esp_spp_status_t status; /*!< status */ + } init; /*!< SPP callback param of SPP_INIT_EVT */ + + /** + * @brief SPP_UNINIT_EVT + */ + struct spp_uninit_evt_param { + esp_spp_status_t status; /*!< status */ + } uninit; /*!< SPP callback param of SPP_UNINIT_EVT */ + + /** + * @brief SPP_DISCOVERY_COMP_EVT + */ + struct spp_discovery_comp_evt_param { + esp_spp_status_t status; /*!< status */ + uint8_t scn_num; /*!< The num of scn_num */ + uint8_t scn[ESP_SPP_MAX_SCN]; /*!< channel # */ + const char *service_name[ESP_SPP_MAX_SCN]; /*!< service_name */ + } disc_comp; /*!< SPP callback param of SPP_DISCOVERY_COMP_EVT */ + + /** + * @brief ESP_SPP_OPEN_EVT + */ + struct spp_open_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + int fd; /*!< The file descriptor only for ESP_SPP_MODE_VFS */ + esp_bd_addr_t rem_bda; /*!< The peer address */ + } open; /*!< SPP callback param of ESP_SPP_OPEN_EVT */ + + /** + * @brief ESP_SPP_SRV_OPEN_EVT + */ + struct spp_srv_open_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + uint32_t new_listen_handle; /*!< The new listen handle */ + int fd; /*!< The file descriptor only for ESP_SPP_MODE_VFS */ + esp_bd_addr_t rem_bda; /*!< The peer address */ + } srv_open; /*!< SPP callback param of ESP_SPP_SRV_OPEN_EVT */ + /** + * @brief ESP_SPP_CLOSE_EVT + */ + struct spp_close_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t port_status; /*!< PORT status */ + uint32_t handle; /*!< The connection handle */ + bool async; /*!< FALSE, if local initiates disconnect */ + } close; /*!< SPP callback param of ESP_SPP_CLOSE_EVT */ + + /** + * @brief ESP_SPP_START_EVT + */ + struct spp_start_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + uint8_t sec_id; /*!< security ID used by this server */ + uint8_t scn; /*!< Server channel number */ + bool use_co; /*!< TRUE to use co_rfc_data */ + } start; /*!< SPP callback param of ESP_SPP_START_EVT */ + + /** + * @brief ESP_SPP_SRV_STOP_EVT + */ + struct spp_srv_stop_evt_param { + esp_spp_status_t status; /*!< status */ + uint8_t scn; /*!< Server channel number */ + } srv_stop; /*!< SPP callback param of ESP_SPP_SRV_STOP_EVT */ + + /** + * @brief ESP_SPP_CL_INIT_EVT + */ + struct spp_cl_init_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + uint8_t sec_id; /*!< security ID used by this server */ + bool use_co; /*!< TRUE to use co_rfc_data */ + } cl_init; /*!< SPP callback param of ESP_SPP_CL_INIT_EVT */ + + /** + * @brief ESP_SPP_WRITE_EVT + */ + struct spp_write_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + int len; /*!< The length of the data written. */ + bool cong; /*!< congestion status */ + } write; /*!< SPP callback param of ESP_SPP_WRITE_EVT */ + + /** + * @brief ESP_SPP_DATA_IND_EVT + */ + struct spp_data_ind_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + uint16_t len; /*!< The length of data */ + uint8_t *data; /*!< The data received */ + } data_ind; /*!< SPP callback param of ESP_SPP_DATA_IND_EVT */ + + /** + * @brief ESP_SPP_CONG_EVT + */ + struct spp_cong_evt_param { + esp_spp_status_t status; /*!< status */ + uint32_t handle; /*!< The connection handle */ + bool cong; /*!< TRUE, congested. FALSE, uncongested */ + } cong; /*!< SPP callback param of ESP_SPP_CONG_EVT */ + + /** + * @brief ESP_SPP_VFS_REGISTER_EVT + */ + struct spp_vfs_register_evt_param { + esp_spp_status_t status; /*!< status */ + } vfs_register; /*!< SPP callback param of ESP_SPP_VFS_REGISTER_EVT */ + + /** + * @brief ESP_SPP_VFS_UNREGISTER_EVT + */ + struct spp_vfs_unregister_evt_param { + esp_spp_status_t status; /*!< status */ + } vfs_unregister; /*!< SPP callback param of ESP_SPP_VFS_UNREGISTER_EVT */ +} esp_spp_cb_param_t; /*!< SPP callback parameter union type */ + +/** + * @brief SPP callback function type. + * When handle ESP_SPP_DATA_IND_EVT, it is strongly recommended to cache incoming data, and process them in + * other lower priority application task rather than in this callback directly. + * + * @param event: Event type + * @param param: Point to callback parameter, currently is union type + */ +typedef void (*esp_spp_cb_t)(esp_spp_cb_event_t event, esp_spp_cb_param_t *param); + +/** + * @brief This function is called to init callbacks with SPP module. + * + * @param[in] callback: pointer to the init callback function. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_register_callback(esp_spp_cb_t callback); + +/** + * @brief This function is called to init SPP module. + * When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT. + * This function should be called after esp_bluedroid_enable() completes successfully. + * + * @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_init(esp_spp_mode_t mode) __attribute__((deprecated("Please use esp_spp_enhanced_init"))); + + +/** + * @brief This function is called to init SPP module. + * When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT. + * This function should be called after esp_bluedroid_enable() completes successfully. + * + * @param[in] cfg: SPP configuration. + * + * @note The member variable enable_l2cap_etrm in esp_spp_cfg_t can affect all L2CAP channel + * configurations of the upper layer RFCOMM protocol. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg); + +/** + * @brief This function is called to uninit SPP module. + * The operation will close all active SPP connection first, then the callback function will be called + * with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. + * When the operation is completed, the callback function will be called with ESP_SPP_UNINIT_EVT. + * This function should be called after esp_spp_init()/esp_spp_enhanced_init() completes successfully. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_deinit(void); + + +/** + * @brief This function is called to performs service discovery for the services provided by the given peer device. + * When the operation is completed, the callback function will be called with ESP_SPP_DISCOVERY_COMP_EVT. + * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). + * + * @param[in] bd_addr: Remote device bluetooth device address. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr); + +/** + * @brief This function makes an SPP connection to a remote BD Address. + * When the connection is initiated or failed to initiate, the callback is called with ESP_SPP_CL_INIT_EVT. + * When the connection is established or failed, the callback is called with ESP_SPP_OPEN_EVT. + * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). + * + * @param[in] sec_mask: Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only. + * @param[in] role: Master or slave. + * @param[in] remote_scn: Remote device bluetooth device SCN. + * @param[in] peer_bd_addr: Remote device bluetooth device address. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr); + +/** + * @brief This function closes an SPP connection. + * When the operation is completed, the callback function will be called with ESP_SPP_CLOSE_EVT. + * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). + * + * @param[in] handle: The connection handle. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_disconnect(uint32_t handle); + +/** + * @brief This function create a SPP server and starts listening for an + * SPP connection request from a remote Bluetooth device. + * When the server is started successfully, the callback is called with ESP_SPP_START_EVT. + * When the connection is established, the callback is called with ESP_SPP_SRV_OPEN_EVT. + * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). + * + * @param[in] sec_mask: Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only. + * @param[in] role: Master or slave. + * @param[in] local_scn: The specific channel you want to get. + * If channel is 0, means get any channel. + * @param[in] name: Server's name. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t local_scn, const char *name); + +/** + * @brief This function stops all SPP servers. + * The operation will close all active SPP connection first, then the callback function will be called + * with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. + * When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT. + * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). + * + * @return + * - ESP_OK: success + * - other: failed + */ + +esp_err_t esp_spp_stop_srv(void); + +/** + * @brief This function stops a specific SPP server. + * The operation will close all active SPP connection first on the specific SPP server, then the callback function will be called + * with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection. + * When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT. + * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). + * + * @param[in] scn: Server channel number. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_stop_srv_scn(uint8_t scn); + +/** + * @brief This function is used to write data, only for ESP_SPP_MODE_CB. + * When this function need to be called repeatedly, it is strongly recommended to call this function again after + * the previous event ESP_SPP_WRITE_EVT is received and the parameter 'cong' is equal to false. If the previous event + * ESP_SPP_WRITE_EVT with parameter 'cong' is equal to true, the function can only be called again when the event + * ESP_SPP_CONG_EVT with parameter 'cong' equal to false is received. + * This function must be called after an connection between initiator and acceptor has been established. + * + * @param[in] handle: The connection handle. + * @param[in] len: The length of the data written. + * @param[in] p_data: The data written. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data); + + +/** + * @brief This function is used to register VFS. + * For now, SPP only supports write, read and close. + * When the operation is completed, the callback function will be called with ESP_SPP_VFS_REGISTER_EVT. + * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_vfs_register(void); + +/** + * @brief This function is used to unregister VFS. + * When the operation is completed, the callback function will be called with ESP_SPP_VFS_UNREGISTER_EVT. + * This function must be called after esp_spp_vfs_register() successful and before esp_spp_deinit(). + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_vfs_unregister(void); + +#ifdef __cplusplus +} +#endif + +#endif ///__ESP_SPP_API_H__ |
