Merge branch 'feat/add_ble_50_protocomm_v6.1' into 'release/v6.1'

feat(protocomm): Add support for BLE 5 for bluedroid (v6.1)

See merge request espressif/esp-idf!51226
This commit is contained in:
Jiang Jiang Jian
2026-08-31 11:17:11 +08:00
3 changed files with 277 additions and 9 deletions

View File

@@ -26,10 +26,50 @@ static const char *TAG = "simple_ble";
static simple_ble_cfg_t *g_ble_cfg_p;
static uint16_t *g_gatt_table_map;
static uint8_t adv_config_done;
#if SIMPLE_BLE_LEGACY_ADV || SIMPLE_BLE_EXT_ADV
static uint8_t adv_config_pending_mask;
#endif
static esp_bd_addr_t s_cached_remote_bda = {0x0,};
#define adv_config_flag (1 << 0)
#define scan_rsp_config_flag (1 << 1)
#if SIMPLE_BLE_LEGACY_ADV
#define ADV_CONFIG_FLAG (1 << 0)
#define SCAN_RSP_CONFIG_FLAG (1 << 1)
#elif SIMPLE_BLE_EXT_ADV
#define SIMPLE_BLE_EXT_ADV_INSTANCE 0
#define EXT_ADV_PARAMS_CONFIG_FLAG (1 << 0)
#define EXT_ADV_DATA_CONFIG_FLAG (1 << 1)
#define EXT_SCAN_RSP_CONFIG_FLAG (1 << 2)
#define EXT_ADV_RAND_ADDR_CONFIG_FLAG (1 << 3)
static esp_ble_gap_ext_adv_params_t s_ext_adv_params = {
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND,
.interval_min = 0x100,
.interval_max = 0x100,
.channel_map = ADV_CHNL_ALL,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
.tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE,
.primary_phy = ESP_BLE_GAP_PHY_1M,
.max_skip = 0,
.secondary_phy = ESP_BLE_GAP_PHY_1M,
.sid = 0,
.scan_req_notif = false,
};
static const esp_ble_gap_ext_adv_t s_ext_adv = {
.instance = SIMPLE_BLE_EXT_ADV_INSTANCE,
.duration = 0,
.max_events = 0,
};
static void simple_ble_ext_adv_start(void)
{
esp_err_t err = esp_ble_gap_ext_adv_start(1, &s_ext_adv);
if (err != ESP_OK) {
ESP_LOGE(TAG, "ext_adv_start failed, error code = 0x%x", err);
}
}
#endif
uint8_t get_keep_ble_on()
{
@@ -59,6 +99,7 @@ const uint8_t *simple_ble_get_uuid128(uint16_t handle)
return NULL;
}
#if SIMPLE_BLE_LEGACY_ADV
static void simple_ble_set_random_addr_if_configured(void)
{
if (g_ble_cfg_p->ble_addr == NULL) {
@@ -72,6 +113,7 @@ static void simple_ble_set_random_addr_if_configured(void)
ESP_LOGW(TAG, "Failed to set random address, using configured address type");
}
}
#endif
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
@@ -80,24 +122,83 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
}
switch (event) {
#if SIMPLE_BLE_LEGACY_ADV
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
adv_config_done &= (~adv_config_flag);
if (param->adv_data_cmpl.status != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(TAG, "adv_data_set failed, status %d", param->adv_data_cmpl.status);
break;
}
adv_config_pending_mask &= (~ADV_CONFIG_FLAG);
simple_ble_set_random_addr_if_configured();
if (adv_config_done == 0) {
if (adv_config_pending_mask == 0) {
esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
}
break;
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
adv_config_done &= (~scan_rsp_config_flag);
if (param->scan_rsp_data_cmpl.status != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(TAG, "scan_rsp_data_set failed, status %d", param->scan_rsp_data_cmpl.status);
break;
}
adv_config_pending_mask &= (~SCAN_RSP_CONFIG_FLAG);
simple_ble_set_random_addr_if_configured();
if (adv_config_done == 0) {
if (adv_config_pending_mask == 0) {
esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
}
break;
#elif SIMPLE_BLE_EXT_ADV
case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
if (param->ext_adv_set_params.status != ESP_BT_STATUS_SUCCESS ||
param->ext_adv_set_params.instance != SIMPLE_BLE_EXT_ADV_INSTANCE) {
ESP_LOGE(TAG, "ext_adv_set_params failed, status %d, instance %d",
param->ext_adv_set_params.status, param->ext_adv_set_params.instance);
break;
}
adv_config_pending_mask &= (~EXT_ADV_PARAMS_CONFIG_FLAG);
if (adv_config_pending_mask == 0) {
simple_ble_ext_adv_start();
}
break;
case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT:
if (param->ext_adv_set_rand_addr.status != ESP_BT_STATUS_SUCCESS ||
param->ext_adv_set_rand_addr.instance != SIMPLE_BLE_EXT_ADV_INSTANCE) {
ESP_LOGE(TAG, "ext_adv_set_rand_addr failed, status %d, instance %d",
param->ext_adv_set_rand_addr.status, param->ext_adv_set_rand_addr.instance);
break;
}
adv_config_pending_mask &= (~EXT_ADV_RAND_ADDR_CONFIG_FLAG);
if (adv_config_pending_mask == 0) {
simple_ble_ext_adv_start();
}
break;
case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT:
if (param->ext_adv_data_set.status != ESP_BT_STATUS_SUCCESS ||
param->ext_adv_data_set.instance != SIMPLE_BLE_EXT_ADV_INSTANCE) {
ESP_LOGE(TAG, "ext_adv_data_set failed, status %d, instance %d",
param->ext_adv_data_set.status, param->ext_adv_data_set.instance);
break;
}
adv_config_pending_mask &= (~EXT_ADV_DATA_CONFIG_FLAG);
if (adv_config_pending_mask == 0) {
simple_ble_ext_adv_start();
}
break;
case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
if (param->scan_rsp_set.status != ESP_BT_STATUS_SUCCESS ||
param->scan_rsp_set.instance != SIMPLE_BLE_EXT_ADV_INSTANCE) {
ESP_LOGE(TAG, "ext_scan_rsp_data_set failed, status %d, instance %d",
param->scan_rsp_set.status, param->scan_rsp_set.instance);
break;
}
adv_config_pending_mask &= (~EXT_SCAN_RSP_CONFIG_FLAG);
if (adv_config_pending_mask == 0) {
simple_ble_ext_adv_start();
}
break;
#endif
case ESP_GAP_BLE_SEC_REQ_EVT:
esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
break;
@@ -145,18 +246,65 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
ESP_LOGE(TAG, "set device name failed, error code = 0x%x", ret);
return;
}
#if SIMPLE_BLE_LEGACY_ADV
ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->adv_data_p);
if (ret) {
ESP_LOGE(TAG, "config raw adv data failed, error code = 0x%x ", ret);
return;
}
adv_config_done |= adv_config_flag;
adv_config_pending_mask |= ADV_CONFIG_FLAG;
ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->scan_rsp_data_p);
if (ret) {
ESP_LOGE(TAG, "config raw scan rsp data failed, error code = 0x%x", ret);
return;
}
adv_config_done |= scan_rsp_config_flag;
adv_config_pending_mask |= SCAN_RSP_CONFIG_FLAG;
#elif SIMPLE_BLE_EXT_ADV
s_ext_adv_params.own_addr_type = BLE_ADDR_TYPE_PUBLIC;
if (g_ble_cfg_p->ble_addr != NULL) {
s_ext_adv_params.own_addr_type = BLE_ADDR_TYPE_RANDOM;
}
/* Pre-set all expected flags before the first async call. */
adv_config_pending_mask = EXT_ADV_PARAMS_CONFIG_FLAG |
EXT_ADV_DATA_CONFIG_FLAG |
EXT_SCAN_RSP_CONFIG_FLAG;
if (g_ble_cfg_p->ble_addr != NULL) {
adv_config_pending_mask |= EXT_ADV_RAND_ADDR_CONFIG_FLAG;
}
ret = esp_ble_gap_ext_adv_set_params(SIMPLE_BLE_EXT_ADV_INSTANCE, &s_ext_adv_params);
if (ret) {
ESP_LOGE(TAG, "ext_adv_set_params failed, error code = 0x%x", ret);
return;
}
if (g_ble_cfg_p->ble_addr != NULL) {
esp_bd_addr_t rand_addr;
memcpy(rand_addr, g_ble_cfg_p->ble_addr, sizeof(esp_bd_addr_t));
ret = esp_ble_gap_ext_adv_set_rand_addr(SIMPLE_BLE_EXT_ADV_INSTANCE, rand_addr);
if (ret) {
ESP_LOGE(TAG, "ext_adv_set_rand_addr failed, error code = 0x%x", ret);
return;
}
}
ret = esp_ble_gap_config_ext_adv_data_raw(SIMPLE_BLE_EXT_ADV_INSTANCE,
g_ble_cfg_p->raw_adv_data_len,
g_ble_cfg_p->raw_adv_data_p);
if (ret) {
ESP_LOGE(TAG, "config_ext_adv_data_raw failed, error code = 0x%x", ret);
return;
}
ret = esp_ble_gap_config_ext_scan_rsp_data_raw(SIMPLE_BLE_EXT_ADV_INSTANCE,
g_ble_cfg_p->raw_scan_rsp_data_len,
g_ble_cfg_p->raw_scan_rsp_data_p);
if (ret) {
ESP_LOGE(TAG, "config_ext_scan_rsp_data_raw failed, error code = 0x%x", ret);
return;
}
#endif
break;
case ESP_GATTS_READ_EVT:
if (g_ble_cfg_p && g_ble_cfg_p->read_fn) {
@@ -207,7 +355,11 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
}
memset(s_cached_remote_bda, 0, sizeof(esp_bd_addr_t));
if (g_ble_cfg_p) {
#if SIMPLE_BLE_LEGACY_ADV
esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
#elif SIMPLE_BLE_EXT_ADV
simple_ble_ext_adv_start();
#endif
}
break;
case ESP_GATTS_CREAT_ATTR_TAB_EVT: {

View File

@@ -11,9 +11,16 @@
#include <stdlib.h>
#include <string.h>
#include "sdkconfig.h"
#include <esp_gap_ble_api.h>
#include <esp_gatts_api.h>
#if CONFIG_BT_BLE_42_ADV_EN
#define SIMPLE_BLE_LEGACY_ADV 1
#elif CONFIG_BT_BLE_50_EXTEND_ADV_EN
#define SIMPLE_BLE_EXT_ADV 1
#endif
typedef void (simple_ble_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t p_gatts_if, esp_ble_gatts_cb_param_t *param);
/**
@@ -24,12 +31,21 @@ typedef void (simple_ble_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t p_gatts
typedef struct {
/** Name to be displayed to devices scanning for ESP32 */
const char *device_name;
#if SIMPLE_BLE_LEGACY_ADV
/** Raw advertisement data */
esp_ble_adv_data_t *adv_data_p;
/** Raw scan response data */
esp_ble_adv_data_t *scan_rsp_data_p;
/** Parameters to configure the nature of advertising */
esp_ble_adv_params_t adv_params;
#elif SIMPLE_BLE_EXT_ADV
/** Raw advertisement data for BLE 5.0+ extended advertising */
uint8_t *raw_adv_data_p;
uint32_t raw_adv_data_len;
/** Raw scan response data for BLE 5.0+ extended advertising */
uint8_t *raw_scan_rsp_data_p;
uint32_t raw_scan_rsp_data_len;
#endif
/** Descriptor table which consists of the configuration
* required by services and characteristics */
esp_gatts_attr_db_t *gatt_db;

View File

@@ -92,6 +92,7 @@ static void protocomm_ble_reset_prepare_write(void)
}
// config adv data
#if SIMPLE_BLE_LEGACY_ADV
static esp_ble_adv_data_t adv_config = {
.set_scan_rsp = false,
.include_txpower = true,
@@ -122,6 +123,71 @@ static esp_ble_adv_params_t adv_params = {
.channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
#elif SIMPLE_BLE_EXT_ADV
#define PROTOCOMM_BLE_RAW_AD_MAX ESP_BLE_ADV_DATA_LEN_MAX
static uint8_t s_raw_adv_data[PROTOCOMM_BLE_RAW_AD_MAX];
static uint8_t s_raw_scan_rsp_data[PROTOCOMM_BLE_RAW_AD_MAX];
static uint32_t s_raw_adv_data_len;
static uint32_t s_raw_scan_rsp_data_len;
static esp_err_t protocomm_ble_build_raw_adv_data(const uint8_t *service_uuid)
{
uint32_t offset = 0;
if (offset + 3 > PROTOCOMM_BLE_RAW_AD_MAX) {
return ESP_ERR_INVALID_SIZE;
}
s_raw_adv_data[offset++] = 2;
s_raw_adv_data[offset++] = ESP_BLE_AD_TYPE_FLAG;
s_raw_adv_data[offset++] = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT);
if (offset + 2 + ESP_UUID_LEN_128 > PROTOCOMM_BLE_RAW_AD_MAX) {
return ESP_ERR_INVALID_SIZE;
}
s_raw_adv_data[offset++] = 1 + ESP_UUID_LEN_128;
s_raw_adv_data[offset++] = ESP_BLE_AD_TYPE_128SRV_CMPL;
memcpy(&s_raw_adv_data[offset], service_uuid, ESP_UUID_LEN_128);
offset += ESP_UUID_LEN_128;
s_raw_adv_data_len = offset;
return ESP_OK;
}
static esp_err_t protocomm_ble_build_raw_scan_rsp_data(const char *name,
const uint8_t *mfg_data,
size_t mfg_len)
{
uint32_t offset = 0;
size_t name_len = (name != NULL) ? strlen(name) : 0;
if (name_len > 0) {
if (name_len > ESP_BLE_ADV_NAME_LEN_MAX) {
name_len = ESP_BLE_ADV_NAME_LEN_MAX;
}
if (offset + 2 + name_len > PROTOCOMM_BLE_RAW_AD_MAX) {
return ESP_ERR_INVALID_SIZE;
}
s_raw_scan_rsp_data[offset++] = 1 + (uint8_t)name_len;
s_raw_scan_rsp_data[offset++] = ESP_BLE_AD_TYPE_NAME_CMPL;
memcpy(&s_raw_scan_rsp_data[offset], name, name_len);
offset += name_len;
}
if (mfg_data != NULL && mfg_len > 0) {
if (offset + 2 + mfg_len > PROTOCOMM_BLE_RAW_AD_MAX) {
return ESP_ERR_INVALID_SIZE;
}
s_raw_scan_rsp_data[offset++] = 1 + (uint8_t)mfg_len;
s_raw_scan_rsp_data[offset++] = ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE;
memcpy(&s_raw_scan_rsp_data[offset], mfg_data, mfg_len);
offset += mfg_len;
}
s_raw_scan_rsp_data_len = offset;
return ESP_OK;
}
#endif
static char *protocomm_ble_device_name = NULL;
static uint8_t *protocomm_ble_mfg_data = NULL;
@@ -723,8 +789,10 @@ static void protocomm_ble_cleanup(void)
free(protoble_internal->service_uuid);
protoble_internal->service_uuid = NULL;
}
#if SIMPLE_BLE_LEGACY_ADV
adv_config.p_service_uuid = NULL;
adv_config.service_uuid_len = 0;
#endif
if (protoble_internal->g_nu_lookup) {
for (size_t i = 0; i < protoble_internal->g_nu_lookup_count; i++) {
if (protoble_internal->g_nu_lookup[i].name) {
@@ -857,6 +925,7 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
protoble_internal->ble_notify = config->ble_notify;
// Config adv data
#if SIMPLE_BLE_LEGACY_ADV
adv_config.service_uuid_len = ESP_UUID_LEN_128;
protoble_internal->service_uuid = (uint8_t *)malloc(ESP_UUID_LEN_128);
if (protoble_internal->service_uuid == NULL) {
@@ -870,6 +939,30 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
// Config scan response data
scan_rsp_config.manufacturer_len = protocomm_ble_mfg_data_len;
scan_rsp_config.p_manufacturer_data = (uint8_t *) protocomm_ble_mfg_data;
#elif SIMPLE_BLE_EXT_ADV
protoble_internal->service_uuid = (uint8_t *)malloc(ESP_UUID_LEN_128);
if (protoble_internal->service_uuid == NULL) {
ESP_LOGE(TAG, "Error allocating memory for service UUID");
protocomm_ble_cleanup();
return ESP_ERR_NO_MEM;
}
memcpy(protoble_internal->service_uuid, config->service_uuid, ESP_UUID_LEN_128);
esp_err_t raw_ret = protocomm_ble_build_raw_adv_data(protoble_internal->service_uuid);
if (raw_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to build raw advertising data");
protocomm_ble_cleanup();
return raw_ret;
}
raw_ret = protocomm_ble_build_raw_scan_rsp_data(protocomm_ble_device_name,
protocomm_ble_mfg_data,
protocomm_ble_mfg_data_len);
if (raw_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to build raw scan response data");
protocomm_ble_cleanup();
return raw_ret;
}
#endif
simple_ble_cfg_t *ble_config = simple_ble_init();
if (ble_config == NULL) {
@@ -887,10 +980,17 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
ble_config->set_mtu_fn = transport_simple_ble_set_mtu;
/* Set parameters required for advertising */
#if SIMPLE_BLE_LEGACY_ADV
ble_config->adv_params = adv_params;
ble_config->adv_data_p = &adv_config;
ble_config->scan_rsp_data_p = &scan_rsp_config;
#elif SIMPLE_BLE_EXT_ADV
ble_config->raw_adv_data_p = s_raw_adv_data;
ble_config->raw_adv_data_len = s_raw_adv_data_len;
ble_config->raw_scan_rsp_data_p = s_raw_scan_rsp_data;
ble_config->raw_scan_rsp_data_len = s_raw_scan_rsp_data_len;
#endif
ble_config->device_name = protocomm_ble_device_name;
ble_config->gatt_db_count = populate_gatt_db(&ble_config->gatt_db);