Merge branch 'master' into feature/esp32s2beta_update
This commit is contained in:
commit
24d26fccde
2414 changed files with 160787 additions and 45783 deletions
15
.flake8
15
.flake8
|
@ -140,15 +140,16 @@ exclude =
|
||||||
.git,
|
.git,
|
||||||
__pycache__,
|
__pycache__,
|
||||||
# submodules
|
# submodules
|
||||||
components/esptool_py/esptool,
|
|
||||||
components/bootloader/subproject/components/micro-ecc/micro-ecc,
|
components/bootloader/subproject/components/micro-ecc/micro-ecc,
|
||||||
components/nghttp/nghttp2,
|
components/esptool_py/esptool,
|
||||||
components/libsodium/libsodium,
|
|
||||||
components/json/cJSON,
|
|
||||||
components/mbedtls/mbedtls,
|
|
||||||
components/expat/expat,
|
components/expat/expat,
|
||||||
|
components/json/cJSON,
|
||||||
|
components/libsodium/libsodium,
|
||||||
|
components/mbedtls/mbedtls,
|
||||||
|
components/nghttp/nghttp2,
|
||||||
|
components/bt/host/nimble/nimble,
|
||||||
components/unity/unity,
|
components/unity/unity,
|
||||||
examples/build_system/cmake/import_lib/main/lib/tinyxml2
|
examples/build_system/cmake/import_lib/main/lib/tinyxml2,
|
||||||
# other third-party libraries
|
# other third-party libraries
|
||||||
tools/kconfig_new/kconfiglib.py,
|
tools/kconfig_new/kconfiglib.py,
|
||||||
# autogenerated scripts
|
# autogenerated scripts
|
||||||
|
@ -156,6 +157,8 @@ exclude =
|
||||||
components/protocomm/python/sec0_pb2.py,
|
components/protocomm/python/sec0_pb2.py,
|
||||||
components/protocomm/python/sec1_pb2.py,
|
components/protocomm/python/sec1_pb2.py,
|
||||||
components/protocomm/python/session_pb2.py,
|
components/protocomm/python/session_pb2.py,
|
||||||
|
components/wifi_provisioning/python/wifi_scan_pb2.py,
|
||||||
components/wifi_provisioning/python/wifi_config_pb2.py,
|
components/wifi_provisioning/python/wifi_config_pb2.py,
|
||||||
components/wifi_provisioning/python/wifi_constants_pb2.py,
|
components/wifi_provisioning/python/wifi_constants_pb2.py,
|
||||||
|
components/esp_local_ctrl/python/esp_local_ctrl_pb2.py,
|
||||||
examples/provisioning/custom_config/components/custom_provisioning/python/custom_config_pb2.py,
|
examples/provisioning/custom_config/components/custom_provisioning/python/custom_config_pb2.py,
|
||||||
|
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -58,13 +58,6 @@ TEST_LOGS
|
||||||
coverage.info
|
coverage.info
|
||||||
coverage_report/
|
coverage_report/
|
||||||
|
|
||||||
# Windows tools installer build
|
|
||||||
tools/windows/tool_setup/.*
|
|
||||||
tools/windows/tool_setup/input
|
|
||||||
tools/windows/tool_setup/dl
|
|
||||||
tools/windows/tool_setup/keys
|
|
||||||
tools/windows/tool_setup/Output
|
|
||||||
|
|
||||||
test_multi_heap_host
|
test_multi_heap_host
|
||||||
|
|
||||||
# VS Code Settings
|
# VS Code Settings
|
||||||
|
|
2378
.gitlab-ci.yml
2378
.gitlab-ci.yml
File diff suppressed because it is too large
Load diff
50
.gitmodules
vendored
50
.gitmodules
vendored
|
@ -1,71 +1,81 @@
|
||||||
|
#
|
||||||
|
# All the relative URL paths are intended to be GitHub ones
|
||||||
|
# For Espressif's public projects please use '../../espressif/proj', not a '../proj'
|
||||||
|
#
|
||||||
|
|
||||||
[submodule "components/esptool_py/esptool"]
|
[submodule "components/esptool_py/esptool"]
|
||||||
path = components/esptool_py/esptool
|
path = components/esptool_py/esptool
|
||||||
url = https://github.com/espressif/esptool.git
|
url = ../../espressif/esptool.git
|
||||||
|
|
||||||
[submodule "components/bt/lib"]
|
[submodule "components/bt/controller/lib"]
|
||||||
path = components/bt/lib
|
path = components/bt/controller/lib
|
||||||
url = https://github.com/espressif/esp32-bt-lib.git
|
url = ../../espressif/esp32-bt-lib.git
|
||||||
|
|
||||||
[submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"]
|
[submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"]
|
||||||
path = components/bootloader/subproject/components/micro-ecc/micro-ecc
|
path = components/bootloader/subproject/components/micro-ecc/micro-ecc
|
||||||
url = https://github.com/kmackay/micro-ecc.git
|
url = ../../kmackay/micro-ecc.git
|
||||||
|
|
||||||
[submodule "components/coap/libcoap"]
|
[submodule "components/coap/libcoap"]
|
||||||
path = components/coap/libcoap
|
path = components/coap/libcoap
|
||||||
url = https://github.com/obgm/libcoap.git
|
url = ../../obgm/libcoap.git
|
||||||
|
|
||||||
[submodule "components/nghttp/nghttp2"]
|
[submodule "components/nghttp/nghttp2"]
|
||||||
path = components/nghttp/nghttp2
|
path = components/nghttp/nghttp2
|
||||||
url = https://github.com/nghttp2/nghttp2.git
|
url = ../../nghttp2/nghttp2.git
|
||||||
|
|
||||||
[submodule "components/libsodium/libsodium"]
|
[submodule "components/libsodium/libsodium"]
|
||||||
path = components/libsodium/libsodium
|
path = components/libsodium/libsodium
|
||||||
url = https://github.com/jedisct1/libsodium.git
|
url = ../../jedisct1/libsodium.git
|
||||||
|
|
||||||
[submodule "components/spiffs/spiffs"]
|
[submodule "components/spiffs/spiffs"]
|
||||||
path = components/spiffs/spiffs
|
path = components/spiffs/spiffs
|
||||||
url = https://github.com/pellepl/spiffs.git
|
url = ../../pellepl/spiffs.git
|
||||||
|
|
||||||
[submodule "components/json/cJSON"]
|
[submodule "components/json/cJSON"]
|
||||||
path = components/json/cJSON
|
path = components/json/cJSON
|
||||||
url = https://github.com/DaveGamble/cJSON.git
|
url = ../../DaveGamble/cJSON.git
|
||||||
|
|
||||||
[submodule "components/mbedtls/mbedtls"]
|
[submodule "components/mbedtls/mbedtls"]
|
||||||
path = components/mbedtls/mbedtls
|
path = components/mbedtls/mbedtls
|
||||||
url = https://github.com/espressif/mbedtls.git
|
url = ../../espressif/mbedtls.git
|
||||||
|
|
||||||
[submodule "components/asio/asio"]
|
[submodule "components/asio/asio"]
|
||||||
path = components/asio/asio
|
path = components/asio/asio
|
||||||
url = https://github.com/espressif/asio.git
|
url = ../../espressif/asio.git
|
||||||
|
|
||||||
[submodule "components/expat/expat"]
|
[submodule "components/expat/expat"]
|
||||||
path = components/expat/expat
|
path = components/expat/expat
|
||||||
url = https://github.com/libexpat/libexpat.git
|
url = ../../libexpat/libexpat.git
|
||||||
|
|
||||||
[submodule "components/lwip/lwip"]
|
[submodule "components/lwip/lwip"]
|
||||||
path = components/lwip/lwip
|
path = components/lwip/lwip
|
||||||
url = https://github.com/espressif/esp-lwip.git
|
url = ../../espressif/esp-lwip.git
|
||||||
|
|
||||||
[submodule "components/mqtt/esp-mqtt"]
|
[submodule "components/mqtt/esp-mqtt"]
|
||||||
path = components/mqtt/esp-mqtt
|
path = components/mqtt/esp-mqtt
|
||||||
url = https://github.com/espressif/esp-mqtt.git
|
url = ../../espressif/esp-mqtt.git
|
||||||
|
|
||||||
[submodule "components/protobuf-c/protobuf-c"]
|
[submodule "components/protobuf-c/protobuf-c"]
|
||||||
path = components/protobuf-c/protobuf-c
|
path = components/protobuf-c/protobuf-c
|
||||||
url = https://github.com/protobuf-c/protobuf-c
|
url = ../../protobuf-c/protobuf-c.git
|
||||||
|
|
||||||
[submodule "components/unity/unity"]
|
[submodule "components/unity/unity"]
|
||||||
path = components/unity/unity
|
path = components/unity/unity
|
||||||
url = https://github.com/ThrowTheSwitch/Unity
|
url = ../../ThrowTheSwitch/Unity.git
|
||||||
|
|
||||||
[submodule "examples/build_system/cmake/import_lib/main/lib/tinyxml2"]
|
[submodule "examples/build_system/cmake/import_lib/main/lib/tinyxml2"]
|
||||||
path = examples/build_system/cmake/import_lib/main/lib/tinyxml2
|
path = examples/build_system/cmake/import_lib/main/lib/tinyxml2
|
||||||
url = https://github.com/leethomason/tinyxml2
|
url = ../../leethomason/tinyxml2.git
|
||||||
|
|
||||||
[submodule "components/esp_wifi/lib_esp32"]
|
[submodule "components/esp_wifi/lib_esp32"]
|
||||||
path = components/esp_wifi/lib_esp32
|
path = components/esp_wifi/lib_esp32
|
||||||
url = https://github.com/espressif/esp32-wifi-lib.git
|
url = ../../espressif/esp32-wifi-lib.git
|
||||||
|
|
||||||
[submodule "components/esp_wifi/lib_esp32s2beta"]
|
[submodule "components/esp_wifi/lib_esp32s2beta"]
|
||||||
path = components/esp_wifi/lib_esp32s2beta
|
path = components/esp_wifi/lib_esp32s2beta
|
||||||
url = https://github.com/espressif/esp32-wifi-lib.git
|
url = ../../espressif/esp32-wifi-lib.git
|
||||||
|
|
||||||
|
[submodule "components/bt/host/nimble/nimble"]
|
||||||
|
path = components/bt/host/nimble/nimble
|
||||||
|
url = ../../espressif/esp-nimble.git
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ version: 2
|
||||||
|
|
||||||
# Optionally build your docs in additional formats such as PDF and ePub
|
# Optionally build your docs in additional formats such as PDF and ePub
|
||||||
formats:
|
formats:
|
||||||
- htmlzip
|
|
||||||
- pdf
|
- pdf
|
||||||
|
|
||||||
# Optionally set the version of Python and requirements required to build your docs
|
# Optionally set the version of Python and requirements required to build your docs
|
||||||
|
|
|
@ -11,6 +11,7 @@ unset(compile_definitions)
|
||||||
|
|
||||||
if(CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE)
|
if(CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE)
|
||||||
list(APPEND compile_options "-Os")
|
list(APPEND compile_options "-Os")
|
||||||
|
list(APPEND compile_options "-freorder-blocks")
|
||||||
else()
|
else()
|
||||||
list(APPEND compile_options "-Og")
|
list(APPEND compile_options "-Og")
|
||||||
endif()
|
endif()
|
||||||
|
@ -70,39 +71,13 @@ foreach(component_target ${build_component_targets})
|
||||||
set(COMPONENT_NAME ${_name})
|
set(COMPONENT_NAME ${_name})
|
||||||
set(COMPONENT_DIR ${dir})
|
set(COMPONENT_DIR ${dir})
|
||||||
set(COMPONENT_ALIAS ${alias})
|
set(COMPONENT_ALIAS ${alias})
|
||||||
set(COMPONENT_PATH ${dir}) # also deprecated, see comment in previous loop
|
set(COMPONENT_PATH ${dir}) # for backward compatibility only, COMPONENT_DIR is preferred
|
||||||
idf_build_get_property(build_prefix __PREFIX)
|
idf_build_get_property(build_prefix __PREFIX)
|
||||||
set(__idf_component_context 1)
|
set(__idf_component_context 1)
|
||||||
if(NOT prefix STREQUAL build_prefix)
|
if(NOT prefix STREQUAL build_prefix)
|
||||||
add_subdirectory(${dir} ${prefix}_${_name} EXCLUDE_FROM_ALL)
|
add_subdirectory(${dir} ${prefix}_${_name})
|
||||||
else()
|
else()
|
||||||
add_subdirectory(${dir} ${_name} EXCLUDE_FROM_ALL)
|
add_subdirectory(${dir} ${_name})
|
||||||
endif()
|
endif()
|
||||||
set(__idf_component_context 0)
|
set(__idf_component_context 0)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# Establish dependencies between components
|
|
||||||
idf_build_get_property(build_components BUILD_COMPONENTS)
|
|
||||||
foreach(build_component ${build_components})
|
|
||||||
__component_get_target(component_target ${build_component})
|
|
||||||
__component_get_property(component_lib ${component_target} COMPONENT_LIB)
|
|
||||||
__component_get_property(reqs ${component_target} __REQUIRES)
|
|
||||||
foreach(req ${reqs})
|
|
||||||
__component_get_property(req_lib ${req} COMPONENT_LIB)
|
|
||||||
if(TARGET ${req_lib})
|
|
||||||
set_property(TARGET ${component_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${req_lib})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
get_property(type TARGET ${component_lib} PROPERTY TYPE)
|
|
||||||
if(type STREQUAL STATIC_LIBRARY)
|
|
||||||
__component_get_property(reqs ${component_target} __REQUIRES)
|
|
||||||
__component_get_property(priv_reqs ${component_target} __PRIV_REQUIRES)
|
|
||||||
foreach(req ${reqs} ${priv_reqs})
|
|
||||||
__component_get_property(req_lib ${req} COMPONENT_LIB)
|
|
||||||
if(TARGET ${req_lib})
|
|
||||||
set_property(TARGET ${component_lib} APPEND PROPERTY LINK_LIBRARIES ${req_lib})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
6
Kconfig
6
Kconfig
|
@ -56,11 +56,11 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||||
The executable name/path that is used to run python. On some systems Python 2.x
|
The executable name/path that is used to run python. On some systems Python 2.x
|
||||||
may need to be invoked as python2.
|
may need to be invoked as python2.
|
||||||
|
|
||||||
(Note: This option is used with the GNU Make build system only, not idf.py
|
(Note: This option is used with the legacy GNU Make build system only.)
|
||||||
or CMake-based builds.)
|
|
||||||
|
|
||||||
config SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
config SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
||||||
bool "'make' warns on undefined variables"
|
bool "'make' warns on undefined variables"
|
||||||
|
depends on !IDF_CMAKE
|
||||||
default "y"
|
default "y"
|
||||||
help
|
help
|
||||||
Adds --warn-undefined-variables to MAKEFLAGS. This causes make to
|
Adds --warn-undefined-variables to MAKEFLAGS. This causes make to
|
||||||
|
@ -70,6 +70,8 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||||
or otherwise missing, but it can be unwanted if you have Makefiles which
|
or otherwise missing, but it can be unwanted if you have Makefiles which
|
||||||
depend on undefined variables expanding to an empty string.
|
depend on undefined variables expanding to an empty string.
|
||||||
|
|
||||||
|
(Note: this option is used with the legacy GNU Make build system only.)
|
||||||
|
|
||||||
endmenu # SDK tool configuration
|
endmenu # SDK tool configuration
|
||||||
|
|
||||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||||
|
|
72
README.md
72
README.md
|
@ -13,6 +13,14 @@ See setup guides for detailed instructions to set up the ESP-IDF:
|
||||||
* [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
|
* [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
|
||||||
* [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
|
* [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
|
||||||
|
|
||||||
|
### Non-GitHub forks
|
||||||
|
|
||||||
|
ESP-IDF uses relative locations as its submodules URLs ([.gitmodules](.gitmodules)). So they link to GitHub.
|
||||||
|
If ESP-IDF is forked to a Git repository which is not on GitHub, you will need to run the script
|
||||||
|
[tools/set-submodules-to-github.sh](tools/set-submodules-to-github.sh) after git clone.
|
||||||
|
The script sets absolute URLs for all submodules, allowing `git submodule update --init --recursive` to complete.
|
||||||
|
If cloning ESP-IDF from GitHub, this step is not needed.
|
||||||
|
|
||||||
## Finding a Project
|
## Finding a Project
|
||||||
|
|
||||||
As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in Getting Started, ESP-IDF comes with some example projects in the [examples](examples) directory.
|
As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in Getting Started, ESP-IDF comes with some example projects in the [examples](examples) directory.
|
||||||
|
@ -25,9 +33,17 @@ To start your own project based on an example, copy the example project director
|
||||||
|
|
||||||
See the Getting Started guide links above for a detailed setup guide. This is a quick reference for common commands when working with ESP-IDF projects:
|
See the Getting Started guide links above for a detailed setup guide. This is a quick reference for common commands when working with ESP-IDF projects:
|
||||||
|
|
||||||
|
## Setup Build Environment
|
||||||
|
|
||||||
|
(See Getting Started guide for a full list of required steps with details.)
|
||||||
|
|
||||||
|
* Install host build dependencies mentioned in Getting Started guide.
|
||||||
|
* Add `tools/` directory to the PATH
|
||||||
|
* Run `python -m pip install requirements.txt` to install Python dependencies
|
||||||
|
|
||||||
## Configuring the Project
|
## Configuring the Project
|
||||||
|
|
||||||
`make menuconfig`
|
`idf.py menuconfig`
|
||||||
|
|
||||||
* Opens a text-based configuration menu for the project.
|
* Opens a text-based configuration menu for the project.
|
||||||
* Use up & down arrow keys to navigate the menu.
|
* Use up & down arrow keys to navigate the menu.
|
||||||
|
@ -41,76 +57,48 @@ Once done configuring, press Escape multiple times to exit and say "Yes" to save
|
||||||
|
|
||||||
## Compiling the Project
|
## Compiling the Project
|
||||||
|
|
||||||
`make -j4 all`
|
`idf.py build`
|
||||||
|
|
||||||
... will compile app, bootloader and generate a partition table based on the config.
|
... will compile app, bootloader and generate a partition table based on the config.
|
||||||
|
|
||||||
NOTE: The `-j4` option causes `make` to run 4 parallel jobs. This is much faster than the default single job. The recommended number to pass to this option is `-j(number of CPUs + 1)`.
|
|
||||||
|
|
||||||
## Flashing the Project
|
## Flashing the Project
|
||||||
|
|
||||||
When the build finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this automatically by running:
|
When the build finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this automatically by running:
|
||||||
|
|
||||||
`make -j4 flash`
|
`idf.py -p PORT flash`
|
||||||
|
|
||||||
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
|
Replace PORT with the name of your serial port (like `COM3` on Windows, `/dev/ttyUSB0` on Linux, or `/dev/cu.usbserial-X` on MacOS. If the `-p` option is left out, `idf.py flash` will try to flash the first available serial port.
|
||||||
|
|
||||||
You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
|
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `idf.py menuconfig`.
|
||||||
|
|
||||||
|
You don't need to run `idf.py build` before running `idf.py flash`, `idf.py flash` will automatically rebuild anything which needs it.
|
||||||
|
|
||||||
## Viewing Serial Output
|
## Viewing Serial Output
|
||||||
|
|
||||||
The `make monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
|
The `idf.py monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
|
||||||
|
|
||||||
Exit the monitor by typing Ctrl-].
|
Exit the monitor by typing Ctrl-].
|
||||||
|
|
||||||
To build, flash and monitor output in one pass, you can run:
|
To build, flash and monitor output in one pass, you can run:
|
||||||
|
|
||||||
`make -j4 flash monitor`
|
`idf.py flash monitor`
|
||||||
|
|
||||||
## Compiling & Flashing Only the App
|
## Compiling & Flashing Only the App
|
||||||
|
|
||||||
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
|
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
|
||||||
|
|
||||||
* `make app` - build just the app.
|
* `idf.py app` - build just the app.
|
||||||
* `make app-flash` - flash just the app.
|
* `idf.py app-flash` - flash just the app.
|
||||||
|
|
||||||
`make app-flash` will automatically rebuild the app if any source files have changed.
|
`idf.py app-flash` will automatically rebuild the app if any source files have changed.
|
||||||
|
|
||||||
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
|
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
|
||||||
|
|
||||||
## Parallel Builds
|
|
||||||
|
|
||||||
ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to the number of CPU cores in your system, plus one.)
|
|
||||||
|
|
||||||
Multiple make functions can be combined into one. For example: to build the app & bootloader using 5 jobs in parallel, then flash everything, and then display serial output from the ESP32 run:
|
|
||||||
|
|
||||||
```
|
|
||||||
make -j5 flash monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## The Partition Table
|
|
||||||
|
|
||||||
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
|
|
||||||
|
|
||||||
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x8000 in the flash.
|
|
||||||
|
|
||||||
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
|
|
||||||
|
|
||||||
The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
|
|
||||||
|
|
||||||
* "Single factory app, no OTA"
|
|
||||||
* "Factory app, two OTA definitions"
|
|
||||||
|
|
||||||
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
|
|
||||||
|
|
||||||
For more details about partition tables and how to create custom variations, view the [`docs/en/api-guides/partition-tables.rst`](docs/en/api-guides/partition-tables.rst) file.
|
|
||||||
|
|
||||||
## Erasing Flash
|
## Erasing Flash
|
||||||
|
|
||||||
The `make flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `make erase_flash`.
|
The `idf.py flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `idf.py erase_flash`.
|
||||||
|
|
||||||
This can be combined with other targets, ie `make erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
|
This can be combined with other targets, ie `idf.py -p PORT erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
|
||||||
|
|
||||||
# Resources
|
# Resources
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
if [ -z ${IDF_PATH} ]; then
|
if [ -z ${IDF_PATH} ]; then
|
||||||
echo "IDF_PATH must be set before including this script."
|
echo "IDF_PATH must be set before including this script."
|
||||||
else
|
else
|
||||||
IDF_ADD_PATHS_EXTRAS=
|
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool"
|
||||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/esptool_py/esptool"
|
|
||||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/espcoredump"
|
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/espcoredump"
|
||||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/partition_table/"
|
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/partition_table/"
|
||||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/tools/"
|
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/tools/"
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
set(COMPONENT_SRCS "app_trace.c"
|
set(srcs
|
||||||
|
"app_trace.c"
|
||||||
"app_trace_util.c"
|
"app_trace_util.c"
|
||||||
"host_file_io.c"
|
"host_file_io.c"
|
||||||
"gcov/gcov_rtio.c")
|
"gcov/gcov_rtio.c")
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
|
||||||
|
set(include_dirs "include")
|
||||||
|
|
||||||
if(CONFIG_SYSVIEW_ENABLE)
|
if(CONFIG_SYSVIEW_ENABLE)
|
||||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS
|
list(APPEND include_dirs
|
||||||
sys_view/Config
|
sys_view/Config
|
||||||
sys_view/SEGGER
|
sys_view/SEGGER
|
||||||
sys_view/Sample/OS)
|
sys_view/Sample/OS)
|
||||||
|
|
||||||
list(APPEND COMPONENT_SRCS "sys_view/SEGGER/SEGGER_SYSVIEW.c"
|
list(APPEND srcs
|
||||||
|
"sys_view/SEGGER/SEGGER_SYSVIEW.c"
|
||||||
"sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c"
|
"sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c"
|
||||||
"sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c"
|
"sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c"
|
||||||
"sys_view/esp32/SEGGER_RTT_esp32.c"
|
"sys_view/esp32/SEGGER_RTT_esp32.c"
|
||||||
|
@ -19,16 +22,15 @@ if(CONFIG_SYSVIEW_ENABLE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_HEAP_TRACING_TOHOST)
|
if(CONFIG_HEAP_TRACING_TOHOST)
|
||||||
list(APPEND COMPONENT_SRCS "heap_trace_tohost.c")
|
list(APPEND srcs "heap_trace_tohost.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(COMPONENT_REQUIRES)
|
idf_component_register(SRCS "${srcs}"
|
||||||
set(COMPONENT_PRIV_REQUIRES heap soc)
|
INCLUDE_DIRS "${include_dirs}"
|
||||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
PRIV_REQUIRES soc
|
||||||
|
LDFRAGMENTS linker.lf)
|
||||||
register_component()
|
|
||||||
|
|
||||||
# disable --coverage for this component, as it is used as transport
|
# disable --coverage for this component, as it is used as transport
|
||||||
# for gcov
|
# for gcov
|
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
|
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
|
||||||
target_link_libraries(${COMPONENT_LIB} gcov ${LIBC} ${LIBM} gcc)
|
target_link_libraries(${COMPONENT_LIB} PUBLIC gcov ${LIBC} ${LIBM} gcc)
|
||||||
|
|
23
components/app_trace/project_include.cmake
Normal file
23
components/app_trace/project_include.cmake
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# idf_create_lcov_report
|
||||||
|
#
|
||||||
|
# Create coverage report.
|
||||||
|
function(idf_create_coverage_report report_dir)
|
||||||
|
set(gcov_tool ${CONFIG_SDK_TOOLPREFIX}gcov)
|
||||||
|
idf_build_get_property(project_name PROJECT_NAME)
|
||||||
|
|
||||||
|
add_custom_target(lcov-report
|
||||||
|
COMMENT "Generating coverage report in: ${report_dir}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Using gcov: ${gcov_tool}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${report_dir}/html
|
||||||
|
COMMAND lcov --gcov-tool ${gcov_tool} -c -d ${CMAKE_CURRENT_BINARY_DIR} -o ${report_dir}/${project_name}.info
|
||||||
|
COMMAND genhtml -o ${report_dir}/html ${report_dir}/${project_name}.info)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# idf_clean_coverage_report
|
||||||
|
#
|
||||||
|
# Clean coverage report.
|
||||||
|
function(idf_clean_coverage_report report_dir)
|
||||||
|
add_custom_target(cov-data-clean
|
||||||
|
COMMENT "Clean coverage report in: ${report_dir}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${report_dir})
|
||||||
|
endfunction()
|
|
@ -1,6 +1,3 @@
|
||||||
set(COMPONENT_SRCDIRS ".")
|
idf_component_register(SRC_DIRS "."
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES unity)
|
||||||
set(COMPONENT_REQUIRES unity)
|
|
||||||
|
|
||||||
register_component()
|
|
|
@ -1,15 +1,11 @@
|
||||||
set(COMPONENT_SRCS "esp_ota_ops.c"
|
idf_component_register(SRCS "esp_ota_ops.c"
|
||||||
"esp_app_desc.c")
|
"esp_app_desc.c"
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
INCLUDE_DIRS "include"
|
||||||
|
REQUIRES spi_flash partition_table bootloader_support)
|
||||||
set(COMPONENT_REQUIRES spi_flash partition_table bootloader_support)
|
|
||||||
set(COMPONENT_PRIV_REQUIRES)
|
|
||||||
|
|
||||||
register_component()
|
|
||||||
|
|
||||||
# esp_app_desc structure is added as an undefined symbol because otherwise the
|
# esp_app_desc structure is added as an undefined symbol because otherwise the
|
||||||
# linker will ignore this structure as it has no other files depending on it.
|
# linker will ignore this structure as it has no other files depending on it.
|
||||||
target_link_libraries(${COMPONENT_LIB} "-u esp_app_desc")
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
|
||||||
|
|
||||||
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
||||||
idf_build_get_property(project_ver PROJECT_VER)
|
idf_build_get_property(project_ver PROJECT_VER)
|
||||||
|
@ -34,21 +30,27 @@ if(NOT BOOTLOADER_BUILD)
|
||||||
idf_build_get_property(idf_path IDF_PATH)
|
idf_build_get_property(idf_path IDF_PATH)
|
||||||
idf_build_get_property(python PYTHON)
|
idf_build_get_property(python PYTHON)
|
||||||
add_custom_command(OUTPUT ${blank_otadata_file}
|
add_custom_command(OUTPUT ${blank_otadata_file}
|
||||||
COMMAND ${python} ${idf_path}/components/partition_table/parttool.py
|
COMMAND ${python} ${idf_path}/components/partition_table/gen_empty_partition.py
|
||||||
--partition-type data --partition-subtype ota -q
|
${otadata_size} ${blank_otadata_file})
|
||||||
--partition-table-file ${PARTITION_CSV_PATH} generate_blank_partition_file
|
|
||||||
--output ${blank_otadata_file})
|
|
||||||
|
|
||||||
add_custom_target(blank_ota_data ALL DEPENDS ${blank_otadata_file})
|
add_custom_target(blank_ota_data ALL DEPENDS ${blank_otadata_file})
|
||||||
add_dependencies(app blank_ota_data)
|
add_dependencies(flash blank_ota_data)
|
||||||
|
|
||||||
set(otatool_py ${python} ${COMPONENT_DIR}/otatool.py)
|
set(otatool_py ${python} ${COMPONENT_DIR}/otatool.py)
|
||||||
|
|
||||||
|
set(esptool_args --esptool-args before=${CONFIG_ESPTOOLPY_BEFORE} after=${CONFIG_ESPTOOLPY_AFTER})
|
||||||
|
|
||||||
add_custom_target(read_otadata DEPENDS "${PARTITION_CSV_PATH}"
|
add_custom_target(read_otadata DEPENDS "${PARTITION_CSV_PATH}"
|
||||||
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} read_otadata)
|
COMMAND ${otatool_py} ${esptool_args}
|
||||||
|
--partition-table-file ${PARTITION_CSV_PATH}
|
||||||
|
--partition-table-offset ${PARTITION_TABLE_OFFSET}
|
||||||
|
read_otadata)
|
||||||
|
|
||||||
add_custom_target(erase_otadata DEPENDS "${PARTITION_CSV_PATH}"
|
add_custom_target(erase_otadata DEPENDS "${PARTITION_CSV_PATH}"
|
||||||
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} erase_otadata)
|
COMMAND ${otatool_py} ${esptool_args}
|
||||||
|
--partition-table-file ${PARTITION_CSV_PATH}
|
||||||
|
--partition-table-offset ${PARTITION_TABLE_OFFSET}
|
||||||
|
erase_otadata)
|
||||||
|
|
||||||
esptool_py_flash_project_args(otadata ${otadata_offset} "${blank_otadata_file}" FLASH_IN_PROJECT)
|
esptool_py_flash_project_args(otadata ${otadata_offset} "${blank_otadata_file}" FLASH_IN_PROJECT)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -17,8 +17,7 @@ endif
|
||||||
|
|
||||||
$(BLANK_OTA_DATA_FILE): partition_table_get_info $(PARTITION_TABLE_CSV_PATH) | check_python_dependencies
|
$(BLANK_OTA_DATA_FILE): partition_table_get_info $(PARTITION_TABLE_CSV_PATH) | check_python_dependencies
|
||||||
$(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
$(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||||
$(PARTTOOL_PY) --partition-type data --partition-subtype ota --partition-table-file $(PARTITION_TABLE_CSV_PATH) \
|
$(PYTHON) $(IDF_PATH)/components/partition_table/gen_empty_partition.py $(OTA_DATA_SIZE) $(BLANK_OTA_DATA_FILE); \
|
||||||
-q generate_blank_partition_file --output $(BLANK_OTA_DATA_FILE); \
|
|
||||||
fi; )
|
fi; )
|
||||||
$(eval BLANK_OTA_DATA_FILE = $(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
$(eval BLANK_OTA_DATA_FILE = $(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||||
echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
|
echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
|
||||||
|
@ -29,17 +28,26 @@ blank_ota_data: $(BLANK_OTA_DATA_FILE)
|
||||||
# expand to empty values.
|
# expand to empty values.
|
||||||
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
|
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
|
||||||
|
|
||||||
|
ESPTOOL_ARGS := --esptool-args port=$(CONFIG_ESPTOOLPY_PORT) baud=$(CONFIG_ESPTOOLPY_BAUD) before=$(CONFIG_ESPTOOLPY_BEFORE) after=$(CONFIG_ESPTOOLPY_AFTER)
|
||||||
|
|
||||||
erase_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
erase_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_CSV_PATH) erase_otadata
|
$(OTATOOL_PY) $(ESPTOOL_ARGS) --partition-table-file $(PARTITION_TABLE_CSV_PATH) \
|
||||||
|
--partition-table-offset $(PARTITION_TABLE_OFFSET) \
|
||||||
|
erase_otadata
|
||||||
|
|
||||||
read_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
read_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_CSV_PATH) read_otadata
|
$(OTATOOL_PY) $(ESPTOOL_ARGS) --partition-table-file $(PARTITION_TABLE_CSV_PATH) \
|
||||||
|
--partition-table-offset $(partition_table_offset) \
|
||||||
|
read_otadata
|
||||||
|
|
||||||
erase_ota: erase_otadata
|
erase_ota: erase_otadata
|
||||||
@echo "WARNING: erase_ota is deprecated. Use erase_otadata instead."
|
@echo "WARNING: erase_ota is deprecated. Use erase_otadata instead."
|
||||||
|
|
||||||
all: blank_ota_data
|
all: blank_ota_data
|
||||||
flash: blank_ota_data
|
flash: blank_ota_data
|
||||||
|
ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
|
encrypted-flash: blank_ota_data
|
||||||
|
endif
|
||||||
|
|
||||||
TMP_DEFINES := $(BUILD_DIR_BASE)/app_update/tmp_cppflags.txt
|
TMP_DEFINES := $(BUILD_DIR_BASE)/app_update/tmp_cppflags.txt
|
||||||
export TMP_DEFINES
|
export TMP_DEFINES
|
||||||
|
|
|
@ -21,16 +21,20 @@ import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import binascii
|
import binascii
|
||||||
import subprocess
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import collections
|
import collections
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
__version__ = '1.0'
|
try:
|
||||||
|
from parttool import PartitionName, PartitionType, ParttoolTarget, PARTITION_TABLE_OFFSET
|
||||||
|
except ImportError:
|
||||||
|
COMPONENTS_PATH = os.path.expandvars(os.path.join("$IDF_PATH", "components"))
|
||||||
|
PARTTOOL_DIR = os.path.join(COMPONENTS_PATH, "partition_table")
|
||||||
|
|
||||||
IDF_COMPONENTS_PATH = os.path.expandvars(os.path.join("$IDF_PATH", "components"))
|
sys.path.append(PARTTOOL_DIR)
|
||||||
|
from parttool import PartitionName, PartitionType, ParttoolTarget, PARTITION_TABLE_OFFSET
|
||||||
|
|
||||||
PARTTOOL_PY = os.path.join(IDF_COMPONENTS_PATH, "partition_table", "parttool.py")
|
__version__ = '2.0'
|
||||||
|
|
||||||
SPI_FLASH_SEC_SIZE = 0x2000
|
SPI_FLASH_SEC_SIZE = 0x2000
|
||||||
|
|
||||||
|
@ -42,121 +46,72 @@ def status(msg):
|
||||||
print(msg)
|
print(msg)
|
||||||
|
|
||||||
|
|
||||||
def _invoke_parttool(parttool_args, args, output=False, partition=None):
|
class OtatoolTarget():
|
||||||
invoke_args = []
|
|
||||||
|
|
||||||
if partition:
|
OTADATA_PARTITION = PartitionType("data", "ota")
|
||||||
invoke_args += [sys.executable, PARTTOOL_PY] + partition
|
|
||||||
else:
|
|
||||||
invoke_args += [sys.executable, PARTTOOL_PY, "--partition-type", "data", "--partition-subtype", "ota"]
|
|
||||||
|
|
||||||
if quiet:
|
def __init__(self, port=None, baud=None, partition_table_offset=PARTITION_TABLE_OFFSET, partition_table_file=None,
|
||||||
invoke_args += ["-q"]
|
spi_flash_sec_size=SPI_FLASH_SEC_SIZE, esptool_args=[], esptool_write_args=[],
|
||||||
|
esptool_read_args=[], esptool_erase_args=[]):
|
||||||
if args.port != "":
|
self.target = ParttoolTarget(port, baud, partition_table_offset, partition_table_file, esptool_args,
|
||||||
invoke_args += ["--port", args.port]
|
esptool_write_args, esptool_read_args, esptool_erase_args)
|
||||||
|
self.spi_flash_sec_size = spi_flash_sec_size
|
||||||
if args.partition_table_file:
|
|
||||||
invoke_args += ["--partition-table-file", args.partition_table_file]
|
|
||||||
|
|
||||||
if args.partition_table_offset:
|
|
||||||
invoke_args += ["--partition-table-offset", args.partition_table_offset]
|
|
||||||
|
|
||||||
invoke_args += parttool_args
|
|
||||||
|
|
||||||
if output:
|
|
||||||
return subprocess.check_output(invoke_args)
|
|
||||||
else:
|
|
||||||
return subprocess.check_call(invoke_args)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_otadata_contents(args, check=True):
|
|
||||||
global quiet
|
|
||||||
|
|
||||||
if check:
|
|
||||||
check_args = ["get_partition_info", "--info", "offset", "size"]
|
|
||||||
|
|
||||||
quiet = True
|
|
||||||
output = _invoke_parttool(check_args, args, True).split(b" ")
|
|
||||||
quiet = args.quiet
|
|
||||||
|
|
||||||
if not output:
|
|
||||||
raise RuntimeError("No ota_data partition found")
|
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
|
||||||
f_name = f.name
|
|
||||||
|
|
||||||
|
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||||
|
temp_file.close()
|
||||||
try:
|
try:
|
||||||
invoke_args = ["read_partition", "--output", f_name]
|
self.target.read_partition(OtatoolTarget.OTADATA_PARTITION, temp_file.name)
|
||||||
_invoke_parttool(invoke_args, args)
|
with open(temp_file.name, "rb") as f:
|
||||||
with open(f_name, "rb") as f:
|
self.otadata = f.read()
|
||||||
contents = f.read()
|
except Exception:
|
||||||
|
self.otadata = None
|
||||||
finally:
|
finally:
|
||||||
os.unlink(f_name)
|
os.unlink(temp_file.name)
|
||||||
|
|
||||||
return contents
|
def _check_otadata_partition(self):
|
||||||
|
if not self.otadata:
|
||||||
|
raise Exception("No otadata partition found")
|
||||||
|
|
||||||
|
def erase_otadata(self):
|
||||||
|
self._check_otadata_partition()
|
||||||
|
self.target.erase_partition(OtatoolTarget.OTADATA_PARTITION)
|
||||||
|
|
||||||
def _get_otadata_status(otadata_contents):
|
def _get_otadata_info(self):
|
||||||
status = []
|
info = []
|
||||||
|
|
||||||
otadata_status = collections.namedtuple("otadata_status", "seq crc")
|
otadata_info = collections.namedtuple("otadata_info", "seq crc")
|
||||||
|
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
start = i * (SPI_FLASH_SEC_SIZE >> 1)
|
start = i * (self.spi_flash_sec_size >> 1)
|
||||||
|
|
||||||
seq = bytearray(otadata_contents[start:start + 4])
|
seq = bytearray(self.otadata[start:start + 4])
|
||||||
crc = bytearray(otadata_contents[start + 28:start + 32])
|
crc = bytearray(self.otadata[start + 28:start + 32])
|
||||||
|
|
||||||
seq = struct.unpack('>I', seq)
|
seq = struct.unpack('>I', seq)
|
||||||
crc = struct.unpack('>I', crc)
|
crc = struct.unpack('>I', crc)
|
||||||
|
|
||||||
status.append(otadata_status(seq[0], crc[0]))
|
info.append(otadata_info(seq[0], crc[0]))
|
||||||
|
|
||||||
return status
|
return info
|
||||||
|
|
||||||
|
def _get_partition_id_from_ota_id(self, ota_id):
|
||||||
|
if isinstance(ota_id, int):
|
||||||
|
return PartitionType("app", "ota_" + str(ota_id))
|
||||||
|
else:
|
||||||
|
return PartitionName(ota_id)
|
||||||
|
|
||||||
def read_otadata(args):
|
def switch_ota_partition(self, ota_id):
|
||||||
status("Reading ota_data partition contents...")
|
self._check_otadata_partition()
|
||||||
otadata_info = _get_otadata_contents(args)
|
|
||||||
otadata_info = _get_otadata_status(otadata_info)
|
|
||||||
|
|
||||||
print(otadata_info)
|
sys.path.append(PARTTOOL_DIR)
|
||||||
|
|
||||||
print("\t\t{:11}\t{:8s}|\t{:8s}\t{:8s}".format("OTA_SEQ", "CRC", "OTA_SEQ", "CRC"))
|
|
||||||
print("Firmware: 0x{:8x} \t 0x{:8x} |\t0x{:8x} \t 0x{:8x}".format(otadata_info[0].seq, otadata_info[0].crc,
|
|
||||||
otadata_info[1].seq, otadata_info[1].crc))
|
|
||||||
|
|
||||||
|
|
||||||
def erase_otadata(args):
|
|
||||||
status("Erasing ota_data partition contents...")
|
|
||||||
_invoke_parttool(["erase_partition"], args)
|
|
||||||
status("Erased ota_data partition contents")
|
|
||||||
|
|
||||||
|
|
||||||
def switch_otadata(args):
|
|
||||||
sys.path.append(os.path.join(IDF_COMPONENTS_PATH, "partition_table"))
|
|
||||||
import gen_esp32part as gen
|
import gen_esp32part as gen
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
def is_otadata_info_valid(status):
|
||||||
f_name = f.name
|
|
||||||
|
|
||||||
try:
|
|
||||||
def is_otadata_status_valid(status):
|
|
||||||
seq = status.seq % (1 << 32)
|
seq = status.seq % (1 << 32)
|
||||||
crc = hex(binascii.crc32(struct.pack("I", seq), 0xFFFFFFFF) % (1 << 32))
|
crc = hex(binascii.crc32(struct.pack("I", seq), 0xFFFFFFFF) % (1 << 32))
|
||||||
return seq < (int('0xFFFFFFFF', 16) % (1 << 32)) and status.crc == crc
|
return seq < (int('0xFFFFFFFF', 16) % (1 << 32)) and status.crc == crc
|
||||||
|
|
||||||
status("Looking for ota app partitions...")
|
partition_table = self.target.partition_table
|
||||||
|
|
||||||
# In order to get the number of ota app partitions, we need the partition table
|
|
||||||
partition_table = None
|
|
||||||
invoke_args = ["get_partition_info", "--table", f_name]
|
|
||||||
|
|
||||||
_invoke_parttool(invoke_args, args)
|
|
||||||
|
|
||||||
partition_table = open(f_name, "rb").read()
|
|
||||||
partition_table = gen.PartitionTable.from_binary(partition_table)
|
|
||||||
|
|
||||||
ota_partitions = list()
|
ota_partitions = list()
|
||||||
|
|
||||||
|
@ -171,39 +126,36 @@ def switch_otadata(args):
|
||||||
ota_partitions = sorted(ota_partitions, key=lambda p: p.subtype)
|
ota_partitions = sorted(ota_partitions, key=lambda p: p.subtype)
|
||||||
|
|
||||||
if not ota_partitions:
|
if not ota_partitions:
|
||||||
raise RuntimeError("No ota app partitions found")
|
raise Exception("No ota app partitions found")
|
||||||
|
|
||||||
status("Verifying partition to switch to exists...")
|
|
||||||
|
|
||||||
# Look for the app partition to switch to
|
# Look for the app partition to switch to
|
||||||
ota_partition_next = None
|
ota_partition_next = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if args.name:
|
if isinstance(ota_id, int):
|
||||||
ota_partition_next = filter(lambda p: p.name == args.name, ota_partitions)
|
ota_partition_next = filter(lambda p: p.subtype - gen.MIN_PARTITION_SUBTYPE_APP_OTA == ota_id, ota_partitions)
|
||||||
else:
|
else:
|
||||||
ota_partition_next = filter(lambda p: p.subtype - gen.MIN_PARTITION_SUBTYPE_APP_OTA == args.slot, ota_partitions)
|
ota_partition_next = filter(lambda p: p.name == ota_id, ota_partitions)
|
||||||
|
|
||||||
ota_partition_next = list(ota_partition_next)[0]
|
ota_partition_next = list(ota_partition_next)[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
raise RuntimeError("Partition to switch to not found")
|
raise Exception("Partition to switch to not found")
|
||||||
|
|
||||||
otadata_contents = _get_otadata_contents(args)
|
otadata_info = self._get_otadata_info()
|
||||||
otadata_status = _get_otadata_status(otadata_contents)
|
|
||||||
|
|
||||||
# Find the copy to base the computation for ota sequence number on
|
# Find the copy to base the computation for ota sequence number on
|
||||||
otadata_compute_base = -1
|
otadata_compute_base = -1
|
||||||
|
|
||||||
# Both are valid, take the max as computation base
|
# Both are valid, take the max as computation base
|
||||||
if is_otadata_status_valid(otadata_status[0]) and is_otadata_status_valid(otadata_status[1]):
|
if is_otadata_info_valid(otadata_info[0]) and is_otadata_info_valid(otadata_info[1]):
|
||||||
if otadata_status[0].seq >= otadata_status[1].seq:
|
if otadata_info[0].seq >= otadata_info[1].seq:
|
||||||
otadata_compute_base = 0
|
otadata_compute_base = 0
|
||||||
else:
|
else:
|
||||||
otadata_compute_base = 1
|
otadata_compute_base = 1
|
||||||
# Only one copy is valid, use that
|
# Only one copy is valid, use that
|
||||||
elif is_otadata_status_valid(otadata_status[0]):
|
elif is_otadata_info_valid(otadata_info[0]):
|
||||||
otadata_compute_base = 0
|
otadata_compute_base = 0
|
||||||
elif is_otadata_status_valid(otadata_status[1]):
|
elif is_otadata_info_valid(otadata_info[1]):
|
||||||
otadata_compute_base = 1
|
otadata_compute_base = 1
|
||||||
# Both are invalid (could be initial state - all 0xFF's)
|
# Both are invalid (could be initial state - all 0xFF's)
|
||||||
else:
|
else:
|
||||||
|
@ -216,7 +168,7 @@ def switch_otadata(args):
|
||||||
|
|
||||||
# Find the next ota sequence number
|
# Find the next ota sequence number
|
||||||
if otadata_compute_base == 0 or otadata_compute_base == 1:
|
if otadata_compute_base == 0 or otadata_compute_base == 1:
|
||||||
base_seq = otadata_status[otadata_compute_base].seq % (1 << 32)
|
base_seq = otadata_info[otadata_compute_base].seq % (1 << 32)
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
while base_seq > target_seq % ota_partitions_num + i * ota_partitions_num:
|
while base_seq > target_seq % ota_partitions_num + i * ota_partitions_num:
|
||||||
|
@ -231,10 +183,14 @@ def switch_otadata(args):
|
||||||
ota_seq_crc_next = binascii.crc32(ota_seq_next, 0xFFFFFFFF) % (1 << 32)
|
ota_seq_crc_next = binascii.crc32(ota_seq_next, 0xFFFFFFFF) % (1 << 32)
|
||||||
ota_seq_crc_next = struct.pack("I", ota_seq_crc_next)
|
ota_seq_crc_next = struct.pack("I", ota_seq_crc_next)
|
||||||
|
|
||||||
with open(f_name, "wb") as otadata_next_file:
|
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||||
start = (1 if otadata_compute_base == 0 else 0) * (SPI_FLASH_SEC_SIZE >> 1)
|
temp_file.close()
|
||||||
|
|
||||||
otadata_next_file.write(otadata_contents)
|
try:
|
||||||
|
with open(temp_file.name, "wb") as otadata_next_file:
|
||||||
|
start = (1 if otadata_compute_base == 0 else 0) * (self.spi_flash_sec_size >> 1)
|
||||||
|
|
||||||
|
otadata_next_file.write(self.otadata)
|
||||||
|
|
||||||
otadata_next_file.seek(start)
|
otadata_next_file.seek(start)
|
||||||
otadata_next_file.write(ota_seq_next)
|
otadata_next_file.write(ota_seq_next)
|
||||||
|
@ -244,34 +200,51 @@ def switch_otadata(args):
|
||||||
|
|
||||||
otadata_next_file.flush()
|
otadata_next_file.flush()
|
||||||
|
|
||||||
_invoke_parttool(["write_partition", "--input", f_name], args)
|
self.target.write_partition(OtatoolTarget.OTADATA_PARTITION, temp_file.name)
|
||||||
status("Updated ota_data partition")
|
|
||||||
finally:
|
finally:
|
||||||
os.unlink(f_name)
|
os.unlink(temp_file.name)
|
||||||
|
|
||||||
|
def read_ota_partition(self, ota_id, output):
|
||||||
|
self.target.read_partition(self._get_partition_id_from_ota_id(ota_id), output)
|
||||||
|
|
||||||
|
def write_ota_partition(self, ota_id, input):
|
||||||
|
self.target.write_partition(self._get_partition_id_from_ota_id(ota_id), input)
|
||||||
|
|
||||||
|
def erase_ota_partition(self, ota_id):
|
||||||
|
self.target.erase_partition(self._get_partition_id_from_ota_id(ota_id))
|
||||||
|
|
||||||
|
|
||||||
def _get_partition_specifier(args):
|
def _read_otadata(target):
|
||||||
if args.name:
|
target._check_otadata_partition()
|
||||||
return ["--partition-name", args.name]
|
|
||||||
else:
|
otadata_info = target._get_otadata_info()
|
||||||
return ["--partition-type", "app", "--partition-subtype", "ota_" + str(args.slot)]
|
|
||||||
|
print(" {:8s} \t {:8s} | \t {:8s} \t {:8s}".format("OTA_SEQ", "CRC", "OTA_SEQ", "CRC"))
|
||||||
|
print("Firmware: 0x{:8x} \t0x{:8x} | \t0x{:8x} \t 0x{:8x}".format(otadata_info[0].seq, otadata_info[0].crc,
|
||||||
|
otadata_info[1].seq, otadata_info[1].crc))
|
||||||
|
|
||||||
|
|
||||||
def read_ota_partition(args):
|
def _erase_otadata(target):
|
||||||
invoke_args = ["read_partition", "--output", args.output]
|
target.erase_otadata()
|
||||||
_invoke_parttool(invoke_args, args, partition=_get_partition_specifier(args))
|
status("Erased ota_data partition contents")
|
||||||
status("Read ota partition contents to file {}".format(args.output))
|
|
||||||
|
|
||||||
|
|
||||||
def write_ota_partition(args):
|
def _switch_ota_partition(target, ota_id):
|
||||||
invoke_args = ["write_partition", "--input", args.input]
|
target.switch_ota_partition(ota_id)
|
||||||
_invoke_parttool(invoke_args, args, partition=_get_partition_specifier(args))
|
|
||||||
status("Written contents of file {} to ota partition".format(args.input))
|
|
||||||
|
|
||||||
|
|
||||||
def erase_ota_partition(args):
|
def _read_ota_partition(target, ota_id, output):
|
||||||
invoke_args = ["erase_partition"]
|
target.read_ota_partition(ota_id, output)
|
||||||
_invoke_parttool(invoke_args, args, partition=_get_partition_specifier(args))
|
status("Read ota partition contents to file {}".format(output))
|
||||||
|
|
||||||
|
|
||||||
|
def _write_ota_partition(target, ota_id, input):
|
||||||
|
target.write_ota_partition(ota_id, input)
|
||||||
|
status("Written contents of file {} to ota partition".format(input))
|
||||||
|
|
||||||
|
|
||||||
|
def _erase_ota_partition(target, ota_id):
|
||||||
|
target.erase_ota_partition(ota_id)
|
||||||
status("Erased contents of ota partition")
|
status("Erased contents of ota partition")
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,20 +254,29 @@ def main():
|
||||||
parser = argparse.ArgumentParser("ESP-IDF OTA Partitions Tool")
|
parser = argparse.ArgumentParser("ESP-IDF OTA Partitions Tool")
|
||||||
|
|
||||||
parser.add_argument("--quiet", "-q", help="suppress stderr messages", action="store_true")
|
parser.add_argument("--quiet", "-q", help="suppress stderr messages", action="store_true")
|
||||||
|
parser.add_argument("--esptool-args", help="additional main arguments for esptool", nargs="+")
|
||||||
|
parser.add_argument("--esptool-write-args", help="additional subcommand arguments for esptool write_flash", nargs="+")
|
||||||
|
parser.add_argument("--esptool-read-args", help="additional subcommand arguments for esptool read_flash", nargs="+")
|
||||||
|
parser.add_argument("--esptool-erase-args", help="additional subcommand arguments for esptool erase_region", nargs="+")
|
||||||
|
|
||||||
# There are two possible sources for the partition table: a device attached to the host
|
# There are two possible sources for the partition table: a device attached to the host
|
||||||
# or a partition table CSV/binary file. These sources are mutually exclusive.
|
# or a partition table CSV/binary file. These sources are mutually exclusive.
|
||||||
partition_table_info_source_args = parser.add_mutually_exclusive_group()
|
parser.add_argument("--port", "-p", help="port where the device to read the partition table from is attached")
|
||||||
|
|
||||||
partition_table_info_source_args.add_argument("--port", "-p", help="port where the device to read the partition table from is attached", default="")
|
parser.add_argument("--baud", "-b", help="baudrate to use", type=int)
|
||||||
partition_table_info_source_args.add_argument("--partition-table-file", "-f", help="file (CSV/binary) to read the partition table from", default="")
|
|
||||||
|
|
||||||
parser.add_argument("--partition-table-offset", "-o", help="offset to read the partition table from", default="0x8000")
|
parser.add_argument("--partition-table-offset", "-o", help="offset to read the partition table from", type=str)
|
||||||
|
|
||||||
|
parser.add_argument("--partition-table-file", "-f", help="file (CSV/binary) to read the partition table from; \
|
||||||
|
overrides device attached to specified port as the partition table source when defined")
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(dest="operation", help="run otatool -h for additional help")
|
subparsers = parser.add_subparsers(dest="operation", help="run otatool -h for additional help")
|
||||||
|
|
||||||
|
spi_flash_sec_size = argparse.ArgumentParser(add_help=False)
|
||||||
|
spi_flash_sec_size.add_argument("--spi-flash-sec-size", help="value of SPI_FLASH_SEC_SIZE macro", type=str)
|
||||||
|
|
||||||
# Specify the supported operations
|
# Specify the supported operations
|
||||||
subparsers.add_parser("read_otadata", help="read otadata partition")
|
subparsers.add_parser("read_otadata", help="read otadata partition", parents=[spi_flash_sec_size])
|
||||||
subparsers.add_parser("erase_otadata", help="erase otadata partition")
|
subparsers.add_parser("erase_otadata", help="erase otadata partition")
|
||||||
|
|
||||||
slot_or_name_parser = argparse.ArgumentParser(add_help=False)
|
slot_or_name_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
@ -302,7 +284,7 @@ def main():
|
||||||
slot_or_name_parser_args.add_argument("--slot", help="slot number of the ota partition", type=int)
|
slot_or_name_parser_args.add_argument("--slot", help="slot number of the ota partition", type=int)
|
||||||
slot_or_name_parser_args.add_argument("--name", help="name of the ota partition")
|
slot_or_name_parser_args.add_argument("--name", help="name of the ota partition")
|
||||||
|
|
||||||
subparsers.add_parser("switch_otadata", help="switch otadata partition", parents=[slot_or_name_parser])
|
subparsers.add_parser("switch_ota_partition", help="switch otadata partition", parents=[slot_or_name_parser, spi_flash_sec_size])
|
||||||
|
|
||||||
read_ota_partition_subparser = subparsers.add_parser("read_ota_partition", help="read contents of an ota partition", parents=[slot_or_name_parser])
|
read_ota_partition_subparser = subparsers.add_parser("read_ota_partition", help="read contents of an ota partition", parents=[slot_or_name_parser])
|
||||||
read_ota_partition_subparser.add_argument("--output", help="file to write the contents of the ota partition to")
|
read_ota_partition_subparser.add_argument("--output", help="file to write the contents of the ota partition to")
|
||||||
|
@ -322,17 +304,84 @@ def main():
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Else execute the operation
|
target_args = {}
|
||||||
operation_func = globals()[args.operation]
|
|
||||||
|
if args.port:
|
||||||
|
target_args["port"] = args.port
|
||||||
|
|
||||||
|
if args.partition_table_file:
|
||||||
|
target_args["partition_table_file"] = args.partition_table_file
|
||||||
|
|
||||||
|
if args.partition_table_offset:
|
||||||
|
target_args["partition_table_offset"] = int(args.partition_table_offset, 0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if args.spi_flash_sec_size:
|
||||||
|
target_args["spi_flash_sec_size"] = int(args.spi_flash_sec_size, 0)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if args.esptool_args:
|
||||||
|
target_args["esptool_args"] = args.esptool_args
|
||||||
|
|
||||||
|
if args.esptool_write_args:
|
||||||
|
target_args["esptool_write_args"] = args.esptool_write_args
|
||||||
|
|
||||||
|
if args.esptool_read_args:
|
||||||
|
target_args["esptool_read_args"] = args.esptool_read_args
|
||||||
|
|
||||||
|
if args.esptool_erase_args:
|
||||||
|
target_args["esptool_erase_args"] = args.esptool_erase_args
|
||||||
|
|
||||||
|
if args.baud:
|
||||||
|
target_args["baud"] = args.baud
|
||||||
|
|
||||||
|
target = OtatoolTarget(**target_args)
|
||||||
|
|
||||||
|
# Create the operation table and execute the operation
|
||||||
|
common_args = {'target':target}
|
||||||
|
|
||||||
|
ota_id = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
if args.name is not None:
|
||||||
|
ota_id = ["name"]
|
||||||
|
else:
|
||||||
|
if args.slot is not None:
|
||||||
|
ota_id = ["slot"]
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
otatool_ops = {
|
||||||
|
'read_otadata':(_read_otadata, []),
|
||||||
|
'erase_otadata':(_erase_otadata, []),
|
||||||
|
'switch_ota_partition':(_switch_ota_partition, ota_id),
|
||||||
|
'read_ota_partition':(_read_ota_partition, ["output"] + ota_id),
|
||||||
|
'write_ota_partition':(_write_ota_partition, ["input"] + ota_id),
|
||||||
|
'erase_ota_partition':(_erase_ota_partition, ota_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
(op, op_args) = otatool_ops[args.operation]
|
||||||
|
|
||||||
|
for op_arg in op_args:
|
||||||
|
common_args.update({op_arg:vars(args)[op_arg]})
|
||||||
|
|
||||||
|
try:
|
||||||
|
common_args['ota_id'] = common_args.pop('name')
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
common_args['ota_id'] = common_args.pop('slot')
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
if quiet:
|
if quiet:
|
||||||
# If exceptions occur, suppress and exit quietly
|
# If exceptions occur, suppress and exit quietly
|
||||||
try:
|
try:
|
||||||
operation_func(args)
|
op(**common_args)
|
||||||
except Exception:
|
except Exception:
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
else:
|
else:
|
||||||
operation_func(args)
|
op(**common_args)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
set(COMPONENT_SRCDIRS ".")
|
idf_component_register(SRC_DIRS "."
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES unity test_utils app_update bootloader_support nvs_flash)
|
||||||
set(COMPONENT_REQUIRES unity test_utils app_update bootloader_support nvs_flash)
|
|
||||||
|
|
||||||
register_component()
|
|
|
@ -296,7 +296,7 @@ static void test_flow1(void)
|
||||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||||
// 4 Stage: run OTA1 -> check it -> copy OTA1 to OTA0 -> reboot --//--
|
// 4 Stage: run OTA1 -> check it -> copy OTA1 to OTA0 -> reboot --//--
|
||||||
// 5 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
// 5 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
||||||
|
|
||||||
static void test_flow2(void)
|
static void test_flow2(void)
|
||||||
{
|
{
|
||||||
|
@ -333,7 +333,7 @@ static void test_flow2(void)
|
||||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||||
// 3 Stage: run OTA0 -> check it -> corrupt ota data -> reboot --//--
|
// 3 Stage: run OTA0 -> check it -> corrupt ota data -> reboot --//--
|
||||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
||||||
|
|
||||||
static void test_flow3(void)
|
static void test_flow3(void)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +377,7 @@ static void test_flow3(void)
|
||||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||||
// 3 Stage: run OTA1 -> check it -> corrupt ota sector2 -> reboot --//--
|
// 3 Stage: run OTA1 -> check it -> corrupt ota sector2 -> reboot --//--
|
||||||
// 4 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
// 4 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
||||||
|
|
||||||
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
||||||
#define STORAGE_NAMESPACE "update_ota"
|
#define STORAGE_NAMESPACE "update_ota"
|
||||||
|
@ -444,7 +444,7 @@ static void test_flow4(void)
|
||||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||||
// 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
|
// 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
|
||||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
||||||
|
@ -487,7 +487,7 @@ static void test_flow5(void)
|
||||||
// 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
|
// 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
|
||||||
// 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
|
// 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
|
||||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const esp_partition_t* app_update(void)
|
static const esp_partition_t* app_update(void)
|
||||||
|
@ -581,7 +581,7 @@ static void test_rollback1_1(void)
|
||||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback() -> reboot --//--
|
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback() -> reboot --//--
|
||||||
// 4 Stage: run OTA0 -> check it -> esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
// 4 Stage: run OTA0 -> check it -> esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
|
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
|
||||||
|
|
||||||
static void test_rollback2(void)
|
static void test_rollback2(void)
|
||||||
{
|
{
|
||||||
|
@ -679,7 +679,7 @@ static void test_rollback2_1(void)
|
||||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback(), copy to next app slot -> reboot --//--
|
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback(), copy to next app slot -> reboot --//--
|
||||||
// 4 Stage: run OTA1 -> check it -> PENDING_VERIFY/esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
// 4 Stage: run OTA1 -> check it -> PENDING_VERIFY/esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||||
// 5 Stage: run OTA0(rollback) -> check it -> erase OTA_DATA for next tests -> PASS
|
// 5 Stage: run OTA0(rollback) -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
|
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
|
||||||
|
|
||||||
static void test_erase_last_app_flow(void)
|
static void test_erase_last_app_flow(void)
|
||||||
{
|
{
|
||||||
|
@ -730,4 +730,4 @@ static void test_erase_last_app_rollback(void)
|
||||||
// 3 Stage: run OTA0 -> check it -> copy factory to OTA1 -> reboot --//--
|
// 3 Stage: run OTA0 -> check it -> copy factory to OTA1 -> reboot --//--
|
||||||
// 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
|
// 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
|
||||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||||
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS asio/asio/include port/include)
|
idf_component_register(SRCS "asio/asio/src/asio.cpp"
|
||||||
set(COMPONENT_SRCS "asio/asio/src/asio.cpp")
|
INCLUDE_DIRS "asio/asio/include" "port/include"
|
||||||
|
REQUIRES lwip)
|
||||||
set(COMPONENT_REQUIRES lwip)
|
|
||||||
|
|
||||||
register_component()
|
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
register_component()
|
idf_component_register(PRIV_REQUIRES partition_table)
|
||||||
|
|
||||||
# Do not generate flash file when building bootloader or is in early expansion of the build
|
# Do not generate flash file when building bootloader or is in early expansion of the build
|
||||||
if(BOOTLOADER_BUILD)
|
if(BOOTLOADER_BUILD)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# When secure boot is enabled, do not flash bootloader along with invocation of `idf.py flash`
|
||||||
|
if(NOT CONFIG_SECURE_BOOT_ENABLED)
|
||||||
|
set(flash_bootloader FLASH_IN_PROJECT)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Set values used in flash_bootloader_args.in and generate flash file
|
# Set values used in flash_bootloader_args.in and generate flash file
|
||||||
# for bootloader
|
# for bootloader
|
||||||
set(BOOTLOADER_OFFSET 0x1000)
|
esptool_py_flash_project_args(bootloader 0x1000
|
||||||
esptool_py_flash_project_args(bootloader ${BOOTLOADER_OFFSET}
|
|
||||||
${BOOTLOADER_BUILD_DIR}/bootloader.bin
|
${BOOTLOADER_BUILD_DIR}/bootloader.bin
|
||||||
FLASH_IN_PROJECT
|
${flash_bootloader}
|
||||||
FLASH_FILE_TEMPLATE flash_bootloader_args.in)
|
FLASH_FILE_TEMPLATE flash_bootloader_args.in)
|
||||||
|
|
||||||
|
esptool_py_custom_target(bootloader-flash bootloader "bootloader")
|
||||||
|
add_dependencies(bootloader partition_table)
|
||||||
|
|
|
@ -409,7 +409,8 @@ menu "Security features"
|
||||||
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
|
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
|
||||||
system is complicated and not always possible.
|
system is complicated and not always possible.
|
||||||
|
|
||||||
Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html before enabling.
|
Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html
|
||||||
|
before enabling.
|
||||||
|
|
||||||
choice SECURE_FLASH_ENCRYPTION_KEYSIZE
|
choice SECURE_FLASH_ENCRYPTION_KEYSIZE
|
||||||
bool "Size of generated AES-XTS key"
|
bool "Size of generated AES-XTS key"
|
||||||
|
@ -431,31 +432,40 @@ menu "Security features"
|
||||||
bool "AES-256 (512-bit key)"
|
bool "AES-256 (512-bit key)"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config SECURE_FLASH_ENC_INSECURE
|
choice SECURE_FLASH_ENCRYPTION_MODE
|
||||||
bool "Allow potentially insecure options"
|
bool "Enable usage mode"
|
||||||
depends on SECURE_FLASH_ENC_ENABLED
|
depends on SECURE_FLASH_ENC_ENABLED
|
||||||
default N
|
default SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
help
|
help
|
||||||
You can disable some of the default protections offered by flash encryption, in order to enable testing or
|
By default Development mode is enabled which allows UART bootloader to perform flash encryption operations
|
||||||
a custom combination of security features.
|
|
||||||
|
|
||||||
Only enable these options if you are very sure.
|
Select Release mode only for production or manufacturing. Once enabled you can not reflash using UART
|
||||||
|
bootloader
|
||||||
|
|
||||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html and
|
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html and
|
||||||
https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html for details.
|
https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html for details.
|
||||||
|
|
||||||
|
config SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
|
bool "Development(NOT SECURE)"
|
||||||
|
select SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
||||||
|
|
||||||
|
config SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||||
|
bool "Release"
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
menu "Potentially insecure options"
|
menu "Potentially insecure options"
|
||||||
visible if SECURE_FLASH_ENC_INSECURE || SECURE_BOOT_INSECURE
|
visible if SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT || SECURE_BOOT_INSECURE
|
||||||
|
|
||||||
# NOTE: Options in this menu NEED to have SECURE_BOOT_INSECURE
|
# NOTE: Options in this menu NEED to have SECURE_BOOT_INSECURE
|
||||||
# and/or SECURE_FLASH_ENC_INSECURE in "depends on", as the menu
|
# and/or SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT in "depends on", as the menu
|
||||||
# itself doesn't enable/disable its children (if it's not set,
|
# itself doesn't enable/disable its children (if it's not set,
|
||||||
# it's possible for the insecure menu to be disabled but the insecure option
|
# it's possible for the insecure menu to be disabled but the insecure option
|
||||||
# to remain on which is very bad.)
|
# to remain on which is very bad.)
|
||||||
|
|
||||||
config SECURE_BOOT_ALLOW_ROM_BASIC
|
config SECURE_BOOT_ALLOW_ROM_BASIC
|
||||||
bool "Leave ROM BASIC Interpreter available on reset"
|
bool "Leave ROM BASIC Interpreter available on reset"
|
||||||
depends on SECURE_BOOT_INSECURE || SECURE_FLASH_ENC_INSECURE
|
depends on SECURE_BOOT_INSECURE || SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
default N
|
default N
|
||||||
help
|
help
|
||||||
By default, the BASIC ROM Console starts on reset if no valid bootloader is
|
By default, the BASIC ROM Console starts on reset if no valid bootloader is
|
||||||
|
@ -469,7 +479,7 @@ menu "Security features"
|
||||||
|
|
||||||
config SECURE_BOOT_ALLOW_JTAG
|
config SECURE_BOOT_ALLOW_JTAG
|
||||||
bool "Allow JTAG Debugging"
|
bool "Allow JTAG Debugging"
|
||||||
depends on SECURE_BOOT_INSECURE || SECURE_FLASH_ENC_INSECURE
|
depends on SECURE_BOOT_INSECURE || SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
default N
|
default N
|
||||||
help
|
help
|
||||||
If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot
|
If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot
|
||||||
|
@ -496,7 +506,7 @@ menu "Security features"
|
||||||
|
|
||||||
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
||||||
bool "Leave UART bootloader encryption enabled"
|
bool "Leave UART bootloader encryption enabled"
|
||||||
depends on SECURE_FLASH_ENC_INSECURE
|
depends on SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
default N
|
default N
|
||||||
help
|
help
|
||||||
If not set (default), the bootloader will permanently disable UART bootloader encryption access on
|
If not set (default), the bootloader will permanently disable UART bootloader encryption access on
|
||||||
|
@ -506,7 +516,7 @@ menu "Security features"
|
||||||
|
|
||||||
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC
|
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC
|
||||||
bool "Leave UART bootloader decryption enabled"
|
bool "Leave UART bootloader decryption enabled"
|
||||||
depends on SECURE_FLASH_ENC_INSECURE
|
depends on SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
default N
|
default N
|
||||||
help
|
help
|
||||||
If not set (default), the bootloader will permanently disable UART bootloader decryption access on
|
If not set (default), the bootloader will permanently disable UART bootloader decryption access on
|
||||||
|
@ -517,7 +527,7 @@ menu "Security features"
|
||||||
|
|
||||||
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
|
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
|
||||||
bool "Leave UART bootloader flash cache enabled"
|
bool "Leave UART bootloader flash cache enabled"
|
||||||
depends on SECURE_FLASH_ENC_INSECURE
|
depends on SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
default N
|
default N
|
||||||
help
|
help
|
||||||
If not set (default), the bootloader will permanently disable UART bootloader flash cache access on
|
If not set (default), the bootloader will permanently disable UART bootloader flash cache access on
|
||||||
|
@ -527,3 +537,4 @@ menu "Security features"
|
||||||
|
|
||||||
endmenu # Potentially Insecure
|
endmenu # Potentially Insecure
|
||||||
endmenu # Security features
|
endmenu # Security features
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
--flash_mode ${ESPFLASHMODE}
|
--flash_mode ${ESPFLASHMODE}
|
||||||
--flash_size ${ESPFLASHSIZE}
|
--flash_size ${ESPFLASHSIZE}
|
||||||
--flash_freq ${ESPFLASHFREQ}
|
--flash_freq ${ESPFLASHFREQ}
|
||||||
${BOOTLOADER_OFFSET} bootloader/bootloader.bin
|
${OFFSET} ${IMAGE}
|
||||||
|
|
|
@ -1,32 +1,10 @@
|
||||||
# Do not generate flash file when building bootloader or is in early expansion of the build
|
set(BOOTLOADER_OFFSET 0x1000)
|
||||||
|
|
||||||
|
# Do not generate flash file when building bootloader
|
||||||
if(BOOTLOADER_BUILD)
|
if(BOOTLOADER_BUILD)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_build_get_property(project_dir PROJECT_DIR)
|
|
||||||
|
|
||||||
# This is for tracking the top level project path
|
|
||||||
if(BOOTLOADER_BUILD)
|
|
||||||
set(main_project_path "${CMAKE_BINARY_DIR}/../..")
|
|
||||||
else()
|
|
||||||
set(main_project_path "${project_dir}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
get_filename_component(secure_boot_signing_key
|
|
||||||
"${CONFIG_SECURE_BOOT_SIGNING_KEY}"
|
|
||||||
ABSOLUTE BASE_DIR "${main_project_path}")
|
|
||||||
if(NOT EXISTS ${secure_boot_signing_key})
|
|
||||||
# If the signing key is not found, create a phony gen_secure_boot_signing_key target that
|
|
||||||
# fails the build. fail_at_build_time also touches CMakeCache.txt to cause a cmake run next time
|
|
||||||
# (to pick up a new signing key if one exists, etc.)
|
|
||||||
fail_at_build_time(gen_secure_boot_signing_key
|
|
||||||
"Secure Boot Signing Key ${CONFIG_SECURE_BOOT_SIGNING_KEY} does not exist. Generate using:"
|
|
||||||
"\tespsecure.py generate_signing_key ${CONFIG_SECURE_BOOT_SIGNING_KEY}")
|
|
||||||
else()
|
|
||||||
add_custom_target(gen_secure_boot_signing_key)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# Glue to build the bootloader subproject binary as an external
|
# Glue to build the bootloader subproject binary as an external
|
||||||
# cmake project under this one
|
# cmake project under this one
|
||||||
#
|
#
|
||||||
|
@ -39,37 +17,104 @@ set(bootloader_binary_files
|
||||||
"${BOOTLOADER_BUILD_DIR}/bootloader.map"
|
"${BOOTLOADER_BUILD_DIR}/bootloader.map"
|
||||||
)
|
)
|
||||||
|
|
||||||
# These additional files may get generated
|
idf_build_get_property(project_dir PROJECT_DIR)
|
||||||
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
|
||||||
|
# There are some additional processing when CONFIG_CONFIG_SECURE_SIGNED_APPS. This happens
|
||||||
|
# when either CONFIG_SECURE_BOOT_ENABLED or SECURE_BOOT_BUILD_SIGNED_BINARIES.
|
||||||
|
# For both cases, the user either sets binaries to be signed during build or not
|
||||||
|
# using CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES.
|
||||||
|
#
|
||||||
|
# Regardless, pass the main project's keys (signing/verification) to the bootloader subproject
|
||||||
|
# via config.
|
||||||
|
if(CONFIG_SECURE_SIGNED_APPS)
|
||||||
|
add_custom_target(gen_secure_boot_keys)
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOT_ENABLED)
|
||||||
|
# Check that the configuration is sane
|
||||||
|
if((CONFIG_SECURE_BOOTLOADER_REFLASHABLE AND CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH) OR
|
||||||
|
(NOT CONFIG_SECURE_BOOTLOADER_REFLASHABLE AND NOT CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH))
|
||||||
|
fail_at_build_time(bootloader "Invalid bootloader target: bad sdkconfig?")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||||
set(bootloader_binary_files
|
set(bootloader_binary_files
|
||||||
${bootloader_binary_files}
|
${bootloader_binary_files}
|
||||||
"${BOOTLOADER_BUILD_DIR}/bootloader-reflash-digest.bin"
|
"${BOOTLOADER_BUILD_DIR}/bootloader-reflash-digest.bin"
|
||||||
"${BOOTLOADER_BUILD_DIR}/secure-bootloader-key-192.bin"
|
"${BOOTLOADER_BUILD_DIR}/secure-bootloader-key-192.bin"
|
||||||
"${BOOTLOADER_BUILD_DIR}/secure-bootloader-key-256.bin"
|
"${BOOTLOADER_BUILD_DIR}/secure-bootloader-key-256.bin"
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Since keys are usually given relative to main project dir, get the absolute paths to the keys
|
||||||
|
# for use by the bootloader subproject. Replace the values in config with these absolute paths,
|
||||||
|
# so that bootloader subproject does not need to assume main project dir to obtain path to the keys.
|
||||||
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||||
|
get_filename_component(secure_boot_signing_key
|
||||||
|
"${CONFIG_SECURE_BOOT_SIGNING_KEY}"
|
||||||
|
ABSOLUTE BASE_DIR "${project_dir}")
|
||||||
|
|
||||||
|
if(NOT EXISTS ${secure_boot_signing_key})
|
||||||
|
# If the signing key is not found, create a phony gen_secure_boot_signing_key target that
|
||||||
|
# fails the build. fail_at_build_time causes a cmake run next time
|
||||||
|
# (to pick up a new signing key if one exists, etc.)
|
||||||
|
fail_at_build_time(gen_secure_boot_signing_key
|
||||||
|
"Secure Boot Signing Key ${CONFIG_SECURE_BOOT_SIGNING_KEY} does not exist. Generate using:"
|
||||||
|
"\tespsecure.py generate_signing_key ${CONFIG_SECURE_BOOT_SIGNING_KEY}")
|
||||||
|
else()
|
||||||
|
add_custom_target(gen_secure_boot_signing_key)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(SECURE_BOOT_SIGNING_KEY ${secure_boot_signing_key}) # needed by some other components
|
||||||
|
set(sign_key_arg "-DSECURE_BOOT_SIGNING_KEY=${secure_boot_signing_key}")
|
||||||
|
|
||||||
|
add_dependencies(gen_secure_boot_keys gen_secure_boot_signing_key)
|
||||||
|
else()
|
||||||
|
|
||||||
|
get_filename_component(secure_boot_verification_key
|
||||||
|
${CONFIG_SECURE_BOOT_VERIFICATION_KEY}
|
||||||
|
ABSOLUTE BASE_DIR "${project_dir}")
|
||||||
|
|
||||||
|
if(NOT EXISTS ${secure_boot_verification_key})
|
||||||
|
# If the verification key is not found, create a phony gen_secure_boot_verification_key target that
|
||||||
|
# fails the build. fail_at_build_time causes a cmake run next time
|
||||||
|
# (to pick up a new verification key if one exists, etc.)
|
||||||
|
fail_at_build_time(gen_secure_boot_verification_key
|
||||||
|
"Secure Boot Verification Public Key ${CONFIG_SECURE_BOOT_VERIFICATION_KEY} does not exist."
|
||||||
|
"\tThis can be extracted from the private signing key."
|
||||||
|
"\tSee docs/security/secure-boot.rst for details.")
|
||||||
|
else()
|
||||||
|
add_custom_target(gen_secure_boot_verification_key)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ver_key_arg "-DSECURE_BOOT_VERIFICATION_KEY=${secure_boot_verification_key}")
|
||||||
|
|
||||||
|
add_dependencies(gen_secure_boot_keys gen_secure_boot_verification_key)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if((NOT CONFIG_SECURE_BOOT_ENABLED) OR
|
idf_build_get_property(idf_path IDF_PATH)
|
||||||
CONFIG_SECURE_BOOTLOADER_REFLASHABLE OR
|
idf_build_get_property(idf_target IDF_TARGET)
|
||||||
CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
idf_build_get_property(sdkconfig SDKCONFIG)
|
||||||
idf_build_get_property(idf_path IDF_PATH)
|
|
||||||
idf_build_get_property(sdkconfig SDKCONFIG)
|
externalproject_add(bootloader
|
||||||
idf_build_get_property(idf_target IDF_TARGET)
|
|
||||||
externalproject_add(bootloader
|
|
||||||
# TODO: support overriding the bootloader in COMPONENT_PATHS
|
|
||||||
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
|
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
|
||||||
BINARY_DIR "${BOOTLOADER_BUILD_DIR}"
|
BINARY_DIR "${BOOTLOADER_BUILD_DIR}"
|
||||||
CMAKE_ARGS -DSDKCONFIG=${sdkconfig} -DIDF_PATH=${idf_path} -DIDF_TARGET=${idf_target}
|
CMAKE_ARGS -DSDKCONFIG=${sdkconfig} -DIDF_PATH=${idf_path} -DIDF_TARGET=${idf_target}
|
||||||
-DSECURE_BOOT_SIGNING_KEY=${secure_boot_signing_key}
|
|
||||||
-DPYTHON_DEPS_CHECKED=1
|
-DPYTHON_DEPS_CHECKED=1
|
||||||
-DEXTRA_COMPONENT_DIRS=${CMAKE_CURRENT_LIST_DIR}
|
-DEXTRA_COMPONENT_DIRS=${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
${sign_key_arg} ${ver_key_arg}
|
||||||
|
# LEGACY_INCLUDE_COMMON_HEADERS has to be passed in via cache variable since
|
||||||
|
# the bootloader common component requirements depends on this and
|
||||||
|
# config variables are not available before project() call.
|
||||||
|
-DLEGACY_INCLUDE_COMMON_HEADERS=${CONFIG_LEGACY_INCLUDE_COMMON_HEADERS}
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
BUILD_ALWAYS 1 # no easy way around this...
|
BUILD_ALWAYS 1 # no easy way around this...
|
||||||
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
||||||
DEPENDS gen_secure_boot_signing_key
|
|
||||||
)
|
)
|
||||||
else()
|
|
||||||
fail_at_build_time(bootloader "Invalid bootloader target: bad sdkconfig?")
|
if(CONFIG_SECURE_SIGNED_APPS)
|
||||||
|
add_dependencies(bootloader gen_secure_boot_keys)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# this is a hack due to an (annoying) shortcoming in cmake, it can't
|
# this is a hack due to an (annoying) shortcoming in cmake, it can't
|
||||||
|
|
|
@ -16,7 +16,7 @@ CONFIG_APP_SECURE_VERSION_SIZE_EFUSE_FIELD CONFIG_BOOTLOADER_AP
|
||||||
CONFIG_EFUSE_SECURE_VERSION_EMULATE CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
CONFIG_EFUSE_SECURE_VERSION_EMULATE CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
||||||
|
|
||||||
CONFIG_FLASH_ENCRYPTION_ENABLED CONFIG_SECURE_FLASH_ENC_ENABLED
|
CONFIG_FLASH_ENCRYPTION_ENABLED CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||||
CONFIG_FLASH_ENCRYPTION_INSECURE CONFIG_SECURE_FLASH_ENC_INSECURE
|
CONFIG_FLASH_ENCRYPTION_INSECURE CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||||
CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
||||||
CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC
|
CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC
|
||||||
CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
|
CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
|
||||||
|
|
|
@ -19,7 +19,7 @@ set(COMPONENTS bootloader esptool_py partition_table soc bootloader_support log
|
||||||
set(BOOTLOADER_BUILD 1)
|
set(BOOTLOADER_BUILD 1)
|
||||||
include("${IDF_PATH}/tools/cmake/project.cmake")
|
include("${IDF_PATH}/tools/cmake/project.cmake")
|
||||||
set(common_req log esp_rom esp_common xtensa)
|
set(common_req log esp_rom esp_common xtensa)
|
||||||
if (CONFIG_LEGACY_INCLUDE_COMMON_HEADERS)
|
if(LEGACY_INCLUDE_COMMON_HEADERS)
|
||||||
list(APPEND common_req soc)
|
list(APPEND common_req soc)
|
||||||
endif()
|
endif()
|
||||||
idf_build_set_property(__COMPONENT_REQUIRES_COMMON "${common_req}")
|
idf_build_set_property(__COMPONENT_REQUIRES_COMMON "${common_req}")
|
||||||
|
@ -29,8 +29,6 @@ project(bootloader)
|
||||||
idf_build_set_property(COMPILE_DEFINITIONS "-DBOOTLOADER_BUILD=1" APPEND)
|
idf_build_set_property(COMPILE_DEFINITIONS "-DBOOTLOADER_BUILD=1" APPEND)
|
||||||
idf_build_set_property(COMPILE_OPTIONS "-fno-stack-protector" APPEND)
|
idf_build_set_property(COMPILE_OPTIONS "-fno-stack-protector" APPEND)
|
||||||
|
|
||||||
set(secure_boot_signing_key ${SECURE_BOOT_SIGNING_KEY})
|
|
||||||
|
|
||||||
string(REPLACE ";" " " espsecurepy "${ESPSECUREPY}")
|
string(REPLACE ";" " " espsecurepy "${ESPSECUREPY}")
|
||||||
string(REPLACE ";" " " espefusepy "${ESPEFUSEPY}")
|
string(REPLACE ";" " " espefusepy "${ESPEFUSEPY}")
|
||||||
set(esptoolpy_write_flash "${ESPTOOLPY_WRITE_FLASH_STR}")
|
set(esptoolpy_write_flash "${ESPTOOLPY_WRITE_FLASH_STR}")
|
||||||
|
@ -53,7 +51,7 @@ if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||||
add_custom_command(OUTPUT "${secure_bootloader_key}"
|
add_custom_command(OUTPUT "${secure_bootloader_key}"
|
||||||
COMMAND ${ESPSECUREPY} digest_private_key
|
COMMAND ${ESPSECUREPY} digest_private_key
|
||||||
--keylen "${key_digest_len}"
|
--keylen "${key_digest_len}"
|
||||||
--keyfile "${secure_boot_signing_key}"
|
--keyfile "${SECURE_BOOT_SIGNING_KEY}"
|
||||||
"${secure_bootloader_key}"
|
"${secure_bootloader_key}"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
|
@ -67,7 +65,7 @@ if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||||
"\nTo generate one, you can use this command:"
|
"\nTo generate one, you can use this command:"
|
||||||
"\n\t${espsecurepy} generate_flash_encryption_key ${secure_bootloader_key}"
|
"\n\t${espsecurepy} generate_flash_encryption_key ${secure_bootloader_key}"
|
||||||
"\nIf a signing key is present, then instead use:"
|
"\nIf a signing key is present, then instead use:"
|
||||||
"\n\t${ESPSECUREPY} digest_private_key "
|
"\n\t${espsecurepy} digest_private_key "
|
||||||
"--keylen (192/256) --keyfile KEYFILE "
|
"--keylen (192/256) --keyfile KEYFILE "
|
||||||
"${secure_bootloader_key}")
|
"${secure_bootloader_key}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -78,14 +76,14 @@ if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "DIGEST ${bootloader_digest_bin}"
|
COMMAND ${CMAKE_COMMAND} -E echo "DIGEST ${bootloader_digest_bin}"
|
||||||
COMMAND ${ESPSECUREPY} digest_secure_bootloader --keyfile "${secure_bootloader_key}"
|
COMMAND ${ESPSECUREPY} digest_secure_bootloader --keyfile "${secure_bootloader_key}"
|
||||||
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
|
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||||
DEPENDS gen_secure_bootloader_key "${CMAKE_BINARY_DIR}/bootloader.bin"
|
DEPENDS gen_secure_bootloader_key gen_project_binary
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
add_custom_target (gen_bootloader_digest_bin ALL DEPENDS "${bootloader_digest_bin}")
|
add_custom_target (gen_bootloader_digest_bin ALL DEPENDS "${bootloader_digest_bin}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
if(CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||||
add_custom_command(TARGET bootloader POST_BUILD
|
add_custom_command(TARGET bootloader.elf POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
"=============================================================================="
|
"=============================================================================="
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
|
@ -97,9 +95,8 @@ if(CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
"* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
"* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
elseif(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
elseif(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||||
add_custom_command(TARGET bootloader POST_BUILD
|
add_custom_command(TARGET bootloader.elf POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
"=============================================================================="
|
"=============================================================================="
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# only compile the "micro-ecc/uECC.c" source file
|
# only compile the "micro-ecc/uECC.c" source file
|
||||||
set(COMPONENT_SRCS "micro-ecc/uECC.c")
|
idf_component_register(SRCS "micro-ecc/uECC.c"
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS micro-ecc)
|
INCLUDE_DIRS micro-ecc)
|
||||||
register_component()
|
|
||||||
|
|
|
@ -5,4 +5,5 @@ idf_build_get_property(target IDF_TARGET)
|
||||||
set(scripts "ld/${target}/bootloader.ld"
|
set(scripts "ld/${target}/bootloader.ld"
|
||||||
"ld/${target}/bootloader.rom.ld")
|
"ld/${target}/bootloader.rom.ld")
|
||||||
|
|
||||||
target_linker_script(${COMPONENT_LIB} "${scripts}")
|
target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}")
|
||||||
|
|
||||||
|
|
|
@ -1,64 +1,70 @@
|
||||||
set(COMPONENT_SRCS "src/bootloader_clock.c"
|
set(srcs
|
||||||
|
"src/bootloader_clock.c"
|
||||||
"src/bootloader_common.c"
|
"src/bootloader_common.c"
|
||||||
"src/bootloader_flash.c"
|
"src/bootloader_flash.c"
|
||||||
"src/bootloader_random.c"
|
"src/bootloader_random.c"
|
||||||
"src/bootloader_utility.c"
|
"src/bootloader_utility.c"
|
||||||
"src/esp_image_format.c"
|
"src/esp_image_format.c"
|
||||||
|
"src/flash_encrypt.c"
|
||||||
"src/flash_partitions.c"
|
"src/flash_partitions.c"
|
||||||
"src/flash_qio_mode.c")
|
"src/flash_qio_mode.c"
|
||||||
|
"src/${IDF_TARGET}/bootloader_flash_config_${IDF_TARGET}.c"
|
||||||
|
)
|
||||||
|
|
||||||
if(BOOTLOADER_BUILD)
|
if(BOOTLOADER_BUILD)
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader")
|
set(include_dirs "include" "include_bootloader")
|
||||||
set(COMPONENT_REQUIRES spi_flash soc) #unfortunately the header directly uses SOC registers
|
set(priv_requires micro-ecc spi_flash efuse)
|
||||||
set(COMPONENT_PRIV_REQUIRES micro-ecc efuse)
|
list(APPEND srcs
|
||||||
list(APPEND COMPONENT_SRCS "src/bootloader_init.c"
|
"src/bootloader_init.c"
|
||||||
"src/${IDF_TARGET}/bootloader_sha.c"
|
"src/${IDF_TARGET}/bootloader_sha.c"
|
||||||
"src/${IDF_TARGET}/flash_encrypt.c"
|
"src/${IDF_TARGET}/flash_encrypt.c"
|
||||||
"src/${IDF_TARGET}/secure_boot_signatures.c"
|
"src/${IDF_TARGET}/secure_boot_signatures.c"
|
||||||
"src/${IDF_TARGET}/secure_boot.c"
|
"src/${IDF_TARGET}/secure_boot.c"
|
||||||
"src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c"
|
"src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c"
|
||||||
"src/${IDF_TARGET}/bootloader_clock_${IDF_TARGET}.c")
|
"src/${IDF_TARGET}/bootloader_clock_${IDF_TARGET}.c"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
list(APPEND srcs
|
||||||
|
"src/idf/bootloader_sha.c"
|
||||||
|
"src/idf/secure_boot_signatures.c")
|
||||||
|
set(include_dirs "include")
|
||||||
|
set(priv_include_dirs "include_bootloader")
|
||||||
|
set(priv_requires spi_flash mbedtls efuse)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CONFIG_SECURE_SIGNED_APPS)
|
set(requires soc) #unfortunately the header directly uses SOC registers
|
||||||
|
|
||||||
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
INCLUDE_DIRS "${include_dirs}"
|
||||||
|
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||||
|
REQUIRES "${requires}"
|
||||||
|
PRIV_REQUIRES "${priv_requires}")
|
||||||
|
|
||||||
|
if(BOOTLOADER_BUILD AND CONFIG_SECURE_SIGNED_APPS)
|
||||||
|
# Whether CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES or not, we need verification key to embed
|
||||||
|
# in the library.
|
||||||
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||||
|
# We generate the key from the signing key. The signing key is passed from the main project.
|
||||||
|
get_filename_component(secure_boot_signing_key
|
||||||
|
"${SECURE_BOOT_SIGNING_KEY}"
|
||||||
|
ABSOLUTE BASE_DIR "${project_dir}")
|
||||||
get_filename_component(secure_boot_verification_key
|
get_filename_component(secure_boot_verification_key
|
||||||
"signature_verification_key.bin"
|
"signature_verification_key.bin"
|
||||||
ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
|
ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
|
||||||
add_custom_command(OUTPUT "${secure_boot_verification_key}"
|
add_custom_command(OUTPUT "${secure_boot_verification_key}"
|
||||||
COMMAND ${ESPSECUREPY}
|
COMMAND ${ESPSECUREPY}
|
||||||
extract_public_key --keyfile "${secure_boot_signing_key}"
|
extract_public_key --keyfile "${secure_boot_signing_key}"
|
||||||
"${secure_boot_verification_key}"
|
"${secure_boot_verification_key}"
|
||||||
DEPENDS gen_secure_boot_signing_key
|
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
else()
|
else()
|
||||||
get_filename_component(orig_secure_boot_verification_key
|
# We expect to 'inherit' the verification key passed from main project.
|
||||||
"${CONFIG_SECURE_BOOT_VERIFICATION_KEY}"
|
get_filename_component(secure_boot_verification_key
|
||||||
ABSOLUTE BASE_DIR "${main_project_path}")
|
${SECURE_BOOT_VERIFICATION_KEY}
|
||||||
if(NOT EXISTS ${orig_secure_boot_verification_key})
|
ABSOLUTE BASE_DIR "${project_dir}")
|
||||||
message(FATAL_ERROR
|
|
||||||
"Secure Boot Verification Public Key ${CONFIG_SECURE_BOOT_VERIFICATION_KEY} does not exist."
|
|
||||||
"\nThis can be extracted from the private signing key."
|
|
||||||
"\nSee docs/security/secure-boot.rst for details.")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_custom_command(OUTPUT "${secure_boot_verification_key}"
|
target_add_binary_data(${COMPONENT_LIB} "${secure_boot_verification_key}" "BINARY")
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${orig_secure_boot_verification_key}"
|
|
||||||
"${secure_boot_verification_key}"
|
|
||||||
DEPENDS "${orig_secure_boot_verification_key}"
|
|
||||||
VERBATIM)
|
|
||||||
endif()
|
|
||||||
set(COMPONENT_EMBED_FILES "${secure_boot_verification_key}")
|
|
||||||
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
|
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
|
||||||
"${secure_boot_verification_key}")
|
"${secure_boot_verification_key}")
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
list(APPEND COMPONENT_SRCS "src/idf/bootloader_sha.c"
|
|
||||||
"src/idf/secure_boot_signatures.c")
|
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
|
||||||
set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader")
|
|
||||||
set(COMPONENT_REQUIRES mbedtls soc) #unfortunately the header directly uses SOC registers
|
|
||||||
set(COMPONENT_PRIV_REQUIRES spi_flash efuse)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
register_component()
|
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @brief Configure clocks for early boot
|
/** @brief Configure clocks for early boot
|
||||||
*
|
*
|
||||||
* Called by bootloader, or by the app if the bootloader version is old (pre v2.1).
|
* Called by bootloader, or by the app if the bootloader version is old (pre v2.1).
|
||||||
|
@ -23,3 +27,8 @@ void bootloader_clock_configure(void);
|
||||||
/** @brief Return the rated maximum frequency of this chip
|
/** @brief Return the rated maximum frequency of this chip
|
||||||
*/
|
*/
|
||||||
int bootloader_clock_get_rated_freq_mhz(void);
|
int bootloader_clock_get_rated_freq_mhz(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
#include "esp_flash_partitions.h"
|
#include "esp_flash_partitions.h"
|
||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Type of hold a GPIO in low state
|
/// Type of hold a GPIO in low state
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GPIO_LONG_HOLD = 1, /*!< The long hold GPIO */
|
GPIO_LONG_HOLD = 1, /*!< The long hold GPIO */
|
||||||
|
@ -148,3 +152,7 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t
|
||||||
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
|
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
|
||||||
*/
|
*/
|
||||||
void bootloader_common_vddsdio_configure();
|
void bootloader_common_vddsdio_configure();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2018 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 "esp_image_format.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the flash id in g_rom_flashchip(global esp_rom_spiflash_chip_t structure).
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void bootloader_flash_update_id();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the flash CS setup and hold time.
|
||||||
|
*
|
||||||
|
* @note CS setup time is recomemded to be 1.5T, and CS hold time is recommended to be 2.5T.
|
||||||
|
* cs_setup = 1, cs_setup_time = 0; cs_hold = 1, cs_hold_time = 1.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void bootloader_flash_cs_timing_config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure SPI flash clock.
|
||||||
|
*
|
||||||
|
* @note This function only set clock frequency for SPI0.
|
||||||
|
*
|
||||||
|
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void bootloader_flash_clock_config(const esp_image_header_t* pfhdr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure SPI flash gpio, include the IO matrix and drive strength configuration.
|
||||||
|
*
|
||||||
|
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure SPI flash read dummy based on different mode and frequency.
|
||||||
|
*
|
||||||
|
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable early entropy source for RNG
|
* @brief Enable early entropy source for RNG
|
||||||
*
|
*
|
||||||
|
@ -47,3 +51,7 @@ void bootloader_random_disable(void);
|
||||||
* @param length This many bytes of random data will be copied to buffer
|
* @param length This many bytes of random data will be copied to buffer
|
||||||
*/
|
*/
|
||||||
void bootloader_fill_random(void *buffer, size_t length);
|
void bootloader_fill_random(void *buffer, size_t length);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if half-open intervals overlap
|
* @brief Check if half-open intervals overlap
|
||||||
*
|
*
|
||||||
|
@ -29,6 +33,11 @@ static inline bool bootloader_util_regions_overlap(
|
||||||
const intptr_t start1, const intptr_t end1,
|
const intptr_t start1, const intptr_t end1,
|
||||||
const intptr_t start2, const intptr_t end2)
|
const intptr_t start2, const intptr_t end2)
|
||||||
{
|
{
|
||||||
return (end1 > start2 && end2 > start1) ||
|
assert(end1>start1);
|
||||||
!(end1 <= start2 || end2 <= start1);
|
assert(end2>start2);
|
||||||
|
return (end1 > start2 && end2 > start1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
109
components/bootloader_support/include/esp_app_format.h
Normal file
109
components/bootloader_support/include/esp_app_format.h
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash mode, used in esp_image_header_t
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_IMAGE_SPI_MODE_QIO, /*!< SPI mode QIO */
|
||||||
|
ESP_IMAGE_SPI_MODE_QOUT, /*!< SPI mode QOUT */
|
||||||
|
ESP_IMAGE_SPI_MODE_DIO, /*!< SPI mode DIO */
|
||||||
|
ESP_IMAGE_SPI_MODE_DOUT, /*!< SPI mode DOUT */
|
||||||
|
ESP_IMAGE_SPI_MODE_FAST_READ, /*!< SPI mode FAST_READ */
|
||||||
|
ESP_IMAGE_SPI_MODE_SLOW_READ /*!< SPI mode SLOW_READ */
|
||||||
|
} esp_image_spi_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash clock frequency
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_IMAGE_SPI_SPEED_40M, /*!< SPI clock frequency 40 MHz */
|
||||||
|
ESP_IMAGE_SPI_SPEED_26M, /*!< SPI clock frequency 26 MHz */
|
||||||
|
ESP_IMAGE_SPI_SPEED_20M, /*!< SPI clock frequency 20 MHz */
|
||||||
|
ESP_IMAGE_SPI_SPEED_80M = 0xF /*!< SPI clock frequency 80 MHz */
|
||||||
|
} esp_image_spi_freq_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Supported SPI flash sizes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_IMAGE_FLASH_SIZE_1MB = 0, /*!< SPI flash size 1 MB */
|
||||||
|
ESP_IMAGE_FLASH_SIZE_2MB, /*!< SPI flash size 2 MB */
|
||||||
|
ESP_IMAGE_FLASH_SIZE_4MB, /*!< SPI flash size 4 MB */
|
||||||
|
ESP_IMAGE_FLASH_SIZE_8MB, /*!< SPI flash size 8 MB */
|
||||||
|
ESP_IMAGE_FLASH_SIZE_16MB, /*!< SPI flash size 16 MB */
|
||||||
|
ESP_IMAGE_FLASH_SIZE_MAX /*!< SPI flash size MAX */
|
||||||
|
} esp_image_flash_size_t;
|
||||||
|
|
||||||
|
#define ESP_IMAGE_HEADER_MAGIC 0xE9 /*!< The magic word for the esp_image_header_t structure. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main header of binary image
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t magic; /*!< Magic word ESP_IMAGE_HEADER_MAGIC */
|
||||||
|
uint8_t segment_count; /*!< Count of memory segments */
|
||||||
|
uint8_t spi_mode; /*!< flash read mode (esp_image_spi_mode_t as uint8_t) */
|
||||||
|
uint8_t spi_speed: 4; /*!< flash frequency (esp_image_spi_freq_t as uint8_t) */
|
||||||
|
uint8_t spi_size: 4; /*!< flash chip size (esp_image_flash_size_t as uint8_t) */
|
||||||
|
uint32_t entry_addr; /*!< Entry address */
|
||||||
|
uint8_t wp_pin; /*!< WP pin when SPI pins set via efuse (read by ROM bootloader,
|
||||||
|
* the IDF bootloader uses software to configure the WP
|
||||||
|
* pin and sets this field to 0xEE=disabled) */
|
||||||
|
uint8_t spi_pin_drv[3]; /*!< Drive settings for the SPI flash pins (read by ROM bootloader) */
|
||||||
|
uint8_t reserved[11]; /*!< Reserved bytes in ESP32 additional header space, currently unused */
|
||||||
|
uint8_t hash_appended; /*!< If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum.
|
||||||
|
* Included in image length. This digest
|
||||||
|
* is separate to secure boot and only used for detecting corruption.
|
||||||
|
* For secure boot signed images, the signature
|
||||||
|
* is appended after this (and the simple hash is included in the signed data). */
|
||||||
|
} __attribute__((packed)) esp_image_header_t;
|
||||||
|
|
||||||
|
/** @cond */
|
||||||
|
_Static_assert(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes");
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Header of binary image segment
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t load_addr; /*!< Address of segment */
|
||||||
|
uint32_t data_len; /*!< Length of data */
|
||||||
|
} esp_image_segment_header_t;
|
||||||
|
|
||||||
|
#define ESP_IMAGE_MAX_SEGMENTS 16 /*!< Max count of segments in the image. */
|
||||||
|
|
||||||
|
#define ESP_APP_DESC_MAGIC_WORD 0xABCD5432 /*!< The magic word for the esp_app_desc structure that is in DROM. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Description about application.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t magic_word; /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
|
||||||
|
uint32_t secure_version; /*!< Secure version */
|
||||||
|
uint32_t reserv1[2]; /*!< reserv1 */
|
||||||
|
char version[32]; /*!< Application version */
|
||||||
|
char project_name[32]; /*!< Project name */
|
||||||
|
char time[16]; /*!< Compile time */
|
||||||
|
char date[16]; /*!< Compile date*/
|
||||||
|
char idf_ver[32]; /*!< Version IDF */
|
||||||
|
uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
|
||||||
|
uint32_t reserv2[20]; /*!< reserv2 */
|
||||||
|
} esp_app_desc_t;
|
||||||
|
|
||||||
|
/** @cond */
|
||||||
|
_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
|
||||||
|
/** @endcond */
|
|
@ -11,8 +11,7 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
#ifndef __ESP32_FLASH_ENCRYPT_H
|
#pragma once
|
||||||
#define __ESP32_FLASH_ENCRYPT_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
|
@ -23,6 +22,18 @@
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @brief Flash encryption mode based on efuse values
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_FLASH_ENC_MODE_DISABLED, // flash encryption is not enabled (flash crypt cnt=0)
|
||||||
|
ESP_FLASH_ENC_MODE_DEVELOPMENT, // flash encryption is enabled but for Development (reflash over UART allowed)
|
||||||
|
ESP_FLASH_ENC_MODE_RELEASE // flash encryption is enabled for Release (reflash over UART disabled)
|
||||||
|
} esp_flash_enc_mode_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file esp_partition.h
|
* @file esp_partition.h
|
||||||
* @brief Support functions for flash encryption features
|
* @brief Support functions for flash encryption features
|
||||||
|
@ -117,8 +128,18 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
|
||||||
* is enabled but secure boot is not used. This should protect against
|
* is enabled but secure boot is not used. This should protect against
|
||||||
* serial re-flashing of an unauthorised code in absence of secure boot.
|
* serial re-flashing of an unauthorised code in absence of secure boot.
|
||||||
*
|
*
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
void esp_flash_write_protect_crypt_cnt();
|
void esp_flash_write_protect_crypt_cnt();
|
||||||
|
|
||||||
|
/** @brief Return the flash encryption mode
|
||||||
|
*
|
||||||
|
* The API is called during boot process but can also be called by
|
||||||
|
* application to check the current flash encryption mode of ESP32
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
esp_flash_enc_mode_t esp_get_flash_encryption_mode();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -103,6 +103,17 @@ inline static __attribute__((deprecated)) esp_err_t esp_partition_table_basic_ve
|
||||||
{
|
{
|
||||||
return esp_partition_table_verify(partition_table, log_errors, num_partitions);
|
return esp_partition_table_verify(partition_table, log_errors, num_partitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the region on the main flash is safe to write.
|
||||||
|
*
|
||||||
|
* @param addr Start address of the region
|
||||||
|
* @param size Size of the region
|
||||||
|
*
|
||||||
|
* @return true if the region is safe to write, otherwise false.
|
||||||
|
*/
|
||||||
|
bool esp_partition_main_flash_region_safe(size_t addr, size_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include "esp_flash_partitions.h"
|
#include "esp_flash_partitions.h"
|
||||||
|
#include "esp_app_format.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ESP_ERR_IMAGE_BASE 0x2000
|
#define ESP_ERR_IMAGE_BASE 0x2000
|
||||||
#define ESP_ERR_IMAGE_FLASH_FAIL (ESP_ERR_IMAGE_BASE + 1)
|
#define ESP_ERR_IMAGE_FLASH_FAIL (ESP_ERR_IMAGE_BASE + 1)
|
||||||
|
@ -25,91 +30,8 @@
|
||||||
Can be compiled as part of app or bootloader code.
|
Can be compiled as part of app or bootloader code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* SPI flash mode, used in esp_image_header_t */
|
|
||||||
typedef enum {
|
|
||||||
ESP_IMAGE_SPI_MODE_QIO,
|
|
||||||
ESP_IMAGE_SPI_MODE_QOUT,
|
|
||||||
ESP_IMAGE_SPI_MODE_DIO,
|
|
||||||
ESP_IMAGE_SPI_MODE_DOUT,
|
|
||||||
ESP_IMAGE_SPI_MODE_FAST_READ,
|
|
||||||
ESP_IMAGE_SPI_MODE_SLOW_READ
|
|
||||||
} esp_image_spi_mode_t;
|
|
||||||
|
|
||||||
/* SPI flash clock frequency */
|
|
||||||
typedef enum {
|
|
||||||
ESP_IMAGE_SPI_SPEED_40M,
|
|
||||||
ESP_IMAGE_SPI_SPEED_26M,
|
|
||||||
ESP_IMAGE_SPI_SPEED_20M,
|
|
||||||
ESP_IMAGE_SPI_SPEED_80M = 0xF
|
|
||||||
} esp_image_spi_freq_t;
|
|
||||||
|
|
||||||
/* Supported SPI flash sizes */
|
|
||||||
typedef enum {
|
|
||||||
ESP_IMAGE_FLASH_SIZE_1MB = 0,
|
|
||||||
ESP_IMAGE_FLASH_SIZE_2MB,
|
|
||||||
ESP_IMAGE_FLASH_SIZE_4MB,
|
|
||||||
ESP_IMAGE_FLASH_SIZE_8MB,
|
|
||||||
ESP_IMAGE_FLASH_SIZE_16MB,
|
|
||||||
ESP_IMAGE_FLASH_SIZE_MAX
|
|
||||||
} esp_image_flash_size_t;
|
|
||||||
|
|
||||||
#define ESP_IMAGE_HEADER_MAGIC 0xE9
|
|
||||||
|
|
||||||
/* Main header of binary image */
|
|
||||||
typedef struct {
|
|
||||||
uint8_t magic;
|
|
||||||
uint8_t segment_count;
|
|
||||||
/* flash read mode (esp_image_spi_mode_t as uint8_t) */
|
|
||||||
uint8_t spi_mode;
|
|
||||||
/* flash frequency (esp_image_spi_freq_t as uint8_t) */
|
|
||||||
uint8_t spi_speed: 4;
|
|
||||||
/* flash chip size (esp_image_flash_size_t as uint8_t) */
|
|
||||||
uint8_t spi_size: 4;
|
|
||||||
uint32_t entry_addr;
|
|
||||||
/* WP pin when SPI pins set via efuse (read by ROM bootloader, the IDF bootloader uses software to configure the WP
|
|
||||||
* pin and sets this field to 0xEE=disabled) */
|
|
||||||
uint8_t wp_pin;
|
|
||||||
/* Drive settings for the SPI flash pins (read by ROM bootloader) */
|
|
||||||
uint8_t spi_pin_drv[3];
|
|
||||||
/* Reserved bytes in ESP32 additional header space, currently unused */
|
|
||||||
uint8_t reserved[11];
|
|
||||||
/* If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum. Included in image length. This digest
|
|
||||||
* is separate to secure boot and only used for detecting corruption. For secure boot signed images, the signature
|
|
||||||
* is appended after this (and the simple hash is included in the signed data). */
|
|
||||||
uint8_t hash_appended;
|
|
||||||
} __attribute__((packed)) esp_image_header_t;
|
|
||||||
|
|
||||||
_Static_assert(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes");
|
|
||||||
|
|
||||||
#define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */
|
#define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */
|
||||||
|
|
||||||
/* Header of binary image segment */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t load_addr;
|
|
||||||
uint32_t data_len;
|
|
||||||
} esp_image_segment_header_t;
|
|
||||||
|
|
||||||
#define ESP_APP_DESC_MAGIC_WORD 0xABCD5432 /*!< The magic word for the esp_app_desc structure that is in DROM. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Description about application.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
uint32_t magic_word; /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
|
|
||||||
uint32_t secure_version; /*!< Secure version */
|
|
||||||
uint32_t reserv1[2]; /*!< --- */
|
|
||||||
char version[32]; /*!< Application version */
|
|
||||||
char project_name[32]; /*!< Project name */
|
|
||||||
char time[16]; /*!< Compile time */
|
|
||||||
char date[16]; /*!< Compile date*/
|
|
||||||
char idf_ver[32]; /*!< Version IDF */
|
|
||||||
uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
|
|
||||||
uint32_t reserv2[20]; /*!< --- */
|
|
||||||
} esp_app_desc_t;
|
|
||||||
_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
|
|
||||||
|
|
||||||
#define ESP_IMAGE_MAX_SEGMENTS 16
|
|
||||||
|
|
||||||
/* Structure to hold on-flash image metadata */
|
/* Structure to hold on-flash image metadata */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t start_addr; /* Start address of image */
|
uint32_t start_addr; /* Start address of image */
|
||||||
|
@ -240,3 +162,7 @@ typedef struct {
|
||||||
uint32_t irom_load_addr;
|
uint32_t irom_load_addr;
|
||||||
uint32_t irom_size;
|
uint32_t irom_size;
|
||||||
} esp_image_flash_mapping_t;
|
} esp_image_flash_mapping_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -138,7 +138,6 @@ typedef struct {
|
||||||
uint8_t digest[64];
|
uint8_t digest[64];
|
||||||
} esp_secure_boot_iv_digest_t;
|
} esp_secure_boot_iv_digest_t;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,6 +30,13 @@
|
||||||
bootloader_support components only.
|
bootloader_support components only.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get number of free pages
|
||||||
|
*
|
||||||
|
* @return Number of free pages
|
||||||
|
*/
|
||||||
|
uint32_t bootloader_mmap_get_free_pages();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map a region of flash to data memory
|
* @brief Map a region of flash to data memory
|
||||||
*
|
*
|
||||||
|
|
|
@ -28,6 +28,11 @@ static const char *TAG = "bootloader_mmap";
|
||||||
|
|
||||||
static spi_flash_mmap_handle_t map;
|
static spi_flash_mmap_handle_t map;
|
||||||
|
|
||||||
|
uint32_t bootloader_mmap_get_free_pages()
|
||||||
|
{
|
||||||
|
return spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||||
{
|
{
|
||||||
if (map) {
|
if (map) {
|
||||||
|
@ -104,6 +109,7 @@ static const char *TAG = "bootloader_flash";
|
||||||
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
|
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
|
||||||
#define MMU_SIZE (0x320000)
|
#define MMU_SIZE (0x320000)
|
||||||
#define MMU_BLOCK50_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
|
#define MMU_BLOCK50_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
|
||||||
|
#define FLASH_READ_VADDR MMU_BLOCK50_VADDR
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
/* Use first 63 blocks in MMU for bootloader_mmap,
|
/* Use first 63 blocks in MMU for bootloader_mmap,
|
||||||
63th block for bootloader_flash_read
|
63th block for bootloader_flash_read
|
||||||
|
@ -111,13 +117,25 @@ static const char *TAG = "bootloader_flash";
|
||||||
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
|
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
|
||||||
#define MMU_SIZE (0x3f0000)
|
#define MMU_SIZE (0x3f0000)
|
||||||
#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
|
#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
|
||||||
|
#define FLASH_READ_VADDR MMU_BLOCK63_VADDR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MMU_FREE_PAGES (MMU_SIZE / FLASH_BLOCK_SIZE)
|
||||||
|
|
||||||
static bool mapped;
|
static bool mapped;
|
||||||
|
|
||||||
// Current bootloader mapping (ab)used for bootloader_read()
|
// Current bootloader mapping (ab)used for bootloader_read()
|
||||||
static uint32_t current_read_mapping = UINT32_MAX;
|
static uint32_t current_read_mapping = UINT32_MAX;
|
||||||
|
|
||||||
|
uint32_t bootloader_mmap_get_free_pages()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads)
|
||||||
|
* Since, bootloader_mmap function below assumes it to be 0x320000 (50 pages), we can safely do this.
|
||||||
|
*/
|
||||||
|
return MMU_FREE_PAGES;
|
||||||
|
}
|
||||||
|
|
||||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||||
{
|
{
|
||||||
if (mapped) {
|
if (mapped) {
|
||||||
|
@ -235,9 +253,9 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest
|
||||||
#endif
|
#endif
|
||||||
ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping);
|
ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping);
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, map_at, 64, 1);
|
int e = cache_flash_mmu_set(0, 0, FLASH_READ_VADDR, map_at, 64, 1);
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||||
int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR, map_at, 64, 1, 0);
|
int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, FLASH_READ_VADDR, map_at, 64, 1, 0);
|
||||||
#endif
|
#endif
|
||||||
if (e != 0) {
|
if (e != 0) {
|
||||||
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
||||||
|
@ -255,11 +273,7 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest
|
||||||
Cache_Resume_ICache(autoload);
|
Cache_Resume_ICache(autoload);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
map_ptr = (uint32_t *)(FLASH_READ_VADDR + (word_src - map_at));
|
||||||
map_ptr = (uint32_t *)(MMU_BLOCK50_VADDR + (word_src - map_at));
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
|
||||||
map_ptr = (uint32_t *)(MMU_BLOCK63_VADDR + (word_src - map_at));
|
|
||||||
#endif
|
|
||||||
dest_words[word] = *map_ptr;
|
dest_words[word] = *map_ptr;
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
#include "bootloader_common.h"
|
#include "bootloader_common.h"
|
||||||
#include "bootloader_clock.h"
|
#include "bootloader_clock.h"
|
||||||
#include "bootloader_common.h"
|
#include "bootloader_common.h"
|
||||||
|
#include "bootloader_flash_config.h"
|
||||||
|
|
||||||
#include "flash_qio_mode.h"
|
#include "flash_qio_mode.h"
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ static const char *TAG = "boot";
|
||||||
static esp_err_t bootloader_main();
|
static esp_err_t bootloader_main();
|
||||||
static void print_flash_info(const esp_image_header_t *pfhdr);
|
static void print_flash_info(const esp_image_header_t *pfhdr);
|
||||||
static void update_flash_config(const esp_image_header_t *pfhdr);
|
static void update_flash_config(const esp_image_header_t *pfhdr);
|
||||||
static void flash_gpio_configure(const esp_image_header_t *pfhdr);
|
static void bootloader_init_flash_configure(const esp_image_header_t* pfhdr);
|
||||||
static void uart_console_configure(void);
|
static void uart_console_configure(void);
|
||||||
static void wdt_reset_check(void);
|
static void wdt_reset_check(void);
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ static esp_err_t bootloader_main()
|
||||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
flash_gpio_configure(&fhdr);
|
bootloader_init_flash_configure(&fhdr);
|
||||||
|
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
int rated_freq = bootloader_clock_get_rated_freq_mhz();
|
int rated_freq = bootloader_clock_get_rated_freq_mhz();
|
||||||
|
@ -358,134 +359,11 @@ static void print_flash_info(const esp_image_header_t *phdr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
static void IRAM_ATTR bootloader_init_flash_configure(const esp_image_header_t* pfhdr)
|
||||||
#define FLASH_CLK_IO 6
|
|
||||||
#define FLASH_CS_IO 11
|
|
||||||
#define FLASH_SPIQ_IO 7
|
|
||||||
#define FLASH_SPID_IO 8
|
|
||||||
#define FLASH_SPIWP_IO 10
|
|
||||||
#define FLASH_SPIHD_IO 9
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
#define FLASH_IO_MATRIX_DUMMY_40M 1
|
|
||||||
#define FLASH_IO_MATRIX_DUMMY_80M 2
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
|
||||||
#define FLASH_IO_MATRIX_DUMMY_40M 0
|
|
||||||
#define FLASH_IO_MATRIX_DUMMY_80M 0
|
|
||||||
#endif
|
|
||||||
#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bootloader reads SPI configuration from bin header, so that
|
|
||||||
* the burning configuration can be different with compiling configuration.
|
|
||||||
*/
|
|
||||||
static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t *pfhdr)
|
|
||||||
{
|
{
|
||||||
int spi_cache_dummy = 0;
|
bootloader_flash_gpio_config(pfhdr);
|
||||||
int drv = 2;
|
bootloader_flash_dummy_config(pfhdr);
|
||||||
switch (pfhdr->spi_mode) {
|
bootloader_flash_cs_timing_config();
|
||||||
case ESP_IMAGE_SPI_MODE_QIO:
|
|
||||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
|
||||||
break;
|
|
||||||
case ESP_IMAGE_SPI_MODE_DIO:
|
|
||||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3
|
|
||||||
break;
|
|
||||||
case ESP_IMAGE_SPI_MODE_QOUT:
|
|
||||||
case ESP_IMAGE_SPI_MODE_DOUT:
|
|
||||||
default:
|
|
||||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
|
||||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
|
||||||
switch (pfhdr->spi_speed) {
|
|
||||||
case ESP_IMAGE_SPI_SPEED_80M:
|
|
||||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
|
|
||||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
|
||||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
|
||||||
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
|
||||||
SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY
|
|
||||||
#endif
|
|
||||||
drv = 3;
|
|
||||||
break;
|
|
||||||
case ESP_IMAGE_SPI_SPEED_40M:
|
|
||||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
|
|
||||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
|
||||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
|
||||||
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
|
||||||
SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
|
||||||
uint32_t pkg_ver = chip_ver & 0x7;
|
|
||||||
|
|
||||||
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
|
||||||
// For ESP32D2WD the SPI pins are already configured
|
|
||||||
// flash clock signal should come from IO MUX.
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
|
||||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
|
||||||
// For ESP32PICOD2 the SPI pins are already configured
|
|
||||||
// flash clock signal should come from IO MUX.
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
|
||||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
|
||||||
// For ESP32PICOD4 the SPI pins are already configured
|
|
||||||
// flash clock signal should come from IO MUX.
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
|
||||||
} else {
|
|
||||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
|
||||||
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
|
||||||
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
|
||||||
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
|
||||||
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
|
|
||||||
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
|
|
||||||
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
|
|
||||||
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
|
|
||||||
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
|
|
||||||
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
|
|
||||||
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
|
|
||||||
//select pin function gpio
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
|
||||||
// flash clock signal should come from IO MUX.
|
|
||||||
// set drive ability for clock
|
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
|
||||||
|
|
||||||
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32
|
|
||||||
uint32_t flash_id = g_rom_flashchip.device_id;
|
|
||||||
if (flash_id == FLASH_ID_GD25LQ32C) {
|
|
||||||
// Set drive ability for 1.8v flash in 80Mhz.
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
|
||||||
bootloader_configure_spi_pins(drv);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_console_configure(void)
|
static void uart_console_configure(void)
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
// Copyright 2018 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 <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "string.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp32/rom/gpio.h"
|
||||||
|
#include "esp32/rom/spi_flash.h"
|
||||||
|
#include "esp32/rom/efuse.h"
|
||||||
|
#include "soc/gpio_periph.h"
|
||||||
|
#include "soc/efuse_reg.h"
|
||||||
|
#include "soc/spi_reg.h"
|
||||||
|
#include "soc/spi_caps.h"
|
||||||
|
#include "flash_qio_mode.h"
|
||||||
|
#include "bootloader_flash_config.h"
|
||||||
|
|
||||||
|
void bootloader_flash_update_id()
|
||||||
|
{
|
||||||
|
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||||
|
SET_PERI_REG_MASK(SPI_USER_REG(1), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t* pfhdr)
|
||||||
|
{
|
||||||
|
uint32_t spi_clk_div = 0;
|
||||||
|
switch (pfhdr->spi_speed) {
|
||||||
|
case ESP_IMAGE_SPI_SPEED_80M:
|
||||||
|
spi_clk_div = 1;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_40M:
|
||||||
|
spi_clk_div = 2;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_26M:
|
||||||
|
spi_clk_div = 3;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_20M:
|
||||||
|
spi_clk_div = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
esp_rom_spiflash_config_clk(spi_clk_div, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
|
||||||
|
{
|
||||||
|
uint32_t drv = 2;
|
||||||
|
if (pfhdr->spi_speed == ESP_IMAGE_SPI_SPEED_80M) {
|
||||||
|
drv = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||||
|
uint32_t pkg_ver = chip_ver & 0x7;
|
||||||
|
|
||||||
|
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
||||||
|
// For ESP32D2WD the SPI pins are already configured
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
||||||
|
// For ESP32PICOD2 the SPI pins are already configured
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||||
|
// For ESP32PICOD4 the SPI pins are already configured
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
} else {
|
||||||
|
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||||
|
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||||
|
gpio_matrix_out(SPI_IOMUX_PIN_NUM_CS, SPICS0_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_out(SPI_IOMUX_PIN_NUM_MISO, SPIQ_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(SPI_IOMUX_PIN_NUM_MISO, SPIQ_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(SPI_IOMUX_PIN_NUM_MOSI, SPID_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(SPI_IOMUX_PIN_NUM_MOSI, SPID_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(SPI_IOMUX_PIN_NUM_WP, SPIWP_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(SPI_IOMUX_PIN_NUM_WP, SPIWP_IN_IDX, 0);
|
||||||
|
gpio_matrix_out(SPI_IOMUX_PIN_NUM_HD, SPIHD_OUT_IDX, 0, 0);
|
||||||
|
gpio_matrix_in(SPI_IOMUX_PIN_NUM_HD, SPIHD_IN_IDX, 0);
|
||||||
|
//select pin function gpio
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
||||||
|
// flash clock signal should come from IO MUX.
|
||||||
|
// set drive ability for clock
|
||||||
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||||
|
|
||||||
|
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||||
|
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||||
|
// Set drive ability for 1.8v flash in 80Mhz.
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr)
|
||||||
|
{
|
||||||
|
int spi_cache_dummy = 0;
|
||||||
|
uint32_t modebit = READ_PERI_REG(SPI_CTRL_REG(0));
|
||||||
|
if (modebit & SPI_FASTRD_MODE) {
|
||||||
|
if (modebit & SPI_FREAD_QIO) { //SPI mode is QIO
|
||||||
|
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
|
||||||
|
} else if (modebit & SPI_FREAD_DIO) { //SPI mode is DIO
|
||||||
|
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
||||||
|
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN_V, SPI0_R_DIO_ADDR_BITSLEN, SPI_USR_ADDR_BITLEN_S);
|
||||||
|
} else if(modebit & (SPI_FREAD_QUAD | SPI_FREAD_DUAL)) { //SPI mode is QOUT or DIO
|
||||||
|
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||||
|
switch (pfhdr->spi_speed) {
|
||||||
|
case ESP_IMAGE_SPI_SPEED_80M:
|
||||||
|
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||||
|
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_40M:
|
||||||
|
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||||
|
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_26M:
|
||||||
|
case ESP_IMAGE_SPI_SPEED_20M:
|
||||||
|
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||||
|
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + g_rom_spiflash_dummy_len_plus[0],
|
||||||
|
SPI_USR_DUMMY_CYCLELEN_S);
|
||||||
|
}
|
|
@ -27,6 +27,12 @@
|
||||||
#include "esp32/rom/cache.h"
|
#include "esp32/rom/cache.h"
|
||||||
#include "esp32/rom/spi_flash.h" /* TODO: Remove this */
|
#include "esp32/rom/spi_flash.h" /* TODO: Remove this */
|
||||||
|
|
||||||
|
/* This file implements FLASH ENCRYPTION related APIs to perform
|
||||||
|
* various operations such as programming necessary flash encryption
|
||||||
|
* eFuses, detect whether flash encryption is enabled (by reading eFuse)
|
||||||
|
* and if required encrypt the partitions in flash memory
|
||||||
|
*/
|
||||||
|
|
||||||
static const char *TAG = "flash_encrypt";
|
static const char *TAG = "flash_encrypt";
|
||||||
|
|
||||||
/* Static functions for stages of flash encryption */
|
/* Static functions for stages of flash encryption */
|
||||||
|
@ -203,7 +209,13 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
||||||
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == EFUSE_RD_FLASH_CRYPT_CNT (0x7F) */
|
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == EFUSE_RD_FLASH_CRYPT_CNT (0x7F) */
|
||||||
uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
||||||
ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
|
ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
|
||||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, new_flash_crypt_cnt);
|
uint32_t wdata0_reg = ((new_flash_crypt_cnt & EFUSE_FLASH_CRYPT_CNT) << EFUSE_FLASH_CRYPT_CNT_S);
|
||||||
|
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||||
|
ESP_LOGI(TAG, "Write protecting FLASH_CRYPT_CNT eFuse");
|
||||||
|
wdata0_reg |= EFUSE_WR_DIS_FLASH_CRYPT_CNT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
REG_WRITE(EFUSE_BLK0_WDATA0_REG, wdata0_reg);
|
||||||
esp_efuse_burn_new_values();
|
esp_efuse_burn_new_values();
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Flash encryption completed");
|
ESP_LOGI(TAG, "Flash encryption completed");
|
||||||
|
@ -338,13 +350,3 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
|
||||||
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
|
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void esp_flash_write_protect_crypt_cnt()
|
|
||||||
{
|
|
||||||
uint32_t efuse_blk0 = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
|
||||||
bool flash_crypt_wr_dis = efuse_blk0 & EFUSE_WR_DIS_FLASH_CRYPT_CNT;
|
|
||||||
if(!flash_crypt_wr_dis) {
|
|
||||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_FLASH_CRYPT_CNT);
|
|
||||||
esp_efuse_burn_new_values();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "esp32/rom/sha.h"
|
#include "esp32/rom/sha.h"
|
||||||
#include "uECC.h"
|
#include "uECC.h"
|
||||||
|
|
||||||
typedef SHA_CTX sha_context;
|
#include <sys/param.h>
|
||||||
|
|
||||||
static const char *TAG = "secure_boot";
|
static const char *TAG = "secure_boot";
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ extern const uint8_t signature_verification_key_end[] asm("_binary_signature_ver
|
||||||
|
|
||||||
#define DIGEST_LEN 32
|
#define DIGEST_LEN 32
|
||||||
|
|
||||||
|
/* Mmap source address mask */
|
||||||
|
#define MMAP_ALIGNED_MASK 0x0000FFFF
|
||||||
|
|
||||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||||
{
|
{
|
||||||
uint8_t digest[DIGEST_LEN];
|
uint8_t digest[DIGEST_LEN];
|
||||||
|
@ -40,21 +43,44 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||||
|
|
||||||
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
|
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
|
||||||
|
|
||||||
data = bootloader_mmap(src_addr, length + sizeof(esp_secure_boot_sig_block_t));
|
bootloader_sha256_handle_t handle = bootloader_sha256_start();
|
||||||
if (data == NULL) {
|
|
||||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length + sizeof(esp_secure_boot_sig_block_t));
|
uint32_t free_page_count = bootloader_mmap_get_free_pages();
|
||||||
|
ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
|
||||||
|
|
||||||
|
int32_t data_len_remain = length;
|
||||||
|
uint32_t data_addr = src_addr;
|
||||||
|
while (data_len_remain > 0) {
|
||||||
|
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||||
|
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||||
|
uint32_t data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||||
|
data = (const uint8_t *) bootloader_mmap(data_addr, data_len);
|
||||||
|
if(!data) {
|
||||||
|
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", data_addr, data_len);
|
||||||
|
bootloader_sha256_finish(handle, NULL);
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
bootloader_sha256_data(handle, data, data_len);
|
||||||
|
bootloader_munmap(data);
|
||||||
|
|
||||||
// Calculate digest of main image
|
data_addr += data_len;
|
||||||
bootloader_sha256_handle_t handle = bootloader_sha256_start();
|
data_len_remain -= data_len;
|
||||||
bootloader_sha256_data(handle, data, length);
|
}
|
||||||
|
|
||||||
|
/* Done! Get the digest */
|
||||||
bootloader_sha256_finish(handle, digest);
|
bootloader_sha256_finish(handle, digest);
|
||||||
|
|
||||||
// Map the signature block and verify the signature
|
// Map the signature block
|
||||||
sigblock = (const esp_secure_boot_sig_block_t *)(data + length);
|
sigblock = (const esp_secure_boot_sig_block_t *) bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
|
||||||
|
if(!sigblock) {
|
||||||
|
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
// Verify the signature
|
||||||
esp_err_t err = esp_secure_boot_verify_signature_block(sigblock, digest);
|
esp_err_t err = esp_secure_boot_verify_signature_block(sigblock, digest);
|
||||||
bootloader_munmap(data);
|
// Unmap
|
||||||
|
bootloader_munmap(sigblock);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "string.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp32/rom/gpio.h"
|
||||||
|
#include "esp32/rom/spi_flash.h"
|
||||||
|
#include "esp32/rom/efuse.h"
|
||||||
|
#include "soc/gpio_periph.h"
|
||||||
|
#include "soc/efuse_reg.h"
|
||||||
|
#include "soc/spi_reg.h"
|
||||||
|
#include "soc/spi_caps.h"
|
||||||
|
#include "flash_qio_mode.h"
|
||||||
|
#include "bootloader_flash_config.h"
|
||||||
|
|
||||||
|
void bootloader_flash_update_id()
|
||||||
|
{
|
||||||
|
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||||
|
{
|
||||||
|
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||||
|
SET_PERI_REG_MASK(SPI_USER_REG(1), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||||
|
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t* pfhdr)
|
||||||
|
{
|
||||||
|
uint32_t spi_clk_div = 0;
|
||||||
|
switch (pfhdr->spi_speed) {
|
||||||
|
case ESP_IMAGE_SPI_SPEED_80M:
|
||||||
|
spi_clk_div = 1;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_40M:
|
||||||
|
spi_clk_div = 2;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_26M:
|
||||||
|
spi_clk_div = 3;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_20M:
|
||||||
|
spi_clk_div = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
esp_rom_spiflash_config_clk(spi_clk_div, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr)
|
||||||
|
{
|
||||||
|
int spi_cache_dummy = 0;
|
||||||
|
uint32_t modebit = READ_PERI_REG(SPI_CTRL_REG(0));
|
||||||
|
if (modebit & SPI_FASTRD_MODE) {
|
||||||
|
if (modebit & SPI_FREAD_QIO) { //SPI mode is QIO
|
||||||
|
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
|
||||||
|
} else if (modebit & SPI_FREAD_DIO) { //SPI mode is DIO
|
||||||
|
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
||||||
|
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN_V, SPI0_R_DIO_ADDR_BITSLEN, SPI_USR_ADDR_BITLEN_S);
|
||||||
|
} else if(modebit & (SPI_FREAD_QUAD | SPI_FREAD_DUAL)) { //SPI mode is QOUT or DIO
|
||||||
|
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||||
|
switch (pfhdr->spi_speed) {
|
||||||
|
case ESP_IMAGE_SPI_SPEED_80M:
|
||||||
|
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||||
|
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_40M:
|
||||||
|
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||||
|
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||||
|
break;
|
||||||
|
case ESP_IMAGE_SPI_SPEED_26M:
|
||||||
|
case ESP_IMAGE_SPI_SPEED_20M:
|
||||||
|
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||||
|
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
||||||
|
SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||||
|
|
||||||
|
}
|
|
@ -380,24 +380,22 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||||
}
|
}
|
||||||
#endif // BOOTLOADER_BUILD
|
#endif // BOOTLOADER_BUILD
|
||||||
|
|
||||||
#ifndef BOOTLOADER_BUILD
|
uint32_t free_page_count = bootloader_mmap_get_free_pages();
|
||||||
uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
|
|
||||||
ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
|
ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
|
||||||
uint32_t offset_page = 0;
|
|
||||||
while (data_len >= free_page_count * SPI_FLASH_MMU_PAGE_SIZE) {
|
int32_t data_len_remain = data_len;
|
||||||
offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
while (data_len_remain > 0) {
|
||||||
err = process_segment_data(load_addr, data_addr, (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE, do_load, sha_handle, checksum);
|
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||||
if (err != ESP_OK) {
|
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||||
return err;
|
data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||||
}
|
|
||||||
data_addr += (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
|
|
||||||
data_len -= (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
|
err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
data_addr += data_len;
|
||||||
|
data_len_remain -= data_len;
|
||||||
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
52
components/bootloader_support/src/flash_encrypt.c
Normal file
52
components/bootloader_support/src/flash_encrypt.c
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// 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 <strings.h>
|
||||||
|
#include "esp_efuse.h"
|
||||||
|
#include "esp_efuse_table.h"
|
||||||
|
#include "esp_flash_encrypt.h"
|
||||||
|
|
||||||
|
void esp_flash_write_protect_crypt_cnt()
|
||||||
|
{
|
||||||
|
uint8_t flash_crypt_cnt_wr_dis = 0;
|
||||||
|
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
|
||||||
|
if (!flash_crypt_cnt_wr_dis) {
|
||||||
|
esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_flash_enc_mode_t esp_get_flash_encryption_mode()
|
||||||
|
{
|
||||||
|
uint8_t efuse_flash_crypt_cnt_wr_protected = 0;
|
||||||
|
uint8_t dis_dl_enc = 0, dis_dl_dec = 0, dis_dl_cache = 0;
|
||||||
|
esp_flash_enc_mode_t mode = ESP_FLASH_ENC_MODE_DEVELOPMENT;
|
||||||
|
|
||||||
|
if (esp_flash_encryption_enabled()) {
|
||||||
|
/* Check if FLASH CRYPT CNT is write protected */
|
||||||
|
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &efuse_flash_crypt_cnt_wr_protected, 1);
|
||||||
|
if (efuse_flash_crypt_cnt_wr_protected) {
|
||||||
|
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_CACHE, &dis_dl_cache, 1);
|
||||||
|
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_ENCRYPT, &dis_dl_enc, 1);
|
||||||
|
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_DECRYPT, &dis_dl_dec, 1);
|
||||||
|
/* Check if DISABLE_DL_DECRYPT, DISABLE_DL_ENCRYPT & DISABLE_DL_CACHE are set */
|
||||||
|
if ( dis_dl_cache && dis_dl_enc && dis_dl_dec ) {
|
||||||
|
mode = ESP_FLASH_ENC_MODE_RELEASE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mode = ESP_FLASH_ENC_MODE_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
set(COMPONENT_SRCDIRS ".")
|
idf_component_register(SRC_DIRS "."
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES unity bootloader_support app_update)
|
||||||
set(COMPONENT_REQUIRES unity bootloader_support app_update)
|
|
||||||
|
|
||||||
register_component()
|
|
||||||
|
|
|
@ -1,300 +1,510 @@
|
||||||
if(CONFIG_BT_ENABLED)
|
if(CONFIG_BT_ENABLED)
|
||||||
|
|
||||||
set(COMPONENT_SRCS "bt.c")
|
set(srcs "controller/bt.c")
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS include)
|
set(include_dirs include
|
||||||
|
common/osi/include)
|
||||||
|
|
||||||
|
list(APPEND priv_include_dirs
|
||||||
|
common/btc/include
|
||||||
|
common/include)
|
||||||
|
|
||||||
|
list(APPEND srcs "common/btc/core/btc_alarm.c"
|
||||||
|
"common/btc/core/btc_manage.c"
|
||||||
|
"common/btc/core/btc_task.c"
|
||||||
|
"common/osi/alarm.c"
|
||||||
|
"common/osi/allocator.c"
|
||||||
|
"common/osi/buffer.c"
|
||||||
|
"common/osi/config.c"
|
||||||
|
"common/osi/fixed_queue.c"
|
||||||
|
"common/osi/future.c"
|
||||||
|
"common/osi/hash_functions.c"
|
||||||
|
"common/osi/hash_map.c"
|
||||||
|
"common/osi/list.c"
|
||||||
|
"common/osi/mutex.c"
|
||||||
|
"common/osi/thread.c"
|
||||||
|
"common/osi/osi.c"
|
||||||
|
"common/osi/semaphore.c")
|
||||||
|
|
||||||
if(CONFIG_BT_BLUEDROID_ENABLED)
|
if(CONFIG_BT_BLUEDROID_ENABLED)
|
||||||
|
|
||||||
list(APPEND COMPONENT_PRIV_INCLUDEDIRS
|
list(APPEND priv_include_dirs
|
||||||
bluedroid/bta/include
|
host/bluedroid/bta/include
|
||||||
bluedroid/bta/ar/include
|
host/bluedroid/bta/ar/include
|
||||||
bluedroid/bta/av/include
|
host/bluedroid/bta/av/include
|
||||||
bluedroid/bta/dm/include
|
host/bluedroid/bta/dm/include
|
||||||
bluedroid/bta/gatt/include
|
host/bluedroid/bta/gatt/include
|
||||||
bluedroid/bta/hf_client/include
|
host/bluedroid/bta/hf_client/include
|
||||||
bluedroid/bta/hh/include
|
host/bluedroid/bta/hh/include
|
||||||
bluedroid/bta/jv/include
|
host/bluedroid/bta/jv/include
|
||||||
bluedroid/bta/sdp/include
|
host/bluedroid/bta/sdp/include
|
||||||
bluedroid/bta/sys/include
|
host/bluedroid/bta/sys/include
|
||||||
bluedroid/device/include
|
host/bluedroid/device/include
|
||||||
bluedroid/hci/include
|
host/bluedroid/hci/include
|
||||||
bluedroid/osi/include
|
host/bluedroid/external/sbc/decoder/include
|
||||||
bluedroid/external/sbc/decoder/include
|
host/bluedroid/external/sbc/encoder/include
|
||||||
bluedroid/external/sbc/encoder/include
|
host/bluedroid/external/sbc/plc/include
|
||||||
bluedroid/external/sbc/plc/include
|
host/bluedroid/btc/profile/esp/blufi/include
|
||||||
bluedroid/btc/profile/esp/blufi/include
|
host/bluedroid/btc/profile/esp/include
|
||||||
bluedroid/btc/profile/esp/include
|
host/bluedroid/btc/profile/std/a2dp/include
|
||||||
bluedroid/btc/profile/std/a2dp/include
|
host/bluedroid/btc/profile/std/include
|
||||||
bluedroid/btc/profile/std/include
|
host/bluedroid/btc/include
|
||||||
bluedroid/btc/include
|
host/bluedroid/stack/btm/include
|
||||||
bluedroid/stack/btm/include
|
host/bluedroid/stack/gap/include
|
||||||
bluedroid/stack/gap/include
|
host/bluedroid/stack/gatt/include
|
||||||
bluedroid/stack/gatt/include
|
host/bluedroid/stack/l2cap/include
|
||||||
bluedroid/stack/l2cap/include
|
host/bluedroid/stack/sdp/include
|
||||||
bluedroid/stack/sdp/include
|
host/bluedroid/stack/smp/include
|
||||||
bluedroid/stack/smp/include
|
host/bluedroid/stack/avct/include
|
||||||
bluedroid/stack/avct/include
|
host/bluedroid/stack/avrc/include
|
||||||
bluedroid/stack/avrc/include
|
host/bluedroid/stack/avdt/include
|
||||||
bluedroid/stack/avdt/include
|
host/bluedroid/stack/a2dp/include
|
||||||
bluedroid/stack/a2dp/include
|
host/bluedroid/stack/rfcomm/include
|
||||||
bluedroid/stack/rfcomm/include
|
host/bluedroid/stack/include
|
||||||
bluedroid/stack/include
|
host/bluedroid/common/include)
|
||||||
bluedroid/common/include)
|
|
||||||
|
|
||||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS bluedroid/api/include/api)
|
list(APPEND include_dirs host/bluedroid/api/include/api)
|
||||||
|
|
||||||
list(APPEND COMPONENT_SRCS "bluedroid/api/esp_a2dp_api.c"
|
list(APPEND srcs "host/bluedroid/api/esp_a2dp_api.c"
|
||||||
"bluedroid/api/esp_avrc_api.c"
|
"host/bluedroid/api/esp_avrc_api.c"
|
||||||
"bluedroid/api/esp_blufi_api.c"
|
"host/bluedroid/api/esp_blufi_api.c"
|
||||||
"bluedroid/api/esp_bt_device.c"
|
"host/bluedroid/api/esp_bt_device.c"
|
||||||
"bluedroid/api/esp_bt_main.c"
|
"host/bluedroid/api/esp_bt_main.c"
|
||||||
"bluedroid/api/esp_gap_ble_api.c"
|
"host/bluedroid/api/esp_gap_ble_api.c"
|
||||||
"bluedroid/api/esp_gap_bt_api.c"
|
"host/bluedroid/api/esp_gap_bt_api.c"
|
||||||
"bluedroid/api/esp_gatt_common_api.c"
|
"host/bluedroid/api/esp_gatt_common_api.c"
|
||||||
"bluedroid/api/esp_gattc_api.c"
|
"host/bluedroid/api/esp_gattc_api.c"
|
||||||
"bluedroid/api/esp_gatts_api.c"
|
"host/bluedroid/api/esp_gatts_api.c"
|
||||||
"bluedroid/api/esp_hf_client_api.c"
|
"host/bluedroid/api/esp_hf_client_api.c"
|
||||||
"bluedroid/api/esp_spp_api.c"
|
"host/bluedroid/api/esp_spp_api.c"
|
||||||
"bluedroid/bta/ar/bta_ar.c"
|
"host/bluedroid/bta/ar/bta_ar.c"
|
||||||
"bluedroid/bta/av/bta_av_aact.c"
|
"host/bluedroid/bta/av/bta_av_aact.c"
|
||||||
"bluedroid/bta/av/bta_av_act.c"
|
"host/bluedroid/bta/av/bta_av_act.c"
|
||||||
"bluedroid/bta/av/bta_av_api.c"
|
"host/bluedroid/bta/av/bta_av_api.c"
|
||||||
"bluedroid/bta/av/bta_av_cfg.c"
|
"host/bluedroid/bta/av/bta_av_cfg.c"
|
||||||
"bluedroid/bta/av/bta_av_ci.c"
|
"host/bluedroid/bta/av/bta_av_ci.c"
|
||||||
"bluedroid/bta/av/bta_av_main.c"
|
"host/bluedroid/bta/av/bta_av_main.c"
|
||||||
"bluedroid/bta/av/bta_av_sbc.c"
|
"host/bluedroid/bta/av/bta_av_sbc.c"
|
||||||
"bluedroid/bta/av/bta_av_ssm.c"
|
"host/bluedroid/bta/av/bta_av_ssm.c"
|
||||||
"bluedroid/bta/dm/bta_dm_act.c"
|
"host/bluedroid/bta/dm/bta_dm_act.c"
|
||||||
"bluedroid/bta/dm/bta_dm_api.c"
|
"host/bluedroid/bta/dm/bta_dm_api.c"
|
||||||
"bluedroid/bta/dm/bta_dm_cfg.c"
|
"host/bluedroid/bta/dm/bta_dm_cfg.c"
|
||||||
"bluedroid/bta/dm/bta_dm_ci.c"
|
"host/bluedroid/bta/dm/bta_dm_ci.c"
|
||||||
"bluedroid/bta/dm/bta_dm_co.c"
|
"host/bluedroid/bta/dm/bta_dm_co.c"
|
||||||
"bluedroid/bta/dm/bta_dm_main.c"
|
"host/bluedroid/bta/dm/bta_dm_main.c"
|
||||||
"bluedroid/bta/dm/bta_dm_pm.c"
|
"host/bluedroid/bta/dm/bta_dm_pm.c"
|
||||||
"bluedroid/bta/dm/bta_dm_sco.c"
|
"host/bluedroid/bta/dm/bta_dm_sco.c"
|
||||||
"bluedroid/bta/gatt/bta_gatt_common.c"
|
"host/bluedroid/bta/gatt/bta_gatt_common.c"
|
||||||
"bluedroid/bta/gatt/bta_gattc_act.c"
|
"host/bluedroid/bta/gatt/bta_gattc_act.c"
|
||||||
"bluedroid/bta/gatt/bta_gattc_api.c"
|
"host/bluedroid/bta/gatt/bta_gattc_api.c"
|
||||||
"bluedroid/bta/gatt/bta_gattc_cache.c"
|
"host/bluedroid/bta/gatt/bta_gattc_cache.c"
|
||||||
"bluedroid/bta/gatt/bta_gattc_ci.c"
|
"host/bluedroid/bta/gatt/bta_gattc_ci.c"
|
||||||
"bluedroid/bta/gatt/bta_gattc_co.c"
|
"host/bluedroid/bta/gatt/bta_gattc_co.c"
|
||||||
"bluedroid/bta/gatt/bta_gattc_main.c"
|
"host/bluedroid/bta/gatt/bta_gattc_main.c"
|
||||||
"bluedroid/bta/gatt/bta_gattc_utils.c"
|
"host/bluedroid/bta/gatt/bta_gattc_utils.c"
|
||||||
"bluedroid/bta/gatt/bta_gatts_act.c"
|
"host/bluedroid/bta/gatt/bta_gatts_act.c"
|
||||||
"bluedroid/bta/gatt/bta_gatts_api.c"
|
"host/bluedroid/bta/gatt/bta_gatts_api.c"
|
||||||
"bluedroid/bta/gatt/bta_gatts_co.c"
|
"host/bluedroid/bta/gatt/bta_gatts_co.c"
|
||||||
"bluedroid/bta/gatt/bta_gatts_main.c"
|
"host/bluedroid/bta/gatt/bta_gatts_main.c"
|
||||||
"bluedroid/bta/gatt/bta_gatts_utils.c"
|
"host/bluedroid/bta/gatt/bta_gatts_utils.c"
|
||||||
"bluedroid/bta/hh/bta_hh_act.c"
|
"host/bluedroid/bta/hh/bta_hh_act.c"
|
||||||
"bluedroid/bta/hh/bta_hh_api.c"
|
"host/bluedroid/bta/hh/bta_hh_api.c"
|
||||||
"bluedroid/bta/hh/bta_hh_cfg.c"
|
"host/bluedroid/bta/hh/bta_hh_cfg.c"
|
||||||
"bluedroid/bta/hh/bta_hh_le.c"
|
"host/bluedroid/bta/hh/bta_hh_le.c"
|
||||||
"bluedroid/bta/hh/bta_hh_main.c"
|
"host/bluedroid/bta/hh/bta_hh_main.c"
|
||||||
"bluedroid/bta/hh/bta_hh_utils.c"
|
"host/bluedroid/bta/hh/bta_hh_utils.c"
|
||||||
"bluedroid/bta/jv/bta_jv_act.c"
|
"host/bluedroid/bta/jv/bta_jv_act.c"
|
||||||
"bluedroid/bta/jv/bta_jv_api.c"
|
"host/bluedroid/bta/jv/bta_jv_api.c"
|
||||||
"bluedroid/bta/jv/bta_jv_cfg.c"
|
"host/bluedroid/bta/jv/bta_jv_cfg.c"
|
||||||
"bluedroid/bta/jv/bta_jv_main.c"
|
"host/bluedroid/bta/jv/bta_jv_main.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_act.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_act.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_api.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_api.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_at.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_at.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_cmd.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_cmd.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_main.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_main.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_rfc.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_rfc.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_sco.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_sco.c"
|
||||||
"bluedroid/bta/hf_client/bta_hf_client_sdp.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_sdp.c"
|
||||||
"bluedroid/bta/sdp/bta_sdp.c"
|
"host/bluedroid/bta/sdp/bta_sdp.c"
|
||||||
"bluedroid/bta/sdp/bta_sdp_act.c"
|
"host/bluedroid/bta/sdp/bta_sdp_act.c"
|
||||||
"bluedroid/bta/sdp/bta_sdp_api.c"
|
"host/bluedroid/bta/sdp/bta_sdp_api.c"
|
||||||
"bluedroid/bta/sdp/bta_sdp_cfg.c"
|
"host/bluedroid/bta/sdp/bta_sdp_cfg.c"
|
||||||
"bluedroid/bta/sys/bta_sys_conn.c"
|
"host/bluedroid/bta/sys/bta_sys_conn.c"
|
||||||
"bluedroid/bta/sys/bta_sys_main.c"
|
"host/bluedroid/bta/sys/bta_sys_main.c"
|
||||||
"bluedroid/bta/sys/utl.c"
|
"host/bluedroid/bta/sys/utl.c"
|
||||||
"bluedroid/btc/core/btc_alarm.c"
|
"host/bluedroid/btc/core/btc_ble_storage.c"
|
||||||
"bluedroid/btc/core/btc_ble_storage.c"
|
"host/bluedroid/btc/core/btc_config.c"
|
||||||
"bluedroid/btc/core/btc_config.c"
|
"host/bluedroid/btc/core/btc_dev.c"
|
||||||
"bluedroid/btc/core/btc_dev.c"
|
"host/bluedroid/btc/core/btc_dm.c"
|
||||||
"bluedroid/btc/core/btc_dm.c"
|
"host/bluedroid/btc/core/btc_main.c"
|
||||||
"bluedroid/btc/core/btc_main.c"
|
"host/bluedroid/btc/core/btc_profile_queue.c"
|
||||||
"bluedroid/btc/core/btc_manage.c"
|
"host/bluedroid/btc/core/btc_sec.c"
|
||||||
"bluedroid/btc/core/btc_profile_queue.c"
|
"host/bluedroid/btc/core/btc_sm.c"
|
||||||
"bluedroid/btc/core/btc_sec.c"
|
"host/bluedroid/btc/core/btc_storage.c"
|
||||||
"bluedroid/btc/core/btc_sm.c"
|
"host/bluedroid/btc/core/btc_util.c"
|
||||||
"bluedroid/btc/core/btc_storage.c"
|
"host/bluedroid/btc/profile/esp/blufi/blufi_prf.c"
|
||||||
"bluedroid/btc/core/btc_task.c"
|
"host/bluedroid/btc/profile/esp/blufi/blufi_protocol.c"
|
||||||
"bluedroid/btc/core/btc_util.c"
|
"host/bluedroid/btc/profile/std/a2dp/bta_av_co.c"
|
||||||
"bluedroid/btc/profile/esp/blufi/blufi_prf.c"
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c"
|
||||||
"bluedroid/btc/profile/esp/blufi/blufi_protocol.c"
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c"
|
||||||
"bluedroid/btc/profile/std/a2dp/bta_av_co.c"
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c"
|
||||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp.c"
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c"
|
||||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c"
|
"host/bluedroid/btc/profile/std/a2dp/btc_av.c"
|
||||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c"
|
"host/bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
||||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c"
|
"host/bluedroid/btc/profile/std/avrc/bta_avrc_co.c"
|
||||||
"bluedroid/btc/profile/std/a2dp/btc_av.c"
|
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
||||||
"bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
||||||
"bluedroid/btc/profile/std/avrc/bta_avrc_co.c"
|
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||||
"bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
"host/bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
||||||
"bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
"host/bluedroid/btc/profile/std/gap/bta_gap_bt_co.c"
|
||||||
"bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
"host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c"
|
||||||
"bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
"host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c"
|
||||||
"bluedroid/btc/profile/std/gatt/btc_gatt_common.c"
|
"host/bluedroid/btc/profile/std/gatt/btc_gattc.c"
|
||||||
"bluedroid/btc/profile/std/gatt/btc_gatt_util.c"
|
"host/bluedroid/btc/profile/std/gatt/btc_gatts.c"
|
||||||
"bluedroid/btc/profile/std/gatt/btc_gattc.c"
|
"host/bluedroid/btc/profile/std/spp/btc_spp.c"
|
||||||
"bluedroid/btc/profile/std/gatt/btc_gatts.c"
|
"host/bluedroid/device/bdaddr.c"
|
||||||
"bluedroid/btc/profile/std/spp/btc_spp.c"
|
"host/bluedroid/device/controller.c"
|
||||||
"bluedroid/device/bdaddr.c"
|
"host/bluedroid/device/interop.c"
|
||||||
"bluedroid/device/controller.c"
|
"host/bluedroid/external/sbc/decoder/srce/alloc.c"
|
||||||
"bluedroid/device/interop.c"
|
"host/bluedroid/external/sbc/decoder/srce/bitalloc-sbc.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/alloc.c"
|
"host/bluedroid/external/sbc/decoder/srce/bitalloc.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/bitalloc-sbc.c"
|
"host/bluedroid/external/sbc/decoder/srce/bitstream-decode.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/bitalloc.c"
|
"host/bluedroid/external/sbc/decoder/srce/decoder-oina.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/bitstream-decode.c"
|
"host/bluedroid/external/sbc/decoder/srce/decoder-private.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/decoder-oina.c"
|
"host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/decoder-private.c"
|
"host/bluedroid/external/sbc/decoder/srce/dequant.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/decoder-sbc.c"
|
"host/bluedroid/external/sbc/decoder/srce/framing-sbc.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/dequant.c"
|
"host/bluedroid/external/sbc/decoder/srce/framing.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/framing-sbc.c"
|
"host/bluedroid/external/sbc/decoder/srce/oi_codec_version.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/framing.c"
|
"host/bluedroid/external/sbc/decoder/srce/synthesis-8-generated.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/oi_codec_version.c"
|
"host/bluedroid/external/sbc/decoder/srce/synthesis-dct8.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/synthesis-8-generated.c"
|
"host/bluedroid/external/sbc/decoder/srce/synthesis-sbc.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/synthesis-dct8.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_analysis.c"
|
||||||
"bluedroid/external/sbc/decoder/srce/synthesis-sbc.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_dct.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_analysis.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_dct_coeffs.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_dct.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_dct_coeffs.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_coeffs.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_enc_coeffs.c"
|
"host/bluedroid/external/sbc/encoder/srce/sbc_packing.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_encoder.c"
|
"host/bluedroid/external/sbc/plc/sbc_plc.c"
|
||||||
"bluedroid/external/sbc/encoder/srce/sbc_packing.c"
|
"host/bluedroid/hci/hci_audio.c"
|
||||||
"bluedroid/external/sbc/plc/sbc_plc.c"
|
"host/bluedroid/hci/hci_hal_h4.c"
|
||||||
"bluedroid/hci/hci_audio.c"
|
"host/bluedroid/hci/hci_layer.c"
|
||||||
"bluedroid/hci/hci_hal_h4.c"
|
"host/bluedroid/hci/hci_packet_factory.c"
|
||||||
"bluedroid/hci/hci_layer.c"
|
"host/bluedroid/hci/hci_packet_parser.c"
|
||||||
"bluedroid/hci/hci_packet_factory.c"
|
"host/bluedroid/hci/packet_fragmenter.c"
|
||||||
"bluedroid/hci/hci_packet_parser.c"
|
"host/bluedroid/main/bte_init.c"
|
||||||
"bluedroid/hci/packet_fragmenter.c"
|
"host/bluedroid/main/bte_main.c"
|
||||||
"bluedroid/main/bte_init.c"
|
"host/bluedroid/stack/a2dp/a2d_api.c"
|
||||||
"bluedroid/main/bte_main.c"
|
"host/bluedroid/stack/a2dp/a2d_sbc.c"
|
||||||
"bluedroid/osi/alarm.c"
|
"host/bluedroid/stack/avct/avct_api.c"
|
||||||
"bluedroid/osi/allocator.c"
|
"host/bluedroid/stack/avct/avct_ccb.c"
|
||||||
"bluedroid/osi/buffer.c"
|
"host/bluedroid/stack/avct/avct_l2c.c"
|
||||||
"bluedroid/osi/config.c"
|
"host/bluedroid/stack/avct/avct_lcb.c"
|
||||||
"bluedroid/osi/fixed_queue.c"
|
"host/bluedroid/stack/avct/avct_lcb_act.c"
|
||||||
"bluedroid/osi/future.c"
|
"host/bluedroid/stack/avdt/avdt_ad.c"
|
||||||
"bluedroid/osi/hash_functions.c"
|
"host/bluedroid/stack/avdt/avdt_api.c"
|
||||||
"bluedroid/osi/hash_map.c"
|
"host/bluedroid/stack/avdt/avdt_ccb.c"
|
||||||
"bluedroid/osi/list.c"
|
"host/bluedroid/stack/avdt/avdt_ccb_act.c"
|
||||||
"bluedroid/osi/mutex.c"
|
"host/bluedroid/stack/avdt/avdt_l2c.c"
|
||||||
"bluedroid/osi/osi.c"
|
"host/bluedroid/stack/avdt/avdt_msg.c"
|
||||||
"bluedroid/osi/semaphore.c"
|
"host/bluedroid/stack/avdt/avdt_scb.c"
|
||||||
"bluedroid/stack/a2dp/a2d_api.c"
|
"host/bluedroid/stack/avdt/avdt_scb_act.c"
|
||||||
"bluedroid/stack/a2dp/a2d_sbc.c"
|
"host/bluedroid/stack/avrc/avrc_api.c"
|
||||||
"bluedroid/stack/avct/avct_api.c"
|
"host/bluedroid/stack/avrc/avrc_bld_ct.c"
|
||||||
"bluedroid/stack/avct/avct_ccb.c"
|
"host/bluedroid/stack/avrc/avrc_bld_tg.c"
|
||||||
"bluedroid/stack/avct/avct_l2c.c"
|
"host/bluedroid/stack/avrc/avrc_opt.c"
|
||||||
"bluedroid/stack/avct/avct_lcb.c"
|
"host/bluedroid/stack/avrc/avrc_pars_ct.c"
|
||||||
"bluedroid/stack/avct/avct_lcb_act.c"
|
"host/bluedroid/stack/avrc/avrc_pars_tg.c"
|
||||||
"bluedroid/stack/avdt/avdt_ad.c"
|
"host/bluedroid/stack/avrc/avrc_sdp.c"
|
||||||
"bluedroid/stack/avdt/avdt_api.c"
|
"host/bluedroid/stack/avrc/avrc_utils.c"
|
||||||
"bluedroid/stack/avdt/avdt_ccb.c"
|
"host/bluedroid/stack/btm/btm_acl.c"
|
||||||
"bluedroid/stack/avdt/avdt_ccb_act.c"
|
"host/bluedroid/stack/btm/btm_ble.c"
|
||||||
"bluedroid/stack/avdt/avdt_l2c.c"
|
"host/bluedroid/stack/btm/btm_ble_addr.c"
|
||||||
"bluedroid/stack/avdt/avdt_msg.c"
|
"host/bluedroid/stack/btm/btm_ble_adv_filter.c"
|
||||||
"bluedroid/stack/avdt/avdt_scb.c"
|
"host/bluedroid/stack/btm/btm_ble_batchscan.c"
|
||||||
"bluedroid/stack/avdt/avdt_scb_act.c"
|
"host/bluedroid/stack/btm/btm_ble_bgconn.c"
|
||||||
"bluedroid/stack/avrc/avrc_api.c"
|
"host/bluedroid/stack/btm/btm_ble_cont_energy.c"
|
||||||
"bluedroid/stack/avrc/avrc_bld_ct.c"
|
"host/bluedroid/stack/btm/btm_ble_gap.c"
|
||||||
"bluedroid/stack/avrc/avrc_bld_tg.c"
|
"host/bluedroid/stack/btm/btm_ble_multi_adv.c"
|
||||||
"bluedroid/stack/avrc/avrc_opt.c"
|
"host/bluedroid/stack/btm/btm_ble_privacy.c"
|
||||||
"bluedroid/stack/avrc/avrc_pars_ct.c"
|
"host/bluedroid/stack/btm/btm_dev.c"
|
||||||
"bluedroid/stack/avrc/avrc_pars_tg.c"
|
"host/bluedroid/stack/btm/btm_devctl.c"
|
||||||
"bluedroid/stack/avrc/avrc_sdp.c"
|
"host/bluedroid/stack/btm/btm_inq.c"
|
||||||
"bluedroid/stack/avrc/avrc_utils.c"
|
"host/bluedroid/stack/btm/btm_main.c"
|
||||||
"bluedroid/stack/btm/btm_acl.c"
|
"host/bluedroid/stack/btm/btm_pm.c"
|
||||||
"bluedroid/stack/btm/btm_ble.c"
|
"host/bluedroid/stack/btm/btm_sco.c"
|
||||||
"bluedroid/stack/btm/btm_ble_addr.c"
|
"host/bluedroid/stack/btm/btm_sec.c"
|
||||||
"bluedroid/stack/btm/btm_ble_adv_filter.c"
|
"host/bluedroid/stack/btu/btu_hcif.c"
|
||||||
"bluedroid/stack/btm/btm_ble_batchscan.c"
|
"host/bluedroid/stack/btu/btu_init.c"
|
||||||
"bluedroid/stack/btm/btm_ble_bgconn.c"
|
"host/bluedroid/stack/btu/btu_task.c"
|
||||||
"bluedroid/stack/btm/btm_ble_cont_energy.c"
|
"host/bluedroid/stack/gap/gap_api.c"
|
||||||
"bluedroid/stack/btm/btm_ble_gap.c"
|
"host/bluedroid/stack/gap/gap_ble.c"
|
||||||
"bluedroid/stack/btm/btm_ble_multi_adv.c"
|
"host/bluedroid/stack/gap/gap_conn.c"
|
||||||
"bluedroid/stack/btm/btm_ble_privacy.c"
|
"host/bluedroid/stack/gap/gap_utils.c"
|
||||||
"bluedroid/stack/btm/btm_dev.c"
|
"host/bluedroid/stack/gatt/att_protocol.c"
|
||||||
"bluedroid/stack/btm/btm_devctl.c"
|
"host/bluedroid/stack/gatt/gatt_api.c"
|
||||||
"bluedroid/stack/btm/btm_inq.c"
|
"host/bluedroid/stack/gatt/gatt_attr.c"
|
||||||
"bluedroid/stack/btm/btm_main.c"
|
"host/bluedroid/stack/gatt/gatt_auth.c"
|
||||||
"bluedroid/stack/btm/btm_pm.c"
|
"host/bluedroid/stack/gatt/gatt_cl.c"
|
||||||
"bluedroid/stack/btm/btm_sco.c"
|
"host/bluedroid/stack/gatt/gatt_db.c"
|
||||||
"bluedroid/stack/btm/btm_sec.c"
|
"host/bluedroid/stack/gatt/gatt_main.c"
|
||||||
"bluedroid/stack/btu/btu_hcif.c"
|
"host/bluedroid/stack/gatt/gatt_sr.c"
|
||||||
"bluedroid/stack/btu/btu_init.c"
|
"host/bluedroid/stack/gatt/gatt_utils.c"
|
||||||
"bluedroid/stack/btu/btu_task.c"
|
"host/bluedroid/stack/hcic/hciblecmds.c"
|
||||||
"bluedroid/stack/gap/gap_api.c"
|
"host/bluedroid/stack/hcic/hcicmds.c"
|
||||||
"bluedroid/stack/gap/gap_ble.c"
|
"host/bluedroid/stack/l2cap/l2c_api.c"
|
||||||
"bluedroid/stack/gap/gap_conn.c"
|
"host/bluedroid/stack/l2cap/l2c_ble.c"
|
||||||
"bluedroid/stack/gap/gap_utils.c"
|
"host/bluedroid/stack/l2cap/l2c_csm.c"
|
||||||
"bluedroid/stack/gatt/att_protocol.c"
|
"host/bluedroid/stack/l2cap/l2c_fcr.c"
|
||||||
"bluedroid/stack/gatt/gatt_api.c"
|
"host/bluedroid/stack/l2cap/l2c_link.c"
|
||||||
"bluedroid/stack/gatt/gatt_attr.c"
|
"host/bluedroid/stack/l2cap/l2c_main.c"
|
||||||
"bluedroid/stack/gatt/gatt_auth.c"
|
"host/bluedroid/stack/l2cap/l2c_ucd.c"
|
||||||
"bluedroid/stack/gatt/gatt_cl.c"
|
"host/bluedroid/stack/l2cap/l2c_utils.c"
|
||||||
"bluedroid/stack/gatt/gatt_db.c"
|
"host/bluedroid/stack/l2cap/l2cap_client.c"
|
||||||
"bluedroid/stack/gatt/gatt_main.c"
|
"host/bluedroid/stack/rfcomm/port_api.c"
|
||||||
"bluedroid/stack/gatt/gatt_sr.c"
|
"host/bluedroid/stack/rfcomm/port_rfc.c"
|
||||||
"bluedroid/stack/gatt/gatt_utils.c"
|
"host/bluedroid/stack/rfcomm/port_utils.c"
|
||||||
"bluedroid/stack/hcic/hciblecmds.c"
|
"host/bluedroid/stack/rfcomm/rfc_l2cap_if.c"
|
||||||
"bluedroid/stack/hcic/hcicmds.c"
|
"host/bluedroid/stack/rfcomm/rfc_mx_fsm.c"
|
||||||
"bluedroid/stack/l2cap/l2c_api.c"
|
"host/bluedroid/stack/rfcomm/rfc_port_fsm.c"
|
||||||
"bluedroid/stack/l2cap/l2c_ble.c"
|
"host/bluedroid/stack/rfcomm/rfc_port_if.c"
|
||||||
"bluedroid/stack/l2cap/l2c_csm.c"
|
"host/bluedroid/stack/rfcomm/rfc_ts_frames.c"
|
||||||
"bluedroid/stack/l2cap/l2c_fcr.c"
|
"host/bluedroid/stack/rfcomm/rfc_utils.c"
|
||||||
"bluedroid/stack/l2cap/l2c_link.c"
|
"host/bluedroid/stack/sdp/sdp_api.c"
|
||||||
"bluedroid/stack/l2cap/l2c_main.c"
|
"host/bluedroid/stack/sdp/sdp_db.c"
|
||||||
"bluedroid/stack/l2cap/l2c_ucd.c"
|
"host/bluedroid/stack/sdp/sdp_discovery.c"
|
||||||
"bluedroid/stack/l2cap/l2c_utils.c"
|
"host/bluedroid/stack/sdp/sdp_main.c"
|
||||||
"bluedroid/stack/l2cap/l2cap_client.c"
|
"host/bluedroid/stack/sdp/sdp_server.c"
|
||||||
"bluedroid/stack/rfcomm/port_api.c"
|
"host/bluedroid/stack/sdp/sdp_utils.c"
|
||||||
"bluedroid/stack/rfcomm/port_rfc.c"
|
"host/bluedroid/stack/smp/aes.c"
|
||||||
"bluedroid/stack/rfcomm/port_utils.c"
|
"host/bluedroid/stack/smp/p_256_curvepara.c"
|
||||||
"bluedroid/stack/rfcomm/rfc_l2cap_if.c"
|
"host/bluedroid/stack/smp/p_256_ecc_pp.c"
|
||||||
"bluedroid/stack/rfcomm/rfc_mx_fsm.c"
|
"host/bluedroid/stack/smp/p_256_multprecision.c"
|
||||||
"bluedroid/stack/rfcomm/rfc_port_fsm.c"
|
"host/bluedroid/stack/smp/smp_act.c"
|
||||||
"bluedroid/stack/rfcomm/rfc_port_if.c"
|
"host/bluedroid/stack/smp/smp_api.c"
|
||||||
"bluedroid/stack/rfcomm/rfc_ts_frames.c"
|
"host/bluedroid/stack/smp/smp_br_main.c"
|
||||||
"bluedroid/stack/rfcomm/rfc_utils.c"
|
"host/bluedroid/stack/smp/smp_cmac.c"
|
||||||
"bluedroid/stack/sdp/sdp_api.c"
|
"host/bluedroid/stack/smp/smp_keys.c"
|
||||||
"bluedroid/stack/sdp/sdp_db.c"
|
"host/bluedroid/stack/smp/smp_l2c.c"
|
||||||
"bluedroid/stack/sdp/sdp_discovery.c"
|
"host/bluedroid/stack/smp/smp_main.c"
|
||||||
"bluedroid/stack/sdp/sdp_main.c"
|
"host/bluedroid/stack/smp/smp_utils.c")
|
||||||
"bluedroid/stack/sdp/sdp_server.c"
|
endif()
|
||||||
"bluedroid/stack/sdp/sdp_utils.c"
|
|
||||||
"bluedroid/stack/smp/aes.c"
|
if(CONFIG_BLE_MESH)
|
||||||
"bluedroid/stack/smp/p_256_curvepara.c"
|
list(APPEND include_dirs
|
||||||
"bluedroid/stack/smp/p_256_ecc_pp.c"
|
"esp_ble_mesh/mesh_core"
|
||||||
"bluedroid/stack/smp/p_256_multprecision.c"
|
"esp_ble_mesh/mesh_core/include"
|
||||||
"bluedroid/stack/smp/smp_act.c"
|
"esp_ble_mesh/mesh_core/settings"
|
||||||
"bluedroid/stack/smp/smp_api.c"
|
"esp_ble_mesh/btc/include"
|
||||||
"bluedroid/stack/smp/smp_br_main.c"
|
"esp_ble_mesh/mesh_models/include"
|
||||||
"bluedroid/stack/smp/smp_cmac.c"
|
"esp_ble_mesh/api/core/include"
|
||||||
"bluedroid/stack/smp/smp_keys.c"
|
"esp_ble_mesh/api/models/include"
|
||||||
"bluedroid/stack/smp/smp_l2c.c"
|
"esp_ble_mesh/api")
|
||||||
"bluedroid/stack/smp/smp_main.c"
|
|
||||||
"bluedroid/stack/smp/smp_utils.c")
|
list(APPEND srcs "esp_ble_mesh/api/core/esp_ble_mesh_common_api.c"
|
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c"
|
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c"
|
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c"
|
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c"
|
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c"
|
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c"
|
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c"
|
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c"
|
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c"
|
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c"
|
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c"
|
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_config_model.c"
|
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_generic_model.c"
|
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_health_model.c"
|
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c"
|
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_prov.c"
|
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c"
|
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
|
||||||
|
"esp_ble_mesh/mesh_core/settings/settings_nvs.c"
|
||||||
|
"esp_ble_mesh/mesh_core/access.c"
|
||||||
|
"esp_ble_mesh/mesh_core/adv.c"
|
||||||
|
"esp_ble_mesh/mesh_core/beacon.c"
|
||||||
|
"esp_ble_mesh/mesh_core/cfg_cli.c"
|
||||||
|
"esp_ble_mesh/mesh_core/cfg_srv.c"
|
||||||
|
"esp_ble_mesh/mesh_core/crypto.c"
|
||||||
|
"esp_ble_mesh/mesh_core/friend.c"
|
||||||
|
"esp_ble_mesh/mesh_core/health_cli.c"
|
||||||
|
"esp_ble_mesh/mesh_core/health_srv.c"
|
||||||
|
"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"
|
||||||
|
"esp_ble_mesh/mesh_core/net.c"
|
||||||
|
"esp_ble_mesh/mesh_core/prov.c"
|
||||||
|
"esp_ble_mesh/mesh_core/provisioner_beacon.c"
|
||||||
|
"esp_ble_mesh/mesh_core/provisioner_main.c"
|
||||||
|
"esp_ble_mesh/mesh_core/provisioner_prov.c"
|
||||||
|
"esp_ble_mesh/mesh_core/provisioner_proxy.c"
|
||||||
|
"esp_ble_mesh/mesh_core/proxy.c"
|
||||||
|
"esp_ble_mesh/mesh_core/settings.c"
|
||||||
|
"esp_ble_mesh/mesh_core/test.c"
|
||||||
|
"esp_ble_mesh/mesh_core/transport.c"
|
||||||
|
"esp_ble_mesh/mesh_models/generic_client.c"
|
||||||
|
"esp_ble_mesh/mesh_models/lighting_client.c"
|
||||||
|
"esp_ble_mesh/mesh_models/mesh_common.c"
|
||||||
|
"esp_ble_mesh/mesh_models/model_common.c"
|
||||||
|
"esp_ble_mesh/mesh_models/sensor_client.c"
|
||||||
|
"esp_ble_mesh/mesh_models/time_scene_client.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_BT_NIMBLE_ENABLED)
|
||||||
|
|
||||||
|
list(APPEND include_dirs
|
||||||
|
host/nimble/nimble/porting/nimble/include
|
||||||
|
host/nimble/port/include
|
||||||
|
host/nimble/nimble/nimble/include
|
||||||
|
host/nimble/nimble/nimble/host/include
|
||||||
|
host/nimble/nimble/nimble/host/services/ans/include
|
||||||
|
host/nimble/nimble/nimble/host/services/bas/include
|
||||||
|
host/nimble/nimble/nimble/host/services/gap/include
|
||||||
|
host/nimble/nimble/nimble/host/services/gatt/include
|
||||||
|
host/nimble/nimble/nimble/host/services/ias/include
|
||||||
|
host/nimble/nimble/nimble/host/services/lls/include
|
||||||
|
host/nimble/nimble/nimble/host/services/tps/include
|
||||||
|
host/nimble/nimble/nimble/host/util/include
|
||||||
|
host/nimble/nimble/nimble/host/store/ram/include
|
||||||
|
host/nimble/nimble/nimble/host/store/config/include
|
||||||
|
host/nimble/nimble/porting/npl/freertos/include
|
||||||
|
host/nimble/nimble/ext/tinycrypt/include
|
||||||
|
host/nimble/esp-hci/include)
|
||||||
|
|
||||||
|
list(APPEND srcs "host/nimble/nimble/ext/tinycrypt/src/utils.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/sha256.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/ecc.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/ctr_prng.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/ctr_mode.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/aes_decrypt.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/aes_encrypt.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/ccm_mode.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/ecc_dsa.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/cmac_mode.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/ecc_dh.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/hmac_prng.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/ecc_platform_specific.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/hmac.c"
|
||||||
|
"host/nimble/nimble/ext/tinycrypt/src/cbc_mode.c"
|
||||||
|
"host/nimble/nimble/nimble/host/util/src/addr.c"
|
||||||
|
"host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c"
|
||||||
|
"host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c"
|
||||||
|
"host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c"
|
||||||
|
"host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c"
|
||||||
|
"host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c"
|
||||||
|
"host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c"
|
||||||
|
"host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_conn.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_store_util.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_shutdown.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap_sig_cmd.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_id.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att_svr.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gatts_lcl.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_ibeacon.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_atomic.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_alg.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_stop.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_dbg.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_mqueue.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gattc.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_store.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_lgcy.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_cfg.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_monitor.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att_clt.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_mbuf.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att_cmd.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_log.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_eddystone.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_startup.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap_sig.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gap.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_cmd.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_uuid.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_pvcy.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_flow.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_sc.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_misc.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gatts.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_adv.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci.c"
|
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci_util.c"
|
||||||
|
"host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c"
|
||||||
|
"host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c"
|
||||||
|
"host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c"
|
||||||
|
"host/nimble/nimble/nimble/src/ble_util.c"
|
||||||
|
"host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c"
|
||||||
|
"host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/endian.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/os_cputime_pwr2.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/hal_timer.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/os_mempool.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/os_msys_init.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/nimble_port.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/mem.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/os_mbuf.c"
|
||||||
|
"host/nimble/nimble/porting/nimble/src/os_cputime.c"
|
||||||
|
"host/nimble/esp-hci/src/esp_nimble_hci.c")
|
||||||
|
|
||||||
|
if(CONFIG_BT_NIMBLE_MESH)
|
||||||
|
|
||||||
|
list(APPEND include_dirs
|
||||||
|
host/nimble/nimble/nimble/host/mesh/include)
|
||||||
|
|
||||||
|
list(APPEND srcs "host/nimble/nimble/nimble/host/mesh/src/shell.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/friend.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/crypto.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/settings.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/adv.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/model_srv.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/beacon.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/glue.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/model_cli.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/transport.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/prov.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/mesh.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/access.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/cfg_srv.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/cfg_cli.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/light_model.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/health_cli.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/lpn.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/proxy.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/health_srv.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/testing.c"
|
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/net.c")
|
||||||
|
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# requirements can't depend on config
|
# requirements can't depend on config
|
||||||
set(COMPONENT_PRIV_REQUIRES nvs_flash soc)
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
INCLUDE_DIRS "${include_dirs}"
|
||||||
register_component()
|
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||||
|
REQUIRES nvs_flash soc)
|
||||||
|
|
||||||
if(CONFIG_BT_ENABLED)
|
if(CONFIG_BT_ENABLED)
|
||||||
if(GCC_NOT_5_2_0)
|
if(GCC_NOT_5_2_0)
|
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${COMPONENT_LIB} "-L${CMAKE_CURRENT_LIST_DIR}/lib")
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib")
|
||||||
target_link_libraries(${COMPONENT_LIB} btdm_app)
|
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||||
endif()
|
endif()
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,199 +0,0 @@
|
||||||
// Copyright 2015-2016 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 <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "common/bt_target.h"
|
|
||||||
#include "btc/btc_task.h"
|
|
||||||
#include "common/bt_trace.h"
|
|
||||||
#include "osi/thread.h"
|
|
||||||
#include "common/bt_defs.h"
|
|
||||||
#include "osi/allocator.h"
|
|
||||||
#include "btc/btc_main.h"
|
|
||||||
#include "btc/btc_dev.h"
|
|
||||||
#include "btc_gatts.h"
|
|
||||||
#include "btc_gattc.h"
|
|
||||||
#include "btc_gatt_common.h"
|
|
||||||
#include "btc_gap_ble.h"
|
|
||||||
#include "btc_blufi_prf.h"
|
|
||||||
#include "btc/btc_dm.h"
|
|
||||||
#include "btc/btc_alarm.h"
|
|
||||||
#include "bta/bta_gatt_api.h"
|
|
||||||
#if CONFIG_BT_CLASSIC_ENABLED
|
|
||||||
#include "btc/btc_profile_queue.h"
|
|
||||||
#if (BTC_GAP_BT_INCLUDED == TRUE)
|
|
||||||
#include "btc_gap_bt.h"
|
|
||||||
#endif /* BTC_GAP_BT_INCLUDED == TRUE */
|
|
||||||
#if BTC_AV_INCLUDED
|
|
||||||
#include "btc_av.h"
|
|
||||||
#include "btc_avrc.h"
|
|
||||||
#endif /* #if BTC_AV_INCLUDED */
|
|
||||||
#if CONFIG_BT_SPP_ENABLED
|
|
||||||
#include "btc_spp.h"
|
|
||||||
#endif /* #if CONFIG_BT_SPP_ENABLED */
|
|
||||||
#if BTC_HF_CLIENT_INCLUDED
|
|
||||||
#include "btc_hf_client.h"
|
|
||||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
|
||||||
#endif /* #if CONFIG_BT_CLASSIC_ENABLED */
|
|
||||||
|
|
||||||
|
|
||||||
static xTaskHandle xBtcTaskHandle = NULL;
|
|
||||||
static xQueueHandle xBtcQueue = 0;
|
|
||||||
|
|
||||||
static btc_func_t profile_tab[BTC_PID_NUM] = {
|
|
||||||
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
|
|
||||||
[BTC_PID_DEV] = {btc_dev_call_handler, NULL },
|
|
||||||
#if (GATTS_INCLUDED == TRUE)
|
|
||||||
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
|
|
||||||
#endif ///GATTS_INCLUDED == TRUE
|
|
||||||
#if (GATTC_INCLUDED == TRUE)
|
|
||||||
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
|
|
||||||
#endif ///GATTC_INCLUDED == TRUE
|
|
||||||
#if (GATTS_INCLUDED == TRUE || GATTC_INCLUDED == TRUE)
|
|
||||||
[BTC_PID_GATT_COMMON] = {btc_gatt_com_call_handler, NULL },
|
|
||||||
#endif //GATTC_INCLUDED == TRUE || GATTS_INCLUDED == TRUE
|
|
||||||
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
|
|
||||||
[BTC_PID_BLE_HID] = {NULL, NULL},
|
|
||||||
[BTC_PID_SPPLIKE] = {NULL, NULL},
|
|
||||||
#if (GATTS_INCLUDED == TRUE)
|
|
||||||
[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 },
|
|
||||||
[BTC_PID_ALARM] = {btc_alarm_handler, NULL },
|
|
||||||
#if CONFIG_BT_CLASSIC_ENABLED
|
|
||||||
#if (BTC_GAP_BT_INCLUDED == TRUE)
|
|
||||||
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, btc_gap_bt_cb_handler },
|
|
||||||
#endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
|
|
||||||
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
|
|
||||||
#if BTC_AV_INCLUDED
|
|
||||||
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
|
|
||||||
[BTC_PID_AVRC_CT] = {btc_avrc_ct_call_handler, NULL },
|
|
||||||
[BTC_PID_AVRC_TG] = {btc_avrc_tg_call_handler, NULL },
|
|
||||||
#endif /* #if BTC_AV_INCLUDED */
|
|
||||||
#if CONFIG_BT_SPP_ENABLED
|
|
||||||
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
|
|
||||||
#endif /* #if CONFIG_BT_SPP_ENABLED */
|
|
||||||
#if BTC_HF_CLIENT_INCLUDED
|
|
||||||
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
|
||||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
|
||||||
#endif /* #if CONFIG_BT_CLASSIC_ENABLED */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
**
|
|
||||||
** Function btc_task
|
|
||||||
**
|
|
||||||
** Description Process profile Task Thread.
|
|
||||||
******************************************************************************/
|
|
||||||
static void btc_task(void *arg)
|
|
||||||
{
|
|
||||||
btc_msg_t msg;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) {
|
|
||||||
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
|
|
||||||
switch (msg.sig) {
|
|
||||||
case BTC_SIG_API_CALL:
|
|
||||||
profile_tab[msg.pid].btc_call(&msg);
|
|
||||||
break;
|
|
||||||
case BTC_SIG_API_CB:
|
|
||||||
profile_tab[msg.pid].btc_cb(&msg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (msg.arg) {
|
|
||||||
osi_free(msg.arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bt_status_t btc_task_post(btc_msg_t *msg, task_post_t timeout)
|
|
||||||
{
|
|
||||||
if (msg == NULL) {
|
|
||||||
return BT_STATUS_PARM_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xQueueSend(xBtcQueue, msg, timeout) != pdTRUE) {
|
|
||||||
BTC_TRACE_ERROR("Btc Post failed\n");
|
|
||||||
return BT_STATUS_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BT_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
|
|
||||||
{
|
|
||||||
btc_msg_t lmsg;
|
|
||||||
|
|
||||||
if (msg == NULL) {
|
|
||||||
return BT_STATUS_PARM_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
|
|
||||||
|
|
||||||
memcpy(&lmsg, msg, sizeof(btc_msg_t));
|
|
||||||
if (arg) {
|
|
||||||
lmsg.arg = (void *)osi_malloc(arg_len);
|
|
||||||
if (lmsg.arg == NULL) {
|
|
||||||
return BT_STATUS_NOMEM;
|
|
||||||
}
|
|
||||||
memset(lmsg.arg, 0x00, arg_len); //important, avoid arg which have no length
|
|
||||||
memcpy(lmsg.arg, arg, arg_len);
|
|
||||||
if (copy_func) {
|
|
||||||
copy_func(&lmsg, lmsg.arg, arg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lmsg.arg = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return btc_task_post(&lmsg, TASK_POST_BLOCKING);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int btc_init(void)
|
|
||||||
{
|
|
||||||
xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_LEN, sizeof(btc_msg_t));
|
|
||||||
xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, BTC_TASK_PINNED_TO_CORE);
|
|
||||||
if (xBtcTaskHandle == NULL || xBtcQueue == 0){
|
|
||||||
return BT_STATUS_NOMEM;
|
|
||||||
}
|
|
||||||
btc_gap_callback_init();
|
|
||||||
#if SCAN_QUEUE_CONGEST_CHECK
|
|
||||||
btc_adv_list_init();
|
|
||||||
#endif
|
|
||||||
/* TODO: initial the profile_tab */
|
|
||||||
return BT_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void btc_deinit(void)
|
|
||||||
{
|
|
||||||
vTaskDelete(xBtcTaskHandle);
|
|
||||||
vQueueDelete(xBtcQueue);
|
|
||||||
#if SCAN_QUEUE_CONGEST_CHECK
|
|
||||||
btc_adv_list_deinit();
|
|
||||||
#endif
|
|
||||||
xBtcTaskHandle = NULL;
|
|
||||||
xBtcQueue = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool btc_check_queue_is_congest(void)
|
|
||||||
{
|
|
||||||
UBaseType_t wait_size = uxQueueMessagesWaiting(xBtcQueue);
|
|
||||||
if(wait_size >= QUEUE_CONGEST_SIZE) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -1,552 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2014 Google, Inc.
|
|
||||||
*
|
|
||||||
* 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 <stdbool.h>
|
|
||||||
#include "common/bt_target.h"
|
|
||||||
#include "common/bt_trace.h"
|
|
||||||
#include "device/bdaddr.h"
|
|
||||||
#include "stack/bt_types.h"
|
|
||||||
#include "device/controller.h"
|
|
||||||
#include "device/event_mask.h"
|
|
||||||
#include "stack/hcimsgs.h"
|
|
||||||
#include "hci/hci_layer.h"
|
|
||||||
#include "hci/hci_packet_factory.h"
|
|
||||||
#include "hci/hci_packet_parser.h"
|
|
||||||
#include "stack/btm_ble_api.h"
|
|
||||||
#include "device/version.h"
|
|
||||||
#include "osi/future.h"
|
|
||||||
|
|
||||||
const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" };
|
|
||||||
|
|
||||||
#if (BLE_INCLUDED)
|
|
||||||
const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_DUMO_EVENT_MASK_EXT };
|
|
||||||
#else
|
|
||||||
const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_LISBON_EVENT_MASK_EXT };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO(zachoverflow): factor out into common module
|
|
||||||
const uint8_t SCO_HOST_BUFFER_SIZE = 0xff;
|
|
||||||
|
|
||||||
#define HCI_SUPPORTED_COMMANDS_ARRAY_SIZE 64
|
|
||||||
#define MAX_FEATURES_CLASSIC_PAGE_COUNT 3
|
|
||||||
#define BLE_SUPPORTED_STATES_SIZE 8
|
|
||||||
#define BLE_SUPPORTED_FEATURES_SIZE 8
|
|
||||||
|
|
||||||
static const hci_t *hci;
|
|
||||||
static const hci_packet_factory_t *packet_factory;
|
|
||||||
static const hci_packet_parser_t *packet_parser;
|
|
||||||
|
|
||||||
static bt_bdaddr_t address;
|
|
||||||
static bt_version_t bt_version;
|
|
||||||
|
|
||||||
static uint8_t supported_commands[HCI_SUPPORTED_COMMANDS_ARRAY_SIZE];
|
|
||||||
static bt_device_features_t features_classic[MAX_FEATURES_CLASSIC_PAGE_COUNT];
|
|
||||||
static uint8_t last_features_classic_page_index;
|
|
||||||
|
|
||||||
static uint16_t acl_data_size_classic;
|
|
||||||
static uint16_t acl_data_size_ble;
|
|
||||||
static uint16_t acl_buffer_count_classic;
|
|
||||||
static uint8_t acl_buffer_count_ble;
|
|
||||||
|
|
||||||
static uint8_t sco_data_size;
|
|
||||||
static uint16_t sco_buffer_count;
|
|
||||||
|
|
||||||
static uint8_t ble_white_list_size;
|
|
||||||
static uint8_t ble_resolving_list_max_size;
|
|
||||||
static uint8_t ble_supported_states[BLE_SUPPORTED_STATES_SIZE];
|
|
||||||
static bt_device_features_t features_ble;
|
|
||||||
static uint16_t ble_suggested_default_data_length;
|
|
||||||
static uint16_t ble_suggested_default_data_txtime;
|
|
||||||
|
|
||||||
static bool readable;
|
|
||||||
static bool ble_supported;
|
|
||||||
static bool simple_pairing_supported;
|
|
||||||
static bool secure_connections_supported;
|
|
||||||
|
|
||||||
#define AWAIT_COMMAND(command) future_await(hci->transmit_command_futured(command))
|
|
||||||
|
|
||||||
// Module lifecycle functions
|
|
||||||
|
|
||||||
static void start_up(void)
|
|
||||||
{
|
|
||||||
BT_HDR *response;
|
|
||||||
|
|
||||||
// Send the initial reset command
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_reset());
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
|
|
||||||
// Request the classic buffer size next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_read_buffer_size());
|
|
||||||
packet_parser->parse_read_buffer_size_response(
|
|
||||||
response, &acl_data_size_classic, &acl_buffer_count_classic,
|
|
||||||
&sco_data_size, &sco_buffer_count);
|
|
||||||
|
|
||||||
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
|
|
||||||
// Enable controller to host flow control
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_set_c2h_flow_control(HCI_HOST_FLOW_CTRL_ACL_ON));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
|
|
||||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
|
||||||
// Enable adv flow control
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_set_adv_report_flow_control(HCI_HOST_FLOW_CTRL_ADV_REPORT_ON, (uint16_t)BLE_ADV_REPORT_FLOW_CONTROL_NUM, (uint16_t)BLE_ADV_REPORT_DISCARD_THRSHOLD));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
#endif
|
|
||||||
// Tell the controller about our buffer sizes and buffer counts next
|
|
||||||
// TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?
|
|
||||||
response = AWAIT_COMMAND(
|
|
||||||
packet_factory->make_host_buffer_size(
|
|
||||||
L2CAP_MTU_SIZE,
|
|
||||||
SCO_HOST_BUFFER_SIZE,
|
|
||||||
L2CAP_HOST_FC_ACL_BUFS,
|
|
||||||
10
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
|
|
||||||
// Read the local version info off the controller next, including
|
|
||||||
// information such as manufacturer and supported HCI version
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_read_local_version_info());
|
|
||||||
packet_parser->parse_read_local_version_info_response(response, &bt_version);
|
|
||||||
|
|
||||||
// Read the bluetooth address off the controller next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_read_bd_addr());
|
|
||||||
packet_parser->parse_read_bd_addr_response(response, &address);
|
|
||||||
|
|
||||||
// Request the controller's supported commands next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_read_local_supported_commands());
|
|
||||||
packet_parser->parse_read_local_supported_commands_response(
|
|
||||||
response,
|
|
||||||
supported_commands,
|
|
||||||
HCI_SUPPORTED_COMMANDS_ARRAY_SIZE
|
|
||||||
);
|
|
||||||
|
|
||||||
// Read page 0 of the controller features next
|
|
||||||
uint8_t page_number = 0;
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_read_local_extended_features(page_number));
|
|
||||||
packet_parser->parse_read_local_extended_features_response(
|
|
||||||
response,
|
|
||||||
&page_number,
|
|
||||||
&last_features_classic_page_index,
|
|
||||||
features_classic,
|
|
||||||
MAX_FEATURES_CLASSIC_PAGE_COUNT
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(page_number == 0);
|
|
||||||
page_number++;
|
|
||||||
|
|
||||||
// Inform the controller what page 0 features we support, based on what
|
|
||||||
// it told us it supports. We need to do this first before we request the
|
|
||||||
// next page, because the controller's response for page 1 may be
|
|
||||||
// dependent on what we configure from page 0
|
|
||||||
#if (BT_SSP_INCLUDED == TRUE)
|
|
||||||
simple_pairing_supported = HCI_SIMPLE_PAIRING_SUPPORTED(features_classic[0].as_array);
|
|
||||||
#else
|
|
||||||
simple_pairing_supported = false;
|
|
||||||
#endif
|
|
||||||
if (simple_pairing_supported) {
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_write_simple_pairing_mode(HCI_SP_MODE_ENABLED));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (BLE_INCLUDED == TRUE)
|
|
||||||
if (HCI_LE_SPT_SUPPORTED(features_classic[0].as_array)) {
|
|
||||||
uint8_t simultaneous_le_host = HCI_SIMUL_LE_BREDR_SUPPORTED(features_classic[0].as_array) ? BTM_BLE_SIMULTANEOUS_HOST : 0;
|
|
||||||
response = AWAIT_COMMAND(
|
|
||||||
packet_factory->make_ble_write_host_support(BTM_BLE_HOST_SUPPORT, simultaneous_le_host)
|
|
||||||
);
|
|
||||||
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Done telling the controller about what page 0 features we support
|
|
||||||
// Request the remaining feature pages
|
|
||||||
while (page_number <= last_features_classic_page_index &&
|
|
||||||
page_number < MAX_FEATURES_CLASSIC_PAGE_COUNT) {
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_read_local_extended_features(page_number));
|
|
||||||
packet_parser->parse_read_local_extended_features_response(
|
|
||||||
response,
|
|
||||||
&page_number,
|
|
||||||
&last_features_classic_page_index,
|
|
||||||
features_classic,
|
|
||||||
MAX_FEATURES_CLASSIC_PAGE_COUNT
|
|
||||||
);
|
|
||||||
|
|
||||||
page_number++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (SC_MODE_INCLUDED == TRUE)
|
|
||||||
secure_connections_supported = HCI_SC_CTRLR_SUPPORTED(features_classic[2].as_array);
|
|
||||||
if (secure_connections_supported) {
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_write_secure_connections_host_support(HCI_SC_MODE_ENABLED));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (BLE_INCLUDED == TRUE)
|
|
||||||
ble_supported = last_features_classic_page_index >= 1 && HCI_LE_HOST_SUPPORTED(features_classic[1].as_array);
|
|
||||||
if (ble_supported) {
|
|
||||||
// Request the ble white list size next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_read_white_list_size());
|
|
||||||
packet_parser->parse_ble_read_white_list_size_response(response, &ble_white_list_size);
|
|
||||||
|
|
||||||
// Request the ble buffer size next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_read_buffer_size());
|
|
||||||
packet_parser->parse_ble_read_buffer_size_response(
|
|
||||||
response,
|
|
||||||
&acl_data_size_ble,
|
|
||||||
&acl_buffer_count_ble
|
|
||||||
);
|
|
||||||
|
|
||||||
// Response of 0 indicates ble has the same buffer size as classic
|
|
||||||
if (acl_data_size_ble == 0) {
|
|
||||||
acl_data_size_ble = acl_data_size_classic;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request the ble supported states next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_read_supported_states());
|
|
||||||
packet_parser->parse_ble_read_supported_states_response(
|
|
||||||
response,
|
|
||||||
ble_supported_states,
|
|
||||||
sizeof(ble_supported_states)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Request the ble supported features next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_read_local_supported_features());
|
|
||||||
packet_parser->parse_ble_read_local_supported_features_response(
|
|
||||||
response,
|
|
||||||
&features_ble
|
|
||||||
);
|
|
||||||
|
|
||||||
if (HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array)) {
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_read_resolving_list_size());
|
|
||||||
packet_parser->parse_ble_read_resolving_list_size_response(
|
|
||||||
response,
|
|
||||||
&ble_resolving_list_max_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array)) {
|
|
||||||
/* set default tx data length to MAX 251 */
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_write_suggested_default_data_length(BTM_BLE_DATA_SIZE_MAX, BTM_BLE_DATA_TX_TIME_MAX));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_read_suggested_default_data_length());
|
|
||||||
packet_parser->parse_ble_read_suggested_default_data_length_response(
|
|
||||||
response,
|
|
||||||
&ble_suggested_default_data_length,
|
|
||||||
&ble_suggested_default_data_txtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the ble event mask next
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_ble_set_event_mask(&BLE_EVENT_MASK));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_set_event_mask(&CLASSIC_EVENT_MASK));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
|
|
||||||
|
|
||||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_write_sync_flow_control_enable(1));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
|
|
||||||
response = AWAIT_COMMAND(packet_factory->make_write_default_erroneous_data_report(1));
|
|
||||||
packet_parser->parse_generic_command_complete(response);
|
|
||||||
#endif
|
|
||||||
readable = true;
|
|
||||||
// return future_new_immediate(FUTURE_SUCCESS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void shut_down(void)
|
|
||||||
{
|
|
||||||
readable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool get_is_ready(void)
|
|
||||||
{
|
|
||||||
return readable;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bt_bdaddr_t *get_address(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return &address;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bt_version_t *get_bt_version(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return &bt_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(zachoverflow): hide inside, move decoder inside too
|
|
||||||
static const bt_device_features_t *get_features_classic(int index)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(index < MAX_FEATURES_CLASSIC_PAGE_COUNT);
|
|
||||||
return &features_classic[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t get_last_features_classic_index(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return last_features_classic_page_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bt_device_features_t *get_features_ble(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return &features_ble;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint8_t *get_ble_supported_states(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return ble_supported_states;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_simple_pairing(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return simple_pairing_supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_secure_connections(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return secure_connections_supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_simultaneous_le_bredr(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return HCI_SIMUL_LE_BREDR_SUPPORTED(features_classic[0].as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_reading_remote_extended_features(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(supported_commands);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_interlaced_inquiry_scan(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(features_classic[0].as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_rssi_with_inquiry_results(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return HCI_LMP_INQ_RSSI_SUPPORTED(features_classic[0].as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_extended_inquiry_response(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return HCI_EXT_INQ_RSP_SUPPORTED(features_classic[0].as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_master_slave_role_switch(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return HCI_SWITCH_SUPPORTED(features_classic[0].as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_ble(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return ble_supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_ble_privacy(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_ble_packet_extension(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_ble_connection_parameters_request(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return HCI_LE_CONN_PARAM_REQ_SUPPORTED(features_ble.as_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t get_acl_data_size_classic(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return acl_data_size_classic;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t get_acl_data_size_ble(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return acl_data_size_ble;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t get_acl_packet_size_classic(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return acl_data_size_classic + HCI_DATA_PREAMBLE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t get_acl_packet_size_ble(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return acl_data_size_ble + HCI_DATA_PREAMBLE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t get_ble_suggested_default_data_length(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return ble_suggested_default_data_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t get_ble_suggested_default_data_txtime(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return ble_suggested_default_data_txtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t get_acl_buffer_count_classic(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return acl_buffer_count_classic;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t get_acl_buffer_count_ble(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return acl_buffer_count_ble;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t get_ble_white_list_size(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return ble_white_list_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t get_ble_resolving_list_max_size(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
return ble_resolving_list_max_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_ble_resolving_list_max_size(int resolving_list_max_size)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
assert(ble_supported);
|
|
||||||
ble_resolving_list_max_size = resolving_list_max_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
|
||||||
static uint8_t get_sco_data_size(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return sco_data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t get_sco_buffer_count(void)
|
|
||||||
{
|
|
||||||
assert(readable);
|
|
||||||
return sco_buffer_count;
|
|
||||||
}
|
|
||||||
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE) */
|
|
||||||
|
|
||||||
static const controller_t interface = {
|
|
||||||
start_up,
|
|
||||||
shut_down,
|
|
||||||
get_is_ready,
|
|
||||||
|
|
||||||
get_address,
|
|
||||||
get_bt_version,
|
|
||||||
|
|
||||||
get_features_classic,
|
|
||||||
get_last_features_classic_index,
|
|
||||||
|
|
||||||
get_features_ble,
|
|
||||||
get_ble_supported_states,
|
|
||||||
|
|
||||||
supports_simple_pairing,
|
|
||||||
supports_secure_connections,
|
|
||||||
supports_simultaneous_le_bredr,
|
|
||||||
supports_reading_remote_extended_features,
|
|
||||||
supports_interlaced_inquiry_scan,
|
|
||||||
supports_rssi_with_inquiry_results,
|
|
||||||
supports_extended_inquiry_response,
|
|
||||||
supports_master_slave_role_switch,
|
|
||||||
|
|
||||||
supports_ble,
|
|
||||||
supports_ble_packet_extension,
|
|
||||||
supports_ble_connection_parameters_request,
|
|
||||||
supports_ble_privacy,
|
|
||||||
|
|
||||||
get_acl_data_size_classic,
|
|
||||||
get_acl_data_size_ble,
|
|
||||||
|
|
||||||
get_acl_packet_size_classic,
|
|
||||||
get_acl_packet_size_ble,
|
|
||||||
get_ble_suggested_default_data_length,
|
|
||||||
get_ble_suggested_default_data_txtime,
|
|
||||||
|
|
||||||
get_acl_buffer_count_classic,
|
|
||||||
get_acl_buffer_count_ble,
|
|
||||||
|
|
||||||
get_ble_white_list_size,
|
|
||||||
|
|
||||||
get_ble_resolving_list_max_size,
|
|
||||||
set_ble_resolving_list_max_size,
|
|
||||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
|
||||||
get_sco_data_size,
|
|
||||||
get_sco_buffer_count,
|
|
||||||
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE) */
|
|
||||||
};
|
|
||||||
|
|
||||||
const controller_t *controller_get_interface()
|
|
||||||
{
|
|
||||||
static bool loaded = false;
|
|
||||||
if (!loaded) {
|
|
||||||
loaded = true;
|
|
||||||
|
|
||||||
hci = hci_layer_get_interface();
|
|
||||||
packet_factory = hci_packet_factory_get_interface();
|
|
||||||
packet_parser = hci_packet_parser_get_interface();
|
|
||||||
}
|
|
||||||
|
|
||||||
return &interface;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
// Copyright 2015-2016 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.
|
|
||||||
|
|
||||||
#ifndef __THREAD_H__
|
|
||||||
#define __THREAD_H__
|
|
||||||
|
|
||||||
#include "freertos/xtensa_api.h"
|
|
||||||
#include "freertos/FreeRTOSConfig.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/queue.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#include "esp_task.h"
|
|
||||||
#include "common/bt_defs.h"
|
|
||||||
|
|
||||||
#define portBASE_TYPE int
|
|
||||||
|
|
||||||
struct bt_task_evt {
|
|
||||||
uint32_t sig; //task sig
|
|
||||||
void *par; //point to task param
|
|
||||||
void *cb; //point to function cb
|
|
||||||
void *arg; //point to function arg
|
|
||||||
};
|
|
||||||
typedef struct bt_task_evt BtTaskEvt_t;
|
|
||||||
|
|
||||||
typedef bt_status_t (* BtTaskCb_t)(void *arg);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SIG_HCI_HAL_RECV_PACKET = 0,
|
|
||||||
SIG_HCI_HAL_NUM,
|
|
||||||
} SIG_HCI_HAL_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SIG_HCI_HOST_SEND_AVAILABLE = 0,
|
|
||||||
SIG_HCI_HOST_NUM,
|
|
||||||
} SIG_HCI_HOST_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SIG_BTU_START_UP = 0,
|
|
||||||
SIG_BTU_HCI_MSG,
|
|
||||||
SIG_BTU_BTA_MSG,
|
|
||||||
SIG_BTU_BTA_ALARM,
|
|
||||||
SIG_BTU_GENERAL_ALARM,
|
|
||||||
SIG_BTU_ONESHOT_ALARM,
|
|
||||||
SIG_BTU_L2CAP_ALARM,
|
|
||||||
SIG_BTU_NUM,
|
|
||||||
} SIG_BTU_t;
|
|
||||||
|
|
||||||
#define TASK_PINNED_TO_CORE (CONFIG_BT_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY)
|
|
||||||
|
|
||||||
#define HCI_HOST_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
|
||||||
#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
|
|
||||||
#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3)
|
|
||||||
#define HCI_HOST_TASK_NAME "hciHostT"
|
|
||||||
#define HCI_HOST_QUEUE_LEN 40
|
|
||||||
|
|
||||||
#define HCI_H4_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
|
||||||
#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
|
|
||||||
#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4)
|
|
||||||
#define HCI_H4_TASK_NAME "hciH4T"
|
|
||||||
#define HCI_H4_QUEUE_LEN 1
|
|
||||||
|
|
||||||
#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
|
||||||
#define BTU_TASK_STACK_SIZE (CONFIG_BT_BTU_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE)
|
|
||||||
#define BTU_TASK_PRIO (configMAX_PRIORITIES - 5)
|
|
||||||
#define BTU_TASK_NAME "btuT"
|
|
||||||
#define BTU_QUEUE_LEN 50
|
|
||||||
|
|
||||||
#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
|
||||||
#define BTC_TASK_STACK_SIZE (CONFIG_BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
|
|
||||||
#define BTC_TASK_NAME "btcT"
|
|
||||||
#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6)
|
|
||||||
#define BTC_TASK_QUEUE_LEN 60
|
|
||||||
|
|
||||||
#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
|
||||||
#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_BT_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
|
|
||||||
#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT"
|
|
||||||
#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3)
|
|
||||||
#define BTC_A2DP_SINK_DATA_QUEUE_LEN (3)
|
|
||||||
#define BTC_A2DP_SINK_CTRL_QUEUE_LEN (5)
|
|
||||||
#define BTC_A2DP_SINK_TASK_QUEUE_SET_LEN (BTC_A2DP_SINK_DATA_QUEUE_LEN + BTC_A2DP_SINK_CTRL_QUEUE_LEN)
|
|
||||||
|
|
||||||
#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
|
||||||
#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_BT_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
|
|
||||||
#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT"
|
|
||||||
#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3)
|
|
||||||
#define BTC_A2DP_SOURCE_DATA_QUEUE_LEN (1)
|
|
||||||
#define BTC_A2DP_SOURCE_CTRL_QUEUE_LEN (5)
|
|
||||||
#define BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN (BTC_A2DP_SOURCE_DATA_QUEUE_LEN + BTC_A2DP_SOURCE_CTRL_QUEUE_LEN)
|
|
||||||
|
|
||||||
#define TASK_POST_NON_BLOCKING (0)
|
|
||||||
#define TASK_POST_BLOCKING (portMAX_DELAY)
|
|
||||||
typedef uint32_t task_post_t; /* Timeout of task post return, unit TICK */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
TASK_POST_SUCCESS = 0,
|
|
||||||
TASK_POST_FAIL,
|
|
||||||
} task_post_status_t;
|
|
||||||
|
|
||||||
task_post_status_t btu_task_post(uint32_t sig, void *param, task_post_t timeout);
|
|
||||||
task_post_status_t hci_host_task_post(task_post_t timeout);
|
|
||||||
task_post_status_t hci_hal_h4_task_post(task_post_t timeout);
|
|
||||||
|
|
||||||
#endif /* __THREAD_H__ */
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "btc/btc_task.h"
|
#include "btc/btc_task.h"
|
||||||
#include "btc/btc_alarm.h"
|
#include "btc/btc_alarm.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
void btc_alarm_handler(btc_msg_t *msg)
|
void btc_alarm_handler(btc_msg_t *msg)
|
||||||
{
|
{
|
|
@ -14,12 +14,13 @@
|
||||||
|
|
||||||
|
|
||||||
#include "btc/btc_task.h"
|
#include "btc/btc_task.h"
|
||||||
#include "common/bt_trace.h"
|
|
||||||
#include "osi/thread.h"
|
#include "osi/thread.h"
|
||||||
#include "esp_bt_defs.h"
|
|
||||||
#include "esp_gatt_defs.h"
|
|
||||||
|
|
||||||
static void *btc_profile_cb_tab[BTC_PID_NUM] = {};
|
#if BTC_DYNAMIC_MEMORY == FALSE
|
||||||
|
void *btc_profile_cb_tab[BTC_PID_NUM] = {};
|
||||||
|
#else
|
||||||
|
void **btc_profile_cb_tab;
|
||||||
|
#endif
|
||||||
|
|
||||||
void esp_profile_cb_reset(void)
|
void esp_profile_cb_reset(void)
|
||||||
{
|
{
|
368
components/bt/common/btc/core/btc_task.c
Normal file
368
components/bt/common/btc/core/btc_task.c
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
// Copyright 2015-2016 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#include "osi/thread.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "bt_common.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||||
|
#include "common/bt_target.h"
|
||||||
|
#include "btc/btc_main.h"
|
||||||
|
#include "btc/btc_manage.h"
|
||||||
|
#include "btc/btc_dev.h"
|
||||||
|
#include "btc_gatts.h"
|
||||||
|
#include "btc_gattc.h"
|
||||||
|
#include "btc_gatt_common.h"
|
||||||
|
#include "btc_gap_ble.h"
|
||||||
|
#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"
|
||||||
|
#if (BTC_GAP_BT_INCLUDED == TRUE)
|
||||||
|
#include "btc_gap_bt.h"
|
||||||
|
#endif /* BTC_GAP_BT_INCLUDED == TRUE */
|
||||||
|
#if BTC_AV_INCLUDED
|
||||||
|
#include "btc_av.h"
|
||||||
|
#include "btc_avrc.h"
|
||||||
|
#include "btc_av_co.h"
|
||||||
|
#endif /* #if BTC_AV_INCLUDED */
|
||||||
|
#if (BTC_SPP_INCLUDED == TRUE)
|
||||||
|
#include "btc_spp.h"
|
||||||
|
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
||||||
|
#if BTC_HF_CLIENT_INCLUDED
|
||||||
|
#include "btc_hf_client.h"
|
||||||
|
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||||
|
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH
|
||||||
|
#include "btc_ble_mesh_prov.h"
|
||||||
|
#include "btc_ble_mesh_health_model.h"
|
||||||
|
#include "btc_ble_mesh_config_model.h"
|
||||||
|
#include "btc_ble_mesh_generic_model.h"
|
||||||
|
#include "btc_ble_mesh_lighting_model.h"
|
||||||
|
#include "btc_ble_mesh_sensor_model.h"
|
||||||
|
#include "btc_ble_mesh_time_scene_model.h"
|
||||||
|
#endif /* #if CONFIG_BLE_MESH */
|
||||||
|
|
||||||
|
#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
||||||
|
#define BTC_TASK_STACK_SIZE (BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
|
||||||
|
#define BTC_TASK_NAME "btcT"
|
||||||
|
#define BTC_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 6)
|
||||||
|
|
||||||
|
osi_thread_t *btc_thread;
|
||||||
|
|
||||||
|
static const btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||||
|
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
|
||||||
|
[BTC_PID_DEV] = {btc_dev_call_handler, NULL },
|
||||||
|
#if (GATTS_INCLUDED == TRUE)
|
||||||
|
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
|
||||||
|
#endif ///GATTS_INCLUDED == TRUE
|
||||||
|
#if (GATTC_INCLUDED == TRUE)
|
||||||
|
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
|
||||||
|
#endif ///GATTC_INCLUDED == TRUE
|
||||||
|
#if (GATTS_INCLUDED == TRUE || GATTC_INCLUDED == TRUE)
|
||||||
|
[BTC_PID_GATT_COMMON] = {btc_gatt_com_call_handler, NULL },
|
||||||
|
#endif //GATTC_INCLUDED == TRUE || GATTS_INCLUDED == TRUE
|
||||||
|
#if (BLE_INCLUDED == TRUE)
|
||||||
|
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
|
||||||
|
#else
|
||||||
|
[BTC_PID_GAP_BLE] = {NULL, NULL},
|
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
[BTC_PID_BLE_HID] = {NULL, NULL},
|
||||||
|
[BTC_PID_SPPLIKE] = {NULL, NULL},
|
||||||
|
#if (GATTS_INCLUDED == TRUE)
|
||||||
|
[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 },
|
||||||
|
[BTC_PID_ALARM] = {btc_alarm_handler, NULL },
|
||||||
|
#if CLASSIC_BT_INCLUDED
|
||||||
|
#if (BTC_GAP_BT_INCLUDED == TRUE)
|
||||||
|
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, btc_gap_bt_cb_handler },
|
||||||
|
#endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
|
||||||
|
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
|
||||||
|
#if BTC_AV_INCLUDED
|
||||||
|
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
|
||||||
|
[BTC_PID_AVRC_CT] = {btc_avrc_ct_call_handler, NULL },
|
||||||
|
[BTC_PID_AVRC_TG] = {btc_avrc_tg_call_handler, NULL },
|
||||||
|
#endif /* #if BTC_AV_INCLUDED */
|
||||||
|
#if (BTC_SPP_INCLUDED == TRUE)
|
||||||
|
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
|
||||||
|
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
||||||
|
#if BTC_HF_CLIENT_INCLUDED
|
||||||
|
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
||||||
|
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||||
|
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BLE_MESH
|
||||||
|
[BTC_PID_PROV] = {btc_mesh_prov_call_handler, btc_mesh_prov_cb_handler},
|
||||||
|
[BTC_PID_MODEL] = {btc_mesh_model_call_handler, btc_mesh_model_cb_handler},
|
||||||
|
[BTC_PID_HEALTH_CLIENT] = {btc_mesh_health_client_call_handler, btc_mesh_health_client_cb_handler},
|
||||||
|
[BTC_PID_HEALTH_SERVER] = {btc_mesh_health_server_call_handler, btc_mesh_health_server_cb_handler},
|
||||||
|
[BTC_PID_CFG_CLIENT] = {btc_mesh_cfg_client_call_handler, btc_mesh_cfg_client_cb_handler},
|
||||||
|
[BTC_PID_CFG_SERVER] = {NULL , btc_mesh_cfg_server_cb_handler},
|
||||||
|
[BTC_PID_GENERIC_CLIENT] = {btc_mesh_generic_client_call_handler, btc_mesh_generic_client_cb_handler},
|
||||||
|
[BTC_PID_LIGHT_CLIENT] = {btc_mesh_light_client_call_handler, btc_mesh_light_client_cb_handler},
|
||||||
|
[BTC_PID_SENSOR_CLIENT] = {btc_mesh_sensor_client_call_handler, btc_mesh_sensor_client_cb_handler},
|
||||||
|
[BTC_PID_TIME_SCENE_CLIENT] = {btc_mesh_time_scene_client_call_handler, btc_mesh_time_scene_client_cb_handler},
|
||||||
|
#endif /* #if CONFIG_BLE_MESH */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
**
|
||||||
|
** Function btc_task
|
||||||
|
**
|
||||||
|
** Description Process profile Task Thread.
|
||||||
|
******************************************************************************/
|
||||||
|
static void btc_thread_handler(void *arg)
|
||||||
|
{
|
||||||
|
btc_msg_t *msg = (btc_msg_t *)arg;
|
||||||
|
|
||||||
|
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, msg->arg);
|
||||||
|
switch (msg->sig) {
|
||||||
|
case BTC_SIG_API_CALL:
|
||||||
|
profile_tab[msg->pid].btc_call(msg);
|
||||||
|
break;
|
||||||
|
case BTC_SIG_API_CB:
|
||||||
|
profile_tab[msg->pid].btc_cb(msg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->arg) {
|
||||||
|
osi_free(msg->arg);
|
||||||
|
}
|
||||||
|
osi_free(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout)
|
||||||
|
{
|
||||||
|
btc_msg_t *lmsg;
|
||||||
|
|
||||||
|
lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t));
|
||||||
|
if (lmsg == NULL) {
|
||||||
|
return BT_STATUS_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(lmsg, msg, sizeof(btc_msg_t));
|
||||||
|
|
||||||
|
if (osi_thread_post(btc_thread, btc_thread_handler, lmsg, 0, timeout) == false) {
|
||||||
|
return BT_STATUS_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
|
||||||
|
{
|
||||||
|
btc_msg_t lmsg;
|
||||||
|
|
||||||
|
if (msg == NULL) {
|
||||||
|
return BT_STATUS_PARM_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
|
||||||
|
|
||||||
|
memcpy(&lmsg, msg, sizeof(btc_msg_t));
|
||||||
|
if (arg) {
|
||||||
|
lmsg.arg = (void *)osi_malloc(arg_len);
|
||||||
|
if (lmsg.arg == NULL) {
|
||||||
|
return BT_STATUS_NOMEM;
|
||||||
|
}
|
||||||
|
memset(lmsg.arg, 0x00, arg_len); //important, avoid arg which have no length
|
||||||
|
memcpy(lmsg.arg, arg, arg_len);
|
||||||
|
if (copy_func) {
|
||||||
|
copy_func(&lmsg, lmsg.arg, arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lmsg.arg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return btc_task_post(&lmsg, OSI_THREAD_MAX_TIMEOUT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BTC_DYNAMIC_MEMORY
|
||||||
|
|
||||||
|
static void btc_deinit_mem(void) {
|
||||||
|
if (btc_dm_cb_ptr) {
|
||||||
|
osi_free(btc_dm_cb_ptr);
|
||||||
|
btc_dm_cb_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btc_profile_cb_tab) {
|
||||||
|
osi_free(btc_profile_cb_tab);
|
||||||
|
btc_profile_cb_tab = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (BLE_INCLUDED == TRUE)
|
||||||
|
if (gl_bta_adv_data_ptr) {
|
||||||
|
osi_free(gl_bta_adv_data_ptr);
|
||||||
|
gl_bta_adv_data_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gl_bta_scan_rsp_data_ptr) {
|
||||||
|
osi_free(gl_bta_scan_rsp_data_ptr);
|
||||||
|
gl_bta_scan_rsp_data_ptr = NULL;
|
||||||
|
}
|
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
|
||||||
|
if (btc_creat_tab_env_ptr) {
|
||||||
|
osi_free(btc_creat_tab_env_ptr);
|
||||||
|
btc_creat_tab_env_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blufi_env_ptr) {
|
||||||
|
osi_free(blufi_env_ptr);
|
||||||
|
blufi_env_ptr = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||||
|
if (hf_client_local_param_ptr) {
|
||||||
|
osi_free(hf_client_local_param_ptr);
|
||||||
|
hf_client_local_param_ptr = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE
|
||||||
|
if (btc_rc_cb_ptr) {
|
||||||
|
osi_free(btc_rc_cb_ptr);
|
||||||
|
btc_rc_cb_ptr = NULL;
|
||||||
|
}
|
||||||
|
if (bta_av_co_cb_ptr) {
|
||||||
|
osi_free(bta_av_co_cb_ptr);
|
||||||
|
bta_av_co_cb_ptr = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bt_status_t btc_init_mem(void) {
|
||||||
|
if ((btc_dm_cb_ptr = (btc_dm_cb_t *)osi_malloc(sizeof(btc_dm_cb_t))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)btc_dm_cb_ptr, 0, sizeof(btc_dm_cb_t));
|
||||||
|
|
||||||
|
if ((btc_profile_cb_tab = (void **)osi_malloc(sizeof(void *) * BTC_PID_NUM)) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)btc_profile_cb_tab, 0, sizeof(void *) * BTC_PID_NUM);
|
||||||
|
|
||||||
|
#if (BLE_INCLUDED == TRUE)
|
||||||
|
if ((gl_bta_adv_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)gl_bta_adv_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA));
|
||||||
|
|
||||||
|
if ((gl_bta_scan_rsp_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)gl_bta_scan_rsp_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA));
|
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
|
||||||
|
if ((btc_creat_tab_env_ptr = (esp_btc_creat_tab_t *)osi_malloc(sizeof(esp_btc_creat_tab_t))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)btc_creat_tab_env_ptr, 0, sizeof(esp_btc_creat_tab_t));
|
||||||
|
|
||||||
|
if ((blufi_env_ptr = (tBLUFI_ENV *)osi_malloc(sizeof(tBLUFI_ENV))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)blufi_env_ptr, 0, sizeof(tBLUFI_ENV));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||||
|
if ((hf_client_local_param_ptr = (hf_client_local_param_t *)osi_malloc(sizeof(hf_client_local_param_t))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)hf_client_local_param_ptr, 0, sizeof(hf_client_local_param_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE
|
||||||
|
if ((btc_rc_cb_ptr = (btc_rc_cb_t *)osi_malloc(sizeof(btc_rc_cb_t))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)btc_rc_cb_ptr, 0, sizeof(btc_rc_cb_t));
|
||||||
|
if ((bta_av_co_cb_ptr = (tBTA_AV_CO_CB *)osi_malloc(sizeof(tBTA_AV_CO_CB))) == NULL) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset((void *)bta_av_co_cb_ptr, 0, sizeof(tBTA_AV_CO_CB));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return BT_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
error_exit:;
|
||||||
|
btc_deinit_mem();
|
||||||
|
return BT_STATUS_NOMEM;
|
||||||
|
}
|
||||||
|
#endif ///BTC_DYNAMIC_MEMORY
|
||||||
|
|
||||||
|
int btc_init(void)
|
||||||
|
{
|
||||||
|
btc_thread = osi_thread_create("BTC_TASK", BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 3);
|
||||||
|
if (btc_thread == NULL) {
|
||||||
|
return BT_STATUS_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BTC_DYNAMIC_MEMORY
|
||||||
|
if (btc_init_mem() != BT_STATUS_SUCCESS){
|
||||||
|
return BT_STATUS_NOMEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (BLE_INCLUDED == TRUE)
|
||||||
|
btc_gap_callback_init();
|
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if SCAN_QUEUE_CONGEST_CHECK
|
||||||
|
btc_adv_list_init();
|
||||||
|
#endif
|
||||||
|
/* TODO: initial the profile_tab */
|
||||||
|
return BT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void btc_deinit(void)
|
||||||
|
{
|
||||||
|
#if BTC_DYNAMIC_MEMORY
|
||||||
|
btc_deinit_mem();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
osi_thread_free(btc_thread);
|
||||||
|
btc_thread = NULL;
|
||||||
|
|
||||||
|
#if SCAN_QUEUE_CONGEST_CHECK
|
||||||
|
btc_adv_list_deinit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool btc_check_queue_is_congest(void)
|
||||||
|
{
|
||||||
|
if (osi_thread_queue_wait_size(btc_thread, 0) >= BT_QUEUE_CONGEST_SIZE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,11 @@
|
||||||
#include "btc/btc_task.h"
|
#include "btc/btc_task.h"
|
||||||
#include "esp_bt_defs.h"
|
#include "esp_bt_defs.h"
|
||||||
|
|
||||||
|
#if BTC_DYNAMIC_MEMORY == FALSE
|
||||||
|
extern void *btc_profile_cb_tab[BTC_PID_NUM];
|
||||||
|
#else
|
||||||
|
extern void **btc_profile_cb_tab;
|
||||||
|
#endif
|
||||||
/* reset gatt callback table */
|
/* reset gatt callback table */
|
||||||
void esp_profile_cb_reset(void);
|
void esp_profile_cb_reset(void);
|
||||||
|
|
|
@ -16,10 +16,13 @@
|
||||||
#define __BTC_TASK_H__
|
#define __BTC_TASK_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "common/bt_target.h"
|
#include "bt_common.h"
|
||||||
#include "common/bt_defs.h"
|
|
||||||
#include "osi/thread.h"
|
#include "osi/thread.h"
|
||||||
|
|
||||||
|
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||||
|
#include "common/bt_target.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct btc_msg {
|
typedef struct btc_msg {
|
||||||
uint8_t sig; //event signal
|
uint8_t sig; //event signal
|
||||||
uint8_t aid; //application id
|
uint8_t aid; //application id
|
||||||
|
@ -53,17 +56,29 @@ typedef enum {
|
||||||
BTC_PID_BLUFI,
|
BTC_PID_BLUFI,
|
||||||
BTC_PID_DM_SEC,
|
BTC_PID_DM_SEC,
|
||||||
BTC_PID_ALARM,
|
BTC_PID_ALARM,
|
||||||
#if CONFIG_BT_CLASSIC_ENABLED
|
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||||
BTC_PID_GAP_BT,
|
BTC_PID_GAP_BT,
|
||||||
BTC_PID_PRF_QUE,
|
BTC_PID_PRF_QUE,
|
||||||
BTC_PID_A2DP,
|
BTC_PID_A2DP,
|
||||||
BTC_PID_AVRC_CT,
|
BTC_PID_AVRC_CT,
|
||||||
BTC_PID_AVRC_TG,
|
BTC_PID_AVRC_TG,
|
||||||
BTC_PID_SPP,
|
BTC_PID_SPP,
|
||||||
#if BTC_HF_CLIENT_INCLUDED
|
#if (BTC_HF_CLIENT_INCLUDED == TRUE)
|
||||||
BTC_PID_HF_CLIENT,
|
BTC_PID_HF_CLIENT,
|
||||||
#endif /* BTC_HF_CLIENT_INCLUDED */
|
#endif /* BTC_HF_CLIENT_INCLUDED */
|
||||||
#endif /* CONFIG_BT_CLASSIC_ENABLED */
|
#endif /* CLASSIC_BT_INCLUDED */
|
||||||
|
#if CONFIG_BLE_MESH
|
||||||
|
BTC_PID_PROV,
|
||||||
|
BTC_PID_MODEL,
|
||||||
|
BTC_PID_HEALTH_CLIENT,
|
||||||
|
BTC_PID_HEALTH_SERVER,
|
||||||
|
BTC_PID_CFG_CLIENT,
|
||||||
|
BTC_PID_CFG_SERVER,
|
||||||
|
BTC_PID_GENERIC_CLIENT,
|
||||||
|
BTC_PID_LIGHT_CLIENT,
|
||||||
|
BTC_PID_SENSOR_CLIENT,
|
||||||
|
BTC_PID_TIME_SCENE_CLIENT,
|
||||||
|
#endif /* CONFIG_BLE_MESH */
|
||||||
BTC_PID_NUM,
|
BTC_PID_NUM,
|
||||||
} btc_pid_t; //btc profile id
|
} btc_pid_t; //btc profile id
|
||||||
|
|
158
components/bt/common/include/bt_common.h
Normal file
158
components/bt/common/include/bt_common.h
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
|
||||||
|
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef _BT_COMMON_H_
|
||||||
|
#define _BT_COMMON_H_
|
||||||
|
|
||||||
|
#include "bt_user_config.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE true
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BT_QUEUE_CONGEST_SIZE
|
||||||
|
#define BT_QUEUE_CONGEST_SIZE 40
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BTC_INITIAL_TRACE_LEVEL UC_BT_LOG_BTC_TRACE_LEVEL
|
||||||
|
#define OSI_INITIAL_TRACE_LEVEL UC_BT_LOG_OSI_TRACE_LEVEL
|
||||||
|
|
||||||
|
#if UC_BT_BLE_DYNAMIC_ENV_MEMORY
|
||||||
|
#define BT_BLE_DYNAMIC_ENV_MEMORY TRUE
|
||||||
|
#define BTC_DYNAMIC_MEMORY TRUE
|
||||||
|
#else
|
||||||
|
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
||||||
|
#define BTC_DYNAMIC_MEMORY FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BT_BLE_DYNAMIC_ENV_MEMORY
|
||||||
|
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* OS Configuration from User config (eg: sdkconfig) */
|
||||||
|
#define TASK_PINNED_TO_CORE UC_TASK_PINNED_TO_CORE
|
||||||
|
#define BT_TASK_MAX_PRIORITIES configMAX_PRIORITIES
|
||||||
|
#define BT_BTC_TASK_STACK_SIZE UC_BTC_TASK_STACK_SIZE
|
||||||
|
|
||||||
|
/* Define trace levels */
|
||||||
|
#define BT_TRACE_LEVEL_NONE UC_TRACE_LEVEL_NONE /* No trace messages to be generated */
|
||||||
|
#define BT_TRACE_LEVEL_ERROR UC_TRACE_LEVEL_ERROR /* Error condition trace messages */
|
||||||
|
#define BT_TRACE_LEVEL_WARNING UC_TRACE_LEVEL_WARNING /* Warning condition trace messages */
|
||||||
|
#define BT_TRACE_LEVEL_API UC_TRACE_LEVEL_API /* API traces */
|
||||||
|
#define BT_TRACE_LEVEL_EVENT UC_TRACE_LEVEL_EVENT /* Debug messages for events */
|
||||||
|
#define BT_TRACE_LEVEL_DEBUG UC_TRACE_LEVEL_DEBUG /* Full debug messages */
|
||||||
|
#define BT_TRACE_LEVEL_VERBOSE UC_TRACE_LEVEL_VERBOSE /* Verbose debug messages */
|
||||||
|
|
||||||
|
#define MAX_TRACE_LEVEL UC_TRACE_LEVEL_VERBOSE
|
||||||
|
|
||||||
|
#ifndef LOG_LOCAL_LEVEL
|
||||||
|
#ifndef BOOTLOADER_BUILD
|
||||||
|
#define LOG_LOCAL_LEVEL UC_LOG_DEFAULT_LEVEL
|
||||||
|
#else
|
||||||
|
#define LOG_LOCAL_LEVEL UC_BOOTLOADER_LOG_LEVEL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mapping between ESP_LOG_LEVEL and BT_TRACE_LEVEL
|
||||||
|
#if (LOG_LOCAL_LEVEL >= 4)
|
||||||
|
#define LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL+1)
|
||||||
|
#else
|
||||||
|
#define LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
|
#define BT_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_INITIAL_TRACE_LEVEL, LOG_LOCAL_LEVEL_MAPPING) >= BT_TRACE_LEVEL_##LEVEL)
|
||||||
|
|
||||||
|
#define BT_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||||
|
#define BT_PRINT_W(tag, format, ...) {esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||||
|
#define BT_PRINT_I(tag, format, ...) {esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||||
|
#define BT_PRINT_D(tag, format, ...) {esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||||
|
#define BT_PRINT_V(tag, format, ...) {esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||||
|
|
||||||
|
#ifndef assert
|
||||||
|
#define assert(x) do { if (!(x)) BT_PRINT_E("BT", "bt host error %s %u\n", __FILE__, __LINE__); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !UC_BT_STACK_NO_LOG
|
||||||
|
/* define traces for BTC */
|
||||||
|
#define BTC_TRACE_ERROR(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTC, ERROR)) BT_PRINT_E("BT_BTC", fmt, ## args);}
|
||||||
|
#define BTC_TRACE_WARNING(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTC, WARNING)) BT_PRINT_W("BT_BTC", fmt, ## args);}
|
||||||
|
#define BTC_TRACE_API(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTC,API)) BT_PRINT_I("BT_BTC", fmt, ## args);}
|
||||||
|
#define BTC_TRACE_EVENT(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTC,EVENT)) BT_PRINT_D("BT_BTC", fmt, ## args);}
|
||||||
|
#define BTC_TRACE_DEBUG(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTC,DEBUG)) BT_PRINT_D("BT_BTC", fmt, ## args);}
|
||||||
|
#define BTC_TRACE_VERBOSE(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BTC,VERBOSE)) BT_PRINT_V("BT_BTC", fmt, ## args);}
|
||||||
|
|
||||||
|
/* define traces for OSI */
|
||||||
|
#define OSI_TRACE_ERROR(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(OSI, ERROR)) BT_PRINT_E("BT_OSI", fmt, ## args);}
|
||||||
|
#define OSI_TRACE_WARNING(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(OSI, WARNING)) BT_PRINT_W("BT_OSI", fmt, ## args);}
|
||||||
|
#define OSI_TRACE_API(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(OSI,API)) BT_PRINT_I("BT_OSI", fmt, ## args);}
|
||||||
|
#define OSI_TRACE_EVENT(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(OSI,EVENT)) BT_PRINT_D("BT_OSI", fmt, ## args);}
|
||||||
|
#define OSI_TRACE_DEBUG(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(OSI,DEBUG)) BT_PRINT_D("BT_OSI", fmt, ## args);}
|
||||||
|
#define OSI_TRACE_VERBOSE(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(OSI,VERBOSE)) BT_PRINT_V("BT_OSI", fmt, ## args);}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* define traces for BTC */
|
||||||
|
#define BTC_TRACE_ERROR(fmt, args...)
|
||||||
|
#define BTC_TRACE_WARNING(fmt, args...)
|
||||||
|
#define BTC_TRACE_API(fmt, args...)
|
||||||
|
#define BTC_TRACE_EVENT(fmt, args...)
|
||||||
|
#define BTC_TRACE_DEBUG(fmt, args...)
|
||||||
|
#define BTC_TRACE_VERBOSE(fmt, args...)
|
||||||
|
|
||||||
|
/* define traces for OSI */
|
||||||
|
#define OSI_TRACE_ERROR(fmt, args...)
|
||||||
|
#define OSI_TRACE_WARNING(fmt, args...)
|
||||||
|
#define OSI_TRACE_API(fmt, args...)
|
||||||
|
#define OSI_TRACE_EVENT(fmt, args...)
|
||||||
|
#define OSI_TRACE_DEBUG(fmt, args...)
|
||||||
|
#define OSI_TRACE_VERBOSE(fmt, args...)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Bluetooth Error Status */
|
||||||
|
/** We need to build on this */
|
||||||
|
|
||||||
|
/* relate to ESP_BT_STATUS_xxx in esp_bt_defs.h */
|
||||||
|
typedef enum {
|
||||||
|
BT_STATUS_SUCCESS = 0,
|
||||||
|
BT_STATUS_FAIL,
|
||||||
|
BT_STATUS_NOT_READY,
|
||||||
|
BT_STATUS_NOMEM,
|
||||||
|
BT_STATUS_BUSY,
|
||||||
|
BT_STATUS_DONE, /* request already completed */
|
||||||
|
BT_STATUS_UNSUPPORTED,
|
||||||
|
BT_STATUS_PARM_INVALID,
|
||||||
|
BT_STATUS_UNHANDLED,
|
||||||
|
BT_STATUS_AUTH_FAILURE,
|
||||||
|
BT_STATUS_RMT_DEV_DOWN,
|
||||||
|
BT_STATUS_AUTH_REJECTED,
|
||||||
|
BT_STATUS_INVALID_STATIC_RAND_ADDR,
|
||||||
|
BT_STATUS_PENDING,
|
||||||
|
BT_STATUS_UNACCEPT_CONN_INTERVAL,
|
||||||
|
BT_STATUS_PARAM_OUT_OF_RANGE,
|
||||||
|
BT_STATUS_TIMEOUT,
|
||||||
|
BT_STATUS_MEMORY_FULL,
|
||||||
|
BT_STATUS_EIR_TOO_LARGE,
|
||||||
|
} bt_status_t;
|
||||||
|
|
||||||
|
#endif /* _BT_COMMON_H_ */
|
83
components/bt/common/include/bt_user_config.h
Normal file
83
components/bt/common/include/bt_user_config.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef __BT_USER_CONFIG_H__
|
||||||
|
#define __BT_USER_CONFIG_H__
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#define UC_TRACE_LEVEL_NONE 0 /* No trace messages to be generated */
|
||||||
|
#define UC_TRACE_LEVEL_ERROR 1 /* Error condition trace messages */
|
||||||
|
#define UC_TRACE_LEVEL_WARNING 2 /* Warning condition trace messages */
|
||||||
|
#define UC_TRACE_LEVEL_API 3 /* API traces */
|
||||||
|
#define UC_TRACE_LEVEL_EVENT 4 /* Debug messages for events */
|
||||||
|
#define UC_TRACE_LEVEL_DEBUG 5 /* Full debug messages */
|
||||||
|
#define UC_TRACE_LEVEL_VERBOSE 6 /* Verbose debug messages */
|
||||||
|
|
||||||
|
//DYNAMIC ENV ALLOCATOR
|
||||||
|
#ifdef CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY
|
||||||
|
#define UC_BT_BLE_DYNAMIC_ENV_MEMORY CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY
|
||||||
|
#else
|
||||||
|
#define UC_BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_STACK_NO_LOG
|
||||||
|
#define UC_BT_STACK_NO_LOG CONFIG_BT_STACK_NO_LOG
|
||||||
|
#else
|
||||||
|
#define UC_BT_STACK_NO_LOG FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Thread/Task reference
|
||||||
|
**********************************************************/
|
||||||
|
#ifdef CONFIG_BLUEDROID_PINNED_TO_CORE
|
||||||
|
#define UC_TASK_PINNED_TO_CORE (CONFIG_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY)
|
||||||
|
#else
|
||||||
|
#define UC_TASK_PINNED_TO_CORE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Trace reference
|
||||||
|
**********************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOG_DEFAULT_LEVEL
|
||||||
|
#define UC_LOG_DEFAULT_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||||
|
#else
|
||||||
|
#define UC_LOG_DEFAULT_LEVEL 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_LOG_LEVEL
|
||||||
|
#define UC_BOOTLOADER_LOG_LEVEL CONFIG_BOOTLOADER_LOG_LEVEL
|
||||||
|
#else
|
||||||
|
#define UC_BOOTLOADER_LOG_LEVEL 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LOG_BTC_TRACE_LEVEL
|
||||||
|
#define UC_BT_LOG_BTC_TRACE_LEVEL CONFIG_BT_LOG_BTC_TRACE_LEVEL
|
||||||
|
#else
|
||||||
|
#define UC_BT_LOG_BTC_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LOG_OSI_TRACE_LEVEL
|
||||||
|
#define UC_BT_LOG_OSI_TRACE_LEVEL CONFIG_BT_LOG_OSI_TRACE_LEVEL
|
||||||
|
#else
|
||||||
|
#define UC_BT_LOG_OSI_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __BT_USER_CONFIG_H__ */
|
|
@ -18,8 +18,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "common/bt_defs.h"
|
|
||||||
#include "common/bt_trace.h"
|
|
||||||
#include "osi/alarm.h"
|
#include "osi/alarm.h"
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
#include "osi/list.h"
|
#include "osi/list.h"
|
||||||
|
@ -27,6 +25,7 @@
|
||||||
#include "btc/btc_task.h"
|
#include "btc/btc_task.h"
|
||||||
#include "btc/btc_alarm.h"
|
#include "btc/btc_alarm.h"
|
||||||
#include "osi/mutex.h"
|
#include "osi/mutex.h"
|
||||||
|
#include "bt_common.h"
|
||||||
|
|
||||||
typedef struct alarm_t {
|
typedef struct alarm_t {
|
||||||
/* timer id point to here */
|
/* timer id point to here */
|
||||||
|
@ -44,7 +43,11 @@ enum {
|
||||||
static osi_mutex_t alarm_mutex;
|
static osi_mutex_t alarm_mutex;
|
||||||
static int alarm_state;
|
static int alarm_state;
|
||||||
|
|
||||||
|
#if (BT_BLE_DYNAMIC_ENV_MEMORY == FALSE)
|
||||||
static struct alarm_t alarm_cbs[ALARM_CBS_NUM];
|
static struct alarm_t alarm_cbs[ALARM_CBS_NUM];
|
||||||
|
#else
|
||||||
|
static struct alarm_t *alarm_cbs;
|
||||||
|
#endif
|
||||||
|
|
||||||
static osi_alarm_err_t alarm_free(osi_alarm_t *alarm);
|
static osi_alarm_err_t alarm_free(osi_alarm_t *alarm);
|
||||||
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic);
|
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic);
|
||||||
|
@ -78,7 +81,14 @@ void osi_alarm_init(void)
|
||||||
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state);
|
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
memset(alarm_cbs, 0x00, sizeof(alarm_cbs));
|
#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
|
||||||
|
if ((alarm_cbs = (osi_alarm_t *)osi_malloc(sizeof(osi_alarm_t) * ALARM_CBS_NUM)) == NULL) {
|
||||||
|
OSI_TRACE_ERROR("%s, malloc failed\n", __func__);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset(alarm_cbs, 0x00, sizeof(osi_alarm_t) * ALARM_CBS_NUM);
|
||||||
alarm_state = ALARM_STATE_OPEN;
|
alarm_state = ALARM_STATE_OPEN;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -100,6 +110,12 @@ void osi_alarm_deinit(void)
|
||||||
alarm_free(&alarm_cbs[i]);
|
alarm_free(&alarm_cbs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
|
||||||
|
osi_free(alarm_cbs);
|
||||||
|
alarm_cbs = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
alarm_state = ALARM_STATE_IDLE;
|
alarm_state = ALARM_STATE_IDLE;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -251,12 +267,12 @@ end:
|
||||||
|
|
||||||
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
|
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
|
||||||
{
|
{
|
||||||
return alarm_set(alarm, timeout, false);
|
return alarm_set(alarm, timeout, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period)
|
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period)
|
||||||
{
|
{
|
||||||
return alarm_set(alarm, period, true);
|
return alarm_set(alarm, period, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm)
|
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm)
|
|
@ -18,13 +18,14 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "common/bt_defs.h"
|
#include "bt_common.h"
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
|
|
||||||
extern void *pvPortZalloc(size_t size);
|
extern void *pvPortZalloc(size_t size);
|
||||||
extern void vPortFree(void *pv);
|
extern void vPortFree(void *pv);
|
||||||
|
|
||||||
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
|
|
||||||
|
#if HEAP_MEMORY_DEBUG
|
||||||
|
|
||||||
#define OSI_MEM_DBG_INFO_MAX 1024*3
|
#define OSI_MEM_DBG_INFO_MAX 1024*3
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -35,8 +36,16 @@ typedef struct {
|
||||||
} osi_mem_dbg_info_t;
|
} osi_mem_dbg_info_t;
|
||||||
|
|
||||||
static uint32_t mem_dbg_count = 0;
|
static uint32_t mem_dbg_count = 0;
|
||||||
static uint32_t mem_dbg_count2 = 0;
|
|
||||||
static osi_mem_dbg_info_t mem_dbg_info[OSI_MEM_DBG_INFO_MAX];
|
static osi_mem_dbg_info_t mem_dbg_info[OSI_MEM_DBG_INFO_MAX];
|
||||||
|
static uint32_t mem_dbg_current_size = 0;
|
||||||
|
static uint32_t mem_dbg_max_size = 0;
|
||||||
|
|
||||||
|
#define OSI_MEM_DBG_MAX_SECTION_NUM 5
|
||||||
|
typedef struct {
|
||||||
|
bool used;
|
||||||
|
uint32_t max_size;
|
||||||
|
} osi_mem_dbg_max_size_section_t;
|
||||||
|
static osi_mem_dbg_max_size_section_t mem_dbg_max_size_section[OSI_MEM_DBG_MAX_SECTION_NUM];
|
||||||
|
|
||||||
void osi_mem_dbg_init(void)
|
void osi_mem_dbg_init(void)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +58,13 @@ void osi_mem_dbg_init(void)
|
||||||
mem_dbg_info[i].line = 0;
|
mem_dbg_info[i].line = 0;
|
||||||
}
|
}
|
||||||
mem_dbg_count = 0;
|
mem_dbg_count = 0;
|
||||||
mem_dbg_count2 = 0;
|
mem_dbg_current_size = 0;
|
||||||
|
mem_dbg_max_size = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||||
|
mem_dbg_max_size_section[i].used = false;
|
||||||
|
mem_dbg_max_size_section[i].max_size = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void osi_mem_dbg_record(void *p, int size, const char *func, int line)
|
void osi_mem_dbg_record(void *p, int size, const char *func, int line)
|
||||||
|
@ -75,6 +90,19 @@ void osi_mem_dbg_record(void *p, int size, const char *func, int line)
|
||||||
if (i >= OSI_MEM_DBG_INFO_MAX) {
|
if (i >= OSI_MEM_DBG_INFO_MAX) {
|
||||||
OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line);
|
OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mem_dbg_current_size += size;
|
||||||
|
if(mem_dbg_max_size < mem_dbg_current_size) {
|
||||||
|
mem_dbg_max_size = mem_dbg_current_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||||
|
if (mem_dbg_max_size_section[i].used) {
|
||||||
|
if(mem_dbg_max_size_section[i].max_size < mem_dbg_current_size) {
|
||||||
|
mem_dbg_max_size_section[i].max_size = mem_dbg_current_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void osi_mem_dbg_clean(void *p, const char *func, int line)
|
void osi_mem_dbg_clean(void *p, const char *func, int line)
|
||||||
|
@ -88,6 +116,7 @@ void osi_mem_dbg_clean(void *p, const char *func, int line)
|
||||||
|
|
||||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||||
if (mem_dbg_info[i].p == p) {
|
if (mem_dbg_info[i].p == p) {
|
||||||
|
mem_dbg_current_size -= mem_dbg_info[i].size;
|
||||||
mem_dbg_info[i].p = NULL;
|
mem_dbg_info[i].p = NULL;
|
||||||
mem_dbg_info[i].size = 0;
|
mem_dbg_info[i].size = 0;
|
||||||
mem_dbg_info[i].func = NULL;
|
mem_dbg_info[i].func = NULL;
|
||||||
|
@ -112,6 +141,60 @@ void osi_mem_dbg_show(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OSI_TRACE_ERROR("--> count %d\n", mem_dbg_count);
|
OSI_TRACE_ERROR("--> count %d\n", mem_dbg_count);
|
||||||
|
OSI_TRACE_ERROR("--> size %dB\n--> max size %dB\n", mem_dbg_current_size, mem_dbg_max_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t osi_mem_dbg_get_max_size(void)
|
||||||
|
{
|
||||||
|
return mem_dbg_max_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t osi_mem_dbg_get_current_size(void)
|
||||||
|
{
|
||||||
|
return mem_dbg_current_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void osi_men_dbg_set_section_start(uint8_t index)
|
||||||
|
{
|
||||||
|
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) {
|
||||||
|
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
|
||||||
|
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mem_dbg_max_size_section[index].used) {
|
||||||
|
OSI_TRACE_WARNING("This index(%d) has been started, restart it.\n", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_dbg_max_size_section[index].used = true;
|
||||||
|
mem_dbg_max_size_section[index].max_size = mem_dbg_current_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void osi_men_dbg_set_section_end(uint8_t index)
|
||||||
|
{
|
||||||
|
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) {
|
||||||
|
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
|
||||||
|
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mem_dbg_max_size_section[index].used) {
|
||||||
|
OSI_TRACE_ERROR("This index(%d) has not been started.\n", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_dbg_max_size_section[index].used = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index)
|
||||||
|
{
|
||||||
|
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM){
|
||||||
|
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
|
||||||
|
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mem_dbg_max_size_section[index].max_size;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -130,47 +213,47 @@ char *osi_strdup(const char *str)
|
||||||
|
|
||||||
void *osi_malloc_func(size_t size)
|
void *osi_malloc_func(size_t size)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
|
#if HEAP_MEMORY_DEBUG
|
||||||
void *p;
|
void *p;
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||||
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||||
#else
|
#else
|
||||||
p = malloc(size);
|
p = malloc(size);
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||||
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
||||||
return p;
|
return p;
|
||||||
#else
|
#else
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||||
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||||
#else
|
#else
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||||
#endif /* #ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG */
|
#endif /* #if HEAP_MEMORY_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
void *osi_calloc_func(size_t size)
|
void *osi_calloc_func(size_t size)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
|
#if HEAP_MEMORY_DEBUG
|
||||||
void *p;
|
void *p;
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||||
p = heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
p = heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||||
#else
|
#else
|
||||||
p = calloc(1, size);
|
p = calloc(1, size);
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||||
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
||||||
return p;
|
return p;
|
||||||
#else
|
#else
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||||
return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||||
#else
|
#else
|
||||||
return calloc(1, size);
|
return calloc(1, size);
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||||
#endif /* #ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG */
|
#endif /* #if HEAP_MEMORY_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
void osi_free_func(void *ptr)
|
void osi_free_func(void *ptr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
|
#if HEAP_MEMORY_DEBUG
|
||||||
osi_mem_dbg_clean(ptr, __func__, __LINE__);
|
osi_mem_dbg_clean(ptr, __func__, __LINE__);
|
||||||
#endif
|
#endif
|
||||||
free(ptr);
|
free(ptr);
|
|
@ -16,11 +16,9 @@
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "common/bt_trace.h"
|
#include "bt_common.h"
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
#include "osi/buffer.h"
|
#include "osi/buffer.h"
|
||||||
#include "common/bt_defs.h"
|
|
||||||
#include "common/bt_trace.h"
|
|
||||||
|
|
||||||
struct buffer_t {
|
struct buffer_t {
|
||||||
buffer_t *root;
|
buffer_t *root;
|
|
@ -23,10 +23,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bt_common.h"
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
#include "osi/config.h"
|
#include "osi/config.h"
|
||||||
#include "osi/list.h"
|
#include "osi/list.h"
|
||||||
#include "common/bt_trace.h"
|
|
||||||
|
|
||||||
#define CONFIG_FILE_MAX_SIZE (1536)//1.5k
|
#define CONFIG_FILE_MAX_SIZE (1536)//1.5k
|
||||||
#define CONFIG_FILE_DEFAULE_LENGTH (2048)
|
#define CONFIG_FILE_DEFAULE_LENGTH (2048)
|
||||||
|
@ -440,8 +440,9 @@ bool config_save(const config_t *config, const char *filename)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
uint count = (w_cnt_total / CONFIG_FILE_MAX_SIZE);
|
int count = (w_cnt_total / CONFIG_FILE_MAX_SIZE);
|
||||||
for (int i = 0; i <= count; i++)
|
assert(count <= 0xFF);
|
||||||
|
for (uint8_t i = 0; i <= count; i++)
|
||||||
{
|
{
|
||||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, i);
|
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, i);
|
||||||
if (i == count) {
|
if (i == count) {
|
|
@ -16,12 +16,10 @@
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "common/bt_defs.h"
|
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
#include "osi/fixed_queue.h"
|
#include "osi/fixed_queue.h"
|
||||||
#include "osi/list.h"
|
#include "osi/list.h"
|
||||||
#include "osi/osi.h"
|
#include "osi/osi.h"
|
||||||
#include "common/bt_trace.h"
|
|
||||||
#include "osi/mutex.h"
|
#include "osi/mutex.h"
|
||||||
#include "osi/semaphore.h"
|
#include "osi/semaphore.h"
|
||||||
|
|
||||||
|
@ -129,45 +127,12 @@ size_t fixed_queue_capacity(fixed_queue_t *queue)
|
||||||
return queue->capacity;
|
return queue->capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixed_queue_enqueue(fixed_queue_t *queue, void *data)
|
bool fixed_queue_enqueue(fixed_queue_t *queue, void *data, uint32_t timeout)
|
||||||
{
|
{
|
||||||
assert(queue != NULL);
|
assert(queue != NULL);
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
osi_sem_take(&queue->enqueue_sem, OSI_SEM_MAX_TIMEOUT);
|
if (osi_sem_take(&queue->enqueue_sem, timeout) != 0) {
|
||||||
|
|
||||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
|
||||||
|
|
||||||
list_append(queue->list, data);
|
|
||||||
osi_mutex_unlock(&queue->lock);
|
|
||||||
|
|
||||||
osi_sem_give(&queue->dequeue_sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *fixed_queue_dequeue(fixed_queue_t *queue)
|
|
||||||
{
|
|
||||||
void *ret = NULL;
|
|
||||||
|
|
||||||
assert(queue != NULL);
|
|
||||||
|
|
||||||
osi_sem_take(&queue->dequeue_sem, OSI_SEM_MAX_TIMEOUT);
|
|
||||||
|
|
||||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
|
||||||
ret = list_front(queue->list);
|
|
||||||
list_remove(queue->list, ret);
|
|
||||||
osi_mutex_unlock(&queue->lock);
|
|
||||||
|
|
||||||
osi_sem_give(&queue->enqueue_sem);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fixed_queue_try_enqueue(fixed_queue_t *queue, void *data)
|
|
||||||
{
|
|
||||||
assert(queue != NULL);
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
if (osi_sem_take(&queue->enqueue_sem, 0) != 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,15 +146,13 @@ bool fixed_queue_try_enqueue(fixed_queue_t *queue, void *data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *fixed_queue_try_dequeue(fixed_queue_t *queue)
|
void *fixed_queue_dequeue(fixed_queue_t *queue, uint32_t timeout)
|
||||||
{
|
{
|
||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
|
|
||||||
if (queue == NULL) {
|
assert(queue != NULL);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (osi_sem_take(queue->dequeue_sem, 0) != 0) {
|
if (osi_sem_take(queue->dequeue_sem, timeout) != 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "common/bt_trace.h"
|
#include "bt_common.h"
|
||||||
|
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
#include "osi/future.h"
|
#include "osi/future.h"
|
||||||
#include "osi/osi.h"
|
#include "osi/osi.h"
|
|
@ -16,8 +16,7 @@
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "common/bt_defs.h"
|
#include "bt_common.h"
|
||||||
#include "common/bt_trace.h"
|
|
||||||
#include "osi/list.h"
|
#include "osi/list.h"
|
||||||
#include "osi/hash_map.h"
|
#include "osi/hash_map.h"
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
|
@ -22,7 +22,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
|
||||||
char *osi_strdup(const char *str);
|
char *osi_strdup(const char *str);
|
||||||
|
|
||||||
|
@ -30,14 +29,19 @@ void *osi_malloc_func(size_t size);
|
||||||
void *osi_calloc_func(size_t size);
|
void *osi_calloc_func(size_t size);
|
||||||
void osi_free_func(void *ptr);
|
void osi_free_func(void *ptr);
|
||||||
|
|
||||||
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
|
#if HEAP_MEMORY_DEBUG
|
||||||
|
|
||||||
void osi_mem_dbg_init(void);
|
void osi_mem_dbg_init(void);
|
||||||
void osi_mem_dbg_record(void *p, int size, const char *func, int line);
|
void osi_mem_dbg_record(void *p, int size, const char *func, int line);
|
||||||
void osi_mem_dbg_clean(void *p, const char *func, int line);
|
void osi_mem_dbg_clean(void *p, const char *func, int line);
|
||||||
void osi_mem_dbg_show(void);
|
void osi_mem_dbg_show(void);
|
||||||
|
uint32_t osi_mem_dbg_get_max_size(void);
|
||||||
|
uint32_t osi_mem_dbg_get_current_size(void);
|
||||||
|
void osi_men_dbg_set_section_start(uint8_t index);
|
||||||
|
void osi_men_dbg_set_section_end(uint8_t index);
|
||||||
|
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index);
|
||||||
|
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||||
#define osi_malloc(size) \
|
#define osi_malloc(size) \
|
||||||
({ \
|
({ \
|
||||||
void *p; \
|
void *p; \
|
||||||
|
@ -76,7 +80,7 @@ void osi_mem_dbg_show(void);
|
||||||
(void *)p; \
|
(void *)p; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -84,11 +88,11 @@ void osi_mem_dbg_show(void);
|
||||||
do { \
|
do { \
|
||||||
void *p; \
|
void *p; \
|
||||||
\
|
\
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST \
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
|
||||||
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||||
#else \
|
#else \
|
||||||
p = malloc((size)); \
|
p = malloc((size)); \
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ \
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
|
||||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
(void *)p; \
|
(void *)p; \
|
||||||
}while(0)
|
}while(0)
|
||||||
|
@ -97,13 +101,13 @@ do { \
|
||||||
do { \
|
do { \
|
||||||
void *p; \
|
void *p; \
|
||||||
\
|
\
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST \
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
|
||||||
p = heap_caps_calloc_prefer(1, size, 2, \
|
p = heap_caps_calloc_prefer(1, size, 2, \
|
||||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
||||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||||
#else \
|
#else \
|
||||||
p = calloc(1, (size)); \
|
p = calloc(1, (size)); \
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ \
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
|
||||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
(void *)p; \
|
(void *)p; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
@ -118,16 +122,16 @@ do { \
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||||
#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
|
#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
|
||||||
#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
|
#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
|
||||||
#else
|
#else
|
||||||
#define osi_malloc(size) malloc((size))
|
#define osi_malloc(size) malloc((size))
|
||||||
#define osi_calloc(size) calloc(1, (size))
|
#define osi_calloc(size) calloc(1, (size))
|
||||||
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||||
#define osi_free(p) free((p))
|
#define osi_free(p) free((p))
|
||||||
|
|
||||||
#endif /* CONFIG_BT_BLUEDROID_MEM_DEBUG */
|
#endif /* HEAP_MEMORY_DEBUG */
|
||||||
|
|
||||||
#define FREE_AND_RESET(a) \
|
#define FREE_AND_RESET(a) \
|
||||||
do { \
|
do { \
|
|
@ -21,11 +21,14 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "osi/list.h"
|
#include "osi/list.h"
|
||||||
|
#include "osi/semaphore.h"
|
||||||
|
|
||||||
#ifndef QUEUE_SIZE_MAX
|
#ifndef QUEUE_SIZE_MAX
|
||||||
#define QUEUE_SIZE_MAX 254
|
#define QUEUE_SIZE_MAX 254
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define FIXED_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
|
||||||
|
|
||||||
struct fixed_queue_t;
|
struct fixed_queue_t;
|
||||||
|
|
||||||
typedef struct fixed_queue_t fixed_queue_t;
|
typedef struct fixed_queue_t fixed_queue_t;
|
||||||
|
@ -56,27 +59,14 @@ size_t fixed_queue_length(fixed_queue_t *queue);
|
||||||
// not be NULL.
|
// not be NULL.
|
||||||
size_t fixed_queue_capacity(fixed_queue_t *queue);
|
size_t fixed_queue_capacity(fixed_queue_t *queue);
|
||||||
|
|
||||||
// Enqueues the given |data| into the |queue|. The caller will be blocked
|
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
|
||||||
// if nore more space is available in the queue. Neither |queue| nor |data|
|
// If enqueue failed, it will return false, otherwise return true
|
||||||
// may be NULL.
|
bool fixed_queue_enqueue(fixed_queue_t *queue, void *data, uint32_t timeout);
|
||||||
void fixed_queue_enqueue(fixed_queue_t *queue, void *data);
|
|
||||||
|
|
||||||
// Dequeues the next element from |queue|. If the queue is currently empty,
|
// Dequeues the next element from |queue|. If the queue is currently empty,
|
||||||
// this function will block the caller until an item is enqueued. This
|
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
|
||||||
// function will never return NULL. |queue| may not be NULL.
|
// If dequeue failed, it will return NULL, otherwise return a point.
|
||||||
void *fixed_queue_dequeue(fixed_queue_t *queue);
|
void *fixed_queue_dequeue(fixed_queue_t *queue, uint32_t timeout);
|
||||||
|
|
||||||
// Tries to enqueue |data| into the |queue|. This function will never block
|
|
||||||
// the caller. If the queue capacity would be exceeded by adding one more
|
|
||||||
// element, this function returns false immediately. Otherwise, this function
|
|
||||||
// returns true. Neither |queue| nor |data| may be NULL.
|
|
||||||
bool fixed_queue_try_enqueue(fixed_queue_t *queue, void *data);
|
|
||||||
|
|
||||||
// Tries to dequeue an element from |queue|. This function will never block
|
|
||||||
// the caller. If the queue is empty, this function returns NULL immediately.
|
|
||||||
// Otherwise, the next element in the queue is returned. |queue| may not be
|
|
||||||
// NULL.
|
|
||||||
void *fixed_queue_try_dequeue(fixed_queue_t *queue);
|
|
||||||
|
|
||||||
// Returns the first element from |queue|, if present, without dequeuing it.
|
// Returns the first element from |queue|, if present, without dequeuing it.
|
||||||
// This function will never block the caller. Returns NULL if there are no
|
// This function will never block the caller. Returns NULL if there are no
|
|
@ -23,9 +23,9 @@
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
#include "osi/semaphore.h"
|
||||||
|
|
||||||
|
#define OSI_MUTEX_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
|
||||||
#define OSI_MUTEX_MAX_TIMEOUT 0xffffffffUL
|
|
||||||
|
|
||||||
#define osi_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
#define osi_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||||
#define osi_mutex_set_invalid( x ) ( ( *x ) = NULL )
|
#define osi_mutex_set_invalid( x ) ( ( *x ) = NULL )
|
92
components/bt/common/osi/include/osi/thread.h
Normal file
92
components/bt/common/osi/include/osi/thread.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
// Copyright 2015-2016 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.
|
||||||
|
|
||||||
|
#ifndef __THREAD_H__
|
||||||
|
#define __THREAD_H__
|
||||||
|
|
||||||
|
#include "freertos/xtensa_api.h"
|
||||||
|
#include "freertos/FreeRTOSConfig.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "osi/semaphore.h"
|
||||||
|
#include "esp_task.h"
|
||||||
|
#include "bt_common.h"
|
||||||
|
|
||||||
|
#define portBASE_TYPE int
|
||||||
|
|
||||||
|
#define OSI_THREAD_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
|
||||||
|
|
||||||
|
struct osi_thread;
|
||||||
|
|
||||||
|
typedef struct osi_thread osi_thread_t;
|
||||||
|
|
||||||
|
typedef void (*osi_thread_func_t)(void *context);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OSI_THREAD_CORE_0 = 0,
|
||||||
|
OSI_THREAD_CORE_1,
|
||||||
|
OSI_THREAD_CORE_AFFINITY,
|
||||||
|
} osi_thread_core_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Create a thread or task
|
||||||
|
* param name: thread name
|
||||||
|
* param stack_size: thread stack size
|
||||||
|
* param priority: thread priority
|
||||||
|
* param core: the CPU core which this thread run, OSI_THREAD_CORE_AFFINITY means unspecific CPU core
|
||||||
|
* param work_queue_num: speicify queue number, the queue[0] has highest priority, and the priority is decrease by index
|
||||||
|
* return : if create successfully, return thread handler; otherwise return NULL.
|
||||||
|
*/
|
||||||
|
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Destroy a thread or task
|
||||||
|
* param thread: point of thread handler
|
||||||
|
*/
|
||||||
|
void osi_thread_free(osi_thread_t *thread);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Post an msg to a thread and told the thread call the function
|
||||||
|
* param thread: point of thread handler
|
||||||
|
* param func: callback function that called by target thread
|
||||||
|
* param context: argument of callback function
|
||||||
|
* param queue_idx: the queue which the msg send to
|
||||||
|
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
|
||||||
|
* return : if post successfully, return true, otherwise return false
|
||||||
|
*/
|
||||||
|
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Set the priority of thread
|
||||||
|
* param thread: point of thread handler
|
||||||
|
* param priority: priority
|
||||||
|
* return : if set successfully, return true, otherwise return false
|
||||||
|
*/
|
||||||
|
bool osi_thread_set_priority(osi_thread_t *thread, int priority);
|
||||||
|
|
||||||
|
/* brief: Get thread name
|
||||||
|
* param thread: point of thread handler
|
||||||
|
* return: constant point of thread name
|
||||||
|
*/
|
||||||
|
const char *osi_thread_name(osi_thread_t *thread);
|
||||||
|
|
||||||
|
/* brief: Get the size of the specified queue
|
||||||
|
* param thread: point of thread handler
|
||||||
|
* param wq_idx: the queue index of the thread
|
||||||
|
* return: queue size
|
||||||
|
*/
|
||||||
|
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
|
||||||
|
|
||||||
|
#endif /* __THREAD_H__ */
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
#include "common/bt_defs.h"
|
#include "bt_common.h"
|
||||||
|
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
#include "osi/list.h"
|
#include "osi/list.h"
|
||||||
#include "osi/osi.h"
|
#include "osi/osi.h"
|
278
components/bt/common/osi/thread.c
Normal file
278
components/bt/common/osi/thread.c
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Google, Inc.
|
||||||
|
*
|
||||||
|
* 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 <string.h>
|
||||||
|
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
#include "osi/fixed_queue.h"
|
||||||
|
#include "osi/semaphore.h"
|
||||||
|
#include "osi/thread.h"
|
||||||
|
|
||||||
|
struct osi_thread {
|
||||||
|
void *thread_handle; /*!< Store the thread object */
|
||||||
|
int thread_id; /*!< May for some OS, such as Linux */
|
||||||
|
bool stop;
|
||||||
|
uint8_t work_queue_num; /*!< Work queue number */
|
||||||
|
fixed_queue_t **work_queues; /*!< Point to queue array, and the priority inverse array index */
|
||||||
|
osi_sem_t work_sem;
|
||||||
|
osi_sem_t stop_sem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct osi_thread_start_arg {
|
||||||
|
osi_thread_t *thread;
|
||||||
|
osi_sem_t start_sem;
|
||||||
|
int error;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
osi_thread_func_t func;
|
||||||
|
void *context;
|
||||||
|
} work_item_t;
|
||||||
|
|
||||||
|
static const size_t DEFAULT_WORK_QUEUE_CAPACITY = 100;
|
||||||
|
|
||||||
|
static void osi_thread_run(void *arg)
|
||||||
|
{
|
||||||
|
struct osi_thread_start_arg *start = (struct osi_thread_start_arg *)arg;
|
||||||
|
osi_thread_t *thread = start->thread;
|
||||||
|
|
||||||
|
osi_sem_give(&start->start_sem);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
osi_sem_take(&thread->work_sem, OSI_SEM_MAX_TIMEOUT);
|
||||||
|
|
||||||
|
if (thread->stop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!thread->stop && idx < thread->work_queue_num) {
|
||||||
|
work_item_t *item = fixed_queue_dequeue(thread->work_queues[idx], 0);
|
||||||
|
if (item) {
|
||||||
|
item->func(item->context);
|
||||||
|
osi_free(item);
|
||||||
|
idx = 0;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thread->thread_handle = NULL;
|
||||||
|
osi_sem_give(&thread->stop_sem);
|
||||||
|
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int osi_thread_join(osi_thread_t *thread, uint32_t wait_ms)
|
||||||
|
{
|
||||||
|
assert(thread != NULL);
|
||||||
|
return osi_sem_take(&thread->stop_sem, wait_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void osi_thread_stop(osi_thread_t *thread)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
assert(thread != NULL);
|
||||||
|
|
||||||
|
//stop the thread
|
||||||
|
thread->stop = true;
|
||||||
|
osi_sem_give(&thread->work_sem);
|
||||||
|
|
||||||
|
//join
|
||||||
|
ret = osi_thread_join(thread, 1000); //wait 1000ms
|
||||||
|
|
||||||
|
//if join failed, delete the task here
|
||||||
|
if (ret != 0 && thread->thread_handle) {
|
||||||
|
vTaskDelete(thread->thread_handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//in linux, the stack_size, priority and core may not be set here, the code will be ignore the arguments
|
||||||
|
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
osi_thread_t *thread;
|
||||||
|
struct osi_thread_start_arg start_arg = {0};
|
||||||
|
|
||||||
|
if (stack_size <= 0 ||
|
||||||
|
core < OSI_THREAD_CORE_0 || core > OSI_THREAD_CORE_AFFINITY ||
|
||||||
|
work_queue_num <= 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread = (osi_thread_t *)osi_malloc(sizeof(osi_thread_t));
|
||||||
|
if (thread == NULL) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread->stop = false;
|
||||||
|
thread->work_queue_num = work_queue_num;
|
||||||
|
thread->work_queues = (fixed_queue_t **)osi_malloc(sizeof(fixed_queue_t *) * work_queue_num);
|
||||||
|
if (thread->work_queues == NULL) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < thread->work_queue_num; i++) {
|
||||||
|
thread->work_queues[i] = fixed_queue_new(DEFAULT_WORK_QUEUE_CAPACITY);
|
||||||
|
if (thread->work_queues[i] == NULL) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = osi_sem_new(&thread->work_sem, 1, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = osi_sem_new(&thread->stop_sem, 1, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_arg.thread = thread;
|
||||||
|
ret = osi_sem_new(&start_arg.start_sem, 1, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xTaskCreatePinnedToCore(osi_thread_run, name, stack_size, &start_arg, priority, &thread->thread_handle, core) != pdPASS) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
osi_sem_take(&start_arg.start_sem, OSI_SEM_MAX_TIMEOUT);
|
||||||
|
osi_sem_free(&start_arg.start_sem);
|
||||||
|
|
||||||
|
return thread;
|
||||||
|
|
||||||
|
_err:
|
||||||
|
|
||||||
|
if (thread) {
|
||||||
|
if (start_arg.start_sem) {
|
||||||
|
osi_sem_free(&start_arg.start_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->thread_handle) {
|
||||||
|
vTaskDelete(thread->thread_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < thread->work_queue_num; i++) {
|
||||||
|
if (thread->work_queues[i]) {
|
||||||
|
fixed_queue_free(thread->work_queues[i], osi_free_func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->work_queues) {
|
||||||
|
osi_free(thread->work_queues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->work_sem) {
|
||||||
|
osi_sem_free(&thread->work_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->stop_sem) {
|
||||||
|
osi_sem_free(&thread->stop_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
osi_free(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void osi_thread_free(osi_thread_t *thread)
|
||||||
|
{
|
||||||
|
if (!thread)
|
||||||
|
return;
|
||||||
|
|
||||||
|
osi_thread_stop(thread);
|
||||||
|
|
||||||
|
for (int i = 0; i < thread->work_queue_num; i++) {
|
||||||
|
if (thread->work_queues[i]) {
|
||||||
|
fixed_queue_free(thread->work_queues[i], osi_free_func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->work_queues) {
|
||||||
|
osi_free(thread->work_queues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->work_sem) {
|
||||||
|
osi_sem_free(&thread->work_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->stop_sem) {
|
||||||
|
osi_sem_free(&thread->stop_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
osi_free(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout)
|
||||||
|
{
|
||||||
|
assert(thread != NULL);
|
||||||
|
assert(func != NULL);
|
||||||
|
|
||||||
|
if (queue_idx >= thread->work_queue_num) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
work_item_t *item = (work_item_t *)osi_malloc(sizeof(work_item_t));
|
||||||
|
if (item == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
item->func = func;
|
||||||
|
item->context = context;
|
||||||
|
|
||||||
|
if (fixed_queue_enqueue(thread->work_queues[queue_idx], item, timeout) == false) {
|
||||||
|
osi_free(item);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
osi_sem_give(&thread->work_sem);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool osi_thread_set_priority(osi_thread_t *thread, int priority)
|
||||||
|
{
|
||||||
|
assert(thread != NULL);
|
||||||
|
|
||||||
|
vTaskPrioritySet(thread->thread_handle, priority);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *osi_thread_name(osi_thread_t *thread)
|
||||||
|
{
|
||||||
|
assert(thread != NULL);
|
||||||
|
|
||||||
|
return pcTaskGetTaskName(thread->thread_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx)
|
||||||
|
{
|
||||||
|
if (wq_idx < 0 || wq_idx >= thread->work_queue_num) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixed_queue_length(thread->work_queues[wq_idx]);
|
||||||
|
}
|
|
@ -3,130 +3,196 @@
|
||||||
#
|
#
|
||||||
ifdef CONFIG_BT_ENABLED
|
ifdef CONFIG_BT_ENABLED
|
||||||
|
|
||||||
COMPONENT_SRCDIRS := .
|
COMPONENT_SRCDIRS := controller
|
||||||
|
|
||||||
COMPONENT_ADD_INCLUDEDIRS := include
|
COMPONENT_ADD_INCLUDEDIRS := include
|
||||||
|
|
||||||
LIBS := btdm_app
|
LIBS := btdm_app
|
||||||
|
|
||||||
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/lib \
|
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/controller/lib \
|
||||||
$(addprefix -l,$(LIBS))
|
$(addprefix -l,$(LIBS))
|
||||||
|
|
||||||
# re-link program if BT binary libs change
|
# re-link program if BT binary libs change
|
||||||
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
|
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/controller/lib/lib%.a,$(LIBS))
|
||||||
|
|
||||||
COMPONENT_SUBMODULES += lib
|
COMPONENT_SUBMODULES += controller/lib
|
||||||
|
|
||||||
ifeq ($(GCC_NOT_5_2_0), 1)
|
ifeq ($(GCC_NOT_5_2_0), 1)
|
||||||
# TODO: annotate fallthroughs in Bluedroid code with comments
|
# TODO: annotate fallthroughs in Bluedroid code with comments
|
||||||
CFLAGS += -Wno-implicit-fallthrough
|
CFLAGS += -Wno-implicit-fallthrough
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
ifdef CONFIG_BT_BLUEDROID_ENABLED
|
ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||||
|
|
||||||
COMPONENT_PRIV_INCLUDEDIRS += bluedroid/bta/include \
|
COMPONENT_PRIV_INCLUDEDIRS += host/bluedroid/bta/include \
|
||||||
bluedroid/bta/ar/include \
|
host/bluedroid/bta/ar/include \
|
||||||
bluedroid/bta/av/include \
|
host/bluedroid/bta/av/include \
|
||||||
bluedroid/bta/hf_client/include \
|
host/bluedroid/bta/hf_client/include \
|
||||||
bluedroid/bta/dm/include \
|
host/bluedroid/bta/dm/include \
|
||||||
bluedroid/bta/gatt/include \
|
host/bluedroid/bta/gatt/include \
|
||||||
bluedroid/bta/hh/include \
|
host/bluedroid/bta/hh/include \
|
||||||
bluedroid/bta/jv/include \
|
host/bluedroid/bta/jv/include \
|
||||||
bluedroid/bta/sdp/include \
|
host/bluedroid/bta/sdp/include \
|
||||||
bluedroid/bta/sys/include \
|
host/bluedroid/bta/sys/include \
|
||||||
bluedroid/btcore/include \
|
host/bluedroid/device/include \
|
||||||
bluedroid/device/include \
|
host/bluedroid/gki/include \
|
||||||
bluedroid/gki/include \
|
host/bluedroid/hci/include \
|
||||||
bluedroid/hci/include \
|
host/bluedroid/utils/include \
|
||||||
bluedroid/osi/include \
|
host/bluedroid/external/sbc/decoder/include \
|
||||||
bluedroid/utils/include \
|
host/bluedroid/external/sbc/encoder/include \
|
||||||
bluedroid/external/sbc/decoder/include \
|
host/bluedroid/external/sbc/plc/include \
|
||||||
bluedroid/external/sbc/encoder/include \
|
host/bluedroid/btc/profile/esp/blufi/include \
|
||||||
bluedroid/external/sbc/plc/include \
|
host/bluedroid/btc/profile/esp/include \
|
||||||
bluedroid/btc/core/include \
|
host/bluedroid/btc/profile/std/gatt/include \
|
||||||
bluedroid/btc/profile/esp/blufi/include \
|
host/bluedroid/btc/profile/std/gap/include \
|
||||||
bluedroid/btc/profile/esp/include \
|
host/bluedroid/btc/profile/std/a2dp/include \
|
||||||
bluedroid/btc/profile/std/gatt/include \
|
host/bluedroid/btc/profile/std/include \
|
||||||
bluedroid/btc/profile/std/gap/include \
|
host/bluedroid/btc/include \
|
||||||
bluedroid/btc/profile/std/a2dp/include \
|
host/bluedroid/btif/include \
|
||||||
bluedroid/btc/profile/std/include \
|
host/bluedroid/stack/btm/include \
|
||||||
bluedroid/btc/include \
|
host/bluedroid/stack/btu/include \
|
||||||
bluedroid/btif/include \
|
host/bluedroid/stack/gap/include \
|
||||||
bluedroid/stack/btm/include \
|
host/bluedroid/stack/gatt/include \
|
||||||
bluedroid/stack/btu/include \
|
host/bluedroid/stack/hcic/include \
|
||||||
bluedroid/stack/gap/include \
|
host/bluedroid/stack/l2cap/include \
|
||||||
bluedroid/stack/gatt/include \
|
host/bluedroid/stack/sdp/include \
|
||||||
bluedroid/stack/hcic/include \
|
host/bluedroid/stack/smp/include \
|
||||||
bluedroid/stack/l2cap/include \
|
host/bluedroid/stack/avct/include \
|
||||||
bluedroid/stack/sdp/include \
|
host/bluedroid/stack/avrc/include \
|
||||||
bluedroid/stack/smp/include \
|
host/bluedroid/stack/avdt/include \
|
||||||
bluedroid/stack/avct/include \
|
host/bluedroid/stack/a2dp/include \
|
||||||
bluedroid/stack/avrc/include \
|
host/bluedroid/stack/rfcomm/include \
|
||||||
bluedroid/stack/avdt/include \
|
host/bluedroid/stack/include \
|
||||||
bluedroid/stack/a2dp/include \
|
host/bluedroid/utils/include \
|
||||||
bluedroid/stack/rfcomm/include \
|
host/bluedroid/common/include
|
||||||
bluedroid/stack/include \
|
|
||||||
bluedroid/utils/include \
|
|
||||||
bluedroid/common/include
|
|
||||||
|
|
||||||
COMPONENT_ADD_INCLUDEDIRS += bluedroid/api/include/api
|
COMPONENT_ADD_INCLUDEDIRS += host/bluedroid/api/include/api \
|
||||||
|
common/osi/include
|
||||||
|
|
||||||
|
COMPONENT_SRCDIRS += host/bluedroid/bta/dm \
|
||||||
|
host/bluedroid/bta/gatt \
|
||||||
|
host/bluedroid/bta/hh \
|
||||||
|
host/bluedroid/bta/sdp \
|
||||||
|
host/bluedroid/bta/av \
|
||||||
|
host/bluedroid/bta/ar \
|
||||||
|
host/bluedroid/bta/sys \
|
||||||
|
host/bluedroid/bta/jv \
|
||||||
|
host/bluedroid/bta/hf_client \
|
||||||
|
host/bluedroid/bta \
|
||||||
|
host/bluedroid/btif \
|
||||||
|
host/bluedroid/device \
|
||||||
|
host/bluedroid/gki \
|
||||||
|
host/bluedroid/hci \
|
||||||
|
host/bluedroid/main \
|
||||||
|
host/bluedroid/external/sbc/decoder/srce \
|
||||||
|
host/bluedroid/external/sbc/encoder/srce \
|
||||||
|
host/bluedroid/external/sbc/plc \
|
||||||
|
host/bluedroid/btc/core \
|
||||||
|
host/bluedroid/btc/profile/esp/blufi \
|
||||||
|
host/bluedroid/btc/profile/std/gap \
|
||||||
|
host/bluedroid/btc/profile/std/gatt \
|
||||||
|
host/bluedroid/btc/profile/std/a2dp \
|
||||||
|
host/bluedroid/btc/profile/std/avrc \
|
||||||
|
host/bluedroid/btc/profile/std/spp \
|
||||||
|
host/bluedroid/btc/profile/std/hf_client \
|
||||||
|
host/bluedroid/btc/profile \
|
||||||
|
host/bluedroid/stack/btm \
|
||||||
|
host/bluedroid/stack/btu \
|
||||||
|
host/bluedroid/stack/gap \
|
||||||
|
host/bluedroid/stack/gatt \
|
||||||
|
host/bluedroid/stack/hcic \
|
||||||
|
host/bluedroid/stack/include \
|
||||||
|
host/bluedroid/stack/l2cap \
|
||||||
|
host/bluedroid/stack/sdp \
|
||||||
|
host/bluedroid/stack/smp \
|
||||||
|
host/bluedroid/stack/avct \
|
||||||
|
host/bluedroid/stack/avrc \
|
||||||
|
host/bluedroid/stack/avdt \
|
||||||
|
host/bluedroid/stack/a2dp \
|
||||||
|
host/bluedroid/stack/rfcomm \
|
||||||
|
host/bluedroid/stack \
|
||||||
|
host/bluedroid/utils \
|
||||||
|
host/bluedroid/api \
|
||||||
|
host/bluedroid
|
||||||
|
|
||||||
COMPONENT_SRCDIRS += bluedroid/bta/dm \
|
|
||||||
bluedroid/bta/gatt \
|
|
||||||
bluedroid/bta/hh \
|
|
||||||
bluedroid/bta/sdp \
|
|
||||||
bluedroid/bta/av \
|
|
||||||
bluedroid/bta/ar \
|
|
||||||
bluedroid/bta/sys \
|
|
||||||
bluedroid/bta/jv \
|
|
||||||
bluedroid/bta/hf_client \
|
|
||||||
bluedroid/bta \
|
|
||||||
bluedroid/btcore \
|
|
||||||
bluedroid/btif \
|
|
||||||
bluedroid/device \
|
|
||||||
bluedroid/gki \
|
|
||||||
bluedroid/hci \
|
|
||||||
bluedroid/main \
|
|
||||||
bluedroid/osi \
|
|
||||||
bluedroid/external/sbc/decoder/srce \
|
|
||||||
bluedroid/external/sbc/encoder/srce \
|
|
||||||
bluedroid/external/sbc/plc \
|
|
||||||
bluedroid/btc/core \
|
|
||||||
bluedroid/btc/profile/esp/blufi \
|
|
||||||
bluedroid/btc/profile/std/gap \
|
|
||||||
bluedroid/btc/profile/std/gatt \
|
|
||||||
bluedroid/btc/profile/std/a2dp \
|
|
||||||
bluedroid/btc/profile/std/avrc \
|
|
||||||
bluedroid/btc/profile/std/spp \
|
|
||||||
bluedroid/btc/profile/std/hf_client \
|
|
||||||
bluedroid/btc/profile \
|
|
||||||
bluedroid/stack/btm \
|
|
||||||
bluedroid/stack/btu \
|
|
||||||
bluedroid/stack/gap \
|
|
||||||
bluedroid/stack/gatt \
|
|
||||||
bluedroid/stack/hcic \
|
|
||||||
bluedroid/stack/include \
|
|
||||||
bluedroid/stack/l2cap \
|
|
||||||
bluedroid/stack/sdp \
|
|
||||||
bluedroid/stack/smp \
|
|
||||||
bluedroid/stack/avct \
|
|
||||||
bluedroid/stack/avrc \
|
|
||||||
bluedroid/stack/avdt \
|
|
||||||
bluedroid/stack/a2dp \
|
|
||||||
bluedroid/stack/rfcomm \
|
|
||||||
bluedroid/stack \
|
|
||||||
bluedroid/utils \
|
|
||||||
bluedroid/api \
|
|
||||||
bluedroid
|
|
||||||
|
|
||||||
ifeq ($(GCC_NOT_5_2_0), 1)
|
ifeq ($(GCC_NOT_5_2_0), 1)
|
||||||
bluedroid/bta/sdp/bta_sdp_act.o: CFLAGS += -Wno-unused-const-variable
|
host/bluedroid/bta/sdp/bta_sdp_act.o: CFLAGS += -Wno-unused-const-variable
|
||||||
bluedroid/btc/core/btc_config.o: CFLAGS += -Wno-unused-const-variable
|
host/bluedroid/btc/core/btc_config.o: CFLAGS += -Wno-unused-const-variable
|
||||||
bluedroid/stack/btm/btm_sec.o: CFLAGS += -Wno-unused-const-variable
|
host/bluedroid/stack/btm/btm_sec.o: CFLAGS += -Wno-unused-const-variable
|
||||||
bluedroid/stack/smp/smp_keys.o: CFLAGS += -Wno-unused-const-variable
|
host/bluedroid/stack/smp/smp_keys.o: CFLAGS += -Wno-unused-const-variable
|
||||||
|
endif
|
||||||
|
|
||||||
|
COMPONENT_PRIV_INCLUDEDIRS += common/btc/include \
|
||||||
|
common/include
|
||||||
|
|
||||||
|
COMPONENT_SRCDIRS += common/osi \
|
||||||
|
common/btc/core
|
||||||
|
|
||||||
|
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/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 \
|
||||||
|
esp_ble_mesh/api/core \
|
||||||
|
esp_ble_mesh/api/models
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifdef CONFIG_BT_NIMBLE_ENABLED
|
||||||
|
COMPONENT_ADD_INCLUDEDIRS += host/nimble/nimble/nimble/include \
|
||||||
|
host/nimble/nimble/nimble/host/include \
|
||||||
|
host/nimble/nimble/porting/nimble/include \
|
||||||
|
host/nimble/nimble/porting/npl/freertos/include \
|
||||||
|
host/nimble/nimble/nimble/host/services/ans/include \
|
||||||
|
host/nimble/nimble/nimble/host/services/bas/include \
|
||||||
|
host/nimble/nimble/nimble/host/services/gap/include \
|
||||||
|
host/nimble/nimble/nimble/host/services/gatt/include \
|
||||||
|
host/nimble/nimble/nimble/host/services/ias/include \
|
||||||
|
host/nimble/nimble/nimble/host/services/lls/include \
|
||||||
|
host/nimble/nimble/nimble/host/services/tps/include \
|
||||||
|
host/nimble/nimble/nimble/host/util/include \
|
||||||
|
host/nimble/nimble/nimble/host/store/ram/include \
|
||||||
|
host/nimble/nimble/nimble/host/store/config/include \
|
||||||
|
host/nimble/nimble/ext/tinycrypt/include \
|
||||||
|
host/nimble/esp-hci/include \
|
||||||
|
host/nimble/port/include
|
||||||
|
|
||||||
|
COMPONENT_SRCDIRS += host/nimble/nimble/nimble/host/src \
|
||||||
|
host/nimble/nimble/porting/nimble/src \
|
||||||
|
host/nimble/nimble/porting/npl/freertos/src \
|
||||||
|
host/nimble/nimble/ext/tinycrypt/src \
|
||||||
|
host/nimble/nimble/nimble/host/services/ans/src \
|
||||||
|
host/nimble/nimble/nimble/host/services/bas/src \
|
||||||
|
host/nimble/nimble/nimble/host/services/gap/src \
|
||||||
|
host/nimble/nimble/nimble/host/services/gatt/src \
|
||||||
|
host/nimble/nimble/nimble/host/services/ias/src \
|
||||||
|
host/nimble/nimble/nimble/host/services/lls/src \
|
||||||
|
host/nimble/nimble/nimble/host/services/tps/src \
|
||||||
|
host/nimble/nimble/nimble/host/util/src \
|
||||||
|
host/nimble/nimble/nimble/host/store/ram/src \
|
||||||
|
host/nimble/nimble/nimble/host/store/config/src \
|
||||||
|
host/nimble/esp-hci/src
|
||||||
|
|
||||||
|
COMPONENT_OBJEXCLUDE += host/nimble/nimble/nimble/host/store/config/src/ble_store_config_conf.o
|
||||||
|
|
||||||
|
ifdef CONFIG_BT_NIMBLE_MESH
|
||||||
|
|
||||||
|
COMPONENT_ADD_INCLUDEDIRS += host/nimble/nimble/nimble/host/mesh/include
|
||||||
|
COMPONENT_SRCDIRS += host/nimble/nimble/nimble/host/mesh/src
|
||||||
|
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -234,10 +234,14 @@ extern uint32_t _data_end_btdm_rom;
|
||||||
|
|
||||||
extern uint32_t _bt_bss_start;
|
extern uint32_t _bt_bss_start;
|
||||||
extern uint32_t _bt_bss_end;
|
extern uint32_t _bt_bss_end;
|
||||||
|
extern uint32_t _nimble_bss_start;
|
||||||
|
extern uint32_t _nimble_bss_end;
|
||||||
extern uint32_t _btdm_bss_start;
|
extern uint32_t _btdm_bss_start;
|
||||||
extern uint32_t _btdm_bss_end;
|
extern uint32_t _btdm_bss_end;
|
||||||
extern uint32_t _bt_data_start;
|
extern uint32_t _bt_data_start;
|
||||||
extern uint32_t _bt_data_end;
|
extern uint32_t _bt_data_end;
|
||||||
|
extern uint32_t _nimble_data_start;
|
||||||
|
extern uint32_t _nimble_data_end;
|
||||||
extern uint32_t _btdm_data_start;
|
extern uint32_t _btdm_data_start;
|
||||||
extern uint32_t _btdm_data_end;
|
extern uint32_t _btdm_data_end;
|
||||||
|
|
||||||
|
@ -1045,6 +1049,19 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
|
||||||
ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end);
|
ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end);
|
||||||
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mem_start = (intptr_t)&_nimble_bss_start;
|
||||||
|
mem_end = (intptr_t)&_nimble_bss_end;
|
||||||
|
if (mem_start != mem_end) {
|
||||||
|
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
|
||||||
|
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||||
|
}
|
||||||
|
mem_start = (intptr_t)&_nimble_data_start;
|
||||||
|
mem_end = (intptr_t)&_nimble_data_end;
|
||||||
|
if (mem_start != mem_end) {
|
||||||
|
ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end);
|
||||||
|
ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
1
components/bt/controller/lib
Submodule
1
components/bt/controller/lib
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit cc2fd1177d97f1a4b9e0d819035ddf52ba77079d
|
803
components/bt/esp_ble_mesh/Kconfig.in
Normal file
803
components/bt/esp_ble_mesh/Kconfig.in
Normal file
|
@ -0,0 +1,803 @@
|
||||||
|
if BLE_MESH
|
||||||
|
|
||||||
|
config BLE_MESH_HCI_5_0
|
||||||
|
bool "Support sending 20ms non-connectable adv packets"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
It is a temporary solution and needs further modifications.
|
||||||
|
|
||||||
|
config BLE_MESH_USE_DUPLICATE_SCAN
|
||||||
|
bool "Support Duplicate Scan in BLE Mesh"
|
||||||
|
select BLE_SCAN_DUPLICATE
|
||||||
|
select BLE_MESH_SCAN_DUPLICATE_EN
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable this option to allow using specific duplicate scan filter
|
||||||
|
in BLE Mesh, and Scan Duplicate Type must be set to 0x02.
|
||||||
|
|
||||||
|
config BLE_MESH_FAST_PROV
|
||||||
|
bool "Enable BLE Mesh Fast Provisioning"
|
||||||
|
select BLE_MESH_NODE
|
||||||
|
select BLE_MESH_PROVISIONER
|
||||||
|
select BLE_MESH_PB_ADV
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable this option to allow BLE Mesh fast provisioning solution to be used.
|
||||||
|
|
||||||
|
config BLE_MESH_NODE
|
||||||
|
bool "Support for BLE Mesh Node"
|
||||||
|
help
|
||||||
|
Enable the device to be provisioned into a node.
|
||||||
|
|
||||||
|
config BLE_MESH_PROVISIONER
|
||||||
|
bool "Support for BLE Mesh Provisioner"
|
||||||
|
help
|
||||||
|
Enable the device to be a provisioner.
|
||||||
|
|
||||||
|
if BLE_MESH_PROVISIONER
|
||||||
|
|
||||||
|
config BLE_MESH_WAIT_FOR_PROV_MAX_DEV_NUM
|
||||||
|
int "Maximum number of unprovisioned devices that can be added to device queue"
|
||||||
|
default 20
|
||||||
|
range 1 100
|
||||||
|
help
|
||||||
|
This option specifies how may unprovisioned devices can be added to device
|
||||||
|
queue for provisioning.
|
||||||
|
|
||||||
|
config BLE_MESH_MAX_STORED_NODES
|
||||||
|
int "Maximum number of nodes whose information can be stored"
|
||||||
|
default 20
|
||||||
|
range 1 1000
|
||||||
|
help
|
||||||
|
This option specifies the maximum number of nodes whose information can be
|
||||||
|
stored by a provisioner in its upper layer.
|
||||||
|
|
||||||
|
config BLE_MESH_MAX_PROV_NODES
|
||||||
|
int "Maximum number of devices that can be provisioned by provisioner"
|
||||||
|
default 20
|
||||||
|
range 1 100
|
||||||
|
help
|
||||||
|
This option specifies how many devices can be provisioned by provisioner.
|
||||||
|
|
||||||
|
if BLE_MESH_PB_ADV
|
||||||
|
config BLE_MESH_PBA_SAME_TIME
|
||||||
|
int "Maximum number of PB-ADV running at the same time by provisioner"
|
||||||
|
default 2
|
||||||
|
range 1 10
|
||||||
|
help
|
||||||
|
This option specifies how many devices can be provisioned at the same
|
||||||
|
time using PB-ADV.
|
||||||
|
endif # BLE_MESH_PB_ADV
|
||||||
|
|
||||||
|
if BLE_MESH_PB_GATT
|
||||||
|
config BLE_MESH_PBG_SAME_TIME
|
||||||
|
int "Maximum number of PB-GATT running at the same time by provisioner"
|
||||||
|
default 1
|
||||||
|
range 1 5
|
||||||
|
help
|
||||||
|
This option specifies how many devices can be provisioned at the same
|
||||||
|
time using PB-GATT.
|
||||||
|
endif # BLE_MESH_PB_GATT
|
||||||
|
|
||||||
|
config BLE_MESH_PROVISIONER_SUBNET_COUNT
|
||||||
|
int "Maximum number of mesh subnets that can be created by provisioner"
|
||||||
|
default 3
|
||||||
|
range 1 4096
|
||||||
|
help
|
||||||
|
This option specifies how many subnets per network a provisioner can create.
|
||||||
|
|
||||||
|
config BLE_MESH_PROVISIONER_APP_KEY_COUNT
|
||||||
|
int "Maximum number of application keys that can be owned by provisioner"
|
||||||
|
default 9
|
||||||
|
range 1 4096
|
||||||
|
help
|
||||||
|
This option specifies how many application keys the provisioner can have.
|
||||||
|
|
||||||
|
endif # BLE_MESH_PROVISIONER
|
||||||
|
|
||||||
|
# Virtual option enabled whenever Generic Provisioning layer is needed
|
||||||
|
config BLE_MESH_PROV
|
||||||
|
bool "BLE Mesh Provisioning support"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable this option to support BLE Mesh Provisioning functionality. For
|
||||||
|
BLE Mesh, this option should be always enabled.
|
||||||
|
|
||||||
|
config BLE_MESH_PB_ADV
|
||||||
|
bool "Provisioning support using the advertising bearer (PB-ADV)"
|
||||||
|
select BLE_MESH_PROV
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable this option to allow the device to be provisioned over the
|
||||||
|
advertising bearer.
|
||||||
|
|
||||||
|
config BLE_MESH_PB_GATT
|
||||||
|
bool "Provisioning support using GATT (PB-GATT)"
|
||||||
|
select BLE_MESH_PROXY
|
||||||
|
select BLE_MESH_PROV
|
||||||
|
help
|
||||||
|
Enable this option to allow the device to be provisioned over GATT.
|
||||||
|
|
||||||
|
# Virtual option enabled whenever any Proxy protocol is needed
|
||||||
|
config BLE_MESH_PROXY
|
||||||
|
bool "BLE Mesh Proxy protocol support"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable this option to support BLE Mesh Proxy protocol used by PB-GATT
|
||||||
|
and other proxy pdu transmission.
|
||||||
|
|
||||||
|
config BLE_MESH_GATT_PROXY
|
||||||
|
bool "BLE Mesh GATT Proxy Service"
|
||||||
|
select BLE_MESH_PROXY
|
||||||
|
help
|
||||||
|
This option enables support for Mesh GATT Proxy Service, i.e. the
|
||||||
|
ability to act as a proxy between a Mesh GATT Client and a Mesh network.
|
||||||
|
|
||||||
|
config BLE_MESH_NODE_ID_TIMEOUT
|
||||||
|
int "Node Identity advertising timeout"
|
||||||
|
depends on BLE_MESH_GATT_PROXY
|
||||||
|
range 1 60
|
||||||
|
default 60
|
||||||
|
help
|
||||||
|
This option determines for how long the local node advertises using
|
||||||
|
Node Identity. The given value is in seconds. The specification limits
|
||||||
|
this to 60 seconds and lists it as the recommended value as well.
|
||||||
|
So leaving the default value is the safest option.
|
||||||
|
|
||||||
|
if BLE_MESH_PROXY
|
||||||
|
|
||||||
|
config BLE_MESH_PROXY_FILTER_SIZE
|
||||||
|
int "Maximum number of filter entries per Proxy Client"
|
||||||
|
default 1
|
||||||
|
default 3 if BLE_MESH_GATT_PROXY
|
||||||
|
range 1 32767
|
||||||
|
help
|
||||||
|
This option specifies how many Proxy Filter entries the local node supports.
|
||||||
|
|
||||||
|
endif # BLE_MESH_PROXY
|
||||||
|
|
||||||
|
config BLE_MESH_NET_BUF_POOL_USAGE
|
||||||
|
bool "BLE Mesh net buffer pool usage tracking"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable BLE Mesh net buffer pool tracking.
|
||||||
|
|
||||||
|
config BLE_MESH_SETTINGS
|
||||||
|
bool "Store BLE Mesh Node configuration persistently"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
When selected, the BLE Mesh stack will take care of storing/restoring the
|
||||||
|
BLE Mesh configuration persistently in flash. Currently this only supports
|
||||||
|
storing BLE Mesh node configuration.
|
||||||
|
|
||||||
|
if BLE_MESH_SETTINGS
|
||||||
|
config BLE_MESH_STORE_TIMEOUT
|
||||||
|
int "Delay (in seconds) before storing anything persistently"
|
||||||
|
range 0 1000000
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
This value defines in seconds how soon any pending changes are actually
|
||||||
|
written into persistent storage (flash) after a change occurs.
|
||||||
|
|
||||||
|
config BLE_MESH_SEQ_STORE_RATE
|
||||||
|
int "How often the sequence number gets updated in storage"
|
||||||
|
range 0 1000000
|
||||||
|
default 128
|
||||||
|
help
|
||||||
|
This value defines how often the local sequence number gets updated in
|
||||||
|
persistent storage (i.e. flash). e.g. a value of 100 means that the
|
||||||
|
sequence number will be stored to flash on every 100th increment.
|
||||||
|
If the node sends messages very frequently a higher value makes more
|
||||||
|
sense, whereas if the node sends infrequently a value as low as 0
|
||||||
|
(update storage for every increment) can make sense. When the stack
|
||||||
|
gets initialized it will add sequence number to the last stored one,
|
||||||
|
so that it starts off with a value that's guaranteed to be larger than
|
||||||
|
the last one used before power off.
|
||||||
|
|
||||||
|
config BLE_MESH_RPL_STORE_TIMEOUT
|
||||||
|
int "Minimum frequency that the RPL gets updated in storage"
|
||||||
|
range 0 1000000
|
||||||
|
default 5
|
||||||
|
help
|
||||||
|
This value defines in seconds how soon the RPL(Replay Protection List)
|
||||||
|
gets written to persistent storage after a change occurs. If the node
|
||||||
|
receives messages frequently, then a large value is recommended. If the
|
||||||
|
node receives messages rarely, then the value can be as low as 0 (which
|
||||||
|
means the PRL is written into the storage immediately).
|
||||||
|
Note that if the node operates in a security-sensitive case, and there is
|
||||||
|
a risk of sudden power-off, then a value of 0 is strongly recommended.
|
||||||
|
Otherwise, a power loss before RPL being written into the storage may
|
||||||
|
introduce message replay attacks and system security will be in a
|
||||||
|
vulnerable state.
|
||||||
|
endif # if BLE_MESH_SETTINGS
|
||||||
|
|
||||||
|
config BLE_MESH_SUBNET_COUNT
|
||||||
|
int "Maximum number of mesh subnets per network"
|
||||||
|
default 3
|
||||||
|
range 1 4096
|
||||||
|
help
|
||||||
|
This option specifies how many subnets a Mesh network can have at the same time.
|
||||||
|
|
||||||
|
config BLE_MESH_APP_KEY_COUNT
|
||||||
|
int "Maximum number of application keys per network"
|
||||||
|
default 3
|
||||||
|
range 1 4096
|
||||||
|
help
|
||||||
|
This option specifies how many application keys the device can store per network.
|
||||||
|
|
||||||
|
config BLE_MESH_MODEL_KEY_COUNT
|
||||||
|
int "Maximum number of application keys per model"
|
||||||
|
default 3
|
||||||
|
range 1 4096
|
||||||
|
help
|
||||||
|
This option specifies the maximum number of application keys to which each model
|
||||||
|
can be bound.
|
||||||
|
|
||||||
|
config BLE_MESH_MODEL_GROUP_COUNT
|
||||||
|
int "Maximum number of group address subscriptions per model"
|
||||||
|
default 3
|
||||||
|
range 1 4096
|
||||||
|
help
|
||||||
|
This option specifies the maximum number of addresses to which each model can
|
||||||
|
be subscribed.
|
||||||
|
|
||||||
|
config BLE_MESH_LABEL_COUNT
|
||||||
|
int "Maximum number of Label UUIDs used for Virtual Addresses"
|
||||||
|
default 3
|
||||||
|
range 0 4096
|
||||||
|
help
|
||||||
|
This option specifies how many Label UUIDs can be stored.
|
||||||
|
|
||||||
|
config BLE_MESH_CRPL
|
||||||
|
int "Maximum capacity of the replay protection list"
|
||||||
|
default 10
|
||||||
|
range 2 65535
|
||||||
|
help
|
||||||
|
This option specifies the maximum capacity of the replay protection list.
|
||||||
|
It is similar to Network message cache size, but has a different purpose.
|
||||||
|
|
||||||
|
config BLE_MESH_MSG_CACHE_SIZE
|
||||||
|
int "Network message cache size"
|
||||||
|
default 10
|
||||||
|
range 2 65535
|
||||||
|
help
|
||||||
|
Number of messages that are cached for the network. This helps prevent
|
||||||
|
unnecessary decryption operations and unnecessary relays. This option
|
||||||
|
is similar to Replay protection list, but has a different purpose.
|
||||||
|
|
||||||
|
config BLE_MESH_ADV_BUF_COUNT
|
||||||
|
int "Number of advertising buffers"
|
||||||
|
default 60
|
||||||
|
range 6 256
|
||||||
|
help
|
||||||
|
Number of advertising buffers available. The transport layer reserves
|
||||||
|
ADV_BUF_COUNT - 3 buffers for outgoing segments. The maximum outgoing
|
||||||
|
SDU size is 12 times this value (out of which 4 or 8 bytes are used
|
||||||
|
for the Transport Layer MIC). For example, 5 segments means the maximum
|
||||||
|
SDU size is 60 bytes, which leaves 56 bytes for application layer data
|
||||||
|
using a 4-byte MIC, or 52 bytes using an 8-byte MIC.
|
||||||
|
|
||||||
|
config BLE_MESH_IVU_DIVIDER
|
||||||
|
int "Divider for IV Update state refresh timer"
|
||||||
|
default 4
|
||||||
|
range 2 96
|
||||||
|
help
|
||||||
|
When the IV Update state enters Normal operation or IV Update
|
||||||
|
in Progress, we need to keep track of how many hours has passed
|
||||||
|
in the state, since the specification requires us to remain in
|
||||||
|
the state at least for 96 hours (Update in Progress has an
|
||||||
|
additional upper limit of 144 hours).
|
||||||
|
|
||||||
|
In order to fulfill the above requirement, even if the node might
|
||||||
|
be powered off once in a while, we need to store persistently
|
||||||
|
how many hours the node has been in the state. This doesn't
|
||||||
|
necessarily need to happen every hour (thanks to the flexible
|
||||||
|
duration range). The exact cadence will depend a lot on the
|
||||||
|
ways that the node will be used and what kind of power source it
|
||||||
|
has.
|
||||||
|
|
||||||
|
Since there is no single optimal answer, this configuration
|
||||||
|
option allows specifying a divider, i.e. how many intervals
|
||||||
|
the 96 hour minimum gets split into. After each interval the
|
||||||
|
duration that the node has been in the current state gets
|
||||||
|
stored to flash. E.g. the default value of 4 means that the
|
||||||
|
state is saved every 24 hours (96 / 4).
|
||||||
|
|
||||||
|
config BLE_MESH_TX_SEG_MSG_COUNT
|
||||||
|
int "Maximum number of simultaneous outgoing segmented messages"
|
||||||
|
default 1
|
||||||
|
range 1 BLE_MESH_ADV_BUF_COUNT
|
||||||
|
help
|
||||||
|
Maximum number of simultaneous outgoing multi-segment and/or reliable messages.
|
||||||
|
|
||||||
|
config BLE_MESH_RX_SEG_MSG_COUNT
|
||||||
|
int "Maximum number of simultaneous incoming segmented messages"
|
||||||
|
default 1
|
||||||
|
range 1 255
|
||||||
|
help
|
||||||
|
Maximum number of simultaneous incoming multi-segment and/or reliable messages.
|
||||||
|
|
||||||
|
config BLE_MESH_RX_SDU_MAX
|
||||||
|
int "Maximum incoming Upper Transport Access PDU length"
|
||||||
|
default 384
|
||||||
|
range 36 384
|
||||||
|
help
|
||||||
|
Maximum incoming Upper Transport Access PDU length. Leave this to the default
|
||||||
|
value, unless you really need to optimize memory usage.
|
||||||
|
|
||||||
|
config BLE_MESH_TX_SEG_MAX
|
||||||
|
int "Maximum number of segments in outgoing messages"
|
||||||
|
default 20
|
||||||
|
range 2 32
|
||||||
|
help
|
||||||
|
Maximum number of segments supported for outgoing messages.
|
||||||
|
This value should typically be fine-tuned based on what
|
||||||
|
models the local node supports, i.e. what's the largest
|
||||||
|
message payload that the node needs to be able to send.
|
||||||
|
This value affects memory and call stack consumption, which
|
||||||
|
is why the default is lower than the maximum that the
|
||||||
|
specification would allow (32 segments).
|
||||||
|
|
||||||
|
The maximum outgoing SDU size is 12 times this number (out of
|
||||||
|
which 4 or 8 bytes is used for the Transport Layer MIC). For
|
||||||
|
example, 5 segments means the maximum SDU size is 60 bytes,
|
||||||
|
which leaves 56 bytes for application layer data using a
|
||||||
|
4-byte MIC and 52 bytes using an 8-byte MIC.
|
||||||
|
|
||||||
|
Be sure to specify a sufficient number of advertising buffers
|
||||||
|
when setting this option to a higher value. There must be at
|
||||||
|
least three more advertising buffers (BLE_MESH_ADV_BUF_COUNT)
|
||||||
|
as there are outgoing segments.
|
||||||
|
|
||||||
|
config BLE_MESH_RELAY
|
||||||
|
bool "Relay support"
|
||||||
|
help
|
||||||
|
Support for acting as a Mesh Relay Node.
|
||||||
|
|
||||||
|
config BLE_MESH_LOW_POWER
|
||||||
|
bool "Support for Low Power features"
|
||||||
|
help
|
||||||
|
Enable this option to operate as a Low Power Node.
|
||||||
|
|
||||||
|
if BLE_MESH_LOW_POWER
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_ESTABLISHMENT
|
||||||
|
bool "Perform Friendship establishment using low power"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Perform the Friendship establishment using low power with the help of a
|
||||||
|
reduced scan duty cycle. The downside of this is that the node may miss
|
||||||
|
out on messages intended for it until it has successfully set up Friendship
|
||||||
|
with a Friend node.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_AUTO
|
||||||
|
bool "Automatically start looking for Friend nodes once provisioned"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Once provisioned, automatically enable LPN functionality and start looking
|
||||||
|
for Friend nodes. If this option is disabled LPN mode needs to be manually
|
||||||
|
enabled by calling bt_mesh_lpn_set(true).
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_AUTO_TIMEOUT
|
||||||
|
int "Time from last received message before going to LPN mode"
|
||||||
|
default 15
|
||||||
|
range 0 3600
|
||||||
|
depends on BLE_MESH_LPN_AUTO
|
||||||
|
help
|
||||||
|
Time in seconds from the last received message, that the node waits out
|
||||||
|
before starting to look for Friend nodes.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_RETRY_TIMEOUT
|
||||||
|
int "Retry timeout for Friend requests"
|
||||||
|
default 8
|
||||||
|
range 1 3600
|
||||||
|
help
|
||||||
|
Time in seconds between Friend Requests, if a previous Friend Request did
|
||||||
|
not yield any acceptable Friend Offers.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_RSSI_FACTOR
|
||||||
|
int "RSSIFactor, used in Friend Offer Delay calculation"
|
||||||
|
range 0 3
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
The contribution of the RSSI, measured by the Friend node, used in Friend
|
||||||
|
Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_RECV_WIN_FACTOR
|
||||||
|
int "ReceiveWindowFactor, used in Friend Offer Delay calculation"
|
||||||
|
range 0 3
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
The contribution of the supported Receive Window used in Friend Offer
|
||||||
|
Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_MIN_QUEUE_SIZE
|
||||||
|
int "Minimum size of the acceptable friend queue (MinQueueSizeLog)"
|
||||||
|
range 1 7
|
||||||
|
default 1
|
||||||
|
help
|
||||||
|
The MinQueueSizeLog field is defined as log_2(N), where N is the minimum
|
||||||
|
number of maximum size Lower Transport PDUs that the Friend node can store
|
||||||
|
in its Friend Queue. As an example, MinQueueSizeLog value 1 gives N = 2,
|
||||||
|
and value 7 gives N = 128.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_RECV_DELAY
|
||||||
|
int "Receive delay requested by the local node"
|
||||||
|
range 10 255
|
||||||
|
default 100
|
||||||
|
help
|
||||||
|
The ReceiveDelay is the time between the Low Power node sending a
|
||||||
|
request and listening for a response. This delay allows the Friend
|
||||||
|
node time to prepare the response. The value is in units of milliseconds.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_POLL_TIMEOUT
|
||||||
|
int "The value of the PollTimeout timer"
|
||||||
|
range 10 244735
|
||||||
|
default 300
|
||||||
|
help
|
||||||
|
PollTimeout timer is used to measure time between two consecutive
|
||||||
|
requests sent by a Low Power node. If no requests are received
|
||||||
|
the Friend node before the PollTimeout timer expires, then the
|
||||||
|
friendship is considered terminated. The value is in units of 100
|
||||||
|
milliseconds, so e.g. a value of 300 means 30 seconds.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_INIT_POLL_TIMEOUT
|
||||||
|
int "The starting value of the PollTimeout timer"
|
||||||
|
range 10 BLE_MESH_LPN_POLL_TIMEOUT
|
||||||
|
default BLE_MESH_LPN_POLL_TIMEOUT
|
||||||
|
help
|
||||||
|
The initial value of the PollTimeout timer when Friendship is to be
|
||||||
|
established for the first time. After this, the timeout gradually
|
||||||
|
grows toward the actual PollTimeout, doubling in value for each iteration.
|
||||||
|
The value is in units of 100 milliseconds, so e.g. a value of 300 means
|
||||||
|
30 seconds.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_SCAN_LATENCY
|
||||||
|
int "Latency for enabling scanning"
|
||||||
|
range 0 50
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
Latency (in milliseconds) is the time it takes to enable scanning. In
|
||||||
|
practice, it means how much time in advance of the Receive Window, the
|
||||||
|
request to enable scanning is made.
|
||||||
|
|
||||||
|
config BLE_MESH_LPN_GROUPS
|
||||||
|
int "Number of groups the LPN can subscribe to"
|
||||||
|
range 0 16384
|
||||||
|
default 8
|
||||||
|
help
|
||||||
|
Maximum number of groups to which the LPN can subscribe.
|
||||||
|
endif # BLE_MESH_LOW_POWER
|
||||||
|
|
||||||
|
config BLE_MESH_FRIEND
|
||||||
|
bool "Support for acting as a Friend Node"
|
||||||
|
help
|
||||||
|
Enable this option to be able to act as a Friend Node.
|
||||||
|
|
||||||
|
if BLE_MESH_FRIEND
|
||||||
|
|
||||||
|
config BLE_MESH_FRIEND_RECV_WIN
|
||||||
|
int "Friend Receive Window"
|
||||||
|
range 1 255
|
||||||
|
default 255
|
||||||
|
help
|
||||||
|
Receive Window in milliseconds supported by the Friend node.
|
||||||
|
|
||||||
|
config BLE_MESH_FRIEND_QUEUE_SIZE
|
||||||
|
int "Minimum number of buffers supported per Friend Queue"
|
||||||
|
range 2 65536
|
||||||
|
default 16
|
||||||
|
help
|
||||||
|
Minimum number of buffers available to be stored for each local Friend Queue.
|
||||||
|
|
||||||
|
config BLE_MESH_FRIEND_SUB_LIST_SIZE
|
||||||
|
int "Friend Subscription List Size"
|
||||||
|
range 0 1023
|
||||||
|
default 3
|
||||||
|
help
|
||||||
|
Size of the Subscription List that can be supported by a Friend node for a
|
||||||
|
Low Power node.
|
||||||
|
|
||||||
|
config BLE_MESH_FRIEND_LPN_COUNT
|
||||||
|
int "Number of supported LPN nodes"
|
||||||
|
range 1 1000
|
||||||
|
default 2
|
||||||
|
help
|
||||||
|
Number of Low Power Nodes with which a Friend can have Friendship simultaneously.
|
||||||
|
|
||||||
|
config BLE_MESH_FRIEND_SEG_RX
|
||||||
|
int "Number of incomplete segment lists per LPN"
|
||||||
|
range 1 1000
|
||||||
|
default 1
|
||||||
|
help
|
||||||
|
Number of incomplete segment lists tracked for each Friends' LPN.
|
||||||
|
In other words, this determines from how many elements can segmented
|
||||||
|
messages destined for the Friend queue be received simultaneously.
|
||||||
|
|
||||||
|
endif # BLE_MESH_FRIEND
|
||||||
|
|
||||||
|
config BLE_MESH_NO_LOG
|
||||||
|
bool "Disable BLE Mesh debug logs (minimize bin size)"
|
||||||
|
depends on BLE_MESH
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Select this to save the BLE Mesh related rodata code size.
|
||||||
|
|
||||||
|
menu "BLE Mesh STACK DEBUG LOG LEVEL"
|
||||||
|
depends on BLE_MESH && !BLE_MESH_NO_LOG
|
||||||
|
|
||||||
|
choice BLE_MESH_STACK_TRACE_LEVEL
|
||||||
|
prompt "BLE_MESH_STACK"
|
||||||
|
default BLE_MESH_TRACE_LEVEL_WARNING
|
||||||
|
depends on BLE_MESH && !BLE_MESH_NO_LOG
|
||||||
|
help
|
||||||
|
Define BLE Mesh trace level for BLE Mesh stack.
|
||||||
|
|
||||||
|
config BLE_MESH_TRACE_LEVEL_NONE
|
||||||
|
bool "NONE"
|
||||||
|
config BLE_MESH_TRACE_LEVEL_ERROR
|
||||||
|
bool "ERROR"
|
||||||
|
config BLE_MESH_TRACE_LEVEL_WARNING
|
||||||
|
bool "WARNING"
|
||||||
|
config BLE_MESH_TRACE_LEVEL_INFO
|
||||||
|
bool "INFO"
|
||||||
|
config BLE_MESH_TRACE_LEVEL_DEBUG
|
||||||
|
bool "DEBUG"
|
||||||
|
config BLE_MESH_TRACE_LEVEL_VERBOSE
|
||||||
|
bool "VERBOSE"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config BLE_MESH_STACK_TRACE_LEVEL
|
||||||
|
int
|
||||||
|
depends on BLE_MESH
|
||||||
|
default 0 if BLE_MESH_TRACE_LEVEL_NONE
|
||||||
|
default 1 if BLE_MESH_TRACE_LEVEL_ERROR
|
||||||
|
default 2 if BLE_MESH_TRACE_LEVEL_WARNING
|
||||||
|
default 3 if BLE_MESH_TRACE_LEVEL_INFO
|
||||||
|
default 4 if BLE_MESH_TRACE_LEVEL_DEBUG
|
||||||
|
default 5 if BLE_MESH_TRACE_LEVEL_VERBOSE
|
||||||
|
default 2
|
||||||
|
|
||||||
|
endmenu #BLE Mesh DEBUG LOG LEVEL
|
||||||
|
|
||||||
|
menu "BLE Mesh NET BUF DEBUG LOG LEVEL"
|
||||||
|
depends on BLE_MESH && !BLE_MESH_NO_LOG
|
||||||
|
|
||||||
|
choice BLE_MESH_NET_BUF_TRACE_LEVEL
|
||||||
|
prompt "BLE_MESH_NET_BUF"
|
||||||
|
default BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING
|
||||||
|
depends on BLE_MESH && !BLE_MESH_NO_LOG
|
||||||
|
help
|
||||||
|
Define BLE Mesh trace level for BLE Mesh net buffer.
|
||||||
|
|
||||||
|
config BLE_MESH_NET_BUF_TRACE_LEVEL_NONE
|
||||||
|
bool "NONE"
|
||||||
|
config BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR
|
||||||
|
bool "ERROR"
|
||||||
|
config BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING
|
||||||
|
bool "WARNING"
|
||||||
|
config BLE_MESH_NET_BUF_TRACE_LEVEL_INFO
|
||||||
|
bool "INFO"
|
||||||
|
config BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG
|
||||||
|
bool "DEBUG"
|
||||||
|
config BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE
|
||||||
|
bool "VERBOSE"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config BLE_MESH_NET_BUF_TRACE_LEVEL
|
||||||
|
int
|
||||||
|
depends on BLE_MESH
|
||||||
|
default 0 if BLE_MESH_NET_BUF_TRACE_LEVEL_NONE
|
||||||
|
default 1 if BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR
|
||||||
|
default 2 if BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING
|
||||||
|
default 3 if BLE_MESH_NET_BUF_TRACE_LEVEL_INFO
|
||||||
|
default 4 if BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG
|
||||||
|
default 5 if BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE
|
||||||
|
default 2
|
||||||
|
|
||||||
|
endmenu #BLE Mesh NET BUF DEBUG LOG LEVEL
|
||||||
|
|
||||||
|
config BLE_MESH_IRQ_LOCK
|
||||||
|
bool "Used the IRQ lock instead of task lock"
|
||||||
|
help
|
||||||
|
To improve the real-time requirements of bt controller in BLE Mesh,
|
||||||
|
task lock is used to replace IRQ lock.
|
||||||
|
|
||||||
|
config BLE_MESH_CLIENT_MSG_TIMEOUT
|
||||||
|
int "Timeout(ms) for client message response"
|
||||||
|
range 100 1200000
|
||||||
|
default 4000
|
||||||
|
help
|
||||||
|
Timeout value used by the node to get response of the acknowledged
|
||||||
|
message which is sent by the client model.
|
||||||
|
|
||||||
|
menu "Support for BLE Mesh Client Models"
|
||||||
|
|
||||||
|
config BLE_MESH_CFG_CLI
|
||||||
|
bool "Configuration Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Configuration client model.
|
||||||
|
|
||||||
|
config BLE_MESH_HEALTH_CLI
|
||||||
|
bool "Health Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Health client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_ONOFF_CLI
|
||||||
|
bool "Generic OnOff Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic OnOff client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_LEVEL_CLI
|
||||||
|
bool "Generic Level Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic Level client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI
|
||||||
|
bool "Generic Default Transition Time Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic Default Transition Time client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_POWER_ONOFF_CLI
|
||||||
|
bool "Generic Power Onoff Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic Power Onoff client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_POWER_LEVEL_CLI
|
||||||
|
bool "Generic Power Level Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic Power Level client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_BATTERY_CLI
|
||||||
|
bool "Generic Battery Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic Battery client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_LOCATION_CLI
|
||||||
|
bool "Generic Location Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic Location client model.
|
||||||
|
|
||||||
|
config BLE_MESH_GENERIC_PROPERTY_CLI
|
||||||
|
bool "Generic Property Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Generic Property client model.
|
||||||
|
|
||||||
|
config BLE_MESH_SENSOR_CLI
|
||||||
|
bool "Sensor Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Sensor client model.
|
||||||
|
|
||||||
|
config BLE_MESH_TIME_CLI
|
||||||
|
bool "Time Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Time client model.
|
||||||
|
|
||||||
|
config BLE_MESH_SCENE_CLI
|
||||||
|
bool "Scene Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Scene client model.
|
||||||
|
|
||||||
|
config BLE_MESH_SCHEDULER_CLI
|
||||||
|
bool "Scheduler Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Scheduler client model.
|
||||||
|
|
||||||
|
config BLE_MESH_LIGHT_LIGHTNESS_CLI
|
||||||
|
bool "Light Lightness Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Light Lightness client model.
|
||||||
|
|
||||||
|
config BLE_MESH_LIGHT_CTL_CLI
|
||||||
|
bool "Light CTL Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Light CTL client model.
|
||||||
|
|
||||||
|
config BLE_MESH_LIGHT_HSL_CLI
|
||||||
|
bool "Light HSL Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Light HSL client model.
|
||||||
|
|
||||||
|
config BLE_MESH_LIGHT_XYL_CLI
|
||||||
|
bool "Light XYL Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Light XYL client model.
|
||||||
|
|
||||||
|
config BLE_MESH_LIGHT_LC_CLI
|
||||||
|
bool "Light LC Client Model"
|
||||||
|
help
|
||||||
|
Enable support for Light LC client model.
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
config BLE_MESH_IV_UPDATE_TEST
|
||||||
|
bool "Test the IV Update Procedure"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option removes the 96 hour limit of the IV Update Procedure and
|
||||||
|
lets the state to be changed at any time.
|
||||||
|
|
||||||
|
menu "BLE Mesh specific test option"
|
||||||
|
|
||||||
|
config BLE_MESH_SELF_TEST
|
||||||
|
bool "Perform BLE Mesh self-tests"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option adds extra self-tests which are run every time BLE Mesh
|
||||||
|
networking is initialized.
|
||||||
|
|
||||||
|
config BLE_MESH_SHELL
|
||||||
|
bool "Enable BLE Mesh shell"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Activate shell module that provides BLE Mesh commands to the console.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG
|
||||||
|
bool "Enable BLE Mesh debug logs"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
if BLE_MESH_DEBUG
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_NET
|
||||||
|
bool "Network layer debug"
|
||||||
|
help
|
||||||
|
Enable Network layer debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_TRANS
|
||||||
|
bool "Transport layer debug"
|
||||||
|
help
|
||||||
|
Enable Transport layer debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_BEACON
|
||||||
|
bool "Beacon debug"
|
||||||
|
help
|
||||||
|
Enable Beacon-related debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_CRYPTO
|
||||||
|
bool "Crypto debug"
|
||||||
|
help
|
||||||
|
Enable cryptographic debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_PROV
|
||||||
|
bool "Provisioning debug"
|
||||||
|
help
|
||||||
|
Enable Provisioning debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_ACCESS
|
||||||
|
bool "Access layer debug"
|
||||||
|
help
|
||||||
|
Enable Access layer debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_MODEL
|
||||||
|
bool "Foundation model debug"
|
||||||
|
help
|
||||||
|
Enable Foundation Models debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_ADV
|
||||||
|
bool "Advertising debug"
|
||||||
|
help
|
||||||
|
Enable advertising debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_LOW_POWER
|
||||||
|
bool "Low Power debug"
|
||||||
|
help
|
||||||
|
Enable Low Power debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_FRIEND
|
||||||
|
bool "Friend debug"
|
||||||
|
help
|
||||||
|
Enable Friend debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
config BLE_MESH_DEBUG_PROXY
|
||||||
|
bool "Proxy debug"
|
||||||
|
depends on BLE_MESH_PROXY
|
||||||
|
help
|
||||||
|
Enable Proxy protocol debug logs for the BLE Mesh functionality.
|
||||||
|
|
||||||
|
endif # BLE_MESH_DEBUG
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif # BLE_MESH
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2017-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 <stdint.h>
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#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"
|
||||||
|
|
||||||
|
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};
|
||||||
|
|
||||||
|
if (prov == NULL || comp == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
// Create a semaphore
|
||||||
|
if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) {
|
||||||
|
LOG_ERROR("%s, Failed to allocate memory for the semaphore", __func__);
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg.mesh_init.prov = prov;
|
||||||
|
arg.mesh_init.comp = comp;
|
||||||
|
/* Transport semaphore pointer to BTC layer, and will give the semaphore in the BTC task */
|
||||||
|
arg.mesh_init.semaphore = semaphore;
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_MESH_INIT;
|
||||||
|
|
||||||
|
if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) != BT_STATUS_SUCCESS) {
|
||||||
|
vSemaphoreDelete(semaphore);
|
||||||
|
LOG_ERROR("%s, BLE Mesh initialise failed", __func__);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take the Semaphore, wait BLE Mesh initialization to finish. */
|
||||||
|
xSemaphoreTake(semaphore, portMAX_DELAY);
|
||||||
|
/* Don't forget to delete the semaphore at the end. */
|
||||||
|
vSemaphoreDelete(semaphore);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2017-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 <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#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"
|
||||||
|
|
||||||
|
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model)
|
||||||
|
{
|
||||||
|
if (model == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return btc_ble_mesh_model_pub_period_get(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t esp_ble_mesh_get_primary_element_address(void)
|
||||||
|
{
|
||||||
|
return btc_ble_mesh_get_primary_addr();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model, uint16_t group_addr)
|
||||||
|
{
|
||||||
|
if (model == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return btc_ble_mesh_model_find_group(model, group_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr)
|
||||||
|
{
|
||||||
|
return btc_ble_mesh_elem_find(element_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t esp_ble_mesh_get_element_count(void)
|
||||||
|
{
|
||||||
|
return btc_ble_mesh_elem_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_ble_mesh_model_t *esp_ble_mesh_find_vendor_model(const esp_ble_mesh_elem_t *element,
|
||||||
|
uint16_t company_id, uint16_t model_id)
|
||||||
|
{
|
||||||
|
if (element == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return btc_ble_mesh_model_find_vnd(element, company_id, model_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(const esp_ble_mesh_elem_t *element, uint16_t model_id)
|
||||||
|
{
|
||||||
|
if (element == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return btc_ble_mesh_model_find(element, model_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void)
|
||||||
|
{
|
||||||
|
return btc_ble_mesh_comp_get();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2017-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 <stdint.h>
|
||||||
|
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#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"
|
||||||
|
|
|
@ -0,0 +1,338 @@
|
||||||
|
// Copyright 2017-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 <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#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"
|
||||||
|
|
||||||
|
#define ESP_BLE_MESH_TX_SDU_MAX ((CONFIG_BLE_MESH_ADV_BUF_COUNT - 3) * 12)
|
||||||
|
|
||||||
|
static esp_err_t ble_mesh_send_msg(esp_ble_mesh_model_t *model,
|
||||||
|
esp_ble_mesh_msg_ctx_t *ctx,
|
||||||
|
uint32_t opcode,
|
||||||
|
btc_ble_mesh_model_act_t act,
|
||||||
|
uint16_t length, uint8_t *data,
|
||||||
|
int32_t msg_timeout, bool need_rsp,
|
||||||
|
esp_ble_mesh_dev_role_t device_role)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_model_args_t arg = {0};
|
||||||
|
uint8_t op_len = 0, mic_len = 0;
|
||||||
|
uint8_t *msg_data = NULL;
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
esp_err_t status;
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (device_role > ROLE_FAST_PROV) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When data is NULL, it is mandatory to set length to 0 to prevent users from misinterpreting parameters. */
|
||||||
|
if (data == NULL) {
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode < 0x100) {
|
||||||
|
op_len = 1;
|
||||||
|
} else if (opcode < 0x10000) {
|
||||||
|
op_len = 2;
|
||||||
|
} else {
|
||||||
|
op_len = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||||
|
if (op_len + length > model->pub->msg->size) {
|
||||||
|
LOG_ERROR("%s, Model publication msg size %d is too small", __func__, model->pub->msg->size);
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||||
|
mic_len = 4;
|
||||||
|
} else {
|
||||||
|
mic_len = ctx->send_rel ? 8 : 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op_len + length + mic_len > MIN(ESP_BLE_MESH_SDU_MAX_LEN, ESP_BLE_MESH_TX_SDU_MAX)) {
|
||||||
|
LOG_ERROR("%s, Data length %d is too large", __func__, length);
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||||
|
bt_mesh_model_msg_init(model->pub->msg, opcode);
|
||||||
|
net_buf_simple_add_mem(model->pub->msg, data, length);
|
||||||
|
} else {
|
||||||
|
msg_data = (uint8_t *)osi_malloc(op_len + length);
|
||||||
|
if (msg_data == NULL) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
esp_ble_mesh_model_msg_opcode_init(msg_data, opcode);
|
||||||
|
memcpy(msg_data + op_len, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_MODEL;
|
||||||
|
msg.act = act;
|
||||||
|
|
||||||
|
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||||
|
arg.model_publish.model = model;
|
||||||
|
arg.model_publish.device_role = device_role;
|
||||||
|
} else {
|
||||||
|
arg.model_send.model = model;
|
||||||
|
arg.model_send.ctx = ctx;
|
||||||
|
arg.model_send.need_rsp = need_rsp;
|
||||||
|
arg.model_send.opcode = opcode;
|
||||||
|
arg.model_send.length = op_len + length;
|
||||||
|
arg.model_send.data = msg_data;
|
||||||
|
arg.model_send.device_role = device_role;
|
||||||
|
arg.model_send.msg_timeout = msg_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_model_args_t), btc_ble_mesh_prov_arg_deep_copy)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
|
||||||
|
osi_free(msg_data);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return (btc_profile_cb_set(BTC_PID_MODEL, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_model_msg_opcode_init(uint8_t *data, uint32_t opcode)
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
|
||||||
|
if (data == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode < 0x100) {
|
||||||
|
/* 1-byte OpCode */
|
||||||
|
data[0] = opcode & 0xff;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode < 0x10000) {
|
||||||
|
/* 2-byte OpCode, big endian */
|
||||||
|
val = sys_cpu_to_be16 (opcode);
|
||||||
|
memcpy(data, &val, 2);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3-byte OpCode, note that little endian for the least 2 bytes(Company ID) of opcode */
|
||||||
|
data[0] = (opcode >> 16) & 0xff;
|
||||||
|
val = sys_cpu_to_le16(opcode & 0xffff);
|
||||||
|
memcpy(&data[1], &val, 2);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model)
|
||||||
|
{
|
||||||
|
if (model == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
return btc_ble_mesh_client_init(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model,
|
||||||
|
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
|
||||||
|
uint16_t length, uint8_t *data)
|
||||||
|
{
|
||||||
|
if (!model || !ctx) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
return ble_mesh_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
|
||||||
|
length, data, 0, false, ROLE_NODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model,
|
||||||
|
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
|
||||||
|
uint16_t length, uint8_t *data, int32_t msg_timeout,
|
||||||
|
bool need_rsp, esp_ble_mesh_dev_role_t device_role)
|
||||||
|
{
|
||||||
|
if (!model || !ctx) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
return ble_mesh_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND,
|
||||||
|
length, data, msg_timeout, need_rsp, device_role);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcode,
|
||||||
|
uint16_t length, uint8_t *data,
|
||||||
|
esp_ble_mesh_dev_role_t device_role)
|
||||||
|
{
|
||||||
|
if (!model || !model->pub || !model->pub->msg) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
return ble_mesh_send_msg(model, NULL, opcode, BTC_BLE_MESH_ACT_MODEL_PUBLISH,
|
||||||
|
length, data, 0, false, device_role);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_node_local_reset(void)
|
||||||
|
{
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_NODE_RESET;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_PROVISIONER)
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_set_node_name(int index, const char *name)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_NODE_NAME;
|
||||||
|
|
||||||
|
arg.set_node_name.index = index;
|
||||||
|
memset(arg.set_node_name.name, 0, sizeof(arg.set_node_name.name));
|
||||||
|
memcpy(arg.set_node_name.name, name, strlen(name));
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *esp_ble_mesh_provisioner_get_node_name(int index)
|
||||||
|
{
|
||||||
|
return bt_mesh_provisioner_get_node_name(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int esp_ble_mesh_provisioner_get_node_index(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bt_mesh_provisioner_get_node_index(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16],
|
||||||
|
uint16_t net_idx, uint16_t app_idx)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_LOCAL_APP_KEY;
|
||||||
|
|
||||||
|
arg.add_local_app_key.net_idx = net_idx;
|
||||||
|
arg.add_local_app_key.app_idx = app_idx;
|
||||||
|
if (app_key) {
|
||||||
|
memcpy(arg.add_local_app_key.app_key, app_key, 16);
|
||||||
|
} else {
|
||||||
|
bzero(arg.add_local_app_key.app_key, 16);
|
||||||
|
}
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *esp_ble_mesh_provisioner_get_local_app_key(uint16_t net_idx, uint16_t app_idx)
|
||||||
|
{
|
||||||
|
return bt_mesh_provisioner_local_app_key_get(net_idx, app_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_bind_app_key_to_local_model(uint16_t element_addr, uint16_t app_idx,
|
||||||
|
uint16_t model_id, uint16_t company_id)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr)) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_BIND_LOCAL_MOD_APP;
|
||||||
|
|
||||||
|
arg.local_mod_app_bind.elem_addr = element_addr;
|
||||||
|
arg.local_mod_app_bind.app_idx = app_idx;
|
||||||
|
arg.local_mod_app_bind.model_id = model_id;
|
||||||
|
arg.local_mod_app_bind.cid = company_id;
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (net_idx == ESP_BLE_MESH_KEY_PRIMARY) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY;
|
||||||
|
|
||||||
|
arg.add_local_net_key.net_idx = net_idx;
|
||||||
|
if (net_key) {
|
||||||
|
memcpy(arg.add_local_net_key.net_key, net_key, 16);
|
||||||
|
} else {
|
||||||
|
bzero(arg.add_local_net_key.net_key, 16);
|
||||||
|
}
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx)
|
||||||
|
{
|
||||||
|
return bt_mesh_provisioner_local_net_key_get(net_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BLE_MESH_PROVISIONER */
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_FAST_PROV)
|
||||||
|
const uint8_t *esp_ble_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx)
|
||||||
|
{
|
||||||
|
return bt_mesh_get_fast_prov_app_key(net_idx, app_idx);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_FAST_PROV */
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
// Copyright 2017-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 <stdint.h>
|
||||||
|
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#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"
|
||||||
|
|
||||||
|
#define MAX_PROV_LINK_IDX (CONFIG_BLE_MESH_PBA_SAME_TIME + CONFIG_BLE_MESH_PBG_SAME_TIME)
|
||||||
|
#define MAX_OOB_INPUT_NUM 0x5F5E0FF /* Decimal: 99999999 */
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb_t callback)
|
||||||
|
{
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
return (btc_profile_cb_set(BTC_PID_PROV, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool esp_ble_mesh_node_is_provisioned(void)
|
||||||
|
{
|
||||||
|
return bt_mesh_is_provisioned();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROV_ENABLE;
|
||||||
|
arg.node_prov_enable.bearers = bearers;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROV_DISABLE;
|
||||||
|
arg.node_prov_disable.bearers = bearers;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_node_set_oob_pub_key(uint8_t pub_key_x[32], uint8_t pub_key_y[32],
|
||||||
|
uint8_t private_key[32])
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (!pub_key_x || !pub_key_y || !private_key) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_SET_OOB_PUB_KEY;
|
||||||
|
|
||||||
|
memcpy(arg.set_oob_pub_key.pub_key_x, pub_key_x, 32);
|
||||||
|
memcpy(arg.set_oob_pub_key.pub_key_y, pub_key_y, 32);
|
||||||
|
memcpy(arg.set_oob_pub_key.private_key, private_key, 32);
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_node_input_number(uint32_t number)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (number > MAX_OOB_INPUT_NUM) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_INPUT_NUMBER;
|
||||||
|
arg.input_number.number = number;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_node_input_string(const char *string)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (!string) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_INPUT_STRING;
|
||||||
|
memset(arg.input_string.string, 0, sizeof(arg.input_string.string));
|
||||||
|
strncpy(arg.input_string.string, string, strlen(string));
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (!name || strlen(name) > ESP_BLE_MESH_DEVICE_NAME_MAX_LEN) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_SET_DEVICE_NAME;
|
||||||
|
|
||||||
|
memset(arg.set_device_name.name, 0, sizeof(arg.set_device_name.name));
|
||||||
|
memcpy(arg.set_device_name.name, name, strlen(name));
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_PROVISIONER)
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_read_oob_pub_key(uint8_t link_idx, uint8_t pub_key_x[32],
|
||||||
|
uint8_t pub_key_y[32])
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (!pub_key_x || !pub_key_y || link_idx >= MAX_PROV_LINK_IDX) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_READ_OOB_PUB_KEY;
|
||||||
|
|
||||||
|
arg.provisioner_read_oob_pub_key.link_idx = link_idx;
|
||||||
|
memcpy(arg.provisioner_read_oob_pub_key.pub_key_x, pub_key_x, 32);
|
||||||
|
memcpy(arg.provisioner_read_oob_pub_key.pub_key_y, pub_key_y, 32);
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link_idx)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (!string || link_idx >= MAX_PROV_LINK_IDX) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_INPUT_STR;
|
||||||
|
|
||||||
|
memset(arg.provisioner_input_str.string, 0, sizeof(arg.provisioner_input_str.string));
|
||||||
|
strncpy(arg.provisioner_input_str.string, string, strlen(string));
|
||||||
|
arg.provisioner_input_str.link_idx = link_idx;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_input_number(uint32_t number, uint8_t link_idx)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (number > MAX_OOB_INPUT_NUM || link_idx >= MAX_PROV_LINK_IDX) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_INPUT_NUM;
|
||||||
|
|
||||||
|
arg.provisioner_input_num.number = number;
|
||||||
|
arg.provisioner_input_num.link_idx = link_idx;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_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);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ENABLE;
|
||||||
|
|
||||||
|
arg.provisioner_enable.bearers = bearers;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_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);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DISABLE;
|
||||||
|
|
||||||
|
arg.provisioner_disable.bearers = bearers;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t *add_dev,
|
||||||
|
esp_ble_mesh_dev_add_flag_t flags)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (add_dev == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DEV_ADD;
|
||||||
|
|
||||||
|
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.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)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_dev)
|
||||||
|
{
|
||||||
|
uint8_t val = DEL_DEV_ADDR_FLAG | DEL_DEV_UUID_FLAG;
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (del_dev == NULL || (__builtin_popcount(del_dev->flag & val) != 1)) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DEV_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));
|
||||||
|
} else if (del_dev->flag & DEL_DEV_UUID_FLAG) {
|
||||||
|
memcpy(arg.provisioner_dev_del.del_dev.uuid, del_dev->uuid, 16);
|
||||||
|
}
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, uint8_t match_len,
|
||||||
|
uint8_t offset, bool prov_after_match)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_DEV_UUID_MATCH;
|
||||||
|
|
||||||
|
if (match_len && match_val) {
|
||||||
|
memcpy(arg.set_dev_uuid_match.match_val, match_val, match_len);
|
||||||
|
}
|
||||||
|
arg.set_dev_uuid_match.match_len = match_len;
|
||||||
|
arg.set_dev_uuid_match.offset = offset;
|
||||||
|
arg.set_dev_uuid_match.prov_after_match = prov_after_match;
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_info_t *prov_data_info)
|
||||||
|
{
|
||||||
|
uint8_t val = PROV_DATA_NET_IDX_FLAG | PROV_DATA_FLAGS_FLAG | PROV_DATA_IV_INDEX_FLAG;
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (prov_data_info == NULL || (__builtin_popcount(prov_data_info->flag & val) != 1)) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_PROV_DATA_INFO;
|
||||||
|
|
||||||
|
arg.set_prov_data_info.prov_data.flag = prov_data_info->flag;
|
||||||
|
if (prov_data_info->flag & PROV_DATA_NET_IDX_FLAG) {
|
||||||
|
arg.set_prov_data_info.prov_data.net_idx = prov_data_info->net_idx;
|
||||||
|
} else if (prov_data_info->flag & PROV_DATA_FLAGS_FLAG) {
|
||||||
|
arg.set_prov_data_info.prov_data.flags = prov_data_info->flags;
|
||||||
|
} else if (prov_data_info->flag & PROV_DATA_IV_INDEX_FLAG) {
|
||||||
|
arg.set_prov_data_info.prov_data.iv_index = prov_data_info->iv_index;
|
||||||
|
}
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BLE_MESH_PROVISIONER */
|
||||||
|
|
||||||
|
/* The following APIs are for fast provisioning */
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_FAST_PROV)
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_prov_info)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (fast_prov_info == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO;
|
||||||
|
|
||||||
|
arg.set_fast_prov_info.unicast_min = fast_prov_info->unicast_min;
|
||||||
|
arg.set_fast_prov_info.unicast_max = fast_prov_info->unicast_max;
|
||||||
|
arg.set_fast_prov_info.net_idx = fast_prov_info->net_idx;
|
||||||
|
arg.set_fast_prov_info.flags = fast_prov_info->flags;
|
||||||
|
arg.set_fast_prov_info.iv_index = fast_prov_info->iv_index;
|
||||||
|
arg.set_fast_prov_info.offset = fast_prov_info->offset;
|
||||||
|
arg.set_fast_prov_info.match_len = fast_prov_info->match_len;
|
||||||
|
if (fast_prov_info->match_len && fast_prov_info->match_val) {
|
||||||
|
memcpy(arg.set_fast_prov_info.match_val, fast_prov_info->match_val, fast_prov_info->match_len);
|
||||||
|
}
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_set_fast_prov_action(esp_ble_mesh_fast_prov_action_t action)
|
||||||
|
{
|
||||||
|
btc_ble_mesh_prov_args_t arg = {0};
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
if (action >= FAST_PROV_ACT_MAX) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION;
|
||||||
|
|
||||||
|
arg.set_fast_prov_action.action = action;
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BLE_MESH_FAST_PROV */
|
||||||
|
|
65
components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c
Normal file
65
components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright 2017-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 <stdint.h>
|
||||||
|
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#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"
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_proxy_identity_enable(void)
|
||||||
|
{
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROXY_IDENTITY_ENABLE;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_proxy_gatt_enable(void)
|
||||||
|
{
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROXY_GATT_ENABLE;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_mesh_proxy_gatt_disable(void)
|
||||||
|
{
|
||||||
|
btc_msg_t msg = {0};
|
||||||
|
|
||||||
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_PROV;
|
||||||
|
msg.act = BTC_BLE_MESH_ACT_PROXY_GATT_DISABLE;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2017-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.
|
||||||
|
|
||||||
|
#ifndef _ESP_BLE_MESH_COMMON_API_H_
|
||||||
|
#define _ESP_BLE_MESH_COMMON_API_H_
|
||||||
|
|
||||||
|
#include "esp_ble_mesh_defs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize BLE Mesh module.
|
||||||
|
* This API initializes provisioning capabilities and composition data information.
|
||||||
|
*
|
||||||
|
* @note After calling this API, the device needs to call esp_ble_mesh_prov_enable()
|
||||||
|
* to enable provisioning functionality again.
|
||||||
|
*
|
||||||
|
* @param[in] prov: Pointer to the device provisioning capabilities. This pointer must
|
||||||
|
* remain valid during the lifetime of the BLE Mesh device.
|
||||||
|
* @param[in] comp: Pointer to the device composition data information. This pointer
|
||||||
|
* must remain valid during the lifetime of the BLE Mesh device.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp);
|
||||||
|
|
||||||
|
#endif /* _ESP_BLE_MESH_COMMON_API_H_ */
|
|
@ -0,0 +1,107 @@
|
||||||
|
// Copyright 2017-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.
|
||||||
|
|
||||||
|
#ifndef _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
|
||||||
|
#define _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
|
||||||
|
|
||||||
|
#include "esp_ble_mesh_defs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the model publish period, the unit is ms.
|
||||||
|
*
|
||||||
|
* @param[in] model: Model instance pointer.
|
||||||
|
*
|
||||||
|
* @return Publish period value on success, 0 or (negative) error code from errno.h on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the address of the primary element.
|
||||||
|
*
|
||||||
|
* @return Address of the primary element on success, or
|
||||||
|
* ESP_BLE_MESH_ADDR_UNASSIGNED on failure which means the device has not been provisioned.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t esp_ble_mesh_get_primary_element_address(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the model has subscribed to the given group address.
|
||||||
|
* Note: E.g., once a status message is received and the destination address
|
||||||
|
* is a group address, the model uses this API to check if it is successfully subscribed
|
||||||
|
* to the given group address.
|
||||||
|
*
|
||||||
|
* @param[in] model: Pointer to the model.
|
||||||
|
* @param[in] group_addr: Group address.
|
||||||
|
*
|
||||||
|
* @return Pointer to the group address within the Subscription List of the model on success, or
|
||||||
|
* NULL on failure which means the model has not subscribed to the given group address.
|
||||||
|
* Note: With the pointer to the group address returned, you can reset the group address
|
||||||
|
* to 0x0000 in order to unsubscribe the model from the group.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model, uint16_t group_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the BLE Mesh element pointer via the element address.
|
||||||
|
*
|
||||||
|
* @param[in] element_addr: Element address.
|
||||||
|
*
|
||||||
|
* @return Pointer to the element on success, or NULL on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the number of elements that have been registered.
|
||||||
|
*
|
||||||
|
* @return Number of elements.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t esp_ble_mesh_get_element_count(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the Vendor specific model with the given element,
|
||||||
|
* the company ID and the Vendor Model ID.
|
||||||
|
*
|
||||||
|
* @param[in] element: Element to which the model belongs.
|
||||||
|
* @param[in] company_id: A 16-bit company identifier assigned by the Bluetooth SIG.
|
||||||
|
* @param[in] model_id: A 16-bit vendor-assigned model identifier.
|
||||||
|
*
|
||||||
|
* @return Pointer to the Vendor Model on success, or NULL on failure which means the Vendor Model is not found.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_ble_mesh_model_t *esp_ble_mesh_find_vendor_model(const esp_ble_mesh_elem_t *element,
|
||||||
|
uint16_t company_id, uint16_t model_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the SIG model with the given element and Model id.
|
||||||
|
*
|
||||||
|
* @param[in] element: Element to which the model belongs.
|
||||||
|
* @param[in] model_id: SIG model identifier.
|
||||||
|
*
|
||||||
|
* @return Pointer to the SIG Model on success, or NULL on failure which means the SIG Model is not found.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(const esp_ble_mesh_elem_t *element, uint16_t model_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the Composition data which has been registered.
|
||||||
|
*
|
||||||
|
* @return Pointer to the Composition data on success, or NULL on failure which means the Composition data is not initialized.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void);
|
||||||
|
|
||||||
|
#endif /* _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_ */
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2017-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.
|
||||||
|
|
||||||
|
#ifndef _ESP_BLE_MESH_LOW_POWER_API_H_
|
||||||
|
#define _ESP_BLE_MESH_LOW_POWER_API_H_
|
||||||
|
|
||||||
|
#include "esp_ble_mesh_defs.h"
|
||||||
|
|
||||||
|
#endif /* _ESP_BLE_MESH_LOW_POWER_API_H_ */
|
|
@ -0,0 +1,265 @@
|
||||||
|
// Copyright 2017-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.
|
||||||
|
|
||||||
|
#ifndef _ESP_BLE_MESH_NETWORKING_API_H_
|
||||||
|
#define _ESP_BLE_MESH_NETWORKING_API_H_
|
||||||
|
|
||||||
|
#include "esp_ble_mesh_defs.h"
|
||||||
|
|
||||||
|
/** @brief: event, event code of user-defined model events; param, parameters of user-defined model events */
|
||||||
|
typedef void (* esp_ble_mesh_model_cb_t)(esp_ble_mesh_model_cb_event_t event,
|
||||||
|
esp_ble_mesh_model_cb_param_t *param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register BLE Mesh callback for user-defined models' operations.
|
||||||
|
* This callback can report the following events generated for the user-defined models:
|
||||||
|
* - Call back the messages received by user-defined client and server models to the
|
||||||
|
* application layer;
|
||||||
|
* - If users call esp_ble_mesh_server/client_model_send, this callback notifies the
|
||||||
|
* application layer of the send_complete event;
|
||||||
|
* - If user-defined client model sends a message that requires response, and the response
|
||||||
|
* message is received after the timer expires, the response message will be reported
|
||||||
|
* to the application layer as published by a peer device;
|
||||||
|
* - If the user-defined client model fails to receive the response message during a specified
|
||||||
|
* period of time, a timeout event will be reported to the application layer.
|
||||||
|
*
|
||||||
|
* @note The client models (i.e. Config Client model, Health Client model, Generic
|
||||||
|
* Client models, Sensor Client model, Scene Client model and Lighting Client models)
|
||||||
|
* that have been realized internally have their specific register functions.
|
||||||
|
* For example, esp_ble_mesh_register_config_client_callback is the register
|
||||||
|
* function for Config Client Model.
|
||||||
|
*
|
||||||
|
* @param[in] callback: Pointer to the callback function.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb_t callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add the message opcode to the beginning of the model message
|
||||||
|
* before sending or publishing the model message.
|
||||||
|
*
|
||||||
|
* @note This API is only used to set the opcode of the message.
|
||||||
|
*
|
||||||
|
* @param[in] data: Pointer to the message data.
|
||||||
|
* @param[in] opcode: The message opcode.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_model_msg_opcode_init(uint8_t *data, uint32_t opcode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the user-defined client model. All user-defined client models
|
||||||
|
* shall call this function to initialize the client model internal data.
|
||||||
|
* Node: Before calling this API, the op_pair_size and op_pair variabled within
|
||||||
|
* the user_data(defined using esp_ble_mesh_client_t_) of the client model
|
||||||
|
* need to be initialized.
|
||||||
|
*
|
||||||
|
* @param[in] model: BLE Mesh Client model to which the message belongs.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send server model messages(such as server model status messages).
|
||||||
|
*
|
||||||
|
* @param[in] model: BLE Mesh Server Model to which the message belongs.
|
||||||
|
* @param[in] ctx: Message context, includes keys, TTL, etc.
|
||||||
|
* @param[in] opcode: Message opcode.
|
||||||
|
* @param[in] length: Message length (exclude the message opcode).
|
||||||
|
* @param[in] data: Parameters of Access Payload (exclude the message opcode) to be sent.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model,
|
||||||
|
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
|
||||||
|
uint16_t length, uint8_t *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send client model message (such as model get, set, etc).
|
||||||
|
*
|
||||||
|
* @param[in] model: BLE Mesh Client Model to which the message belongs.
|
||||||
|
* @param[in] ctx: Message context, includes keys, TTL, etc.
|
||||||
|
* @param[in] opcode: Message opcode.
|
||||||
|
* @param[in] length: Message length (exclude the message opcode).
|
||||||
|
* @param[in] data: Parameters of the Access Payload (exclude the message opcode) to be sent.
|
||||||
|
* @param[in] msg_timeout: Time to get response to the message (in milliseconds).
|
||||||
|
* @param[in] need_rsp: TRUE if the opcode requires the peer device to reply, FALSE otherwise.
|
||||||
|
* @param[in] device_role: Role of the device (Node/Provisioner) that sends the message.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model,
|
||||||
|
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
|
||||||
|
uint16_t length, uint8_t *data, int32_t msg_timeout,
|
||||||
|
bool need_rsp, esp_ble_mesh_dev_role_t device_role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a model publication message.
|
||||||
|
*
|
||||||
|
* @note Before calling this function, the user needs to ensure that the model
|
||||||
|
* publication message (@ref esp_ble_mesh_model_pub_t.msg) contains a valid
|
||||||
|
* message to be sent. And if users want to update the publishing message,
|
||||||
|
* this API should be called in ESP_BLE_MESH_MODEL_PUBLISH_UPDATE_EVT
|
||||||
|
* with the message updated.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param[in] model: Mesh (client) Model publishing the message.
|
||||||
|
* @param[in] opcode: Message opcode.
|
||||||
|
* @param[in] length: Message length (exclude the message opcode).
|
||||||
|
* @param[in] data: Parameters of the Access Payload (exclude the message opcode) to be sent.
|
||||||
|
* @param[in] device_role: Role of the device (node/provisioner) publishing the message of the type esp_ble_mesh_dev_role_t.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcode,
|
||||||
|
uint16_t length, uint8_t *data,
|
||||||
|
esp_ble_mesh_dev_role_t device_role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the provisioning procedure of the local BLE Mesh node.
|
||||||
|
*
|
||||||
|
* @note All provisioning information in this node will be deleted and the node
|
||||||
|
* needs to be reprovisioned. The API function esp_ble_mesh_node_prov_enable()
|
||||||
|
* needs to be called to start a new provisioning procedure.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_node_local_reset(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called to set the node (provisioned device) name.
|
||||||
|
*
|
||||||
|
* @param[in] index: Index of the node in the node queue.
|
||||||
|
* @param[in] name: Name (end by '\0') to be set for the node.
|
||||||
|
*
|
||||||
|
* @note index is obtained from the parameters of ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_set_node_name(int index, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called to get the node (provisioned device) name.
|
||||||
|
*
|
||||||
|
* @param[in] index: Index of the node in the node queue.
|
||||||
|
*
|
||||||
|
* @note index is obtained from the parameters of ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT.
|
||||||
|
*
|
||||||
|
* @return Node name on success, or NULL on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *esp_ble_mesh_provisioner_get_node_name(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called to get the node (provisioned device) index.
|
||||||
|
*
|
||||||
|
* @param[in] name: Name of the node (end by '\0').
|
||||||
|
*
|
||||||
|
* @return Node index on success, or (negative) error code from errno.h on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int esp_ble_mesh_provisioner_get_node_index(const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called to set the app key for the local BLE Mesh stack.
|
||||||
|
*
|
||||||
|
* @param[in] app_key: The app key to be set for the local BLE Mesh stack.
|
||||||
|
* @param[in] net_idx: The network key index.
|
||||||
|
* @param[in] app_idx: The app key index.
|
||||||
|
*
|
||||||
|
* @note app_key: If set to NULL, app_key will be generated internally.
|
||||||
|
* net_idx: Should be an existing one.
|
||||||
|
* app_idx: If it is going to be generated internally, it should be set to
|
||||||
|
* 0xFFFF, and the new app_idx will be reported via an event.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called by Provisioner to get the local app key value.
|
||||||
|
*
|
||||||
|
* @param[in] net_idx: Network key index.
|
||||||
|
* @param[in] app_idx: Application key index.
|
||||||
|
*
|
||||||
|
* @return App key on success, or NULL on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const uint8_t *esp_ble_mesh_provisioner_get_local_app_key(uint16_t net_idx, uint16_t app_idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called by Provisioner to bind own model with proper app key.
|
||||||
|
*
|
||||||
|
* @param[in] element_addr: Provisioner local element address
|
||||||
|
* @param[in] app_idx: Provisioner local appkey index
|
||||||
|
* @param[in] model_id: Provisioner local model id
|
||||||
|
* @param[in] company_id: Provisioner local company id
|
||||||
|
*
|
||||||
|
* @note company_id: If going to bind app_key with local vendor model, company_id
|
||||||
|
* should be set to 0xFFFF.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_bind_app_key_to_local_model(uint16_t element_addr, uint16_t app_idx,
|
||||||
|
uint16_t model_id, uint16_t company_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called by Provisioner to add local network key.
|
||||||
|
*
|
||||||
|
* @param[in] net_key: The network key to be added to the Provisioner local BLE Mesh stack.
|
||||||
|
* @param[in] net_idx: The network key index.
|
||||||
|
*
|
||||||
|
* @note net_key: If set to NULL, net_key will be generated internally.
|
||||||
|
* net_idx: If it is going to be generated internally, it should be set to
|
||||||
|
* 0xFFFF, and the new net_idx will be reported via an event.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success or error code otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_mesh_provisioner_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called by Provisioner to get the local network key value.
|
||||||
|
*
|
||||||
|
* @param[in] net_idx: Network key index.
|
||||||
|
*
|
||||||
|
* @return Network key on success, or NULL on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called to get fast provisioning application key.
|
||||||
|
*
|
||||||
|
* @param[in] net_idx: Network key index.
|
||||||
|
* @param[in] app_idx: Application key index.
|
||||||
|
*
|
||||||
|
* @return Application key on success, or NULL on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const uint8_t *esp_ble_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx);
|
||||||
|
|
||||||
|
#endif /* _ESP_BLE_MESH_NETWORKING_API_H_ */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue