From c9d5c144513384df268373fd7e03bb525a777fd2 Mon Sep 17 00:00:00 2001 From: "lorenzo.consolaro" Date: Wed, 6 Apr 2022 14:08:32 +0200 Subject: [PATCH] Fix iOS advertisement response and simplify --- .../protocomm/src/simple_ble/simple_ble.c | 10 +- .../protocomm/src/simple_ble/simple_ble.h | 6 +- .../protocomm/src/transports/protocomm_ble.c | 169 ++++-------------- 3 files changed, 38 insertions(+), 147 deletions(-) diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c index 6ea752c9bc..48d23874ad 100644 --- a/components/protocomm/src/simple_ble/simple_ble.c +++ b/components/protocomm/src/simple_ble/simple_ble.c @@ -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); @@ -94,15 +94,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; diff --git a/components/protocomm/src/simple_ble/simple_ble.h b/components/protocomm/src/simple_ble/simple_ble.h index ebe69438ac..8f09adcb1e 100644 --- a/components/protocomm/src/simple_ble/simple_ble.h +++ b/components/protocomm/src/simple_ble/simple_ble.h @@ -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 diff --git a/components/protocomm/src/transports/protocomm_ble.c b/components/protocomm/src/transports/protocomm_ble.c index e619e5621b..7dac4cacc5 100644 --- a/components/protocomm/src/transports/protocomm_ble.c +++ b/components/protocomm/src/transports/protocomm_ble.c @@ -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, @@ -418,8 +436,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; } @@ -492,133 +508,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) { @@ -638,10 +535,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);