diff --git a/components/protocomm/include/transports/protocomm_ble.h b/components/protocomm/include/transports/protocomm_ble.h index 51aec06e99..361028790b 100644 --- a/components/protocomm/include/transports/protocomm_ble.h +++ b/components/protocomm/include/transports/protocomm_ble.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,6 +41,7 @@ typedef enum { * (29 - (BLE device name length) - 2). */ #define MAX_BLE_MANUFACTURER_DATA_LEN 29 +#define BLE_ADDR_LEN 6 /** * @brief This structure maps handler required by protocomm layer to * UUIDs which are used to uniquely identify BLE characteristics @@ -137,6 +138,10 @@ typedef struct protocomm_ble_config { */ unsigned ble_link_encryption:1; + /** + * BLE address + */ + uint8_t *ble_addr; } protocomm_ble_config_t; /** diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c index 8a4ae0f3d9..c9693a7df4 100644 --- a/components/protocomm/src/simple_ble/simple_ble.c +++ b/components/protocomm/src/simple_ble/simple_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,12 +48,24 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param switch (event) { case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: adv_config_done &= (~adv_config_flag); + + if (g_ble_cfg_p->ble_addr) { + esp_ble_gap_set_rand_addr(g_ble_cfg_p->ble_addr); + g_ble_cfg_p->adv_params.own_addr_type = BLE_ADDR_TYPE_RANDOM; + } + if (adv_config_done == 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 (g_ble_cfg_p->ble_addr) { + esp_ble_gap_set_rand_addr(g_ble_cfg_p->ble_addr); + g_ble_cfg_p->adv_params.own_addr_type = BLE_ADDR_TYPE_RANDOM; + } + if (adv_config_done == 0) { esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); } diff --git a/components/protocomm/src/simple_ble/simple_ble.h b/components/protocomm/src/simple_ble/simple_ble.h index 06d2bfa7b2..259225de83 100644 --- a/components/protocomm/src/simple_ble/simple_ble.h +++ b/components/protocomm/src/simple_ble/simple_ble.h @@ -51,6 +51,9 @@ typedef struct { unsigned ble_bonding:1; /** BLE Secure Connection flag */ unsigned ble_sm_sc:1; + /** BLE Address */ + uint8_t *ble_addr; + } simple_ble_cfg_t; diff --git a/components/protocomm/src/transports/protocomm_ble.c b/components/protocomm/src/transports/protocomm_ble.c index 322c608641..6fedd85abb 100644 --- a/components/protocomm/src/transports/protocomm_ble.c +++ b/components/protocomm/src/transports/protocomm_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -103,6 +103,7 @@ static esp_ble_adv_params_t adv_params = { static char *protocomm_ble_device_name = NULL; static uint8_t *protocomm_ble_mfg_data = NULL; static size_t protocomm_ble_mfg_data_len; +static uint8_t *protocomm_ble_addr = NULL; static void hexdump(const char *msg, uint8_t *buf, int len) { @@ -524,6 +525,10 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con protocomm_ble_mfg_data_len = config->manufacturer_data_len; } + if (config->ble_addr != NULL) { + protocomm_ble_addr = config->ble_addr; + } + protoble_internal = (_protocomm_ble_internal_t *) calloc(1, sizeof(_protocomm_ble_internal_t)); if (protoble_internal == NULL) { ESP_LOGE(TAG, "Error allocating internal protocomm structure"); @@ -594,6 +599,10 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con ble_config->ble_bonding = config->ble_bonding; ble_config->ble_sm_sc = config->ble_sm_sc; + if (config->ble_addr != NULL) { + ble_config->ble_addr = protocomm_ble_addr; + } + if (ble_config->gatt_db_count == -1) { ESP_LOGE(TAG, "Invalid GATT database count"); simple_ble_deinit(); diff --git a/components/protocomm/src/transports/protocomm_nimble.c b/components/protocomm/src/transports/protocomm_nimble.c index 3b2b2bfc69..2852c782c8 100644 --- a/components/protocomm/src/transports/protocomm_nimble.c +++ b/components/protocomm/src/transports/protocomm_nimble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -79,6 +79,7 @@ static struct ble_hs_adv_fields adv_data, resp_data; static uint8_t *protocomm_ble_mfg_data; static size_t protocomm_ble_mfg_data_len; +static uint8_t *protocomm_ble_addr; /********************************************************************** * Maintain database of uuid_name addresses to free memory afterwards * **********************************************************************/ @@ -130,6 +131,8 @@ typedef struct { unsigned ble_sm_sc:1; /** BLE Link Encryption flag */ unsigned ble_link_encryption:1; + /** BLE address */ + uint8_t *ble_addr; } simple_ble_cfg_t; static simple_ble_cfg_t *ble_cfg_p; @@ -461,10 +464,25 @@ simple_ble_on_sync(void) { int rc; - rc = ble_hs_util_ensure_addr(0); - if (rc != 0) { - ESP_LOGE(TAG, "Error loading address"); - return; + if (protocomm_ble_addr) { + rc = ble_hs_id_set_rnd(protocomm_ble_addr); + if (rc != 0) { + ESP_LOGE(TAG,"Error in setting address"); + return; + } + + rc = ble_hs_util_ensure_addr(1); + if (rc != 0) { + ESP_LOGE(TAG,"Error loading address"); + return; + } + } + else { + rc = ble_hs_util_ensure_addr(0); + if (rc != 0) { + ESP_LOGE(TAG, "Error loading address"); + return; + } } /* Figure out address to use while advertising (no privacy for now) */ @@ -727,7 +745,7 @@ ble_gatt_add_primary_svcs(struct ble_gatt_svc_def *gatt_db_svcs, int char_count) gatt_db_svcs->type = BLE_GATT_SVC_TYPE_PRIMARY; /* Allocate (number of characteristics + 1) memory for characteristics, the - * addtional characteristic consist of all 0s indicating end of + * additional characteristic consist of all 0s indicating end of * characteristics */ gatt_db_svcs->characteristics = (struct ble_gatt_chr_def *) calloc((char_count + 1), sizeof(struct ble_gatt_chr_def)); @@ -781,7 +799,7 @@ populate_gatt_db(struct ble_gatt_svc_def **gatt_db_svcs, const protocomm_ble_con rc = ble_gatt_add_char_dsc((void *) (*gatt_db_svcs)->characteristics, i, BLE_GATT_UUID_CHAR_DSC); if (rc != 0) { - ESP_LOGE(TAG, "Error adding GATT Discriptor !!"); + ESP_LOGE(TAG, "Error adding GATT Descriptor !!"); return rc; } } @@ -813,6 +831,11 @@ static void protocomm_ble_cleanup(void) protocomm_ble_mfg_data = NULL; protocomm_ble_mfg_data_len = 0; } + + if (protocomm_ble_addr) { + free(protocomm_ble_addr); + protocomm_ble_addr = NULL; + } } static void free_gatt_ble_misc_memory(simple_ble_cfg_t *ble_config) @@ -970,6 +993,10 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con ble_config->ble_bonding = config->ble_bonding; ble_config->ble_sm_sc = config->ble_sm_sc; + if (config->ble_addr != NULL) { + protocomm_ble_addr = config->ble_addr; + } + if (populate_gatt_db(&ble_config->gatt_db, config) != 0) { ESP_LOGE(TAG, "Error populating GATT Database"); free_gatt_ble_misc_memory(ble_config); diff --git a/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h b/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h index fc19e16b17..c30a3a86b8 100644 --- a/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h +++ b/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h @@ -1,16 +1,8 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -65,9 +57,9 @@ void wifi_prov_scheme_ble_event_cb_free_bt (void *user_data, wifi_prov_cb_event * the default UUID will be used. * * @note The data being pointed to by the argument must be valid - * atleast till provisioning is started. Upon start, the + * at least till provisioning is started. Upon start, the * manager will store an internal copy of this UUID, and - * this data can be freed or invalidated afterwords. + * this data can be freed or invalidated afterwards. * * @param[in] uuid128 A custom 128 bit UUID * @@ -100,6 +92,31 @@ esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128); */ esp_err_t wifi_prov_scheme_ble_set_mfg_data(uint8_t *mfg_data, ssize_t mfg_data_len); +/** + * @brief Set Bluetooth Random address + * + * This must be called before starting provisioning, i.e. before + * making a call to wifi_prov_mgr_start_provisioning(). + * + * This API can be used in cases where a new identity address is to be used during + * provisioning. This will result in this device being treated as a new device by remote + * devices. + * + * @note This API will change the existing BD address for the device. The address once + * set will remain unchanged until BLE stack tear down happens when + * wifi_prov_mgr_deinit is invoked. + * + * This API is only to be called to set random address. Re-invoking this API + * after provisioning is started will have no effect. + * + * @param[in] rand_addr The static random address to be set of length 6 bytes. + * + * @return + * - ESP_OK : Success + * - ESP_ERR_INVALID_ARG : Null argument + */ +esp_err_t wifi_prov_scheme_ble_set_random_addr(const uint8_t *rand_addr); + #ifdef __cplusplus } #endif diff --git a/components/wifi_provisioning/src/scheme_ble.c b/components/wifi_provisioning/src/scheme_ble.c index d323fda21d..6ca994fbc8 100644 --- a/components/wifi_provisioning/src/scheme_ble.c +++ b/components/wifi_provisioning/src/scheme_ble.c @@ -22,7 +22,7 @@ static const char *TAG = "wifi_prov_scheme_ble"; extern const wifi_prov_scheme_t wifi_prov_scheme_ble; static uint8_t *custom_service_uuid; - +static uint8_t *custom_ble_addr; static uint8_t *custom_manufacturer_data; static size_t custom_manufacturer_data_len; @@ -59,6 +59,22 @@ static esp_err_t prov_start(protocomm_t *pc, void *config) return ESP_OK; } +esp_err_t wifi_prov_scheme_ble_set_random_addr(const uint8_t *addr) +{ + if (!addr) { + return ESP_ERR_INVALID_ARG; + } + + custom_ble_addr = (uint8_t *) malloc(BLE_ADDR_LEN); + if (custom_ble_addr == NULL) { + ESP_LOGE(TAG, "Error allocating memory for random address"); + return ESP_ERR_NO_MEM; + } + + memcpy(custom_ble_addr, addr, BLE_ADDR_LEN); + return ESP_OK; +} + esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128) { if (!uuid128) { @@ -159,6 +175,12 @@ static esp_err_t set_config_service(void *config, const char *service_name, cons ble_config->manufacturer_data_len = 0; } + if (custom_ble_addr){ + ble_config->ble_addr = custom_ble_addr; + } else { + ble_config->ble_addr = NULL; + } + return ESP_OK; } diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 15adc2ac92..8de84705fc 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1005,7 +1005,6 @@ components/vfs/include/esp_vfs_common.h components/vfs/include/esp_vfs_eventfd.h components/vfs/test/test_vfs_lwip.c components/vfs/test/test_vfs_paths.c -components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h components/wifi_provisioning/include/wifi_provisioning/scheme_console.h components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h