mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Fix iOS advertisement response and simplify
This commit is contained in:
parent
58f378602f
commit
721a59dd31
@ -42,13 +42,13 @@ const uint8_t *simple_ble_get_uuid128(uint16_t handle)
|
||||
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
|
||||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
||||
adv_config_done &= (~adv_config_flag);
|
||||
if (adv_config_done == 0) {
|
||||
esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
|
||||
}
|
||||
break;
|
||||
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
|
||||
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
|
||||
adv_config_done &= (~scan_rsp_config_flag);
|
||||
if (adv_config_done == 0) {
|
||||
esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
|
||||
@ -91,15 +91,13 @@ 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;
|
||||
}
|
||||
ret = esp_ble_gap_config_adv_data_raw(g_ble_cfg_p->raw_adv_data_p,
|
||||
g_ble_cfg_p->raw_adv_data_len);
|
||||
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;
|
||||
ret = esp_ble_gap_config_scan_rsp_data_raw(g_ble_cfg_p->raw_scan_rsp_data_p,
|
||||
g_ble_cfg_p->raw_scan_rsp_data_len);
|
||||
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;
|
||||
|
@ -25,11 +25,9 @@ typedef struct {
|
||||
/** Name to be displayed to devices scanning for ESP32 */
|
||||
const char *device_name;
|
||||
/** Raw advertisement data */
|
||||
uint8_t *raw_adv_data_p;
|
||||
uint8_t raw_adv_data_len;
|
||||
esp_ble_adv_data_t *adv_data_p;
|
||||
/** Raw scan response data */
|
||||
uint8_t *raw_scan_rsp_data_p;
|
||||
uint8_t raw_scan_rsp_data_len;
|
||||
esp_ble_adv_data_t *scan_rsp_data_p;
|
||||
/** Parameters to configure the nature of advertising */
|
||||
esp_ble_adv_params_t adv_params;
|
||||
/** Descriptor table which consists of the configuration
|
||||
|
@ -25,7 +25,6 @@ static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
|
||||
static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
|
||||
static const uint16_t character_user_description = ESP_GATT_UUID_CHAR_DESCRIPTION;
|
||||
static const uint8_t character_prop_read_write = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE;
|
||||
static const uint8_t ble_advertisement_flags = ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
@ -52,14 +51,33 @@ typedef struct _protocomm_ble {
|
||||
ssize_t g_nu_lookup_count;
|
||||
uint16_t gatt_mtu;
|
||||
uint8_t *service_uuid;
|
||||
uint8_t *raw_adv_data_p;
|
||||
uint8_t raw_adv_data_len;
|
||||
uint8_t *raw_scan_rsp_data_p;
|
||||
uint8_t raw_scan_rsp_data_len;
|
||||
} _protocomm_ble_internal_t;
|
||||
|
||||
static _protocomm_ble_internal_t *protoble_internal;
|
||||
|
||||
// config adv data
|
||||
static esp_ble_adv_data_t adv_config = {
|
||||
.set_scan_rsp = false,
|
||||
.include_txpower = true,
|
||||
.min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
|
||||
.max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
|
||||
.appearance = 0x00,
|
||||
.manufacturer_len = 0,
|
||||
.p_manufacturer_data = NULL,
|
||||
.service_data_len = 0,
|
||||
.p_service_data = NULL,
|
||||
.service_uuid_len = 0, // Filled later
|
||||
.p_service_uuid = NULL, // Filled later
|
||||
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
|
||||
};
|
||||
// config scan response data
|
||||
static esp_ble_adv_data_t scan_rsp_config = {
|
||||
.set_scan_rsp = true,
|
||||
.include_name = true,
|
||||
.manufacturer_len = 0, // Filled later
|
||||
.p_manufacturer_data = NULL, // Filler later
|
||||
};
|
||||
|
||||
static esp_ble_adv_params_t adv_params = {
|
||||
.adv_int_min = 0x100,
|
||||
.adv_int_max = 0x100,
|
||||
@ -417,8 +435,6 @@ static void protocomm_ble_cleanup(void)
|
||||
}
|
||||
free(protoble_internal->g_nu_lookup);
|
||||
}
|
||||
free(protoble_internal->raw_adv_data_p);
|
||||
free(protoble_internal->raw_scan_rsp_data_p);
|
||||
free(protoble_internal);
|
||||
protoble_internal = NULL;
|
||||
}
|
||||
@ -491,133 +507,14 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
|
||||
protoble_internal->pc_ble = pc;
|
||||
protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE;
|
||||
|
||||
/* The BLE advertisement data (max 31 bytes) consists of:
|
||||
* 1) Flags -
|
||||
* Size : length (1 byte) + type (1 byte) + value (1 byte) = 3 bytes
|
||||
* 2) Complete 128 bit UUID of the service -
|
||||
* Size : length (1 byte) + type (1 byte) + value (16 bytes) = 18 bytes
|
||||
*
|
||||
* Remaining 31 - (3 + 18) = 10 bytes could be used for manufacturer data
|
||||
* or something else in the future.
|
||||
*/
|
||||
raw_data_info_t adv_data[] = {
|
||||
{ /* Flags */
|
||||
.type = ESP_BLE_AD_TYPE_FLAG,
|
||||
.length = sizeof(ble_advertisement_flags),
|
||||
.data_p = (uint8_t *) &ble_advertisement_flags
|
||||
},
|
||||
{ /* 128 bit Service UUID */
|
||||
.type = ESP_BLE_AD_TYPE_128SRV_CMPL,
|
||||
.length = ESP_UUID_LEN_128,
|
||||
.data_p = (uint8_t *) config->service_uuid
|
||||
},
|
||||
};
|
||||
// Config adv data
|
||||
adv_config.service_uuid_len = ESP_UUID_LEN_128;
|
||||
adv_config.p_service_uuid = (uint8_t *) config->service_uuid;
|
||||
protoble_internal->service_uuid = (uint8_t *) config->service_uuid;
|
||||
|
||||
/* Get the total raw data length required for above entries */
|
||||
uint8_t adv_data_len = 0;
|
||||
for (uint8_t i = 0; i < (sizeof(adv_data) / sizeof(adv_data[0])); i++) {
|
||||
/* Add extra bytes required per entry, i.e.
|
||||
* length (1 byte) + type (1 byte) = 2 bytes */
|
||||
adv_data_len += adv_data[i].length + 2;
|
||||
}
|
||||
if (adv_data_len > ESP_BLE_ADV_DATA_LEN_MAX) {
|
||||
ESP_LOGE(TAG, "Advertisement data too long = %d bytes", adv_data_len);
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Allocate memory for the raw advertisement data */
|
||||
protoble_internal->raw_adv_data_len = adv_data_len;
|
||||
protoble_internal->raw_adv_data_p = malloc(adv_data_len);
|
||||
if (protoble_internal->raw_adv_data_p == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for raw advertisement data");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Form the raw advertisement data using above entries */
|
||||
for (uint8_t i = 0, len = 0; i < (sizeof(adv_data) / sizeof(adv_data[0])); i++) {
|
||||
protoble_internal->raw_adv_data_p[len++] = adv_data[i].length + 1; // + 1 byte for type
|
||||
protoble_internal->raw_adv_data_p[len++] = adv_data[i].type;
|
||||
memcpy(&protoble_internal->raw_adv_data_p[len],
|
||||
adv_data[i].data_p, adv_data[i].length);
|
||||
|
||||
if (adv_data[i].type == ESP_BLE_AD_TYPE_128SRV_CMPL) {
|
||||
/* Remember where the primary service UUID is kept in the
|
||||
* raw advertisement data, so that it can be used while
|
||||
* populating the GATT database
|
||||
*/
|
||||
protoble_internal->service_uuid = &protoble_internal->raw_adv_data_p[len];
|
||||
}
|
||||
|
||||
len += adv_data[i].length;
|
||||
}
|
||||
|
||||
size_t ble_devname_len = strlen(protocomm_ble_device_name);
|
||||
/* The BLE scan response (31 bytes) consists of:
|
||||
* 1) Device name (complete / incomplete) -
|
||||
* Size : The maximum supported name length
|
||||
* will be 31 - 2 (length + type) = 29 bytes
|
||||
*
|
||||
* Any remaining space may be used for accommodating
|
||||
* other fields in the future
|
||||
*
|
||||
* 2) Manufacturer Data (To be truncated depending upon available size)
|
||||
* Size : The maximum supported manufacturer data size
|
||||
* will be 31 - 2 (length + type) - ble_devname_len - 2 (length + type)
|
||||
*/
|
||||
|
||||
raw_data_info_t scan_resp_data[] = {
|
||||
{ /* If full device name can fit in the scan response then indicate
|
||||
* that by setting type to "Complete Name", else set it to "Short Name"
|
||||
* so that client can fetch full device name - after connecting - by
|
||||
* reading the device name characteristic under GAP service */
|
||||
.type = (ble_devname_len > (ESP_BLE_SCAN_RSP_DATA_LEN_MAX - 2) ?
|
||||
ESP_BLE_AD_TYPE_NAME_SHORT : ESP_BLE_AD_TYPE_NAME_CMPL),
|
||||
.length = MIN(ble_devname_len, (ESP_BLE_SCAN_RSP_DATA_LEN_MAX - 2)),
|
||||
.data_p = (uint8_t *) protocomm_ble_device_name
|
||||
},
|
||||
{
|
||||
0,
|
||||
},
|
||||
};
|
||||
|
||||
if (protocomm_ble_mfg_data_len > 0) {
|
||||
scan_resp_data[1].type = ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE;
|
||||
scan_resp_data[1].length = protocomm_ble_mfg_data_len;
|
||||
scan_resp_data[1].data_p = (uint8_t *) protocomm_ble_mfg_data;
|
||||
}
|
||||
|
||||
/* Get the total raw scan response data length required for above entries */
|
||||
uint8_t scan_resp_data_len = 0;
|
||||
for (int i = 0; i < (sizeof(scan_resp_data) / sizeof(scan_resp_data[0])); i++) {
|
||||
/* Add extra bytes required per entry, i.e.
|
||||
* length (1 byte) + type (1 byte) = 2 bytes */
|
||||
scan_resp_data_len += scan_resp_data[i].length + 2;
|
||||
}
|
||||
if (scan_resp_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX) {
|
||||
ESP_LOGE(TAG, "Scan response data too long = %d bytes", scan_resp_data_len);
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Allocate memory for the raw scan response data */
|
||||
protoble_internal->raw_scan_rsp_data_len = scan_resp_data_len;
|
||||
protoble_internal->raw_scan_rsp_data_p = malloc(scan_resp_data_len);
|
||||
if (protoble_internal->raw_scan_rsp_data_p == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for raw response data");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Form the raw scan response data using above entries */
|
||||
for (uint8_t i = 0, len = 0; i < (sizeof(scan_resp_data) / sizeof(scan_resp_data[0])); i++) {
|
||||
protoble_internal->raw_scan_rsp_data_p[len++] = scan_resp_data[i].length + 1; // + 1 byte for type
|
||||
protoble_internal->raw_scan_rsp_data_p[len++] = scan_resp_data[i].type;
|
||||
memcpy(&protoble_internal->raw_scan_rsp_data_p[len],
|
||||
scan_resp_data[i].data_p, scan_resp_data[i].length);
|
||||
len += scan_resp_data[i].length;
|
||||
}
|
||||
// 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;
|
||||
|
||||
simple_ble_cfg_t *ble_config = simple_ble_init();
|
||||
if (ble_config == NULL) {
|
||||
@ -637,10 +534,8 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
|
||||
/* Set parameters required for advertising */
|
||||
ble_config->adv_params = adv_params;
|
||||
|
||||
ble_config->raw_adv_data_p = protoble_internal->raw_adv_data_p;
|
||||
ble_config->raw_adv_data_len = protoble_internal->raw_adv_data_len;
|
||||
ble_config->raw_scan_rsp_data_p = protoble_internal->raw_scan_rsp_data_p;
|
||||
ble_config->raw_scan_rsp_data_len = protoble_internal->raw_scan_rsp_data_len;
|
||||
ble_config->adv_data_p = &adv_config;
|
||||
ble_config->scan_rsp_data_p = &scan_rsp_config;
|
||||
|
||||
ble_config->device_name = protocomm_ble_device_name;
|
||||
ble_config->gatt_db_count = populate_gatt_db(&ble_config->gatt_db);
|
||||
|
Loading…
Reference in New Issue
Block a user