summaryrefslogtreecommitdiff
path: root/lib/bt/host/bluedroid/api
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-03-28 14:32:49 +1100
committerjacqueline <me@jacqueline.id.au>2024-03-28 14:32:49 +1100
commitee29c25b29eaa4fac4e897442634b69ecc8d8125 (patch)
tree8c5f1a140463f20f104316fa3492984e191154e9 /lib/bt/host/bluedroid/api
parent239e6d89507a24c849385f4bfa93ac4ad58e5de5 (diff)
downloadtangara-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')
-rw-r--r--lib/bt/host/bluedroid/api/esp_a2dp_api.c353
-rw-r--r--lib/bt/host/bluedroid/api/esp_avrc_api.c477
-rw-r--r--lib/bt/host/bluedroid/api/esp_bluedroid_hci.c89
-rw-r--r--lib/bt/host/bluedroid/api/esp_bt_device.c78
-rw-r--r--lib/bt/host/bluedroid/api/esp_bt_main.c230
-rw-r--r--lib/bt/host/bluedroid/api/esp_gap_ble_api.c1601
-rw-r--r--lib/bt/host/bluedroid/api/esp_gap_bt_api.c497
-rw-r--r--lib/bt/host/bluedroid/api/esp_gatt_common_api.c75
-rw-r--r--lib/bt/host/bluedroid/api/esp_gattc_api.c786
-rw-r--r--lib/bt/host/bluedroid/api/esp_gatts_api.c442
-rw-r--r--lib/bt/host/bluedroid/api/esp_hf_ag_api.c578
-rw-r--r--lib/bt/host/bluedroid/api/esp_hf_client_api.c561
-rw-r--r--lib/bt/host/bluedroid/api/esp_hidd_api.c170
-rw-r--r--lib/bt/host/bluedroid/api/esp_hidh_api.c250
-rw-r--r--lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c131
-rw-r--r--lib/bt/host/bluedroid/api/esp_sdp_api.c130
-rw-r--r--lib/bt/host/bluedroid/api/esp_spp_api.c255
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h463
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h736
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h84
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h205
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_bt_device.h99
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_bt_main.h99
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h2547
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h916
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h48
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h485
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h913
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h600
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h716
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h736
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h246
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h413
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h482
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h251
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h271
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_spp_api.h439
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__