From 673f58fe03bb2fb194e1953bf867afbab8130911 Mon Sep 17 00:00:00 2001 From: lly Date: Tue, 8 Oct 2019 16:34:05 +0800 Subject: [PATCH 01/21] ble_mesh: fix not restoring ble mesh cfg value --- components/bt/esp_ble_mesh/mesh_core/settings.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index 491782f400..874ff7d772 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/components/bt/esp_ble_mesh/mesh_core/settings.c @@ -538,6 +538,7 @@ static int cfg_set(const char *name) return 0; } + memcpy(&stored_cfg.cfg, &val, sizeof(val)); stored_cfg.valid = true; BT_DBG("Restore configuration state"); return 0; From 6153a0ab6275a264ea90ff79a63b6b0be91895e5 Mon Sep 17 00:00:00 2001 From: Marcin Borowicz Date: Sun, 14 Jul 2019 16:45:35 +0200 Subject: [PATCH 02/21] spiffs: follow symlinks feature during partition in spiffsgen --- components/spiffs/Kconfig | 7 +++++++ components/spiffs/Makefile.projbuild | 9 ++++++++- components/spiffs/project_include.cmake | 7 ++++++- components/spiffs/spiffsgen.py | 7 ++++++- tools/ldgen/samples/sdkconfig | 1 + 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/components/spiffs/Kconfig b/components/spiffs/Kconfig index c533b819ac..be191c24f4 100644 --- a/components/spiffs/Kconfig +++ b/components/spiffs/Kconfig @@ -76,6 +76,13 @@ menu "SPIFFS Configuration" SPIFFS_OBJ_NAME_LEN + SPIFFS_META_LENGTH should not exceed SPIFFS_PAGE_SIZE - 64. + config SPIFFS_FOLLOW_SYMLINKS + bool "Enable symbolic links for image creation" + default "n" + help + If this option is enabled, symbolic links are taken into account + during partition image creation. + config SPIFFS_USE_MAGIC bool "Enable SPIFFS Filesystem Magic" default "y" diff --git a/components/spiffs/Makefile.projbuild b/components/spiffs/Makefile.projbuild index 4d8f39c081..87e1f59edf 100644 --- a/components/spiffs/Makefile.projbuild +++ b/components/spiffs/Makefile.projbuild @@ -13,6 +13,12 @@ else USE_MAGIC_LEN = "" endif +ifdef CONFIG_SPIFFS_FOLLOW_SYMLINKS +FOLLOW_SYMLINKS = "--follow-symlinks" +else +FOLLOW_SYMLINKS = "" +endif + # spiffs_create_partition_image # # Create a spiffs image of the specified directory on the host during build and optionally @@ -27,6 +33,7 @@ $(1)_bin: $(PARTITION_TABLE_BIN) $(SPIFFS_IMAGE_DEPENDS) | check_python_dependen --page-size=$(CONFIG_SPIFFS_PAGE_SIZE) \ --obj-name-len=$(CONFIG_SPIFFS_OBJ_NAME_LEN) \ --meta-len=$(CONFIG_SPIFFS_META_LENGTH) \ + $(FOLLOW_SYMLINKS) \ $(USE_MAGIC) \ $(USE_MAGIC_LEN) @@ -43,4 +50,4 @@ endef ESPTOOL_ALL_FLASH_ARGS += $(foreach partition,$(SPIFFSGEN_FLASH_IN_PROJECT), \ $(shell $(GET_PART_INFO) --partition-table-file $(PARTITION_TABLE_BIN) \ -get_partition_info --partition-name $(partition) --info offset) $(BUILD_DIR_BASE)/$(partition).bin) \ No newline at end of file +get_partition_info --partition-name $(partition) --info offset) $(BUILD_DIR_BASE)/$(partition).bin) diff --git a/components/spiffs/project_include.cmake b/components/spiffs/project_include.cmake index 31f63b5111..061a67d0bb 100644 --- a/components/spiffs/project_include.cmake +++ b/components/spiffs/project_include.cmake @@ -25,6 +25,10 @@ function(spiffs_create_partition_image partition base_dir) set(use_magic_len "--use-magic-len") endif() + if(CONFIG_SPIFFS_FOLLOW_SYMLINKS) + set(follow_symlinks "--follow-symlinks") + endif() + # Execute SPIFFS image generation; this always executes as there is no way to specify for CMake to watch for # contents of the base dir changing. add_custom_target(spiffs_${partition}_bin ALL @@ -32,6 +36,7 @@ function(spiffs_create_partition_image partition base_dir) --page-size=${CONFIG_SPIFFS_PAGE_SIZE} --obj-name-len=${CONFIG_SPIFFS_OBJ_NAME_LEN} --meta-len=${CONFIG_SPIFFS_META_LENGTH} + ${follow_symlinks} ${use_magic} ${use_magic_len} DEPENDS ${arg_DEPENDS} @@ -46,4 +51,4 @@ function(spiffs_create_partition_image partition base_dir) else() esptool_py_flash_project_args(${partition} ${offset} ${image_file}) endif() -endfunction() \ No newline at end of file +endfunction() diff --git a/components/spiffs/spiffsgen.py b/components/spiffs/spiffsgen.py index de160294d3..fc22d1b36b 100755 --- a/components/spiffs/spiffsgen.py +++ b/components/spiffs/spiffsgen.py @@ -488,6 +488,11 @@ def main(): action="store_true", default=True) + parser.add_argument("--follow-symlinks", + help="Take into account symbolic links during partition image creation.", + action="store_true", + default=False) + parser.add_argument("--use-magic-len", help="Use position in memory to create different magic numbers for each block. Specify if CONFIG_SPIFFS_USE_MAGIC_LENGTH.", action="store_true", @@ -513,7 +518,7 @@ def main(): spiffs = SpiffsFS(image_size, spiffs_build_default) - for root, dirs, files in os.walk(args.base_dir): + for root, dirs, files in os.walk(args.base_dir, followlinks=args.follow_symlinks): for f in files: full_path = os.path.join(root, f) spiffs.create_file("/" + os.path.relpath(full_path, args.base_dir).replace("\\", "/"), full_path) diff --git a/tools/ldgen/samples/sdkconfig b/tools/ldgen/samples/sdkconfig index 112abbec64..dd70883e86 100644 --- a/tools/ldgen/samples/sdkconfig +++ b/tools/ldgen/samples/sdkconfig @@ -516,6 +516,7 @@ CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_FOLLOW_SYMLINKS= CONFIG_SPIFFS_META_LENGTH=4 CONFIG_SPIFFS_USE_MTIME=y From a986283997b70781ce5aa21e79355d8906502d30 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Tue, 8 Oct 2019 17:55:12 +0800 Subject: [PATCH 03/21] spiffs: follow symlinks in host test --- components/spiffs/test_spiffs_host/Makefile | 6 ++++- .../spiffs/test_spiffs_host/test_spiffs.cpp | 25 +++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/components/spiffs/test_spiffs_host/Makefile b/components/spiffs/test_spiffs_host/Makefile index 15b327acf1..3e7e9d5f5a 100644 --- a/components/spiffs/test_spiffs_host/Makefile +++ b/components/spiffs/test_spiffs_host/Makefile @@ -87,7 +87,11 @@ $(TEST_PROGRAM): lib $(TEST_OBJ_FILES) $(SPI_FLASH_SIM_BUILD_DIR)/$(SPI_FLASH_SI # Use spiffs source directory as the test image spiffs_image: ../spiffs $(shell find ../spiffs -type d) $(shell find ../spiffs -type -f -name '*') - ../spiffsgen.py 2097152 ../spiffs image.bin + # Creation of test symlinks unfortunately causes rerun of spiffsgen.py every make invoke + rm -f ../spiffs/include ../spiffs/CMakeLists.txt + ln -s ../include ../spiffs/include + ln -s ../CMakeLists.txt ../spiffs/CMakeLists.txt + ../spiffsgen.py --follow-symlinks 2097152 ../spiffs image.bin test: $(TEST_PROGRAM) spiffs_image ./$(TEST_PROGRAM) diff --git a/components/spiffs/test_spiffs_host/test_spiffs.cpp b/components/spiffs/test_spiffs_host/test_spiffs.cpp index 868ce45809..ce7347b3f1 100644 --- a/components/spiffs/test_spiffs_host/test_spiffs.cpp +++ b/components/spiffs/test_spiffs_host/test_spiffs.cpp @@ -1,9 +1,13 @@ #include #include #include +#include #include +#include +#include #include #include +#include #include "esp_partition.h" #include "spiffs.h" @@ -96,7 +100,18 @@ static void check_spiffs_files(spiffs *fs, const char *base_path, char* cur_path while ((entry = readdir(dir)) != NULL) { char *name = entry->d_name; - if (entry->d_type == DT_DIR) { + + char path[PATH_MAX] = { 0 }; + + // Read the file from host FS + strcpy(path, cur_path); + strcat(path, "/"); + strcat(path, name); + + struct stat sb; + stat(path, &sb); + + if (S_ISDIR(sb.st_mode)) { if (!strcmp(name, ".") || !strcmp(name, "..")) continue; cur_path[len] = '/'; @@ -104,13 +119,6 @@ static void check_spiffs_files(spiffs *fs, const char *base_path, char* cur_path check_spiffs_files(fs, base_path, cur_path); cur_path[len] = '\0'; } else { - char path[PATH_MAX]; - - // Read the file from host FS - strcpy(path, cur_path); - strcat(path, "/"); - strcat(path, name); - FILE* f = fopen(path , "r"); REQUIRE(f); fseek(f, 0, SEEK_END); @@ -126,6 +134,7 @@ static void check_spiffs_files(spiffs *fs, const char *base_path, char* cur_path // Read the file from SPIFFS char *spiffs_path = path + strlen(base_path); spiffs_res = SPIFFS_open(fs, spiffs_path, SPIFFS_RDONLY, 0); + REQUIRE(spiffs_res > SPIFFS_OK); spiffs_file fd = spiffs_res; From 19c644f7fd83451c729e47be6733f39e2dd4b37d Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Tue, 8 Oct 2019 13:17:34 +0200 Subject: [PATCH 04/21] Fix memory leak upon failure of esp_vfs_fat_sdmmc_mount() Closes https://github.com/espressif/esp-idf/issues/4165 --- components/fatfs/vfs/vfs_fat_sdmmc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/fatfs/vfs/vfs_fat_sdmmc.c b/components/fatfs/vfs/vfs_fat_sdmmc.c index 83cc0aee5b..ebaf07780b 100644 --- a/components/fatfs/vfs/vfs_fat_sdmmc.c +++ b/components/fatfs/vfs/vfs_fat_sdmmc.c @@ -159,6 +159,8 @@ fail: ff_diskio_unregister(pdrv); free(s_card); s_card = NULL; + free(s_base_path); + s_base_path = NULL; return err; } From 35353de137b2e9f167be753b5321ae659e1803e4 Mon Sep 17 00:00:00 2001 From: lly Date: Fri, 11 Oct 2019 09:51:02 +0800 Subject: [PATCH 05/21] ble_mesh: fix not callback net_key when device is provisioned --- components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h | 1 + components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c | 3 ++- components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h | 3 ++- components/bt/esp_ble_mesh/mesh_core/net.c | 3 ++- components/bt/esp_ble_mesh/mesh_core/prov.c | 4 ++-- components/bt/esp_ble_mesh/mesh_core/prov.h | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 9166af62cc..9696bb48ca 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -1287,6 +1287,7 @@ typedef union { */ struct ble_mesh_provision_complete_evt_param { uint16_t net_idx; /*!< NetKey Index */ + uint8_t net_key[16]; /*!< NetKey */ uint16_t addr; /*!< Primary address */ uint8_t flags; /*!< Flags */ uint32_t iv_index; /*!< IV Index */ diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index 12080d51b9..09aa53125f 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -522,7 +522,7 @@ static void btc_ble_mesh_link_close_cb(bt_mesh_prov_bearer_t bearer) return; } -static void btc_ble_mesh_complete_cb(u16_t net_idx, u16_t addr, u8_t flags, u32_t iv_index) +static void btc_ble_mesh_complete_cb(u16_t net_idx, const u8_t net_key[16], u16_t addr, u8_t flags, u32_t iv_index) { esp_ble_mesh_prov_cb_param_t mesh_param = {0}; btc_msg_t msg = {0}; @@ -531,6 +531,7 @@ static void btc_ble_mesh_complete_cb(u16_t net_idx, u16_t addr, u8_t flags, u32_ LOG_DEBUG("%s", __func__); mesh_param.node_prov_complete.net_idx = net_idx; + memcpy(mesh_param.node_prov_complete.net_key, net_key, 16); mesh_param.node_prov_complete.addr = addr; mesh_param.node_prov_complete.flags = flags; mesh_param.node_prov_complete.iv_index = iv_index; diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h index 374c6a0770..1a79a7a1e7 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h @@ -164,11 +164,12 @@ struct bt_mesh_prov { * assigned the specified NetKeyIndex and primary element address. * * @param net_idx NetKeyIndex given during provisioning. + * @param net_key NetKey given during provisioning. * @param addr Primary element address. * @param flags Key Refresh & IV Update flags * @param iv_index IV Index. */ - void (*complete)(u16_t net_idx, u16_t addr, u8_t flags, u32_t iv_index); + void (*complete)(u16_t net_idx, const u8_t net_key[16], u16_t addr, u8_t flags, u32_t iv_index); /** @brief Node has been reset. * diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index ad778269a9..63d875f35c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -1476,11 +1476,12 @@ void bt_mesh_net_start(void) u16_t addr = bt_mesh_primary_addr(); u32_t iv_index = bt_mesh.iv_index; u8_t flags = (u8_t)bt_mesh.sub[0].kr_flag; + const u8_t *net_key = bt_mesh.sub[0].keys[flags].net; if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS)) { flags |= BLE_MESH_NET_FLAG_IVU; } - bt_mesh_prov_complete(net_idx, addr, flags, iv_index); + bt_mesh_prov_complete(net_idx, net_key, addr, flags, iv_index); } } #endif diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.c b/components/bt/esp_ble_mesh/mesh_core/prov.c index 63848eaa51..63ba90acbd 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/prov.c @@ -1744,10 +1744,10 @@ int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) return 0; } -void bt_mesh_prov_complete(u16_t net_idx, u16_t addr, u8_t flags, u32_t iv_index) +void bt_mesh_prov_complete(u16_t net_idx, const u8_t net_key[16], u16_t addr, u8_t flags, u32_t iv_index) { if (prov->complete) { - prov->complete(net_idx, addr, flags, iv_index); + prov->complete(net_idx, net_key, addr, flags, iv_index); } } diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.h b/components/bt/esp_ble_mesh/mesh_core/prov.h index f96ed7707f..610e55c6d5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.h +++ b/components/bt/esp_ble_mesh/mesh_core/prov.h @@ -28,7 +28,7 @@ const struct bt_mesh_prov *bt_mesh_prov_get(void); int bt_mesh_prov_init(const struct bt_mesh_prov *prov); -void bt_mesh_prov_complete(u16_t net_idx, u16_t addr, u8_t flags, u32_t iv_index); +void bt_mesh_prov_complete(u16_t net_idx, const u8_t net_key[16], u16_t addr, u8_t flags, u32_t iv_index); void bt_mesh_prov_reset(void); #endif /* _PROV_H_ */ From 499d087c91141834bc41a282a592ba1d61f7b2c8 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 6 Jun 2019 16:53:26 +0800 Subject: [PATCH 06/21] C++: add provisions for optional RTTI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ref. https://github.com/espressif/esp-idf/issues/1684 This change allows RTTI to be enabled in menuconfig. For full RTTI support, libstdc++.a in the toolchain should be built without -fno-rtti, as it is done now. Generally if libstdc++.a is built with RTTI, applications which do not use RTTI (and build with -fno-rtti) could still include typeinfo structures referenced from STL classes’ vtables. This change works around this, by moving all typeinfo structures from libstdc++.a into a non-loadable section, placed into a non-existent memory region starting at address 0. This can be done because when the application is compiled with -fno-rtti, typeinfo structures are not used at run time. This way, typeinfo structures do not contribute to the application binary size. If the application is build with RTTI support, typeinfo structures are linked into the application .rodata section as usual. Note that this commit does not actually enable RTTI support. The respective Kconfig option is hidden, and will be made visible when the toolchain is updated. --- CMakeLists.txt | 6 ++++++ Kconfig | 9 +++++++++ components/esp32/CMakeLists.txt | 5 +++++ components/esp32/component.mk | 21 +++++++++++++-------- components/esp32/ld/esp32.discard-rtti.ld | 11 +++++++++++ components/esp32/ld/esp32.ld | 5 +++++ make/project.mk | 7 ++++++- tools/cmake/build.cmake | 3 +-- 8 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 components/esp32/ld/esp32.discard-rtti.ld diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dae14c8cd..55c9109f90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,12 @@ else() list(APPEND cxx_compile_options "-fno-exceptions") endif() +if(CONFIG_COMPILER_CXX_RTTI) + list(APPEND cxx_compile_options "-frtti") +else() + list(APPEND cxx_compile_options "-fno-rtti") +endif() + if(CONFIG_COMPILER_DISABLE_GCC8_WARNINGS) list(APPEND compile_options "-Wno-parentheses" "-Wno-sizeof-pointer-memaccess" diff --git a/Kconfig b/Kconfig index 92c76c38d5..815f87d072 100644 --- a/Kconfig +++ b/Kconfig @@ -237,6 +237,15 @@ mainmenu "Espressif IoT Development Framework Configuration" Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate memory for thrown exceptions when there is not enough memory on the heap. + config COMPILER_CXX_RTTI + # Invisible option, until the toolchain with RTTI support is released. + # Use prompt "Enable C++ run-time type info (RTTI)" when updating. + bool + help + Enabling this option compiles all C++ files with RTTI support enabled. + This increases binary size (typically by tens of kB) but allows using + dynamic_cast conversion and typeid operator. + choice COMPILER_STACK_CHECK_MODE prompt "Stack smashing protection mode" default COMPILER_STACK_CHECK_MODE_NONE diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 7d9ad3872d..70a3805939 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -56,6 +56,11 @@ else() target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.extram.bss.ld") endif() + if(NOT CONFIG_COMPILER_CXX_RTTI) + # This has to be linked before esp32.project.ld + target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.discard-rtti.ld") + endif() + # Process the template file through the linker script generation mechanism, and use the output for linking the # final binary target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 8f999b26d6..836f242e20 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -5,18 +5,23 @@ COMPONENT_SRCDIRS := . ifdef CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - # This linker script must come before esp32.project.ld - LINKER_SCRIPTS += esp32.extram.bss.ld + # This linker script must come before esp32.project.ld + LINKER_SCRIPTS += esp32.extram.bss.ld endif -#Linker scripts used to link the final application. -#Warning: These linker scripts are only used when the normal app is compiled; the bootloader -#specifies its own scripts. +ifndef CONFIG_COMPILER_CXX_RTTI + # This linker script must come before esp32.project.ld + LINKER_SCRIPTS += esp32.discard-rtti.ld +endif + +# Linker scripts used to link the final application. +# Warning: These linker scripts are only used when the normal app is compiled; the bootloader +# specifies its own scripts. LINKER_SCRIPTS += $(COMPONENT_BUILD_DIR)/esp32.project.ld esp32.peripherals.ld -#ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the -#linker will ignore panic_highint_hdl.S as it has no other files depending on any -#symbols in it. +# ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the +# linker will ignore panic_highint_hdl.S as it has no other files depending on any +# symbols in it. COMPONENT_ADD_LDFLAGS += -L $(COMPONENT_PATH)/ld \ -T esp32_out.ld \ -u ld_include_panic_highint_hdl \ diff --git a/components/esp32/ld/esp32.discard-rtti.ld b/components/esp32/ld/esp32.discard-rtti.ld new file mode 100644 index 0000000000..f9fdff9947 --- /dev/null +++ b/components/esp32/ld/esp32.discard-rtti.ld @@ -0,0 +1,11 @@ +/* This is only included if CONFIG_COMPILER_CXX_RTTI is not set, to + * move RTTI sections of libstdc++ to an unused non-loadable memory region. + */ + +SECTIONS +{ + .rodata.discard-rtti (NOLOAD): + { + *libstdc++.a:(.rodata._ZTI* .rodata._ZTS*) + } > discard_seg +} diff --git a/components/esp32/ld/esp32.ld b/components/esp32/ld/esp32.ld index 0400fc2ab3..cb0f14437b 100644 --- a/components/esp32/ld/esp32.ld +++ b/components/esp32/ld/esp32.ld @@ -98,6 +98,11 @@ MEMORY /* external memory ,including data and text */ extern_ram_seg(RWX) : org = 0x3F800000, len = 0x400000 + + /* This is not a memory range which can really be accessed; we use it as a "bitbucket" + where non-loadable sections, which aren't used at run time, can be discarded. + */ + discard_seg (R) : org = 0x00000000, len = 0x10000000 } #if defined(CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE) diff --git a/make/project.mk b/make/project.mk index a8ec59f405..61e80ac068 100644 --- a/make/project.mk +++ b/make/project.mk @@ -468,7 +468,6 @@ CXXFLAGS ?= EXTRA_CXXFLAGS ?= CXXFLAGS := $(strip \ -std=gnu++11 \ - -fno-rtti \ $(OPTIMIZATION_FLAGS) $(DEBUG_FLAGS) \ $(COMMON_FLAGS) \ $(COMMON_WARNING_FLAGS) \ @@ -481,6 +480,12 @@ else CXXFLAGS += -fno-exceptions endif +ifdef CONFIG_COMPILER_CXX_RTTI +CXXFLAGS += -frtti +else +CXXFLAGS += -fno-rtti +endif + ARFLAGS := cru export CFLAGS CPPFLAGS CXXFLAGS ARFLAGS diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake index f495ed8fa9..c3bbdeafff 100644 --- a/tools/cmake/build.cmake +++ b/tools/cmake/build.cmake @@ -114,8 +114,7 @@ function(__build_set_default_build_specifications) list(APPEND c_compile_options "-std=gnu99" "-Wno-old-style-declaration") - list(APPEND cxx_compile_options "-std=gnu++11" - "-fno-rtti") + list(APPEND cxx_compile_options "-std=gnu++11") idf_build_set_property(COMPILE_DEFINITIONS "${compile_definitions}" APPEND) idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND) From 640eac84fa37af91bf40b49f10a97b30e4b7b6f8 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 9 Oct 2019 11:03:26 +0200 Subject: [PATCH 07/21] mqtt: updated to latest version to include latest fixes, support for global CA store, extended error structure to receive mqtt specific errors. updated idf ssl example to use this error struct https://github.com/espressif/esp-mqtt/issues/135 --- components/mqtt/esp-mqtt | 2 +- examples/protocols/mqtt/ssl/main/app_main.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/components/mqtt/esp-mqtt b/components/mqtt/esp-mqtt index fb3d2107cd..e3b013e2db 160000 --- a/components/mqtt/esp-mqtt +++ b/components/mqtt/esp-mqtt @@ -1 +1 @@ -Subproject commit fb3d2107cdac440d84f2fab81ea9b5217aa4ba1f +Subproject commit e3b013e2db58124ea68cf7c8f44a8cba6e1572b7 diff --git a/examples/protocols/mqtt/ssl/main/app_main.c b/examples/protocols/mqtt/ssl/main/app_main.c index fd0a49d7bf..4a1c0142fb 100644 --- a/examples/protocols/mqtt/ssl/main/app_main.c +++ b/examples/protocols/mqtt/ssl/main/app_main.c @@ -80,10 +80,14 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) break; case MQTT_EVENT_ERROR: ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); - int mbedtls_err = 0; - esp_err_t err = esp_tls_get_and_clear_last_error(event->error_handle, &mbedtls_err, NULL); - ESP_LOGI(TAG, "Last esp error code: 0x%x", err); - ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err); + if (event->error_handle->error_type == MQTT_ERROR_TYPE_ESP_TLS) { + ESP_LOGI(TAG, "Last error code reported from esp-tls: 0x%x", event->error_handle->esp_tls_last_esp_err); + ESP_LOGI(TAG, "Last tls stack error number: 0x%x", event->error_handle->esp_tls_stack_err); + } else if (event->error_handle->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) { + ESP_LOGI(TAG, "Connection refused error: 0x%x", event->error_handle->connect_return_code); + } else { + ESP_LOGW(TAG, "Unknown error type: 0x%x", event->error_handle->error_type); + } break; default: ESP_LOGI(TAG, "Other event id:%d", event->event_id); From 571864e8aeba85b941133766601543e0decd0faf Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Thu, 5 Sep 2019 13:11:36 +0800 Subject: [PATCH 08/21] esp_flash: fix set qe bit and write command issues There used to be dummy phase before out phase in common command transactions. This corrupts the data. The code before never actually operate (clear) the QE bit, once it finds the QE bit is set. It's hard to check whether the QE set/disable functions work well. This commit: 1. Cancel the dummy phase 2. Set and clear the QE bit according to chip settings, allowing tests for QE bits. However for some chips (Winbond for example), it's not forced to clear the QE bit if not able to. 3. Also refactor to allow chip_generic and other chips to share the same code to read and write qe bit; let common command and read command share configure_host_io_mode. 4. Rename read mode to io mode since maybe we will write data with quad mode one day. --- .../soc/esp32/include/hal/spi_flash_ll.h | 17 +- components/soc/include/hal/spi_flash_hal.h | 29 ++- components/soc/include/hal/spi_flash_types.h | 8 +- components/soc/src/hal/spi_flash_hal.c | 5 - components/soc/src/hal/spi_flash_hal_iram.c | 29 ++- components/spi_flash/CMakeLists.txt | 20 +- components/spi_flash/esp_flash_api.c | 85 ++++++-- components/spi_flash/esp_flash_spi_init.c | 2 +- components/spi_flash/include/esp_flash.h | 18 +- .../spi_flash/include/esp_flash_spi_init.h | 2 +- .../spi_flash/include/memspi_host_driver.h | 2 +- .../spi_flash/include/spi_flash_chip_driver.h | 8 +- .../include/spi_flash_chip_generic.h | 118 ++++++++-- components/spi_flash/spi_flash_chip_generic.c | 204 +++++++++++++----- components/spi_flash/spi_flash_chip_issi.c | 23 +- components/spi_flash/test/test_esp_flash.c | 2 +- 16 files changed, 423 insertions(+), 149 deletions(-) diff --git a/components/soc/esp32/include/hal/spi_flash_ll.h b/components/soc/esp32/include/hal/spi_flash_ll.h index 5522a17219..a30284fa65 100644 --- a/components/soc/esp32/include/hal/spi_flash_ll.h +++ b/components/soc/esp32/include/hal/spi_flash_ll.h @@ -202,21 +202,6 @@ static inline bool spi_flash_ll_host_idle(const spi_dev_t *dev) return dev->ext2.st != 0; } -/** - * Set phases for user-defined transaction to read - * - * @param dev Beginning address of the peripheral registers. - */ -static inline void spi_flash_ll_read_phase(spi_dev_t *dev) -{ - typeof (dev->user) user = { - .usr_command = 1, - .usr_mosi = 0, - .usr_miso = 1, - .usr_addr = 1, - }; - dev->user = user; -} /*------------------------------------------------------------------------------ * Configs *----------------------------------------------------------------------------*/ @@ -239,7 +224,7 @@ static inline void spi_flash_ll_set_cs_pin(spi_dev_t *dev, int pin) * @param dev Beginning address of the peripheral registers. * @param read_mode I/O mode to use in the following transactions. */ -static inline void spi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_read_mode_t read_mode) +static inline void spi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mode_t read_mode) { typeof (dev->ctrl) ctrl = dev->ctrl; ctrl.val &= ~(SPI_FREAD_QIO_M | SPI_FREAD_QUAD_M | SPI_FREAD_DIO_M | SPI_FREAD_DUAL_M); diff --git a/components/soc/include/hal/spi_flash_hal.h b/components/soc/include/hal/spi_flash_hal.h index bf89c41488..ec1b361514 100644 --- a/components/soc/include/hal/spi_flash_hal.h +++ b/components/soc/include/hal/spi_flash_hal.h @@ -155,23 +155,38 @@ esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_driver_t *chip_drv, boo bool spi_flash_hal_host_idle(spi_flash_host_driver_t *driver); /** - * Configure the SPI host hardware registers for the specified read mode. + * @brief Configure the SPI host hardware registers for the specified io mode. * * Note that calling this configures SPI host registers, so if running any - * other commands as part of set_read_mode() then these must be run before + * other commands as part of set_io_mode() then these must be run before * calling this function. * + * The command value, address length and dummy cycles are configured according + * to the format of read commands: + * + * - command: 8 bits, value set. + * - address: 24 bits + * - dummy: cycles to compensate the input delay + * - out & in data: 0 bits. + * + * The following commands still need to: + * + * - Read data: set address value and data (length and contents), no need + * to touch command and dummy phases. + * - Common read: set command value, address value (or length to 0 if not used) + * - Common write: set command value, address value (or length to 0 if not + * used), disable dummy phase, and set output data. + * * @param driver The driver context - * @param read_mode The HW read mode to use + * @param io_mode The HW read mode to use * @param addr_bitlen Length of the address phase, in bits * @param dummy_cyclelen_base Base cycles of the dummy phase, some extra dummy cycles may be appended to compensate the timing. - * @param read_command Actual reading command to send to flash chip on the bus. + * @param command Actual reading command to send to flash chip on the bus. * * @return always return ESP_OK. */ -esp_err_t spi_flash_hal_configure_host_read_mode(spi_flash_host_driver_t *driver, esp_flash_read_mode_t read_mode, - uint32_t addr_bitlen, uint32_t dummy_cyclelen_base, - uint32_t read_command); +esp_err_t spi_flash_hal_configure_host_io_mode(spi_flash_host_driver_t *driver, uint32_t command, uint32_t addr_bitlen, + int dummy_cyclelen_base, esp_flash_io_mode_t io_mode); /** * Poll until the last operation is done. diff --git a/components/soc/include/hal/spi_flash_types.h b/components/soc/include/hal/spi_flash_types.h index c19eee1ed0..3e825c2aa6 100644 --- a/components/soc/include/hal/spi_flash_types.h +++ b/components/soc/include/hal/spi_flash_types.h @@ -61,7 +61,7 @@ typedef enum { SPI_FLASH_QIO, ///< Both address & data transferred using quad I/O SPI_FLASH_READ_MODE_MAX, ///< The fastest io mode supported by the host is ``ESP_FLASH_READ_MODE_MAX-1``. -} esp_flash_read_mode_t; +} esp_flash_io_mode_t; ///Slowest io mode supported by ESP32, currently SlowRd #define SPI_FLASH_READ_MODE_MIN SPI_FLASH_SLOWRD @@ -130,9 +130,11 @@ struct spi_flash_host_driver_t { */ bool (*host_idle)(spi_flash_host_driver_t *driver); /** - * Configure the host to work at different read mode. + * Configure the host to work at different read mode. Responsible to compensate the timing and set IO mode. */ - esp_err_t (*configure_host_read_mode)(spi_flash_host_driver_t *driver, esp_flash_read_mode_t read_mode, uint32_t addr_bitlen, uint32_t dummy_bitlen_base, uint32_t read_command); + esp_err_t (*configure_host_io_mode)(spi_flash_host_driver_t *driver, uint32_t command, + uint32_t addr_bitlen, int dummy_bitlen_base, + esp_flash_io_mode_t io_mode); /** * Internal use, poll the HW until the last operation is done. */ diff --git a/components/soc/src/hal/spi_flash_hal.c b/components/soc/src/hal/spi_flash_hal.c index 6a88d35a17..ee787fd914 100644 --- a/components/soc/src/hal/spi_flash_hal.c +++ b/components/soc/src/hal/spi_flash_hal.c @@ -67,8 +67,3 @@ esp_err_t spi_flash_hal_init(spi_flash_memspi_data_t *data_out, const spi_flash_ ESP_EARLY_LOGD(TAG, "extra_dummy: %d", data_out->extra_dummy); return ESP_OK; } - -static inline spi_dev_t *get_spi_dev(spi_flash_host_driver_t *chip_drv) -{ - return ((spi_flash_memspi_data_t *)chip_drv->driver_data)->spi; -} diff --git a/components/soc/src/hal/spi_flash_hal_iram.c b/components/soc/src/hal/spi_flash_hal_iram.c index 56a525baac..ea8e2bfbc7 100644 --- a/components/soc/src/hal/spi_flash_hal_iram.c +++ b/components/soc/src/hal/spi_flash_hal_iram.c @@ -52,28 +52,37 @@ esp_err_t spi_flash_hal_device_config(spi_flash_host_driver_t *driver) return ESP_OK; } -esp_err_t spi_flash_hal_configure_host_read_mode(spi_flash_host_driver_t *driver, esp_flash_read_mode_t read_mode, - uint32_t addr_bitlen, uint32_t dummy_cyclelen_base, - uint32_t read_command) +esp_err_t spi_flash_hal_configure_host_io_mode( + spi_flash_host_driver_t *host, + uint32_t command, + uint32_t addr_bitlen, + int dummy_cyclelen_base, + esp_flash_io_mode_t io_mode) { // Add dummy cycles to compensate for latency of GPIO matrix and external delay, if necessary... int dummy_cyclelen = dummy_cyclelen_base + ((spi_flash_memspi_data_t *)driver->driver_data)->extra_dummy; spi_dev_t *dev = get_spi_dev(driver); + spi_flash_ll_set_command8(dev, command); spi_flash_ll_set_addr_bitlen(dev, addr_bitlen); - spi_flash_ll_set_command8(dev, read_command); - spi_flash_ll_read_phase(dev); spi_flash_ll_set_dummy(dev, dummy_cyclelen); - spi_flash_ll_set_read_mode(dev, read_mode); + //disable all data phases, enable them later if needed + spi_flash_ll_set_miso_bitlen(dev, 0); + spi_flash_ll_set_mosi_bitlen(dev, 0); + spi_flash_ll_set_read_mode(dev, io_mode); return ESP_OK; } esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *chip_drv, spi_flash_trans_t *trans) { - chip_drv->configure_host_read_mode(chip_drv, SPI_FLASH_FASTRD, 0, 0, 0); + host->configure_host_io_mode(host, trans->command, 0, 0, SPI_FLASH_FASTRD); + spi_dev_t *dev = get_spi_dev(chip_drv); - spi_flash_ll_set_command8(dev, trans->command); - spi_flash_ll_set_addr_bitlen(dev, 0); + //disable dummy if no input phase + if (trans->miso_len == 0) { + spi_flash_ll_set_dummy(dev, 0); + } + spi_flash_ll_set_miso_bitlen(dev, trans->miso_len); spi_flash_ll_set_mosi_bitlen(dev, trans->mosi_len); @@ -122,7 +131,7 @@ void spi_flash_hal_program_page(spi_flash_host_driver_t *chip_drv, const void *b esp_err_t spi_flash_hal_read(spi_flash_host_driver_t *chip_drv, void *buffer, uint32_t address, uint32_t read_len) { spi_dev_t *dev = get_spi_dev(chip_drv); - //the command is already set by ``spi_flash_hal_configure_host_read_mode`` before. + //the command is already set by ``spi_flash_hal_configure_host_io_mode`` before. spi_flash_ll_set_address(dev, address << 8); spi_flash_ll_set_miso_bitlen(dev, read_len * 8); spi_flash_ll_user_start(dev); diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 878b3c8cf9..497125e47b 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -3,25 +3,31 @@ if(BOOTLOADER_BUILD) # Bootloader needs SPIUnlock from this file, but doesn't # need other parts of this component set(srcs "spi_flash_rom_patch.c") + set(cache_srcs "") else() - set(srcs + set(cache_srcs "cache_utils.c" "flash_mmap.c" "flash_ops.c" + ) + set(srcs "partition.c" "spi_flash_rom_patch.c" ) # New implementation + list(APPEND cache_srcs + "esp_flash_api.c" + "esp_flash_spi_init.c" + "spi_flash_os_func_app.c" + "spi_flash_os_func_noos.c" + ) list(APPEND srcs "spi_flash_chip_drivers.c" "spi_flash_chip_generic.c" "spi_flash_chip_issi.c" - "spi_flash_os_func_app.c" - "spi_flash_os_func_noos.c" "memspi_host_driver.c" - "esp_flash_api.c" - "esp_flash_spi_init.c" ) + list(APPEND srcs ${cache_srcs}) set(priv_requires bootloader_support app_update soc) endif() @@ -30,3 +36,7 @@ idf_component_register(SRCS "${srcs}" INCLUDE_DIRS include PRIV_INCLUDE_DIRS private_include LDFRAGMENTS linker.lf) + +# Avoid cache miss by unexpected inlineing when built by -Os +set_source_files_properties(${cache_srcs} PROPERTIES COMPILE_FLAGS + "-fno-inline-functions -fno-inline-small-functions -fno-inline-functions-called-once") diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index bb5be1bb84..7cb0e0d139 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -60,7 +60,7 @@ static const char io_mode_str[][IO_STR_LEN] = { "qio", }; -_Static_assert(sizeof(io_mode_str)/IO_STR_LEN == SPI_FLASH_READ_MODE_MAX, "the io_mode_str should be consistent with the esp_flash_read_mode_t defined in spi_flash_ll.h"); +_Static_assert(sizeof(io_mode_str)/IO_STR_LEN == SPI_FLASH_READ_MODE_MAX, "the io_mode_str should be consistent with the esp_flash_io_mode_t defined in spi_flash_ll.h"); /* Static function to notify OS of a new SPI flash operation. @@ -139,38 +139,51 @@ esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip) if (err == ESP_OK) { // Try to set the flash mode to whatever default mode was chosen - err = chip->chip_drv->set_read_mode(chip); + err = chip->chip_drv->set_io_mode(chip); + if (err == ESP_ERR_FLASH_NO_RESPONSE && !esp_flash_is_quad_mode(chip)) { + //some chips (e.g. Winbond) don't support to clear QE, treat as success + err = ESP_OK; + } } // Done: all fields on 'chip' are initialised return spiflash_end(chip, err); } +//this is not public, but useful in unit tests +esp_err_t IRAM_ATTR esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id) +{ + esp_err_t err = spiflash_start(chip); + if (err != ESP_OK) { + return err; + } + + // Send generic RDID command twice, check for a matching result and retry in case we just powered on (inner + // function fails if it sees all-ones or all-zeroes.) + err = chip->host->read_id(chip->host, flash_id); + + if (err == ESP_OK) { // check we see the same ID twice, in case of transient power-on errors + uint32_t new_id; + err = chip->host->read_id(chip->host, &new_id); + if (err == ESP_OK && (new_id != *flash_id)) { + err = ESP_ERR_FLASH_NOT_INITIALISED; + } + } + + return spiflash_end(chip, err); +} + static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip) { esp_err_t err; uint32_t flash_id; int retries = 10; do { - err = spiflash_start(chip); - if (err != ESP_OK) { - return err; - } - - // Send generic RDID command twice, check for a matching result and retry in case we just powered on (inner - // function fails if it sees all-ones or all-zeroes.) - err = chip->host->read_id(chip->host, &flash_id); - - if (err == ESP_OK) { // check we see the same ID twice, in case of transient power-on errors - uint32_t new_id; - err = chip->host->read_id(chip->host, &new_id); - if (err == ESP_OK && (new_id != flash_id)) { - err = ESP_ERR_FLASH_NOT_INITIALISED; - } - } - - err = spiflash_end(chip, err); - } while (err != ESP_OK && retries-- > 0); + err = esp_flash_read_chip_id(chip, &flash_id); + } while (err == ESP_ERR_FLASH_NOT_INITIALISED && retries-- > 0); + if (err != ESP_OK) { + return err; + } // Detect the chip and set the chip_drv structure for it const spi_flash_chip_t **drivers = esp_flash_registered_chips; @@ -617,6 +630,36 @@ esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address return spi_flash_read_encrypted(address, out_buffer, length); } +// test only, non-public +IRAM_ATTR esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe) +{ + VERIFY_OP(get_io_mode); + esp_flash_io_mode_t io_mode; + + esp_err_t err = spiflash_start(chip); + if (err != ESP_OK) { + return err; + } + err = chip->chip_drv->get_io_mode(chip, &io_mode); + err = spiflash_end(chip, err); + if (err == ESP_OK) { + *qe = (io_mode == SPI_FLASH_QOUT); + } + return err; +} + +IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe) +{ + VERIFY_OP(set_io_mode); + chip->read_mode = (qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD); + esp_err_t err = spiflash_start(chip); + if (err != ESP_OK) { + return err; + } + err = chip->chip_drv->set_io_mode(chip); + return spiflash_end(chip, err); +} + #ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL esp_err_t esp_flash_app_disable_protect(bool disable) { diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 01b6ec7172..67e7d2064b 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -62,7 +62,7 @@ __attribute__((unused)) static const char TAG[] = "spi_flash"; esp_flash_t *esp_flash_default_chip = NULL; -static IRAM_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool use_iomux) +static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool use_iomux) { //Not using spicommon_cs_initialize since we don't want to put the whole //spi_periph_signal into the DRAM. Copy these data from flash before the diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index caca075960..b2b38806d9 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -63,7 +63,7 @@ struct esp_flash_t { const esp_flash_os_functions_t *os_func; ///< Pointer to os-specific hook structure. Call ``esp_flash_init_os_functions()`` to setup this field, after the host is properly initialized. void *os_func_data; ///< Pointer to argument for os-specific hooks. Left NULL and will be initialized with ``os_func``. - esp_flash_read_mode_t read_mode; ///< Configured SPI flash read mode. Set before ``esp_flash_init`` is called. + esp_flash_io_mode_t read_mode; ///< Configured SPI flash read mode. Set before ``esp_flash_init`` is called. uint32_t size; ///< Size of SPI flash in bytes. If 0, size will be detected during initialisation. }; @@ -286,6 +286,22 @@ esp_err_t esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *ou extern esp_flash_t *esp_flash_default_chip; +/******************************************************************************* + * Utility Functions + ******************************************************************************/ + +/** + * @brief Returns true if chip is configured for Quad I/O or Quad Fast Read. + * + * @param chip Pointer to SPI flash chip to use. If NULL, esp_flash_default_chip is substituted. + * + * @return true if flash works in quad mode, otherwise false + */ +static inline bool esp_flash_is_quad_mode(const esp_flash_t *chip) +{ + return (chip->read_mode == SPI_FLASH_QIO) || (chip->read_mode == SPI_FLASH_QOUT); +} + #ifdef __cplusplus } #endif diff --git a/components/spi_flash/include/esp_flash_spi_init.h b/components/spi_flash/include/esp_flash_spi_init.h index 4a26a4fd1b..f7e9816183 100644 --- a/components/spi_flash/include/esp_flash_spi_init.h +++ b/components/spi_flash/include/esp_flash_spi_init.h @@ -22,7 +22,7 @@ typedef struct { spi_host_device_t host_id; ///< Bus to use int cs_id; ///< CS pin (signal) to use int cs_io_num; ///< GPIO pin to output the CS signal - esp_flash_read_mode_t io_mode; ///< IO mode to read from the Flash + esp_flash_io_mode_t io_mode; ///< IO mode to read from the Flash esp_flash_speed_t speed; ///< Speed of the Flash clock int input_delay_ns; ///< Input delay of the data pins, in ns. Set to 0 if unknown. } esp_flash_spi_device_config_t; diff --git a/components/spi_flash/include/memspi_host_driver.h b/components/spi_flash/include/memspi_host_driver.h index cb0f3e9d9e..a200f20edd 100644 --- a/components/spi_flash/include/memspi_host_driver.h +++ b/components/spi_flash/include/memspi_host_driver.h @@ -32,7 +32,7 @@ .read = spi_flash_hal_read, \ .max_read_bytes = SPI_FLASH_HAL_MAX_READ_BYTES, \ .host_idle = spi_flash_hal_host_idle, \ - .configure_host_read_mode = spi_flash_hal_configure_host_read_mode, \ + .configure_host_io_mode = spi_flash_hal_configure_host_io_mode, \ .poll_cmd_done = spi_flash_hal_poll_cmd_done, \ .flush_cache = memspi_host_flush_cache, \ } diff --git a/components/spi_flash/include/spi_flash_chip_driver.h b/components/spi_flash/include/spi_flash_chip_driver.h index 9dd8ffa971..46667350de 100644 --- a/components/spi_flash/include/spi_flash_chip_driver.h +++ b/components/spi_flash/include/spi_flash_chip_driver.h @@ -149,7 +149,13 @@ struct spi_flash_chip_t { * * Can return ESP_ERR_FLASH_UNSUPPORTED_HOST or ESP_ERR_FLASH_UNSUPPORTED_CHIP if the specified mode is unsupported. */ - esp_err_t (*set_read_mode)(esp_flash_t *chip); + esp_err_t (*set_io_mode)(esp_flash_t *chip); + + /* + * Get whether the Quad Enable (QE) is set. (*out_io_mode)=SPI_FLASH_QOUT if + * enabled, otherwise disabled + */ + esp_err_t (*get_io_mode)(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode); }; /* Pointer to an array of pointers to all known drivers for flash chips. This array is used diff --git a/components/spi_flash/include/spi_flash_chip_generic.h b/components/spi_flash/include/spi_flash_chip_generic.h index 672ca6550b..36dd3cb89e 100644 --- a/components/spi_flash/include/spi_flash_chip_generic.h +++ b/components/spi_flash/include/spi_flash_chip_generic.h @@ -213,7 +213,21 @@ esp_err_t spi_flash_chip_generic_wait_idle(esp_flash_t *chip, uint32_t timeout_m * - ESP_ERR_TIMEOUT if not idle before timeout * - or other error passed from the ``set_write_protect`` or ``common_command`` function of host driver */ -esp_err_t spi_flash_chip_generic_set_read_mode(esp_flash_t *chip); +esp_err_t spi_flash_chip_generic_set_io_mode(esp_flash_t *chip); + +/** + * Get whether the Quad Enable (QE) is set. + * + * @param chip Pointer to SPI flash chip to use. If NULL, esp_flash_default_chip is substituted. + * @param out_quad_mode Pointer to store the output mode. + * - SPI_FLASH_QOUT: QE is enabled + * - otherwise: QE is disabled + * + * @return + * - ESP_OK if success + * - or other error passed from the ``common_command`` function of host driver + */ +esp_err_t spi_flash_chip_generic_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_quad_mode); /** * Generic SPI flash chip_drv, uses all the above functions for its operations. @@ -244,6 +258,78 @@ extern const spi_flash_chip_t esp_flash_chip_generic; */ esp_err_t spi_flash_generic_wait_host_idle(esp_flash_t *chip, uint32_t *timeout_ms); +/// Function pointer type for reading status register with QE bit. +typedef esp_err_t (*esp_flash_rdsr_func_t)(esp_flash_t* chip, uint32_t* out_sr); + +/** + * Use RDSR2 (35H) to read bit 15-8 of the SR, and RDSR (05H) to read bit 7-0. + * + * @param chip Pointer to SPI flash chip to use. + * @param out_sr Pointer to buffer to hold the status register, 16 bits. + * + * @return ESP_OK if success, otherwise error code passed from the + * `common_command` function of the host driver. + */ +esp_err_t spi_flash_common_read_status_16b_rdsr_rdsr2(esp_flash_t* chip, uint32_t* out_sr); + +/** + * Use RDSR2 (35H) to read bit 15-8 of the SR. + * + * @param chip Pointer to SPI flash chip to use. + * @param out_sr Pointer to buffer to hold the status register, 8 bits. + * + * @return ESP_OK if success, otherwise error code passed from the + * `common_command` function of the host driver. + */ +esp_err_t spi_flash_common_read_status_8b_rdsr2(esp_flash_t* chip, uint32_t* out_sr); + +/** + * Use RDSR (05H) to read bit 7-0 of the SR. + * + * @param chip Pointer to SPI flash chip to use. + * @param out_sr Pointer to buffer to hold the status register, 8 bits. + * + * @return ESP_OK if success, otherwise error code passed from the + * `common_command` function of the host driver. + */ +esp_err_t spi_flash_common_read_status_8b_rdsr(esp_flash_t* chip, uint32_t* out_sr); + +/// Function pointer type for writing status register with QE bit. +typedef esp_err_t (*esp_flash_wrsr_func_t)(esp_flash_t* chip, uint32_t sr); + +/** + * Use WRSR (01H) to write bit 7-0 of the SR. + * + * @param chip Pointer to SPI flash chip to use. + * @param sr Value of the status register to write, 8 bits. + * + * @return ESP_OK if success, otherwise error code passed from the + * `common_command` function of the host driver. + */ +esp_err_t spi_flash_common_write_status_8b_wrsr(esp_flash_t* chip, uint32_t sr); + +/** + * Use WRSR (01H) to write bit 15-0 of the SR. + * + * @param chip Pointer to SPI flash chip to use. + * @param sr Value of the status register to write, 16 bits. + * + * @return ESP_OK if success, otherwise error code passed from the + * `common_command` function of the host driver. + */ +esp_err_t spi_flash_common_write_status_16b_wrsr(esp_flash_t* chip, uint32_t sr); + +/** + * Use WRSR2 (31H) to write bit 15-8 of the SR. + * + * @param chip Pointer to SPI flash chip to use. + * @param sr Value of the status register to write, 8 bits. + * + * @return ESP_OK if success, otherwise error code passed from the + * `common_command` function of the host driver. + */ +esp_err_t spi_flash_common_write_status_8b_wrsr2(esp_flash_t* chip, uint32_t sr); + /** * @brief Utility function for set_read_mode chip_drv function. If required, * set and check the QE bit in the flash chip to enable the QIO/QOUT mode. @@ -253,16 +339,19 @@ esp_err_t spi_flash_generic_wait_host_idle(esp_flash_t *chip, uint32_t *timeout_ * * Registers to actually do Quad transtions and command to be sent in reading * should also be configured via - * spi_flash_chip_generic_config_host_read_mode(). + * spi_flash_chip_generic_config_host_io_mode(). * - * @param qe_rdsr_command SPI flash command to read status register - * @param qe_wrsr_command SPI flash command to write status register - * @param qe_sr_bitwidth Width of the status register these commands operate on, in bits. - * @param qe_sr_bit Bit mask for enabling Quad Enable functions on this chip. + * Note that the bit length and qe position of wrsr_func, rdsr_func and + * qe_sr_bit should be consistent. + * + * @param chip Pointer to SPI flash chip to use. + * @param wrsr_func Function pointer for writing the status register + * @param rdsr_func Function pointer for reading the status register + * @param qe_sr_bit status with the qe bit only. * * @return always ESP_OK (currently). */ -esp_err_t spi_flash_common_set_read_mode(esp_flash_t *chip, uint8_t qe_rdsr_command, uint8_t qe_wrsr_command, uint8_t qe_sr_bitwidth, unsigned qe_sr_bit); +esp_err_t spi_flash_common_set_io_mode(esp_flash_t *chip, esp_flash_wrsr_func_t wrsr_func, esp_flash_rdsr_func_t rdsr_func, uint32_t qe_sr_bit); /** * @brief Configure the host registers to use the specified read mode set in @@ -278,17 +367,4 @@ esp_err_t spi_flash_common_set_read_mode(esp_flash_t *chip, uint8_t qe_rdsr_comm * - ESP_ERR_FLASH_NOT_INITIALISED if chip not initialized properly * - or other error passed from the ``configure_host_mode`` function of host driver */ -esp_err_t spi_flash_chip_generic_config_host_read_mode(esp_flash_t *chip); - -/** - * @brief Returns true if chip is configured for Quad I/O or Quad Fast Read. - * - * @param chip Pointer to SPI flash chip to use. If NULL, esp_flash_default_chip is substituted. - * - * @return true if flash works in quad mode, otherwise false - */ -static inline bool spi_flash_is_quad_mode(const esp_flash_t *chip) -{ - return (chip->read_mode == SPI_FLASH_QIO) || (chip->read_mode == SPI_FLASH_QOUT); -} - +esp_err_t spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip); diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index 8bbb9d1374..16d6b85e16 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -144,7 +144,7 @@ esp_err_t spi_flash_chip_generic_read(esp_flash_t *chip, void *buffer, uint32_t { esp_err_t err = ESP_OK; // Configure the host, and return - spi_flash_chip_generic_config_host_read_mode(chip); + spi_flash_chip_generic_config_host_io_mode(chip); while (err == ESP_OK && length > 0) { uint32_t read_len = MIN(length, chip->host->max_read_bytes); @@ -277,7 +277,7 @@ esp_err_t spi_flash_chip_generic_wait_idle(esp_flash_t *chip, uint32_t timeout_m return (timeout_ms > 0) ? ESP_OK : ESP_ERR_TIMEOUT; } -esp_err_t spi_flash_chip_generic_config_host_read_mode(esp_flash_t *chip) +esp_err_t spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip) { uint32_t dummy_cyclelen_base; uint32_t addr_bitlen; @@ -320,62 +320,33 @@ esp_err_t spi_flash_chip_generic_config_host_read_mode(esp_flash_t *chip) return ESP_ERR_FLASH_NOT_INITIALISED; } - return chip->host->configure_host_read_mode(chip->host, chip->read_mode, addr_bitlen, dummy_cyclelen_base, read_command); + return chip->host->configure_host_io_mode(chip->host, read_command, addr_bitlen, dummy_cyclelen_base, + chip->read_mode); } -esp_err_t spi_flash_common_set_read_mode(esp_flash_t *chip, uint8_t qe_rdsr_command, uint8_t qe_wrsr_command, uint8_t qe_sr_bitwidth, unsigned qe_sr_bit) -{ - if (spi_flash_is_quad_mode(chip)) { - // Ensure quad modes are enabled, using the Quad Enable parameters supplied. - spi_flash_trans_t t = { - .command = qe_rdsr_command, - .mosi_data = 0, - .mosi_len = 0, - .miso_len = qe_sr_bitwidth, - }; - chip->host->common_command(chip->host, &t); - unsigned sr = t.miso_data[0]; - ESP_EARLY_LOGV(TAG, "set_read_mode: status before 0x%x", sr); - if ((sr & qe_sr_bit) == 0) { - //some chips needs the write protect to be disabled before writing to Status Register - chip->chip_drv->set_chip_write_protect(chip, false); - - sr |= qe_sr_bit; - spi_flash_trans_t t = { - .command = qe_wrsr_command, - .mosi_data = sr, - .mosi_len = qe_sr_bitwidth, - .miso_len = 0, - }; - chip->host->common_command(chip->host, &t); - - /* Check the new QE bit has stayed set */ - spi_flash_trans_t t_rdsr = { - .command = qe_rdsr_command, - .mosi_data = 0, - .mosi_len = 0, - .miso_len = qe_sr_bitwidth - }; - chip->host->common_command(chip->host, &t_rdsr); - sr = t_rdsr.miso_data[0]; - ESP_EARLY_LOGV(TAG, "set_read_mode: status after 0x%x", sr); - if ((sr & qe_sr_bit) == 0) { - return ESP_ERR_FLASH_NO_RESPONSE; - } - - chip->chip_drv->set_chip_write_protect(chip, true); - } - } - return ESP_OK; -} - -esp_err_t spi_flash_chip_generic_set_read_mode(esp_flash_t *chip) +esp_err_t spi_flash_chip_generic_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode) { // On "generic" chips, this involves checking // bit 1 (QE) of RDSR2 (35h) result // (it works this way on GigaDevice & Fudan Micro chips, probably others...) const uint8_t BIT_QE = 1 << 1; - return spi_flash_common_set_read_mode(chip, CMD_RDSR2, CMD_WRSR2, 8, BIT_QE); + uint32_t sr; + esp_err_t ret = spi_flash_common_read_status_8b_rdsr2(chip, &sr); + if (ret == ESP_OK) { + *out_io_mode = ((sr & BIT_QE)? SPI_FLASH_QOUT: 0); + } + return ret; +} + +esp_err_t spi_flash_chip_generic_set_io_mode(esp_flash_t *chip) +{ + // On "generic" chips, this involves checking + // bit 9 (QE) of RDSR (05h) result + const uint32_t BIT_QE = 1 << 9; + return spi_flash_common_set_io_mode(chip, + spi_flash_common_write_status_16b_wrsr, + spi_flash_common_read_status_16b_rdsr_rdsr2, + BIT_QE); } static const char chip_name[] = "generic"; @@ -409,5 +380,134 @@ const spi_flash_chip_t esp_flash_chip_generic = { .write_encrypted = spi_flash_chip_generic_write_encrypted, .wait_idle = spi_flash_chip_generic_wait_idle, - .set_read_mode = spi_flash_chip_generic_set_read_mode, + .set_io_mode = spi_flash_chip_generic_set_io_mode, + .get_io_mode = spi_flash_chip_generic_get_io_mode, }; + +/******************************************************************************* + * Utility functions + ******************************************************************************/ + +static esp_err_t spi_flash_common_read_qe_sr(esp_flash_t *chip, uint8_t qe_rdsr_command, uint8_t qe_sr_bitwidth, uint32_t *sr) +{ + spi_flash_trans_t t = { + .command = qe_rdsr_command, + .mosi_data = 0, + .mosi_len = 0, + .miso_len = qe_sr_bitwidth, + }; + esp_err_t ret = chip->host->common_command(chip->host, &t); + *sr = t.miso_data[0]; + return ret; +} + +static esp_err_t spi_flash_common_write_qe_sr(esp_flash_t *chip, uint8_t qe_wrsr_command, uint8_t qe_sr_bitwidth, uint32_t qe) +{ + spi_flash_trans_t t = { + .command = qe_wrsr_command, + .mosi_data = qe, + .mosi_len = qe_sr_bitwidth, + .miso_len = 0, + }; + return chip->host->common_command(chip->host, &t); +} + +esp_err_t spi_flash_common_read_status_16b_rdsr_rdsr2(esp_flash_t* chip, uint32_t* out_sr) +{ + uint32_t sr, sr2; + esp_err_t ret = spi_flash_common_read_qe_sr(chip, CMD_RDSR2, 8, &sr2); + if (ret == ESP_OK) { + ret = spi_flash_common_read_qe_sr(chip, CMD_RDSR, 8, &sr); + } + if (ret == ESP_OK) { + *out_sr = (sr & 0xff) | ((sr2 & 0xff) << 8); + } + return ret; +} + +esp_err_t spi_flash_common_read_status_8b_rdsr2(esp_flash_t* chip, uint32_t* out_sr) +{ + return spi_flash_common_read_qe_sr(chip, CMD_RDSR2, 8, out_sr); +} + +esp_err_t spi_flash_common_read_status_8b_rdsr(esp_flash_t* chip, uint32_t* out_sr) +{ + return spi_flash_common_read_qe_sr(chip, CMD_RDSR, 8, out_sr); +} + +esp_err_t spi_flash_common_write_status_16b_wrsr(esp_flash_t* chip, uint32_t sr) +{ + return spi_flash_common_write_qe_sr(chip, CMD_WRSR, 16, sr); +} + +esp_err_t spi_flash_common_write_status_8b_wrsr(esp_flash_t* chip, uint32_t sr) +{ + return spi_flash_common_write_qe_sr(chip, CMD_WRSR, 8, sr); +} + +esp_err_t spi_flash_common_write_status_8b_wrsr2(esp_flash_t* chip, uint32_t sr) +{ + return spi_flash_common_write_qe_sr(chip, CMD_WRSR2, 8, sr); +} + +esp_err_t spi_flash_common_set_io_mode(esp_flash_t *chip, esp_flash_wrsr_func_t wrsr_func, esp_flash_rdsr_func_t rdsr_func, uint32_t qe_sr_bit) +{ + esp_err_t ret = ESP_OK; + const bool is_quad_mode = esp_flash_is_quad_mode(chip); + bool update_config = false; + const bool force_check = true; //in case some chips doesn't support erase QE + + bool need_check = is_quad_mode; + if (force_check) { + need_check = true; + } + + uint32_t sr_update; + if (need_check) { + // Ensure quad modes are enabled, using the Quad Enable parameters supplied. + uint32_t sr; + ret = (*rdsr_func)(chip, &sr); + if (ret != ESP_OK) { + return ret; + } + ESP_EARLY_LOGD(TAG, "set_io_mode: status before 0x%x", sr); + if (is_quad_mode) { + sr_update = sr | qe_sr_bit; + } else { + sr_update = sr & (~qe_sr_bit); + } + ESP_EARLY_LOGV(TAG, "set_io_mode: status update 0x%x", sr_update); + if (sr != sr_update) { + update_config = true; + } + } + + if (update_config) { + //some chips needs the write protect to be disabled before writing to Status Register + chip->chip_drv->set_chip_write_protect(chip, false); + + ret = (*wrsr_func)(chip, sr_update); + if (ret != ESP_OK) { + return ret; + } + + ret = chip->chip_drv->wait_idle(chip, DEFAULT_IDLE_TIMEOUT); + if (ret != ESP_OK) { + return ret; + } + + /* Check the new QE bit has stayed set */ + uint32_t sr; + ret = (*rdsr_func)(chip, &sr); + if (ret != ESP_OK) { + return ret; + } + ESP_EARLY_LOGD(TAG, "set_io_mode: status after 0x%x", sr); + if (sr != sr_update) { + ret = ESP_ERR_FLASH_NO_RESPONSE; + } + + chip->chip_drv->set_chip_write_protect(chip, true); + } + return ret; +} diff --git a/components/spi_flash/spi_flash_chip_issi.c b/components/spi_flash/spi_flash_chip_issi.c index 71684ec195..d5ecd4c040 100644 --- a/components/spi_flash/spi_flash_chip_issi.c +++ b/components/spi_flash/spi_flash_chip_issi.c @@ -35,13 +35,29 @@ esp_err_t spi_flash_chip_issi_probe(esp_flash_t *chip, uint32_t flash_id) return ESP_OK; } -esp_err_t spi_flash_chip_issi_set_read_mode(esp_flash_t *chip) +esp_err_t spi_flash_chip_issi_set_io_mode(esp_flash_t *chip) { /* ISSI uses bit 6 of "basic" SR as Quad Enable */ const uint8_t BIT_QE = 1 << 6; - return spi_flash_common_set_read_mode(chip, CMD_RDSR, CMD_WRSR, 8, BIT_QE); + return spi_flash_common_set_io_mode(chip, + spi_flash_common_write_status_8b_wrsr, + spi_flash_common_read_status_8b_rdsr, + BIT_QE); } +esp_err_t spi_flash_chip_issi_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode) +{ + /* ISSI uses bit 6 of "basic" SR as Quad Enable */ + const uint8_t BIT_QE = 1 << 6; + uint32_t sr; + esp_err_t ret = spi_flash_common_read_status_8b_rdsr(chip, &sr); + if (ret == ESP_OK) { + *out_io_mode = ((sr & BIT_QE)? SPI_FLASH_QOUT: 0); + } + return ret; +} + + static const char chip_name[] = "issi"; // The issi chip can use the functions for generic chips except from set read mode and probe, @@ -73,5 +89,6 @@ const spi_flash_chip_t esp_flash_chip_issi = { .write_encrypted = spi_flash_chip_generic_write_encrypted, .wait_idle = spi_flash_chip_generic_wait_idle, - .set_read_mode = spi_flash_chip_issi_set_read_mode, + .set_io_mode = spi_flash_chip_issi_set_io_mode, + .get_io_mode = spi_flash_chip_issi_get_io_mode, }; diff --git a/components/spi_flash/test/test_esp_flash.c b/components/spi_flash/test/test_esp_flash.c index f6eaf94f15..338553ff10 100644 --- a/components/spi_flash/test/test_esp_flash.c +++ b/components/spi_flash/test/test_esp_flash.c @@ -127,7 +127,7 @@ static void release_bus(int host_id) } } -static void setup_new_chip(esp_flash_read_mode_t io_mode, esp_flash_speed_t speed) +static void setup_new_chip(esp_flash_io_mode_t io_mode, esp_flash_speed_t speed) { //the bus should be initialized before the flash is attached to the bus setup_bus(TEST_HOST); From 15d311bb80ecd9191fcabd4a846711b433c4448c Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Thu, 5 Sep 2019 13:17:11 +0800 Subject: [PATCH 09/21] esp_flash: rename internal variables for better readability chip_drv in HAL are renamed as host --- components/soc/src/hal/spi_flash_hal_iram.c | 64 ++++++++++----------- components/spi_flash/memspi_host_driver.c | 4 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/components/soc/src/hal/spi_flash_hal_iram.c b/components/soc/src/hal/spi_flash_hal_iram.c index ea8e2bfbc7..a6fb23fe5a 100644 --- a/components/soc/src/hal/spi_flash_hal_iram.c +++ b/components/soc/src/hal/spi_flash_hal_iram.c @@ -19,22 +19,22 @@ #define ADDRESS_MASK_24BIT 0xFFFFFF -static inline spi_dev_t *get_spi_dev(spi_flash_host_driver_t *chip_drv) +static inline spi_dev_t *get_spi_dev(spi_flash_host_driver_t *host) { - return ((spi_flash_memspi_data_t *)chip_drv->driver_data)->spi; + return ((spi_flash_memspi_data_t *)host->driver_data)->spi; } -void spi_flash_hal_poll_cmd_done(spi_flash_host_driver_t *driver) +void spi_flash_hal_poll_cmd_done(spi_flash_host_driver_t *host) { - while (!spi_flash_ll_cmd_is_done(get_spi_dev(driver))) { + while (!spi_flash_ll_cmd_is_done(get_spi_dev(host))) { //nop } } -esp_err_t spi_flash_hal_device_config(spi_flash_host_driver_t *driver) +esp_err_t spi_flash_hal_device_config(spi_flash_host_driver_t *host) { - spi_flash_memspi_data_t *drv_data = (spi_flash_memspi_data_t *)driver->driver_data; - spi_dev_t *dev = get_spi_dev(driver); + spi_flash_memspi_data_t *drv_data = (spi_flash_memspi_data_t *)host->driver_data; + spi_dev_t *dev = get_spi_dev(host); spi_flash_ll_reset(dev); spi_flash_ll_set_cs_pin(dev, drv_data->cs_num); spi_flash_ll_set_clock(dev, &drv_data->clock_conf); @@ -60,9 +60,9 @@ esp_err_t spi_flash_hal_configure_host_io_mode( esp_flash_io_mode_t io_mode) { // Add dummy cycles to compensate for latency of GPIO matrix and external delay, if necessary... - int dummy_cyclelen = dummy_cyclelen_base + ((spi_flash_memspi_data_t *)driver->driver_data)->extra_dummy; + int dummy_cyclelen = dummy_cyclelen_base + ((spi_flash_memspi_data_t *)host->driver_data)->extra_dummy; - spi_dev_t *dev = get_spi_dev(driver); + spi_dev_t *dev = get_spi_dev(host); spi_flash_ll_set_command8(dev, command); spi_flash_ll_set_addr_bitlen(dev, addr_bitlen); spi_flash_ll_set_dummy(dev, dummy_cyclelen); @@ -73,11 +73,11 @@ esp_err_t spi_flash_hal_configure_host_io_mode( return ESP_OK; } -esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *chip_drv, spi_flash_trans_t *trans) +esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *host, spi_flash_trans_t *trans) { host->configure_host_io_mode(host, trans->command, 0, 0, SPI_FLASH_FASTRD); - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); //disable dummy if no input phase if (trans->miso_len == 0) { spi_flash_ll_set_dummy(dev, 0); @@ -89,61 +89,61 @@ esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *chip_drv, spi_fl spi_flash_ll_write_word(dev, trans->mosi_data); spi_flash_ll_user_start(dev); - chip_drv->poll_cmd_done(chip_drv); + host->poll_cmd_done(host); spi_flash_ll_get_buffer_data(dev, trans->miso_data, 8); return ESP_OK; } -void spi_flash_hal_erase_chip(spi_flash_host_driver_t *chip_drv) +void spi_flash_hal_erase_chip(spi_flash_host_driver_t *host) { - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); spi_flash_ll_erase_chip(dev); - chip_drv->poll_cmd_done(chip_drv); + host->poll_cmd_done(host); } -void spi_flash_hal_erase_sector(spi_flash_host_driver_t *chip_drv, uint32_t start_address) +void spi_flash_hal_erase_sector(spi_flash_host_driver_t *host, uint32_t start_address) { - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); spi_flash_ll_set_addr_bitlen(dev, 24); spi_flash_ll_set_address(dev, start_address & ADDRESS_MASK_24BIT); spi_flash_ll_erase_sector(dev); - chip_drv->poll_cmd_done(chip_drv); + host->poll_cmd_done(host); } -void spi_flash_hal_erase_block(spi_flash_host_driver_t *chip_drv, uint32_t start_address) +void spi_flash_hal_erase_block(spi_flash_host_driver_t *host, uint32_t start_address) { - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); spi_flash_ll_set_addr_bitlen(dev, 24); spi_flash_ll_set_address(dev, start_address & ADDRESS_MASK_24BIT); spi_flash_ll_erase_block(dev); - chip_drv->poll_cmd_done(chip_drv); + host->poll_cmd_done(host); } -void spi_flash_hal_program_page(spi_flash_host_driver_t *chip_drv, const void *buffer, uint32_t address, uint32_t length) +void spi_flash_hal_program_page(spi_flash_host_driver_t *host, const void *buffer, uint32_t address, uint32_t length) { - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); spi_flash_ll_set_addr_bitlen(dev, 24); spi_flash_ll_set_address(dev, (address & ADDRESS_MASK_24BIT) | (length << 24)); spi_flash_ll_program_page(dev, buffer, length); - chip_drv->poll_cmd_done(chip_drv); + host->poll_cmd_done(host); } -esp_err_t spi_flash_hal_read(spi_flash_host_driver_t *chip_drv, void *buffer, uint32_t address, uint32_t read_len) +esp_err_t spi_flash_hal_read(spi_flash_host_driver_t *host, void *buffer, uint32_t address, uint32_t read_len) { - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); //the command is already set by ``spi_flash_hal_configure_host_io_mode`` before. spi_flash_ll_set_address(dev, address << 8); spi_flash_ll_set_miso_bitlen(dev, read_len * 8); spi_flash_ll_user_start(dev); - chip_drv->poll_cmd_done(chip_drv); + host->poll_cmd_done(host); spi_flash_ll_get_buffer_data(dev, buffer, read_len); return ESP_OK; } -bool spi_flash_hal_host_idle(spi_flash_host_driver_t *chip_drv) +bool spi_flash_hal_host_idle(spi_flash_host_driver_t *host) { - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); bool idle = spi_flash_ll_host_idle(dev); // Not clear if this is necessary, or only necessary if @@ -155,10 +155,10 @@ bool spi_flash_hal_host_idle(spi_flash_host_driver_t *chip_drv) return idle; } -esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_driver_t *chip_drv, bool wp) +esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_driver_t *host, bool wp) { - spi_dev_t *dev = get_spi_dev(chip_drv); + spi_dev_t *dev = get_spi_dev(host); spi_flash_ll_set_write_protect(dev, wp); - chip_drv->poll_cmd_done(chip_drv); + host->poll_cmd_done(host); return ESP_OK; } diff --git a/components/spi_flash/memspi_host_driver.c b/components/spi_flash/memspi_host_driver.c index 85b31998a0..adc900cd7a 100644 --- a/components/spi_flash/memspi_host_driver.c +++ b/components/spi_flash/memspi_host_driver.c @@ -38,7 +38,7 @@ esp_err_t memspi_host_init_pointers(spi_flash_host_driver_t *host, memspi_host_d return ESP_OK; } -esp_err_t memspi_host_read_id_hs(spi_flash_host_driver_t *chip_drv, uint32_t *id) +esp_err_t memspi_host_read_id_hs(spi_flash_host_driver_t *host, uint32_t *id) { //NOTE: we do have a read id function, however it doesn't work in high freq spi_flash_trans_t t = { @@ -47,7 +47,7 @@ esp_err_t memspi_host_read_id_hs(spi_flash_host_driver_t *chip_drv, uint32_t *id .mosi_len = 0, .miso_len = 24 }; - chip_drv->common_command(chip_drv, &t); + host->common_command(host, &t); uint32_t raw_flash_id = t.miso_data[0]; ESP_EARLY_LOGV(TAG, "raw_chip_id: %X\n", raw_flash_id); if (raw_flash_id == 0xFFFFFF || raw_flash_id == 0) { From 1e1d50376b04e7ce66e0a2ef9fd0c1a3fe8e56a0 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Wed, 4 Sep 2019 21:09:30 +0800 Subject: [PATCH 10/21] esp_flash: add unit test for external flash and QE toggling Tests for external flash chips used to controlled by macros, one bin for one chip. And tests are done manually. This commit refactored the test so that all 3 chips can all run in single test. --- components/spi_flash/test/test_esp_flash.c | 359 ++++++++++++--------- tools/ci/config/target-test.yml | 8 + 2 files changed, 219 insertions(+), 148 deletions(-) diff --git a/components/spi_flash/test/test_esp_flash.c b/components/spi_flash/test/test_esp_flash.c index 338553ff10..0e5679f738 100644 --- a/components/spi_flash/test/test_esp_flash.c +++ b/components/spi_flash/test/test_esp_flash.c @@ -16,19 +16,18 @@ #include "unity.h" #include "driver/gpio.h" #include "soc/io_mux_reg.h" - +#include "sdkconfig.h" #define FUNC_SPI 1 static uint8_t sector_buf[4096]; -// #define TEST_SPI1_CS1 -// #define TEST_SPI2_CS0 -// #define TEST_SPI3_CS0 #define TEST_SPI_SPEED ESP_FLASH_10MHZ #define TEST_SPI_READ_MODE SPI_FLASH_FASTRD //#define FORCE_GPIO_MATRIX +#define EXTRA_SPI1_CLK_IO 17 //the pin which is usually used by the PSRAM clk + #define HSPI_PIN_NUM_MOSI HSPI_IOMUX_PIN_NUM_MOSI #define HSPI_PIN_NUM_MISO HSPI_IOMUX_PIN_NUM_MISO #define HSPI_PIN_NUM_CLK HSPI_IOMUX_PIN_NUM_CLK @@ -41,40 +40,56 @@ static uint8_t sector_buf[4096]; #define VSPI_PIN_NUM_HD VSPI_IOMUX_PIN_NUM_HD #define VSPI_PIN_NUM_WP VSPI_IOMUX_PIN_NUM_WP -#if defined TEST_SPI1_CS1 -# define TEST_HOST SPI_HOST -# define TEST_CS 1 -// #define TEST_CS_PIN 14 -# define TEST_CS_PIN 16 //the pin which is usually used by the PSRAM -// #define TEST_CS_PIN 27 -# define TEST_INPUT_DELAY 0 -# define EXTRA_SPI1_CLK_IO 17 //the pin which is usually used by the PSRAM clk - -#elif defined TEST_SPI2_CS0 - -# define TEST_HOST HSPI_HOST -# define TEST_CS 0 -# define TEST_CS_PIN HSPI_IOMUX_PIN_NUM_CS -# define TEST_INPUT_DELAY 20 - -#elif defined TEST_SPI3_CS0 - -# define TEST_HOST VSPI_HOST -# define TEST_CS 0 -# define TEST_CS_PIN VSPI_IOMUX_PIN_NUM_CS -# define TEST_INPUT_DELAY 0 +#define ALL_TEST_NUM (sizeof(config_list)/sizeof(flashtest_config_t)) +typedef void (*flash_test_func_t)(esp_flash_t* chip); +#define FLASH_TEST_CASE(STR, FUNC_TO_RUN) \ + TEST_CASE(STR, "[esp_flash]") {flash_test_func(FUNC_TO_RUN, 1);} +#ifdef CONFIG_ESP32_SPIRAM_SUPPORT +// These tests needs external flash, right on the place of psram +#define FLASH_TEST_CASE_3(STR, FUNCT_TO_RUN) #else -# define SKIP_EXTENDED_CHIP_TEST +#define FLASH_TEST_CASE_3(STR, FUNC_TO_RUN) \ + TEST_CASE(STR", 3 chips", "[esp_flash][test_env=UT_T1_ESP_FLASH]") {flash_test_func(FUNC_TO_RUN, ALL_TEST_NUM);} #endif +//currently all the configs are the same with esp_flash_spi_device_config_t, no more information required +typedef esp_flash_spi_device_config_t flashtest_config_t; static const char TAG[] = "test_esp_flash"; - -#ifndef SKIP_EXTENDED_CHIP_TEST - -static esp_flash_t *test_chip = NULL; +flashtest_config_t config_list[] = { + // 0 always reserved for main flash + { + .host_id = -1, // no need to init + }, + { + .io_mode = TEST_SPI_READ_MODE, + .speed = TEST_SPI_SPEED, + .host_id = SPI_HOST, + .cs_id = 1, + .cs_io_num = 16, //the pin which is usually used by the PSRAM + .input_delay_ns = 0, + }, + /* current runner doesn't have a flash on HSPI + { + .io_mode = TEST_SPI_READ_MODE, + .speed = TEST_SPI_SPEED, + .host = HSPI_HOST, + .cs_id = 0, + .cs_io_num = HSPI_IOMUX_PIN_NUM_CS, + .input_delay_ns = 20, + }, + */ + { + .io_mode = TEST_SPI_READ_MODE, + .speed = TEST_SPI_SPEED, + .host_id = VSPI_HOST, + .cs_id = 0, + .cs_io_num = VSPI_IOMUX_PIN_NUM_CS, + .input_delay_ns = 0, + }, +}; static void setup_bus(spi_host_device_t host_id) { @@ -127,33 +142,50 @@ static void release_bus(int host_id) } } -static void setup_new_chip(esp_flash_io_mode_t io_mode, esp_flash_speed_t speed) +static void setup_new_chip(const flashtest_config_t* test_cfg, esp_flash_t** out_chip) { //the bus should be initialized before the flash is attached to the bus - setup_bus(TEST_HOST); + if (test_cfg->host_id == -1) { + *out_chip = NULL; + return; + } + setup_bus(test_cfg->host_id); esp_flash_spi_device_config_t dev_cfg = { - .host_id = TEST_HOST, - .io_mode = io_mode, - .speed = speed, - .cs_id = TEST_CS, - .cs_io_num = TEST_CS_PIN, - .input_delay_ns = TEST_INPUT_DELAY, + .host_id = test_cfg->host_id, + .io_mode = test_cfg->io_mode, + .speed = test_cfg->speed, + .cs_id = test_cfg->cs_id, + .cs_io_num = test_cfg->cs_io_num, + .input_delay_ns = test_cfg->input_delay_ns, }; - esp_err_t err = spi_bus_add_flash_device(&test_chip, &dev_cfg); + esp_flash_t* init_chip; + esp_err_t err = spi_bus_add_flash_device(&init_chip, &dev_cfg); TEST_ESP_OK(err); - err = esp_flash_init(test_chip); + err = esp_flash_init(init_chip); TEST_ESP_OK(err); + *out_chip = init_chip; } -void teardown_test_chip(void) +void teardown_test_chip(esp_flash_t* chip, spi_host_device_t host) { - spi_bus_remove_flash_device(test_chip); - test_chip = NULL; - release_bus(TEST_HOST); + //happen to work when chip==NULL + spi_bus_remove_flash_device(chip); + release_bus(host); } -#endif +static void flash_test_func(flash_test_func_t func, int test_num) +{ + for (int i = 0; i < test_num; i++) { + flashtest_config_t* config = &config_list[i]; + esp_flash_t* chip; + setup_new_chip(config, &chip); + (*func)(chip); + teardown_test_chip(chip, config->host_id); + } +} + +/* ---------- Test code start ------------*/ static void test_metadata(esp_flash_t *chip) { @@ -164,15 +196,8 @@ static void test_metadata(esp_flash_t *chip) printf("Flash ID %08x detected size %d bytes\n", id, size); } -TEST_CASE("SPI flash metadata functions", "[esp_flash]") -{ -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_metadata(test_chip); - teardown_test_chip(); -#endif - test_metadata(NULL); -} +FLASH_TEST_CASE("SPI flash metadata functions", test_metadata); +FLASH_TEST_CASE_3("SPI flash metadata functions", test_metadata); static uint32_t erase_test_region(esp_flash_t *chip, int num_sectors) { @@ -203,7 +228,7 @@ static uint32_t erase_test_region(esp_flash_t *chip, int num_sectors) return offs; } -void test_simple_read_write(void *chip) +void test_simple_read_write(esp_flash_t *chip) { ESP_LOGI(TAG, "Testing chip %p...", chip); uint32_t offs = erase_test_region(chip, 1); @@ -230,17 +255,10 @@ void test_simple_read_write(void *chip) } } -TEST_CASE("SPI flash simple read/write", "[esp_flash]") -{ - test_simple_read_write(NULL); -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_simple_read_write(test_chip); - teardown_test_chip(); -#endif -} +FLASH_TEST_CASE("SPI flash simple read/write", test_simple_read_write); +FLASH_TEST_CASE_3("SPI flash simple read/write", test_simple_read_write); -void test_unaligned_read_write(void *chip) +void test_unaligned_read_write(esp_flash_t *chip) { ESP_LOGI(TAG, "Testing chip %p...", chip); uint32_t offs = erase_test_region(chip, 2); @@ -258,17 +276,10 @@ void test_unaligned_read_write(void *chip) TEST_ASSERT(memcmp(buf, msg, strlen(msg) + 1) == 0); } -TEST_CASE("SPI flash unaligned read/write", "[esp_flash]") -{ -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_unaligned_read_write(test_chip); - teardown_test_chip(); -#endif - test_unaligned_read_write(NULL); -} +FLASH_TEST_CASE("SPI flash unaligned read/write", test_unaligned_read_write); +FLASH_TEST_CASE_3("SPI flash unaligned read/write", test_unaligned_read_write); -void test_single_read_write(void *chip) +void test_single_read_write(esp_flash_t* chip) { ESP_LOGI(TAG, "Testing chip %p...", chip); uint32_t offs = erase_test_region(chip, 2); @@ -284,21 +295,14 @@ void test_single_read_write(void *chip) } } -TEST_CASE("SPI flash single byte reads/writes", "[esp_flash]") -{ - test_single_read_write(NULL); -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_single_read_write(test_chip); - teardown_test_chip(); -#endif -} +FLASH_TEST_CASE("SPI flash single byte reads/writes", test_single_read_write); +FLASH_TEST_CASE_3("SPI flash single byte reads/writes", test_single_read_write); /* this test is notable because it generates a lot of unaligned reads/writes, and also reads/writes across both a sector boundary & many page boundaries. */ -void test_three_byte_read_write(void *chip) +void test_three_byte_read_write(esp_flash_t *chip) { ESP_LOGI(TAG, "Testing chip %p...", chip); uint32_t offs = erase_test_region(chip, 2); @@ -315,15 +319,8 @@ void test_three_byte_read_write(void *chip) } } -TEST_CASE("SPI flash three byte reads/writes", "[esp_flash]") -{ -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_three_byte_read_write(test_chip); - teardown_test_chip(); -#endif - test_three_byte_read_write(NULL); -} +FLASH_TEST_CASE("SPI flash three byte reads/writes", test_three_byte_read_write); +FLASH_TEST_CASE_3("SPI flash three byte reads/writes", test_three_byte_read_write); void test_erase_large_region(esp_flash_t *chip) { @@ -355,15 +352,8 @@ void test_erase_large_region(esp_flash_t *chip) TEST_ASSERT_EQUAL_HEX32(0xFFFFFFFF, readback); } -TEST_CASE("SPI flash erase large region", "[esp_flash]") -{ - test_erase_large_region(NULL); -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_erase_large_region(test_chip); - teardown_test_chip(); -#endif -} +FLASH_TEST_CASE("SPI flash erase large region", test_erase_large_region); +FLASH_TEST_CASE_3("SPI flash erase large region", test_erase_large_region); static void test_write_protection(esp_flash_t* chip) { @@ -385,15 +375,8 @@ static void test_write_protection(esp_flash_t* chip) } } -TEST_CASE("Test esp_flash can enable/disable write protetion", "[esp_flash]") -{ - test_write_protection(NULL); -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_write_protection(test_chip); - teardown_test_chip(); -#endif -} +FLASH_TEST_CASE("Test esp_flash can enable/disable write protetion", test_write_protection); +FLASH_TEST_CASE_3("Test esp_flash can enable/disable write protetion", test_write_protection); static const uint8_t large_const_buffer[16400] = { 203, // first byte @@ -410,8 +393,73 @@ static void test_write_large_buffer(esp_flash_t *chip, const uint8_t *source, si static void write_large_buffer(esp_flash_t *chip, const esp_partition_t *part, const uint8_t *source, size_t length); static void read_and_check(esp_flash_t *chip, const esp_partition_t *part, const uint8_t *source, size_t length); -TEST_CASE("SPI flash test reading with all speed/mode permutations", "[esp_flash]") +// Internal functions for testing, from esp_flash_api.c +esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe); +esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe); +esp_err_t esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id); + +static bool check_winbond_chip(esp_flash_t* chip) { + uint32_t flash_id; + esp_err_t ret = esp_flash_read_chip_id(chip, &flash_id); + TEST_ESP_OK(ret); + if ((flash_id >> 16) == 0xEF) { + return true; + } else { + return false; + } +} + +static void test_toggle_qe(esp_flash_t* chip) +{ + bool qe; + if (chip == NULL) { + chip = esp_flash_default_chip; + } + esp_flash_io_mode_t io_mode_before = chip->read_mode; + esp_err_t ret = esp_flash_get_io_mode(chip, &qe); + TEST_ESP_OK(ret); + + bool is_winbond_chip = check_winbond_chip(chip); + + for (int i = 0; i < 4; i ++) { + ESP_LOGI(TAG, "write qe: %d->%d", qe, !qe); + qe = !qe; + chip->read_mode = qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD; + ret = esp_flash_set_io_mode(chip, qe); + if (is_winbond_chip && !qe && ret == ESP_ERR_FLASH_NO_RESPONSE) { + //allows clear qe failure for Winbond chips + ret = ESP_OK; + } + TEST_ESP_OK(ret); + + bool qe_read; + ret = esp_flash_get_io_mode(chip, &qe_read); + TEST_ESP_OK(ret); + ESP_LOGD(TAG, "qe read: %d", qe_read); + if (qe != qe_read && !qe && is_winbond_chip) { + ESP_LOGE(TAG, "cannot clear QE bit, this may be normal for Winbond chips."); + chip->read_mode = io_mode_before; + return; + } + TEST_ASSERT_EQUAL(qe, qe_read); + } + //restore the io_mode after test + chip->read_mode = io_mode_before; +} + +FLASH_TEST_CASE("Test esp_flash_write can toggle QE bit", test_toggle_qe); +FLASH_TEST_CASE_3("Test esp_flash_write can toggle QE bit", test_toggle_qe); + + +void test_permutations(flashtest_config_t* config) +{ + //replace config pointer with pointer to internal temporary config + flashtest_config_t temp_cfg; + memcpy(&temp_cfg, config, sizeof(flashtest_config_t)); + flashtest_config_t* cfg = &temp_cfg; + esp_flash_t* chip; + const int length = sizeof(large_const_buffer); uint8_t *source_buf = malloc(length); TEST_ASSERT_NOT_NULL(source_buf); @@ -423,60 +471,75 @@ TEST_CASE("SPI flash test reading with all speed/mode permutations", "[esp_flash const esp_partition_t *part = get_test_data_partition(); TEST_ASSERT(part->size > length + 2 + SPI_FLASH_SEC_SIZE); -#ifndef SKIP_EXTENDED_CHIP_TEST - //use the lowest speed to write and read to make sure success - setup_new_chip(TEST_SPI_READ_MODE, ESP_FLASH_SPEED_MIN); - write_large_buffer(test_chip, part, source_buf, length); - read_and_check(test_chip, part, source_buf, length); - teardown_test_chip(); + //write data to be read, and use the lowest speed to write and read to make sure success + cfg->io_mode = SPI_FLASH_READ_MODE_MIN; + cfg->speed = ESP_FLASH_SPEED_MIN; + setup_new_chip(cfg, &chip); + write_large_buffer(chip, part, source_buf, length); + read_and_check(chip, part, source_buf, length); + teardown_test_chip(chip, cfg->host_id); - esp_flash_read_mode_t io_mode = SPI_FLASH_READ_MODE_MIN; - while (io_mode != SPI_FLASH_READ_MODE_MAX) { + + if (config->host_id != -1) { esp_flash_speed_t speed = ESP_FLASH_SPEED_MIN; while (speed != ESP_FLASH_SPEED_MAX) { - ESP_LOGI(TAG, "test flash io mode: %d, speed: %d", io_mode, speed); - setup_new_chip(io_mode, speed); - read_and_check(test_chip, part, source_buf, length); - teardown_test_chip(); + //test io_mode in the inner loop to test QE set/clear function, since + //the io mode will switch frequently. + esp_flash_io_mode_t io_mode = SPI_FLASH_READ_MODE_MIN; + while (io_mode != SPI_FLASH_READ_MODE_MAX) { + ESP_LOGI(TAG, "test flash io mode: %d, speed: %d", io_mode, speed); + cfg->io_mode = io_mode; + cfg->speed = speed; + setup_new_chip(cfg, &chip); + read_and_check(chip, part, source_buf, length); + teardown_test_chip(chip, cfg->host_id); + io_mode++; + } speed++; } - io_mode++; + } else { + //test main flash + write_large_buffer(NULL, part, source_buf, length); + read_and_check(NULL, part, source_buf, length); } -#endif - - //test main flash BTW - write_large_buffer(NULL, part, source_buf, length); - read_and_check(NULL, part, source_buf, length); free(source_buf); } -TEST_CASE("Test esp_flash_write large const buffer", "[esp_flash]") +TEST_CASE("SPI flash test reading with all speed/mode permutations", "[esp_flash]") { - //buffer in flash - test_write_large_buffer(NULL, large_const_buffer, sizeof(large_const_buffer)); -#ifndef SKIP_EXTENDED_CHIP_TEST - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_write_large_buffer(test_chip, large_const_buffer, sizeof(large_const_buffer)); - teardown_test_chip(); -#endif + test_permutations(&config_list[0]); } -#ifndef SKIP_EXTENDED_CHIP_TEST -TEST_CASE("Test esp_flash_write large RAM buffer", "[esp_flash]") +#ifndef CONFIG_ESP32_SPIRAM_SUPPORT +TEST_CASE("SPI flash test reading with all speed/mode permutations, 3 chips", "[esp_flash][test_env=UT_T1_ESP_FLASH]") +{ + for (int i = 0; i < ALL_TEST_NUM; i++) { + test_permutations(&config_list[i]); + } +} +#endif + +static void test_write_large_const_buffer(esp_flash_t* chip) +{ + test_write_large_buffer(chip, large_const_buffer, sizeof(large_const_buffer)); +} + +FLASH_TEST_CASE("Test esp_flash_write large const buffer", test_write_large_const_buffer); +FLASH_TEST_CASE_3("Test esp_flash_write large const buffer", test_write_large_const_buffer); + +static void test_write_large_ram_buffer(esp_flash_t* chip) { // buffer in RAM uint8_t *source_buf = malloc(sizeof(large_const_buffer)); TEST_ASSERT_NOT_NULL(source_buf); memcpy(source_buf, large_const_buffer, sizeof(large_const_buffer)); - - setup_new_chip(TEST_SPI_READ_MODE, TEST_SPI_SPEED); - test_write_large_buffer(test_chip, source_buf, sizeof(large_const_buffer)); - teardown_test_chip(); - + test_write_large_buffer(chip, source_buf, sizeof(large_const_buffer)); free(source_buf); } -#endif + +FLASH_TEST_CASE("Test esp_flash_write large RAM buffer", test_write_large_ram_buffer); +FLASH_TEST_CASE_3("Test esp_flash_write large RAM buffer", test_write_large_ram_buffer); static void write_large_buffer(esp_flash_t *chip, const esp_partition_t *part, const uint8_t *source, size_t length) { diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index c2845ac964..f0f3f08227 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -457,6 +457,14 @@ UT_033: - UT_T2_Ethernet - psram +UT_034: + extends: .unit_test_template + parallel: 4 + tags: + - ESP32_IDF + - UT_T1_ESP_FLASH + + nvs_compatible_test: extends: .test_template artifacts: From eb104aa16f80fb9d54b3e5bf3b79550e95d51294 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Tue, 10 Sep 2019 00:56:46 +0800 Subject: [PATCH 11/21] esp_flash: fix the quad issue for some GD flash chips The GD flash with product ID 40H, is already used in Wrover-nosufix modules. --- components/spi_flash/CMakeLists.txt | 3 +- components/spi_flash/Kconfig | 19 ++- components/spi_flash/esp_flash_api.c | 23 ++-- components/spi_flash/include/esp_flash.h | 1 + .../spi_flash/include/spi_flash_chip_gd.h | 32 ++++++ components/spi_flash/linker.lf | 1 + components/spi_flash/spi_flash_chip_drivers.c | 4 + components/spi_flash/spi_flash_chip_gd.c | 108 ++++++++++++++++++ components/spi_flash/spi_flash_chip_generic.c | 6 +- 9 files changed, 180 insertions(+), 17 deletions(-) create mode 100644 components/spi_flash/include/spi_flash_chip_gd.h create mode 100644 components/spi_flash/spi_flash_chip_gd.c diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 497125e47b..61900d09ba 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -14,7 +14,7 @@ else() "partition.c" "spi_flash_rom_patch.c" ) - # New implementation + # New implementation after IDF v4.0 list(APPEND cache_srcs "esp_flash_api.c" "esp_flash_spi_init.c" @@ -25,6 +25,7 @@ else() "spi_flash_chip_drivers.c" "spi_flash_chip_generic.c" "spi_flash_chip_issi.c" + "spi_flash_chip_gd.c" "memspi_host_driver.c" ) list(APPEND srcs ${cache_srcs}) diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 8a10651ff0..046146e006 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -90,8 +90,23 @@ menu "SPI Flash driver" bool "ISSI" default y help - Enable this to support auto detection of ISSI chips if chip vendor not specified. - This adds support for variant chips, however will extend detecting time. + Enable this to support auto detection of ISSI chips if chip vendor not directly + given by ``chip_drv`` member of the chip struct. This adds support for variant + chips, however will extend detecting time. + + config SPI_FLASH_SUPPORT_GD_CHIP + bool "GigaDevice" + default y + help + Enable this to support auto detection of GD (GigaDevice) chips if chip vendor not + directly given by ``chip_drv`` member of the chip struct. If you are using Wrover + modules, please don't disable this, otherwise your flash may not work in 4-bit + mode. + + This adds support for variant chips, however will extend detecting time and image + size. Note that the default chip driver supports the GD chips with product ID + 60H. + endmenu #auto detect flash chips endmenu diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 7cb0e0d139..ff9c49e4d4 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -62,6 +62,7 @@ static const char io_mode_str[][IO_STR_LEN] = { _Static_assert(sizeof(io_mode_str)/IO_STR_LEN == SPI_FLASH_READ_MODE_MAX, "the io_mode_str should be consistent with the esp_flash_io_mode_t defined in spi_flash_ll.h"); +esp_err_t esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id); /* Static function to notify OS of a new SPI flash operation. @@ -115,6 +116,18 @@ esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip) return ESP_ERR_INVALID_ARG; } + //read chip id + uint32_t flash_id; + int retries = 10; + do { + err = esp_flash_read_chip_id(chip, &flash_id); + } while (err == ESP_ERR_FLASH_NOT_INITIALISED && retries-- > 0); + + if (err != ESP_OK) { + return err; + } + chip->chip_id = flash_id; + if (!esp_flash_chip_driver_initialized(chip)) { // Detect chip_drv err = detect_spi_flash_chip(chip); @@ -175,15 +188,7 @@ esp_err_t IRAM_ATTR esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip) { esp_err_t err; - uint32_t flash_id; - int retries = 10; - do { - err = esp_flash_read_chip_id(chip, &flash_id); - } while (err == ESP_ERR_FLASH_NOT_INITIALISED && retries-- > 0); - - if (err != ESP_OK) { - return err; - } + uint32_t flash_id = chip->chip_id; // Detect the chip and set the chip_drv structure for it const spi_flash_chip_t **drivers = esp_flash_registered_chips; diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index b2b38806d9..afce78c5e6 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -65,6 +65,7 @@ struct esp_flash_t { esp_flash_io_mode_t read_mode; ///< Configured SPI flash read mode. Set before ``esp_flash_init`` is called. uint32_t size; ///< Size of SPI flash in bytes. If 0, size will be detected during initialisation. + uint32_t chip_id; ///< Detected chip id. }; diff --git a/components/spi_flash/include/spi_flash_chip_gd.h b/components/spi_flash/include/spi_flash_chip_gd.h new file mode 100644 index 0000000000..0d52435a38 --- /dev/null +++ b/components/spi_flash/include/spi_flash_chip_gd.h @@ -0,0 +1,32 @@ +// Copyright 2015-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. + +#pragma once + +#include +#include "esp_flash.h" +#include "spi_flash_chip_driver.h" + + +/** + * GD (GigaDevice) SPI flash chip_drv, uses all the above functions for its operations. In + * default autodetection, this is used as a catchall if a more specific chip_drv + * is not found. + * + * Note that this is for GD chips with product ID 40H (GD25Q) and 60H (GD25LQ). The chip diver uses + * different commands to write the SR2 register according to the chip ID. For GD25Q40 - GD25Q16 + * chips, and GD25LQ chips, WRSR (01H) command is used; while WRSR2 (31H) is used for GD25Q32 - + * GD25Q127 chips. + */ +extern const spi_flash_chip_t esp_flash_chip_gd; diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index e5d886ca4b..5e2c1af32f 100644 --- a/components/spi_flash/linker.lf +++ b/components/spi_flash/linker.lf @@ -4,5 +4,6 @@ entries: spi_flash_rom_patch (noflash_text) spi_flash_chip_generic (noflash) spi_flash_chip_issi (noflash) + spi_flash_chip_gd(noflash) memspi_host_driver (noflash) diff --git a/components/spi_flash/spi_flash_chip_drivers.c b/components/spi_flash/spi_flash_chip_drivers.c index ae10bcec37..316ac9ae17 100644 --- a/components/spi_flash/spi_flash_chip_drivers.c +++ b/components/spi_flash/spi_flash_chip_drivers.c @@ -16,6 +16,7 @@ #include "spi_flash_chip_driver.h" #include "spi_flash_chip_generic.h" #include "spi_flash_chip_issi.h" +#include "spi_flash_chip_gd.h" #include "sdkconfig.h" /* @@ -30,6 +31,9 @@ static const spi_flash_chip_t *default_registered_chips[] = { #ifdef CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP &esp_flash_chip_issi, +#endif +#ifdef CONFIG_SPI_FLASH_SUPPORT_GD_CHIP + &esp_flash_chip_gd, #endif &esp_flash_chip_generic, NULL, diff --git a/components/spi_flash/spi_flash_chip_gd.c b/components/spi_flash/spi_flash_chip_gd.c new file mode 100644 index 0000000000..bc877d2cb1 --- /dev/null +++ b/components/spi_flash/spi_flash_chip_gd.c @@ -0,0 +1,108 @@ +// Copyright 2015-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. + +#include +#include "spi_flash_chip_generic.h" +#include "spi_flash_defs.h" + +#define FLASH_ID_MASK 0xFF00 +#define FLASH_SIZE_MASK 0xFF +#define GD25Q_PRODUCT_ID 0x4000 +#define GD25LQ_PRODUCT_ID 0x6000 + +#define WRSR_16B_REQUIRED(chip_id) (((chip_id) & FLASH_ID_MASK) == GD25LQ_PRODUCT_ID || \ + ((chip_id) & FLASH_SIZE_MASK) <= 0x15) + +/* Driver for GD flash chip */ + +esp_err_t spi_flash_chip_gd_probe(esp_flash_t *chip, uint32_t flash_id) +{ + /* Check manufacturer and product IDs match our desired masks */ + const uint8_t MFG_ID = 0xC8; + if (flash_id >> 16 != MFG_ID) { + return ESP_ERR_NOT_FOUND; + } + + uint32_t product_id = flash_id & FLASH_ID_MASK; + if (product_id != GD25Q_PRODUCT_ID && product_id != GD25LQ_PRODUCT_ID) { + return ESP_ERR_NOT_FOUND; + } + + return ESP_OK; +} + +esp_err_t spi_flash_chip_gd_set_io_mode(esp_flash_t *chip) +{ + if (WRSR_16B_REQUIRED(chip->chip_id)) { + const uint32_t qe = 1<<9; + return spi_flash_common_set_io_mode(chip, + spi_flash_common_write_status_16b_wrsr, + spi_flash_common_read_status_16b_rdsr_rdsr2, + qe); + } else { + const uint32_t qe = 1<<1; + return spi_flash_common_set_io_mode(chip, + spi_flash_common_write_status_8b_wrsr2, + spi_flash_common_read_status_8b_rdsr2, + qe); + } +} + +esp_err_t spi_flash_chip_gd_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode) +{ + /* GD uses bit 1 of SR2 as Quad Enable */ + const uint8_t BIT_QE = 1 << 1; + uint32_t sr; + esp_err_t ret = spi_flash_common_read_status_8b_rdsr2(chip, &sr); + if (ret == ESP_OK) { + *out_io_mode = ((sr & BIT_QE)? SPI_FLASH_QOUT: 0); + } + return ret; +} + + +static const char chip_name[] = "gd"; + +// The issi chip can use the functions for generic chips except from set read mode and probe, +// So we only replace these two functions. +const spi_flash_chip_t esp_flash_chip_gd = { + .name = chip_name, + .probe = spi_flash_chip_gd_probe, + .reset = spi_flash_chip_generic_reset, + .detect_size = spi_flash_chip_generic_detect_size, + .erase_chip = spi_flash_chip_generic_erase_chip, + .erase_sector = spi_flash_chip_generic_erase_sector, + .erase_block = spi_flash_chip_generic_erase_block, + .sector_size = 4 * 1024, + .block_erase_size = 64 * 1024, + + .get_chip_write_protect = spi_flash_chip_generic_get_write_protect, + .set_chip_write_protect = spi_flash_chip_generic_set_write_protect, + + // TODO support protected regions on ISSI flash + .num_protectable_regions = 0, + .protectable_regions = NULL, + .get_protected_regions = NULL, + .set_protected_regions = NULL, + + .read = spi_flash_chip_generic_read, + .write = spi_flash_chip_generic_write, + .program_page = spi_flash_chip_generic_page_program, + .page_size = 256, + .write_encrypted = spi_flash_chip_generic_write_encrypted, + + .wait_idle = spi_flash_chip_generic_wait_idle, + .set_io_mode = spi_flash_chip_gd_set_io_mode, + .get_io_mode = spi_flash_chip_gd_get_io_mode, +}; diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index 16d6b85e16..23172fb938 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -60,12 +60,8 @@ esp_err_t spi_flash_chip_generic_reset(esp_flash_t *chip) esp_err_t spi_flash_chip_generic_detect_size(esp_flash_t *chip, uint32_t *size) { - uint32_t id = 0; + uint32_t id = chip->chip_id; *size = 0; - esp_err_t err = chip->host->read_id(chip->host, &id); - if (err != ESP_OK) { - return err; - } /* Can't detect size unless the high byte of the product ID matches the same convention, which is usually 0x40 or * 0xC0 or similar. */ From d56e7ec037073b701a1c824d0d710c84950db22c Mon Sep 17 00:00:00 2001 From: liu zhifu Date: Mon, 14 Oct 2019 15:37:00 +0800 Subject: [PATCH 12/21] esp_wifi: modify WiFi buffer number type from uint8_t to uint16_t Modify WiFi receiving buffer number type from uint8_t to uint16_t to support configuring more than 255 buffers. --- components/esp_wifi/lib_esp32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_wifi/lib_esp32 b/components/esp_wifi/lib_esp32 index 4f8e1517f5..1068594fee 160000 --- a/components/esp_wifi/lib_esp32 +++ b/components/esp_wifi/lib_esp32 @@ -1 +1 @@ -Subproject commit 4f8e1517f53e9aca81cf7b604563b3807df834d9 +Subproject commit 1068594fee5fd8a73b353c4e77ff3b44d111393d From 7f410a0bcbafa85dba05807c53c3c38999506509 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 8 Oct 2019 19:53:56 +0200 Subject: [PATCH 13/21] mdns: fix possible race condition when checking DHCP status on WIFI_EVENT_STA_CONNECTED event. tcpip_adapter_dhcpc_get_status() returns the actual internal value of dhcp client without any locking or TCP/IP stack context call, so when CONNECTED event fired with default settings it started DHCP client in TCP/IP stack context and at the same time mdns event handler checking actual DHCP state, which could still be INIT (not STARTED). Purpose of this check is to enable PCB if DHCP was stopped before setting network interface up (typically static IP settings), so the solutin is to check against TCPIP_ADAPTER_DHCP_STOPPED state --- components/mdns/mdns.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index b34452ba0f..d4a68963c4 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -3062,7 +3062,7 @@ static void _mdns_handle_system_event(esp_event_base_t event_base, switch(event_id) { case WIFI_EVENT_STA_CONNECTED: if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &dcst)) { - if (dcst != TCPIP_ADAPTER_DHCP_STARTED) { + if (dcst == TCPIP_ADAPTER_DHCP_STOPPED) { _mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4); } } @@ -3085,7 +3085,7 @@ static void _mdns_handle_system_event(esp_event_base_t event_base, switch (event_id) { case ETHERNET_EVENT_CONNECTED: if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &dcst)) { - if (dcst != TCPIP_ADAPTER_DHCP_STARTED) { + if (dcst == TCPIP_ADAPTER_DHCP_STOPPED) { _mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4); } } From 07e0254f06929b0596775484c779aaf9e39258f2 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 8 Oct 2019 19:56:11 +0200 Subject: [PATCH 14/21] lwip: autoip: used Kconfig parameters instead of constants to be in line with previous esp-lwip port and to have the BCT passed --- components/lwip/lwip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lwip/lwip b/components/lwip/lwip index 8c801667e8..89932176f5 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 8c801667e8586ae6dedf80d13aaaec71b7b9a33d +Subproject commit 89932176f598bb1b6595c65bfc7832334e0a1e08 From c6934d61754682d34a630f8232b3f497df8c8fec Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Fri, 27 Sep 2019 09:35:26 +0800 Subject: [PATCH 15/21] MQTT: update default broker URL for examples The MQTT broker URL used as default in the examples has ceased operation. All examples and documention have been updated to point to the new domain mqtt.eclipse.org. This also required an update of the python example test scripts to use TLS 1.2 --- .../mqtt/weekend_test/mqtt_publish_test.py | 3 +- docs/en/api-reference/protocols/mqtt.rst | 28 +++++++++---------- .../mqtt/publish_test/CMakeLists.txt | 2 +- .../mqtt/publish_test/main/Kconfig.projbuild | 8 +++--- .../mqtt/publish_test/main/component.mk | 2 +- ...t_eclipse_org.pem => mqtt_eclipse_org.pem} | 0 .../mqtt/publish_test/main/publish_test.c | 8 +++--- examples/protocols/mqtt/ssl/CMakeLists.txt | 2 +- examples/protocols/mqtt/ssl/README.md | 8 +++--- .../protocols/mqtt/ssl/main/Kconfig.projbuild | 2 +- examples/protocols/mqtt/ssl/main/app_main.c | 8 +++--- examples/protocols/mqtt/ssl/main/component.mk | 2 +- ...t_eclipse_org.pem => mqtt_eclipse_org.pem} | 0 .../mqtt/ssl/mqtt_ssl_example_test.py | 2 +- .../protocols/mqtt/tcp/main/Kconfig.projbuild | 2 +- examples/protocols/mqtt/ws/README.md | 2 +- .../protocols/mqtt/ws/main/Kconfig.projbuild | 2 +- .../protocols/mqtt/ws/mqtt_ws_example_test.py | 1 - examples/protocols/mqtt/wss/CMakeLists.txt | 2 +- examples/protocols/mqtt/wss/README.md | 10 +++---- .../protocols/mqtt/wss/main/Kconfig.projbuild | 2 +- examples/protocols/mqtt/wss/main/app_main.c | 8 +++--- examples/protocols/mqtt/wss/main/component.mk | 2 +- ...t_eclipse_org.pem => mqtt_eclipse_org.pem} | 0 .../mqtt/wss/mqtt_wss_example_test.py | 2 +- .../pppos_client/main/pppos_client_main.c | 2 +- 26 files changed, 54 insertions(+), 56 deletions(-) rename examples/protocols/mqtt/publish_test/main/{iot_eclipse_org.pem => mqtt_eclipse_org.pem} (100%) rename examples/protocols/mqtt/ssl/main/{iot_eclipse_org.pem => mqtt_eclipse_org.pem} (100%) rename examples/protocols/mqtt/wss/main/{iot_eclipse_org.pem => mqtt_eclipse_org.pem} (100%) diff --git a/components/mqtt/weekend_test/mqtt_publish_test.py b/components/mqtt/weekend_test/mqtt_publish_test.py index 9263f3ada7..7b738a81a5 100644 --- a/components/mqtt/weekend_test/mqtt_publish_test.py +++ b/components/mqtt/weekend_test/mqtt_publish_test.py @@ -80,13 +80,12 @@ def test_single_config(dut, transport, qos, repeat, published): try: if transport in ["ws", "wss"]: client = mqtt.Client(transport="websockets") - client.ws_set_options(path="/ws", headers=None) else: client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message if transport in ["ssl", "wss"]: - client.tls_set(None, None, None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None) + client.tls_set(None, None, None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None) client.tls_insecure_set(True) print("Connecting...") client.connect(broker_host[transport], broker_port[transport], 60) diff --git a/docs/en/api-reference/protocols/mqtt.rst b/docs/en/api-reference/protocols/mqtt.rst index cb956755a6..80d6270b9f 100644 --- a/docs/en/api-reference/protocols/mqtt.rst +++ b/docs/en/api-reference/protocols/mqtt.rst @@ -32,30 +32,30 @@ URI - Curently support ``mqtt``, ``mqtts``, ``ws``, ``wss`` schemes - MQTT over TCP samples: - - ``mqtt://iot.eclipse.org``: MQTT over TCP, default port 1883: - - ``mqtt://iot.eclipse.org:1884`` MQTT over TCP, port 1884: - - ``mqtt://username:password@iot.eclipse.org:1884`` MQTT over TCP, + - ``mqtt://mqtt.eclipse.org``: MQTT over TCP, default port 1883: + - ``mqtt://mqtt.eclipse.org:1884`` MQTT over TCP, port 1884: + - ``mqtt://username:password@mqtt.eclipse.org:1884`` MQTT over TCP, port 1884, with username and password - MQTT over SSL samples: - - ``mqtts://iot.eclipse.org``: MQTT over SSL, port 8883 - - ``mqtts://iot.eclipse.org:8884``: MQTT over SSL, port 8884 + - ``mqtts://mqtt.eclipse.org``: MQTT over SSL, port 8883 + - ``mqtts://mqtt.eclipse.org:8884``: MQTT over SSL, port 8884 - MQTT over Websocket samples: - - ``ws://iot.eclipse.org:80/ws`` + - ``ws://mqtt.eclipse.org:80/mqtt`` - MQTT over Websocket Secure samples: - - ``wss://iot.eclipse.org:443/ws`` + - ``wss://mqtt.eclipse.org:443/mqtt`` - Minimal configurations: .. code:: c const esp_mqtt_client_config_t mqtt_cfg = { - .uri = "mqtt://iot.eclipse.org", + .uri = "mqtt://mqtt.eclipse.org", // .user_context = (void *)your_context }; esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); @@ -71,25 +71,25 @@ URI .. code:: c const esp_mqtt_client_config_t mqtt_cfg = { - .uri = "mqtt://iot.eclipse.org:1234", + .uri = "mqtt://mqtt.eclipse.org:1234", .port = 4567, }; - //MQTT client will connect to iot.eclipse.org using port 4567 + //MQTT client will connect to mqtt.eclipse.org using port 4567 SSL ^^^ -- Get certificate from server, example: ``iot.eclipse.org`` - ``openssl s_client -showcerts -connect iot.eclipse.org:8883 /dev/null|openssl x509 -outform PEM >iot_eclipse_org.pem`` +- Get certificate from server, example: ``mqtt.eclipse.org`` + ``openssl s_client -showcerts -connect mqtt.eclipse.org:8883 /dev/null|openssl x509 -outform PEM >mqtt_eclipse_org.pem`` - Check the sample application: ``examples/mqtt_ssl`` - Configuration: .. code:: cpp const esp_mqtt_client_config_t mqtt_cfg = { - .uri = "mqtts://iot.eclipse.org:8883", + .uri = "mqtts://mqtt.eclipse.org:8883", .event_handle = mqtt_event_handler, - .cert_pem = (const char *)iot_eclipse_org_pem_start, + .cert_pem = (const char *)mqtt_eclipse_org_pem_start, }; For more options on ``esp_mqtt_client_config_t``, please refer to API reference below diff --git a/examples/protocols/mqtt/publish_test/CMakeLists.txt b/examples/protocols/mqtt/publish_test/CMakeLists.txt index 2203d063f7..4a46af3e58 100644 --- a/examples/protocols/mqtt/publish_test/CMakeLists.txt +++ b/examples/protocols/mqtt/publish_test/CMakeLists.txt @@ -10,4 +10,4 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_publish) -target_add_binary_data(mqtt_publish.elf "main/iot_eclipse_org.pem" TEXT) +target_add_binary_data(mqtt_publish.elf "main/mqtt_eclipse_org.pem" TEXT) diff --git a/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild b/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild index 8360e573d2..bf4197482e 100644 --- a/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild @@ -2,25 +2,25 @@ menu "Example Configuration" config EXAMPLE_BROKER_SSL_URI string "Broker SSL URL" - default "mqtts://iot.eclipse.org:8883" + default "mqtts://mqtt.eclipse.org:8883" help URL of an mqtt broker for ssl transport config EXAMPLE_BROKER_TCP_URI string "Broker TCP URL" - default "mqtt://iot.eclipse.org:1883" + default "mqtt://mqtt.eclipse.org:1883" help URL of an mqtt broker for tcp transport config EXAMPLE_BROKER_WS_URI string "Broker WS URL" - default "ws://iot.eclipse.org:80/ws" + default "ws://mqtt.eclipse.org:80/mqtt" help URL of an mqtt broker for ws transport config EXAMPLE_BROKER_WSS_URI string "Broker WSS URL" - default "wss://iot.eclipse.org:443/ws" + default "wss://mqtt.eclipse.org:443/mqtt" help URL of an mqtt broker for wss transport diff --git a/examples/protocols/mqtt/publish_test/main/component.mk b/examples/protocols/mqtt/publish_test/main/component.mk index 797c4a1f67..597752fb9b 100644 --- a/examples/protocols/mqtt/publish_test/main/component.mk +++ b/examples/protocols/mqtt/publish_test/main/component.mk @@ -1 +1 @@ -COMPONENT_EMBED_TXTFILES := iot_eclipse_org.pem +COMPONENT_EMBED_TXTFILES := mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/publish_test/main/iot_eclipse_org.pem b/examples/protocols/mqtt/publish_test/main/mqtt_eclipse_org.pem similarity index 100% rename from examples/protocols/mqtt/publish_test/main/iot_eclipse_org.pem rename to examples/protocols/mqtt/publish_test/main/mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/publish_test/main/publish_test.c b/examples/protocols/mqtt/publish_test/main/publish_test.c index 9183bbb8bb..918f9a191a 100644 --- a/examples/protocols/mqtt/publish_test/main/publish_test.c +++ b/examples/protocols/mqtt/publish_test/main/publish_test.c @@ -46,11 +46,11 @@ static int qos_test = 0; #if CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDDEN == 1 -static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; +static const uint8_t mqtt_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; #else -extern const uint8_t iot_eclipse_org_pem_start[] asm("_binary_iot_eclipse_org_pem_start"); +extern const uint8_t mqtt_eclipse_org_pem_start[] asm("_binary_mqtt_eclipse_org_pem_start"); #endif -extern const uint8_t iot_eclipse_org_pem_end[] asm("_binary_iot_eclipse_org_pem_end"); +extern const uint8_t mqtt_eclipse_org_pem_end[] asm("_binary_mqtt_eclipse_org_pem_end"); static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) { @@ -127,7 +127,7 @@ static void mqtt_app_start(void) mqtt_event_group = xEventGroupCreate(); const esp_mqtt_client_config_t mqtt_cfg = { .event_handle = mqtt_event_handler, - .cert_pem = (const char *)iot_eclipse_org_pem_start, + .cert_pem = (const char *)mqtt_eclipse_org_pem_start, }; ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); diff --git a/examples/protocols/mqtt/ssl/CMakeLists.txt b/examples/protocols/mqtt/ssl/CMakeLists.txt index a7b2c44204..2b78a842b8 100644 --- a/examples/protocols/mqtt/ssl/CMakeLists.txt +++ b/examples/protocols/mqtt/ssl/CMakeLists.txt @@ -9,4 +9,4 @@ set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_exam include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_ssl) -target_add_binary_data(mqtt_ssl.elf "main/iot_eclipse_org.pem" TEXT) +target_add_binary_data(mqtt_ssl.elf "main/mqtt_eclipse_org.pem" TEXT) diff --git a/examples/protocols/mqtt/ssl/README.md b/examples/protocols/mqtt/ssl/README.md index e2693729d4..aa96a6841a 100644 --- a/examples/protocols/mqtt/ssl/README.md +++ b/examples/protocols/mqtt/ssl/README.md @@ -2,7 +2,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example connects to the broker iot.eclipse.org using ssl transport and as a demonstration subscribes/unsubscribes and send a message on certain topic. +This example connects to the broker mqtt.eclipse.org using ssl transport and as a demonstration subscribes/unsubscribes and send a message on certain topic. (Please note that the public broker is maintained by the community so may not be always available, for details please see this [disclaimer](https://iot.eclipse.org/getting-started/#sandboxes)) It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker. @@ -19,13 +19,13 @@ This example can be executed on any ESP32 board, the only required interface is * Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. * When using Make build system, set `Default serial port` under `Serial flasher config`. -PEM certificate for this example could be extracted from an openssl `s_client` command connecting to iot.eclipse.org. +PEM certificate for this example could be extracted from an openssl `s_client` command connecting to mqtt.eclipse.org. In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used). ``` -echo "" | openssl s_client -showcerts -connect iot.eclipse.org:8883 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >iot_eclipse_org.pem +echo "" | openssl s_client -showcerts -connect mqtt.eclipse.org:8883 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >mqtt_eclipse_org.pem ``` Please note that this is not a general command for downloading a root certificate for an arbitrary host; -this command works with iot.eclipse.org as the site provides root certificate in the chain, which then could be extracted +this command works with mqtt.eclipse.org as the site provides root certificate in the chain, which then could be extracted with text operation. ### Build and Flash diff --git a/examples/protocols/mqtt/ssl/main/Kconfig.projbuild b/examples/protocols/mqtt/ssl/main/Kconfig.projbuild index e318733662..3c44294b00 100644 --- a/examples/protocols/mqtt/ssl/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/ssl/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URI string "Broker URL" - default "mqtts://iot.eclipse.org:8883" + default "mqtts://mqtt.eclipse.org:8883" help URL of an mqtt broker which this example connects to. diff --git a/examples/protocols/mqtt/ssl/main/app_main.c b/examples/protocols/mqtt/ssl/main/app_main.c index fd0a49d7bf..cf0df58367 100644 --- a/examples/protocols/mqtt/ssl/main/app_main.c +++ b/examples/protocols/mqtt/ssl/main/app_main.c @@ -35,11 +35,11 @@ static const char *TAG = "MQTTS_EXAMPLE"; #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1 -static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; +static const uint8_t mqtt_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; #else -extern const uint8_t iot_eclipse_org_pem_start[] asm("_binary_iot_eclipse_org_pem_start"); +extern const uint8_t mqtt_eclipse_org_pem_start[] asm("_binary_mqtt_eclipse_org_pem_start"); #endif -extern const uint8_t iot_eclipse_org_pem_end[] asm("_binary_iot_eclipse_org_pem_end"); +extern const uint8_t mqtt_eclipse_org_pem_end[] asm("_binary_mqtt_eclipse_org_pem_end"); static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { @@ -101,7 +101,7 @@ static void mqtt_app_start(void) { const esp_mqtt_client_config_t mqtt_cfg = { .uri = CONFIG_BROKER_URI, - .cert_pem = (const char *)iot_eclipse_org_pem_start, + .cert_pem = (const char *)mqtt_eclipse_org_pem_start, }; ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); diff --git a/examples/protocols/mqtt/ssl/main/component.mk b/examples/protocols/mqtt/ssl/main/component.mk index 797c4a1f67..597752fb9b 100644 --- a/examples/protocols/mqtt/ssl/main/component.mk +++ b/examples/protocols/mqtt/ssl/main/component.mk @@ -1 +1 @@ -COMPONENT_EMBED_TXTFILES := iot_eclipse_org.pem +COMPONENT_EMBED_TXTFILES := mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/ssl/main/iot_eclipse_org.pem b/examples/protocols/mqtt/ssl/main/mqtt_eclipse_org.pem similarity index 100% rename from examples/protocols/mqtt/ssl/main/iot_eclipse_org.pem rename to examples/protocols/mqtt/ssl/main/mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py index 7e66482533..ef9d1a9d64 100644 --- a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py +++ b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py @@ -87,7 +87,7 @@ def test_examples_protocol_mqtt_ssl(env, extra_data): client.on_message = on_message client.tls_set(None, None, - None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None) + None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None) client.tls_insecure_set(True) print("Connecting...") client.connect(broker_url, broker_port, 60) diff --git a/examples/protocols/mqtt/tcp/main/Kconfig.projbuild b/examples/protocols/mqtt/tcp/main/Kconfig.projbuild index fbd48103ba..fc6e8a184c 100644 --- a/examples/protocols/mqtt/tcp/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/tcp/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URL string "Broker URL" - default "mqtt://iot.eclipse.org" + default "mqtt://mqtt.eclipse.org" help URL of the broker to connect to diff --git a/examples/protocols/mqtt/ws/README.md b/examples/protocols/mqtt/ws/README.md index c0526b0735..3b2a05a979 100644 --- a/examples/protocols/mqtt/ws/README.md +++ b/examples/protocols/mqtt/ws/README.md @@ -2,7 +2,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example connects to the broker iot.eclipse.org over web sockets as a demonstration subscribes/unsubscribes and send a message on certain topic. +This example connects to the broker mqtt.eclipse.org over web sockets as a demonstration subscribes/unsubscribes and send a message on certain topic. (Please note that the public broker is maintained by the community so may not be always available, for details please see this [disclaimer](https://iot.eclipse.org/getting-started/#sandboxes)) It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker. diff --git a/examples/protocols/mqtt/ws/main/Kconfig.projbuild b/examples/protocols/mqtt/ws/main/Kconfig.projbuild index 46f3ad5652..c298f5d7c8 100644 --- a/examples/protocols/mqtt/ws/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/ws/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URI string "Broker URL" - default "ws://iot.eclipse.org:80/ws" + default "ws://mqtt.eclipse.org:80/mqtt" help URL of an mqtt broker which this example connects to. diff --git a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py index 0578876e2c..58b8d5e37a 100644 --- a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py +++ b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py @@ -82,7 +82,6 @@ def test_examples_protocol_mqtt_ws(env, extra_data): client = mqtt.Client(transport="websockets") client.on_connect = on_connect client.on_message = on_message - client.ws_set_options(path="/ws", headers=None) print("Connecting...") client.connect(broker_url, broker_port, 60) except Exception: diff --git a/examples/protocols/mqtt/wss/CMakeLists.txt b/examples/protocols/mqtt/wss/CMakeLists.txt index 3e2d5fc23e..2350bd8299 100644 --- a/examples/protocols/mqtt/wss/CMakeLists.txt +++ b/examples/protocols/mqtt/wss/CMakeLists.txt @@ -9,4 +9,4 @@ set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_exam include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_websocket_secure) -target_add_binary_data(mqtt_websocket_secure.elf "main/iot_eclipse_org.pem" TEXT) +target_add_binary_data(mqtt_websocket_secure.elf "main/mqtt_eclipse_org.pem" TEXT) diff --git a/examples/protocols/mqtt/wss/README.md b/examples/protocols/mqtt/wss/README.md index 9851d54337..c07477fe12 100644 --- a/examples/protocols/mqtt/wss/README.md +++ b/examples/protocols/mqtt/wss/README.md @@ -1,7 +1,7 @@ # ESP-MQTT MQTT over WSS Sample application (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example connects to the broker iot.eclipse.org over secure websockets and as a demonstration subscribes/unsubscribes and send a message on certain topic. +This example connects to the broker mqtt.eclipse.org over secure websockets and as a demonstration subscribes/unsubscribes and send a message on certain topic. (Please note that the public broker is maintained by the community so may not be always available, for details please see this [disclaimer](https://iot.eclipse.org/getting-started/#sandboxes)) It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker. @@ -18,15 +18,15 @@ This example can be executed on any ESP32 board, the only required interface is * Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. * When using Make build system, set `Default serial port` under `Serial flasher config`. -Note how to create a PEM certificate for iot.eclipse.org: +Note how to create a PEM certificate for mqtt.eclipse.org: -PEM certificate for this example could be extracted from an openssl `s_client` command connecting to iot.eclipse.org. +PEM certificate for this example could be extracted from an openssl `s_client` command connecting to mqtt.eclipse.org. In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used). ``` -echo "" | openssl s_client -showcerts -connect iot.eclipse.org:443 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >iot_eclipse_org.pem +echo "" | openssl s_client -showcerts -connect mqtt.eclipse.org:443 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >mqtt_eclipse_org.pem ``` Please note that this is not a general command for downloading a root certificate for an arbitrary host; -this command works with iot.eclipse.org as the site provides root certificate in the chain, which then could be extracted +this command works with mqtt.eclipse.org as the site provides root certificate in the chain, which then could be extracted with text operation. ### Build and Flash diff --git a/examples/protocols/mqtt/wss/main/Kconfig.projbuild b/examples/protocols/mqtt/wss/main/Kconfig.projbuild index d3f7bf51c0..5e43c89493 100644 --- a/examples/protocols/mqtt/wss/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/wss/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config BROKER_URI string "Broker URL" - default "wss://iot.eclipse.org:443/ws" + default "wss://mqtt.eclipse.org:443/mqtt" help URL of an mqtt broker which this example connects to. diff --git a/examples/protocols/mqtt/wss/main/app_main.c b/examples/protocols/mqtt/wss/main/app_main.c index a9de24455a..529e960605 100644 --- a/examples/protocols/mqtt/wss/main/app_main.c +++ b/examples/protocols/mqtt/wss/main/app_main.c @@ -33,11 +33,11 @@ static const char *TAG = "MQTTWSS_EXAMPLE"; #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1 -static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; +static const uint8_t mqtt_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; #else -extern const uint8_t iot_eclipse_org_pem_start[] asm("_binary_iot_eclipse_org_pem_start"); +extern const uint8_t mqtt_eclipse_org_pem_start[] asm("_binary_mqtt_eclipse_org_pem_start"); #endif -extern const uint8_t iot_eclipse_org_pem_end[] asm("_binary_iot_eclipse_org_pem_end"); +extern const uint8_t mqtt_eclipse_org_pem_end[] asm("_binary_mqtt_eclipse_org_pem_end"); static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { @@ -95,7 +95,7 @@ static void mqtt_app_start(void) { const esp_mqtt_client_config_t mqtt_cfg = { .uri = CONFIG_BROKER_URI, - .cert_pem = (const char *)iot_eclipse_org_pem_start, + .cert_pem = (const char *)mqtt_eclipse_org_pem_start, }; ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); diff --git a/examples/protocols/mqtt/wss/main/component.mk b/examples/protocols/mqtt/wss/main/component.mk index 797c4a1f67..597752fb9b 100644 --- a/examples/protocols/mqtt/wss/main/component.mk +++ b/examples/protocols/mqtt/wss/main/component.mk @@ -1 +1 @@ -COMPONENT_EMBED_TXTFILES := iot_eclipse_org.pem +COMPONENT_EMBED_TXTFILES := mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/wss/main/iot_eclipse_org.pem b/examples/protocols/mqtt/wss/main/mqtt_eclipse_org.pem similarity index 100% rename from examples/protocols/mqtt/wss/main/iot_eclipse_org.pem rename to examples/protocols/mqtt/wss/main/mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py index 58ce56036d..15ca2834a8 100644 --- a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py +++ b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py @@ -85,7 +85,7 @@ def test_examples_protocol_mqtt_wss(env, extra_data): client.on_message = on_message client.tls_set(None, None, - None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None) + None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None) print("Connecting...") client.connect(broker_url, broker_port, 60) except Exception: diff --git a/examples/protocols/pppos_client/main/pppos_client_main.c b/examples/protocols/pppos_client/main/pppos_client_main.c index 4f376ea68f..c3a18a6cb6 100644 --- a/examples/protocols/pppos_client/main/pppos_client_main.c +++ b/examples/protocols/pppos_client/main/pppos_client_main.c @@ -16,7 +16,7 @@ #include "sim800.h" #include "bg96.h" -#define BROKER_URL "mqtt://iot.eclipse.org" +#define BROKER_URL "mqtt://mqtt.eclipse.org" static const char *TAG = "pppos_example"; static EventGroupHandle_t event_group = NULL; From 2c7165f7838a54f6e577a0055f80c32cf019ceae Mon Sep 17 00:00:00 2001 From: Kirill Chalov Date: Mon, 22 Jul 2019 12:48:52 +0800 Subject: [PATCH 16/21] Review the file api-reference/peripherals/spi_slave.rst --- .../api-reference/peripherals/spi_slave.rst | 269 ++++++++---------- 1 file changed, 114 insertions(+), 155 deletions(-) diff --git a/docs/en/api-reference/peripherals/spi_slave.rst b/docs/en/api-reference/peripherals/spi_slave.rst index 7b5762f5de..f2b3359c34 100644 --- a/docs/en/api-reference/peripherals/spi_slave.rst +++ b/docs/en/api-reference/peripherals/spi_slave.rst @@ -1,84 +1,108 @@ -SPI Slave driver -================= +SPI Slave Driver +================ -Overview --------- +SPI Slave driver is a program that controls ESP32's SPI peripherals while they function as slaves. -The ESP32 has four SPI peripheral devices, called SPI0, SPI1, HSPI and VSPI. SPI0 is entirely dedicated to -the flash cache the ESP32 uses to map the SPI flash device it is connected to into memory. SPI1 is -connected to the same hardware lines as SPI0 and is used to write to the flash chip. HSPI and VSPI -are free to use, and with the spi_slave driver, these can be used as a SPI slave, driven from a -connected SPI master. -The spi_slave driver -^^^^^^^^^^^^^^^^^^^^^ +Overview of ESP32's SPI peripherals +----------------------------------- + +ESP32 integrates two general purpose SPI controllers which can be used as slave nodes driven by an off-chip SPI master + +- SPI2, sometimes referred to as HSPI +- SPI3, sometimes referred to as VSPI + +SPI2 and SPI3 have independent signal buses with the same respective names. -The spi_slave driver allows using the HSPI and/or VSPI peripheral as a -full-duplex SPI slave. It can send/receive transactions within 64 bytes, or -make use of DMA to send/receive transactions longer than that. However, there -are some `known issues `_ when the DMA is enabled. Terminology -^^^^^^^^^^^ +----------- -The spi_slave driver uses the following terms: +The terms used in relation to the SPI slave driver are given in the table below. -* Host: The SPI peripheral inside the ESP32 initiating the SPI transmissions. One of HSPI or VSPI. -* Bus: The SPI bus, common to all SPI devices connected to a master. In general the bus consists of the - miso, mosi, sclk and optionally quadwp and quadhd signals. The SPI slaves are connected to these - signals in parallel. Each SPI slave is also connected to one CS signal. - - - miso - Also known as q, this is the output of the serial stream from the ESP32 to the SPI master - - - mosi - Also known as d, this is the output of the serial stream from the SPI master to the ESP32 - - - sclk - Clock signal. Each data bit is clocked out or in on the positive or negative edge of this signal - - - cs - Chip Select. An active Chip Select delineates a single transaction to/from a slave. - -* Transaction: One instance of CS going active, data transfer from and to a master happening, and - CS going inactive again. Transactions are atomic, as in they will never be interrupted by another - transaction. +================= ========================================================================================= +Term Definition +================= ========================================================================================= +**Host** The SPI controller peripheral external to ESP32 that initiates SPI transmissions over the bus, and acts as an SPI Master. +**Device** SPI slave device, in this case the SPI2 and SPI3 controllers. Each Device shares the MOSI, MISO and SCLK signals but is only active on the bus when the Host asserts the Device's individual CS line. +**Bus** A signal bus, common to all Devices connected to one Host. In general, a bus includes the following lines: MISO, MOSI, SCLK, one or more CS lines, and, optionally, QUADWP and QUADHD. So Devices are connected to the same lines, with the exception that each Device has its own CS line. Several Devices can also share one CS line if connected in the daisy-chain manner. +- **MISO** Master In, Slave Out, a.k.a. Q. Data transmission from a Device to Host. +- **MOSI** Master In, Slave Out, a.k.a. D. Data transmission from a Host to Device. +- **SCLK** Serial Clock. Oscillating signal generated by a Host that keeps the transmission of data bits in sync. +- **CS** Chip Select. Allows a Host to select individual Device(s) connected to the bus in order to send or receive data. +- **QUADWP** Write Protect signal. Only used for 4-bit (qio/qout) transactions. +- **QUADHD** Hold signal. Only used for 4-bit (qio/qout) transactions. +- **Assertion** The action of activating a line. The opposite action of returning the line back to inactive (back to idle) is called *de-assertion*. +**Transaction** One instance of a Host asserting a CS line, transferring data to and from a Device, and de-asserting the CS line. Transactions are atomic, which means they can never be interrupted by another transaction. +**Launch edge** Edge of the clock at which the source register *launches* the signal onto the line. +**Latch edge** Edge of the clock at which the destination register *latches in* the signal. +================= ========================================================================================= -SPI transactions -^^^^^^^^^^^^^^^^ -A full-duplex SPI transaction starts with the master pulling CS low. After this happens, the master -starts sending out clock pulses on the CLK line: every clock pulse causes a data bit to be shifted from -the master to the slave on the MOSI line and vice versa on the MISO line. At the end of the transaction, -the master makes CS high again. +Driver Features +--------------- -.. note:: The SPI slave peripheral relies on the control of software very - much. The master shouldn't start a transaction when the slave hasn't prepared - for it. Using one more GPIO as the handshake signal to sync is a good idea. - For more details, see :ref:`transaction_interval`. +The SPI slave driver allows using the SPI2 and/or SPI3 peripherals as full-duplex Devices. The driver can send/receive transactions up to 64 bytes in length, or utilize DMA to send/receive longer transactions. However, there are some :ref:`known issues ` related to DMA. -GPIO matrix and IOMUX -^^^^^^^^^^^^^^^^^^^^^ -Most peripheral signals in ESP32 can connect directly to a specific GPIO, -which is called its IOMUX pin. When a peripheral signal is routed to a pin -other than its IOMUX pin, ESP32 uses the less direct GPIO matrix to make this -connection. +SPI Transactions +---------------- -If the driver is configured with all SPI signals set to their specific IOMUX -pins (or left unconnected), it will bypass the GPIO matrix. If any SPI signal -is configured to a pin other than its IOMUx pin, the driver will -automatically route all the signals via the GPIO Matrix. The GPIO matrix -samples all signals at 80MHz and sends them between the GPIO and the -peripheral. +A full-duplex SPI transaction begins when the Host asserts the CS line and starts sending out clock pulses on the SCLK line. Every clock pulse, a data bit is shifted from the Host to the Device on the MOSI line and back on the MISO line at the same time. At the end of the transaction, the Host de-asserts the CS line. -When the GPIO matrix is used, setup time of MISO is more easily violated, -since the output delay of MISO signal is increased. +The attributes of a transaction are determined by the configuration structure for an SPI host acting as a slave device :cpp:type:`spi_slave_interface_config_t`, and transaction configuration structure :cpp:type:`spi_slave_transaction_t`. -.. note:: More details about influence of output delay on the maximum clock - frequency, see :ref:`timing_considerations` below. +As not every transaction requires both writing and reading data, you have a choice to configure the :cpp:type:`spi_transaction_t` structure for TX only, RX only, or TX and RX transactions. If :cpp:member:`spi_slave_transaction_t::rx_buffer` is set to NULL, the read phase will be skipped. If :cpp:member:`spi_slave_transaction_t::tx_buffer` is set to NULL, the write phase will be skipped. -IOMUX pins for SPI controllers are as below: +.. note:: + + A Host should not start a transaction before its Device is ready for receiving data. It is recommended to use another GPIO pin for a handshake signal to sync the Devices. For more details, see :ref:`transaction_interval`. + + +Driver Usage +------------ + +- Initialize an SPI peripheral as a Device by calling the function cpp:func:`spi_slave_initialize`. Make sure to set the correct I/O pins in the struct :cpp:type:`bus_config`. Set the unused signals to ``-1``. If transactions will be longer than 32 bytes, allow a DMA channel 1 or 2 by setting the parameter ``dma_chan`` to ``1`` or ``2`` respectively. Otherwise, set ``dma_chan`` to ``0``. + +- Before initiating transactions, fill one or more :cpp:type:`spi_slave_transaction_t` structs with the transaction parameters required. Either queue all transactions by calling the function :cpp:func:`spi_slave_queue_trans` and, at a later time, query the result by using the function :cpp:func:`spi_slave_get_trans_result`, or handle all requests individually by feeding them into :cpp:func:`spi_slave_transmit`. The latter two functions will be blocked until the Host has initiated and finished a transaction, causing the queued data to be sent and received. + +- (Optional) To unload the SPI slave driver, call :cpp:func:`spi_slave_free`. + + +Transaction Data and Master/Slave Length Mismatches +--------------------------------------------------- + +Normally, the data that needs to be transferred to or from a Device is read or written to a chunk of memory indicated by the :cpp:member:`rx_buffer` and :cpp:member:`tx_buffer` members of the :cpp:type:`spi_transaction_t` structure. The SPI driver can be configured to use DMA for transfers, in which case these buffers must be allocated in DMA-capable memory using ``pvPortMallocCaps(size, MALLOC_CAP_DMA)``. + +The amount of data that the driver can read or write to the buffers is limited by the member :cpp:member:`spi_transaction_t::length`. However, this member does not define the actual length of an SPI transaction. A transaction's length is determined by a Host which drives the clock and CS lines. The actual length of the transmission can be read only after a transaction is finished from the member :cpp:member:`spi_slave_transaction_t::trans_len`. + +If the length of the transmission is greater than the buffer length, only the initial number of bits specified in the :cpp:member:`length` member will be sent and received. In this case, :cpp:member:`trans_len` is set to :cpp:member:`length` instead of the actual transaction length. To meet the actual transaction length requirements, set :cpp:member:`length` to a value greater than the maximum :cpp:member:`trans_len` expected. If the transmission length is shorter than the buffer length, only the data equal to the length of the buffer will be transmitted. + +.. Warning:: + + The ESP32 DMA hardware has a limit to the number of bytes sent by a Host and received by a Device. The transaction length must be longer than 8 bytes and a multiple of 4 bytes; otherwise, the SPI hardware might fail to receive the last 1 to 7 bytes. + + +GPIO Matrix and IO_MUX +---------------------- + +Most of ESP32's peripheral signals have direct connection to their dedicated IO_MUX pins. However, the signals can also be routed to any other available pins using the less direct GPIO matrix. + +If at least one signal is routed through the GPIO matrix, then all signals will be routed through it. The GPIO matrix samples all signals at 80 MHz and transmits them between the GPIO and the peripheral. + +If the driver is configured so that all SPI signals are either routed to their dedicated IO_MUX pins or are not connected at all, the GPIO matrix will be bypassed. + +The GPIO matrix introduces flexibility of routing but also increases the input delay of the MISO signal, which makes MISO setup time violations more likely. If SPI needs to operate at high speeds, use dedicated IO_MUX pins. + +.. note:: + + For more details about the influence of the MISO input delay on the maximum clock frequency, see :ref:`timing_considerations`. + +The IO_MUX pins for SPI buses are given below. +----------+------+------+ -| Pin Name | HSPI | VSPI | +| Pin Name | SPI2 | SPI3 | + +------+------+ | | GPIO Number | +==========+======+======+ @@ -95,139 +119,74 @@ IOMUX pins for SPI controllers are as below: | QUADHD | 4 | 21 | +----------+------+------+ -note * Only the first device attaching to the bus can use CS0 pin. - -Using the spi_slave driver -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Initialize a SPI peripheral as a slave by calling ``spi_slave_initialize``. Make sure to set the - correct IO pins in the ``bus_config`` struct. Take care to set signals that are not needed to -1. - A DMA channel (either 1 or 2) must be given if transactions will be larger than 32 bytes, if not - the dma_chan parameter may be 0. - -- To set up a transaction, fill one or more spi_transaction_t structure with any transaction - parameters you need. Either queue all transactions by calling ``spi_slave_queue_trans``, later - quering the result using ``spi_slave_get_trans_result``, or handle all requests synchroneously - by feeding them into ``spi_slave_transmit``. The latter two functions will block until the - master has initiated and finished a transaction, causing the queued data to be sent and received. - -- Optional: to unload the SPI slave driver, call ``spi_slave_free``. +* Only the first Device attached to the bus can use the CS0 pin. -Transaction data and master/slave length mismatches -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Normally, data to be transferred to or from a device will be read from or written to a chunk of memory -indicated by the ``rx_buffer`` and ``tx_buffer`` members of the transaction structure. The SPI driver -may decide to use DMA for transfers, so these buffers should be allocated in DMA-capable memory using -``pvPortMallocCaps(size, MALLOC_CAP_DMA)``. - -The amount of data written to the buffers is limited by the ``length`` member of the transaction structure: -the driver will never read/write more data than indicated there. The ``length`` cannot define the actual -length of the SPI transaction; this is determined by the master as it drives the clock and CS lines. The actual length -transferred can be read from the ``trans_len`` member of the ``spi_slave_transaction_t`` structure after transaction. -In case the length of the transmission is larger than the buffer length, only the start of the transmission -will be sent and received, and the ``trans_len`` is set to ``length`` instead of the actual length. It's recommended to -set ``length`` longer than the maximum length expected if the ``trans_len`` is required. In case the transmission -length is shorter than the buffer length, only data up to the length of the buffer will be exchanged. - -Warning: Due to a design peculiarity in the ESP32, if the amount of bytes sent by the master or the length -of the transmission queues in the slave driver, in bytes, is not both larger than eight and dividable by -four, the SPI hardware can fail to write the last one to seven bytes to the receive buffer. - -Speed and Timing considerations +Speed and Timing Considerations ------------------------------- .. _transaction_interval: -Transaction interval +Transaction Interval ^^^^^^^^^^^^^^^^^^^^ -The SPI slave is designed as s general purpose device controlled by the CPU. -Different from dedicated devices, CPU-based SPI slave doesn't have too much -pre-defined registers. All transactions should be triggered by the CPU, which -means the response speed would not be real-time, and there'll always be -noticeable intervals between transfers. +The ESP32 SPI slave peripherals are designed as general purpose Devices controlled by a CPU. As opposed to dedicated slaves, CPU-based SPI Devices have a limited number of pre-defined registers. All transactions must be handled by the CPU, which means that the transfers and responses are not real-time, and there might be noticeable latency. -During the transaction intervals, the device is not prepared for -transactions, the response is not meaningful at all. It is suggested to use -:cpp:func:`spi_slave_queue_trans` with :cpp:func:`spi_slave_get_trans_result` -to shorten the interval to half the case when using -:cpp:func:`spi_slave_transmit`. +As a solution, a Device's response rate can be doubled by using the functions :cpp:func:`spi_slave_queue_trans` and then :cpp:func:`spi_slave_get_trans_result` instead of using :cpp:func:`spi_slave_transmit`. -The master should always wait for the slave to be ready to start new -transactions. Suggested way is to use a gpio by the slave to indicate whether -it's ready. The example is in :example:`peripherals/spi_slave`. +You can also configure a GPIO pin through which the Device will signal to the Host when it is ready for a new transaction. A code example of this can be found in :example:`peripherals/spi_slave`. -SCLK frequency requirement -^^^^^^^^^^^^^^^^^^^^^^^^^^ -The spi slave is designed to work under 10MHz or lower. The clock and data -cannot be recognized or received correctly if the clock is too fast or -doesn't have a 50% duty cycle. +SCLK Frequency Requirements +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Moreover, there are more requirements if the data meets the timing -requirement: +The SPI slaves are designed to operate at up to 10 MHz. The data cannot be recognized or received correctly if the clock is too fast or does not have a 50% duty cycle. + +On top of that, there are additional requirements for the data to meet the timing constraints: - Read (MOSI): - Given that the MOSI is valid right at the launch edge, the slave can - read data correctly. Luckily, it's usually the case for most masters. + The Device can read data correctly only if the data is already set at the launch edge. Although it is usually the case for most masters. - Write (MISO): - To meet the requirement that MISO is stable before the next latch edge of - SPI clock, the output delay of MISO signal should be shorter than half a - clock. The output delay and frequency limitation (given that the clock is - balanced) of different cases are as below : + The output delay of the MISO signal needs to be shorter than half of a clock cycle period so that the MISO line is stable before the next latch edge. Given that the clock is balanced, the output delay and frequency limitations in different cases are given below. +-------------+---------------------------+------------------------+ - | | Output delay of MISO (ns) | Freq. limit (MHZ) | + | | Output delay of MISO (ns) | Freq. limit (MHz) | +=============+===========================+========================+ - | IOMUX | 43.75 | <11.4 | + | IO_MUX | 43.75 | <11.4 | +-------------+---------------------------+------------------------+ | GPIO matrix | 68.75 | <7.2 | +-------------+---------------------------+------------------------+ Note: - 1. Random error will happen if the frequency exactly equals the - limitation - 2. The clock uncertainty between master and slave (12.5ns) is - included. - 3. The output delay is measured under ideal case (free of load). When - the loading of MISO pin is too heavy, the output delay will be longer, - and the maximum allowed frequency will be lower. + 1. If the frequency is equal to the limitation, it can lead to random errors. + 2. The clock uncertainty between Host and Device (12.5ns) is included. + 3. The output delay is measured under ideal circumstances (no load). If the MISO pin is heavily loaded, the output delay will be longer, and the maximum allowed frequency will be lower. + + Exception: The frequency is allowed to be higher if the master has more tolerance for the MISO setup time, e.g., latch data at the next edge than expected, or configurable latching time. - There is an exceptions: The frequency is allowed to be higher if the - master has more toleration for the MISO setup time, e.g. latch data at - the next edge than expected, or configurable latching time. .. _spi_dma_known_issues: -Restrictions and Known issues -------------------------------- +Restrictions and Known Issues +----------------------------- -1. If the DMA is enabled, the rx buffer should be WORD aligned, i.e. Start - from the boundary of 32-bit and have length of multiples of 4 bytes. Or the - DMA may write incorrectly or out of the boundary.The driver will check for - this. +1. If DMA is enabled, the rx buffer should be word-aligned (starting from a 32-bit boundary and having a length of multiples of 4 bytes). Otherwise, DMA may write incorrectly or not in a boundary aligned manner. The driver reports an error if this condition is not satisfied. - Also, master should write lengths which are a multiple of 4 bytes. Data - longer than that will be discarded. + Also, a Host should write lengths that are multiples of 4 bytes. The data with inappropriate lengths will be discarded. -2. Furthurmore, the DMA requires a spi mode 1/3 timing. When using spi mode - 0/2, the MISO signal has to output half a clock earlier to meet the timing. - The new timing is as below: +2. Furthermore, DMA requires SPI modes 1 and 3. For SPI modes 0 and 2, the MISO signal has to be launched half a clock cycle earlier to meet the timing. The new timing is as follows: .. image:: /../_static/spi_slave_miso_dma.png - The hold time after the latch edge is 68.75ns (when GPIO matrix is - bypassed), no longer half a SPI clock. The master should sample immediately - at the latch edge, or communicate in mode 1/3. Or just initial the spi - slave without DMA. +If DMA is enabled, a Device's launch edge is half of an SPI clock cycle ahead of the normal time, shifting to the Master's actual latch edge. In this case, if the GPIO matrix is bypassed, the hold time for data sampling is 68.75 ns and no longer a half of an SPI clock cycle. If the GPIO matrix is used, the hold time will increase to 93.75 ns. The Host should sample the data immediately at the latch edge or communicate in SPI modes 1 or 3. If your Host cannot meet these timing requirements, initialize your Device without DMA. + Application Example ------------------- -Slave/master communication: :example:`peripherals/spi_slave`. +The code example for Device/Host communication can be found in the :example:`peripherals/spi_slave` directory of ESP-IDF examples. + API Reference ------------- From 0744b6fadb119ec047e174a0be593d50e8b62549 Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Wed, 16 Oct 2019 12:37:45 +0200 Subject: [PATCH 17/21] CI: Adjust the test parameters of IDF Monitor --- tools/test_idf_monitor/run_test_idf_monitor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/test_idf_monitor/run_test_idf_monitor.py b/tools/test_idf_monitor/run_test_idf_monitor.py index 747e99e742..ea67d50873 100755 --- a/tools/test_idf_monitor/run_test_idf_monitor.py +++ b/tools/test_idf_monitor/run_test_idf_monitor.py @@ -36,8 +36,8 @@ test_list = ( ('in1.txt', '*:V', 'in1f1.txt', 60), ('in1.txt', 'hello_world', 'in1f2.txt', 60), ('in1.txt', '*:N', 'in1f3.txt', 60), - ('in2.txt', 'boot mdf_device_handle:I mesh:E vfs:I', 'in2f1.txt', 240), - ('in2.txt', 'vfs', 'in2f2.txt', 240), + ('in2.txt', 'boot mdf_device_handle:I mesh:E vfs:I', 'in2f1.txt', 420), + ('in2.txt', 'vfs', 'in2f2.txt', 420), ) IN_DIR = 'tests/' # tests are in this directory @@ -51,7 +51,7 @@ HOST = 'localhost' # blocking socket operations are used with timeout: SOCKET_TIMEOUT = 30 # the test is restarted after failure (idf_monitor has to be killed): -RETRIES_PER_TEST = 3 +RETRIES_PER_TEST = 2 def monitor_timeout(process): From 87c3decc1255edced1348841866b49324533d152 Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Mon, 6 Aug 2018 11:36:40 +0530 Subject: [PATCH 18/21] Remove check for would_block in mbedtls Basically, in the portability layer, it is checked if the socket is NON-block, and if not, then even the EAGAIN and EWOULDBLOCK errors are diverted to a RECV error. This causes a problem for sockets with receive timeouts set. When such a timeout is set, the condition for NON_BLOCK isn't met and hence a hard error is returned. Searching for EAGAIN and EWOULDBLOCK in lwip returns only 3 results (accept, recvfrom, close) and all of them look to be genuine cases for EWOULDBLOCK. So removing this check to make receive timeout with TLS work. --- components/mbedtls/port/net_sockets.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/components/mbedtls/port/net_sockets.c b/components/mbedtls/port/net_sockets.c index e64510071e..d6ca4b6741 100644 --- a/components/mbedtls/port/net_sockets.c +++ b/components/mbedtls/port/net_sockets.c @@ -198,14 +198,6 @@ static int net_would_block( const mbedtls_net_context *ctx ) { int error = errno; - /* - * Never return 'WOULD BLOCK' on a non-blocking socket - */ - if ( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK ) { - errno = error; - return ( 0 ); - } - switch ( errno = error ) { #if defined EAGAIN case EAGAIN: From 56f73d7720a8ff174cc2c9becd9708fea377aa63 Mon Sep 17 00:00:00 2001 From: Ajita Chavan Date: Sat, 19 Oct 2019 14:56:43 +0800 Subject: [PATCH 19/21] flash_ops: fix spi_flash_read with source buffer not from internal memory and size < 16 Closes https://github.com/espressif/esp-idf/issues/4010 --- components/spi_flash/flash_ops.c | 10 ++++++ components/spi_flash/test/CMakeLists.txt | 6 +++- components/spi_flash/test/component.mk | 4 +++ components/spi_flash/test/test_read_write.c | 33 ++++++++++++++++++++ tools/ci/config/target-test.yml | 4 +-- tools/unit-test-app/configs/spi_flash_legacy | 3 ++ 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 tools/unit-test-app/configs/spi_flash_legacy diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 1c5406a1c3..6e61da87de 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -513,7 +513,17 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size) goto out; } COUNTER_ADD_BYTES(read, read_size); +#ifdef ESP_PLATFORM + if (esp_ptr_external_ram(dstv)) { + spi_flash_guard_end(); + memcpy(dstv, ((uint8_t *) t) + left_off, size); + spi_flash_guard_start(); + } else { + memcpy(dstv, ((uint8_t *) t) + left_off, size); + } +#else memcpy(dstv, ((uint8_t *) t) + left_off, size); +#endif goto out; } uint8_t *dstc = (uint8_t *) dstv; diff --git a/components/spi_flash/test/CMakeLists.txt b/components/spi_flash/test/CMakeLists.txt index ae23154f2f..831e142120 100644 --- a/components/spi_flash/test/CMakeLists.txt +++ b/components/spi_flash/test/CMakeLists.txt @@ -1,3 +1,7 @@ idf_component_register(SRC_DIRS "." INCLUDE_DIRS "." - REQUIRES unity test_utils spi_flash bootloader_support app_update) \ No newline at end of file + REQUIRES unity test_utils spi_flash bootloader_support app_update) + +if(CONFIG_SPI_FLASH_USE_LEGACY_IMPL) + set(COMPONENT_SRCEXCLUDE "test_esp_flash.c" "test_partition_ext.c") +endif() diff --git a/components/spi_flash/test/component.mk b/components/spi_flash/test/component.mk index 5dd172bdb7..2a236e9d03 100644 --- a/components/spi_flash/test/component.mk +++ b/components/spi_flash/test/component.mk @@ -3,3 +3,7 @@ # COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive + +ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL + COMPONENT_OBJEXCLUDE += test_esp_flash.o test_partition_ext.o +endif diff --git a/components/spi_flash/test/test_read_write.c b/components/spi_flash/test/test_read_write.c index e780b6e2fe..f357695ebb 100644 --- a/components/spi_flash/test/test_read_write.c +++ b/components/spi_flash/test/test_read_write.c @@ -28,6 +28,7 @@ #include "soc/timer_periph.h" #include "esp_heap_caps.h" +#define MIN_BLOCK_SIZE 12 /* Base offset in flash for tests. */ static size_t start; @@ -266,4 +267,36 @@ TEST_CASE("spi_flash_write can write from external RAM buffer", "[spi_flash]") free(buf_int); } +TEST_CASE("spi_flash_read less than 16 bytes into buffer in external RAM", "[spi_flash]") +{ + uint8_t *buf_ext_8 = (uint8_t *) heap_caps_malloc(MIN_BLOCK_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(buf_ext_8); + + uint8_t *buf_int_8 = (uint8_t *) heap_caps_malloc(MIN_BLOCK_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(buf_int_8); + + uint8_t data_8[MIN_BLOCK_SIZE]; + for (int i = 0; i < MIN_BLOCK_SIZE; i++) { + data_8[i] = i; + } + + const esp_partition_t *part = get_test_data_partition(); + TEST_ESP_OK(spi_flash_erase_range(part->address, SPI_FLASH_SEC_SIZE)); + TEST_ESP_OK(spi_flash_write(part->address, data_8, MIN_BLOCK_SIZE)); + TEST_ESP_OK(spi_flash_read(part->address, buf_ext_8, MIN_BLOCK_SIZE)); + TEST_ESP_OK(spi_flash_read(part->address, buf_int_8, MIN_BLOCK_SIZE)); + + TEST_ASSERT_EQUAL(0, memcmp(buf_ext_8, data_8, MIN_BLOCK_SIZE)); + TEST_ASSERT_EQUAL(0, memcmp(buf_int_8, data_8, MIN_BLOCK_SIZE)); + + if (buf_ext_8) { + free(buf_ext_8); + buf_ext_8 = NULL; + } + if (buf_int_8) { + free(buf_int_8); + buf_int_8 = NULL; + } +} + #endif // CONFIG_ESP32_SPIRAM_SUPPORT diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index c2845ac964..35e80e0ebf 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -233,7 +233,7 @@ UT_001: UT_002: extends: .unit_test_template - parallel: 18 + parallel: 30 tags: - ESP32_IDF - UT_T1_1 @@ -432,7 +432,7 @@ UT_029: # Gitlab parallel max value is 50. We need to create another UT job if parallel is larger than 50. UT_030: extends: .unit_test_template - parallel: 6 + parallel: 10 tags: - ESP32_IDF - UT_T1_1 diff --git a/tools/unit-test-app/configs/spi_flash_legacy b/tools/unit-test-app/configs/spi_flash_legacy new file mode 100644 index 0000000000..3d5b1d9d2d --- /dev/null +++ b/tools/unit-test-app/configs/spi_flash_legacy @@ -0,0 +1,3 @@ +TEST_COMPONENTS=spi_flash +CONFIG_ESP32_SPIRAM_SUPPORT=y +CONFIG_SPI_FLASH_USE_LEGACY_IMPL=y From d3020b217d29927cb998e3bf3d7bf5d229dc1d0a Mon Sep 17 00:00:00 2001 From: Kewal Date: Mon, 21 Oct 2019 14:55:58 +0800 Subject: [PATCH 20/21] Add api to get total heap size in bytes for given capability --- components/heap/heap_caps.c | 12 ++++++++++++ components/heap/include/esp_heap_caps.h | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 9c7d91a2ee..2a9b12a514 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -329,6 +329,18 @@ IRAM_ATTR void *heap_caps_calloc( size_t n, size_t size, uint32_t caps) return result; } +size_t heap_caps_get_total_size(uint32_t caps) +{ + size_t total_size = 0; + heap_t *heap; + SLIST_FOREACH(heap, ®istered_heaps, next) { + if (heap_caps_match(heap, caps)) { + total_size += (heap->end - heap->start); + } + } + return total_size; +} + size_t heap_caps_get_free_size( uint32_t caps ) { size_t ret = 0; diff --git a/components/heap/include/esp_heap_caps.h b/components/heap/include/esp_heap_caps.h index 3b72522886..6df13cbf59 100644 --- a/components/heap/include/esp_heap_caps.h +++ b/components/heap/include/esp_heap_caps.h @@ -101,6 +101,20 @@ void *heap_caps_realloc( void *ptr, size_t size, int caps); */ void *heap_caps_calloc(size_t n, size_t size, uint32_t caps); +/** + * @brief Get the total size of all the regions that have the given capabilities + * + * This function takes all regions capable of having the given capabilities allocated in them + * and adds up the total space they have. + * + * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type + * of memory + * + * @return total size in bytes + */ + +size_t heap_caps_get_total_size(uint32_t caps); + /** * @brief Get the total free size of all the regions that have the given capabilities * From f58d7d14c7e264375b6824dceb742f553b51269c Mon Sep 17 00:00:00 2001 From: Hrishikesh Dhayagude Date: Mon, 21 Oct 2019 20:18:21 +0800 Subject: [PATCH 21/21] components/bt: Add support of NimBLE host in ESP BLE Mesh --- components/bt/CMakeLists.txt | 11 +- components/bt/Kconfig | 1 - components/bt/common/btc/core/btc_task.c | 4 +- .../bt/common/btc/include/btc/btc_manage.h | 2 - components/bt/common/include/bt_user_config.h | 2 +- components/bt/component.mk | 48 +- components/bt/esp_ble_mesh/Kconfig.in | 1 + .../api/core/esp_ble_mesh_common_api.c | 11 +- .../esp_ble_mesh_local_data_operation_api.c | 2 - .../api/core/esp_ble_mesh_low_power_api.c | 2 - .../api/core/esp_ble_mesh_networking_api.c | 16 +- .../api/core/esp_ble_mesh_provisioning_api.c | 42 +- .../api/core/esp_ble_mesh_proxy_api.c | 8 +- .../include/esp_ble_mesh_provisioning_api.h | 2 +- .../bt/esp_ble_mesh/api/esp_ble_mesh_defs.h | 46 +- .../models/esp_ble_mesh_config_model_api.c | 11 +- .../models/esp_ble_mesh_generic_model_api.c | 9 +- .../models/esp_ble_mesh_health_model_api.c | 13 +- .../models/esp_ble_mesh_lighting_model_api.c | 9 +- .../models/esp_ble_mesh_sensor_model_api.c | 9 +- .../esp_ble_mesh_time_scene_model_api.c | 9 +- .../bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c | 2 +- .../btc/include/btc_ble_mesh_prov.h | 1 - components/bt/esp_ble_mesh/mesh_core/adv.c | 2 +- .../{ => bluedroid_host}/mesh_bearer_adapt.c | 38 + .../mesh_core/include/mesh_bearer_adapt.h | 17 + .../mesh_core/include/mesh_trace.h | 6 + .../bt/esp_ble_mesh/mesh_core/mesh_hci.c | 45 - .../bt/esp_ble_mesh/mesh_core/mesh_kernel.c | 3 +- .../mesh_core/nimble_host/mesh_bearer_adapt.c | 1796 +++++++++++++++++ .../bt/host/bluedroid/api/esp_gap_bt_api.c | 1 + components/bt/host/nimble/Kconfig.in | 1 + .../ble_mesh_client_model/main/CMakeLists.txt | 1 + .../main/ble_mesh_demo_init.c | 143 ++ .../main/ble_mesh_demo_init.h | 18 + .../main/ble_mesh_demo_main.c | 56 +- .../main/ble_mesh_register_provisioner_cmd.c | 6 +- .../main/CMakeLists.txt | 3 +- .../main/ble_mesh_demo_init.c | 143 ++ .../main/ble_mesh_demo_init.h | 18 + .../main/ble_mesh_demo_main.c | 73 +- .../main/CMakeLists.txt | 1 + .../main/ble_mesh_demo_init.c | 143 ++ .../main/ble_mesh_demo_init.h | 18 + .../main/ble_mesh_demo_main.c | 66 +- .../ble_mesh_node/main/CMakeLists.txt | 1 + .../ble_mesh_node/main/ble_mesh_demo_init.c | 143 ++ .../ble_mesh_node/main/ble_mesh_demo_init.h | 18 + .../ble_mesh_node/main/ble_mesh_demo_main.c | 57 +- .../Ble_Mesh_Node_Example_Walkthrough.md | 2 +- .../ble_mesh_provisioner/main/CMakeLists.txt | 3 +- .../main/ble_mesh_demo_init.c | 143 ++ .../main/ble_mesh_demo_init.h | 18 + .../main/ble_mesh_demo_main.c | 67 +- ...le_Mesh_Provisioner_Example_Walkthrough.md | 2 +- .../ble_mesh_wifi_coexist/main/CMakeLists.txt | 1 + .../main/ble_mesh_demo_init.c | 143 ++ .../main/ble_mesh_demo_init.h | 18 + .../main/ble_mesh_demo_main.c | 66 +- 59 files changed, 3066 insertions(+), 475 deletions(-) rename components/bt/esp_ble_mesh/mesh_core/{ => bluedroid_host}/mesh_bearer_adapt.c (97%) delete mode 100644 components/bt/esp_ble_mesh/mesh_core/mesh_hci.c create mode 100644 components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.c create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.h create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.c create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.h create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.c create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.h create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.c create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.h create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.c create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.h create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.c create mode 100644 examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.h diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index d9cae26f12..506575708f 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -289,6 +289,11 @@ if(CONFIG_BT_ENABLED) "host/bluedroid/stack/smp/smp_l2c.c" "host/bluedroid/stack/smp/smp_main.c" "host/bluedroid/stack/smp/smp_utils.c") + + if(CONFIG_BLE_MESH) + list(APPEND srcs "esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c") + endif() + endif() if(CONFIG_BLE_MESH) @@ -335,9 +340,7 @@ if(CONFIG_BT_ENABLED) "esp_ble_mesh/mesh_core/lpn.c" "esp_ble_mesh/mesh_core/mesh_aes_encrypt.c" "esp_ble_mesh/mesh_core/mesh_atomic.c" - "esp_ble_mesh/mesh_core/mesh_bearer_adapt.c" "esp_ble_mesh/mesh_core/mesh_buf.c" - "esp_ble_mesh/mesh_core/mesh_hci.c" "esp_ble_mesh/mesh_core/mesh_kernel.c" "esp_ble_mesh/mesh_core/mesh_main.c" "esp_ble_mesh/mesh_core/mesh_util.c" @@ -469,6 +472,10 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/porting/nimble/src/os_cputime.c" "host/nimble/esp-hci/src/esp_nimble_hci.c") + if (CONFIG_BLE_MESH) + list(APPEND srcs "esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c") + endif() + if(CONFIG_BT_NIMBLE_MESH) list(APPEND include_dirs diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 6d340656b2..6346b818f0 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -410,7 +410,6 @@ endmenu menuconfig BLE_MESH bool "ESP BLE Mesh Support" - depends on BT_BLUEDROID_ENABLED help This option enables ESP BLE Mesh support. The specific features that are available may depend on other features that have been enabled in the diff --git a/components/bt/common/btc/core/btc_task.c b/components/bt/common/btc/core/btc_task.c index cdcfe74700..a3e2a67777 100644 --- a/components/bt/common/btc/core/btc_task.c +++ b/components/bt/common/btc/core/btc_task.c @@ -19,6 +19,7 @@ #include "esp_log.h" #include "bt_common.h" #include "osi/allocator.h" +#include "btc/btc_alarm.h" #ifdef CONFIG_BT_BLUEDROID_ENABLED #include "common/bt_target.h" @@ -32,7 +33,6 @@ #include "btc_blufi_prf.h" #include "blufi_int.h" #include "btc/btc_dm.h" -#include "btc/btc_alarm.h" #include "bta/bta_gatt_api.h" #if CLASSIC_BT_INCLUDED #include "btc/btc_profile_queue.h" @@ -94,7 +94,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = { [BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler }, #endif ///GATTS_INCLUDED == TRUE [BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler }, +#endif [BTC_PID_ALARM] = {btc_alarm_handler, NULL }, +#ifdef CONFIG_BT_BLUEDROID_ENABLED #if CLASSIC_BT_INCLUDED #if (BTC_GAP_BT_INCLUDED == TRUE) [BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, btc_gap_bt_cb_handler }, diff --git a/components/bt/common/btc/include/btc/btc_manage.h b/components/bt/common/btc/include/btc/btc_manage.h index 48ba1c5e10..e787e15916 100644 --- a/components/bt/common/btc/include/btc/btc_manage.h +++ b/components/bt/common/btc/include/btc/btc_manage.h @@ -15,9 +15,7 @@ #ifndef __BTC_MANAGE_H__ #define __BTC_MANAGE_H__ -#include "bta/bta_api.h" #include "btc/btc_task.h" -#include "esp_bt_defs.h" #if BTC_DYNAMIC_MEMORY == FALSE extern void *btc_profile_cb_tab[BTC_PID_NUM]; diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 37f5ca1158..52b855f31e 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -49,7 +49,7 @@ #ifdef CONFIG_BTC_TASK_STACK_SIZE #define UC_BTC_TASK_STACK_SIZE CONFIG_BTC_TASK_STACK_SIZE #else -#define UC_BTC_TASK_STACK_SIZE 3072 +#define UC_BTC_TASK_STACK_SIZE 4096 #endif /********************************************************** diff --git a/components/bt/component.mk b/components/bt/component.mk index da70ea45a1..ed542dcc4f 100644 --- a/components/bt/component.mk +++ b/components/bt/component.mk @@ -129,26 +129,31 @@ COMPONENT_PRIV_INCLUDEDIRS += common/btc/include \ COMPONENT_SRCDIRS += common/osi \ common/btc/core +ifdef CONFIG_BLE_MESH + +COMPONENT_SRCDIRS += esp_ble_mesh/mesh_core/bluedroid_host + +endif endif ifdef CONFIG_BLE_MESH - COMPONENT_ADD_INCLUDEDIRS += esp_ble_mesh/mesh_core \ - esp_ble_mesh/mesh_core/include \ - esp_ble_mesh/mesh_core/settings \ - esp_ble_mesh/btc/include \ - esp_ble_mesh/mesh_models/common/include \ - esp_ble_mesh/mesh_models/client/include \ - esp_ble_mesh/api/core/include \ - esp_ble_mesh/api/models/include \ - esp_ble_mesh/api +COMPONENT_ADD_INCLUDEDIRS += esp_ble_mesh/mesh_core \ + esp_ble_mesh/mesh_core/include \ + esp_ble_mesh/mesh_core/settings \ + esp_ble_mesh/btc/include \ + esp_ble_mesh/mesh_models/common/include \ + esp_ble_mesh/mesh_models/client/include \ + esp_ble_mesh/api/core/include \ + esp_ble_mesh/api/models/include \ + esp_ble_mesh/api - COMPONENT_SRCDIRS += esp_ble_mesh/mesh_core \ - esp_ble_mesh/mesh_core/settings \ - esp_ble_mesh/btc \ - esp_ble_mesh/mesh_models/common \ - esp_ble_mesh/mesh_models/client \ - esp_ble_mesh/api/core \ - esp_ble_mesh/api/models +COMPONENT_SRCDIRS += esp_ble_mesh/mesh_core \ + esp_ble_mesh/mesh_core/settings \ + esp_ble_mesh/btc \ + esp_ble_mesh/mesh_models/common \ + esp_ble_mesh/mesh_models/client \ + esp_ble_mesh/api/core \ + esp_ble_mesh/api/models endif @@ -196,6 +201,17 @@ endif COMPONENT_OBJEXCLUDE += host/nimble/nimble/nimble/host/store/config/src/ble_store_config_conf.o +ifdef CONFIG_BLE_MESH +COMPONENT_PRIV_INCLUDEDIRS += common/btc/include \ + common/include + +COMPONENT_SRCDIRS += common/osi \ + common/btc/core \ + esp_ble_mesh/mesh_core/nimble_host + +COMPONENT_ADD_INCLUDEDIRS += common/osi/include +endif + ifdef CONFIG_BT_NIMBLE_MESH COMPONENT_ADD_INCLUDEDIRS += host/nimble/nimble/nimble/host/mesh/include diff --git a/components/bt/esp_ble_mesh/Kconfig.in b/components/bt/esp_ble_mesh/Kconfig.in index 806f98521a..63c7eb9d27 100644 --- a/components/bt/esp_ble_mesh/Kconfig.in +++ b/components/bt/esp_ble_mesh/Kconfig.in @@ -8,6 +8,7 @@ if BLE_MESH config BLE_MESH_USE_DUPLICATE_SCAN bool "Support Duplicate Scan in BLE Mesh" + depends on BT_BLUEDROID_ENABLED select BLE_SCAN_DUPLICATE select BLE_MESH_SCAN_DUPLICATE_EN default y diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c index 2a5253f907..b946a16c2c 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c @@ -19,10 +19,9 @@ #include "btc/btc_task.h" #include "btc/btc_manage.h" +#include "osi/alarm.h" #include "esp_err.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" #include "btc_ble_mesh_prov.h" #include "esp_ble_mesh_defs.h" @@ -32,12 +31,18 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp btc_ble_mesh_prov_args_t arg = {0}; SemaphoreHandle_t semaphore = NULL; btc_msg_t msg = {0}; + esp_err_t ret; if (prov == NULL || comp == NULL) { return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + ret = bt_mesh_host_init(); + if (ret != ESP_OK) { + return ret; + } // Create a semaphore if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) { diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c index 50e49b80ab..f02cb6fb9f 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c @@ -19,8 +19,6 @@ #include "btc/btc_manage.h" #include "esp_err.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" #include "btc_ble_mesh_prov.h" #include "esp_ble_mesh_defs.h" diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c index 4d93f809ef..07301c8377 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c @@ -18,8 +18,6 @@ #include "btc/btc_manage.h" #include "esp_err.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" #include "btc_ble_mesh_prov.h" #include "esp_ble_mesh_defs.h" diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c index 7ebe7916ea..e8e3153b3b 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c @@ -19,8 +19,6 @@ #include "btc/btc_manage.h" #include "esp_err.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" #include "btc_ble_mesh_prov.h" #include "esp_ble_mesh_networking_api.h" @@ -41,7 +39,7 @@ static esp_err_t ble_mesh_send_msg(esp_ble_mesh_model_t *model, btc_msg_t msg = {0}; esp_err_t status; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); if (device_role > ROLE_FAST_PROV) { return ESP_ERR_INVALID_ARG; @@ -118,7 +116,7 @@ static esp_err_t ble_mesh_send_msg(esp_ble_mesh_model_t *model, esp_err_t esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_MODEL, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -198,7 +196,7 @@ esp_err_t esp_ble_mesh_node_local_reset(void) { btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -218,7 +216,7 @@ esp_err_t esp_ble_mesh_provisioner_set_node_name(int index, const char *name) return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -251,7 +249,7 @@ esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16], btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -283,7 +281,7 @@ esp_err_t esp_ble_mesh_provisioner_bind_app_key_to_local_model(uint16_t element_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -306,7 +304,7 @@ esp_err_t esp_ble_mesh_provisioner_add_local_net_key(const uint8_t net_key[16], return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c index b8f12244eb..b9501eb49f 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c @@ -18,8 +18,6 @@ #include "btc/btc_manage.h" #include "esp_err.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" #include "btc_ble_mesh_prov.h" #include "esp_ble_mesh_provisioning_api.h" @@ -29,7 +27,7 @@ esp_err_t esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_PROV, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -44,7 +42,7 @@ esp_err_t esp_ble_mesh_node_prov_enable(esp_ble_mesh_prov_bearer_t bearers) btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -60,7 +58,7 @@ esp_err_t esp_ble_mesh_node_prov_disable(esp_ble_mesh_prov_bearer_t bearers) btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -81,7 +79,7 @@ esp_err_t esp_ble_mesh_node_set_oob_pub_key(uint8_t pub_key_x[32], uint8_t pub_k return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -104,7 +102,7 @@ esp_err_t esp_ble_mesh_node_input_number(uint32_t number) return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -124,7 +122,7 @@ esp_err_t esp_ble_mesh_node_input_string(const char *string) return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -145,7 +143,7 @@ esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name) return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -168,7 +166,7 @@ esp_err_t esp_ble_mesh_provisioner_read_oob_pub_key(uint8_t link_idx, uint8_t pu return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -191,7 +189,7 @@ esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -214,7 +212,7 @@ esp_err_t esp_ble_mesh_provisioner_input_number(uint32_t number, uint8_t link_id return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -232,7 +230,7 @@ esp_err_t esp_ble_mesh_provisioner_prov_enable(esp_ble_mesh_prov_bearer_t bearer btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -249,7 +247,7 @@ esp_err_t esp_ble_mesh_provisioner_prov_disable(esp_ble_mesh_prov_bearer_t beare btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -271,7 +269,7 @@ esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -280,7 +278,7 @@ esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t arg.provisioner_dev_add.add_dev.addr_type = add_dev->addr_type; arg.provisioner_dev_add.add_dev.oob_info = add_dev->oob_info; arg.provisioner_dev_add.add_dev.bearer = add_dev->bearer; - memcpy(arg.provisioner_dev_add.add_dev.addr, add_dev->addr, sizeof(esp_bd_addr_t)); + memcpy(arg.provisioner_dev_add.add_dev.addr, add_dev->addr, sizeof(esp_ble_mesh_bd_addr_t)); memcpy(arg.provisioner_dev_add.add_dev.uuid, add_dev->uuid, 16); arg.provisioner_dev_add.flags = flags; return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) @@ -297,7 +295,7 @@ esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -306,7 +304,7 @@ esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_ arg.provisioner_dev_del.del_dev.flag = del_dev->flag; if (del_dev->flag & DEL_DEV_ADDR_FLAG) { arg.provisioner_dev_del.del_dev.addr_type = del_dev->addr_type; - memcpy(arg.provisioner_dev_del.del_dev.addr, del_dev->addr, sizeof(esp_bd_addr_t)); + memcpy(arg.provisioner_dev_del.del_dev.addr, del_dev->addr, sizeof(esp_ble_mesh_bd_addr_t)); } else if (del_dev->flag & DEL_DEV_UUID_FLAG) { memcpy(arg.provisioner_dev_del.del_dev.uuid, del_dev->uuid, 16); } @@ -320,7 +318,7 @@ esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -346,7 +344,7 @@ esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_inf return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -379,7 +377,7 @@ esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_pr return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -408,7 +406,7 @@ esp_err_t esp_ble_mesh_set_fast_prov_action(esp_ble_mesh_fast_prov_action_t acti return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c index 4d25a656f4..950220da3f 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c @@ -18,8 +18,6 @@ #include "btc/btc_manage.h" #include "esp_err.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" #include "btc_ble_mesh_prov.h" #include "esp_ble_mesh_defs.h" @@ -28,7 +26,7 @@ esp_err_t esp_ble_mesh_proxy_identity_enable(void) { btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -41,7 +39,7 @@ esp_err_t esp_ble_mesh_proxy_gatt_enable(void) { btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; @@ -54,7 +52,7 @@ esp_err_t esp_ble_mesh_proxy_gatt_disable(void) { btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h index a5a4256f44..b947ac6643 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h @@ -259,7 +259,7 @@ esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_ * @param[in] bearer: Adv packet received from PB-GATT or PB-ADV bearer. * */ -typedef void (*esp_ble_mesh_prov_adv_cb_t)(const esp_bd_addr_t addr, const esp_ble_addr_type_t addr_type, +typedef void (*esp_ble_mesh_prov_adv_cb_t)(const esp_ble_mesh_bd_addr_t addr, const esp_ble_mesh_addr_type_t addr_type, const uint8_t adv_type, const uint8_t *dev_uuid, uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer); diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 9696bb48ca..1e6bfbc762 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -17,8 +17,6 @@ #include -#include "esp_bt_defs.h" - #include "mesh_proxy.h" #include "mesh_access.h" #include "mesh_main.h" @@ -31,6 +29,16 @@ #include "model_opcode.h" #include "mesh_common.h" +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#include "esp_bt_defs.h" +#include "esp_bt_main.h" +#define ESP_BLE_HOST_STATUS_ENABLED ESP_BLUEDROID_STATUS_ENABLED +#define ESP_BLE_HOST_STATUS_CHECK(status) ESP_BLUEDROID_STATUS_CHECK(status) +#else +#define ESP_BLE_HOST_STATUS_ENABLED 0 +#define ESP_BLE_HOST_STATUS_CHECK(status) do {} while (0) +#endif + /*!< The maximum length of a BLE Mesh message, including Opcode, Payload and TransMIC */ #define ESP_BLE_MESH_SDU_MAX_LEN 384 @@ -790,6 +798,30 @@ typedef enum { .input_action = in_act, \ } +typedef uint8_t UINT8; +typedef uint16_t UINT16; +typedef uint32_t UINT32; +typedef uint64_t UINT64; + +#define BT_OCTET32_LEN 32 +typedef UINT8 BT_OCTET32[BT_OCTET32_LEN]; /* octet array: size 32 */ + + +#ifndef BD_ADDR_LEN +#define BD_ADDR_LEN 6 +typedef uint8_t BD_ADDR[BD_ADDR_LEN]; +#endif + +typedef uint8_t esp_ble_mesh_bd_addr_t[BD_ADDR_LEN]; + +/// BLE device address type +typedef enum { + ESP_BLE_MESH_ADDR_TYPE_PUBLIC = 0x00, + ESP_BLE_MESH_ADDR_TYPE_RANDOM = 0x01, + ESP_BLE_MESH_ADDR_TYPE_RPA_PUBLIC = 0x02, + ESP_BLE_MESH_ADDR_TYPE_RPA_RANDOM = 0x03, +} esp_ble_mesh_addr_type_t; + typedef struct esp_ble_mesh_model esp_ble_mesh_model_t; /** Abstraction that describes a BLE Mesh Element. @@ -1110,8 +1142,8 @@ typedef uint8_t esp_ble_mesh_dev_add_flag_t; /** Information of the device which is going to be added for provisioning. */ typedef struct { - esp_bd_addr_t addr; /*!< Device address */ - esp_ble_addr_type_t addr_type; /*!< Device address type */ + esp_ble_mesh_bd_addr_t addr; /*!< Device address */ + esp_ble_mesh_addr_type_t addr_type; /*!< Device address type */ uint8_t uuid[16]; /*!< Device UUID */ uint16_t oob_info; /*!< Device OOB Info */ /*!< ADD_DEV_START_PROV_NOW_FLAG shall not be set if the bearer has both PB-ADV and PB-GATT enabled */ @@ -1124,8 +1156,8 @@ typedef struct { typedef struct { union { struct { - esp_bd_addr_t addr; /*!< Device address */ - esp_ble_addr_type_t addr_type; /*!< Device address type */ + esp_ble_mesh_bd_addr_t addr; /*!< Device address */ + esp_ble_mesh_addr_type_t addr_type; /*!< Device address type */ }; uint8_t uuid[16]; /*!< Device UUID */ }; @@ -1340,7 +1372,7 @@ typedef union { struct ble_mesh_provisioner_recv_unprov_adv_pkt_param { uint8_t dev_uuid[16]; /*!< Device UUID of the unprovisoned device */ uint8_t addr[6]; /*!< Device address of the unprovisoned device */ - esp_ble_addr_type_t addr_type; /*!< Device address type */ + esp_ble_mesh_addr_type_t addr_type; /*!< Device address type */ uint16_t oob_info; /*!< OOB Info of the unprovisoned device */ uint8_t adv_type; /*!< Avertising type of the unprovisoned device */ esp_ble_mesh_prov_bearer_t bearer; /*!< Bearer of the unprovisoned device */ diff --git a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c index 08cfcc04fe..3b997e113f 100644 --- a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c +++ b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c @@ -17,22 +17,19 @@ #include "btc/btc_task.h" #include "btc/btc_manage.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" - #include "btc_ble_mesh_config_model.h" #include "esp_ble_mesh_config_model_api.h" esp_err_t esp_ble_mesh_register_config_client_callback(esp_ble_mesh_cfg_client_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_CONFIG_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL); } esp_err_t esp_ble_mesh_register_config_server_callback(esp_ble_mesh_cfg_server_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_CONFIG_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -47,7 +44,7 @@ esp_err_t esp_ble_mesh_config_client_get_state(esp_ble_mesh_client_common_param_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_CONFIG_CLIENT; @@ -69,7 +66,7 @@ esp_err_t esp_ble_mesh_config_client_set_state(esp_ble_mesh_client_common_param_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_CONFIG_CLIENT; diff --git a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c index fdf1f72d63..24d55dec37 100644 --- a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c +++ b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c @@ -17,15 +17,12 @@ #include "btc/btc_task.h" #include "btc/btc_manage.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" - #include "btc_ble_mesh_generic_model.h" #include "esp_ble_mesh_generic_model_api.h" esp_err_t esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_client_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_GENERIC_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -40,7 +37,7 @@ esp_err_t esp_ble_mesh_generic_client_get_state(esp_ble_mesh_client_common_param return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GENERIC_CLIENT; @@ -62,7 +59,7 @@ esp_err_t esp_ble_mesh_generic_client_set_state(esp_ble_mesh_client_common_param return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GENERIC_CLIENT; diff --git a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c index cdbdb04ac4..4c32ab6d49 100644 --- a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c +++ b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c @@ -17,22 +17,19 @@ #include "btc/btc_task.h" #include "btc/btc_manage.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" - #include "btc_ble_mesh_health_model.h" #include "esp_ble_mesh_health_model_api.h" esp_err_t esp_ble_mesh_register_health_client_callback(esp_ble_mesh_health_client_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_HEALTH_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL); } esp_err_t esp_ble_mesh_register_health_server_callback(esp_ble_mesh_health_server_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_HEALTH_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -47,7 +44,7 @@ esp_err_t esp_ble_mesh_health_client_get_state(esp_ble_mesh_client_common_param_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_HEALTH_CLIENT; @@ -69,7 +66,7 @@ esp_err_t esp_ble_mesh_health_client_set_state(esp_ble_mesh_client_common_param_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_HEALTH_CLIENT; @@ -86,7 +83,7 @@ esp_err_t esp_ble_mesh_health_server_fault_update(esp_ble_mesh_elem_t *element) btc_ble_mesh_health_server_args_t arg = {0}; btc_msg_t msg = {0}; - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_HEALTH_SERVER; diff --git a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c index df998b243f..33dba45aba 100644 --- a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c +++ b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c @@ -17,15 +17,12 @@ #include "btc/btc_task.h" #include "btc/btc_manage.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" - #include "btc_ble_mesh_lighting_model.h" #include "esp_ble_mesh_lighting_model_api.h" esp_err_t esp_ble_mesh_register_light_client_callback(esp_ble_mesh_light_client_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_LIGHTING_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -40,7 +37,7 @@ esp_err_t esp_ble_mesh_light_client_get_state(esp_ble_mesh_client_common_param_t return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_LIGHTING_CLIENT; @@ -62,7 +59,7 @@ esp_err_t esp_ble_mesh_light_client_set_state(esp_ble_mesh_client_common_param_t return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_LIGHTING_CLIENT; diff --git a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c index 20ae8bdd5e..7a74b7554c 100644 --- a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c +++ b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c @@ -17,15 +17,12 @@ #include "btc/btc_task.h" #include "btc/btc_manage.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" - #include "btc_ble_mesh_sensor_model.h" #include "esp_ble_mesh_sensor_model_api.h" esp_err_t esp_ble_mesh_register_sensor_client_callback(esp_ble_mesh_sensor_client_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_SENSOR_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -40,7 +37,7 @@ esp_err_t esp_ble_mesh_sensor_client_get_state(esp_ble_mesh_client_common_param_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_SENSOR_CLIENT; @@ -62,7 +59,7 @@ esp_err_t esp_ble_mesh_sensor_client_set_state(esp_ble_mesh_client_common_param_ return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_SENSOR_CLIENT; diff --git a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c index 88c27cea98..482638011c 100644 --- a/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c +++ b/components/bt/esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c @@ -17,15 +17,12 @@ #include "btc/btc_task.h" #include "btc/btc_manage.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" - #include "btc_ble_mesh_time_scene_model.h" #include "esp_ble_mesh_time_scene_model_api.h" esp_err_t esp_ble_mesh_register_time_scene_client_callback(esp_ble_mesh_time_scene_client_cb_t callback) { - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); return (btc_profile_cb_set(BTC_PID_TIME_SCENE_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -40,7 +37,7 @@ esp_err_t esp_ble_mesh_time_scene_client_get_state(esp_ble_mesh_client_common_pa return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_TIME_SCENE_CLIENT; @@ -62,7 +59,7 @@ esp_err_t esp_ble_mesh_time_scene_client_set_state(esp_ble_mesh_client_common_pa return ESP_ERR_INVALID_ARG; } - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_TIME_SCENE_CLIENT; diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index 09aa53125f..2dd68e2a49 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -689,7 +689,7 @@ static void btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb( } memcpy(mesh_param.provisioner_recv_unprov_adv_pkt.dev_uuid, dev_uuid, 16); - memcpy(mesh_param.provisioner_recv_unprov_adv_pkt.addr, addr, ESP_BD_ADDR_LEN); + memcpy(mesh_param.provisioner_recv_unprov_adv_pkt.addr, addr, BLE_MESH_ADDR_LEN); mesh_param.provisioner_recv_unprov_adv_pkt.addr_type = addr_type; mesh_param.provisioner_recv_unprov_adv_pkt.oob_info = oob_info; mesh_param.provisioner_recv_unprov_adv_pkt.adv_type = adv_type; diff --git a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h index f51e71428f..a179b62030 100644 --- a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h +++ b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h @@ -21,7 +21,6 @@ #include "freertos/semphr.h" #include "btc/btc_task.h" -#include "esp_bt_defs.h" #include "mesh_access.h" #include "mesh_buf.h" diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.c b/components/bt/esp_ble_mesh/mesh_core/adv.c index 994e28215c..05de517823 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.c +++ b/components/bt/esp_ble_mesh/mesh_core/adv.c @@ -388,7 +388,7 @@ void bt_mesh_adv_init(void) xBleMeshQueue = xQueueCreate(150, sizeof(bt_mesh_msg_t)); configASSERT(xBleMeshQueue); int ret = xTaskCreatePinnedToCore(adv_thread, "BLE_Mesh_ADV_Task", 3072, NULL, - configMAX_PRIORITIES - 7, NULL, TASK_PINNED_TO_CORE); + configMAX_PRIORITIES - 7, NULL, ADV_TASK_CORE); configASSERT(ret == pdTRUE); } diff --git a/components/bt/esp_ble_mesh/mesh_core/mesh_bearer_adapt.c b/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c similarity index 97% rename from components/bt/esp_ble_mesh/mesh_core/mesh_bearer_adapt.c rename to components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c index d6eed43b8e..9b5ed3ca5c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/mesh_bearer_adapt.c +++ b/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c @@ -19,6 +19,8 @@ #include "stack/hcimsgs.h" #include "osi/future.h" #include "osi/allocator.h" +#include "bt_common.h" +#include "device/controller.h" #include "mbedtls/aes.h" @@ -32,6 +34,8 @@ #include "provisioner_prov.h" #include "mesh_common.h" +struct bt_mesh_dev bt_mesh_dev; + #define BLE_MESH_BTM_CHECK_STATUS(func) do { \ tBTM_STATUS __status = (func); \ if ((__status != BTM_SUCCESS) && (__status != BTM_CMD_STARTED)) { \ @@ -97,6 +101,40 @@ static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb; static tBTA_GATTC_IF bt_mesh_gattc_if; #endif /* defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER */ +esp_err_t bt_mesh_host_init(void) +{ + return ESP_OK; +} + +void bt_mesh_hci_init(void) +{ + const uint8_t *features = controller_get_interface()->get_features_ble()->as_array; + if (features != NULL) { + memcpy(bt_mesh_dev.features[0], features, 8); + memcpy(bt_mesh_dev.le.features, features, 8); + } + + /** + * Currently 20ms non-connectable adv interval is supported, and we need to add + * a flag to indicate this support. + */ +#ifdef CONFIG_BLE_MESH_HCI_5_0 + bt_mesh_dev.hci_version = BLE_MESH_HCI_VERSION_5_0; +#else + bt_mesh_dev.hci_version = controller_get_interface()->get_bt_version()->hci_version; +#endif + bt_mesh_dev.lmp_version = controller_get_interface()->get_bt_version()->lmp_version; + bt_mesh_dev.hci_revision = controller_get_interface()->get_bt_version()->hci_revision; + bt_mesh_dev.lmp_subversion = controller_get_interface()->get_bt_version()->lmp_subversion; + bt_mesh_dev.manufacturer = controller_get_interface()->get_bt_version()->manufacturer; + + const uint8_t *p = controller_get_interface()->get_ble_supported_states(); + uint64_t states_fh = 0, states_sh = 0; + STREAM_TO_UINT32(states_fh, p); + STREAM_TO_UINT32(states_sh, p); + bt_mesh_dev.le.states = (states_sh << 32) | states_fh; +} + static void bt_mesh_scan_results_change_2_bta(tBTM_INQ_RESULTS *p_inq, u8_t *p_eir, tBTA_DM_SEARCH_CBACK *p_scan_cback) { diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h index 1382031878..0d8ecd96dd 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h @@ -16,8 +16,23 @@ #include "mesh_uuid.h" /* BLE Mesh Max Connection Count */ +#ifdef CONFIG_BT_BLUEDROID_ENABLED #define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS +#define ADV_TASK_CORE TASK_PINNED_TO_CORE +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +#define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS + +#ifdef CONFIG_BT_NIMBLE_PINNED_TO_CORE +#define ADV_TASK_CORE (CONFIG_BT_NIMBLE_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_NIMBLE_PINNED_TO_CORE : tskNO_AFFINITY) +#else +#define ADV_TASK_CORE (0) +#endif + +#endif + /* BD ADDR types */ #define BLE_MESH_ADDR_PUBLIC 0x00 #define BLE_MESH_ADDR_RANDOM 0x01 @@ -620,6 +635,8 @@ struct bt_mesh_gatt_attr { .attr_count = ARRAY_SIZE(_attrs), \ } +esp_err_t bt_mesh_host_init(void); + int bt_le_adv_start(const struct bt_mesh_adv_param *param, const struct bt_mesh_adv_data *ad, size_t ad_len, const struct bt_mesh_adv_data *sd, size_t sd_len); diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_trace.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_trace.h index 325c807f93..dee8bb7cd3 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_trace.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_trace.h @@ -47,6 +47,12 @@ #define MESH_TRACE_TAG "BLE_MESH" +#define LOG_ERROR(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) esp_log_write(ESP_LOG_ERROR, "BT_LOG", LOG_FORMAT(E, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } +#define LOG_WARN(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) esp_log_write(ESP_LOG_WARN, "BT_LOG", LOG_FORMAT(W, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } +#define LOG_INFO(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) esp_log_write(ESP_LOG_INFO, "BT_LOG", LOG_FORMAT(I, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } +#define LOG_DEBUG(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) esp_log_write(ESP_LOG_DEBUG, "BT_LOG", LOG_FORMAT(D, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } +#define LOG_VERBOSE(format, ... ) {if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) esp_log_write(ESP_LOG_VERBOSE, "BT_LOG", LOG_FORMAT(V, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__); } + #if (LOG_LOCAL_LEVEL >= 4) #define BLE_MESH_LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL + 1) #else diff --git a/components/bt/esp_ble_mesh/mesh_core/mesh_hci.c b/components/bt/esp_ble_mesh/mesh_core/mesh_hci.c deleted file mode 100644 index 72da73a389..0000000000 --- a/components/bt/esp_ble_mesh/mesh_core/mesh_hci.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017 Nordic Semiconductor ASA - * Copyright (c) 2015-2016 Intel Corporation - * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -#include "stack/bt_types.h" -#include "device/controller.h" - -#include "mesh_hci.h" - -struct bt_mesh_dev bt_mesh_dev; - -void bt_mesh_hci_init(void) -{ - const uint8_t *features = controller_get_interface()->get_features_ble()->as_array; - if (features != NULL) { - memcpy(bt_mesh_dev.features[0], features, 8); - memcpy(bt_mesh_dev.le.features, features, 8); - } - - /** - * Currently 20ms non-connectable adv interval is supported, and we need to add - * a flag to indicate this support. - */ -#ifdef CONFIG_BLE_MESH_HCI_5_0 - bt_mesh_dev.hci_version = BLE_MESH_HCI_VERSION_5_0; -#else - bt_mesh_dev.hci_version = controller_get_interface()->get_bt_version()->hci_version; -#endif - bt_mesh_dev.lmp_version = controller_get_interface()->get_bt_version()->lmp_version; - bt_mesh_dev.hci_revision = controller_get_interface()->get_bt_version()->hci_revision; - bt_mesh_dev.lmp_subversion = controller_get_interface()->get_bt_version()->lmp_subversion; - bt_mesh_dev.manufacturer = controller_get_interface()->get_bt_version()->manufacturer; - - const uint8_t *p = controller_get_interface()->get_ble_supported_states(); - uint64_t states_fh = 0, states_sh = 0; - STREAM_TO_UINT32(states_fh, p); - STREAM_TO_UINT32(states_sh, p); - bt_mesh_dev.le.states = (states_sh << 32) | states_fh; -} diff --git a/components/bt/esp_ble_mesh/mesh_core/mesh_kernel.c b/components/bt/esp_ble_mesh/mesh_core/mesh_kernel.c index c169aa387d..612d213d4d 100644 --- a/components/bt/esp_ble_mesh/mesh_core/mesh_kernel.c +++ b/components/bt/esp_ble_mesh/mesh_core/mesh_kernel.c @@ -14,8 +14,7 @@ #include "osi/alarm.h" #include "osi/hash_functions.h" -#include "common/bt_trace.h" -#include "common/bt_defs.h" +#include "bt_common.h" #include "esp_timer.h" diff --git a/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c b/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c new file mode 100644 index 0000000000..c4f1a1ff87 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c @@ -0,0 +1,1796 @@ +/* + * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2015-2016 Intel Corporation + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "sdkconfig.h" + +#include "btc/btc_task.h" +#include "osi/alarm.h" + +#include "mbedtls/aes.h" +#include "mbedtls/ecp.h" + +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "host/ble_att.h" +#include "host/ble_gatt.h" +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" + +#include "mesh_hci.h" +#include "mesh_aes_encrypt.h" +#include "mesh_bearer_adapt.h" +#include "mesh_trace.h" +#include "mesh_buf.h" +#include "mesh_atomic.h" + +#include "esp_ble_mesh_defs.h" + +#include "provisioner_prov.h" +#include "mesh_common.h" + +/** @def BT_UUID_MESH_PROV + * @brief Mesh Provisioning Service + */ +#define BT_UUID_MESH_PROV_VAL 0x1827 +/** @def BT_UUID_MESH_PROXY + * @brief Mesh Proxy Service + */ +#define BT_UUID_MESH_PROXY_VAL 0x1828 +/** @def BT_UUID_GATT_CCC + * @brief GATT Client Characteristic Configuration + */ +#define BT_UUID_GATT_CCC_VAL 0x2902 +/** @def BT_UUID_MESH_PROV_DATA_IN + * @brief Mesh Provisioning Data In + */ +#define BT_UUID_MESH_PROV_DATA_IN_VAL 0x2adb +/** @def BT_UUID_MESH_PROV_DATA_OUT + * @brief Mesh Provisioning Data Out + */ +#define BT_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc +/** @def BT_UUID_MESH_PROXY_DATA_IN + * @brief Mesh Proxy Data In + */ +#define BT_UUID_MESH_PROXY_DATA_IN_VAL 0x2add +/** @def BT_UUID_MESH_PROXY_DATA_OUT + * @brief Mesh Proxy Data Out + */ +#define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade + +#define BLE_MESH_GATT_GET_CONN_ID(conn_id) ((u16_t)(conn_id)) +#define BLE_MESH_GATT_CREATE_CONN_ID(conn_id) ((u16_t)(conn_id)) + +static uint16_t proxy_svc_start_handle, prov_svc_start_handle; +struct bt_mesh_dev bt_mesh_dev; + +/* P-256 Variables */ +static u8_t bt_mesh_public_key[64]; +static BT_OCTET32 bt_mesh_private_key = { + 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, + 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50, + 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, + 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd +}; + +/* Scan related functions */ +static bt_mesh_scan_cb_t *bt_mesh_scan_dev_found_cb; + +#if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE +/* the gatt database list to save the attribute table */ +static sys_slist_t bt_mesh_gatts_db; + +/* Static Variables */ +static struct bt_mesh_conn bt_mesh_gatts_conn[BLE_MESH_MAX_CONN]; +static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb; + +static BD_ADDR bt_mesh_gatts_addr; + +#endif /* defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE */ + +esp_err_t bt_mesh_host_init(void) +{ + int rc; + rc = btc_init(); + if (rc != 0) { + return ESP_FAIL; + } + + rc = osi_alarm_create_mux(); + if (rc != 0) { + return ESP_FAIL; + } + + osi_alarm_init(); + return ESP_OK; +} + +uint8_t ble_hs_hci_get_hci_version(void); + +void bt_mesh_hci_init(void) +{ + /** + * Currently 20ms non-connectable adv interval is supported, and we need to add + * a flag to indicate this support. + */ +#ifdef CONFIG_BLE_MESH_HCI_5_0 + bt_mesh_dev.hci_version = BLE_MESH_HCI_VERSION_5_0; +#else + bt_mesh_dev.hci_version = ble_hs_hci_get_hci_version(); +#endif + return; +} + +static struct ble_gap_disc_params scan_param; +#if defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER +static struct gattc_prov_info { + /* Service to be found depends on the type of adv pkt received */ + struct bt_mesh_conn conn; + BD_ADDR addr; + u8_t addr_type; + u16_t service_uuid; + u16_t mtu; + bool wr_desc_done; /* Indicate if write char descriptor event is received */ + u16_t start_handle; /* Service attribute start handle */ + u16_t end_handle; /* Service attribute end handle */ + u16_t data_in_handle; /* Data In Characteristic attribute handle */ + u16_t data_out_handle; /* Data Out Characteristic attribute handle */ + u16_t ccc_handle; /* Data Out Characteristic CCC attribute handle */ +} bt_mesh_gattc_info[BLE_MESH_MAX_CONN]; + +static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb; + +static int ble_on_subscribe(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + struct bt_mesh_conn *conn = NULL; + uint8_t value[2] = {0x01, 0x00}; + int i = (int)arg, j, len; + MODLOG_DFLT(INFO, "Subscribe complete; status=%d conn_handle=%d " + "attr_handle=%d\n", + error->status, conn_handle, attr->handle); + + for (j = i+1; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) { + if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].ccc_handle) { + break; + } + } + if (j == ARRAY_SIZE(bt_mesh_gattc_info)) { + + conn = &bt_mesh_gattc_info[i].conn; + + if (bt_mesh_gattc_info[i].ccc_handle != attr->handle) { + BT_WARN("%s, gattc ccc_handle is not matched", __func__); + bt_mesh_gattc_disconnect(conn); + return 0; + } + + if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) { + if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_write_descr != NULL) { + len = bt_mesh_gattc_conn_cb->prov_write_descr(&bt_mesh_gattc_info[i].conn, bt_mesh_gattc_info[i].addr); + if (len < 0) { + BT_ERR("%s, prov_write_descr failed", __func__); + bt_mesh_gattc_disconnect(conn); + return 0; + } + bt_mesh_gattc_info[i].wr_desc_done = true; + } + } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) { + if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_write_descr != NULL) { + len = bt_mesh_gattc_conn_cb->proxy_write_descr(&bt_mesh_gattc_info[i].conn); + if (len < 0) { + BT_ERR("%s, proxy_write_descr failed", __func__); + bt_mesh_gattc_disconnect(conn); + return 0; + } + } + } + + + return 0; + } + + ble_gattc_write_flat(conn_handle, bt_mesh_gattc_info[i].ccc_handle, value, sizeof(value), ble_on_subscribe, (void *)j); + return 0; +} + +static int dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg) +{ + int rc = 0, j, i = (int)arg; /* char index */ + uint8_t value[2] = {0x01, 0x00}; + + switch (error->status) { + case 0: + bt_mesh_gattc_info[i].ccc_handle = dsc->handle; + break; + + case BLE_HS_EDONE: + /* All descriptors in this characteristic discovered; start discovering + * descriptors in the next characteristic. + */ + for (j = i+1; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) { + if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].data_out_handle) { + break; + } + } + if (j == ARRAY_SIZE(bt_mesh_gattc_info)) { + /* Register Notification for Mesh Provisioning/Proxy Data Out Characteristic */ + for (j = 0; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) { + if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].ccc_handle) { + break; + } + } + if (j == ARRAY_SIZE(bt_mesh_gattc_info)) { + return 0; + } + ble_gattc_write_flat(conn_handle, bt_mesh_gattc_info[i].ccc_handle, value, sizeof(value), ble_on_subscribe, (void *)j); + } else { + ble_gattc_disc_all_dscs(conn_handle, bt_mesh_gattc_info[j].data_out_handle, 0xffff, dsc_disced, (void *)j); + } + rc = 0; + break; + + default: + /* Error; abort discovery. */ + rc = error->status; + break; + } + + return rc; +} + + +static int chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) +{ + int rc = 0, j; + uint16_t uuid16 = 0; + int i = (int)arg; /* service index */ + struct bt_mesh_conn *conn = &bt_mesh_gattc_info[i].conn; + const ble_uuid_any_t *uuid = &chr->uuid; + if (chr) { + uuid16 = (uint16_t) BLE_UUID16(uuid)->value; + } + switch (error->status) { + case 0: + /* Get Mesh Provisioning/Proxy Data In/Out Characteristic */ + if ((uuid16 == BLE_MESH_UUID_MESH_PROV_DATA_IN_VAL) || (uuid16 == BLE_MESH_UUID_MESH_PROXY_DATA_IN_VAL)) { + if (!(chr->properties & BLE_MESH_GATT_CHRC_WRITE_WITHOUT_RESP)) { + bt_mesh_gattc_disconnect(conn); + BT_ERR("Write without response is not set for Data In characteristic"); + return 0; + } + bt_mesh_gattc_info[i].data_in_handle = chr->val_handle; + } else if ((uuid16 == BLE_MESH_UUID_MESH_PROV_DATA_OUT_VAL) || (uuid16 == BLE_MESH_UUID_MESH_PROXY_DATA_OUT_VAL)) { + if (!(chr->properties & BLE_MESH_GATT_CHRC_NOTIFY)) { + bt_mesh_gattc_disconnect(conn); + BT_ERR("Notify is not set for Data Out characteristic"); + return 0; + } + bt_mesh_gattc_info[i].data_out_handle = chr->val_handle; + } + break; + case BLE_HS_EDONE: + /* All characteristics in this service discovered; start discovering + * characteristics in the next service. + */ + for (j = i+1; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) { + if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && (bt_mesh_gattc_info[j].start_handle > bt_mesh_gattc_info[j].end_handle)) { + break; + } + } + if (j == ARRAY_SIZE(bt_mesh_gattc_info)) { + for (j = 0; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) { + if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].data_out_handle) { + break; + } + } + ble_gattc_disc_all_dscs(conn_handle, bt_mesh_gattc_info[j].data_out_handle, 0xffff, dsc_disced, (void *)j); + } else { + ble_gattc_disc_all_chrs(conn_handle, bt_mesh_gattc_info[j].start_handle, bt_mesh_gattc_info[j].end_handle, + chr_disced, (void *)j); + } + break; + + default: + rc = error->status; + break; + } + + return rc; +} + + +static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_svc *service, void *arg) +{ + struct bt_mesh_conn *conn = NULL; + int rc = 0, i; + const ble_uuid_any_t *uuid; + uint8_t uuid_length; + switch (error->status) { + case 0: + if (!service) { + return 0; + } + uuid = &service->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + if (uuid_length != 2) { + return 0; + } + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (bt_mesh_gattc_info[i].service_uuid == (uint16_t)BLE_UUID16(uuid)->value) { + bt_mesh_gattc_info[i].start_handle = service->start_handle; + bt_mesh_gattc_info[i].end_handle = service->end_handle; + break; + } + } + + break; + case BLE_HS_EDONE: + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (bt_mesh_gattc_info[i].conn.handle == conn_handle) { + break; + } + } + + if (i == ARRAY_SIZE(bt_mesh_gattc_info)) { + BT_ERR("%s, Conn handle is not found", __func__); + return 0; + } + conn = &bt_mesh_gattc_info[i].conn; + if (bt_mesh_gattc_info[i].start_handle == 0x00 || + bt_mesh_gattc_info[i].end_handle == 0x00 || + (bt_mesh_gattc_info[i].start_handle > bt_mesh_gattc_info[i].end_handle)) { + bt_mesh_gattc_disconnect(conn); + return 0; + } + + /* Get the characteristic num within Mesh Provisioning/Proxy Service */ + ble_gattc_disc_all_chrs(conn_handle, bt_mesh_gattc_info[i].start_handle, bt_mesh_gattc_info[i].end_handle, + chr_disced, (void *)i); + break; + + default: + rc = error->status; + break; + } + + return rc; +} + + +#endif /* defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER */ + +static int disc_cb(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_disc_desc *desc; + +#if defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER + int rc, i; + uint8_t notif_data[100]; + uint16_t notif_len; + ssize_t len; + struct ble_gap_conn_desc conn_desc; + struct bt_mesh_conn *conn = NULL; +#endif + + switch (event->type) { + case BLE_GAP_EVENT_DISC: + desc = &event->disc; + + struct net_buf_simple *buf = bt_mesh_alloc_buf(desc->length_data); + if (!buf) { + BT_ERR("%s, Failed to allocate memory", __func__); + return 0; + } + net_buf_simple_add_mem(buf, desc->data, desc->length_data); + + if (bt_mesh_scan_dev_found_cb) { + bt_mesh_scan_dev_found_cb((bt_mesh_addr_t *)&desc->addr, desc->rssi, desc->event_type, buf); + } + osi_free(buf); + break; +#if defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER + case BLE_GAP_EVENT_CONNECT: + if (event->connect.status == 0) { + /* Connection successfully established. */ + MODLOG_DFLT(INFO, "Connection established "); + + rc = ble_gap_conn_find(event->connect.conn_handle, &conn_desc); + assert(rc == 0); + + if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->connected != NULL) { + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (!memcmp(bt_mesh_gattc_info[i].addr, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN)) { + bt_mesh_gattc_info[i].conn.handle = event->connect.conn_handle; + (bt_mesh_gattc_conn_cb->connected)(bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, i); + break; + } + } + } + } +#if BLE_MESH_DEV + if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) { + rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL); + if (rc != 0) { + BT_ERR("%s, Invalid status %d", __func__, rc); + break; + } + bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING); + } +#else + rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL); + if (rc != 0) { + BT_ERR("%s, Invalid status %d", __func__, rc); + break; + } +#endif /* BLE_MESH_DEV */ + break; + case BLE_GAP_EVENT_DISCONNECT: + if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->disconnected != NULL) { + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + memcpy(&conn_desc, &event->disconnect.conn, sizeof(conn_desc)); + if (!memcmp(bt_mesh_gattc_info[i].addr, conn_desc.peer_ota_addr.val, BLE_MESH_ADDR_LEN)) { + if (bt_mesh_gattc_info[i].conn.handle == event->disconnect.conn.conn_handle) { + (bt_mesh_gattc_conn_cb->disconnected)(&bt_mesh_gattc_info[i].conn, event->disconnect.reason); + if (!bt_mesh_gattc_info[i].wr_desc_done) { + /* Add this in case connection is established, connected event comes, but + * connection is terminated before server->filter_type is set to PROV. + */ + provisioner_clear_link_conn_info(bt_mesh_gattc_info[i].addr); + } + } else { + /* Add this in case connection is failed to be established, and here we + * need to clear some provision link info, like connecting flag, device + * uuid, address info, etc. + */ + provisioner_clear_link_conn_info(bt_mesh_gattc_info[i].addr); + } + /* Decrease prov pbg_count */ + provisioner_pbg_count_dec(); + /* Reset corresponding gattc info */ + memset(&bt_mesh_gattc_info[i], 0, sizeof(bt_mesh_gattc_info[i])); + bt_mesh_gattc_info[i].conn.handle = 0xFFFF; + bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT; + bt_mesh_gattc_info[i].wr_desc_done = false; + break; + } + } + } + break; + case BLE_GAP_EVENT_MTU: + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (bt_mesh_gattc_info[i].conn.handle == event->mtu.conn_handle) { + bt_mesh_gattc_info[i].mtu = event->mtu.value; + break; + } + } + /** Once mtu exchanged accomplished, start to find services, and here + * need a flag to indicate which service to find(Mesh Prov Service or + * Mesh Proxy Service) + */ + ble_uuid_any_t bt_uuid; + if (i != ARRAY_SIZE(bt_mesh_gattc_info)) { + //service_uuid.len = sizeof(bt_mesh_gattc_info[i].service_uuid); + if (sizeof(bt_mesh_gattc_info[i].service_uuid) == 0x02) { + bt_uuid.u16.u.type = BLE_UUID_TYPE_16; + bt_uuid.u16.value = bt_mesh_gattc_info[i].service_uuid; + + } else if (sizeof(bt_mesh_gattc_info[i].service_uuid) == 0x10) { + bt_uuid.u128.u.type = BLE_UUID_TYPE_128; + memcpy(bt_uuid.u128.value, &bt_mesh_gattc_info[i].service_uuid, 16); + } + /* Search Mesh Provisioning Service or Mesh Proxy Service */ + ble_gattc_disc_all_svcs(bt_mesh_gattc_info[i].conn.handle, svc_disced, NULL); + } + break; + case BLE_GAP_EVENT_NOTIFY_RX: + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (bt_mesh_gattc_info[i].conn.handle == event->notify_rx.conn_handle) { + break; + } + } + + if (i == ARRAY_SIZE(bt_mesh_gattc_info)) { + BT_ERR("%s, Conn handle is not found", __func__); + return 0; + } + + conn = &bt_mesh_gattc_info[i].conn; + ble_gap_conn_find(event->notify_rx.conn_handle, &conn_desc); + + if (bt_mesh_gattc_info[i].data_out_handle != event->notify_rx.attr_handle) { + /* Data isn't populated yet */ + return 0; + } + + if (memcmp(bt_mesh_gattc_info[i].addr, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN) || + (bt_mesh_gattc_info[i].data_out_handle != event->notify_rx.attr_handle) || + (event->notify_rx.indication != 0)) { + BT_ERR("%s, Notification error", __func__); + bt_mesh_gattc_disconnect(conn); + return 0; + } + + notif_len = OS_MBUF_PKTLEN(event->notify_rx.om); + rc = os_mbuf_copydata(event->notify_rx.om, 0, notif_len, notif_data); + + if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) { + if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_notify != NULL) { + len = bt_mesh_gattc_conn_cb->prov_notify(&bt_mesh_gattc_info[i].conn, + notif_data, notif_len); + if (len < 0) { + BT_ERR("%s, prov_notify failed", __func__); + bt_mesh_gattc_disconnect(conn); + return 0; + } + } + } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) { + if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL) { + len = bt_mesh_gattc_conn_cb->proxy_notify(&bt_mesh_gattc_info[i].conn, + notif_data, notif_len); + if (len < 0) { + BT_ERR("%s, proxy_notify failed", __func__); + bt_mesh_gattc_disconnect(conn); + return 0; + } + } + } + break; +#endif + default: + break; + } + + return 0; +} + +static int start_le_scan(u8_t scan_type, u16_t interval, u16_t window, u8_t filter_dup) +{ + + scan_param.filter_duplicates = filter_dup; + scan_param.itvl = interval; + scan_param.window = window; + + if (scan_type == BLE_MESH_SCAN_PASSIVE) { + scan_param.passive = 1; + } else { + scan_param.passive = 0; + } + ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL); + +#if BLE_MESH_DEV + if (scan_type == BLE_MESH_SCAN_ACTIVE) { + bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ACTIVE_SCAN); + } else { + bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ACTIVE_SCAN); + } +#endif + + return 0; +} + +static int set_ad(const struct bt_mesh_adv_data *ad, size_t ad_len, u8_t *buf, u8_t *buf_len) +{ + int i; + + for (i = 0; i < ad_len; i++) { + buf[(*buf_len)++] = ad[i].data_len + 1; + buf[(*buf_len)++] = ad[i].type; + + memcpy(&buf[*buf_len], ad[i].data, + ad[i].data_len); + *buf_len += ad[i].data_len; + } + + return 0; +} + +#if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE +static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(u16_t handle); + +static int gap_event_cb(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + MODLOG_DFLT(INFO, "connection %s; status=%d ", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + if (event->connect.status == 0) { + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + } + MODLOG_DFLT(INFO, "\n"); +#if BLE_MESH_DEV + /* When connection is created, advertising will be stopped automatically. */ + bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING); +#endif + if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->connected != NULL) { + u8_t index = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle); + if (index < BLE_MESH_MAX_CONN) { + bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle); + (bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0); + } + memcpy(bt_mesh_gatts_addr, desc.peer_id_addr.val, BLE_MESH_ADDR_LEN); + /* This is for EspBleMesh Android app. When it tries to connect with the + * device at the first time and it fails due to some reason. And after + * the second connection, the device needs to send GATT service change + * indication to the phone manually to notify it dicovering service again. + */ + ble_svc_gatt_changed(prov_svc_start_handle, 0xffff); + + } + + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason); + MODLOG_DFLT(INFO, "\n"); +#if BLE_MESH_DEV + bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING); +#endif + if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->disconnected != NULL) { + u8_t index = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle); + if (index < BLE_MESH_MAX_CONN) { + bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle); + (bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason); + } + memset(bt_mesh_gatts_addr, 0x0, BLE_MESH_ADDR_LEN); + } + + return 0; + + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + MODLOG_DFLT(INFO, "connection updated; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + MODLOG_DFLT(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_ADV_COMPLETE: + MODLOG_DFLT(INFO, "advertise complete; reason=%d", + event->adv_complete.reason); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + MODLOG_DFLT(INFO, "encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + MODLOG_DFLT(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_SUBSCRIBE: + MODLOG_DFLT(INFO, "subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d\n", + event->subscribe.conn_handle, + event->subscribe.attr_handle, + event->subscribe.reason, + event->subscribe.prev_notify, + event->subscribe.cur_notify, + event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(event->subscribe.attr_handle + 1); + u8_t index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle); + u16_t len = 0; + uint16_t ccc_val = 0; + + if (event->subscribe.prev_notify != event->subscribe.cur_notify) { + ccc_val = event->subscribe.cur_notify; + } else if (event->subscribe.prev_indicate != event->subscribe.cur_indicate) { + if (event->subscribe.cur_indicate) { + ccc_val = 2; + } else { + ccc_val = 0; + } + } + + if (attr != NULL && attr->write != NULL) { + if ((len = attr->write(&bt_mesh_gatts_conn[index], attr, + &ccc_val, + sizeof(ccc_val), + 0 /* offset */, 0)) > 0) { + } + } + + return 0; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + + case BLE_GAP_EVENT_REPEAT_PAIRING: + /* We already have a bond with the peer, but it is attempting to + * establish a new secure link. This app sacrifices security for + * convenience: just throw away the old bond and accept the new link. + */ + + /* Delete the old bond. */ + rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); + assert(rc == 0); + ble_store_util_delete_peer(&desc.peer_id_addr); + + /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should + * continue with the pairing operation. + */ + return BLE_GAP_REPEAT_PAIRING_RETRY; + + case BLE_GAP_EVENT_PASSKEY_ACTION: + MODLOG_DFLT(INFO, "PASSKEY_ACTION_EVENT started \n"); + return 0; + } + + return 0; +} +#else + +static int gap_event_cb(struct ble_gap_event *event, void *arg) +{ + return 0; +} +#endif + +/* APIs functions */ +int bt_le_adv_start(const struct bt_mesh_adv_param *param, + const struct bt_mesh_adv_data *ad, size_t ad_len, + const struct bt_mesh_adv_data *sd, size_t sd_len) +{ +#if BLE_MESH_DEV + if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) { + return -EALREADY; + } +#endif + uint8_t buf[BLE_HS_ADV_MAX_SZ]; + uint8_t buf_len = 0; + int err; + struct ble_gap_adv_params adv_params; + + err = set_ad(ad, ad_len, buf, &buf_len); + if (err) { + BT_ERR("set_ad failed: err %d", err); + return err; + } + + err = ble_gap_adv_set_data(buf, buf_len); + if (err != 0) { + BT_ERR("Advertising set failed: err %d", err); + return err; + } + + if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) { + buf_len = 0; + + err = set_ad(sd, sd_len, buf, &buf_len); + if (err) { + BT_ERR("set_ad failed: err %d", err); + return err; + } + + err = ble_gap_adv_rsp_set_data(buf, buf_len); + if (err != 0) { + BT_ERR("Scan rsp failed: err %d", err); + return err; + } + } + + memset(&adv_params, 0, sizeof adv_params); + adv_params.itvl_min = param->interval_min; + adv_params.itvl_max = param->interval_max; + + if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) { + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + } else if (sd != NULL) { + adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + } else { + adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; + adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; + adv_params.itvl_min = 160; + adv_params.itvl_max = 160; + } + + err = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, + gap_event_cb, NULL); + if (err) { + BT_ERR("Advertising start failed: err %d", err); + return err; + } + +#if BLE_MESH_DEV + bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING); + + if (!(param->options & BLE_MESH_ADV_OPT_ONE_TIME)) { + bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING); + } +#endif + + return 0; +} + +int bt_le_adv_stop(void) +{ +#if BLE_MESH_DEV + bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING); + if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) { + return 0; + } +#endif + ble_gap_adv_stop(); + +#if BLE_MESH_DEV + bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING); +#endif + + return 0; +} + +int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb) +{ + int err; + +#if BLE_MESH_DEV + if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) { + return -EALREADY; + } +#endif + +#if BLE_MESH_DEV + if (param->filter_dup) { + bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCAN_FILTER_DUP); + } else { + bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCAN_FILTER_DUP); + } +#endif + + err = start_le_scan(param->type, param->interval, param->window, param->filter_dup); + if (err) { + return err; + } + +#if BLE_MESH_DEV + bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING); +#endif + + bt_mesh_scan_dev_found_cb = cb; + return err; +} + +int bt_le_scan_stop(void) +{ +#if BLE_MESH_DEV + if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) { + bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING); + ble_gap_disc_cancel(); + } +#else + ble_gap_disc_cancel(); +#endif + + bt_mesh_scan_dev_found_cb = NULL; + return 0; +} +#if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE + +void bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb *cb) +{ + bt_mesh_gatts_conn_cb = cb; +} + +static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(u16_t handle) +{ + struct bt_mesh_gatt_service *svc = NULL; + struct bt_mesh_gatt_attr *attr = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER(&bt_mesh_gatts_db, svc, node) { + int i; + + for (i = 0; i < svc->attr_count; i++) { + attr = &svc->attrs[i]; + /* Check the attrs handle is equal to the handle or not */ + if (attr->handle == handle) { + return attr; + } + } + } + + return NULL; +} + +static void bt_mesh_gatts_foreach_attr(u16_t start_handle, u16_t end_handle, + bt_mesh_gatt_attr_func_t func, void *user_data) +{ + struct bt_mesh_gatt_service *svc = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER(&bt_mesh_gatts_db, svc, node) { + int i; + + for (i = 0; i < svc->attr_count; i++) { + struct bt_mesh_gatt_attr *attr = &svc->attrs[i]; + + /* Check if attribute handle is within range */ + if (attr->handle < start_handle || + attr->handle > end_handle) { + continue; + } + + if (func(attr, user_data) == BLE_MESH_GATT_ITER_STOP) { + return; + } + } + } +} + +static u8_t find_next(const struct bt_mesh_gatt_attr *attr, void *user_data) +{ + struct bt_mesh_gatt_attr **next = user_data; + + *next = (struct bt_mesh_gatt_attr *)attr; + + return BLE_MESH_GATT_ITER_STOP; +} + +static struct bt_mesh_gatt_attr *bt_mesh_gatts_attr_next(const struct bt_mesh_gatt_attr *attr) +{ + struct bt_mesh_gatt_attr *next = NULL; + + bt_mesh_gatts_foreach_attr(attr->handle + 1, attr->handle + 1, find_next, &next); + + return next; +} + +ssize_t bt_mesh_gatts_attr_read(struct bt_mesh_conn *conn, const struct bt_mesh_gatt_attr *attr, + void *buf, u16_t buf_len, u16_t offset, + const void *value, u16_t value_len) +{ + u16_t len; + + if (offset > value_len) { + return BLE_MESH_GATT_ERR(BLE_MESH_ATT_ERR_INVALID_OFFSET); + } + + len = MIN(buf_len, value_len - offset); + + BT_DBG("handle 0x%04x offset %u length %u", attr->handle, offset, len); + + memcpy(buf, value + offset, len); + + return len; +} + +struct gatts_incl { + u16_t start_handle; + u16_t end_handle; + u16_t uuid16; +} __packed; + +ssize_t bt_mesh_gatts_attr_read_included(struct bt_mesh_conn *conn, + const struct bt_mesh_gatt_attr *attr, + void *buf, u16_t len, u16_t offset) +{ + struct bt_mesh_gatt_attr *incl = attr->user_data; + struct bt_mesh_uuid *uuid = incl->user_data; + struct gatts_incl pdu = {0}; + u8_t value_len; + + /* First attr points to the start handle */ + pdu.start_handle = sys_cpu_to_le16(incl->handle); + value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle); + + /* + * Core 4.2, Vol 3, Part G, 3.2, + * The Service UUID shall only be present when the UUID is a 16-bit Bluetooth UUID. + */ + if (uuid->type == BLE_MESH_UUID_TYPE_16) { + pdu.uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(uuid)->val); + value_len += sizeof(pdu.uuid16); + } + + return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &pdu, value_len); +} + +ssize_t bt_mesh_gatts_attr_read_service(struct bt_mesh_conn *conn, + const struct bt_mesh_gatt_attr *attr, + void *buf, u16_t len, u16_t offset) +{ + struct bt_mesh_uuid *uuid = attr->user_data; + + if (uuid->type == BLE_MESH_UUID_TYPE_16) { + u16_t uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(uuid)->val); + + return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &uuid16, 2); + } + + return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, + BLE_MESH_UUID_128(uuid)->val, 16); +} + +struct gatts_chrc { + u8_t properties; + u16_t value_handle; + union { + u16_t uuid16; + u8_t uuid[16]; + }; +} __packed; + +ssize_t bt_mesh_gatts_attr_read_chrc(struct bt_mesh_conn *conn, + const struct bt_mesh_gatt_attr *attr, void *buf, + u16_t len, u16_t offset) +{ + struct bt_mesh_gatt_char *chrc = attr->user_data; + const struct bt_mesh_gatt_attr *next = NULL; + struct gatts_chrc pdu = {0}; + u8_t value_len; + + pdu.properties = chrc->properties; + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 534: + * 3.3.2 Characteristic Value Declaration + * The Characteristic Value declaration contains the value of the + * characteristic. It is the first Attribute after the characteristic + * declaration. All characteristic definitions shall have a + * Characteristic Value declaration. + */ + next = bt_mesh_gatts_attr_next(attr); + if (!next) { + BT_WARN("%s, No value for characteristic at 0x%04x", __func__, attr->handle); + pdu.value_handle = 0x0000; + } else { + pdu.value_handle = sys_cpu_to_le16(next->handle); + } + value_len = sizeof(pdu.properties) + sizeof(pdu.value_handle); + + if (chrc->uuid->type == BLE_MESH_UUID_TYPE_16) { + pdu.uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(chrc->uuid)->val); + value_len += 2; + } else { + memcpy(pdu.uuid, BLE_MESH_UUID_128(chrc->uuid)->val, 16); + value_len += 16; + } + + return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &pdu, value_len); +} + +static int gatts_register(struct bt_mesh_gatt_service *svc) +{ + struct bt_mesh_gatt_service *last; + u16_t handle; + + if (sys_slist_is_empty(&bt_mesh_gatts_db)) { + handle = 0; + goto populate; + } + + last = SYS_SLIST_PEEK_TAIL_CONTAINER(&bt_mesh_gatts_db, last, node); + handle = last->attrs[last->attr_count - 1].handle; + BT_DBG("%s, handle = %d", __func__, handle); + +populate: + sys_slist_append(&bt_mesh_gatts_db, &svc->node); + return 0; +} + +int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) +{ + uint16_t offset = 0; + int i; + if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) { + offset = proxy_svc_start_handle; + } else if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROV_VAL) { + offset = prov_svc_start_handle; + } + + for (i = 0; i < svc->attr_count; i++) { + svc->attrs[i].handle = offset + i; + } + gatts_register(svc); + return 0; +} + +int bt_mesh_gatts_disconnect(struct bt_mesh_conn *conn, u8_t reason) +{ + u16_t conn_id = BLE_MESH_GATT_CREATE_CONN_ID(conn->handle); + ble_gap_terminate(conn_id, reason); + return 0; +} + +int bt_mesh_gatts_service_unregister(struct bt_mesh_gatt_service *svc) +{ + assert(svc != NULL); + BT_ERR("%s, Unsupported for NimBLE host", __func__); + return 0; +} + +int bt_mesh_gatts_notify(struct bt_mesh_conn *conn, const struct bt_mesh_gatt_attr *attr, + const void *data, u16_t len) +{ + struct os_mbuf *om; + u16_t conn_id = BLE_MESH_GATT_CREATE_CONN_ID(conn->handle); + + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + ble_gattc_notify_custom(conn_id, attr->handle, om); + + return 0; +} + +u16_t bt_mesh_gatt_get_mtu(struct bt_mesh_conn *conn) +{ + return ble_att_preferred_mtu(); +} + +/* APIs added by Espressif */ +int bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service *svc) +{ + int rc; + uint16_t handle; + if (!svc) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + const ble_uuid_t *uuid; + if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) { + uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL); + } else { + uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL); + } + + rc = ble_gatts_find_svc(uuid, &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 0); + + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(handle, 0xffff); + + return 0; +} + +int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc) +{ + int rc; + uint16_t handle; + const ble_uuid_t *uuid; + if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) { + uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL); + } else { + uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL); + } + + rc = ble_gatts_find_svc(uuid, &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 1); + + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(handle, 0xffff); + + return 0; +} +#endif /* defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE */ + +#if defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER +void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb) +{ + bt_mesh_gattc_conn_cb = cb; +} + +u16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (conn == &bt_mesh_gattc_info[i].conn) { + break; + } + } + + if (i == ARRAY_SIZE(bt_mesh_gattc_info)) { + return 0; + } + + return bt_mesh_gattc_info[i].service_uuid; +} + +/** For provisioner acting as a GATT client, it may follow the procedures + * listed below. + * 1. Create connection with the unprovisioned device + * 2. Exchange MTU size + * 3. Find Mesh Prov Service in the device's service database + * 4. Find Mesh Prov Data In/Out characteristic within the service + * 5. Get CCC of Mesh Prov Data Out Characteristic + * 6. Set the Notification bit of CCC + */ + +int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, u16_t service_uuid) +{ + u8_t zero[6] = {0}; + int i, rc; + + if (!addr || !memcmp(addr->val, zero, BLE_MESH_ADDR_LEN) || + (addr->type > BLE_ADDR_RANDOM)) { + BT_ERR("%s, Invalid remote address", __func__); + return -EINVAL; + } + + if (service_uuid != BLE_MESH_UUID_MESH_PROV_VAL && + service_uuid != BLE_MESH_UUID_MESH_PROXY_VAL) { + BT_ERR("%s, Invalid service uuid 0x%04x", __func__, service_uuid); + return -EINVAL; + } + + /* Check if already creating connection with the device */ + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (!memcmp(bt_mesh_gattc_info[i].addr, addr->val, BLE_MESH_ADDR_LEN)) { + BT_WARN("%s, Already create connection with %s", + __func__, bt_hex(addr->val, BLE_MESH_ADDR_LEN)); + return -EALREADY; + } + } + + /* Find empty element in queue to store device info */ + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if ((bt_mesh_gattc_info[i].conn.handle == 0xFFFF) && + (bt_mesh_gattc_info[i].service_uuid == 0x0000)) { + memcpy(bt_mesh_gattc_info[i].addr, addr->val, BLE_MESH_ADDR_LEN); + bt_mesh_gattc_info[i].addr_type = addr->type; + /* Service to be found after exhanging mtu size */ + bt_mesh_gattc_info[i].service_uuid = service_uuid; + break; + } + } + + if (i == ARRAY_SIZE(bt_mesh_gattc_info)) { + BT_WARN("%s, gattc info is full", __func__); + return -ENOMEM; + } + +#if BLE_MESH_DEV + if (bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) { + rc = ble_gap_disc_cancel(); + if (rc != 0) { + return -1; + } + } +#else + rc = ble_gap_disc_cancel(); + if (rc != 0) { + return -1; + } +#endif /* BLE_MESH_DEV */ + + BT_DBG("%s, create conn with %s", __func__, bt_hex(addr->val, BLE_MESH_ADDR_LEN)); + + /* Min_interval: 250ms + * Max_interval: 250ms + * Slave_latency: 0x0 + * Supervision_timeout: 32 sec + */ + struct ble_gap_conn_params conn_params = {0}; + conn_params.itvl_min = 0xC8; /* (250 * 1000) / 1250 = 200 = 0xC8 */ + conn_params.itvl_max = 0xC8; /* (250 * 1000) / 1250 = 200 = 0xC8 */ + conn_params.latency = 0; + conn_params.supervision_timeout = 0xC80; + conn_params.scan_itvl = 0x0020; //0x0010 + conn_params.scan_window = 0x0020; //0x0010 + conn_params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; + conn_params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; + + + ble_addr_t peer_addr; + memcpy(peer_addr.val, addr->val, 6); + peer_addr.type = addr->type; + + rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER, &conn_params, + disc_cb, NULL); + /* Increment pbg_count */ + provisioner_pbg_count_inc(); + + return 0; +} + +static int mtu_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t mtu, void *arg) +{ + int i; + if (error->status == 0) { + + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (bt_mesh_gattc_info[i].conn.handle == conn_handle) { + bt_mesh_gattc_info[i].mtu = mtu; + break; + } + } + } + return 0; +} + + + +void bt_mesh_gattc_exchange_mtu(u8_t index) +{ + /** Set local MTU and exchange with GATT server. + * ATT_MTU >= 69 for Mesh GATT Prov Service + * ATT_NTU >= 33 for Mesh GATT Proxy Service + */ + + ble_gattc_exchange_mtu(bt_mesh_gattc_info[index].conn.handle, mtu_cb, NULL); +} + +u16_t bt_mesh_gattc_get_mtu_info(struct bt_mesh_conn *conn) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (conn == &bt_mesh_gattc_info[i].conn) { + return bt_mesh_gattc_info[i].mtu; + } + } + + return 0; +} + +int bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn *conn, const struct bt_mesh_gatt_attr *attr, + const void *data, u16_t len) +{ + u16_t conn_id; + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (conn == &bt_mesh_gattc_info[i].conn) { + break; + } + } + + if (i == ARRAY_SIZE(bt_mesh_gattc_info)) { + BT_ERR("%s, Conn is not found", __func__); + /** Here we return 0 for prov_send() return value check in provisioner.c + */ + return 0; + } + + conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_info[i].conn.handle); + + struct os_mbuf *om; + int rc; + + om = ble_hs_mbuf_from_flat(data, len); + if (om == NULL) { + return -1; + } + + rc = ble_gattc_write_no_rsp(conn_id, bt_mesh_gattc_info[i].data_in_handle, om); + if (rc != 0) { + return -1; + } + + return 0; +} + +void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn) +{ + /** Disconnect + * Clear proper proxy server information + * Clear proper prov_link information + * Clear proper bt_mesh_gattc_info information + * Here in adapter, we just clear proper bt_mesh_gattc_info, and + * when proxy_disconnected callback comes, the proxy server + * information and prov_link information should be cleared. + */ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + if (conn == &bt_mesh_gattc_info[i].conn) { + break; + } + } + + if (i == ARRAY_SIZE(bt_mesh_gattc_info)) { + BT_ERR("%s, Conn is not found", __func__); + return; + } + ble_gap_terminate(bt_mesh_gattc_info[i].conn.handle, BLE_ERR_REM_USER_CONN_TERM); +} + +/** Mesh Provisioning Service: 0x1827 + * Mesh Provisioning Data In: 0x2ADB + * Mesh Provisioning Data Out: 0x2ADC + * Mesh Proxy Service: 0x1828 + * Mesh Proxy Data In: 0x2ADD + * Mesh PROXY Data Out: 0x2ADE + */ +#endif /* defined(CONFIG_BLE_MESH_PROVISIONER) && CONFIG_BLE_MESH_PROVISIONER */ + +struct bt_mesh_conn *bt_mesh_conn_ref(struct bt_mesh_conn *conn) +{ + bt_mesh_atomic_inc(&conn->ref); + + BT_DBG("handle %u ref %u", conn->handle, bt_mesh_atomic_get(&conn->ref)); + + return conn; +} + +void bt_mesh_conn_unref(struct bt_mesh_conn *conn) +{ + bt_mesh_atomic_dec(&conn->ref); + + BT_DBG("handle %u ref %u", conn->handle, bt_mesh_atomic_get(&conn->ref)); +} + +#if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE +static int proxy_char_access_cb(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR || ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) { + struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(attr_handle); + u8_t index = BLE_MESH_GATT_GET_CONN_ID(conn_handle); + u16_t len = 0; + + BT_DBG("%s, write: handle = %d, len = %d, data = %s", __func__, attr_handle, + ctxt->om->om_len, + bt_hex(ctxt->om->om_data, ctxt->om->om_len)); + + if (attr != NULL && attr->write != NULL) { + if ((len = attr->write(&bt_mesh_gatts_conn[index], attr, + ctxt->om->om_data, + ctxt->om->om_len, + 0 /* offset */, 0)) > 0) { + } + } + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR || ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { + BT_ERR("%s, Unhandled read request for chr and dsc: opcode - %d", __func__, ctxt->op); + } + return 0; +} + +static int dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + /* + * We should never never enter this callback - it's attached to notify-only + * characteristic which are notified directly from mbuf. And we can't pass + * NULL as access_cb because gatts will assert on init... + */ + assert(0); + return 0; +} + +static const struct ble_gatt_svc_def svc_defs [] = { +#ifdef CONFIG_BLE_MESH_GATT_PROXY + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + .includes = NULL, + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), + .access_cb = proxy_char_access_cb, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, +#endif +#ifdef CONFIG_BLE_MESH_PB_GATT + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + .includes = NULL, + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + .access_cb = proxy_char_access_cb, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, +#endif + { + 0, /* No more services. */ + }, +}; +#endif + +void gatt_register_cb(struct ble_gatt_register_ctxt *ctxt, + void * arg ) +{ + if (ctxt->op == BLE_GATT_REGISTER_OP_SVC) { + if (ble_uuid_cmp(ctxt->svc.svc_def->uuid, BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL)) == 0) { + proxy_svc_start_handle = ctxt->svc.handle; + } else if (ble_uuid_cmp(ctxt->svc.svc_def->uuid, BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL)) == 0) { + prov_svc_start_handle = ctxt->svc.handle; + } + } +} + +void bt_mesh_gatt_init(void) +{ + ble_att_set_preferred_mtu(BLE_ATT_MTU_DFLT); + + ble_hs_cfg.gatts_register_cb = gatt_register_cb; + +#if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE + int rc; + ble_svc_gap_init(); + ble_svc_gatt_init(); + + rc = ble_gatts_count_cfg(svc_defs); + assert(rc == 0); + + rc = ble_gatts_add_svcs(svc_defs); + assert(rc == 0); + + ble_gatts_start(); + + ble_gatts_svc_set_visibility(prov_svc_start_handle, 1); + ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0); +#endif + +#if CONFIG_BLE_MESH_PROVISIONER + for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) { + bt_mesh_gattc_info[i].conn.handle = 0xFFFF; + bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT; + bt_mesh_gattc_info[i].wr_desc_done = false; + } +#endif +} + +void ble_sm_alg_ecc_init(void); + +void bt_mesh_adapt_init(void) +{ + BT_DBG("%s", __func__); + /* initialization of P-256 parameters */ + ble_sm_alg_ecc_init(); +} + +int bt_mesh_rand(void *buf, size_t len) +{ + int i; + + if (buf == NULL || len == 0) { + BT_ERR("%s, Invalid parameter", __func__); + return -EAGAIN; + } + + for (i = 0; i < (int)(len / sizeof(u32_t)); i++) { + u32_t rand = esp_random(); + memcpy(buf + i * sizeof(u32_t), &rand, sizeof(u32_t)); + } + + BT_DBG("%s, rand: %s", __func__, bt_hex(buf, len)); + return 0; +} + +void bt_mesh_set_private_key(const u8_t pri_key[32]) +{ + memcpy(bt_mesh_private_key, pri_key, 32); +} + +int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); + +const u8_t *bt_mesh_pub_key_get(void) +{ + uint8_t pri_key[32] = {0}; + +#if 1 + if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_HAS_PUB_KEY)) { + return bt_mesh_public_key; + } +#else + /* BLE Mesh BQB test case MESH/NODE/PROV/UPD/BV-12-C requires + * different public key for each provisioning procedure. + * Note: if enabled, when Provisioner provision multiple devices + * at the same time, this may cause invalid confirmation value. + */ + if (bt_mesh_rand(bt_mesh_private_key, 32)) { + BT_ERR("%s, Unable to generate bt_mesh_private_key", __func__); + return NULL; + } +#endif + + int rc = ble_sm_alg_gen_key_pair(bt_mesh_public_key, pri_key); + if (rc != 0) { + BT_ERR("%s, Failed to generate the key pair", __func__); + return NULL; + } + memcpy(bt_mesh_private_key, pri_key, 32); + + bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_HAS_PUB_KEY); + BT_DBG("gen the bt_mesh_public_key:%s", bt_hex(bt_mesh_public_key, sizeof(bt_mesh_public_key))); + + return bt_mesh_public_key; +} + +bool bt_mesh_check_public_key(const u8_t key[64]) +{ + struct mbedtls_ecp_point pt = {0}; + mbedtls_ecp_group grp = {0}; + bool rc = false; + + uint8_t pub[65] = {0}; + /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */ + pub[0] = 0x04; + memcpy(&pub[1], key, 64); + + /* Initialize the required structures here */ + mbedtls_ecp_point_init(&pt); + mbedtls_ecp_group_init(&grp); + + /* Below 3 steps are to validate public key on curve secp256r1 */ + if (mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1) != 0) { + goto exit; + } + + if (mbedtls_ecp_point_read_binary(&grp, &pt, pub, 65) != 0) { + goto exit; + } + + if (mbedtls_ecp_check_pubkey(&grp, &pt) != 0) { + goto exit; + } + + rc = true; + +exit: + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + return rc; + +} + +int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y, + uint8_t *our_priv_key, uint8_t *out_dhkey); + +int bt_mesh_dh_key_gen(const u8_t remote_pk[64], bt_mesh_dh_key_cb_t cb, const u8_t idx) +{ + uint8_t dhkey[32]; + + BT_DBG("private key = %s", bt_hex(bt_mesh_private_key, BT_OCTET32_LEN)); + + ble_sm_alg_gen_dhkey((uint8_t *)&remote_pk[0], (uint8_t *)&remote_pk[32], bt_mesh_private_key, dhkey); + + if (cb != NULL) { + cb((const u8_t *)dhkey, idx); + } + return 0; +} + +#if CONFIG_MBEDTLS_HARDWARE_AES +static void ecb_encrypt(u8_t const *const key_le, u8_t const *const clear_text_le, + u8_t *const cipher_text_le, u8_t *const cipher_text_be) +{ + struct bt_mesh_ecb_param ecb; + mbedtls_aes_context aes_ctx = {0}; + + aes_ctx.key_bytes = 16; + mem_rcopy(&aes_ctx.key[0], key_le, 16); + mem_rcopy(&ecb.clear_text[0], clear_text_le, sizeof(ecb.clear_text)); + mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, &ecb.clear_text[0], &ecb.cipher_text[0]); + + if (cipher_text_le) { + mem_rcopy(cipher_text_le, &ecb.cipher_text[0], + sizeof(ecb.cipher_text)); + } + + if (cipher_text_be) { + memcpy(cipher_text_be, &ecb.cipher_text[0], + sizeof(ecb.cipher_text)); + } +} + +static void ecb_encrypt_be(u8_t const *const key_be, u8_t const *const clear_text_be, + u8_t *const cipher_text_be) +{ + struct bt_mesh_ecb_param ecb; + mbedtls_aes_context aes_ctx = {0}; + + aes_ctx.key_bytes = 16; + memcpy(&aes_ctx.key[0], key_be, 16); + memcpy(&ecb.clear_text[0], clear_text_be, sizeof(ecb.clear_text)); + mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, &ecb.clear_text[0], &ecb.cipher_text[0]); + + memcpy(cipher_text_be, &ecb.cipher_text[0], sizeof(ecb.cipher_text)); +} +#endif /* CONFIG_MBEDTLS_HARDWARE_AES */ + +int bt_mesh_encrypt_le(const u8_t key[16], const u8_t plaintext[16], + u8_t enc_data[16]) +{ +#if CONFIG_MBEDTLS_HARDWARE_AES + BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); + + ecb_encrypt(key, plaintext, enc_data, NULL); + + BT_DBG("enc_data %s", bt_hex(enc_data, 16)); + return 0; +#else /* CONFIG_MBEDTLS_HARDWARE_AES */ + struct tc_aes_key_sched_struct s; + u8_t tmp[16]; + + BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); + + sys_memcpy_swap(tmp, key, 16); + + if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) { + return -EINVAL; + } + + sys_memcpy_swap(tmp, plaintext, 16); + + if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) { + return -EINVAL; + } + + sys_mem_swap(enc_data, 16); + + BT_DBG("enc_data %s", bt_hex(enc_data, 16)); + + return 0; +#endif /* CONFIG_MBEDTLS_HARDWARE_AES */ +} + +int bt_mesh_encrypt_be(const u8_t key[16], const u8_t plaintext[16], + u8_t enc_data[16]) +{ +#if CONFIG_MBEDTLS_HARDWARE_AES + BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); + + ecb_encrypt_be(key, plaintext, enc_data); + + BT_DBG("enc_data %s", bt_hex(enc_data, 16)); + + return 0; +#else /* CONFIG_MBEDTLS_HARDWARE_AES */ + struct tc_aes_key_sched_struct s; + + BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); + + if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) { + return -EINVAL; + } + + if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) { + return -EINVAL; + } + + BT_DBG("enc_data %s", bt_hex(enc_data, 16)); + + return 0; +#endif /* CONFIG_MBEDTLS_HARDWARE_AES */ +} + +#if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) +int bt_mesh_update_exceptional_list(u8_t sub_code, u8_t type, void *info) +{ + BT_ERR("%s, Unsupported for NimBLE host", __func__); + return 0; +} +#endif diff --git a/components/bt/host/bluedroid/api/esp_gap_bt_api.c b/components/bt/host/bluedroid/api/esp_gap_bt_api.c index f096b0fd01..567e38d0ce 100644 --- a/components/bt/host/bluedroid/api/esp_gap_bt_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_bt_api.c @@ -17,6 +17,7 @@ #include "esp_bt_main.h" #include "esp_gap_bt_api.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" diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 5dce952722..ddc21f3556 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -53,6 +53,7 @@ config BT_NIMBLE_PINNED_TO_CORE config BT_NIMBLE_TASK_STACK_SIZE int "NimBLE Host task stack size" depends on BT_NIMBLE_ENABLED + default 5120 if BLE_MESH default 4096 help This configures stack size of NimBLE host task diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/CMakeLists.txt index 1eb2d87ed2..dc91641afd 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/CMakeLists.txt @@ -1,4 +1,5 @@ set(COMPONENT_SRCS "ble_mesh_demo_main.c" + "ble_mesh_demo_init.c" "board.c") set(COMPONENT_ADD_INCLUDEDIRS ".") diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.c new file mode 100644 index 0000000000..ea6aa7f0c5 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.c @@ -0,0 +1,143 @@ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +/* BLE */ +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#endif + +#include "esp_ble_mesh_defs.h" +#include "ble_mesh_demo_init.h" +#include "esp_ble_mesh_common_api.h" + +#ifdef CONFIG_BT_BLUEDROID_ENABLED + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN); +} + +esp_err_t bluetooth_init(void) +{ + esp_err_t ret; + + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "%s initialize controller failed", __func__); + return ret; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "%s enable controller failed", __func__); + return ret; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(TAG, "%s init bluetooth failed", __func__); + return ret; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); + return ret; + } + + return ret; +} + +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +static SemaphoreHandle_t mesh_sem; +static uint8_t own_addr_type; +void ble_store_config_init(void); +static uint8_t addr_val[6] = {0}; + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, addr_val, BD_ADDR_LEN); +} + +static void mesh_on_reset(int reason) +{ + ESP_LOGI(TAG, "Resetting state; reason=%d", reason); +} + +static void mesh_on_sync(void) +{ + int rc; + + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGI(TAG, "error determining address type; rc=%d", rc); + return; + } + + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + xSemaphoreGive(mesh_sem); +} + +void mesh_host_task(void *param) +{ + ESP_LOGI(TAG, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +esp_err_t bluetooth_init(void) +{ + mesh_sem = xSemaphoreCreateBinary(); + if (mesh_sem == NULL) { + ESP_LOGE(TAG, "Failed to create mesh semaphore"); + return ESP_FAIL; + } + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = mesh_on_reset; + ble_hs_cfg.sync_cb = mesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(mesh_host_task); + + xSemaphoreTake(mesh_sem, portMAX_DELAY); + + return ESP_OK; +} +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.h b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.h new file mode 100644 index 0000000000..e5e545bfe1 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_init.h @@ -0,0 +1,18 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#ifndef _BLE_MESH_DEMO_INIT_H_ +#define _BLE_MESH_DEMO_INIT_H_ + +#define TAG "ble_mesh_client" + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid); + +esp_err_t bluetooth_init(void); + +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_main.c index f7466992de..e4af32a4ca 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_main.c @@ -13,9 +13,6 @@ #include "esp_log.h" #include "nvs_flash.h" -#include "esp_bt.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_provisioning_api.h" #include "esp_ble_mesh_networking_api.h" @@ -23,8 +20,7 @@ #include "esp_ble_mesh_generic_model_api.h" #include "board.h" - -#define TAG "ble_mesh_client" +#include "ble_mesh_demo_init.h" #define CID_ESP 0x02E5 @@ -450,8 +446,6 @@ static int ble_mesh_init(void) { int err = 0; - memcpy(dev_uuid + 2, esp_bt_dev_get_address(), ESP_BD_ADDR_LEN); - esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb); esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb); esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_cb); @@ -471,45 +465,6 @@ static int ble_mesh_init(void) return err; } -static esp_err_t bluetooth_init(void) -{ - esp_err_t ret; - - ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - ret = esp_bt_controller_init(&bt_cfg); - if (ret) { - ESP_LOGE(TAG, "%s initialize controller failed", __func__); - return ret; - } - - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - if (ret) { - ESP_LOGE(TAG, "%s enable controller failed", __func__); - return ret; - } - ret = esp_bluedroid_init(); - if (ret) { - ESP_LOGE(TAG, "%s init bluetooth failed", __func__); - return ret; - } - ret = esp_bluedroid_enable(); - if (ret) { - ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); - return ret; - } - - return ret; -} - void app_main(void) { int err; @@ -518,12 +473,21 @@ void app_main(void) board_init(); + err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + err = bluetooth_init(); if (err) { ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); return; } + ble_mesh_get_dev_uuid(dev_uuid); + /* Initialize the Bluetooth Mesh Subsystem */ err = ble_mesh_init(); if (err) { diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_register_provisioner_cmd.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_register_provisioner_cmd.c index 6b74255d37..d36aed92f0 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_register_provisioner_cmd.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_register_provisioner_cmd.c @@ -82,7 +82,7 @@ ble_mesh_provisioner_add_key_t provisioner_add_key; void ble_mesh_regist_provisioner_cmd(void); -void ble_mesh_prov_adv_cb(const esp_bd_addr_t addr, const esp_ble_addr_type_t addr_type, const uint8_t adv_type, +void ble_mesh_prov_adv_cb(const esp_ble_mesh_bd_addr_t addr, const esp_ble_mesh_addr_type_t addr_type, const uint8_t adv_type, const uint8_t *dev_uuid, uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer); void ble_mesh_register_mesh_provisioner(void) @@ -90,12 +90,12 @@ void ble_mesh_register_mesh_provisioner(void) ble_mesh_regist_provisioner_cmd(); } -void ble_mesh_prov_adv_cb(const esp_bd_addr_t addr, const esp_ble_addr_type_t addr_type, const uint8_t adv_type, +void ble_mesh_prov_adv_cb(const esp_ble_mesh_bd_addr_t addr, const esp_ble_mesh_addr_type_t addr_type, const uint8_t adv_type, const uint8_t *dev_uuid, uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer) { ESP_LOGD(TAG, "enter %s\n", __func__); ESP_LOGI(TAG, "scan device address:"); - esp_log_buffer_hex(TAG, addr, sizeof(esp_bd_addr_t)); + esp_log_buffer_hex(TAG, addr, sizeof(esp_ble_mesh_bd_addr_t)); ESP_LOGI(TAG, "scan device uuid:"); esp_log_buffer_hex(TAG, dev_uuid, 16); ESP_LOGD(TAG, "exit %s\n", __func__); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/CMakeLists.txt index 3d3bc6f9a5..6644ba29cd 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/CMakeLists.txt @@ -1,4 +1,5 @@ -set(COMPONENT_SRCS "ble_mesh_demo_main.c") +set(COMPONENT_SRCS "ble_mesh_demo_main.c" + "ble_mesh_demo_init.c") set(COMPONENT_ADD_INCLUDEDIRS ".") diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.c new file mode 100644 index 0000000000..371b3d0bda --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.c @@ -0,0 +1,143 @@ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +/* BLE */ +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#endif + +#include "esp_ble_mesh_defs.h" +#include "ble_mesh_demo_init.h" +#include "esp_ble_mesh_common_api.h" + +#ifdef CONFIG_BT_BLUEDROID_ENABLED + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid, esp_bt_dev_get_address(), BD_ADDR_LEN); +} + +esp_err_t bluetooth_init(void) +{ + esp_err_t ret; + + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "%s initialize controller failed", __func__); + return ret; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "%s enable controller failed", __func__); + return ret; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(TAG, "%s init bluetooth failed", __func__); + return ret; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); + return ret; + } + + return ret; +} + +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +static SemaphoreHandle_t mesh_sem; +static uint8_t own_addr_type; +void ble_store_config_init(void); +static uint8_t addr_val[6] = {0}; + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, addr_val, BD_ADDR_LEN); +} + +static void mesh_on_reset(int reason) +{ + ESP_LOGI(TAG, "Resetting state; reason=%d", reason); +} + +static void mesh_on_sync(void) +{ + int rc; + + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGI(TAG, "error determining address type; rc=%d", rc); + return; + } + + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + xSemaphoreGive(mesh_sem); +} + +void mesh_host_task(void *param) +{ + ESP_LOGI(TAG, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +esp_err_t bluetooth_init(void) +{ + mesh_sem = xSemaphoreCreateBinary(); + if (mesh_sem == NULL) { + ESP_LOGE(TAG, "Failed to create mesh semaphore"); + return ESP_FAIL; + } + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = mesh_on_reset; + ble_hs_cfg.sync_cb = mesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(mesh_host_task); + + xSemaphoreTake(mesh_sem, portMAX_DELAY); + + return ESP_OK; +} +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.h b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.h new file mode 100644 index 0000000000..d1af154289 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_init.h @@ -0,0 +1,18 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#ifndef _BLE_MESH_DEMO_INIT_H_ +#define _BLE_MESH_DEMO_INIT_H_ + +#define TAG "FAST_PROV_CLIENT_DEMO" + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid); + +esp_err_t bluetooth_init(void); + +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c index fa3c948dc4..1a48a0687c 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c @@ -19,10 +19,6 @@ #include "esp_log.h" #include "nvs_flash.h" -#include "esp_bt.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" -#include "esp_gap_ble_api.h" #include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_provisioning_api.h" @@ -33,8 +29,7 @@ #include "esp_fast_prov_common.h" #include "esp_fast_prov_operation.h" #include "esp_fast_prov_client_model.h" - -#define TAG "FAST_PROV_CLIENT_DEMO" +#include "ble_mesh_demo_init.h" #define PROV_OWN_ADDR 0x0001 #define APP_KEY_OCTET 0x12 @@ -191,8 +186,8 @@ static void provisioner_prov_complete(int node_index, const uint8_t uuid[16], ui } } -static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[ESP_BD_ADDR_LEN], - esp_ble_addr_type_t addr_type, uint16_t oob_info, +static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[BLE_MESH_ADDR_LEN], + esp_ble_mesh_addr_type_t addr_type, uint16_t oob_info, uint8_t adv_type, esp_ble_mesh_prov_bearer_t bearer) { esp_ble_mesh_unprov_dev_add_t add_dev = {0}; @@ -532,8 +527,6 @@ static esp_err_t ble_mesh_init(void) { esp_err_t err; - memcpy(dev_uuid, esp_bt_dev_get_address(), 6); - prov_info.unicast_min = prov.prov_start_address + prov_info.max_node_num; prov_info.match_len = sizeof(match); memcpy(prov_info.match_val, match, sizeof(match)); @@ -544,18 +537,18 @@ static esp_err_t ble_mesh_init(void) esp_ble_mesh_register_config_client_callback(example_config_client_callback); esp_ble_mesh_register_generic_client_callback(example_generic_client_callback); - err = esp_ble_mesh_provisioner_set_dev_uuid_match(match, 0x02, 0x00, false); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to set matching device UUID", __func__); - return ESP_FAIL; - } - err = esp_ble_mesh_init(&prov, &comp); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to initialize BLE Mesh", __func__); return ESP_FAIL; } + err = esp_ble_mesh_provisioner_set_dev_uuid_match(match, 0x02, 0x00, false); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to set matching device UUID", __func__); + return ESP_FAIL; + } + err = esp_ble_mesh_client_model_init(&vnd_models[0]); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to initialize fast prov client model", __func__); @@ -579,57 +572,27 @@ static esp_err_t ble_mesh_init(void) return err; } -esp_err_t bluetooth_init(void) -{ - esp_err_t ret; - - ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - ret = esp_bt_controller_init(&bt_cfg); - if (ret) { - ESP_LOGE(TAG, "%s initialize controller failed", __func__); - return ret; - } - - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - if (ret) { - ESP_LOGE(TAG, "%s enable controller failed", __func__); - return ret; - } - ret = esp_bluedroid_init(); - if (ret) { - ESP_LOGE(TAG, "%s init bluetooth failed", __func__); - return ret; - } - ret = esp_bluedroid_enable(); - if (ret) { - ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); - return ret; - } - - return ret; -} - void app_main(void) { int err; ESP_LOGI(TAG, "Initializing..."); + err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + err = bluetooth_init(); if (err) { ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); return; } + ble_mesh_get_dev_uuid(dev_uuid); + /* Initialize the Bluetooth Mesh Subsystem */ err = ble_mesh_init(); if (err) { diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/CMakeLists.txt index 1eb2d87ed2..dc91641afd 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/CMakeLists.txt @@ -1,4 +1,5 @@ set(COMPONENT_SRCS "ble_mesh_demo_main.c" + "ble_mesh_demo_init.c" "board.c") set(COMPONENT_ADD_INCLUDEDIRS ".") diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.c new file mode 100644 index 0000000000..ea6aa7f0c5 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.c @@ -0,0 +1,143 @@ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +/* BLE */ +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#endif + +#include "esp_ble_mesh_defs.h" +#include "ble_mesh_demo_init.h" +#include "esp_ble_mesh_common_api.h" + +#ifdef CONFIG_BT_BLUEDROID_ENABLED + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN); +} + +esp_err_t bluetooth_init(void) +{ + esp_err_t ret; + + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "%s initialize controller failed", __func__); + return ret; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "%s enable controller failed", __func__); + return ret; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(TAG, "%s init bluetooth failed", __func__); + return ret; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); + return ret; + } + + return ret; +} + +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +static SemaphoreHandle_t mesh_sem; +static uint8_t own_addr_type; +void ble_store_config_init(void); +static uint8_t addr_val[6] = {0}; + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, addr_val, BD_ADDR_LEN); +} + +static void mesh_on_reset(int reason) +{ + ESP_LOGI(TAG, "Resetting state; reason=%d", reason); +} + +static void mesh_on_sync(void) +{ + int rc; + + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGI(TAG, "error determining address type; rc=%d", rc); + return; + } + + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + xSemaphoreGive(mesh_sem); +} + +void mesh_host_task(void *param) +{ + ESP_LOGI(TAG, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +esp_err_t bluetooth_init(void) +{ + mesh_sem = xSemaphoreCreateBinary(); + if (mesh_sem == NULL) { + ESP_LOGE(TAG, "Failed to create mesh semaphore"); + return ESP_FAIL; + } + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = mesh_on_reset; + ble_hs_cfg.sync_cb = mesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(mesh_host_task); + + xSemaphoreTake(mesh_sem, portMAX_DELAY); + + return ESP_OK; +} +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.h b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.h new file mode 100644 index 0000000000..9e5272de2f --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_init.h @@ -0,0 +1,18 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#ifndef _BLE_MESH_DEMO_INIT_H_ +#define _BLE_MESH_DEMO_INIT_H_ + +#define TAG "FAST_PROV_SERVER_DEMO" + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid); + +esp_err_t bluetooth_init(void); + +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c index 612c292b2c..7fe64220e6 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c @@ -18,10 +18,6 @@ #include "esp_log.h" #include "nvs_flash.h" -#include "esp_bt.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" - #include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_networking_api.h" @@ -33,8 +29,7 @@ #include "esp_fast_prov_operation.h" #include "esp_fast_prov_client_model.h" #include "esp_fast_prov_server_model.h" - -#define TAG "FAST_PROV_SERVER_DEMO" +#include "ble_mesh_demo_init.h" extern struct _led_state led_state[3]; extern struct k_delayed_work send_self_prov_node_addr_timer; @@ -336,8 +331,8 @@ static void provisioner_prov_complete(int node_idx, const uint8_t uuid[16], uint } } -static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[ESP_BD_ADDR_LEN], - esp_ble_addr_type_t addr_type, uint16_t oob_info, +static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[BLE_MESH_ADDR_LEN], + esp_ble_mesh_addr_type_t addr_type, uint16_t oob_info, uint8_t adv_type, esp_ble_mesh_prov_bearer_t bearer) { esp_ble_mesh_unprov_dev_add_t add_dev = {0}; @@ -358,7 +353,7 @@ static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[ESP_B add_dev.oob_info = oob_info; add_dev.bearer = (uint8_t)bearer; memcpy(add_dev.uuid, dev_uuid, 16); - memcpy(add_dev.addr, addr, ESP_BD_ADDR_LEN); + memcpy(add_dev.addr, addr, BLE_MESH_ADDR_LEN); flag = ADD_DEV_RM_AFTER_PROV_FLAG | ADD_DEV_START_PROV_NOW_FLAG | ADD_DEV_FLUSHABLE_DEV_FLAG; err = esp_ble_mesh_provisioner_add_unprov_dev(&add_dev, flag); if (err != ESP_OK) { @@ -733,9 +728,6 @@ static esp_err_t ble_mesh_init(void) { esp_err_t err; - /* First two bytes of device uuid is compared with match value by Provisioner */ - memcpy(dev_uuid + 2, esp_bt_dev_get_address(), 6); - esp_ble_mesh_register_prov_callback(example_ble_mesh_provisioning_cb); esp_ble_mesh_register_custom_model_callback(example_ble_mesh_custom_model_cb); esp_ble_mesh_register_config_client_callback(example_ble_mesh_config_client_cb); @@ -774,47 +766,6 @@ static esp_err_t ble_mesh_init(void) return ESP_OK; } -static esp_err_t bluetooth_init(void) -{ - esp_err_t ret; - - ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - ret = esp_bt_controller_init(&bt_cfg); - if (ret) { - ESP_LOGE(TAG, "%s initialize controller failed", __func__); - return ret; - } - - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - if (ret) { - ESP_LOGE(TAG, "%s enable controller failed", __func__); - return ret; - } - - ret = esp_bluedroid_init(); - if (ret) { - ESP_LOGE(TAG, "%s init bluetooth failed", __func__); - return ret; - } - - ret = esp_bluedroid_enable(); - if (ret) { - ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); - return ret; - } - - return ret; -} - void app_main(void) { esp_err_t err; @@ -827,12 +778,21 @@ void app_main(void) return; } + err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + err = bluetooth_init(); if (err) { ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); return; } + ble_mesh_get_dev_uuid(dev_uuid); + /* Initialize the Bluetooth Mesh Subsystem */ err = ble_mesh_init(); if (err) { diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/CMakeLists.txt index 1eb2d87ed2..dc91641afd 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/CMakeLists.txt @@ -1,4 +1,5 @@ set(COMPONENT_SRCS "ble_mesh_demo_main.c" + "ble_mesh_demo_init.c" "board.c") set(COMPONENT_ADD_INCLUDEDIRS ".") diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.c new file mode 100644 index 0000000000..ea6aa7f0c5 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.c @@ -0,0 +1,143 @@ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +/* BLE */ +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#endif + +#include "esp_ble_mesh_defs.h" +#include "ble_mesh_demo_init.h" +#include "esp_ble_mesh_common_api.h" + +#ifdef CONFIG_BT_BLUEDROID_ENABLED + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN); +} + +esp_err_t bluetooth_init(void) +{ + esp_err_t ret; + + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "%s initialize controller failed", __func__); + return ret; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "%s enable controller failed", __func__); + return ret; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(TAG, "%s init bluetooth failed", __func__); + return ret; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); + return ret; + } + + return ret; +} + +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +static SemaphoreHandle_t mesh_sem; +static uint8_t own_addr_type; +void ble_store_config_init(void); +static uint8_t addr_val[6] = {0}; + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, addr_val, BD_ADDR_LEN); +} + +static void mesh_on_reset(int reason) +{ + ESP_LOGI(TAG, "Resetting state; reason=%d", reason); +} + +static void mesh_on_sync(void) +{ + int rc; + + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGI(TAG, "error determining address type; rc=%d", rc); + return; + } + + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + xSemaphoreGive(mesh_sem); +} + +void mesh_host_task(void *param) +{ + ESP_LOGI(TAG, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +esp_err_t bluetooth_init(void) +{ + mesh_sem = xSemaphoreCreateBinary(); + if (mesh_sem == NULL) { + ESP_LOGE(TAG, "Failed to create mesh semaphore"); + return ESP_FAIL; + } + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = mesh_on_reset; + ble_hs_cfg.sync_cb = mesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(mesh_host_task); + + xSemaphoreTake(mesh_sem, portMAX_DELAY); + + return ESP_OK; +} +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.h b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.h new file mode 100644 index 0000000000..d4432076e3 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_init.h @@ -0,0 +1,18 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#ifndef _BLE_MESH_DEMO_INIT_H_ +#define _BLE_MESH_DEMO_INIT_H_ + +#define TAG "ble_mesh_node" + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid); + +esp_err_t bluetooth_init(void); + +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_main.c index 1d8fb2cd56..4c5e16eb83 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_main.c @@ -13,10 +13,6 @@ #include "esp_log.h" #include "nvs_flash.h" -#include "esp_bt.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" - #include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_networking_api.h" @@ -24,8 +20,7 @@ #include "esp_ble_mesh_config_model_api.h" #include "board.h" - -#define TAG "ble_mesh_node" +#include "ble_mesh_demo_init.h" #define CID_ESP 0x02E5 @@ -314,8 +309,6 @@ static esp_err_t ble_mesh_init(void) { int err = 0; - memcpy(dev_uuid + 2, esp_bt_dev_get_address(), ESP_BD_ADDR_LEN); - esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb); esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb); @@ -334,45 +327,6 @@ static esp_err_t ble_mesh_init(void) return err; } -static esp_err_t bluetooth_init(void) -{ - esp_err_t ret; - - ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - ret = esp_bt_controller_init(&bt_cfg); - if (ret) { - ESP_LOGE(TAG, "%s initialize controller failed", __func__); - return ret; - } - - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - if (ret) { - ESP_LOGE(TAG, "%s enable controller failed", __func__); - return ret; - } - ret = esp_bluedroid_init(); - if (ret) { - ESP_LOGE(TAG, "%s init bluetooth failed", __func__); - return ret; - } - ret = esp_bluedroid_enable(); - if (ret) { - ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); - return ret; - } - - return ret; -} - void app_main(void) { int err; @@ -381,12 +335,21 @@ void app_main(void) board_init(); + err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + err = bluetooth_init(); if (err) { ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); return; } + ble_mesh_get_dev_uuid(dev_uuid); + /* Initialize the Bluetooth Mesh Subsystem */ err = ble_mesh_init(); if (err) { diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/tutorial/Ble_Mesh_Node_Example_Walkthrough.md b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/tutorial/Ble_Mesh_Node_Example_Walkthrough.md index cdde9bfdb1..bb2491267f 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/tutorial/Ble_Mesh_Node_Example_Walkthrough.md +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/tutorial/Ble_Mesh_Node_Example_Walkthrough.md @@ -97,7 +97,7 @@ static esp_err_t ble_mesh_init(void) { int err = 0; - memcpy(dev_uuid + 2, esp_bt_dev_get_address(), ESP_BD_ADDR_LEN); + memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BLE_MESH_ADDR_LEN); // See comment 1 esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/CMakeLists.txt index 3d3bc6f9a5..6644ba29cd 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/CMakeLists.txt @@ -1,4 +1,5 @@ -set(COMPONENT_SRCS "ble_mesh_demo_main.c") +set(COMPONENT_SRCS "ble_mesh_demo_main.c" + "ble_mesh_demo_init.c") set(COMPONENT_ADD_INCLUDEDIRS ".") diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.c new file mode 100644 index 0000000000..ea6aa7f0c5 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.c @@ -0,0 +1,143 @@ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +/* BLE */ +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#endif + +#include "esp_ble_mesh_defs.h" +#include "ble_mesh_demo_init.h" +#include "esp_ble_mesh_common_api.h" + +#ifdef CONFIG_BT_BLUEDROID_ENABLED + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN); +} + +esp_err_t bluetooth_init(void) +{ + esp_err_t ret; + + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "%s initialize controller failed", __func__); + return ret; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "%s enable controller failed", __func__); + return ret; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(TAG, "%s init bluetooth failed", __func__); + return ret; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); + return ret; + } + + return ret; +} + +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +static SemaphoreHandle_t mesh_sem; +static uint8_t own_addr_type; +void ble_store_config_init(void); +static uint8_t addr_val[6] = {0}; + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, addr_val, BD_ADDR_LEN); +} + +static void mesh_on_reset(int reason) +{ + ESP_LOGI(TAG, "Resetting state; reason=%d", reason); +} + +static void mesh_on_sync(void) +{ + int rc; + + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGI(TAG, "error determining address type; rc=%d", rc); + return; + } + + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + xSemaphoreGive(mesh_sem); +} + +void mesh_host_task(void *param) +{ + ESP_LOGI(TAG, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +esp_err_t bluetooth_init(void) +{ + mesh_sem = xSemaphoreCreateBinary(); + if (mesh_sem == NULL) { + ESP_LOGE(TAG, "Failed to create mesh semaphore"); + return ESP_FAIL; + } + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = mesh_on_reset; + ble_hs_cfg.sync_cb = mesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(mesh_host_task); + + xSemaphoreTake(mesh_sem, portMAX_DELAY); + + return ESP_OK; +} +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.h b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.h new file mode 100644 index 0000000000..309afa79b9 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_init.h @@ -0,0 +1,18 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#ifndef _BLE_MESH_DEMO_INIT_H_ +#define _BLE_MESH_DEMO_INIT_H_ + +#define TAG "ble_mesh_provisioner" + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid); + +esp_err_t bluetooth_init(void); + +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_main.c index 7f3ddeb405..f35dd40748 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/ble_mesh_demo_main.c @@ -12,10 +12,6 @@ #include "esp_log.h" #include "nvs_flash.h" -#include "esp_bt.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" - #include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_provisioning_api.h" @@ -23,7 +19,7 @@ #include "esp_ble_mesh_config_model_api.h" #include "esp_ble_mesh_generic_model_api.h" -#define TAG "ble_mesh_provisioner" +#include "ble_mesh_demo_init.h" #define LED_OFF 0x0 #define LED_ON 0x1 @@ -243,8 +239,8 @@ static void prov_link_close(esp_ble_mesh_prov_bearer_t bearer, uint8_t reason) bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT", reason); } -static void recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[ESP_BD_ADDR_LEN], - esp_ble_addr_type_t addr_type, uint16_t oob_info, +static void recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[BD_ADDR_LEN], + esp_ble_mesh_addr_type_t addr_type, uint16_t oob_info, uint8_t adv_type, esp_ble_mesh_prov_bearer_t bearer) { esp_ble_mesh_unprov_dev_add_t add_dev = {0}; @@ -255,11 +251,11 @@ static void recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[ESP_BD_ADDR_L * to the application layer. */ - ESP_LOGI(TAG, "address: %s, address type: %d, adv type: %d", bt_hex(addr, ESP_BD_ADDR_LEN), addr_type, adv_type); + ESP_LOGI(TAG, "address: %s, address type: %d, adv type: %d", bt_hex(addr, BD_ADDR_LEN), addr_type, adv_type); ESP_LOGI(TAG, "device uuid: %s", bt_hex(dev_uuid, 16)); ESP_LOGI(TAG, "oob info: %d, bearer: %s", oob_info, (bearer & ESP_BLE_MESH_PROV_ADV) ? "PB-ADV" : "PB-GATT"); - memcpy(add_dev.addr, addr, ESP_BD_ADDR_LEN); + memcpy(add_dev.addr, addr, BD_ADDR_LEN); add_dev.addr_type = (uint8_t)addr_type; memcpy(add_dev.uuid, dev_uuid, 16); add_dev.oob_info = oob_info; @@ -608,14 +604,11 @@ static int ble_mesh_init(void) prov_key.app_idx = APP_KEY_IDX; memset(prov_key.app_key, APP_KEY_OCTET, sizeof(prov_key.app_key)); - memcpy(dev_uuid, esp_bt_dev_get_address(), ESP_BD_ADDR_LEN); - esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb); esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb); esp_ble_mesh_register_config_client_callback(esp_ble_mesh_config_client_cb); esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_client_cb); - esp_ble_mesh_provisioner_set_dev_uuid_match(match, sizeof(match), 0x0, false); err = esp_ble_mesh_init(&provision, &composition); if (err) { @@ -623,6 +616,8 @@ static int ble_mesh_init(void) return err; } + esp_ble_mesh_provisioner_set_dev_uuid_match(match, sizeof(match), 0x0, false); + esp_ble_mesh_provisioner_prov_enable(ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT); esp_ble_mesh_provisioner_add_local_app_key(prov_key.app_key, prov_key.net_idx, prov_key.app_idx); @@ -632,57 +627,27 @@ static int ble_mesh_init(void) return err; } -static esp_err_t bluetooth_init(void) -{ - esp_err_t ret; - - ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - ret = esp_bt_controller_init(&bt_cfg); - if (ret) { - ESP_LOGE(TAG, "%s initialize controller failed", __func__); - return ret; - } - - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - if (ret) { - ESP_LOGE(TAG, "%s enable controller failed", __func__); - return ret; - } - ret = esp_bluedroid_init(); - if (ret) { - ESP_LOGE(TAG, "%s init bluetooth failed", __func__); - return ret; - } - ret = esp_bluedroid_enable(); - if (ret) { - ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); - return ret; - } - - return ret; -} - void app_main(void) { int err; ESP_LOGI(TAG, "Initializing..."); + err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + err = bluetooth_init(); if (err) { ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); return; } + ble_mesh_get_dev_uuid(dev_uuid); + /* Initialize the Bluetooth Mesh Subsystem */ err = ble_mesh_init(); if (err) { diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/tutorial/Ble_Mesh_Provisioner_Example_Walkthrough.md b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/tutorial/Ble_Mesh_Provisioner_Example_Walkthrough.md index 53d0f9d04e..b1d2e1b74e 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/tutorial/Ble_Mesh_Provisioner_Example_Walkthrough.md +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/tutorial/Ble_Mesh_Provisioner_Example_Walkthrough.md @@ -21,7 +21,7 @@ static int ble_mesh_init(void) prov_key.app_idx = ESP_BLE_MESH_APP_IDX; memset(prov_key.app_key, APP_KEY_OCTET, sizeof(prov_key.app_key)); - memcpy(dev_uuid, esp_bt_dev_get_address(), ESP_BD_ADDR_LEN); + memcpy(dev_uuid, esp_bt_dev_get_address(), BLE_MESH_ADDR_LEN); esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb); esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/CMakeLists.txt index 1eb2d87ed2..dc91641afd 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/CMakeLists.txt @@ -1,4 +1,5 @@ set(COMPONENT_SRCS "ble_mesh_demo_main.c" + "ble_mesh_demo_init.c" "board.c") set(COMPONENT_ADD_INCLUDEDIRS ".") diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.c new file mode 100644 index 0000000000..ea6aa7f0c5 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.c @@ -0,0 +1,143 @@ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +/* BLE */ +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#endif + +#include "esp_ble_mesh_defs.h" +#include "ble_mesh_demo_init.h" +#include "esp_ble_mesh_common_api.h" + +#ifdef CONFIG_BT_BLUEDROID_ENABLED + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN); +} + +esp_err_t bluetooth_init(void) +{ + esp_err_t ret; + + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "%s initialize controller failed", __func__); + return ret; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "%s enable controller failed", __func__); + return ret; + } + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(TAG, "%s init bluetooth failed", __func__); + return ret; + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); + return ret; + } + + return ret; +} + +#endif + +#ifdef CONFIG_BT_NIMBLE_ENABLED +static SemaphoreHandle_t mesh_sem; +static uint8_t own_addr_type; +void ble_store_config_init(void); +static uint8_t addr_val[6] = {0}; + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid) +{ + memcpy(dev_uuid + 2, addr_val, BD_ADDR_LEN); +} + +static void mesh_on_reset(int reason) +{ + ESP_LOGI(TAG, "Resetting state; reason=%d", reason); +} + +static void mesh_on_sync(void) +{ + int rc; + + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGI(TAG, "error determining address type; rc=%d", rc); + return; + } + + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + xSemaphoreGive(mesh_sem); +} + +void mesh_host_task(void *param) +{ + ESP_LOGI(TAG, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +esp_err_t bluetooth_init(void) +{ + mesh_sem = xSemaphoreCreateBinary(); + if (mesh_sem == NULL) { + ESP_LOGE(TAG, "Failed to create mesh semaphore"); + return ESP_FAIL; + } + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = mesh_on_reset; + ble_hs_cfg.sync_cb = mesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(mesh_host_task); + + xSemaphoreTake(mesh_sem, portMAX_DELAY); + + return ESP_OK; +} +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.h b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.h new file mode 100644 index 0000000000..9ee5653135 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_init.h @@ -0,0 +1,18 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#ifndef _BLE_MESH_DEMO_INIT_H_ +#define _BLE_MESH_DEMO_INIT_H_ + +#define TAG "BLE_MESH_WIFI_COEXIST_DEMO" + +void ble_mesh_get_dev_uuid(uint8_t *dev_uuid); + +esp_err_t bluetooth_init(void); + +#endif diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c index b68253c382..f2b56076f1 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c @@ -30,10 +30,6 @@ #include "argtable3/argtable3.h" #include "cmd_decl.h" -#include "esp_bt.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" - #include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_networking_api.h" @@ -45,8 +41,7 @@ #include "esp_fast_prov_operation.h" #include "esp_fast_prov_client_model.h" #include "esp_fast_prov_server_model.h" - -#define TAG "BLE_MESH_WIFI_COEXIST_DEMO" +#include "ble_mesh_demo_init.h" extern struct _led_state led_state[3]; extern struct k_delayed_work send_self_prov_node_addr_timer; @@ -348,8 +343,8 @@ static void provisioner_prov_complete(int node_idx, const uint8_t uuid[16], uint } } -static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[ESP_BD_ADDR_LEN], - esp_ble_addr_type_t addr_type, uint16_t oob_info, +static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[BLE_MESH_ADDR_LEN], + esp_ble_mesh_addr_type_t addr_type, uint16_t oob_info, uint8_t adv_type, esp_ble_mesh_prov_bearer_t bearer) { esp_ble_mesh_unprov_dev_add_t add_dev = {0}; @@ -370,7 +365,7 @@ static void example_recv_unprov_adv_pkt(uint8_t dev_uuid[16], uint8_t addr[ESP_B add_dev.oob_info = oob_info; add_dev.bearer = (uint8_t)bearer; memcpy(add_dev.uuid, dev_uuid, 16); - memcpy(add_dev.addr, addr, ESP_BD_ADDR_LEN); + memcpy(add_dev.addr, addr, BLE_MESH_ADDR_LEN); flag = ADD_DEV_RM_AFTER_PROV_FLAG | ADD_DEV_START_PROV_NOW_FLAG | ADD_DEV_FLUSHABLE_DEV_FLAG; err = esp_ble_mesh_provisioner_add_unprov_dev(&add_dev, flag); if (err != ESP_OK) { @@ -745,9 +740,6 @@ static esp_err_t ble_mesh_init(void) { esp_err_t err; - /* First two bytes of device uuid is compared with match value by Provisioner */ - memcpy(dev_uuid + 2, esp_bt_dev_get_address(), 6); - esp_ble_mesh_register_prov_callback(example_ble_mesh_provisioning_cb); esp_ble_mesh_register_custom_model_callback(example_ble_mesh_custom_model_cb); esp_ble_mesh_register_config_client_callback(example_ble_mesh_config_client_cb); @@ -786,47 +778,6 @@ static esp_err_t ble_mesh_init(void) return ESP_OK; } -static esp_err_t bluetooth_init(void) -{ - esp_err_t ret; - - ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - ret = esp_bt_controller_init(&bt_cfg); - if (ret) { - ESP_LOGE(TAG, "%s initialize controller failed", __func__); - return ret; - } - - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - if (ret) { - ESP_LOGE(TAG, "%s enable controller failed", __func__); - return ret; - } - - ret = esp_bluedroid_init(); - if (ret) { - ESP_LOGE(TAG, "%s init bluetooth failed", __func__); - return ret; - } - - ret = esp_bluedroid_enable(); - if (ret) { - ESP_LOGE(TAG, "%s enable bluetooth failed", __func__); - return ret; - } - - return ret; -} - #define WIFI_CONNECTED_BIT BIT0 static void initialize_console(void) @@ -960,12 +911,21 @@ void app_main(void) return; } + err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + err = bluetooth_init(); if (err) { ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); return; } + ble_mesh_get_dev_uuid(dev_uuid); + /* Initialize the Bluetooth Mesh Subsystem */ err = ble_mesh_init(); if (err) {