mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-09 23:32:44 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f21b4c2381 | ||
|
|
d76364c2a4 | ||
|
|
d878a786fd | ||
|
|
42abb32a86 | ||
|
|
9172ed9727 | ||
|
|
8a64cc15a5 | ||
|
|
94d2e8eff0 | ||
|
|
f04d9ac50e | ||
|
|
67b258d55a | ||
|
|
865f0f4f0e | ||
|
|
37b8f8f3e6 | ||
|
|
b3afa26a60 | ||
|
|
4a59e94b4e | ||
|
|
06004072cb | ||
|
|
734c1725fb | ||
|
|
746485f640 | ||
|
|
a6b216ac22 | ||
|
|
787bb39765 | ||
|
|
6bfcd4b41c | ||
|
|
406c7f3ec6 | ||
|
|
4709069e13 | ||
|
|
0cc53db591 | ||
|
|
4c69bf826f | ||
|
|
23dc9a9f47 | ||
|
|
920efaabbd | ||
|
|
96bdca38a1 | ||
|
|
75f2b8d4a1 | ||
|
|
09337109b7 | ||
|
|
19fef9f5ac | ||
|
|
c253f82bec | ||
|
|
7adc84467f | ||
|
|
f95a5f5231 | ||
|
|
5ff01bf027 | ||
|
|
4d1872c66d | ||
|
|
350ae64dad | ||
|
|
5407e36e4a | ||
|
|
557b7bae2e | ||
|
|
ee2c7247fb | ||
|
|
f4d881ff59 | ||
|
|
f4ebf33964 | ||
|
|
ab5c1b0e3b | ||
|
|
d4d8b09ced | ||
|
|
018cd86846 | ||
|
|
8e1ebcad18 | ||
|
|
883eca3119 | ||
|
|
d5086b36ac | ||
|
|
c81cf3bdf6 | ||
|
|
23b76aaf92 | ||
|
|
97a3b51d11 | ||
|
|
3d5c2efb82 | ||
|
|
93f0ecfe2e | ||
|
|
0566fb4260 | ||
|
|
25d269dab6 | ||
|
|
6e160e2e47 | ||
|
|
160df75e64 | ||
|
|
c4cabac522 | ||
|
|
76966b3d8d | ||
|
|
9f62db74d3 | ||
|
|
1b1a646891 | ||
|
|
9fd27046c5 | ||
|
|
f3aa1e81a9 | ||
|
|
0772e12f58 | ||
|
|
06e5eeb494 | ||
|
|
ca6cfada99 | ||
|
|
b01490fc95 | ||
|
|
950b000be6 | ||
|
|
67539296dd | ||
|
|
3d73884ae8 | ||
|
|
138ef35683 | ||
|
|
f207bec03c | ||
|
|
bb80291429 | ||
|
|
311158878f | ||
|
|
dc2415aedf | ||
|
|
9b69fa150f | ||
|
|
73115c34c9 | ||
|
|
512a1d8028 | ||
|
|
c4347a682d | ||
|
|
7c517deb35 | ||
|
|
7a20f71935 | ||
|
|
37a711d829 | ||
|
|
a80c9ef7ab | ||
|
|
91bb47ec68 | ||
|
|
31700298ed | ||
|
|
11921c10b9 | ||
|
|
ee97356448 | ||
|
|
fd9de0c19e | ||
|
|
afd7d930ee | ||
|
|
e8ce6566d5 | ||
|
|
0b319e1670 | ||
|
|
18907c2c8f | ||
|
|
a04c5ba9bc | ||
|
|
fdd86721e7 | ||
|
|
a02b44deef | ||
|
|
041130244c | ||
|
|
c062cd9a95 | ||
|
|
8a41bb02b4 | ||
|
|
d4900702d5 | ||
|
|
8ee473d06e | ||
|
|
2fb0c3cdfe | ||
|
|
4c3d6c1292 | ||
|
|
a5f6bc639b | ||
|
|
93347494b3 | ||
|
|
6255a67654 | ||
|
|
b1d1897547 | ||
|
|
0ad3af78a6 | ||
|
|
a83d66cb88 | ||
|
|
706b211dbf | ||
|
|
105225be91 | ||
|
|
8489c48dda | ||
|
|
63445ae0f7 | ||
|
|
62e7fa86ab | ||
|
|
7ba048a8c5 | ||
|
|
1c18f52de0 | ||
|
|
fd7b14af83 | ||
|
|
aa433f46c9 | ||
|
|
6fe979cad1 | ||
|
|
cbb2ee7ba7 | ||
|
|
bbeb70d81b | ||
|
|
59dfc2ec32 | ||
|
|
8173b5cc87 | ||
|
|
35e508258d | ||
|
|
6a1c9a5f26 | ||
|
|
e1791e769c | ||
|
|
6566973398 | ||
|
|
4ac9954101 | ||
|
|
9fadbf2588 | ||
|
|
c8bbe90e26 | ||
|
|
76dc7098a0 | ||
|
|
40dd5e3957 | ||
|
|
8f87fe4770 | ||
|
|
2de3be7300 | ||
|
|
2ef718fc29 | ||
|
|
68764bf80f | ||
|
|
006ab972c7 | ||
|
|
72b45ab2a6 | ||
|
|
ca626ae04f | ||
|
|
e351376dcf | ||
|
|
1b8994c739 | ||
|
|
4cd13a9317 | ||
|
|
d67a677331 | ||
|
|
9df828835c | ||
|
|
3c68650d7e | ||
|
|
5d57ad769d | ||
|
|
6d2487082e | ||
|
|
f5db0eafbe | ||
|
|
19e0997436 | ||
|
|
7e09b471ab | ||
|
|
21c2ad8c23 | ||
|
|
57bc0fe12c | ||
|
|
4563f8ee5f | ||
|
|
4dd3fe78f7 | ||
|
|
ee8e47ffa1 | ||
|
|
f4ba6279f1 | ||
|
|
e5da8951b3 | ||
|
|
e337f85adc | ||
|
|
66c16561f5 | ||
|
|
ac6aeda1ec | ||
|
|
fcc01f872b | ||
|
|
171fc377ce | ||
|
|
92d4e3afd1 | ||
|
|
610971835b | ||
|
|
7ae7dcd1da | ||
|
|
fb91ddd813 | ||
|
|
f840c0bd32 | ||
|
|
7920885608 | ||
|
|
30d0ededbe | ||
|
|
6491647fcb | ||
|
|
e1b6006761 | ||
|
|
c396fd5ec3 | ||
|
|
260443fe73 | ||
|
|
8f0a19d169 | ||
|
|
d5ff73e928 | ||
|
|
5d8af45b21 | ||
|
|
1f085d5c0e | ||
|
|
ba7d244762 | ||
|
|
52aa593617 | ||
|
|
a257812e14 | ||
|
|
9de1d631b4 | ||
|
|
20344640e3 | ||
|
|
6f9e137336 | ||
|
|
969d017c56 | ||
|
|
7ce5732049 | ||
|
|
dfeae969a4 | ||
|
|
7d7c5f1412 | ||
|
|
a480689459 | ||
|
|
dd2cdf18cc | ||
|
|
609d52c6bf | ||
|
|
6776f65fc9 | ||
|
|
dd5d4bd8d7 | ||
|
|
4b0524258d | ||
|
|
08bc91ecc5 | ||
|
|
ccca5a19ca | ||
|
|
22dfacc18d | ||
|
|
4568f6c776 | ||
|
|
f6ba0d8aa0 | ||
|
|
d99e984a90 | ||
|
|
13df28d5c9 | ||
|
|
e87ace3a33 | ||
|
|
034172154a | ||
|
|
e18972e94e | ||
|
|
149f6c56b3 | ||
|
|
8770ae9db4 | ||
|
|
9b86dc25ab | ||
|
|
29f8fcf7b7 | ||
|
|
abfad4d255 | ||
|
|
14cf724f64 | ||
|
|
8a10c7ae6a | ||
|
|
5bdcc8f5b0 | ||
|
|
0f6adbebed | ||
|
|
0586066d1b | ||
|
|
065dd70056 | ||
|
|
69553da81a | ||
|
|
f68896ca53 | ||
|
|
e1e649ab89 | ||
|
|
bedcf4ad88 | ||
|
|
3b950401d8 | ||
|
|
af1c8a568d | ||
|
|
0eab2428c3 | ||
|
|
ff6d219775 | ||
|
|
565fa98d0c | ||
|
|
55bab4c4b2 | ||
|
|
e71265839e | ||
|
|
d9ce1e6bc9 | ||
|
|
f8a5ae28a7 | ||
|
|
5868098168 | ||
|
|
709b869a34 | ||
|
|
aab33f3219 | ||
|
|
28e332b7fa | ||
|
|
caf15b8f66 | ||
|
|
9c3bcab65c | ||
|
|
85144da53e | ||
|
|
abfc2d766e | ||
|
|
b3c608f2cf | ||
|
|
f012fafe51 | ||
|
|
9ecf67b230 | ||
|
|
5bad8496dc | ||
|
|
164fec9e74 |
@@ -21,7 +21,7 @@ jobs:
|
||||
# Disable the job in forks
|
||||
if: ${{ github.repository_owner == 'espressif' }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04-X64-large
|
||||
steps:
|
||||
# Depending on the branch/tag, set CLONE_BRANCH_OR_TAG variable (used in the Dockerfile
|
||||
# as a build arg) and TAG_NAME (used when tagging the image).
|
||||
|
||||
+1
-2
@@ -117,13 +117,12 @@
|
||||
/components/esp_ringbuf/ @esp-idf-codeowners/system
|
||||
/components/esp_rom/ @esp-idf-codeowners/system @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi
|
||||
/components/esp_security/ @esp-idf-codeowners/security
|
||||
/components/esp_stdio/ @esp-idf-codeowners/storage @esp-idf-codeowners/system
|
||||
/components/esp_system/ @esp-idf-codeowners/system
|
||||
/components/esp_tee/ @esp-idf-codeowners/security
|
||||
/components/esp_timer/ @esp-idf-codeowners/system
|
||||
/components/esp-tls/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_usb_cdc_rom_console/ @esp-idf-codeowners/system @esp-idf-codeowners/peripherals/usb
|
||||
/components/esp_vfs_*/ @esp-idf-codeowners/storage
|
||||
/components/esp_vfs_console/ @esp-idf-codeowners/storage @esp-idf-codeowners/system
|
||||
/components/esp_wifi/ @esp-idf-codeowners/wifi
|
||||
/components/espcoredump/ @esp-idf-codeowners/debugging
|
||||
/components/esptool_py/ @esp-idf-codeowners/tools
|
||||
|
||||
@@ -37,7 +37,7 @@ variables:
|
||||
GIT_FETCH_EXTRA_FLAGS: "--no-recurse-submodules --prune --prune-tags"
|
||||
# we're using .cache folder for caches
|
||||
GIT_CLEAN_FLAGS: -ffdx -e .cache/
|
||||
LATEST_GIT_TAG: v6.0-dev
|
||||
LATEST_GIT_TAG: v6.1-dev
|
||||
|
||||
SUBMODULE_FETCH_TOOL: "tools/ci/ci_fetch_submodule.py"
|
||||
# by default we will fetch all submodules
|
||||
@@ -52,9 +52,9 @@ variables:
|
||||
CHECKOUT_REF_SCRIPT: "$CI_PROJECT_DIR/tools/ci/checkout_project_ref.py"
|
||||
|
||||
# Docker images
|
||||
ESP_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-env-v6.0:3"
|
||||
ESP_IDF_DOC_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-idf-doc-env-v6.0:2-1"
|
||||
TARGET_TEST_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/target-test-env-v6.0:2"
|
||||
ESP_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-env-v6.1:1"
|
||||
ESP_IDF_DOC_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/esp-idf-doc-env-v6.1:1-1"
|
||||
TARGET_TEST_ENV_IMAGE: "${CI_DOCKER_REGISTRY}/target-test-env-v6.1:1"
|
||||
SONARQUBE_SCANNER_IMAGE: "${CI_DOCKER_REGISTRY}/sonarqube-scanner:5"
|
||||
|
||||
# cache python dependencies
|
||||
@@ -66,7 +66,7 @@ variables:
|
||||
CI_PYTHON_CONSTRAINT_BRANCH: ""
|
||||
|
||||
# Update the filename for a specific ESP-IDF release. It is used only with CI_PYTHON_CONSTRAINT_BRANCH.
|
||||
CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v6.0.txt"
|
||||
CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v6.1.txt"
|
||||
|
||||
# Set this variable to repository name of a Python tool you wish to install and test in the context of ESP-IDF CI.
|
||||
# Keep the variable empty when not used.
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
## Related <!-- Optional -->
|
||||
<!-- Related Jira issues and Github issues or write "No related issues"-->
|
||||
|
||||
## Release notes <!-- Mandatory -->
|
||||
<!-- Either state release notes or write "No release notes" -->
|
||||
|
||||
<!-- ## Breaking change notes --><!-- Optional -->
|
||||
|
||||
<!-- ## Dynamic Pipeline Configuration
|
||||
```yaml
|
||||
Test Case Filters:
|
||||
|
||||
@@ -39,27 +39,5 @@ _For other small/non-public changes, which are not expected to be in the release
|
||||
* Mention submodule MR, if there is
|
||||
* Mention backport(ed) MR, if there is
|
||||
|
||||
_Don't touch the subsection titles below, they will be parsed by scripts._
|
||||
|
||||
## Release notes <!-- Mandatory -->
|
||||
|
||||
_Changes made in this MR that should go into the **Release Notes** should be listed here. Please use **past tense** and *specify the area (see maintainers page of IDF internal wiki)*. If there is a subscope, include it and separate with slash (`/`). Minor changes can go to the descriptions above without a release notes entry._
|
||||
|
||||
_Write all the changes in a **list** (Start at the beginning of the line with `-` or `*`). If multiple changes are made, each of them should take a single line. If there is only one change to list, it should still be the only line of a list. If this MR does not need any release notes, write "No release notes" here without the `-` or `*`. e.g._
|
||||
|
||||
* [WiFi] Changed/fixed/updated xxx
|
||||
* [WiFi] Added support of xxx
|
||||
* [Peripheral Drivers/I2S] Fixed xxx (https://github.com/espressif/esp-idf/issues/xxxx)
|
||||
|
||||
## Breaking change notes
|
||||
|
||||
_Remove this subsection if not used._
|
||||
|
||||
_If there are any breaking changes, please mention it here. Talking about (1) what is not accepted any more, (2) the alternative solution and (3) the benefits/reason. e.g._
|
||||
|
||||
_Please strictly follow the breaking change restriction, which means, if there is a breaking change but you are merging to non-major versions, you have to separate the breaking part out to another MR for a major version. The breaking change subsection is only accepted in MRs merging to major versions._
|
||||
|
||||
* [VFS/UART] Now vfs_uart_set_rts_cts accept one more instance argument, to support configuration to different ports.
|
||||
|
||||
<!-- Don't remove the next line - assigns the MR author as the assignee -->
|
||||
/assign me
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
project(esp-idf C CXX ASM)
|
||||
|
||||
if(CMAKE_CURRENT_LIST_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
message(FATAL_ERROR "Current directory '${CMAKE_CURRENT_LIST_DIR}' is not buildable. "
|
||||
"Change directories to one of the example projects in '${CMAKE_CURRENT_LIST_DIR}/examples' and try "
|
||||
"again.")
|
||||
"Change directories to one of the example projects in '${CMAKE_CURRENT_LIST_DIR}/examples' and try again.")
|
||||
endif()
|
||||
|
||||
project(esp-idf C CXX ASM)
|
||||
|
||||
# Variables compile_options, c_compile_options, cxx_compile_options, compile_definitions, link_options shall
|
||||
# not be unset as they may already contain flags, set by toolchain-TARGET.cmake files.
|
||||
|
||||
|
||||
@@ -4,10 +4,26 @@ if(${target} STREQUAL "linux")
|
||||
return() # This component is not supported by the POSIX/Linux simulator
|
||||
endif()
|
||||
|
||||
set(srcs
|
||||
"app_trace.c"
|
||||
"app_trace_util.c"
|
||||
"host_file_io.c")
|
||||
if(CONFIG_APPTRACE_ENABLE)
|
||||
set(srcs
|
||||
"app_trace.c"
|
||||
"app_trace_util.c"
|
||||
"host_file_io.c"
|
||||
)
|
||||
|
||||
if(NOT CONFIG_APPTRACE_DEST_UART) # JTAG or ALL
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
list(APPEND srcs "port/xtensa/port_jtag.c")
|
||||
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||
list(APPEND srcs "port/riscv/port_jtag.c")
|
||||
endif()
|
||||
list(APPEND srcs "app_trace_membufs_proto.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_APPTRACE_DEST_JTAG) # UART or ALL
|
||||
list(APPEND srcs "port/port_uart.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_DEBUG_STUBS_ENABLE)
|
||||
list(APPEND srcs "debug_stubs.c")
|
||||
@@ -17,23 +33,6 @@ set(include_dirs "include")
|
||||
|
||||
set(priv_include_dirs "private_include" "port/include")
|
||||
|
||||
if(CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE)
|
||||
list(APPEND srcs "app_trace_membufs_proto.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_APPTRACE_DEST_JTAG)
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
list(APPEND srcs "port/xtensa/port_jtag.c")
|
||||
endif()
|
||||
if(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||
list(APPEND srcs "port/riscv/port_jtag.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_APPTRACE_DEST_UART)
|
||||
list(APPEND srcs "port/port_uart.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_APPTRACE_SV_ENABLE)
|
||||
list(APPEND include_dirs
|
||||
sys_view/Config
|
||||
@@ -59,6 +58,6 @@ endif()
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
PRIV_REQUIRES esp_driver_gptimer esp_driver_gpio esp_driver_uart
|
||||
REQUIRES esp_timer
|
||||
PRIV_REQUIRES esp_driver_gptimer
|
||||
REQUIRES esp_timer esp_driver_uart
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
@@ -1,36 +1,50 @@
|
||||
menu "Application Level Tracing"
|
||||
|
||||
choice APPTRACE_DESTINATION1
|
||||
prompt "Data Destination 1"
|
||||
default APPTRACE_DEST_NONE
|
||||
config APPTRACE_ENABLE
|
||||
bool "Enable Application Level Tracing"
|
||||
default n
|
||||
help
|
||||
Select destination for application trace: JTAG or none (to disable).
|
||||
Enables/disable application tracing module.
|
||||
This must be enabled to use any tracing library.
|
||||
|
||||
choice APPTRACE_DESTINATION
|
||||
prompt "Data Destination"
|
||||
default APPTRACE_DEST_JTAG if !PM_ENABLE
|
||||
default APPTRACE_DEST_UART if PM_ENABLE
|
||||
depends on APPTRACE_ENABLE
|
||||
help
|
||||
Select destination for application trace: JTAG or UART.
|
||||
When SystemView is enabled, this also controls the SystemView destination.
|
||||
|
||||
config APPTRACE_DEST_JTAG
|
||||
bool "JTAG"
|
||||
select APPTRACE_TRAX_ENABLE if IDF_TARGET_ARCH_XTENSA
|
||||
select APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE
|
||||
select APPTRACE_ENABLE
|
||||
|
||||
config APPTRACE_DEST_NONE
|
||||
bool "None"
|
||||
|
||||
endchoice
|
||||
|
||||
choice APPTRACE_DESTINATION2
|
||||
prompt "Data Destination 2"
|
||||
default APPTRACE_DEST_UART_NONE
|
||||
help
|
||||
Select destination for application trace: UART or none (to disable).
|
||||
depends on !PM_ENABLE
|
||||
|
||||
config APPTRACE_DEST_UART
|
||||
bool "UART"
|
||||
select APPTRACE_ENABLE
|
||||
|
||||
config APPTRACE_DEST_UART_NONE
|
||||
bool "None"
|
||||
config APPTRACE_DEST_NONE
|
||||
bool "None (runtime selection)"
|
||||
help
|
||||
Compile both JTAG and UART interfaces. Increases IRAM usage.
|
||||
Allows runtime selection via esp_apptrace_get_user_params().
|
||||
|
||||
With this option, destination and configuration must be provided
|
||||
at runtime. Default JTAG and UART settings are defined in
|
||||
components/app_trace/include/esp_app_trace_config.h.
|
||||
|
||||
Override these by implementing esp_apptrace_get_user_params()
|
||||
in your application.
|
||||
endchoice
|
||||
|
||||
config APPTRACE_BUF_SIZE
|
||||
int "Size of the apptrace buffer"
|
||||
depends on APPTRACE_DEST_JTAG && !APPTRACE_TRAX_ENABLE
|
||||
default 16384
|
||||
help
|
||||
Size of the memory buffer for trace data in bytes.
|
||||
|
||||
config APPTRACE_DEST_UART_NUM
|
||||
int "UART port number"
|
||||
depends on APPTRACE_DEST_UART
|
||||
@@ -107,6 +121,7 @@ menu "Application Level Tracing"
|
||||
config APPTRACE_UART_TASK_PRIO
|
||||
int
|
||||
prompt "UART Task Priority" if APPTRACE_DEST_UART
|
||||
depends on APPTRACE_DEST_UART
|
||||
default 1
|
||||
range 1 32
|
||||
help
|
||||
@@ -126,23 +141,13 @@ menu "Application Level Tracing"
|
||||
help
|
||||
Enables/disable TRAX tracing HW.
|
||||
|
||||
config APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE
|
||||
bool
|
||||
default n
|
||||
help
|
||||
Enables/disable swapping memory buffers tracing protocol.
|
||||
|
||||
config APPTRACE_ENABLE
|
||||
bool
|
||||
default n
|
||||
help
|
||||
Enables/disable application tracing module.
|
||||
|
||||
config APPTRACE_LOCK_ENABLE
|
||||
bool
|
||||
default !APPTRACE_SV_ENABLE
|
||||
bool "Internal Sync Lock Enable"
|
||||
depends on APPTRACE_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables/disable application tracing module internal sync lock.
|
||||
Keep in mind this will slow down the trace data transfer to the host.
|
||||
|
||||
config APPTRACE_ONPANIC_HOST_FLUSH_TMO
|
||||
int "Timeout for flushing last trace data to host on panic"
|
||||
@@ -162,13 +167,6 @@ menu "Application Level Tracing"
|
||||
Threshold for flushing last trace data to host on panic in post-mortem mode.
|
||||
This is minimal amount of data needed to perform flush. In bytes.
|
||||
|
||||
config APPTRACE_BUF_SIZE
|
||||
int "Size of the apptrace buffer"
|
||||
depends on APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE && !APPTRACE_TRAX_ENABLE
|
||||
default 16384
|
||||
help
|
||||
Size of the memory buffer for trace data in bytes.
|
||||
|
||||
menu "FreeRTOS SystemView Tracing"
|
||||
depends on APPTRACE_ENABLE
|
||||
config APPTRACE_SV_ENABLE
|
||||
@@ -178,30 +176,9 @@ menu "Application Level Tracing"
|
||||
help
|
||||
Enables support for SEGGER SystemView tracing functionality.
|
||||
|
||||
choice APPTRACE_SV_DEST
|
||||
prompt "SystemView destination"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default APPTRACE_SV_DEST_JTAG
|
||||
help
|
||||
SystemView will transfer data through the defined interface.
|
||||
|
||||
config APPTRACE_SV_DEST_JTAG
|
||||
bool "Data destination JTAG"
|
||||
depends on !PM_ENABLE && !APPTRACE_DEST_NONE
|
||||
help
|
||||
Send SEGGER SystemView events through JTAG interface.
|
||||
|
||||
config APPTRACE_SV_DEST_UART
|
||||
bool "Data destination UART"
|
||||
depends on APPTRACE_DEST_UART
|
||||
help
|
||||
Send SEGGER SystemView events through UART interface.
|
||||
|
||||
endchoice
|
||||
|
||||
choice APPTRACE_SV_CPU
|
||||
prompt "CPU to trace"
|
||||
depends on APPTRACE_SV_DEST_UART && !ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
depends on APPTRACE_SV_ENABLE && APPTRACE_DEST_UART && !ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
default APPTRACE_SV_DEST_CPU_0
|
||||
help
|
||||
Define the CPU to trace by SystemView.
|
||||
@@ -218,7 +195,6 @@ menu "Application Level Tracing"
|
||||
|
||||
endchoice
|
||||
|
||||
|
||||
choice APPTRACE_SV_TS_SOURCE
|
||||
prompt "Timer to use as timestamp source"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
|
||||
+153
-207
@@ -7,8 +7,10 @@
|
||||
#include <string.h>
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_app_trace_port.h"
|
||||
#include "esp_app_trace_types.h"
|
||||
#include "esp_private/startup_internal.h"
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_UART && CONFIG_APPTRACE_DEST_UART && (CONFIG_APPTRACE_DEST_UART_NUM == CONFIG_ESP_CONSOLE_UART_NUM)
|
||||
@@ -24,257 +26,205 @@ const static char *TAG = "esp_apptrace";
|
||||
typedef struct {
|
||||
esp_apptrace_hw_t *hw;
|
||||
void *hw_data;
|
||||
esp_apptrace_dest_t dest;
|
||||
} esp_apptrace_channel_t;
|
||||
|
||||
static esp_apptrace_channel_t s_trace_channels[ESP_APPTRACE_DEST_MAX];
|
||||
static bool s_inited;
|
||||
static esp_apptrace_channel_t s_trace_ch;
|
||||
static volatile int s_trace_ch_hw_initialized = 0;
|
||||
|
||||
esp_err_t esp_apptrace_init(void)
|
||||
static esp_err_t esp_apptrace_init(const esp_apptrace_config_t *config)
|
||||
{
|
||||
__attribute__((unused)) void *hw_data = NULL;
|
||||
|
||||
// 'esp_apptrace_init()' is called on every core, so ensure to do main initialization only once
|
||||
if (esp_cpu_get_core_id() == 0) {
|
||||
memset(&s_trace_channels, 0, sizeof(s_trace_channels));
|
||||
#if CONFIG_APPTRACE_DEST_JTAG
|
||||
s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw = esp_apptrace_jtag_hw_get(&hw_data);
|
||||
s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw_data = hw_data;
|
||||
s_trace_ch.hw = esp_apptrace_jtag_hw_get(&hw_data);
|
||||
s_trace_ch.hw_data = hw_data;
|
||||
#elif CONFIG_APPTRACE_DEST_UART
|
||||
const esp_apptrace_uart_config_t *uart_config = &config->dest_cfg.uart;
|
||||
s_trace_ch.hw = esp_apptrace_uart_hw_get(uart_config->uart_num, &hw_data);
|
||||
s_trace_ch.hw_data = hw_data;
|
||||
#else // CONFIG_APPTRACE_DEST_NONE allows runtime selection
|
||||
if (config->dest == ESP_APPTRACE_DEST_JTAG) {
|
||||
s_trace_ch.hw = esp_apptrace_jtag_hw_get(&hw_data);
|
||||
s_trace_ch.hw_data = hw_data;
|
||||
} else if (config->dest == ESP_APPTRACE_DEST_UART) {
|
||||
const esp_apptrace_uart_config_t *uart_config = &config->dest_cfg.uart;
|
||||
s_trace_ch.hw = esp_apptrace_uart_hw_get(uart_config->uart_num, &hw_data);
|
||||
s_trace_ch.hw_data = hw_data;
|
||||
} else {
|
||||
s_trace_ch.hw = NULL;
|
||||
s_trace_ch.hw_data = NULL;
|
||||
ESP_APPTRACE_LOGE("Invalid destination type (%d)!", config->dest);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_APPTRACE_DEST_UART
|
||||
s_trace_channels[ESP_APPTRACE_DEST_UART].hw = esp_apptrace_uart_hw_get(CONFIG_APPTRACE_DEST_UART_NUM, &hw_data);
|
||||
s_trace_channels[ESP_APPTRACE_DEST_UART].hw_data = hw_data;
|
||||
#endif
|
||||
s_inited = true;
|
||||
s_trace_ch.dest = config->dest;
|
||||
s_trace_ch_hw_initialized = 1;
|
||||
} else {
|
||||
// There is NO guarantee that system init functions will execute on core 0 first
|
||||
// So we need to wait for core 0 to set up the hardware interface
|
||||
while (!s_trace_ch_hw_initialized) {
|
||||
esp_rom_delay_us(10);
|
||||
}
|
||||
}
|
||||
|
||||
// esp_apptrace_init() is called on every core, so initialize trace channel on every core
|
||||
for (int i = 0; i < sizeof(s_trace_channels) / sizeof(s_trace_channels[0]); i++) {
|
||||
esp_apptrace_channel_t *ch = &s_trace_channels[i];
|
||||
if (ch->hw) {
|
||||
int res = ch->hw->init(ch->hw_data);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to init trace channel HW interface (%d)!", res);
|
||||
return res;
|
||||
}
|
||||
if (s_trace_ch.hw) {
|
||||
int res = s_trace_ch.hw->init(s_trace_ch.hw_data, config);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to init trace channel HW interface (%d)!", res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(esp_apptrace_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES, 115)
|
||||
esp_err_t esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size)
|
||||
{
|
||||
return esp_apptrace_init();
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_down_buffer_config(esp_apptrace_dest_t dest, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
if (!buf || size == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (buf == NULL || size == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_inited) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (ch->hw->down_buffer_config != NULL) {
|
||||
ch->hw->down_buffer_config(ch->hw_data, buf, size);
|
||||
if (s_trace_ch.hw->down_buffer_config) {
|
||||
s_trace_ch.hw->down_buffer_config(s_trace_ch.hw_data, buf, size);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t user_tmo)
|
||||
uint8_t *esp_apptrace_down_buffer_get(uint32_t *size, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
|
||||
if (!size || *size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (size == NULL || *size == 0) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return NULL;
|
||||
}
|
||||
if (!s_inited) {
|
||||
return NULL;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return NULL;
|
||||
}
|
||||
if (ch->hw->get_down_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->get_down_buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return ch->hw->get_down_buffer(ch->hw_data, size, &tmo);
|
||||
|
||||
return s_trace_ch.hw->get_down_buffer(s_trace_ch.hw_data, size, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo)
|
||||
esp_err_t esp_apptrace_down_buffer_put(uint8_t *ptr, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
|
||||
if (!ptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_inited) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
if (ch->hw->get_down_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->get_down_buffer) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return ch->hw->put_down_buffer(ch->hw_data, ptr, &tmo);
|
||||
|
||||
return s_trace_ch.hw->put_down_buffer(s_trace_ch.hw_data, ptr, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size, uint32_t user_tmo)
|
||||
esp_err_t esp_apptrace_read(void *buf, uint32_t *size, uint32_t user_tmo)
|
||||
{
|
||||
int res = ESP_OK;
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
|
||||
if (!buf || !size || *size == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (buf == NULL || size == NULL || *size == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_inited) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
if (ch->hw->get_down_buffer == NULL || ch->hw->put_down_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->get_down_buffer || !s_trace_ch.hw->put_down_buffer) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
//TODO: callback system
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
|
||||
uint32_t act_sz = *size;
|
||||
*size = 0;
|
||||
uint8_t *ptr = ch->hw->get_down_buffer(ch->hw_data, &act_sz, &tmo);
|
||||
uint8_t *ptr = s_trace_ch.hw->get_down_buffer(s_trace_ch.hw_data, &act_sz, &tmo);
|
||||
if (ptr && act_sz > 0) {
|
||||
ESP_APPTRACE_LOGD("Read %" PRIu32 " bytes from host", act_sz);
|
||||
memcpy(buf, ptr, act_sz);
|
||||
res = ch->hw->put_down_buffer(ch->hw_data, ptr, &tmo);
|
||||
*size = act_sz;
|
||||
} else {
|
||||
res = ESP_ERR_TIMEOUT;
|
||||
return s_trace_ch.hw->put_down_buffer(s_trace_ch.hw_data, ptr, &tmo);
|
||||
}
|
||||
|
||||
return res;
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t user_tmo)
|
||||
uint8_t *esp_apptrace_buffer_get(uint32_t size, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!s_inited) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return NULL;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return NULL;
|
||||
}
|
||||
if (ch->hw->get_up_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->get_up_buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return ch->hw->get_up_buffer(ch->hw_data, size, &tmo);
|
||||
|
||||
return s_trace_ch.hw->get_up_buffer(s_trace_ch.hw_data, size, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo)
|
||||
esp_err_t esp_apptrace_buffer_put(uint8_t *ptr, uint32_t user_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
|
||||
if (!ptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_inited) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
if (ch->hw->put_up_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->put_up_buffer) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
return ch->hw->put_up_buffer(ch->hw_data, ptr, &tmo);
|
||||
|
||||
return s_trace_ch.hw->put_up_buffer(s_trace_ch.hw_data, ptr, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_t size, uint32_t user_tmo)
|
||||
esp_err_t esp_apptrace_write(const void *data, uint32_t size, uint32_t user_tmo)
|
||||
{
|
||||
uint8_t *ptr = NULL;
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
|
||||
if (!data || size == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (data == NULL || size == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_inited) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
if (ch->hw->get_up_buffer == NULL || ch->hw->put_up_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->get_up_buffer || !s_trace_ch.hw->put_up_buffer) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
ptr = ch->hw->get_up_buffer(ch->hw_data, size, &tmo);
|
||||
if (ptr == NULL) {
|
||||
|
||||
uint8_t *ptr = s_trace_ch.hw->get_up_buffer(s_trace_ch.hw_data, size, &tmo);
|
||||
if (!ptr) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
@@ -283,36 +233,29 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
|
||||
memcpy(ptr, data, size);
|
||||
|
||||
// now indicate that this buffer is ready to be sent off to host
|
||||
return ch->hw->put_up_buffer(ch->hw_data, ptr, &tmo);
|
||||
return s_trace_ch.hw->put_up_buffer(s_trace_ch.hw_data, ptr, &tmo);
|
||||
}
|
||||
|
||||
int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const char *fmt, va_list ap)
|
||||
int esp_apptrace_vprintf_to(uint32_t user_tmo, const char *fmt, va_list ap)
|
||||
{
|
||||
uint16_t nargs = 0;
|
||||
uint8_t *pout, *p = (uint8_t *)fmt;
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
|
||||
if (!fmt) {
|
||||
return -1;
|
||||
}
|
||||
if (fmt == NULL) {
|
||||
if (!s_trace_ch.hw) {
|
||||
return -1;
|
||||
}
|
||||
if (!s_inited) {
|
||||
return -1;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return -1;
|
||||
}
|
||||
if (ch->hw->get_up_buffer == NULL || ch->hw->put_up_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->get_up_buffer || !s_trace_ch.hw->put_up_buffer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, user_tmo);
|
||||
|
||||
ESP_APPTRACE_LOGD("fmt %p", fmt);
|
||||
while ((p = (uint8_t *)strchr((char *)p, '%')) && nargs < ESP_APPTRACE_MAX_VPRINTF_ARGS) {
|
||||
p++;
|
||||
@@ -325,8 +268,8 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
|
||||
ESP_APPTRACE_LOGE("Failed to store all printf args!");
|
||||
}
|
||||
|
||||
pout = ch->hw->get_up_buffer(ch->hw_data, 1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo);
|
||||
if (pout == NULL) {
|
||||
pout = s_trace_ch.hw->get_up_buffer(s_trace_ch.hw_data, 1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo);
|
||||
if (!pout) {
|
||||
ESP_APPTRACE_LOGE("Failed to get buffer!");
|
||||
return -1;
|
||||
}
|
||||
@@ -342,7 +285,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
|
||||
ESP_APPTRACE_LOGD("arg %" PRIx32, arg);
|
||||
}
|
||||
|
||||
int ret = ch->hw->put_up_buffer(ch->hw_data, p, &tmo);
|
||||
int ret = s_trace_ch.hw->put_up_buffer(s_trace_ch.hw_data, p, &tmo);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to put printf buf (%d)!", ret);
|
||||
return -1;
|
||||
@@ -353,78 +296,81 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
|
||||
|
||||
int esp_apptrace_vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
return esp_apptrace_vprintf_to(ESP_APPTRACE_DEST_JTAG, 0, fmt, ap);
|
||||
return esp_apptrace_vprintf_to(0, fmt, ap);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, uint32_t usr_tmo)
|
||||
esp_err_t esp_apptrace_flush_nolock(uint32_t min_sz, uint32_t usr_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_inited) {
|
||||
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
if (ch->hw->flush_up_buffer_nolock == NULL) {
|
||||
if (!s_trace_ch.hw->flush_up_buffer_nolock) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, usr_tmo);
|
||||
return ch->hw->flush_up_buffer_nolock(ch->hw_data, min_sz, &tmo);
|
||||
|
||||
return s_trace_ch.hw->flush_up_buffer_nolock(s_trace_ch.hw_data, min_sz, &tmo);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t usr_tmo)
|
||||
esp_err_t esp_apptrace_flush(uint32_t usr_tmo)
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_inited) {
|
||||
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
if (ch->hw->flush_up_buffer == NULL) {
|
||||
if (!s_trace_ch.hw->flush_up_buffer) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, usr_tmo);
|
||||
return ch->hw->flush_up_buffer(ch->hw_data, &tmo);
|
||||
|
||||
return s_trace_ch.hw->flush_up_buffer(s_trace_ch.hw_data, &tmo);
|
||||
}
|
||||
|
||||
bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest)
|
||||
bool esp_apptrace_host_is_connected(void)
|
||||
{
|
||||
esp_apptrace_channel_t *ch;
|
||||
|
||||
ESP_APPTRACE_LOGV("%s(): enter", __func__);
|
||||
if (dest >= ESP_APPTRACE_DEST_MAX) {
|
||||
|
||||
if (!s_trace_ch.hw) {
|
||||
return false;
|
||||
}
|
||||
if (!s_inited) {
|
||||
return false;
|
||||
}
|
||||
ch = &s_trace_channels[dest];
|
||||
if (ch->hw == NULL) {
|
||||
ESP_APPTRACE_LOGE("Trace destination %d not supported!", dest);
|
||||
return false;
|
||||
}
|
||||
if (ch->hw->host_is_connected == NULL) {
|
||||
if (!s_trace_ch.hw->host_is_connected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ch->hw->host_is_connected(ch->hw_data);
|
||||
return s_trace_ch.hw->host_is_connected(s_trace_ch.hw_data);
|
||||
}
|
||||
|
||||
esp_apptrace_dest_t esp_apptrace_get_destination(void)
|
||||
{
|
||||
return s_trace_ch.dest;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_set_header_size(esp_apptrace_header_size_t header_size)
|
||||
{
|
||||
if (!s_trace_ch.hw) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (s_trace_ch.hw->set_header_size) {
|
||||
s_trace_ch.hw->set_header_size(s_trace_ch.hw_data, header_size);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_apptrace_config_t __attribute__((weak)) esp_apptrace_get_user_params(void)
|
||||
{
|
||||
esp_apptrace_config_t default_config = APPTRACE_CONFIG_DEFAULT();
|
||||
return default_config;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(apptrace_early_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES, 115)
|
||||
{
|
||||
esp_apptrace_config_t config = esp_apptrace_get_user_params();
|
||||
return esp_apptrace_init(&config);
|
||||
}
|
||||
|
||||
@@ -18,13 +18,16 @@
|
||||
* In this case host SW will see that wr_sz < block_sz and will report error.
|
||||
*/
|
||||
typedef struct {
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
uint8_t block_sz; // size of allocated block for user data
|
||||
uint8_t wr_sz; // size of actually written data
|
||||
#else
|
||||
uint16_t block_sz; // size of allocated block for user data
|
||||
uint16_t wr_sz; // size of actually written data
|
||||
#endif
|
||||
union {
|
||||
struct {
|
||||
uint8_t block_sz_8;
|
||||
uint8_t wr_sz_8;
|
||||
};
|
||||
struct {
|
||||
uint16_t block_sz_16;
|
||||
uint16_t wr_sz_16;
|
||||
};
|
||||
};
|
||||
} esp_tracedata_hdr_t;
|
||||
|
||||
/** TODO: docs
|
||||
@@ -33,31 +36,24 @@ typedef struct {
|
||||
uint16_t block_sz; // size of allocated block for user data
|
||||
} esp_hostdata_hdr_t;
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) (0)
|
||||
#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (_v_)
|
||||
#define ESP_APPTRACE_USR_DATA_LEN_MAX(_hw_data_) 255UL
|
||||
#else
|
||||
#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) ((_cid_) << 15)
|
||||
#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (~(1 << 15) & (_v_))
|
||||
#define ESP_APPTRACE_USR_DATA_LEN_MAX(_hw_data_) (ESP_APPTRACE_INBLOCK(_hw_data_)->sz - sizeof(esp_tracedata_hdr_t))
|
||||
#endif
|
||||
#define ESP_APPTRACE_USR_BLOCK_RAW_SZ(_s_) ((_s_) + sizeof(esp_tracedata_hdr_t))
|
||||
#define ESP_APPTRACE_INBLOCK_MARKER(_hw_data_) \
|
||||
((_hw_data_)->state.markers[(_hw_data_)->state.in_block % 2])
|
||||
|
||||
#define ESP_APPTRACE_INBLOCK_MARKER(_hw_data_) ((_hw_data_)->state.markers[(_hw_data_)->state.in_block % 2])
|
||||
#define ESP_APPTRACE_INBLOCK_MARKER_UPD(_hw_data_, _v_) do {(_hw_data_)->state.markers[(_hw_data_)->state.in_block % 2] += (_v_);}while(0)
|
||||
#define ESP_APPTRACE_INBLOCK(_hw_data_) (&(_hw_data_)->blocks[(_hw_data_)->state.in_block % 2])
|
||||
#define ESP_APPTRACE_INBLOCK(_hw_data_) \
|
||||
(&(_hw_data_)->blocks[(_hw_data_)->state.in_block % 2])
|
||||
|
||||
const static char *TAG = "esp_apptrace";
|
||||
|
||||
static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto, uint8_t *data, uint32_t size);
|
||||
static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto,
|
||||
uint8_t *data, uint32_t size);
|
||||
|
||||
esp_err_t esp_apptrace_membufs_init(esp_apptrace_membufs_proto_data_t *proto, const esp_apptrace_mem_block_t blocks_cfg[2])
|
||||
esp_err_t esp_apptrace_membufs_init(esp_apptrace_membufs_proto_data_t *proto,
|
||||
const esp_apptrace_mem_block_t blocks_cfg[2])
|
||||
{
|
||||
// disabled by default
|
||||
esp_apptrace_rb_init(&proto->rb_down, NULL, 0);
|
||||
// membufs proto init
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
for (unsigned int i = 0; i < 2; i++) {
|
||||
proto->blocks[i].start = blocks_cfg[i].start;
|
||||
proto->blocks[i].sz = blocks_cfg[i].sz;
|
||||
proto->state.markers[i] = 0;
|
||||
@@ -104,7 +100,8 @@ static esp_err_t esp_apptrace_membufs_swap(esp_apptrace_membufs_proto_data_t *pr
|
||||
*(p - 8), *(p - 7), *(p - 6), *(p - 5), *(p - 4), *(p - 3), *(p - 2), *(p - 1));
|
||||
uint32_t sz = esp_apptrace_membufs_down_buffer_write_nolock(proto, (uint8_t *)(hdr + 1), hdr->block_sz);
|
||||
if (sz != hdr->block_sz) {
|
||||
ESP_APPTRACE_LOGE("Failed to write %" PRIu32 " bytes to down buffer (%" PRIu16 " %" PRIu32 ")!", hdr->block_sz - sz, hdr->block_sz, sz);
|
||||
ESP_APPTRACE_LOGE("Failed to write %" PRIu32 " bytes to down buffer (%" PRIu16 " %" PRIu32 ")!",
|
||||
hdr->block_sz - sz, hdr->block_sz, sz);
|
||||
}
|
||||
hdr->block_sz = 0;
|
||||
}
|
||||
@@ -137,7 +134,8 @@ static esp_err_t esp_apptrace_membufs_swap_waitus(esp_apptrace_membufs_proto_dat
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t *proto,
|
||||
uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr = NULL;
|
||||
|
||||
@@ -170,13 +168,15 @@ uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t
|
||||
return ptr;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_membufs_down_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
esp_err_t esp_apptrace_membufs_down_buffer_put(esp_apptrace_membufs_proto_data_t *proto,
|
||||
uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
/* nothing todo */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto, uint8_t *data, uint32_t size)
|
||||
static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto,
|
||||
uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint32_t total_sz = 0;
|
||||
|
||||
@@ -204,29 +204,21 @@ static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membu
|
||||
return total_sz;
|
||||
}
|
||||
|
||||
static inline uint8_t *esp_apptrace_membufs_pkt_start(uint8_t *ptr, uint16_t size)
|
||||
static inline uint32_t esp_apptrace_membufs_usr_data_len_max(esp_apptrace_membufs_proto_data_t *proto)
|
||||
{
|
||||
// it is safe to use esp_cpu_get_core_id() in macro call because arg is used only once inside it
|
||||
((esp_tracedata_hdr_t *)ptr)->block_sz = ESP_APPTRACE_USR_BLOCK_CORE(esp_cpu_get_core_id()) | size;
|
||||
((esp_tracedata_hdr_t *)ptr)->wr_sz = 0;
|
||||
return ptr + sizeof(esp_tracedata_hdr_t);
|
||||
return proto->header_size == ESP_APPTRACE_HEADER_SIZE_32 ?
|
||||
ESP_APPTRACE_INBLOCK(proto)->sz - ESP_APPTRACE_HEADER_SIZE_32 : 255;
|
||||
}
|
||||
|
||||
static inline void esp_apptrace_membufs_pkt_end(uint8_t *ptr)
|
||||
uint8_t *esp_apptrace_membufs_up_buffer_get(esp_apptrace_membufs_proto_data_t *proto,
|
||||
uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
esp_tracedata_hdr_t *hdr = (esp_tracedata_hdr_t *)(ptr - sizeof(esp_tracedata_hdr_t));
|
||||
// update written size
|
||||
hdr->wr_sz = hdr->block_sz;
|
||||
}
|
||||
|
||||
uint8_t *esp_apptrace_membufs_up_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (size > ESP_APPTRACE_USR_DATA_LEN_MAX(proto)) {
|
||||
if (size > esp_apptrace_membufs_usr_data_len_max(proto)) {
|
||||
ESP_APPTRACE_LOGE("Too large user data size %" PRIu32 "!", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ESP_APPTRACE_INBLOCK_MARKER(proto) + ESP_APPTRACE_USR_BLOCK_RAW_SZ(size) > ESP_APPTRACE_INBLOCK(proto)->sz) {
|
||||
if (ESP_APPTRACE_INBLOCK_MARKER(proto) + size + proto->header_size > ESP_APPTRACE_INBLOCK(proto)->sz) {
|
||||
int res = esp_apptrace_membufs_swap_waitus(proto, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
@@ -235,16 +227,32 @@ uint8_t *esp_apptrace_membufs_up_buffer_get(esp_apptrace_membufs_proto_data_t *p
|
||||
|
||||
uint8_t *buf_ptr = ESP_APPTRACE_INBLOCK(proto)->start + ESP_APPTRACE_INBLOCK_MARKER(proto);
|
||||
// update cur block marker
|
||||
ESP_APPTRACE_INBLOCK_MARKER_UPD(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
|
||||
buf_ptr = esp_apptrace_membufs_pkt_start(buf_ptr, size);
|
||||
proto->state.markers[proto->state.in_block % 2] += size + proto->header_size;
|
||||
|
||||
// update header
|
||||
esp_tracedata_hdr_t *hdr = (esp_tracedata_hdr_t *)buf_ptr;
|
||||
if (proto->header_size == ESP_APPTRACE_HEADER_SIZE_32) {
|
||||
hdr->block_sz_16 = (esp_cpu_get_core_id() << 15) | size;
|
||||
hdr->wr_sz_16 = 0;
|
||||
} else {
|
||||
hdr->block_sz_8 = size;
|
||||
hdr->wr_sz_8 = 0;
|
||||
}
|
||||
ESP_APPTRACE_LOGD("Got %" PRIu32 " bytes from block", size);
|
||||
|
||||
return buf_ptr;
|
||||
return buf_ptr + proto->header_size;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_membufs_up_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
esp_err_t esp_apptrace_membufs_up_buffer_put(esp_apptrace_membufs_proto_data_t *proto,
|
||||
uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
esp_apptrace_membufs_pkt_end(ptr);
|
||||
// update header
|
||||
esp_tracedata_hdr_t *hdr = (esp_tracedata_hdr_t *)(ptr - proto->header_size);
|
||||
if (proto->header_size == ESP_APPTRACE_HEADER_SIZE_32) {
|
||||
hdr->wr_sz_16 = hdr->block_sz_16;
|
||||
} else {
|
||||
hdr->wr_sz_8 = hdr->block_sz_8;
|
||||
}
|
||||
// TODO: mark block as busy in order not to reuse it for other tracing calls until it is completely written
|
||||
// TODO: avoid potential situation when all memory is consumed by low prio tasks which can not complete writing due to
|
||||
// higher prio tasks and the latter can not allocate buffers at all
|
||||
@@ -253,7 +261,8 @@ esp_err_t esp_apptrace_membufs_up_buffer_put(esp_apptrace_membufs_proto_data_t *
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_membufs_flush_nolock(esp_apptrace_membufs_proto_data_t *proto, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
esp_err_t esp_apptrace_membufs_flush_nolock(esp_apptrace_membufs_proto_data_t *proto,
|
||||
uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
int res = ESP_OK;
|
||||
|
||||
@@ -267,7 +276,7 @@ esp_err_t esp_apptrace_membufs_flush_nolock(esp_apptrace_membufs_proto_data_t *p
|
||||
res = esp_apptrace_membufs_swap_waitus(proto, tmo);
|
||||
if (res != ESP_OK) {
|
||||
if (res == ESP_ERR_TIMEOUT) {
|
||||
ESP_APPTRACE_LOGW("Failed to switch to another block in %" PRIi32 " us!", (int32_t)tmo->elapsed);
|
||||
ESP_APPTRACE_LOGW("Failed to switch to another block in %" PRId32 " us!", (int32_t)tmo->elapsed);
|
||||
} else {
|
||||
ESP_APPTRACE_LOGE("Failed to switch to another block, res: %d", res);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
@@ -57,6 +57,12 @@ esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo)
|
||||
///////////////////////////////// LOCK ////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void esp_apptrace_lock_init(esp_apptrace_lock_t *lock)
|
||||
{
|
||||
portMUX_INITIALIZE(&lock->mux);
|
||||
lock->int_state = 0;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_lock_take(esp_apptrace_lock_t *lock, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_heap_trace.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#include <string.h>
|
||||
#include "esp_app_trace.h"
|
||||
|
||||
#if CONFIG_APPTRACE_ENABLE
|
||||
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_host_file_io";
|
||||
|
||||
@@ -79,13 +77,13 @@ typedef struct {
|
||||
void *file;
|
||||
} esp_apptrace_ftell_args_t;
|
||||
|
||||
static esp_err_t esp_apptrace_file_cmd_send(esp_apptrace_dest_t dest, uint8_t cmd, void (*prep_args)(uint8_t *, void *), void *args, uint32_t args_len)
|
||||
static esp_err_t esp_apptrace_file_cmd_send(uint8_t cmd, void (*prep_args)(uint8_t *, void *), void *args, uint32_t args_len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
esp_apptrace_fcmd_hdr_t *hdr;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s %d", __func__, cmd);
|
||||
uint8_t *ptr = esp_apptrace_buffer_get(dest, sizeof(*hdr) + args_len, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
uint8_t *ptr = esp_apptrace_buffer_get(sizeof(*hdr) + args_len, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
if (ptr == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
@@ -97,13 +95,13 @@ static esp_err_t esp_apptrace_file_cmd_send(esp_apptrace_dest_t dest, uint8_t cm
|
||||
}
|
||||
|
||||
// now indicate that this buffer is ready to be sent off to host
|
||||
ret = esp_apptrace_buffer_put(dest, ptr, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
ret = esp_apptrace_buffer_put(ptr, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to put apptrace buffer (%d)!", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_apptrace_flush(dest, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
ret = esp_apptrace_flush(ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to flush apptrace buffer (%d)!", ret);
|
||||
return ret;
|
||||
@@ -112,12 +110,12 @@ static esp_err_t esp_apptrace_file_cmd_send(esp_apptrace_dest_t dest, uint8_t cm
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_file_rsp_recv(esp_apptrace_dest_t dest, uint8_t *buf, uint32_t buf_len)
|
||||
static esp_err_t esp_apptrace_file_rsp_recv(uint8_t *buf, uint32_t buf_len)
|
||||
{
|
||||
uint32_t tot_rd = 0;
|
||||
while (tot_rd < buf_len) {
|
||||
uint32_t rd_size = buf_len - tot_rd;
|
||||
esp_err_t ret = esp_apptrace_read(dest, buf + tot_rd, &rd_size, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
esp_err_t ret = esp_apptrace_read(buf + tot_rd, &rd_size, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read (%d)!", ret);
|
||||
return ret;
|
||||
@@ -137,7 +135,7 @@ static void esp_apptrace_fopen_args_prepare(uint8_t *buf, void *priv)
|
||||
memcpy(buf + args->path_len, args->mode, args->mode_len);
|
||||
}
|
||||
|
||||
void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char *mode)
|
||||
void *esp_apptrace_fopen(const char *path, const char *mode)
|
||||
{
|
||||
esp_apptrace_fopen_args_t cmd_args;
|
||||
|
||||
@@ -151,7 +149,7 @@ void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char
|
||||
cmd_args.mode = mode;
|
||||
cmd_args.mode_len = strlen(mode) + 1;
|
||||
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FOPEN, esp_apptrace_fopen_args_prepare,
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_FOPEN, esp_apptrace_fopen_args_prepare,
|
||||
&cmd_args, cmd_args.path_len + cmd_args.mode_len);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
@@ -160,7 +158,7 @@ void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char
|
||||
|
||||
// now read the answer
|
||||
void *resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
ret = esp_apptrace_file_rsp_recv((uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return NULL;
|
||||
@@ -176,12 +174,12 @@ static void esp_apptrace_fclose_args_prepare(uint8_t *buf, void *priv)
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
}
|
||||
|
||||
int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream)
|
||||
int esp_apptrace_fclose(void *stream)
|
||||
{
|
||||
esp_apptrace_fclose_args_t cmd_args;
|
||||
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FCLOSE, esp_apptrace_fclose_args_prepare,
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_FCLOSE, esp_apptrace_fclose_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
@@ -190,7 +188,7 @@ int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream)
|
||||
|
||||
// now read the answer
|
||||
int resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
ret = esp_apptrace_file_rsp_recv((uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return EOF;
|
||||
@@ -207,7 +205,7 @@ static void esp_apptrace_fwrite_args_prepare(uint8_t *buf, void *priv)
|
||||
memcpy(buf + sizeof(args->file), args->buf, args->size);
|
||||
}
|
||||
|
||||
size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
size_t esp_apptrace_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
esp_apptrace_fwrite_args_t cmd_args;
|
||||
|
||||
@@ -220,7 +218,7 @@ size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t siz
|
||||
cmd_args.buf = (void *)ptr;
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FWRITE, esp_apptrace_fwrite_args_prepare,
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_FWRITE, esp_apptrace_fwrite_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args.file) + cmd_args.size);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
@@ -229,7 +227,7 @@ size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t siz
|
||||
|
||||
// now read the answer
|
||||
size_t resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
ret = esp_apptrace_file_rsp_recv((uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return 0;
|
||||
@@ -249,7 +247,7 @@ static void esp_apptrace_fread_args_prepare(uint8_t *buf, void *priv)
|
||||
memcpy(buf + sizeof(args->file), &args->size, sizeof(args->size));
|
||||
}
|
||||
|
||||
size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
size_t esp_apptrace_fread(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
esp_apptrace_fread_args_t cmd_args;
|
||||
|
||||
@@ -261,7 +259,7 @@ size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size
|
||||
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FREAD, esp_apptrace_fread_args_prepare,
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_FREAD, esp_apptrace_fread_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
@@ -270,7 +268,7 @@ size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size
|
||||
|
||||
// now read the answer
|
||||
size_t resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
ret = esp_apptrace_file_rsp_recv((uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return 0;
|
||||
@@ -279,7 +277,7 @@ size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = esp_apptrace_file_rsp_recv(dest, ptr, resp);
|
||||
ret = esp_apptrace_file_rsp_recv(ptr, resp);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read file data (%d)!", ret);
|
||||
return 0;
|
||||
@@ -300,7 +298,7 @@ static void esp_apptrace_fseek_args_prepare(uint8_t *buf, void *priv)
|
||||
memcpy(buf + sizeof(args->file) + sizeof(args->offset), &args->whence, sizeof(args->whence));
|
||||
}
|
||||
|
||||
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence)
|
||||
int esp_apptrace_fseek(void *stream, long offset, int whence)
|
||||
{
|
||||
esp_apptrace_fseek_args_t cmd_args;
|
||||
|
||||
@@ -309,7 +307,7 @@ int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int
|
||||
cmd_args.file = stream;
|
||||
cmd_args.offset = offset;
|
||||
cmd_args.whence = whence;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FSEEK, esp_apptrace_fseek_args_prepare,
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_FSEEK, esp_apptrace_fseek_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
@@ -318,7 +316,7 @@ int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int
|
||||
|
||||
// now read the answer
|
||||
int resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
ret = esp_apptrace_file_rsp_recv((uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return -1;
|
||||
@@ -334,12 +332,12 @@ static void esp_apptrace_ftell_args_prepare(uint8_t *buf, void *priv)
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
}
|
||||
|
||||
int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
|
||||
int esp_apptrace_ftell(void *stream)
|
||||
{
|
||||
esp_apptrace_ftell_args_t cmd_args;
|
||||
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FTELL, esp_apptrace_ftell_args_prepare,
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_FTELL, esp_apptrace_ftell_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
@@ -348,7 +346,7 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
|
||||
|
||||
// now read the answer
|
||||
int resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
ret = esp_apptrace_file_rsp_recv((uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return -1;
|
||||
@@ -357,10 +355,10 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
|
||||
return resp;
|
||||
}
|
||||
|
||||
int esp_apptrace_fstop(esp_apptrace_dest_t dest)
|
||||
int esp_apptrace_fstop(void)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __func__);
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_STOP, NULL, NULL, 0);
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_STOP, NULL, NULL, 0);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
}
|
||||
@@ -374,12 +372,12 @@ static void esp_apptrace_feof_args_prepare(uint8_t *buf, void *priv)
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
}
|
||||
|
||||
int esp_apptrace_feof(esp_apptrace_dest_t dest, void *stream)
|
||||
int esp_apptrace_feof(void *stream)
|
||||
{
|
||||
esp_apptrace_feof_args_t cmd_args;
|
||||
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FEOF, esp_apptrace_feof_args_prepare,
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(ESP_APPTRACE_FILE_CMD_FEOF, esp_apptrace_feof_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
@@ -388,7 +386,7 @@ int esp_apptrace_feof(esp_apptrace_dest_t dest, void *stream)
|
||||
|
||||
// now read the answer
|
||||
int resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
ret = esp_apptrace_file_rsp_recv((uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return EOF;
|
||||
@@ -396,5 +394,3 @@ int esp_apptrace_feof(esp_apptrace_dest_t dest, void *stream)
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_app_trace_config.h"
|
||||
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -15,83 +16,73 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Application trace data destinations bits.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_APPTRACE_DEST_JTAG, ///< JTAG destination
|
||||
ESP_APPTRACE_DEST_UART, ///< UART destination
|
||||
ESP_APPTRACE_DEST_MAX,
|
||||
} esp_apptrace_dest_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes application tracing module.
|
||||
* @brief Get custom trace initialization parameters (optional callback)
|
||||
*
|
||||
* @note Should be called before any esp_apptrace_xxx call.
|
||||
* This is an optional callback function that user applications can implement to provide
|
||||
* custom trace configuration. A weak default implementation exists in the app_trace component
|
||||
* that returns menuconfig defaults (APPTRACE_CONFIG_DEFAULT()). User applications can override
|
||||
* this by providing their own implementation.
|
||||
*
|
||||
* This function is called during early system initialization (before app_main) on all cores.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_init(void);
|
||||
esp_apptrace_config_t esp_apptrace_get_user_params(void);
|
||||
|
||||
/**
|
||||
* @brief Configures down buffer.
|
||||
* @note Needs to be called before attempting to receive any data using esp_apptrace_down_buffer_get and esp_apptrace_read.
|
||||
* This function does not protect internal data by lock.
|
||||
*
|
||||
* @param dest Indicates HW interface to configure.
|
||||
* @param buf Address of buffer to use for down channel (host to target) data.
|
||||
* @param size Size of the buffer.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_down_buffer_config(esp_apptrace_dest_t dest, uint8_t *buf, uint32_t size);
|
||||
esp_err_t esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Allocates buffer for trace data.
|
||||
* Once the data in the buffer is ready to be sent, esp_apptrace_buffer_put must be called to indicate it.
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t tmo);
|
||||
uint8_t *esp_apptrace_buffer_get(uint32_t size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Indicates that the data in the buffer is ready to be sent.
|
||||
* This function is a counterpart of and must be preceded by esp_apptrace_buffer_get.
|
||||
*
|
||||
* @param dest Indicates HW interface to send data. Should be identical to the same parameter in call to esp_apptrace_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t tmo);
|
||||
esp_err_t esp_apptrace_buffer_put(uint8_t *ptr, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Writes data to trace buffer.
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param data Address of data to write to trace buffer.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_t size, uint32_t tmo);
|
||||
esp_err_t esp_apptrace_write(const void *data, uint32_t size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief vprintf-like function to send log messages to host via specified HW interface.
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param fmt Address of format string.
|
||||
* @param ap List of arguments.
|
||||
*
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t tmo, const char *fmt, va_list ap);
|
||||
int esp_apptrace_vprintf_to(uint32_t tmo, const char *fmt, va_list ap);
|
||||
|
||||
/**
|
||||
* @brief vprintf-like function to send log messages to host.
|
||||
@@ -106,98 +97,104 @@ int esp_apptrace_vprintf(const char *fmt, va_list ap);
|
||||
/**
|
||||
* @brief Flushes remaining data in trace buffer to host.
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t tmo);
|
||||
esp_err_t esp_apptrace_flush(uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Flushes remaining data in trace buffer to host without locking internal data.
|
||||
* This is a special version of esp_apptrace_flush which should be called from panic handler.
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. JTAG destinations only.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, uint32_t tmo);
|
||||
esp_err_t esp_apptrace_flush_nolock(uint32_t min_sz, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Reads host data from trace buffer.
|
||||
*
|
||||
* @param dest Indicates HW interface to read the data on.
|
||||
* @param data Address of buffer to put data from trace buffer.
|
||||
* @param size Pointer to store size of read data. Before call to this function pointed memory must hold requested size of data
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *data, uint32_t *size, uint32_t tmo);
|
||||
esp_err_t esp_apptrace_read(void *data, uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Retrieves incoming data buffer if any.
|
||||
* Once data in the buffer is processed, esp_apptrace_down_buffer_put must be called to indicate it.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data.
|
||||
* @param size Address to store size of available data in down buffer. Must be initialized with requested value.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t tmo);
|
||||
uint8_t *esp_apptrace_down_buffer_get(uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Indicates that the data in the down buffer is processed.
|
||||
* This function is a counterpart of and must be preceded by esp_apptrace_down_buffer_get.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data. Should be identical to the same parameter in call to esp_apptrace_down_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_down_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t tmo);
|
||||
esp_err_t esp_apptrace_down_buffer_put(uint8_t *ptr, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Checks whether host is connected.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
*
|
||||
* @return true if host is connected, otherwise false
|
||||
*/
|
||||
bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest);
|
||||
bool esp_apptrace_host_is_connected(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the destination of the application trace.
|
||||
*
|
||||
* @return The destination of the application trace.
|
||||
*/
|
||||
esp_apptrace_dest_t esp_apptrace_get_destination(void);
|
||||
|
||||
/**
|
||||
* @brief Sets the header size of the application trace packet.
|
||||
*
|
||||
* @param header_size The header size to set.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_set_header_size(esp_apptrace_header_size_t header_size);
|
||||
|
||||
/**
|
||||
* @brief Opens file on host.
|
||||
* This function has the same semantic as 'fopen' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param path Path to file.
|
||||
* @param mode Mode string. See fopen for details.
|
||||
*
|
||||
* @return non zero file handle on success, otherwise 0
|
||||
*/
|
||||
void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char *mode);
|
||||
void *esp_apptrace_fopen(const char *path, const char *mode);
|
||||
|
||||
/**
|
||||
* @brief Closes file on host.
|
||||
* This function has the same semantic as 'fclose' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
*
|
||||
* @return Zero on success, otherwise non-zero. See fclose for details.
|
||||
*/
|
||||
int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream);
|
||||
int esp_apptrace_fclose(void *stream);
|
||||
|
||||
/**
|
||||
* @brief Writes to file on host.
|
||||
* This function has the same semantic as 'fwrite' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param ptr Address of data to write.
|
||||
* @param size Size of an item.
|
||||
* @param nmemb Number of items to write.
|
||||
@@ -205,13 +202,12 @@ int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream);
|
||||
*
|
||||
* @return Number of written items. See fwrite for details.
|
||||
*/
|
||||
size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
size_t esp_apptrace_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Read file on host.
|
||||
* This function has the same semantic as 'fread' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param ptr Address to store read data.
|
||||
* @param size Size of an item.
|
||||
* @param nmemb Number of items to read.
|
||||
@@ -219,53 +215,82 @@ size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t siz
|
||||
*
|
||||
* @return Number of read items. See fread for details.
|
||||
*/
|
||||
size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
size_t esp_apptrace_fread(void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Set position indicator in file on host.
|
||||
* This function has the same semantic as 'fseek' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
* @param offset Offset. See fseek for details.
|
||||
* @param whence Position in file. See fseek for details.
|
||||
*
|
||||
* @return Zero on success, otherwise non-zero. See fseek for details.
|
||||
*/
|
||||
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence);
|
||||
int esp_apptrace_fseek(void *stream, long offset, int whence);
|
||||
|
||||
/**
|
||||
* @brief Get current position indicator for file on host.
|
||||
* This function has the same semantic as 'ftell' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
*
|
||||
* @return Current position in file. See ftell for details.
|
||||
*/
|
||||
int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream);
|
||||
int esp_apptrace_ftell(void *stream);
|
||||
|
||||
/**
|
||||
* @brief Indicates to the host that all file operations are complete.
|
||||
* This function should be called after all file operations are finished and
|
||||
* indicate to the host that it can perform cleanup operations (close open files etc.).
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
int esp_apptrace_fstop(esp_apptrace_dest_t dest);
|
||||
int esp_apptrace_fstop(void);
|
||||
|
||||
/**
|
||||
* @brief Test end-of-file indicator on a stream.
|
||||
* This function has the same semantic as 'feof' except for the first argument.
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
* @param stream File handle returned by esp_apptrace_fopen.
|
||||
*
|
||||
* @return Non-Zero if end-of-file indicator is set for stream. See feof for details.
|
||||
*/
|
||||
int esp_apptrace_feof(esp_apptrace_dest_t dest, void *stream);
|
||||
int esp_apptrace_feof(void *stream);
|
||||
|
||||
#if !CONFIG_APPTRACE_DEST_UART // JTAG or NONE
|
||||
#define APPTRACE_JTAG_CONFIG_DEFAULT() { \
|
||||
.dest = ESP_APPTRACE_DEST_JTAG, \
|
||||
.dest_cfg.jtag = {0}, \
|
||||
.panic_flush_tmo = CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO, \
|
||||
.panic_flush_thresh = CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !CONFIG_APPTRACE_DEST_JTAG // UART or NONE
|
||||
#define APPTRACE_UART_CONFIG_DEFAULT() { \
|
||||
.dest = ESP_APPTRACE_DEST_UART, \
|
||||
.dest_cfg.uart = { \
|
||||
.uart_num = CONFIG_APPTRACE_DEST_UART_NUM, \
|
||||
.tx_pin_num = CONFIG_APPTRACE_UART_TX_GPIO, \
|
||||
.rx_pin_num = CONFIG_APPTRACE_UART_RX_GPIO, \
|
||||
.baud_rate = CONFIG_APPTRACE_UART_BAUDRATE, \
|
||||
.rx_buff_size = CONFIG_APPTRACE_UART_RX_BUFF_SIZE, \
|
||||
.tx_buff_size = CONFIG_APPTRACE_UART_TX_BUFF_SIZE, \
|
||||
.tx_msg_size = CONFIG_APPTRACE_UART_TX_MSG_SIZE, \
|
||||
.task_prio = CONFIG_APPTRACE_UART_TASK_PRIO, \
|
||||
}, \
|
||||
.panic_flush_tmo = CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO, \
|
||||
.panic_flush_thresh = CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH, \
|
||||
}
|
||||
#endif
|
||||
|
||||
// Default picks JTAG if available, otherwise UART
|
||||
#if !CONFIG_APPTRACE_DEST_UART
|
||||
#define APPTRACE_CONFIG_DEFAULT() APPTRACE_JTAG_CONFIG_DEFAULT()
|
||||
#else
|
||||
#define APPTRACE_CONFIG_DEFAULT() APPTRACE_UART_CONFIG_DEFAULT()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef ESP_APP_TRACE_CONFIG_H_
|
||||
#define ESP_APP_TRACE_CONFIG_H_
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* Default configurations for runtime selection (CONFIG_APPTRACE_DEST_NONE)
|
||||
* These values are used when CONFIG_APPTRACE_DEST_NONE is selected in menuconfig.
|
||||
* To customize at runtime, implement esp_apptrace_get_user_params()
|
||||
* in your application. See esp_app_trace.h for details.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_APPTRACE_UART_TX_GPIO) || !defined(CONFIG_APPTRACE_UART_RX_GPIO)
|
||||
#include "soc/uart_pins.h"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_BUF_SIZE
|
||||
#define CONFIG_APPTRACE_BUF_SIZE 16384
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_UART_RX_BUFF_SIZE
|
||||
#define CONFIG_APPTRACE_UART_RX_BUFF_SIZE 128
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_UART_TX_BUFF_SIZE
|
||||
#define CONFIG_APPTRACE_UART_TX_BUFF_SIZE 4096
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_UART_TX_MSG_SIZE
|
||||
#define CONFIG_APPTRACE_UART_TX_MSG_SIZE 128
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_UART_BAUDRATE
|
||||
#define CONFIG_APPTRACE_UART_BAUDRATE 1000000
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_UART_TASK_PRIO
|
||||
#define CONFIG_APPTRACE_UART_TASK_PRIO 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_UART_TX_GPIO
|
||||
#define CONFIG_APPTRACE_UART_TX_GPIO U1TXD_GPIO_NUM
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_UART_RX_GPIO
|
||||
#define CONFIG_APPTRACE_UART_RX_GPIO U1RXD_GPIO_NUM
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_DEST_UART_NUM
|
||||
#define CONFIG_APPTRACE_DEST_UART_NUM 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APPTRACE_SV_DEST_CPU_0
|
||||
#define CONFIG_APPTRACE_SV_DEST_CPU_0 1
|
||||
#endif
|
||||
|
||||
#endif /* ESP_APP_TRACE_CONFIG_H_ */
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef ESP_APP_TRACE_TYPES_H_
|
||||
#define ESP_APP_TRACE_TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "spinlock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Structure which holds data necessary for measuring time intervals.
|
||||
*
|
||||
* After initialization via esp_apptrace_tmo_init() user needs to call esp_apptrace_tmo_check()
|
||||
* periodically to check timeout for expiration.
|
||||
*/
|
||||
typedef struct {
|
||||
int64_t start; ///< time interval start (in us)
|
||||
int64_t tmo; ///< timeout value (in us)
|
||||
int64_t elapsed; ///< elapsed time (in us)
|
||||
} esp_apptrace_tmo_t;
|
||||
|
||||
/** Tracing module synchronization lock */
|
||||
typedef struct {
|
||||
spinlock_t mux;
|
||||
unsigned int_state;
|
||||
} esp_apptrace_lock_t;
|
||||
|
||||
/** Ring buffer control structure.
|
||||
*
|
||||
* @note For purposes of application tracing module if there is no enough space for user data and write pointer can be wrapped
|
||||
* current ring buffer size can be temporarily shrunk in order to provide buffer with requested size.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t *data; ///< pointer to data storage
|
||||
volatile uint32_t size; ///< size of data storage
|
||||
volatile uint32_t cur_size; ///< current size of data storage
|
||||
volatile uint32_t rd; ///< read pointer
|
||||
volatile uint32_t wr; ///< write pointer
|
||||
} esp_apptrace_rb_t;
|
||||
|
||||
/**
|
||||
* Application trace data destinations
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_APPTRACE_DEST_JTAG,
|
||||
ESP_APPTRACE_DEST_UART,
|
||||
} esp_apptrace_dest_t;
|
||||
|
||||
/**
|
||||
* Application trace configuration for UART destination
|
||||
*/
|
||||
typedef struct {
|
||||
int uart_num; ///< Port number
|
||||
int tx_pin_num; ///< TX pin number
|
||||
int rx_pin_num; ///< RX pin number
|
||||
int baud_rate; ///< Baud rate
|
||||
uint32_t rx_buff_size; ///< RX ring buffer size
|
||||
uint32_t tx_buff_size; ///< TX ring buffer size
|
||||
uint32_t tx_msg_size; ///< Maximum size of the single message to transfer.
|
||||
int task_prio; ///< Task priority
|
||||
} esp_apptrace_uart_config_t;
|
||||
|
||||
/**
|
||||
* Application trace trace header size in bytes. It is 2 bytes for SEGGER SystemView
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_APPTRACE_HEADER_SIZE_16 = 2,
|
||||
ESP_APPTRACE_HEADER_SIZE_32 = 4,
|
||||
} esp_apptrace_header_size_t;
|
||||
|
||||
/**
|
||||
* Application trace configuration
|
||||
*/
|
||||
typedef struct {
|
||||
esp_apptrace_dest_t dest; ///< Destination type (JTAG or UART)
|
||||
|
||||
union {
|
||||
esp_apptrace_uart_config_t uart; ///< UART configuration (when dest is ESP_APPTRACE_DEST_UART)
|
||||
struct { ///< Reserved for JTAG (when dest is ESP_APPTRACE_DEST_JTAG)
|
||||
uint8_t _unused;
|
||||
} jtag;
|
||||
} dest_cfg; ///< Destination-specific configuration
|
||||
|
||||
uint32_t panic_flush_tmo; ///< Panic flush timeout in milliseconds
|
||||
uint32_t panic_flush_thresh; ///< Panic flush threshold in bytes
|
||||
} esp_apptrace_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ESP_APP_TRACE_TYPES_H_ */
|
||||
@@ -10,24 +10,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_app_trace_types.h"
|
||||
|
||||
/** Infinite waiting timeout */
|
||||
#define ESP_APPTRACE_TMO_INFINITE ((uint32_t)-1)
|
||||
|
||||
/** Structure which holds data necessary for measuring time intervals.
|
||||
*
|
||||
* After initialization via esp_apptrace_tmo_init() user needs to call esp_apptrace_tmo_check()
|
||||
* periodically to check timeout for expiration.
|
||||
*/
|
||||
typedef struct {
|
||||
int64_t start; ///< time interval start (in us)
|
||||
int64_t tmo; ///< timeout value (in us)
|
||||
int64_t elapsed; ///< elapsed time (in us)
|
||||
} esp_apptrace_tmo_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes timeout structure.
|
||||
*
|
||||
@@ -55,22 +44,12 @@ static inline uint32_t esp_apptrace_tmo_remaining_us(esp_apptrace_tmo_t *tmo)
|
||||
return tmo->tmo != (int64_t) -1 ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE;
|
||||
}
|
||||
|
||||
/** Tracing module synchronization lock */
|
||||
typedef struct {
|
||||
spinlock_t mux;
|
||||
unsigned int_state;
|
||||
} esp_apptrace_lock_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes lock structure.
|
||||
*
|
||||
* @param lock Pointer to lock structure to be initialized.
|
||||
*/
|
||||
static inline void esp_apptrace_lock_init(esp_apptrace_lock_t *lock)
|
||||
{
|
||||
portMUX_INITIALIZE(&lock->mux);
|
||||
lock->int_state = 0;
|
||||
}
|
||||
void esp_apptrace_lock_init(esp_apptrace_lock_t *lock);
|
||||
|
||||
/**
|
||||
* @brief Tries to acquire lock in specified time period.
|
||||
@@ -91,19 +70,6 @@ esp_err_t esp_apptrace_lock_take(esp_apptrace_lock_t *lock, esp_apptrace_tmo_t *
|
||||
*/
|
||||
esp_err_t esp_apptrace_lock_give(esp_apptrace_lock_t *lock);
|
||||
|
||||
/** Ring buffer control structure.
|
||||
*
|
||||
* @note For purposes of application tracing module if there is no enough space for user data and write pointer can be wrapped
|
||||
* current ring buffer size can be temporarily shrunk in order to provide buffer with requested size.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t *data; ///< pointer to data storage
|
||||
volatile uint32_t size; ///< size of data storage
|
||||
volatile uint32_t cur_size; ///< current size of data storage
|
||||
volatile uint32_t rd; ///< read pointer
|
||||
volatile uint32_t wr; ///< write pointer
|
||||
} esp_apptrace_rb_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes ring buffer control structure.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -18,7 +18,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief Flushes remaining data in SystemView trace buffer to host.
|
||||
*
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK.
|
||||
*/
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
[mapping:app_trace]
|
||||
archive: libapp_trace.a
|
||||
entries:
|
||||
app_trace (noflash)
|
||||
app_trace_util (noflash)
|
||||
if APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE:
|
||||
app_trace_membufs_proto (noflash)
|
||||
if APPTRACE_DEST_JTAG = y:
|
||||
port_jtag (noflash)
|
||||
if APPTRACE_DEST_UART = y:
|
||||
port_uart (noflash)
|
||||
if APPTRACE_ENABLE = y:
|
||||
app_trace (noflash)
|
||||
app_trace_util (noflash)
|
||||
if APPTRACE_DEST_JTAG = y || APPTRACE_DEST_NONE = y:
|
||||
port_jtag (noflash)
|
||||
app_trace_membufs_proto (noflash)
|
||||
if APPTRACE_DEST_UART = y || APPTRACE_DEST_NONE = y:
|
||||
port_uart (noflash)
|
||||
if APPTRACE_SV_ENABLE = y:
|
||||
SEGGER_SYSVIEW (noflash)
|
||||
SEGGER_RTT_esp (noflash)
|
||||
@@ -19,6 +19,6 @@ entries:
|
||||
archive: libesp_driver_gptimer.a
|
||||
entries:
|
||||
if APPTRACE_SV_TS_SOURCE_GPTIMER = y:
|
||||
gptimer: gptimer_get_raw_count (noflash)
|
||||
gptimer: gptimer_get_raw_count (noflash)
|
||||
else:
|
||||
* (default)
|
||||
* (default)
|
||||
|
||||
@@ -15,7 +15,7 @@ extern "C" {
|
||||
|
||||
/** Apptrace HW interface. */
|
||||
typedef struct {
|
||||
esp_err_t (*init)(void *hw_data);
|
||||
esp_err_t (*init)(void *hw_data, const esp_apptrace_config_t *config);
|
||||
uint8_t *(*get_up_buffer)(void *hw_data, uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*put_up_buffer)(void *hw_data, uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*flush_up_buffer_nolock)(void *hw_data, uint32_t, esp_apptrace_tmo_t *);
|
||||
@@ -24,6 +24,7 @@ typedef struct {
|
||||
uint8_t *(*get_down_buffer)(void *hw_data, uint32_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*put_down_buffer)(void *hw_data, uint8_t *, esp_apptrace_tmo_t *);
|
||||
bool (*host_is_connected)(void *hw_data);
|
||||
void (*set_header_size)(void *hw_data, esp_apptrace_header_size_t header_size);
|
||||
} esp_apptrace_hw_t;
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data);
|
||||
|
||||
@@ -3,19 +3,16 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "soc/soc.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_app_trace_config.h"
|
||||
#include "esp_app_trace_port.h"
|
||||
|
||||
#include "driver/uart.h"
|
||||
#include "hal/uart_ll.h"
|
||||
|
||||
#define APP_TRACE_MAX_TX_BUFF_UART CONFIG_APPTRACE_UART_TX_BUFF_SIZE
|
||||
#define APP_TRACE_MAX_TX_MSG_UART CONFIG_APPTRACE_UART_TX_MSG_SIZE
|
||||
|
||||
/** UART HW transport data */
|
||||
typedef struct {
|
||||
uint8_t inited;
|
||||
@@ -23,28 +20,34 @@ typedef struct {
|
||||
esp_apptrace_lock_t lock; // sync lock
|
||||
#endif
|
||||
uart_port_t port_num;
|
||||
// TX data ring buffer
|
||||
|
||||
/* TX data ring buffer */
|
||||
uint8_t *tx_data_buff;
|
||||
uint32_t tx_data_buff_size;
|
||||
int32_t tx_data_buff_in;
|
||||
int32_t tx_data_buff_out;
|
||||
// TX message buffer
|
||||
|
||||
/* TX message buffer */
|
||||
uint8_t *tx_msg_buff;
|
||||
uint32_t tx_msg_buff_size;
|
||||
uint32_t tx_pending_msg_size;
|
||||
|
||||
// RX message buffer
|
||||
/* RX message buffer */
|
||||
uint8_t *down_buffer;
|
||||
uint32_t down_buffer_size;
|
||||
// Buffer overflow flags
|
||||
|
||||
/* Buffer overflow flags */
|
||||
bool message_buff_overflow;
|
||||
bool circular_buff_overflow;
|
||||
} esp_apptrace_uart_data_t;
|
||||
|
||||
const static char *TAG = "esp_apptrace_uart";
|
||||
|
||||
static esp_err_t esp_apptrace_uart_lock(esp_apptrace_uart_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_uart_lock(void *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_err_t ret = esp_apptrace_lock_take(&hw_data->lock, tmo);
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
esp_err_t ret = esp_apptrace_lock_take(&uart_data->lock, tmo);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -52,11 +55,12 @@ static esp_err_t esp_apptrace_uart_lock(esp_apptrace_uart_data_t *hw_data, esp_a
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_uart_unlock(esp_apptrace_uart_data_t *hw_data)
|
||||
static esp_err_t esp_apptrace_uart_unlock(void *hw_data)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
ret = esp_apptrace_lock_give(&hw_data->lock);
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
ret = esp_apptrace_lock_give(&uart_data->lock);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -70,58 +74,69 @@ static inline void esp_apptrace_uart_hw_init(void)
|
||||
/***************************** Apptrace HW iface *****************************************/
|
||||
/*****************************************************************************************/
|
||||
|
||||
static esp_err_t esp_apptrace_send_uart_data(esp_apptrace_uart_data_t *hw_data, const char *data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_send_uart_data(void *hw_data, const char *data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
esp_err_t res = esp_apptrace_uart_lock(hw_data, tmo);
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}
|
||||
// We store current out position to handle it without lock
|
||||
volatile int32_t out_position = hw_data->tx_data_buff_out;
|
||||
volatile int32_t out_position = uart_data->tx_data_buff_out;
|
||||
|
||||
int len_free = APP_TRACE_MAX_TX_BUFF_UART - (hw_data->tx_data_buff_in - out_position);
|
||||
if (out_position > hw_data->tx_data_buff_in) {
|
||||
len_free = out_position - hw_data->tx_data_buff_in;
|
||||
int len_free = uart_data->tx_data_buff_size - (uart_data->tx_data_buff_in - out_position);
|
||||
if (out_position > uart_data->tx_data_buff_in) {
|
||||
len_free = out_position - uart_data->tx_data_buff_in;
|
||||
}
|
||||
int check_len = APP_TRACE_MAX_TX_BUFF_UART - hw_data->tx_data_buff_in;
|
||||
int check_len = uart_data->tx_data_buff_size - uart_data->tx_data_buff_in;
|
||||
if (size <= len_free) {
|
||||
if (check_len >= size) {
|
||||
memcpy(&hw_data->tx_data_buff[hw_data->tx_data_buff_in], data, size);
|
||||
hw_data->tx_data_buff_in += size;
|
||||
memcpy(&uart_data->tx_data_buff[uart_data->tx_data_buff_in], data, size);
|
||||
uart_data->tx_data_buff_in += size;
|
||||
} else {
|
||||
memcpy(&hw_data->tx_data_buff[hw_data->tx_data_buff_in], data, APP_TRACE_MAX_TX_BUFF_UART - hw_data->tx_data_buff_in);
|
||||
memcpy(&hw_data->tx_data_buff[0], &data[APP_TRACE_MAX_TX_BUFF_UART - hw_data->tx_data_buff_in], size - (APP_TRACE_MAX_TX_BUFF_UART - hw_data->tx_data_buff_in));
|
||||
hw_data->tx_data_buff_in = size - (APP_TRACE_MAX_TX_BUFF_UART - hw_data->tx_data_buff_in);
|
||||
memcpy(&uart_data->tx_data_buff[uart_data->tx_data_buff_in],
|
||||
data,
|
||||
uart_data->tx_data_buff_size - uart_data->tx_data_buff_in);
|
||||
memcpy(&uart_data->tx_data_buff[0],
|
||||
&data[uart_data->tx_data_buff_size - uart_data->tx_data_buff_in],
|
||||
size - (uart_data->tx_data_buff_size - uart_data->tx_data_buff_in));
|
||||
uart_data->tx_data_buff_in = size - (uart_data->tx_data_buff_size - uart_data->tx_data_buff_in);
|
||||
}
|
||||
if (hw_data->tx_data_buff_in >= APP_TRACE_MAX_TX_BUFF_UART) {
|
||||
hw_data->tx_data_buff_in = 0;
|
||||
if (uart_data->tx_data_buff_in >= uart_data->tx_data_buff_size) {
|
||||
uart_data->tx_data_buff_in = 0;
|
||||
}
|
||||
} else {
|
||||
hw_data->circular_buff_overflow = true;
|
||||
uart_data->circular_buff_overflow = true;
|
||||
}
|
||||
|
||||
if (esp_apptrace_uart_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_uart_unlock(uart_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void send_buff_data(esp_apptrace_uart_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
static void send_buff_data(void *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (hw_data->tx_data_buff_in == hw_data->tx_data_buff_out) {
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
|
||||
if (uart_data->tx_data_buff_in == uart_data->tx_data_buff_out) {
|
||||
return;
|
||||
}
|
||||
// We store current in position to handle it without lock
|
||||
volatile int32_t in_position = hw_data->tx_data_buff_in;
|
||||
if (in_position > hw_data->tx_data_buff_out) {
|
||||
int bytes_sent = uart_write_bytes(hw_data->port_num, &hw_data->tx_data_buff[hw_data->tx_data_buff_out], in_position - hw_data->tx_data_buff_out);
|
||||
hw_data->tx_data_buff_out += bytes_sent;
|
||||
volatile int32_t in_position = uart_data->tx_data_buff_in;
|
||||
if (in_position > uart_data->tx_data_buff_out) {
|
||||
int bytes_sent = uart_write_bytes(uart_data->port_num,
|
||||
&uart_data->tx_data_buff[uart_data->tx_data_buff_out],
|
||||
in_position - uart_data->tx_data_buff_out);
|
||||
uart_data->tx_data_buff_out += bytes_sent;
|
||||
} else {
|
||||
int bytes_sent = uart_write_bytes(hw_data->port_num, &hw_data->tx_data_buff[hw_data->tx_data_buff_out], APP_TRACE_MAX_TX_BUFF_UART - hw_data->tx_data_buff_out);
|
||||
hw_data->tx_data_buff_out += bytes_sent;
|
||||
if (hw_data->tx_data_buff_out >= APP_TRACE_MAX_TX_BUFF_UART) {
|
||||
hw_data->tx_data_buff_out = 0;
|
||||
int bytes_sent = uart_write_bytes(uart_data->port_num,
|
||||
&uart_data->tx_data_buff[uart_data->tx_data_buff_out],
|
||||
uart_data->tx_data_buff_size - uart_data->tx_data_buff_out);
|
||||
uart_data->tx_data_buff_out += bytes_sent;
|
||||
if (uart_data->tx_data_buff_out >= uart_data->tx_data_buff_size) {
|
||||
uart_data->tx_data_buff_out = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,20 +145,21 @@ static void send_buff_data(esp_apptrace_uart_data_t *hw_data, esp_apptrace_tmo_t
|
||||
|
||||
static void esp_apptrace_send_uart_tx_task(void *arg)
|
||||
{
|
||||
esp_apptrace_uart_data_t *hw_data = (esp_apptrace_uart_data_t *)arg;
|
||||
esp_apptrace_uart_data_t *uart_data = arg;
|
||||
esp_apptrace_tmo_t tmo;
|
||||
|
||||
esp_apptrace_tmo_init(&tmo, APP_TRACE_UART_STOP_WAIT_TMO);
|
||||
|
||||
vTaskDelay(10);
|
||||
while (1) {
|
||||
send_buff_data(hw_data, &tmo);
|
||||
send_buff_data(uart_data, &tmo);
|
||||
vTaskDelay(10);
|
||||
if (hw_data->circular_buff_overflow == true) {
|
||||
hw_data->circular_buff_overflow = false;
|
||||
if (uart_data->circular_buff_overflow == true) {
|
||||
uart_data->circular_buff_overflow = false;
|
||||
ESP_LOGE(TAG, "Buffer overflow. Please increase UART baudrate, or increase UART TX ring buffer size in menuconfig.");
|
||||
}
|
||||
if (hw_data->message_buff_overflow == true) {
|
||||
hw_data->message_buff_overflow = false;
|
||||
if (uart_data->message_buff_overflow == true) {
|
||||
uart_data->message_buff_overflow = false;
|
||||
ESP_LOGE(TAG, "Message size more then message buffer!");
|
||||
}
|
||||
}
|
||||
@@ -151,157 +167,181 @@ static void esp_apptrace_send_uart_tx_task(void *arg)
|
||||
|
||||
static const int APP_TRACE_UART_RX_BUF_SIZE = 4024;
|
||||
|
||||
static esp_err_t esp_apptrace_uart_init(esp_apptrace_uart_data_t *hw_data)
|
||||
static esp_err_t esp_apptrace_uart_init(void *hw_data, const esp_apptrace_config_t *config)
|
||||
{
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
const esp_apptrace_uart_config_t *apptrace_uart_config = &config->dest_cfg.uart;
|
||||
|
||||
/* esp_apptrace_uart_init() is called on every core, so ensure to do main initialization only once */
|
||||
int core_id = esp_cpu_get_core_id();
|
||||
if (core_id == 0) {
|
||||
hw_data->tx_data_buff = (uint8_t *)heap_caps_malloc(APP_TRACE_MAX_TX_BUFF_UART, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (hw_data->tx_data_buff == NULL) {
|
||||
uart_data->tx_data_buff_size = apptrace_uart_config->tx_buff_size;
|
||||
uart_data->tx_data_buff = heap_caps_malloc(uart_data->tx_data_buff_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (uart_data->tx_data_buff == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
hw_data->tx_data_buff_in = 0;
|
||||
hw_data->tx_data_buff_out = 0;
|
||||
hw_data->tx_msg_buff = (uint8_t *)heap_caps_malloc(APP_TRACE_MAX_TX_MSG_UART, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (hw_data->tx_msg_buff == NULL) {
|
||||
uart_data->tx_data_buff_in = 0;
|
||||
uart_data->tx_data_buff_out = 0;
|
||||
uart_data->tx_msg_buff_size = apptrace_uart_config->tx_msg_size;
|
||||
uart_data->tx_msg_buff = heap_caps_malloc(uart_data->tx_msg_buff_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (uart_data->tx_msg_buff == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
hw_data->tx_msg_buff_size = 0;
|
||||
hw_data->down_buffer_size = 0;
|
||||
hw_data->message_buff_overflow = false;
|
||||
hw_data->circular_buff_overflow = false;
|
||||
uart_data->tx_pending_msg_size = 0;
|
||||
uart_data->down_buffer_size = 0;
|
||||
uart_data->message_buff_overflow = false;
|
||||
uart_data->circular_buff_overflow = false;
|
||||
|
||||
assert((hw_data->port_num <= SOC_UART_NUM) && "Not possible to configure UART. Please check selected UART port");
|
||||
assert((uart_data->port_num <= SOC_UART_NUM) && "Not possible to configure UART. Please check selected UART port");
|
||||
|
||||
int source_clk = UART_SCLK_DEFAULT;
|
||||
#if SOC_UART_LP_NUM > 0
|
||||
if (hw_data->port_num >= SOC_UART_HP_NUM) {
|
||||
if (uart_data->port_num >= SOC_UART_HP_NUM) {
|
||||
source_clk = LP_UART_SCLK_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
const uart_config_t uart_config = {
|
||||
.baud_rate = CONFIG_APPTRACE_UART_BAUDRATE,
|
||||
.baud_rate = apptrace_uart_config->baud_rate,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.source_clk = source_clk,
|
||||
};
|
||||
ESP_LOGI(TAG, "UART baud rate: %i", CONFIG_APPTRACE_UART_BAUDRATE);
|
||||
ESP_LOGI(TAG, "UART baud rate: %i", apptrace_uart_config->baud_rate);
|
||||
// We won't use a buffer for sending data.
|
||||
esp_err_t err = uart_driver_install(hw_data->port_num, APP_TRACE_UART_RX_BUF_SIZE, APP_TRACE_UART_RX_BUF_SIZE, 0, NULL, 0);
|
||||
assert((err == ESP_OK) && "Not possible to install UART. Please check and change menuconfig parameters!");
|
||||
err = uart_param_config(hw_data->port_num, &uart_config);
|
||||
assert((err == ESP_OK) && "Not possible to configure UART. Please check and change menuconfig parameters!");
|
||||
err = uart_set_pin(hw_data->port_num, CONFIG_APPTRACE_UART_TX_GPIO, CONFIG_APPTRACE_UART_RX_GPIO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
assert((err == ESP_OK) && "Not possible to configure UART RX/TX pins. Please check and change menuconfig parameters!");
|
||||
esp_err_t __attribute__((unused)) err = uart_driver_install(uart_data->port_num,
|
||||
APP_TRACE_UART_RX_BUF_SIZE,
|
||||
APP_TRACE_UART_RX_BUF_SIZE,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
assert((err == ESP_OK) && "Not possible to install UART. Please check and change uart parameters!");
|
||||
err = uart_param_config(uart_data->port_num, &uart_config);
|
||||
assert((err == ESP_OK) && "Not possible to configure UART. Please check and change uart parameters!");
|
||||
err = uart_set_pin(uart_data->port_num,
|
||||
apptrace_uart_config->tx_pin_num,
|
||||
apptrace_uart_config->rx_pin_num,
|
||||
UART_PIN_NO_CHANGE,
|
||||
UART_PIN_NO_CHANGE);
|
||||
assert((err == ESP_OK) && "Not possible to configure UART RX/TX pins. Please check and change the uart pins!");
|
||||
|
||||
int uart_prio = CONFIG_APPTRACE_UART_TASK_PRIO;
|
||||
int uart_prio = apptrace_uart_config->task_prio;
|
||||
if (uart_prio >= (configMAX_PRIORITIES - 1)) {
|
||||
uart_prio = configMAX_PRIORITIES - 1;
|
||||
}
|
||||
err = xTaskCreate(esp_apptrace_send_uart_tx_task, "app_trace_uart_tx_task", 2500, hw_data, uart_prio, NULL);
|
||||
err = xTaskCreate(esp_apptrace_send_uart_tx_task, "app_trace_uart_tx_task", 2500, uart_data, uart_prio, NULL);
|
||||
assert((err == pdPASS) && "Not possible to configure UART. Not possible to create task!");
|
||||
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_apptrace_lock_init(&hw_data->lock);
|
||||
esp_apptrace_lock_init(&uart_data->lock);
|
||||
#endif
|
||||
}
|
||||
// init UART on this CPU
|
||||
esp_apptrace_uart_hw_init();
|
||||
hw_data->inited |= 1 << core_id;
|
||||
uart_data->inited |= 1 << core_id;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_uart_up_buffer_get(esp_apptrace_uart_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
static uint8_t *esp_apptrace_uart_up_buffer_get(void *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
if (size > APP_TRACE_MAX_TX_MSG_UART) {
|
||||
hw_data->message_buff_overflow = true;
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
|
||||
if (size > uart_data->tx_msg_buff_size) {
|
||||
uart_data->message_buff_overflow = true;
|
||||
return NULL;
|
||||
}
|
||||
if (hw_data->tx_msg_buff_size != 0) {
|
||||
if (uart_data->tx_pending_msg_size != 0) {
|
||||
// A previous message was not sent.
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_uart_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = hw_data->tx_msg_buff;
|
||||
hw_data->tx_msg_buff_size = size;
|
||||
uint8_t *ptr = uart_data->tx_msg_buff;
|
||||
|
||||
// Set the amount of data to send
|
||||
uart_data->tx_pending_msg_size = size;
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_uart_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_uart_unlock(uart_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_uart_up_buffer_put(esp_apptrace_uart_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_uart_up_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
esp_err_t res = esp_apptrace_send_uart_data(hw_data, (const char *)ptr, hw_data->tx_msg_buff_size, tmo);
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
esp_err_t res = esp_apptrace_send_uart_data(uart_data, (const char *)ptr, uart_data->tx_pending_msg_size, tmo);
|
||||
// Clear size to indicate that we've sent data
|
||||
hw_data->tx_msg_buff_size = 0;
|
||||
uart_data->tx_pending_msg_size = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void esp_apptrace_uart_down_buffer_config(esp_apptrace_uart_data_t *hw_data, uint8_t *buf, uint32_t size)
|
||||
static void esp_apptrace_uart_down_buffer_config(void *hw_data, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
hw_data->down_buffer = (uint8_t *)malloc(size);
|
||||
if (hw_data->down_buffer == NULL) {
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
|
||||
uart_data->down_buffer = (uint8_t *)malloc(size);
|
||||
if (uart_data->down_buffer == NULL) {
|
||||
assert(false && "Failed to allocate apptrace uart down buffer!");
|
||||
}
|
||||
hw_data->down_buffer_size = size;
|
||||
uart_data->down_buffer_size = size;
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_uart_down_buffer_get(esp_apptrace_uart_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
static uint8_t *esp_apptrace_uart_down_buffer_get(void *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
uint8_t *ptr = NULL;
|
||||
|
||||
if (*size > hw_data->down_buffer_size) {
|
||||
if (*size > uart_data->down_buffer_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t res = esp_apptrace_uart_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_uart_lock(uart_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t uart_fifolen = 0;
|
||||
uart_get_buffered_data_len(hw_data->port_num, &uart_fifolen);
|
||||
uart_get_buffered_data_len(uart_data->port_num, &uart_fifolen);
|
||||
if (uart_fifolen > 0) {
|
||||
if (*size < uart_fifolen) {
|
||||
uart_fifolen = *size;
|
||||
}
|
||||
*size = uart_fifolen;
|
||||
ptr = hw_data->down_buffer;
|
||||
*size = uart_read_bytes(hw_data->port_num, ptr, uart_fifolen, 0);
|
||||
ptr = uart_data->down_buffer;
|
||||
*size = uart_read_bytes(uart_data->port_num, ptr, uart_fifolen, 0);
|
||||
}
|
||||
|
||||
if (esp_apptrace_uart_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_uart_unlock(uart_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_uart_down_buffer_put(esp_apptrace_uart_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_uart_down_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_uart_host_is_connected(esp_apptrace_uart_data_t *hw_data)
|
||||
static bool esp_apptrace_uart_host_is_connected(void *hw_data)
|
||||
{
|
||||
return hw_data->inited & 1;
|
||||
esp_apptrace_uart_data_t *uart_data = hw_data;
|
||||
|
||||
return uart_data->inited & 1;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_uart_flush_nolock(esp_apptrace_uart_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_uart_flush_nolock(void *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_uart_flush(esp_apptrace_uart_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_uart_flush(void *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -312,15 +352,15 @@ esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data)
|
||||
|
||||
static esp_apptrace_uart_data_t s_uart_hw_data;
|
||||
static esp_apptrace_hw_t s_uart_hw = {
|
||||
.init = (esp_err_t (*)(void *))esp_apptrace_uart_init,
|
||||
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_uart_up_buffer_get,
|
||||
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_up_buffer_put,
|
||||
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_uart_flush_nolock,
|
||||
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_uart_flush,
|
||||
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_uart_down_buffer_config,
|
||||
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_down_buffer_get,
|
||||
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_down_buffer_put,
|
||||
.host_is_connected = (bool (*)(void *))esp_apptrace_uart_host_is_connected,
|
||||
.init = esp_apptrace_uart_init,
|
||||
.get_up_buffer = esp_apptrace_uart_up_buffer_get,
|
||||
.put_up_buffer = esp_apptrace_uart_up_buffer_put,
|
||||
.flush_up_buffer_nolock = esp_apptrace_uart_flush_nolock,
|
||||
.flush_up_buffer = esp_apptrace_uart_flush,
|
||||
.down_buffer_config = esp_apptrace_uart_down_buffer_config,
|
||||
.get_down_buffer = esp_apptrace_uart_down_buffer_get,
|
||||
.put_down_buffer = esp_apptrace_uart_down_buffer_put,
|
||||
.host_is_connected = esp_apptrace_uart_host_is_connected,
|
||||
};
|
||||
s_uart_hw_data.port_num = num;
|
||||
*data = &s_uart_hw_data;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_app_trace_config.h"
|
||||
#include "esp_app_trace_membufs_proto.h"
|
||||
#include "esp_app_trace_port.h"
|
||||
#include "riscv/semihosting.h"
|
||||
@@ -74,10 +75,11 @@ __attribute__((weak)) void esp_apptrace_get_up_buffers(esp_apptrace_mem_block_t
|
||||
mem_blocks_cfg[1].sz = CONFIG_APPTRACE_BUF_SIZE;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_lock(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_riscv_lock(void *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_err_t ret = esp_apptrace_lock_take(&hw_data->lock, tmo);
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
esp_err_t ret = esp_apptrace_lock_take(&riscv_data->lock, tmo);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -85,11 +87,12 @@ static esp_err_t esp_apptrace_riscv_lock(esp_apptrace_riscv_data_t *hw_data, esp
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_unlock(esp_apptrace_riscv_data_t *hw_data)
|
||||
static esp_err_t esp_apptrace_riscv_unlock(void *hw_data)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
ret = esp_apptrace_lock_give(&hw_data->lock);
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
ret = esp_apptrace_lock_give(&riscv_data->lock);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -98,89 +101,96 @@ static esp_err_t esp_apptrace_riscv_unlock(esp_apptrace_riscv_data_t *hw_data)
|
||||
/***************************** Apptrace HW iface *****************************************/
|
||||
/*****************************************************************************************/
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_init(esp_apptrace_riscv_data_t *hw_data)
|
||||
static esp_err_t esp_apptrace_riscv_init(void *hw_data, const esp_apptrace_config_t *config)
|
||||
{
|
||||
int core_id = esp_cpu_get_core_id();
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (hw_data->inited == 0) {
|
||||
/* esp_apptrace_riscv_init() is called on every core, so ensure to do main initialization only once */
|
||||
int core_id = esp_cpu_get_core_id();
|
||||
if (core_id == 0) {
|
||||
esp_apptrace_mem_block_t mem_blocks_cfg[2];
|
||||
esp_apptrace_get_up_buffers(mem_blocks_cfg);
|
||||
esp_err_t res = esp_apptrace_membufs_init(&hw_data->membufs, mem_blocks_cfg);
|
||||
riscv_data->membufs.header_size = ESP_APPTRACE_HEADER_SIZE_32;
|
||||
esp_err_t res = esp_apptrace_membufs_init(&riscv_data->membufs, mem_blocks_cfg);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to init membufs proto (%d)!", res);
|
||||
return res;
|
||||
}
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_apptrace_lock_init(&hw_data->lock);
|
||||
esp_apptrace_lock_init(&riscv_data->lock);
|
||||
#endif
|
||||
}
|
||||
hw_data->inited |= 1 << core_id;
|
||||
riscv_data->inited |= 1 << core_id;
|
||||
ESP_APPTRACE_LOGI("Apptrace initialized on CPU%d. Tracing control block @ %p.", core_id, &s_tracing_ctrl[core_id]);
|
||||
s_tracing_ctrl[core_id].mem_blocks = hw_data->membufs.blocks;
|
||||
s_tracing_ctrl[core_id].mem_blocks = riscv_data->membufs.blocks;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ESP_APPTRACE_LOGD("Mem buf[%d] %" PRIu32 " bytes @ %p (%p/%p)", i,
|
||||
s_tracing_ctrl[core_id].mem_blocks[i].sz, s_tracing_ctrl[core_id].mem_blocks[i].start,
|
||||
&(s_tracing_ctrl[core_id].mem_blocks[i].start), &(s_tracing_ctrl[core_id].mem_blocks[i].sz));
|
||||
}
|
||||
// notify host about control block address
|
||||
int res = esp_apptrace_advertise_ctrl_block(&s_tracing_ctrl[core_id]);
|
||||
int __attribute__((unused)) res = esp_apptrace_advertise_ctrl_block(&s_tracing_ctrl[core_id]);
|
||||
assert(res == 0 && "Failed to send config to host!");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_riscv_up_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
static uint8_t *esp_apptrace_riscv_up_buffer_get(void *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_riscv_lock(riscv_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_up_buffer_get(&hw_data->membufs, size, tmo);
|
||||
uint8_t *ptr = esp_apptrace_membufs_up_buffer_get(&riscv_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_riscv_unlock(riscv_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_up_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_riscv_up_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_up_buffer_put() just modifies buffer's header
|
||||
esp_err_t res = esp_apptrace_membufs_up_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
esp_err_t res = esp_apptrace_membufs_up_buffer_put(&riscv_data->membufs, ptr, tmo);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void esp_apptrace_riscv_down_buffer_config(esp_apptrace_riscv_data_t *hw_data, uint8_t *buf, uint32_t size)
|
||||
static void esp_apptrace_riscv_down_buffer_config(void *hw_data, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return;
|
||||
}
|
||||
esp_apptrace_membufs_down_buffer_config(&hw_data->membufs, buf, size);
|
||||
esp_apptrace_membufs_down_buffer_config(&riscv_data->membufs, buf, size);
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_riscv_down_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
static uint8_t *esp_apptrace_riscv_down_buffer_get(void *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_riscv_lock(riscv_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_down_buffer_get(&hw_data->membufs, size, tmo);
|
||||
uint8_t *ptr = esp_apptrace_membufs_down_buffer_get(&riscv_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
@@ -189,9 +199,11 @@ static uint8_t *esp_apptrace_riscv_down_buffer_get(esp_apptrace_riscv_data_t *hw
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_riscv_down_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_down_buffer_put() does nothing
|
||||
@@ -200,7 +212,7 @@ static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *h
|
||||
return res;
|
||||
}*/
|
||||
|
||||
esp_err_t res = esp_apptrace_membufs_down_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
esp_err_t res = esp_apptrace_membufs_down_buffer_put(&riscv_data->membufs, ptr, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
/*if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
@@ -209,36 +221,42 @@ static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *h
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_riscv_host_is_connected(esp_apptrace_riscv_data_t *hw_data)
|
||||
static bool esp_apptrace_riscv_host_is_connected(void *hw_data)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return false;
|
||||
}
|
||||
return s_tracing_ctrl[esp_cpu_get_core_id()].ctrl & ESP_APPTRACE_RISCV_HOST_CONNECT ? true : false;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_flush_nolock(esp_apptrace_riscv_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_riscv_flush_nolock(void *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return esp_apptrace_membufs_flush_nolock(&hw_data->membufs, min_sz, tmo);
|
||||
return esp_apptrace_membufs_flush_nolock(&riscv_data->membufs, min_sz, tmo);
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_flush(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_riscv_flush(void *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(riscv_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_riscv_lock(riscv_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = esp_apptrace_membufs_flush_nolock(&hw_data->membufs, 0, tmo);
|
||||
res = esp_apptrace_membufs_flush_nolock(&riscv_data->membufs, 0, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_riscv_unlock(riscv_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return res;
|
||||
@@ -319,6 +337,12 @@ static bool esp_apptrace_riscv_host_data_pending(void)
|
||||
return (ctrl_reg & ESP_APPTRACE_RISCV_HOST_DATA) ? true : false;
|
||||
}
|
||||
|
||||
static void esp_apptrace_riscv_set_header_size(void *hw_data, esp_apptrace_header_size_t header_size)
|
||||
{
|
||||
esp_apptrace_riscv_data_t *riscv_data = hw_data;
|
||||
riscv_data->membufs.header_size = header_size;
|
||||
}
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
|
||||
{
|
||||
static esp_apptrace_membufs_proto_hw_t s_trace_proto_hw = {
|
||||
@@ -333,15 +357,16 @@ esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
|
||||
},
|
||||
};
|
||||
static esp_apptrace_hw_t s_trace_hw = {
|
||||
.init = (esp_err_t (*)(void *))esp_apptrace_riscv_init,
|
||||
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_get,
|
||||
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_put,
|
||||
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush_nolock,
|
||||
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush,
|
||||
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_riscv_down_buffer_config,
|
||||
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_get,
|
||||
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_put,
|
||||
.host_is_connected = (bool (*)(void *))esp_apptrace_riscv_host_is_connected,
|
||||
.init = esp_apptrace_riscv_init,
|
||||
.get_up_buffer = esp_apptrace_riscv_up_buffer_get,
|
||||
.put_up_buffer = esp_apptrace_riscv_up_buffer_put,
|
||||
.flush_up_buffer_nolock = esp_apptrace_riscv_flush_nolock,
|
||||
.flush_up_buffer = esp_apptrace_riscv_flush,
|
||||
.down_buffer_config = esp_apptrace_riscv_down_buffer_config,
|
||||
.get_down_buffer = esp_apptrace_riscv_down_buffer_get,
|
||||
.put_down_buffer = esp_apptrace_riscv_down_buffer_put,
|
||||
.host_is_connected = esp_apptrace_riscv_host_is_connected,
|
||||
.set_header_size = esp_apptrace_riscv_set_header_size,
|
||||
};
|
||||
*data = &s_trace_hw_data;
|
||||
return &s_trace_hw;
|
||||
|
||||
@@ -195,10 +195,11 @@ static uint8_t * const s_trax_blocks[] = {
|
||||
(uint8_t *)TRACEMEM_BLK1_ADDR
|
||||
};
|
||||
|
||||
static esp_err_t esp_apptrace_trax_lock(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_trax_lock(void *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_err_t ret = esp_apptrace_lock_take(&hw_data->lock, tmo);
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
esp_err_t ret = esp_apptrace_lock_take(&trax_data->lock, tmo);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -206,11 +207,12 @@ static esp_err_t esp_apptrace_trax_lock(esp_apptrace_trax_data_t *hw_data, esp_a
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_unlock(esp_apptrace_trax_data_t *hw_data)
|
||||
static esp_err_t esp_apptrace_trax_unlock(void *hw_data)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
ret = esp_apptrace_lock_give(&hw_data->lock);
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
ret = esp_apptrace_lock_give(&trax_data->lock);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -262,11 +264,12 @@ static inline void esp_apptrace_trax_memory_enable(void)
|
||||
/***************************** Apptrace HW iface *****************************************/
|
||||
/*****************************************************************************************/
|
||||
|
||||
static esp_err_t esp_apptrace_trax_init(esp_apptrace_trax_data_t *hw_data)
|
||||
static esp_err_t esp_apptrace_trax_init(void *hw_data, const esp_apptrace_config_t *config)
|
||||
{
|
||||
int core_id = esp_cpu_get_core_id();
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
// 'esp_apptrace_trax_init()' is called on every core, so ensure to do main initialization only once
|
||||
int core_id = esp_cpu_get_core_id();
|
||||
if (core_id == 0) {
|
||||
esp_apptrace_mem_block_t mem_blocks_cfg[2] = {
|
||||
{
|
||||
@@ -278,87 +281,94 @@ static esp_err_t esp_apptrace_trax_init(esp_apptrace_trax_data_t *hw_data)
|
||||
.sz = ESP_APPTRACE_TRAX_BLOCK_SIZE
|
||||
},
|
||||
};
|
||||
esp_err_t res = esp_apptrace_membufs_init(&hw_data->membufs, mem_blocks_cfg);
|
||||
trax_data->membufs.header_size = ESP_APPTRACE_HEADER_SIZE_32;
|
||||
esp_err_t res = esp_apptrace_membufs_init(&trax_data->membufs, mem_blocks_cfg);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to init membufs proto (%d)!", res);
|
||||
return res;
|
||||
}
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_apptrace_lock_init(&hw_data->lock);
|
||||
esp_apptrace_lock_init(&trax_data->lock);
|
||||
#endif
|
||||
esp_apptrace_trax_memory_enable();
|
||||
esp_apptrace_trax_select_memory_block(0);
|
||||
}
|
||||
// init TRAX on this CPU
|
||||
esp_apptrace_trax_hw_init();
|
||||
hw_data->inited |= 1 << core_id;
|
||||
trax_data->inited |= 1 << core_id;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_trax_up_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
static uint8_t *esp_apptrace_trax_up_buffer_get(void *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_trax_lock(trax_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_up_buffer_get(&hw_data->membufs, size, tmo);
|
||||
uint8_t *ptr = esp_apptrace_membufs_up_buffer_get(&trax_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_trax_unlock(trax_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_up_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_trax_up_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_up_buffer_put() just modifies buffer's header
|
||||
esp_err_t res = esp_apptrace_membufs_up_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
esp_err_t res = esp_apptrace_membufs_up_buffer_put(&trax_data->membufs, ptr, tmo);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void esp_apptrace_trax_down_buffer_config(esp_apptrace_trax_data_t *hw_data, uint8_t *buf, uint32_t size)
|
||||
static void esp_apptrace_trax_down_buffer_config(void *hw_data, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return;
|
||||
}
|
||||
esp_apptrace_membufs_down_buffer_config(&hw_data->membufs, buf, size);
|
||||
esp_apptrace_membufs_down_buffer_config(&trax_data->membufs, buf, size);
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_trax_down_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
static uint8_t *esp_apptrace_trax_down_buffer_get(void *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_trax_lock(trax_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_down_buffer_get(&hw_data->membufs, size, tmo);
|
||||
uint8_t *ptr = esp_apptrace_membufs_down_buffer_get(&trax_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_trax_unlock(trax_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_trax_down_buffer_put(void *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_down_buffer_put() does nothing
|
||||
@@ -367,7 +377,7 @@ static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_
|
||||
return res;
|
||||
}*/
|
||||
|
||||
esp_err_t res = esp_apptrace_membufs_down_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
esp_err_t res = esp_apptrace_membufs_down_buffer_put(&trax_data->membufs, ptr, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
/*if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
@@ -376,36 +386,42 @@ static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_trax_host_is_connected(esp_apptrace_trax_data_t *hw_data)
|
||||
static bool esp_apptrace_trax_host_is_connected(void *hw_data)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return false;
|
||||
}
|
||||
return eri_read(ESP_APPTRACE_TRAX_CTRL_REG) & ESP_APPTRACE_TRAX_HOST_CONNECT ? true : false;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_flush_nolock(esp_apptrace_trax_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_trax_flush_nolock(void *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return esp_apptrace_membufs_flush_nolock(&hw_data->membufs, min_sz, tmo);
|
||||
return esp_apptrace_membufs_flush_nolock(&trax_data->membufs, min_sz, tmo);
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_flush(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
static esp_err_t esp_apptrace_trax_flush(void *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(trax_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo);
|
||||
esp_err_t res = esp_apptrace_trax_lock(trax_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = esp_apptrace_membufs_flush_nolock(&hw_data->membufs, 0, tmo);
|
||||
res = esp_apptrace_membufs_flush_nolock(&trax_data->membufs, 0, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
if (esp_apptrace_trax_unlock(trax_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return res;
|
||||
@@ -494,6 +510,12 @@ static bool esp_apptrace_trax_host_data_pending(void)
|
||||
return (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA) ? true : false;
|
||||
}
|
||||
|
||||
static void esp_apptrace_trax_set_header_size(void *hw_data, esp_apptrace_header_size_t header_size)
|
||||
{
|
||||
esp_apptrace_trax_data_t *trax_data = hw_data;
|
||||
trax_data->membufs.header_size = header_size;
|
||||
}
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
|
||||
{
|
||||
static esp_apptrace_membufs_proto_hw_t s_trax_proto_hw = {
|
||||
@@ -508,15 +530,16 @@ esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
|
||||
},
|
||||
};
|
||||
static esp_apptrace_hw_t s_trax_hw = {
|
||||
.init = (esp_err_t (*)(void *))esp_apptrace_trax_init,
|
||||
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_get,
|
||||
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_put,
|
||||
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_flush_nolock,
|
||||
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_trax_flush,
|
||||
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_trax_down_buffer_config,
|
||||
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_get,
|
||||
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_put,
|
||||
.host_is_connected = (bool (*)(void *))esp_apptrace_trax_host_is_connected,
|
||||
.init = esp_apptrace_trax_init,
|
||||
.get_up_buffer = esp_apptrace_trax_up_buffer_get,
|
||||
.put_up_buffer = esp_apptrace_trax_up_buffer_put,
|
||||
.flush_up_buffer_nolock = esp_apptrace_trax_flush_nolock,
|
||||
.flush_up_buffer = esp_apptrace_trax_flush,
|
||||
.down_buffer_config = esp_apptrace_trax_down_buffer_config,
|
||||
.get_down_buffer = esp_apptrace_trax_down_buffer_get,
|
||||
.put_down_buffer = esp_apptrace_trax_down_buffer_put,
|
||||
.host_is_connected = esp_apptrace_trax_host_is_connected,
|
||||
.set_header_size = esp_apptrace_trax_set_header_size,
|
||||
};
|
||||
*data = &s_trax_hw_data;
|
||||
return &s_trax_hw;
|
||||
|
||||
@@ -40,6 +40,7 @@ typedef struct {
|
||||
esp_apptrace_mem_block_t blocks[2]; // memory blocks
|
||||
// ring buffer control struct for data from host (down buffer)
|
||||
esp_apptrace_rb_t rb_down;
|
||||
int header_size; ///< Size of the trace header (2 or 4 bytes)
|
||||
} esp_apptrace_membufs_proto_data_t;
|
||||
|
||||
esp_err_t esp_apptrace_membufs_init(esp_apptrace_membufs_proto_data_t *proto, const esp_apptrace_mem_block_t blocks_cfg[2]);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
|
||||
|
||||
CONFIG_ESP32_APPTRACE_DESTINATION CONFIG_APPTRACE_DESTINATION
|
||||
CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE
|
||||
CONFIG_ESP32_APPTRACE_DEST_TRAX CONFIG_APPTRACE_DEST_JTAG
|
||||
CONFIG_ESP32_APPTRACE_ENABLE CONFIG_APPTRACE_ENABLE
|
||||
CONFIG_ESP32_APPTRACE_LOCK_ENABLE CONFIG_APPTRACE_LOCK_ENABLE
|
||||
|
||||
@@ -32,19 +32,12 @@ static uint8_t s_events_buf[SYSVIEW_EVENTS_BUF_SZ];
|
||||
static uint16_t s_events_buf_filled;
|
||||
static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE];
|
||||
|
||||
#if CONFIG_APPTRACE_SV_DEST_UART
|
||||
|
||||
#define ESP_APPTRACE_DEST_SYSVIEW ESP_APPTRACE_DEST_UART
|
||||
#if CONFIG_APPTRACE_SV_DEST_CPU_0 || CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
#define APPTRACE_SV_DEST_CPU 0
|
||||
#else
|
||||
#define APPTRACE_SV_DEST_CPU 1
|
||||
#endif // CONFIG_APPTRACE_SV_DEST_CPU_0
|
||||
|
||||
#elif CONFIG_APPTRACE_SV_DEST_JTAG || (CONFIG_APPTRACE_ENABLE && CONFIG_APPTRACE_DEST_UART_NONE)
|
||||
#define ESP_APPTRACE_DEST_SYSVIEW ESP_APPTRACE_DEST_JTAG
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Public code
|
||||
@@ -70,13 +63,13 @@ void SEGGER_RTT_ESP_FlushNoLock(unsigned long min_sz, unsigned long tmo)
|
||||
{
|
||||
esp_err_t res;
|
||||
if (s_events_buf_filled > 0) {
|
||||
res = esp_apptrace_write(ESP_APPTRACE_DEST_SYSVIEW, s_events_buf, s_events_buf_filled, tmo);
|
||||
res = esp_apptrace_write(s_events_buf, s_events_buf_filled, tmo);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to flush buffered events (%d)!", res);
|
||||
}
|
||||
}
|
||||
// flush even if we failed to write buffered events, because no new events will be sent after STOP
|
||||
res = esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_SYSVIEW, min_sz, tmo);
|
||||
res = esp_apptrace_flush_nolock(min_sz, tmo);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to flush apptrace data (%d)!", res);
|
||||
}
|
||||
@@ -124,7 +117,7 @@ void SEGGER_RTT_ESP_Flush(unsigned long min_sz, unsigned long tmo)
|
||||
unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize)
|
||||
{
|
||||
uint32_t size = BufferSize;
|
||||
esp_err_t res = esp_apptrace_read(ESP_APPTRACE_DEST_SYSVIEW, pData, &size, 0);
|
||||
esp_err_t res = esp_apptrace_read(pData, &size, 0);
|
||||
if (res != ESP_OK) {
|
||||
return 0;
|
||||
}
|
||||
@@ -159,70 +152,70 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
{
|
||||
uint8_t *pbuf = (uint8_t *)pBuffer;
|
||||
uint8_t event_id = *pbuf;
|
||||
#if CONFIG_APPTRACE_SV_DEST_UART
|
||||
if (
|
||||
(APPTRACE_SV_DEST_CPU != esp_cpu_get_core_id()) &&
|
||||
(
|
||||
(event_id == SYSVIEW_EVTID_ISR_ENTER) ||
|
||||
(event_id == SYSVIEW_EVTID_ISR_EXIT) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_START_EXEC) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_STOP_EXEC) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_START_READY) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_STOP_READY) ||
|
||||
(event_id == SYSVIEW_EVTID_MARK_START) ||
|
||||
(event_id == SYSVIEW_EVTID_MARK_STOP) ||
|
||||
(event_id == SYSVIEW_EVTID_TIMER_ENTER) ||
|
||||
(event_id == SYSVIEW_EVTID_TIMER_EXIT) ||
|
||||
(event_id == SYSVIEW_EVTID_STACK_INFO) ||
|
||||
(event_id == SYSVIEW_EVTID_MODULEDESC)
|
||||
)
|
||||
) {
|
||||
return NumBytes;
|
||||
}
|
||||
|
||||
// This is workaround for SystemView!
|
||||
// Without this line SystemView will hangs on when heap tracing enabled.
|
||||
if (event_id == SYSVIEW_EVTID_MODULEDESC) {
|
||||
return NumBytes;
|
||||
if (esp_apptrace_get_destination() == ESP_APPTRACE_DEST_UART) {
|
||||
if (
|
||||
(APPTRACE_SV_DEST_CPU != esp_cpu_get_core_id()) &&
|
||||
(
|
||||
(event_id == SYSVIEW_EVTID_ISR_ENTER) ||
|
||||
(event_id == SYSVIEW_EVTID_ISR_EXIT) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_START_EXEC) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_STOP_EXEC) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_START_READY) ||
|
||||
(event_id == SYSVIEW_EVTID_TASK_STOP_READY) ||
|
||||
(event_id == SYSVIEW_EVTID_MARK_START) ||
|
||||
(event_id == SYSVIEW_EVTID_MARK_STOP) ||
|
||||
(event_id == SYSVIEW_EVTID_TIMER_ENTER) ||
|
||||
(event_id == SYSVIEW_EVTID_TIMER_EXIT) ||
|
||||
(event_id == SYSVIEW_EVTID_STACK_INFO) ||
|
||||
(event_id == SYSVIEW_EVTID_MODULEDESC)
|
||||
)
|
||||
) {
|
||||
return NumBytes;
|
||||
}
|
||||
|
||||
// This is workaround for SystemView!
|
||||
// Without this line SystemView will hangs on when heap tracing enabled.
|
||||
if (event_id == SYSVIEW_EVTID_MODULEDESC) {
|
||||
return NumBytes;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_APPTRACE_SV_DEST_UART
|
||||
|
||||
if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
|
||||
return 0;
|
||||
}
|
||||
#if CONFIG_APPTRACE_SV_DEST_JTAG
|
||||
if (esp_cpu_get_core_id()) { // dual core specific code
|
||||
// use the highest - 1 bit of event ID to indicate core ID
|
||||
// the highest bit can not be used due to event ID encoding method
|
||||
// this reduces supported ID range to [0..63] (for 1 byte IDs) plus [128..16383] (for 2 bytes IDs)
|
||||
if (*pbuf & 0x80) { // 2 bytes ID
|
||||
*(pbuf + 1) |= (1 << 6);
|
||||
} else if (NumBytes != 10 || *pbuf != 0) { // ignore sync sequence
|
||||
*pbuf |= (1 << 6);
|
||||
if (esp_apptrace_get_destination() == ESP_APPTRACE_DEST_JTAG) {
|
||||
if (esp_cpu_get_core_id()) { // dual core specific code
|
||||
// use the highest - 1 bit of event ID to indicate core ID
|
||||
// the highest bit can not be used due to event ID encoding method
|
||||
// this reduces supported ID range to [0..63] (for 1 byte IDs) plus [128..16383] (for 2 bytes IDs)
|
||||
if (*pbuf & 0x80) { // 2 bytes ID
|
||||
*(pbuf + 1) |= (1 << 6);
|
||||
} else if (NumBytes != 10 || *pbuf != 0) { // ignore sync sequence
|
||||
*pbuf |= (1 << 6);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_events_buf_filled + NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
|
||||
esp_err_t res = esp_apptrace_write(s_events_buf, s_events_buf_filled, SEGGER_HOST_WAIT_TMO);
|
||||
if (res != ESP_OK) {
|
||||
return 0; // skip current data buffer only, accumulated events are kept
|
||||
}
|
||||
s_events_buf_filled = 0;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_APPTRACE_SV_DEST_JTAG
|
||||
#if CONFIG_APPTRACE_SV_DEST_JTAG
|
||||
if (s_events_buf_filled + NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
memcpy(&s_events_buf[s_events_buf_filled], pBuffer, NumBytes);
|
||||
s_events_buf_filled += NumBytes;
|
||||
|
||||
esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_SYSVIEW, s_events_buf, s_events_buf_filled, SEGGER_HOST_WAIT_TMO);
|
||||
if (esp_apptrace_get_destination() == ESP_APPTRACE_DEST_UART) {
|
||||
esp_err_t res = esp_apptrace_write(pBuffer, NumBytes, SEGGER_HOST_WAIT_TMO);
|
||||
if (res != ESP_OK) {
|
||||
return 0; // skip current data buffer only, accumulated events are kept
|
||||
}
|
||||
s_events_buf_filled = 0;
|
||||
}
|
||||
#endif
|
||||
memcpy(&s_events_buf[s_events_buf_filled], pBuffer, NumBytes);
|
||||
s_events_buf_filled += NumBytes;
|
||||
|
||||
#if CONFIG_APPTRACE_SV_DEST_UART
|
||||
esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_SYSVIEW, pBuffer, NumBytes, SEGGER_HOST_WAIT_TMO);
|
||||
if (res != ESP_OK) {
|
||||
return 0; // skip current data buffer only, accumulated events are kept
|
||||
}
|
||||
s_events_buf_filled = 0;
|
||||
#endif
|
||||
|
||||
if (event_id == SYSVIEW_EVTID_TRACE_STOP) {
|
||||
SEGGER_RTT_ESP_FlushNoLock(0, SEGGER_STOP_WAIT_TMO);
|
||||
@@ -288,19 +281,20 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu
|
||||
*/
|
||||
int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags)
|
||||
{
|
||||
return esp_apptrace_down_buffer_config(ESP_APPTRACE_DEST_SYSVIEW, s_down_buf, sizeof(s_down_buf));
|
||||
return esp_apptrace_down_buffer_config(s_down_buf, sizeof(s_down_buf));
|
||||
}
|
||||
|
||||
/*************************** Init hook ****************************
|
||||
*
|
||||
* This init function is placed here because this port file will be
|
||||
* linked whenever SystemView is used.
|
||||
* This init function is placed here because this port file will be linked whenever SystemView is used.
|
||||
* It is used to initialize SystemView and app trace configuration by the init hook function.
|
||||
* Otherwise, SystemView and app trace initialization needs to be done later in the app_main.
|
||||
*/
|
||||
|
||||
ESP_SYSTEM_INIT_FN(sysview_init, SECONDARY, BIT(0), 120)
|
||||
ESP_SYSTEM_INIT_FN(sysview_early_init, SECONDARY, BIT(0), 120)
|
||||
{
|
||||
esp_apptrace_set_header_size(ESP_APPTRACE_HEADER_SIZE_16);
|
||||
SEGGER_SYSVIEW_Conf();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -9,6 +9,6 @@ components/app_trace/test_apps:
|
||||
- esp_driver_uart
|
||||
- esp_driver_gptimer
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c5", "esp32c61", "esp32h21", "esp32h4"]
|
||||
- if: IDF_TARGET in ["esp32h21", "esp32h4"]
|
||||
temporary: true
|
||||
reason: not support yet # TODO: [ESP32C5] IDF-8705, [ESP32C61] IDF-9306, [ESP32H21] IDF-11539 [ESP32H4] IDF-12325
|
||||
reason: not support yet # TODO: [ESP32H21] IDF-11539 [ESP32H4] IDF-12325
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# app_trace test
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,16 +17,15 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#include "esp_log.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_app_trace_util.h"
|
||||
|
||||
#define ESP_APPTRACE_TEST_USE_PRINT_LOCK 0
|
||||
#define ESP_APPTRACE_TEST_PRN_WRERR_MAX 5
|
||||
#define ESP_APPTRACE_TEST_BLOCKS_BEFORE_CRASH 100
|
||||
#define ESP_APPTRACE_TEST_BLOCK_SIZE 1024
|
||||
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_apptrace_test";
|
||||
|
||||
#if ESP_APPTRACE_TEST_USE_PRINT_LOCK == 1
|
||||
@@ -67,9 +66,9 @@ const static char *TAG = "esp_apptrace_test";
|
||||
#define ESP_APPTRACE_TEST_LOGO( format, ... ) ESP_APPTRACE_TEST_LOG_LEVEL(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE == 0
|
||||
#define ESP_APPTRACE_TEST_WRITE(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_JTAG, _b_, _s_, ESP_APPTRACE_TMO_INFINITE)
|
||||
#define ESP_APPTRACE_TEST_WRITE_FROM_ISR(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_JTAG, _b_, _s_, 0UL)
|
||||
#define ESP_APPTRACE_TEST_WRITE_NOWAIT(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_JTAG, _b_, _s_, 0)
|
||||
#define ESP_APPTRACE_TEST_WRITE(_b_, _s_) esp_apptrace_write(_b_, _s_, ESP_APPTRACE_TMO_INFINITE)
|
||||
#define ESP_APPTRACE_TEST_WRITE_FROM_ISR(_b_, _s_) esp_apptrace_write(_b_, _s_, 0UL)
|
||||
#define ESP_APPTRACE_TEST_WRITE_NOWAIT(_b_, _s_) esp_apptrace_write(_b_, _s_, 0)
|
||||
|
||||
typedef struct {
|
||||
uint8_t *buf;
|
||||
@@ -625,7 +624,7 @@ static int esp_logtrace_printf(const char *fmt, ...)
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
int ret = esp_apptrace_vprintf_to(ESP_APPTRACE_DEST_JTAG, ESP_APPTRACE_TMO_INFINITE, fmt, ap);
|
||||
int ret = esp_apptrace_vprintf_to(ESP_APPTRACE_TMO_INFINITE, fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
@@ -657,7 +656,7 @@ static void esp_logtrace_task(void *p)
|
||||
break;
|
||||
}
|
||||
}
|
||||
esp_err_t ret = esp_apptrace_flush(ESP_APPTRACE_DEST_JTAG, ESP_APPTRACE_TMO_INFINITE);
|
||||
esp_err_t ret = esp_apptrace_flush(ESP_APPTRACE_TMO_INFINITE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to flush printf buf (%d)!", ret);
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
||||
CONFIG_APPTRACE_ENABLE=y
|
||||
CONFIG_APPTRACE_DEST_JTAG=y
|
||||
|
||||
@@ -32,7 +32,8 @@ set(COMPONENTS
|
||||
main
|
||||
efuse
|
||||
esp_libc
|
||||
esp_tee)
|
||||
esp_tee
|
||||
esp_stdio)
|
||||
|
||||
# EXTRA_COMPONENT_DIRS can be populated with directories containing one or several components.
|
||||
# Make sure this variable contains `bootloader_components` directory of the project being compiled.
|
||||
|
||||
@@ -382,13 +382,6 @@ static void IRAM_ATTR bootloader_init_flash_configure(void)
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
bootloader_init_flash_configure();
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) {
|
||||
ESP_EARLY_LOGD(TAG, "Using overridden bootloader_flash_unlock");
|
||||
|
||||
@@ -256,13 +256,6 @@ static void bootloader_spi_flash_resume(void)
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
bootloader_init_flash_configure();
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
bootloader_spi_flash_resume();
|
||||
if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) {
|
||||
|
||||
@@ -254,13 +254,6 @@ static void IRAM_ATTR bootloader_init_flash_configure(void)
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
bootloader_init_flash_configure();
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) {
|
||||
ESP_EARLY_LOGD(TAG, "Using overridden bootloader_flash_unlock");
|
||||
|
||||
@@ -272,13 +272,6 @@ static void bootloader_spi_flash_resume(void)
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
bootloader_init_flash_configure();
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_BOOTLOADER_FLASH_DC_AWARE
|
||||
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.
|
||||
|
||||
@@ -38,7 +38,7 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to
|
||||
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
|
||||
* 240 MHz may cause the chip to lock up (see CPU-3.5 of the errata
|
||||
* document). For rev. 0, switch to 240 instead if it has been enabled
|
||||
* previously.
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/apb_saradc_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_saradc.h"
|
||||
#include "hal/adc_ll.h"
|
||||
#include "hal/temperature_sensor_ll.h"
|
||||
#include "esp_private/sar_periph_ctrl.h"
|
||||
|
||||
#define ADC_RNG_CLKM_DIV_NUM 15
|
||||
#define ADC_RNG_CLKM_DIV_B 0
|
||||
#define ADC_RNG_CLKM_DIV_A 0
|
||||
|
||||
void bootloader_random_enable(void)
|
||||
{
|
||||
@@ -19,49 +21,57 @@ void bootloader_random_enable(void)
|
||||
REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0x3);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M);
|
||||
|
||||
// Bridging sar2 internal reference voltage
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
sar_periph_ctrl_adc_reset();
|
||||
#else
|
||||
tsens_ll_reg_values_t saved_tsens_regs = {};
|
||||
tsens_ll_backup_registers(&saved_tsens_regs);
|
||||
_adc_ll_reset_register();
|
||||
// Restore temperature sensor related register values after ADC reset
|
||||
_temperature_sensor_ll_reset_module();
|
||||
tsens_ll_restore_registers(&saved_tsens_regs);
|
||||
#endif
|
||||
|
||||
// Enable SAR ADC2 internal channel to read adc2 ref voltage for additional entropy
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN_M);
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST_M);
|
||||
REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 0x2);
|
||||
SET_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M);
|
||||
SET_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED_M);
|
||||
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE, 0x3);
|
||||
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_DIV, 1);
|
||||
_adc_ll_enable_bus_clock(true);
|
||||
adc_ll_enable_func_clock(true);
|
||||
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_APB);
|
||||
adc_ll_digi_controller_clk_div(ADC_RNG_CLKM_DIV_NUM, ADC_RNG_CLKM_DIV_B, ADC_RNG_CLKM_DIV_A);
|
||||
adc_ll_digi_set_power_manage(ADC_LL_POWER_SW_ON);
|
||||
adc_ll_digi_set_fsm_time(ADC_LL_FSM_RSTB_WAIT_DEFAULT, ADC_LL_FSM_START_WAIT_DEFAULT,
|
||||
ADC_LL_FSM_STANDBY_WAIT_DEFAULT);
|
||||
|
||||
REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_RSTB_WAIT, 8);
|
||||
REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_XPD_WAIT, 5);
|
||||
REG_SET_FIELD(APB_SARADC_FSM_WAIT_REG, APB_SARADC_STANDBY_WAIT, 100);
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
regi2c_saradc_enable();
|
||||
#else
|
||||
regi2c_ctrl_ll_i2c_sar_periph_enable();
|
||||
#endif
|
||||
// enable analog i2c master clock for RNG runtime
|
||||
ANALOG_CLOCK_ENABLE();
|
||||
adc_ll_regi2c_init();
|
||||
|
||||
SET_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M);
|
||||
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M);
|
||||
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_LEN, 0);
|
||||
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1, 0x9cffff);// Set adc2 internal channel & atten
|
||||
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2, 0xffffff);
|
||||
// Set ADC sampling frequency
|
||||
REG_SET_FIELD(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_TARGET, 100);
|
||||
REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLKM_DIV_NUM, 15);
|
||||
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_MEAS_NUM_LIMIT);
|
||||
SET_PERI_REG_MASK(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M);
|
||||
SET_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_TIMER_EN);
|
||||
adc_digi_pattern_config_t pattern_config = {};
|
||||
pattern_config.unit = ADC_UNIT_2;
|
||||
pattern_config.atten = ADC_ATTEN_DB_12;
|
||||
pattern_config.channel = ADC_CHANNEL_1; //Use reserved channel 10 to get internal voltage
|
||||
adc_ll_digi_set_pattern_table(ADC_UNIT_2, 0, pattern_config);
|
||||
adc_ll_digi_set_pattern_table_len(ADC_UNIT_2, 1);
|
||||
|
||||
adc_ll_digi_dma_enable();
|
||||
|
||||
adc_ll_digi_set_clk_div(1);
|
||||
adc_ll_digi_set_trigger_interval(100);
|
||||
adc_ll_digi_trigger_enable();
|
||||
}
|
||||
|
||||
void bootloader_random_disable(void)
|
||||
{
|
||||
/* Restore internal I2C bus state */
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0);
|
||||
|
||||
/* Restore SARADC to default mode */
|
||||
CLEAR_PERI_REG_MASK(APB_SARADC_CTRL2_REG,APB_SARADC_TIMER_EN);
|
||||
CLEAR_PERI_REG_MASK(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M);
|
||||
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1, 0xffffff);
|
||||
REG_SET_FIELD(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2, 0xffffff);
|
||||
CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M);
|
||||
REG_SET_FIELD(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0);
|
||||
_adc_ll_enable_bus_clock(false);
|
||||
adc_ll_digi_trigger_disable();
|
||||
adc_ll_digi_reset_pattern_table();
|
||||
adc_ll_regi2c_adc_deinit();
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
regi2c_saradc_disable();
|
||||
#endif
|
||||
// disable analog i2c master clock
|
||||
ANALOG_CLOCK_DISABLE();
|
||||
}
|
||||
|
||||
@@ -50,6 +50,9 @@ set(ble_mesh_v11_include_dirs
|
||||
"esp_ble_mesh/v1.1/api/core/include"
|
||||
"esp_ble_mesh/v1.1/api/models/include"
|
||||
"esp_ble_mesh/v1.1/btc/include"
|
||||
"esp_ble_mesh/v1.1/include"
|
||||
"esp_ble_mesh/v1.1/dfu"
|
||||
"esp_ble_mesh/v1.1/mbt"
|
||||
)
|
||||
|
||||
if(CONFIG_IDF_DOC_BUILD)
|
||||
@@ -631,9 +634,13 @@ if(CONFIG_BT_ENABLED)
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_sar_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_srpl_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_mbt_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_dfu_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_dfu_slot_api.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_slot.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_mbt_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c"
|
||||
@@ -641,6 +648,12 @@ if(CONFIG_BT_ENABLED)
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c"
|
||||
"esp_ble_mesh/v1.1/mbt/blob_srv.c"
|
||||
"esp_ble_mesh/v1.1/mbt/blob_cli.c"
|
||||
"esp_ble_mesh/v1.1/dfu/dfu_cli.c"
|
||||
"esp_ble_mesh/v1.1/dfu/dfu_srv.c"
|
||||
"esp_ble_mesh/v1.1/dfu/dfu_slot.c"
|
||||
"esp_ble_mesh/v1.1/dfu/dfu_metadata.c"
|
||||
"esp_ble_mesh/lib/ext.c")
|
||||
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT)
|
||||
list(APPEND srcs "esp_ble_mesh/core/transport.enh.c")
|
||||
|
||||
@@ -255,3 +255,9 @@ config BT_BLE_LOG_UHCI_OUT_UART_IO_NUM_TX
|
||||
default 0
|
||||
help
|
||||
IO number for UART TX port
|
||||
|
||||
config BT_LE_USED_MEM_STATISTICS_ENABLED
|
||||
bool "Enable used memory statistics"
|
||||
default n
|
||||
help
|
||||
Used in internal tests only. Enable used memory statistics.
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
#include "btc_ble_mesh_rpr_model.h"
|
||||
#include "btc_ble_mesh_sar_model.h"
|
||||
#include "btc_ble_mesh_srpl_model.h"
|
||||
#include "btc_ble_mesh_dfu_model.h"
|
||||
#endif /* CONFIG_BLE_MESH_V11_SUPPORT */
|
||||
#endif /* #if CONFIG_BLE_MESH */
|
||||
|
||||
@@ -262,6 +263,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
#if CONFIG_BLE_MESH_MBT_SRV
|
||||
[BTC_PID_MBT_SERVER] = {btc_ble_mesh_mbt_server_call_handler, btc_ble_mesh_mbt_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_MBT_SRV */
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
[BTC_PID_DFU_CLIENT] = {btc_ble_mesh_dfu_client_call_handler, btc_ble_mesh_dfu_client_cb_handler},
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50
|
||||
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -106,6 +106,10 @@ typedef enum {
|
||||
BTC_PID_TIME_SCENE_SERVER,
|
||||
BTC_PID_MBT_CLIENT,
|
||||
BTC_PID_MBT_SERVER,
|
||||
BTC_PID_BLOB_CLIENT,
|
||||
BTC_PID_BLOB_SERVER,
|
||||
BTC_PID_DFU_CLIENT,
|
||||
BTC_PID_DFU_SERVER,
|
||||
BTC_PID_BLE_MESH_BLE_COEX,
|
||||
#endif /* CONFIG_BLE_MESH */
|
||||
#if (BLE_FEAT_ISO_EN == TRUE)
|
||||
|
||||
@@ -141,7 +141,9 @@
|
||||
#define LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define BT_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_INITIAL_TRACE_LEVEL, LOG_LOCAL_LEVEL_MAPPING) >= BT_TRACE_LEVEL_##LEVEL)
|
||||
|
||||
|
||||
@@ -458,10 +458,12 @@ config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
range 0 3000
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
The Bluetooth LE spec requires a Sleep Clock Accuracy (SCA) of < ±500 ppm.
|
||||
This options allows for a larger value to enable the use of less accurate clock sources.
|
||||
|
||||
config BT_LE_LL_PEER_SCA_SET_ENABLE
|
||||
bool "Enable to set constant peer SCA"
|
||||
|
||||
@@ -575,7 +575,7 @@ struct ext_funcs_t ext_funcs_ro = {
|
||||
._esp_intr_alloc = esp_intr_alloc_wrapper,
|
||||
._esp_intr_free = esp_intr_free_wrapper,
|
||||
._malloc = bt_osi_mem_malloc_internal,
|
||||
._free = bt_osi_mem_free,
|
||||
._free = bt_osi_mem_free_internal,
|
||||
._task_create = task_create_wrapper,
|
||||
._task_delete = task_delete_wrapper,
|
||||
._osi_assert = osi_assert_wrapper,
|
||||
@@ -749,7 +749,7 @@ void controller_wakeup_cb(void *arg)
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
static bool esp_bt_check_wakeup_by_bt(void)
|
||||
{
|
||||
return (esp_sleep_get_wakeup_causes() & ESP_SLEEP_WAKEUP_BT);
|
||||
return (esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_BT));
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
|
||||
|
||||
@@ -511,10 +511,12 @@ config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
range 0 3000
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
The Bluetooth LE spec requires a Sleep Clock Accuracy (SCA) of < ±500 ppm.
|
||||
This options allows for a larger value to enable the use of less accurate clock sources.
|
||||
|
||||
config BT_LE_LL_PEER_SCA_SET_ENABLE
|
||||
bool "Enable to set constant peer SCA"
|
||||
@@ -879,3 +881,65 @@ endmenu
|
||||
config BT_LE_DTM_ENABLED
|
||||
bool "Enable Direct Test Mode (DTM) feature"
|
||||
default n
|
||||
|
||||
menu "Scheduling Priority Level Config"
|
||||
choice BT_LE_ADV_SCHED_PRIO_LEVEL
|
||||
prompt "The Adv scheduling priority level"
|
||||
default BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
help
|
||||
The Adv scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_ADV_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_ADV_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_ADV_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
default 0
|
||||
|
||||
choice BT_LE_PERIODIC_ADV_SCHED_PRIO_LEVEL
|
||||
prompt "The Periodic Adv scheduling priority level"
|
||||
default BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
help
|
||||
The Periodic Adv scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_PERIODIC_ADV_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_PERIODIC_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_PERIODIC_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
default 1
|
||||
|
||||
choice BT_LE_SYNC_SCHED_PRIO_LEVEL
|
||||
prompt "The Sync scheduling priority level"
|
||||
default BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
help
|
||||
The SYNC scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_SYNC_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_SYNC_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_SYNC_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
|
||||
default 1
|
||||
endmenu
|
||||
|
||||
@@ -537,7 +537,7 @@ struct ext_funcs_t ext_funcs_ro = {
|
||||
._esp_intr_alloc = esp_intr_alloc_wrapper,
|
||||
._esp_intr_free = esp_intr_free_wrapper,
|
||||
._malloc = bt_osi_mem_malloc_internal,
|
||||
._free = bt_osi_mem_free,
|
||||
._free = bt_osi_mem_free_internal,
|
||||
._task_create = task_create_wrapper,
|
||||
._task_delete = task_delete_wrapper,
|
||||
._osi_assert = osi_assert_wrapper,
|
||||
@@ -736,7 +736,7 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
static bool esp_bt_check_wakeup_by_bt(void)
|
||||
{
|
||||
return (esp_sleep_get_wakeup_causes() & ESP_SLEEP_WAKEUP_BT);
|
||||
return (esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_BT));
|
||||
}
|
||||
|
||||
static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
|
||||
|
||||
@@ -297,7 +297,7 @@ extern "C" {
|
||||
#define RUN_BQB_TEST (0)
|
||||
#define RUN_QA_TEST (0)
|
||||
#define NIMBLE_DISABLE_SCAN_BACKOFF (0)
|
||||
|
||||
#define BT_LL_CTRL_PRIO_LVL_CFG ((CONFIG_BT_LE_DFT_SYNC_SCHED_PRIO_LEVEL << 4) | (CONFIG_BT_LE_DFT_PERIODIC_ADV_SCHED_PRIO_LEVEL << 2) | CONFIG_BT_LE_DFT_ADV_SCHED_PRIO_LEVEL)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -552,10 +552,12 @@ config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
range 0 3000
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
The Bluetooth LE spec requires a Sleep Clock Accuracy (SCA) of < ±500 ppm.
|
||||
This options allows for a larger value to enable the use of less accurate clock sources.
|
||||
|
||||
config BT_LE_LL_PEER_SCA_SET_ENABLE
|
||||
bool "Enable to set constant peer SCA"
|
||||
@@ -913,3 +915,65 @@ endmenu
|
||||
config BT_LE_DTM_ENABLED
|
||||
bool "Enable Direct Test Mode (DTM) feature"
|
||||
default n
|
||||
|
||||
menu "Scheduling Priority Level Config"
|
||||
choice BT_LE_ADV_SCHED_PRIO_LEVEL
|
||||
prompt "The Adv scheduling priority level"
|
||||
default BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
help
|
||||
The Adv scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_ADV_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_ADV_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_ADV_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
default 0
|
||||
|
||||
choice BT_LE_PERIODIC_ADV_SCHED_PRIO_LEVEL
|
||||
prompt "The Periodic Adv scheduling priority level"
|
||||
default BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
help
|
||||
The Periodic Adv scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_PERIODIC_ADV_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_PERIODIC_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_PERIODIC_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
default 1
|
||||
|
||||
choice BT_LE_SYNC_SCHED_PRIO_LEVEL
|
||||
prompt "The Sync scheduling priority level"
|
||||
default BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
help
|
||||
The SYNC scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_SYNC_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_SYNC_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_SYNC_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
|
||||
default 1
|
||||
endmenu
|
||||
|
||||
@@ -553,7 +553,7 @@ struct ext_funcs_t ext_funcs_ro = {
|
||||
._esp_intr_alloc = esp_intr_alloc_wrapper,
|
||||
._esp_intr_free = esp_intr_free_wrapper,
|
||||
._malloc = bt_osi_mem_malloc_internal,
|
||||
._free = bt_osi_mem_free,
|
||||
._free = bt_osi_mem_free_internal,
|
||||
._task_create = task_create_wrapper,
|
||||
._task_delete = task_delete_wrapper,
|
||||
._osi_assert = osi_assert_wrapper,
|
||||
@@ -796,7 +796,7 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
static bool esp_bt_check_wakeup_by_bt(void)
|
||||
{
|
||||
return (esp_sleep_get_wakeup_causes() & ESP_SLEEP_WAKEUP_BT);
|
||||
return (esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_BT));
|
||||
}
|
||||
|
||||
static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
|
||||
|
||||
@@ -300,6 +300,7 @@ extern "C" {
|
||||
#define RUN_BQB_TEST (0)
|
||||
#define RUN_QA_TEST (0)
|
||||
#define NIMBLE_DISABLE_SCAN_BACKOFF (0)
|
||||
#define BT_LL_CTRL_PRIO_LVL_CFG ((CONFIG_BT_LE_DFT_SYNC_SCHED_PRIO_LEVEL << 4) | (CONFIG_BT_LE_DFT_PERIODIC_ADV_SCHED_PRIO_LEVEL << 2) | CONFIG_BT_LE_DFT_ADV_SCHED_PRIO_LEVEL)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -546,10 +546,12 @@ config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
range 0 3000
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
The Bluetooth LE spec requires a Sleep Clock Accuracy (SCA) of < ±500 ppm.
|
||||
This options allows for a larger value to enable the use of less accurate clock sources.
|
||||
|
||||
config BT_LE_LL_PEER_SCA_SET_ENABLE
|
||||
bool "Enable to set constant peer SCA"
|
||||
@@ -917,3 +919,65 @@ endmenu
|
||||
config BT_LE_DTM_ENABLED
|
||||
bool "Enable Direct Test Mode (DTM) feature"
|
||||
default n
|
||||
|
||||
menu "Scheduling Priority Level Config"
|
||||
choice BT_LE_ADV_SCHED_PRIO_LEVEL
|
||||
prompt "The Adv scheduling priority level"
|
||||
default BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
help
|
||||
The Adv scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_ADV_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_ADV_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_ADV_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
default 0
|
||||
|
||||
choice BT_LE_PERIODIC_ADV_SCHED_PRIO_LEVEL
|
||||
prompt "The Periodic Adv scheduling priority level"
|
||||
default BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
help
|
||||
The Periodic Adv scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_PERIODIC_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_PERIODIC_ADV_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_PERIODIC_ADV_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_PERIODIC_ADV_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_PERIODIC_ADV_SCHED_PRIO_HIGH_LEVEL
|
||||
default 1
|
||||
|
||||
choice BT_LE_SYNC_SCHED_PRIO_LEVEL
|
||||
prompt "The Sync scheduling priority level"
|
||||
default BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
help
|
||||
The SYNC scheduling priority level is used for arbitration when internal scheduling conflicts.
|
||||
config BT_LE_SYNC_SCHED_PRIO_LOW_LEVEL
|
||||
bool "low priority level"
|
||||
config BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
bool "medium priority level"
|
||||
config BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
|
||||
bool "high priority level"
|
||||
endchoice
|
||||
|
||||
config BT_LE_DFT_SYNC_SCHED_PRIO_LEVEL
|
||||
int
|
||||
default 0 if BT_LE_SYNC_SCHED_PRIO_LOW_LEVEL
|
||||
default 1 if BT_LE_SYNC_SCHED_PRIO_MID_LEVEL
|
||||
default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
|
||||
default 1
|
||||
endmenu
|
||||
|
||||
@@ -545,7 +545,7 @@ struct ext_funcs_t ext_funcs_ro = {
|
||||
._esp_intr_alloc = esp_intr_alloc_wrapper,
|
||||
._esp_intr_free = esp_intr_free_wrapper,
|
||||
._malloc = bt_osi_mem_malloc_internal,
|
||||
._free = bt_osi_mem_free,
|
||||
._free = bt_osi_mem_free_internal,
|
||||
._task_create = task_create_wrapper,
|
||||
._task_delete = task_delete_wrapper,
|
||||
._osi_assert = osi_assert_wrapper,
|
||||
@@ -764,7 +764,7 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
|
||||
#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
static bool esp_bt_check_wakeup_by_bt(void)
|
||||
{
|
||||
return (esp_sleep_get_wakeup_causes() & ESP_SLEEP_WAKEUP_BT);
|
||||
return (esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_BT));
|
||||
}
|
||||
|
||||
static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
|
||||
|
||||
@@ -297,7 +297,7 @@ extern "C" {
|
||||
#define RUN_BQB_TEST (0)
|
||||
#define RUN_QA_TEST (0)
|
||||
#define NIMBLE_DISABLE_SCAN_BACKOFF (0)
|
||||
|
||||
#define BT_LL_CTRL_PRIO_LVL_CFG ((CONFIG_BT_LE_DFT_SYNC_SCHED_PRIO_LEVEL << 4) | (CONFIG_BT_LE_DFT_PERIODIC_ADV_SCHED_PRIO_LEVEL << 2) | CONFIG_BT_LE_DFT_ADV_SCHED_PRIO_LEVEL)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Submodule components/bt/controller/lib_esp32c2/esp32c2-bt-lib updated: 7778b43e35...c82c623de4
Submodule components/bt/controller/lib_esp32c5/esp32c5-bt-lib updated: afd9ae8754...f909ce5d5a
Submodule components/bt/controller/lib_esp32c6/esp32c6-bt-lib updated: bd5914cd7d...1495595b82
Submodule components/bt/controller/lib_esp32h2/esp32h2-bt-lib updated: 3874210bfe...9cfbeb5f16
@@ -1644,11 +1644,13 @@ if BLE_MESH
|
||||
Enable support for Lighting server models.
|
||||
|
||||
config BLE_MESH_MBT_CLI
|
||||
bool "BLOB Transfer Client model"
|
||||
bool "BLOB Transfer Client model(Deprecated)"
|
||||
depends on BLE_MESH_V11_SUPPORT
|
||||
default n
|
||||
help
|
||||
Enable support for BLOB Transfer Client model.
|
||||
Warn: This version of the Mesh Binary Large Object Transfer Model will be deprecated,
|
||||
and a new version will be released in the future.
|
||||
|
||||
if BLE_MESH_MBT_CLI
|
||||
|
||||
@@ -1663,11 +1665,212 @@ if BLE_MESH
|
||||
endif # BLE_MESH_MBT_CLI
|
||||
|
||||
config BLE_MESH_MBT_SRV
|
||||
bool "BLOB Transfer Server model"
|
||||
bool "BLOB Transfer Server model(Deprecated)"
|
||||
depends on BLE_MESH_V11_SUPPORT
|
||||
default n
|
||||
help
|
||||
Enable support for BLOB Transfer Server model.
|
||||
Warn: This version of the Mesh Binary Large Object Transfer Model will be deprecated,
|
||||
and a new version will be released in the future.
|
||||
|
||||
menu "Binary Larger Object Transfer model"
|
||||
|
||||
config BLE_MESH_BLOB_SRV
|
||||
bool "Support for BLOB Transfer Server model"
|
||||
depends on BLE_MESH_V11_SUPPORT
|
||||
help
|
||||
Enable the Binary Large Object (BLOB) Transfer Server model.
|
||||
|
||||
if BLE_MESH_BLOB_SRV
|
||||
|
||||
config BLE_MESH_BLOB_SRV_PULL_REQ_COUNT
|
||||
int "Number of chunks to request for each pull"
|
||||
default 4
|
||||
range 1 16
|
||||
help
|
||||
In Pull mode (Pull BLOB Transfer Mode), the BLOB Transfer Server
|
||||
requests a fixed number of chunks from the Client. Use this option to
|
||||
control the chunk count in the request. If the BLOB Transfer Server
|
||||
is instantiated on a Low Power node, the pull request count will be
|
||||
trimmed to not overflow the Friend queue.
|
||||
|
||||
config BLE_MESH_BLOB_SIZE_MAX
|
||||
int "Largest BLOB size in bytes"
|
||||
default 524288
|
||||
range 1 3257617792
|
||||
help
|
||||
The maximum object size a BLOB Transfer Server can receive.
|
||||
|
||||
config BLE_MESH_BLOB_BLOCK_SIZE_MIN
|
||||
int "Minimum block size"
|
||||
default 4096
|
||||
range 64 1048576 # 2^6 - 2^20
|
||||
help
|
||||
Minimum acceptable block size in a BLOB transfer. The transfer block
|
||||
size will be some number that is a power of two, and is between block
|
||||
size min and block size max. If no such number exists, a compile
|
||||
time warning will be issued.
|
||||
|
||||
config BLE_MESH_BLOB_BLOCK_SIZE_MAX
|
||||
int "Maximum block size"
|
||||
default 4096
|
||||
range BLE_MESH_BLOB_BLOCK_SIZE_MIN 1048576
|
||||
help
|
||||
Maximum acceptable block size in a BLOB transfer. The transfer block
|
||||
size will be some number that is a power of two, and is between block
|
||||
size min and block size max. If no such number exists, a compile
|
||||
time warning will be issued.
|
||||
|
||||
config BLE_MESH_BLOB_REPORT_TIMEOUT
|
||||
int "Partial Block Report interval in Pull mode"
|
||||
default 10
|
||||
range 1 31
|
||||
help
|
||||
The timer value that Pull BLOB Transfer Server uses to report missed chunks.
|
||||
|
||||
config BLE_MESH_RX_BLOB_CHUNK_SIZE
|
||||
depends on !BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT
|
||||
int "BLOB Server chunk size"
|
||||
default 8
|
||||
range 8 377
|
||||
help
|
||||
Set the chunk size for the BLOB Server.
|
||||
The actual maximum chunk size depends on how many segments are
|
||||
possible and will be clamped to the max possible if set above.
|
||||
see also: BLE_MESH_RX_SEG_MAX,
|
||||
and the maximum SDU a node can receive.
|
||||
|
||||
endif # BLE_MESH_BLOB_SRV
|
||||
|
||||
config BLE_MESH_BLOB_CLI
|
||||
bool "Support for BLOB Transfer Client model"
|
||||
depends on BLE_MESH_V11_SUPPORT
|
||||
help
|
||||
Enable the Binary Large Object (BLOB) Transfer Client model.
|
||||
|
||||
if BLE_MESH_BLOB_CLI
|
||||
|
||||
config BLE_MESH_BLOB_CLI_BLOCK_RETRIES
|
||||
int "Number of retries per block"
|
||||
default 5
|
||||
help
|
||||
Controls the number of times the client will attempt to resend missing
|
||||
chunks to the BLOB receivers for every block.
|
||||
|
||||
config BLE_MESH_TX_BLOB_CHUNK_SIZE
|
||||
depends on !BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT
|
||||
int "BLOB Client chunk size"
|
||||
default 8
|
||||
range 1 377
|
||||
help
|
||||
Set the chunk size for the BLOB Client.
|
||||
The actual maximum chunk size depends on how many segments are
|
||||
possible and will be clamped to the max possible if set above.
|
||||
see also: BLE_MESH_TX_SEG_MAX,
|
||||
and the maximum SDU a node can receive.
|
||||
|
||||
config BLE_MESH_TX_BLOB_CHUNK_SEND_INTERVAL
|
||||
int "BLOB Client chunk send interval"
|
||||
default 0
|
||||
range 0 2147483647
|
||||
help
|
||||
Set the interval in milliseconds in which chunks are sent during the BLOB transfer.
|
||||
Note: Without a delay between each sent chunk, the network might become too busy with the
|
||||
BLOB transfer for other communications to succeed.
|
||||
Note: Timing restrictions, like the timeout base, should be considered or changed
|
||||
accordingly when setting this interval. Otherwise, the interval might be too big for the
|
||||
timeout settings and cause timeouts.
|
||||
|
||||
endif # BLE_MESH_BLOB_CLI
|
||||
|
||||
menu "BLOB models common configuration"
|
||||
visible if BLE_MESH_BLOB_SRV || BLE_MESH_BLOB_CLI
|
||||
|
||||
config BLE_MESH_BLOB_CHUNK_COUNT_MAX
|
||||
int "Maximum chunk count per block"
|
||||
default 256
|
||||
range 1 2992
|
||||
help
|
||||
A BLOB transfer contains several blocks. Each block is made up of
|
||||
several chunks. This option controls the maximum chunk count per
|
||||
block.
|
||||
|
||||
config BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT
|
||||
bool "Align chunk size to max segmented message size"
|
||||
default y
|
||||
|
||||
endmenu #BLOB models common configuration
|
||||
|
||||
endmenu # Binary Larger Object Transfer model
|
||||
|
||||
menu "Device Firmware Update model"
|
||||
|
||||
config BLE_MESH_DFU_SRV
|
||||
bool "Support for Firmware Update Server model"
|
||||
depends on BLE_MESH_BLOB_SRV
|
||||
help
|
||||
Enable the Firmware Update Server model.
|
||||
|
||||
config BLE_MESH_DFU_CLI
|
||||
bool "Support for Firmware Update Client model"
|
||||
depends on BLE_MESH_BLOB_CLI
|
||||
help
|
||||
Enable the Firmware Update Client model.
|
||||
|
||||
menu "Firmware Update model configuration"
|
||||
visible if BLE_MESH_DFU_SRV || BLE_MESH_DFU_CLI
|
||||
|
||||
config BLE_MESH_DFU_FWID_MAXLEN
|
||||
int "DFU FWID max length"
|
||||
default 16
|
||||
range 0 106
|
||||
help
|
||||
This value defines the maximum length of an image's firmware ID.
|
||||
|
||||
config BLE_MESH_DFU_METADATA_MAXLEN
|
||||
int "DFU metadata max length"
|
||||
default 32
|
||||
range 18 255 if BLE_MESH_DFU_METADATA
|
||||
range 0 255
|
||||
help
|
||||
This value defines the maximum length of an image's metadata.
|
||||
|
||||
config BLE_MESH_DFU_METADATA
|
||||
bool "Support for the default metadata format"
|
||||
help
|
||||
This option adds a set of functions that can be used to encode and decode a firmware
|
||||
metadata using the format defined in the Bluetooth mesh DFU subsystem.
|
||||
|
||||
config BLE_MESH_DFU_URI_MAXLEN
|
||||
int "DFU URI max length"
|
||||
default 32
|
||||
range 0 255
|
||||
help
|
||||
This value defines the maximum length of an image's URI, not including
|
||||
a string terminator.
|
||||
|
||||
endmenu #Firmware Update model configuration
|
||||
|
||||
config BLE_MESH_DFU_SLOTS
|
||||
bool "Firmware image slot manager"
|
||||
default y if BLE_MESH_DFU_CLI
|
||||
help
|
||||
Enable the DFU image slot manager, for managing firmware distribution slots
|
||||
for the Firmware Update Client model.
|
||||
|
||||
if BLE_MESH_DFU_SLOTS
|
||||
|
||||
config BLE_MESH_DFU_SLOT_CNT
|
||||
int "Number of firmware image slots"
|
||||
default 1
|
||||
range 1 32767
|
||||
help
|
||||
This value defines the number of firmware slots the DFU image slot manager
|
||||
can keep simultaneously.
|
||||
|
||||
endif #BLE_MESH_DFU_SLOTS
|
||||
|
||||
endmenu # Device Firmware Update model
|
||||
|
||||
endmenu #Support for BLE Mesh Client/Server models
|
||||
|
||||
|
||||
@@ -1982,8 +1982,12 @@ typedef union {
|
||||
#define ESP_BLE_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
|
||||
#define ESP_BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV 0x1310
|
||||
#define ESP_BLE_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311
|
||||
#define ESP_BLE_MESH_MODEL_ID_MBT_SRV 0x1400
|
||||
#define ESP_BLE_MESH_MODEL_ID_MBT_CLI 0x1401
|
||||
#define ESP_BLE_MESH_MODEL_ID_MBT_SRV 0x14fe
|
||||
#define ESP_BLE_MESH_MODEL_ID_MBT_CLI 0x14ff
|
||||
#define ESP_BLE_MESH_MODEL_ID_BLOB_SRV 0x1400
|
||||
#define ESP_BLE_MESH_MODEL_ID_BLOB_CLI 0x1401
|
||||
#define ESP_BLE_MESH_MODEL_ID_DFU_SRV 0x1402
|
||||
#define ESP_BLE_MESH_MODEL_ID_DFU_CLI 0x1403
|
||||
|
||||
/**
|
||||
* esp_ble_mesh_opcode_config_client_get_t belongs to esp_ble_mesh_opcode_t, this typedef is only
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -1410,6 +1410,23 @@ typedef bt_mesh_client_user_data_t bt_mesh_mbt_client_t;
|
||||
extern const struct bt_mesh_model_op bt_mesh_mbt_cli_op[];
|
||||
extern const struct bt_mesh_model_cb bt_mesh_mbt_cli_cb;
|
||||
#endif /* CONFIG_BLE_MESH_MBT_CLI */
|
||||
#if CONFIG_BLE_MESH_BLOB_SRV
|
||||
extern const struct bt_mesh_model_op _bt_mesh_blob_srv_op[];
|
||||
extern const struct bt_mesh_model_cb _bt_mesh_blob_srv_cb;
|
||||
#endif /* CONFIG_BLE_MESH_BLOB_SRV */
|
||||
#if CONFIG_BLE_MESH_BLOB_CLI
|
||||
typedef bt_mesh_client_user_data_t bt_mesh_blob_client_t;
|
||||
extern const struct bt_mesh_model_op _bt_mesh_blob_cli_op[];
|
||||
extern const struct bt_mesh_model_cb _bt_mesh_blob_cli_cb;
|
||||
#endif /* CONFIG_BLE_MESH_BLOB_CLI */
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
extern const struct bt_mesh_model_op _bt_mesh_dfu_srv_op[];
|
||||
extern const struct bt_mesh_model_cb _bt_mesh_dfu_srv_cb;
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
extern const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[];
|
||||
extern const struct bt_mesh_model_cb _bt_mesh_dfu_cli_cb;
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
|
||||
{
|
||||
@@ -2205,9 +2222,9 @@ static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
|
||||
case BLE_MESH_MODEL_ID_MBT_CLI:
|
||||
model->op = (esp_ble_mesh_model_op_t *)bt_mesh_mbt_cli_op;
|
||||
model->cb = (esp_ble_mesh_model_cbs_t *)&bt_mesh_mbt_cli_cb;
|
||||
bt_mesh_mbt_client_t *cli = (bt_mesh_mbt_client_t *)model->user_data;
|
||||
if (cli) {
|
||||
cli->publish_status = btc_ble_mesh_mbt_client_publish_callback;
|
||||
bt_mesh_mbt_client_t *mbt_cli = (bt_mesh_mbt_client_t *)model->user_data;
|
||||
if (mbt_cli) {
|
||||
mbt_cli->publish_status = btc_ble_mesh_mbt_client_publish_callback;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BLE_MESH_MBT_CLI */
|
||||
@@ -2220,6 +2237,43 @@ static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BLE_MESH_MBT_SRV */
|
||||
#if CONFIG_BLE_MESH_BLOB_CLI
|
||||
case BLE_MESH_MODEL_ID_BLOB_CLI:
|
||||
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_blob_cli_op;
|
||||
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_blob_cli_cb;
|
||||
bt_mesh_blob_client_t *blob_cli = (bt_mesh_blob_client_t *)model->user_data;
|
||||
if (blob_cli) {
|
||||
/* TBD: do we need publish callback for Blob Transfer Client model? */
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BLE_MESH_BLOB_CLI */
|
||||
#if CONFIG_BLE_MESH_BLOB_SRV
|
||||
case BLE_MESH_MODEL_ID_BLOB_SRV:
|
||||
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_blob_srv_op;
|
||||
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_blob_srv_cb;
|
||||
if (model->pub) {
|
||||
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BLE_MESH_BLOB_SRV */
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
case BLE_MESH_MODEL_ID_DFU_CLI:
|
||||
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfu_cli_op;
|
||||
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfu_cli_cb;
|
||||
if (model->pub) {
|
||||
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
case BLE_MESH_MODEL_ID_DFU_SRV:
|
||||
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfu_srv_op;
|
||||
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfu_srv_cb;
|
||||
if (model->pub) {
|
||||
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
default:
|
||||
goto set_vnd_op;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -32,6 +32,27 @@ static inline void btc_ble_mesh_set_client_common_param(esp_ble_mesh_client_comm
|
||||
output->ctx.send_cred = input->ctx.send_cred;
|
||||
output->ctx.send_tag = input->ctx.send_tag;
|
||||
output->msg_timeout = input->msg_timeout;
|
||||
if (input->ctx.enh.adv_cfg_used) {
|
||||
output->ctx.enh.adv_cfg_used = input->ctx.enh.adv_cfg_used;
|
||||
output->ctx.enh.adv_cfg.adv_cnt = input->ctx.enh.adv_cfg.adv_cnt;
|
||||
output->ctx.enh.adv_cfg.adv_itvl = input->ctx.enh.adv_cfg.adv_itvl;
|
||||
output->ctx.enh.adv_cfg.channel_map = input->ctx.enh.adv_cfg.channel_map;
|
||||
}
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (input->ctx.enh.ext_adv_cfg_used) {
|
||||
output->ctx.enh.ext_adv_cfg_used = input->ctx.enh.ext_adv_cfg_used;
|
||||
output->ctx.enh.ext_adv_cfg.primary_phy = input->ctx.enh.ext_adv_cfg.primary_phy;
|
||||
output->ctx.enh.ext_adv_cfg.secondary_phy = input->ctx.enh.ext_adv_cfg.secondary_phy;
|
||||
output->ctx.enh.ext_adv_cfg.include_tx_power = input->ctx.enh.ext_adv_cfg.include_tx_power;
|
||||
output->ctx.enh.ext_adv_cfg.tx_power = input->ctx.enh.ext_adv_cfg.tx_power;
|
||||
}
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (input->ctx.enh.long_pkt_cfg_used) {
|
||||
output->ctx.enh.long_pkt_cfg_used = input->ctx.enh.long_pkt_cfg_used;
|
||||
output->ctx.enh.long_pkt_cfg = input->ctx.enh.long_pkt_cfg;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BLE_MESH_ADV_TASK_STACK_SIZE 3072
|
||||
#define BLE_MESH_ADV_TASK_STACK_SIZE (3072)
|
||||
#define BLE_MESH_ADV_TASK_NAME "mesh_adv_task"
|
||||
#define BLE_MESH_ADV_TASK_PRIO (configMAX_PRIORITIES - 5)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -49,6 +49,8 @@ struct k_work;
|
||||
*/
|
||||
typedef void (*k_work_handler_t)(struct k_work *work);
|
||||
|
||||
typedef int32_t k_timeout_t;
|
||||
|
||||
struct k_work {
|
||||
k_work_handler_t handler;
|
||||
int index;
|
||||
@@ -141,6 +143,65 @@ struct k_work {
|
||||
*/
|
||||
#define K_FOREVER (-1)
|
||||
|
||||
/**
|
||||
* @brief Define for delayable work type.
|
||||
*
|
||||
* This macro maps the Zephyr delayable work type `k_work_delayable`
|
||||
* to the ESP-IDF type `k_delayed_work`.
|
||||
*/
|
||||
#define k_work_delayable k_delayed_work
|
||||
|
||||
/**
|
||||
* @brief Reschedule a delayable work item.
|
||||
*
|
||||
* This macro maps to `k_delayed_work_submit`, which cancels
|
||||
* any existing pending submission of the work item and reschedules
|
||||
* it with the new timeout delay.
|
||||
*
|
||||
* @param work Pointer to delayable work item.
|
||||
* @param delay Timeout delay value.
|
||||
* @return See implementation of `k_delayed_work_submit`.
|
||||
*/
|
||||
#define k_work_reschedule k_delayed_work_submit
|
||||
|
||||
/**
|
||||
* @brief Schedule a delayable work item.
|
||||
*
|
||||
* This macro maps to `k_delayed_work_submit`,
|
||||
* which schedules a work item to be processed
|
||||
* after the specified timeout delay. If the work
|
||||
* is already pending, the new delay is applied.
|
||||
*
|
||||
* @param work Pointer to delayable work item.
|
||||
* @param delay Timeout delay value.
|
||||
* @return See implementation of `k_delayed_work_submit`.
|
||||
*/
|
||||
#define k_work_schedule k_delayed_work_submit
|
||||
|
||||
/**
|
||||
* @brief Cancel a delayable work item.
|
||||
*
|
||||
* This macro maps to `k_delayed_work_cancel`,
|
||||
* which cancels a pending work submission
|
||||
* associated with a delayable work item.
|
||||
*
|
||||
* @param work Pointer to delayable work item.
|
||||
* @return See implementation of `k_delayed_work_cancel`.
|
||||
*/
|
||||
#define k_work_cancel_delayable k_delayed_work_cancel
|
||||
|
||||
/**
|
||||
* @brief Initialize a delayable work item.
|
||||
*
|
||||
* This macro maps to `k_delayed_work_init`,
|
||||
* which initializes a delayable work item with
|
||||
* the provided handler function.
|
||||
*
|
||||
* @param work Pointer to delayable work item.
|
||||
* @param handler Work item handler function.
|
||||
*/
|
||||
#define k_work_init_delayable k_delayed_work_init
|
||||
|
||||
/**
|
||||
* @brief Get system uptime (32-bit version).
|
||||
*
|
||||
@@ -160,6 +221,27 @@ struct k_delayed_work {
|
||||
struct k_work work;
|
||||
};
|
||||
|
||||
#define _K_DELAYABLE_WORK_INITIALIZER(work_handler) { \
|
||||
.work = { \
|
||||
.handler = work_handler, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a work item to its containing delayable work structure.
|
||||
*
|
||||
* This function uses container_of to derive the address of the containing
|
||||
* k_work_delayable structure from the address of the embedded k_work structure.
|
||||
*
|
||||
* @param work Pointer to the embedded k_work structure within a k_work_delayable.
|
||||
* @return Pointer to the containing k_work_delayable structure.
|
||||
*/
|
||||
static inline struct k_work_delayable *
|
||||
k_work_delayable_from_work(struct k_work *work)
|
||||
{
|
||||
return CONTAINER_OF(work, struct k_work_delayable, work);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Submit a delayed work item to the system workqueue.
|
||||
*
|
||||
@@ -209,6 +291,21 @@ int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period);
|
||||
*/
|
||||
int32_t k_delayed_work_remaining_get(struct k_delayed_work *work);
|
||||
|
||||
/**
|
||||
* @brief Check if a delayable work item is pending execution.
|
||||
*
|
||||
* This function checks whether a delayable work item has been scheduled
|
||||
* and is waiting to be processed. It returns true if the work item is in
|
||||
* pending state (waiting for timeout expiration or being in work queue).
|
||||
*
|
||||
* @param dwork Pointer to delayable work item.
|
||||
* @return true if work is pending, false otherwise.
|
||||
*/
|
||||
static inline bool k_work_delayable_is_pending(struct k_work_delayable *dwork)
|
||||
{
|
||||
return k_delayed_work_remaining_get(dwork);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Submit a work item to the system workqueue.
|
||||
*
|
||||
@@ -267,10 +364,45 @@ int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler);
|
||||
* @return Current uptime.
|
||||
*/
|
||||
int64_t k_uptime_get(void);
|
||||
int64_t k_uptime_delta(int64_t *reftime);
|
||||
|
||||
void bt_mesh_timer_init(void);
|
||||
void bt_mesh_timer_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize a statically-defined work item.
|
||||
*
|
||||
* This macro can be used to initialize a statically-defined workqueue work
|
||||
* item, prior to its first use. For example,
|
||||
*
|
||||
* @code static K_WORK_DEFINE(<work>, <work_handler>); @endcode
|
||||
*
|
||||
* @param work Symbol name for work item object
|
||||
* @param work_handler Function to invoke each time work item is processed.
|
||||
*/
|
||||
#define K_WORK_DEFINE(work, work_handler) \
|
||||
struct k_work work = _K_WORK_INITIALIZER(work_handler)
|
||||
|
||||
/**
|
||||
* @brief Initialize a statically-defined delayable work item.
|
||||
*
|
||||
* This macro can be used to initialize a statically-defined delayable
|
||||
* work item, prior to its first use. For example,
|
||||
*
|
||||
* @code static K_WORK_DELAYABLE_DEFINE(<dwork>, <work_handler>); @endcode
|
||||
*
|
||||
* Note that if the runtime dependencies support initialization with
|
||||
* k_work_init_delayable() using that will eliminate the initialized
|
||||
* object in ROM that is produced by this macro and copied in at
|
||||
* system startup.
|
||||
*
|
||||
* @param work Symbol name for delayable work item object
|
||||
* @param work_handler Function to invoke each time work item is processed.
|
||||
*/
|
||||
#define K_WORK_DELAYABLE_DEFINE(work, work_handler) \
|
||||
struct k_delayed_work work \
|
||||
= _K_DELAYABLE_WORK_INITIALIZER(work_handler)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#define _BLE_MESH_UTILS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <errno.h>
|
||||
#include "esp_bit_defs.h"
|
||||
#include "mesh/types.h"
|
||||
#include "utils_loops.h"
|
||||
@@ -94,6 +96,81 @@ extern "C" {
|
||||
#define WB_DN(x) ROUND_DOWN(x, sizeof(void *))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Whether @p ptr is an element of @p array
|
||||
*
|
||||
* This macro can be seen as a slightly stricter version of @ref PART_OF_ARRAY
|
||||
* in that it also ensures that @p ptr is aligned to an array-element boundary
|
||||
* of @p array.
|
||||
*
|
||||
* In C, passing a pointer as @p array causes a compile error.
|
||||
*
|
||||
* @param array the array in question
|
||||
* @param ptr the pointer to check
|
||||
*
|
||||
* @return 1 if @p ptr is part of @p array, 0 otherwise
|
||||
*/
|
||||
#define IS_ARRAY_ELEMENT(array, ptr) \
|
||||
((ptr) && POINTER_TO_UINT(array) <= POINTER_TO_UINT(ptr) && \
|
||||
POINTER_TO_UINT(ptr) < POINTER_TO_UINT(&(array)[ARRAY_SIZE(array)]) && \
|
||||
(POINTER_TO_UINT(ptr) - POINTER_TO_UINT(array)) % sizeof((array)[0]) == 0)
|
||||
|
||||
/**
|
||||
* @brief Index of @p ptr within @p array
|
||||
*
|
||||
* With `CONFIG_ASSERT=y`, this macro will trigger a runtime assertion
|
||||
* when @p ptr does not fall into the range of @p array or when @p ptr
|
||||
* is not aligned to an array-element boundary of @p array.
|
||||
*
|
||||
* In C, passing a pointer as @p array causes a compile error.
|
||||
*
|
||||
* @param array the array in question
|
||||
* @param ptr pointer to an element of @p array
|
||||
*
|
||||
* @return the array index of @p ptr within @p array, on success
|
||||
*/
|
||||
#define ARRAY_INDEX(array, ptr) \
|
||||
({ \
|
||||
__ASSERT_NO_MSG(IS_ARRAY_ELEMENT(array, ptr)); \
|
||||
(__typeof__((array)[0]) *)(ptr) - (array); \
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* @brief Divide and round up.
|
||||
*
|
||||
* Example:
|
||||
* @code{.c}
|
||||
* DIV_ROUND_UP(1, 2); // 1
|
||||
* DIV_ROUND_UP(3, 2); // 2
|
||||
* @endcode
|
||||
*
|
||||
* @param n Numerator.
|
||||
* @param d Denominator.
|
||||
*
|
||||
* @return The result of @p n / @p d, rounded up.
|
||||
*/
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
|
||||
/**
|
||||
* @brief Divide and round to the nearest integer.
|
||||
*
|
||||
* Example:
|
||||
* @code{.c}
|
||||
* DIV_ROUND_CLOSEST(5, 2); // 3
|
||||
* DIV_ROUND_CLOSEST(5, -2); // -3
|
||||
* DIV_ROUND_CLOSEST(5, 3); // 2
|
||||
* @endcode
|
||||
*
|
||||
* @param n Numerator.
|
||||
* @param d Denominator.
|
||||
*
|
||||
* @return The result of @p n / @p d, rounded to the nearest integer.
|
||||
*/
|
||||
#define DIV_ROUND_CLOSEST(n, d) \
|
||||
((((n) < 0) ^ ((d) < 0)) ? ((n) - ((d) / 2)) / (d) : \
|
||||
((n) + ((d) / 2)) / (d))
|
||||
|
||||
#ifndef ceiling_fraction
|
||||
#define ceiling_fraction(numerator, divider) \
|
||||
(((numerator) + ((divider) - 1)) / (divider))
|
||||
@@ -125,6 +202,21 @@ extern "C" {
|
||||
#define BIT(n) (1UL << (n))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set or clear a bit depending on a boolean value
|
||||
*
|
||||
* The argument @p var is a variable whose value is written to as a
|
||||
* side effect.
|
||||
*
|
||||
* @param var Variable to be altered
|
||||
* @param bit Bit number
|
||||
* @param set if 0, clears @p bit in @p var; any other value sets @p bit
|
||||
*/
|
||||
#ifndef WRITE_BIT
|
||||
#define WRITE_BIT(var, bit, set) \
|
||||
((var) = (set) ? ((var) | BIT(bit)) : ((var) & ~BIT(bit)))
|
||||
#endif
|
||||
|
||||
#ifndef BIT_MASK
|
||||
#define BIT_MASK(n) (BIT(n) - 1)
|
||||
#endif
|
||||
@@ -219,6 +311,20 @@ const char *bt_hex(const void *buf, size_t len);
|
||||
|
||||
void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Checks if a value is within range.
|
||||
*
|
||||
* @note @p val is evaluated twice.
|
||||
*
|
||||
* @param val Value to be checked.
|
||||
* @param min Lower bound (inclusive).
|
||||
* @param max Upper bound (inclusive).
|
||||
*
|
||||
* @retval true If value is within range
|
||||
* @retval false If the value is not within range
|
||||
*/
|
||||
#define IN_RANGE(val, min, max) ((val) >= (min) && (val) <= (max))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016 Intel Corporation
|
||||
* SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -43,6 +43,28 @@ uint32_t k_uptime_get_32(void)
|
||||
return (uint32_t)(esp_timer_get_time() / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get elapsed time.
|
||||
*
|
||||
* This routine computes the elapsed time between the current system uptime
|
||||
* and an earlier reference time, in milliseconds.
|
||||
*
|
||||
* @param reftime Pointer to a reference time, which is updated to the current
|
||||
* uptime upon return.
|
||||
*
|
||||
* @return Elapsed time.
|
||||
*/
|
||||
int64_t k_uptime_delta(int64_t *reftime)
|
||||
{
|
||||
int64_t uptime, delta;
|
||||
|
||||
uptime = k_uptime_get();
|
||||
delta = uptime - *reftime;
|
||||
*reftime = uptime;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
void bt_mesh_timer_init(void)
|
||||
{
|
||||
bm_alarm_hash_map = hash_map_new(BLE_MESH_ALARM_HASH_MAP_SIZE,
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
extern const struct bt_mesh_comp *comp_0;
|
||||
static uint16_t dev_primary_addr;
|
||||
|
||||
static int model_send(struct bt_mesh_model *model,
|
||||
static int model_send(const struct bt_mesh_model *model,
|
||||
struct bt_mesh_net_tx *tx, bool implicit_bind,
|
||||
struct net_buf_simple *msg,
|
||||
const struct bt_mesh_send_cb *cb, void *cb_data);
|
||||
@@ -300,7 +300,7 @@ static void mod_publish(struct k_work *work)
|
||||
}
|
||||
}
|
||||
|
||||
struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod)
|
||||
struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod)
|
||||
{
|
||||
return &comp_0->elem[mod->elem_idx];
|
||||
}
|
||||
@@ -548,12 +548,31 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool bt_mesh_has_addr(uint16_t addr)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
if (BLE_MESH_ADDR_IS_UNICAST(addr)) {
|
||||
return bt_mesh_elem_find(addr) != NULL;
|
||||
}
|
||||
|
||||
for (index = 0; index < comp_0->elem_count; index++) {
|
||||
struct bt_mesh_elem *elem = &comp_0->elem[index];
|
||||
|
||||
if (bt_mesh_elem_find_group(elem, addr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t bt_mesh_elem_count(void)
|
||||
{
|
||||
return comp_0->elem_count;
|
||||
}
|
||||
|
||||
static bool model_has_key(struct bt_mesh_model *mod, uint16_t key)
|
||||
static bool model_has_key(const struct bt_mesh_model *mod, uint16_t key)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -635,7 +654,7 @@ static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode, bool pull_bu
|
||||
if (pull_buf) {
|
||||
*opcode = net_buf_simple_pull_u8(buf) << 16;
|
||||
/* Using LE for the CID since the model layer is defined as
|
||||
* little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
|
||||
* little-endian in the mesh spec and using BLE_MESH_MODEL_OP_3
|
||||
* will declare the opcode in this way.
|
||||
*/
|
||||
*opcode |= net_buf_simple_pull_le16(buf);
|
||||
@@ -793,7 +812,7 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, uint32_t opcode)
|
||||
case 3:
|
||||
net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff));
|
||||
/* Using LE for the CID since the model layer is defined as
|
||||
* little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
|
||||
* little-endian in the mesh spec and using BLE_MESH_MODEL_OP_3
|
||||
* will declare the opcode in this way.
|
||||
*/
|
||||
net_buf_simple_add_le16(msg, opcode & 0xffff);
|
||||
@@ -951,7 +970,7 @@ void bt_mesh_choose_better_security_cred(struct bt_mesh_net_tx *tx)
|
||||
}
|
||||
#endif /* !CONFIG_BLE_MESH_V11_SUPPORT */
|
||||
|
||||
static int model_send(struct bt_mesh_model *model,
|
||||
static int model_send(const struct bt_mesh_model *model,
|
||||
struct bt_mesh_net_tx *tx, bool implicit_bind,
|
||||
struct net_buf_simple *msg,
|
||||
const struct bt_mesh_send_cb *cb, void *cb_data)
|
||||
@@ -1041,7 +1060,7 @@ int bt_mesh_model_send_implicit(struct bt_mesh_model *model,
|
||||
return model_send(model, &tx, implicit_bind, msg, cb, cb_data);
|
||||
}
|
||||
|
||||
int bt_mesh_model_send(struct bt_mesh_model *model,
|
||||
int bt_mesh_model_send(const struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *msg,
|
||||
const struct bt_mesh_send_cb *cb, void *cb_data)
|
||||
|
||||
@@ -29,6 +29,8 @@ uint8_t bt_mesh_elem_count(void);
|
||||
/* Find local element based on unicast or group address */
|
||||
struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr);
|
||||
|
||||
bool bt_mesh_has_addr(uint16_t addr);
|
||||
|
||||
uint16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, uint16_t addr);
|
||||
|
||||
int bt_mesh_get_opcode(struct net_buf_simple *buf,
|
||||
|
||||
@@ -362,6 +362,10 @@ void bt_mesh_adv_update(void)
|
||||
|
||||
void bt_mesh_adv_init(void)
|
||||
{
|
||||
bt_mesh_adv_common_init();
|
||||
adv_queue = bt_mesh_adv_queue_get();
|
||||
|
||||
assert(adv_queue && adv_queue->q.handle && adv_queue->send);
|
||||
|
||||
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
bt_mesh_relay_adv_init();
|
||||
@@ -370,10 +374,6 @@ void bt_mesh_adv_init(void)
|
||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||
bt_mesh_ble_adv_init();
|
||||
#endif
|
||||
bt_mesh_adv_common_init();
|
||||
adv_queue = bt_mesh_adv_queue_get();
|
||||
|
||||
assert(adv_queue && adv_queue->q.handle && adv_queue->send);
|
||||
|
||||
#if CONFIG_BLE_MESH_RELAY_ADV_BUF && !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||
QueueHandle_t relay_adv_handle =
|
||||
|
||||
@@ -748,6 +748,12 @@ uint16_t ble_mesh_adv_buf_count_get(void)
|
||||
adv_count += CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (CONFIG_BLE_MESH_SUPPORT_BLE_ADV && \
|
||||
!(CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE))
|
||||
adv_count += CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT;
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
||||
|
||||
return adv_count;
|
||||
}
|
||||
|
||||
@@ -822,13 +828,13 @@ void bt_mesh_adv_common_init(void)
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_PROV);
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_DATA);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
#if CONFIG_BLE_MESH_RELAY && !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_PROV);
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_DATA);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
#if CONFIG_BLE_MESH_RELAY && !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -15,8 +15,12 @@
|
||||
#include "mesh/buf.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||
/* Use independent ble adv queue only if multi adv instance is used */
|
||||
static struct bt_mesh_adv_queue ble_adv_queue;
|
||||
static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||
#endif
|
||||
static struct bt_mesh_adv_queue *p_ble_adv_queue;
|
||||
#define BLE_MESH_BLE_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
|
||||
/* length + advertising data + length + scan response data */
|
||||
NET_BUF_POOL_DEFINE(ble_adv_buf_pool, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT,
|
||||
@@ -28,8 +32,6 @@ static struct bt_mesh_ble_adv_tx ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
|
||||
|
||||
#define SEND_BLE_ADV_INFINITE 0xFFFF
|
||||
|
||||
static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||
|
||||
static struct bt_mesh_adv *ble_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
memset(&ble_adv_pool[id], 0, sizeof(struct bt_mesh_adv));
|
||||
@@ -37,27 +39,30 @@ static struct bt_mesh_adv *ble_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
return &ble_adv_pool[id];
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||
/* A separate post function is required only when using a separate queue */
|
||||
static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
|
||||
{
|
||||
BT_DBG("%s", __func__);
|
||||
|
||||
if (ble_adv_queue.q.handle == NULL) {
|
||||
if (p_ble_adv_queue->q.handle == NULL) {
|
||||
BT_ERR("Invalid adv queue");
|
||||
return;
|
||||
}
|
||||
|
||||
if (front) {
|
||||
if (xQueueSendToFront(ble_adv_queue.q.handle, msg, timeout) != pdTRUE) {
|
||||
if (xQueueSendToFront(p_ble_adv_queue->q.handle, msg, timeout) != pdTRUE) {
|
||||
BT_ERR("Failed to send item to adv queue front");
|
||||
bt_mesh_unref_buf(msg);
|
||||
}
|
||||
} else {
|
||||
if (xQueueSend(ble_adv_queue.q.handle, msg, timeout) != pdTRUE) {
|
||||
if (xQueueSend(p_ble_adv_queue->q.handle, msg, timeout) != pdTRUE) {
|
||||
BT_ERR("Failed to send item to adv queue back");
|
||||
bt_mesh_unref_buf(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct net_buf *bt_mesh_ble_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
|
||||
{
|
||||
@@ -282,10 +287,20 @@ int bt_mesh_stop_ble_advertising(uint8_t index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct bt_mesh_adv_queue *bt_mesh_ble_adv_queue_get(void)
|
||||
{
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||
bt_mesh_adv_queue_init(&ble_adv_queue, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT, bt_mesh_ble_task_post);
|
||||
return &ble_adv_queue;
|
||||
#else
|
||||
return bt_mesh_adv_queue_get();
|
||||
#endif
|
||||
}
|
||||
|
||||
void bt_mesh_ble_adv_init(void)
|
||||
{
|
||||
bt_mesh_adv_queue_init(&ble_adv_queue, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT, bt_mesh_ble_task_post);
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_BLE, &ble_adv_queue, &ble_adv_buf_pool, ble_adv_alloc);
|
||||
p_ble_adv_queue = bt_mesh_ble_adv_queue_get();
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_BLE, p_ble_adv_queue, &ble_adv_buf_pool, ble_adv_alloc);
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||
bt_mesh_adv_inst_init(BLE_MESH_BLE_ADV_INS, CONFIG_BLE_MESH_BLE_ADV_INST_ID);
|
||||
@@ -308,7 +323,11 @@ void bt_mesh_ble_adv_deinit(void)
|
||||
bt_mesh_unref_buf_from_pool(&ble_adv_buf_pool);
|
||||
memset(ble_adv_pool, 0, sizeof(ble_adv_pool));
|
||||
|
||||
bt_mesh_adv_queue_deinit(&ble_adv_queue);
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||
/* In other cases, ble_adv queue is an adv queue,
|
||||
* so ble does not need to deinit separately */
|
||||
bt_mesh_adv_queue_deinit(p_ble_adv_queue);
|
||||
#endif
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_BLE);
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||
|
||||
@@ -929,20 +929,6 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
||||
tBTA_DM_BLE_EXT_ADV ext_adv = {0};
|
||||
struct bt_mesh_hci_cp_set_adv_data set = {0};
|
||||
|
||||
if (data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
|
||||
param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
|
||||
if (data->adv_data_len) {
|
||||
set.len = data->adv_data_len;
|
||||
memcpy(set.data, data->adv_data, data->adv_data_len);
|
||||
BTA_DmBleGapConfigExtAdvDataRaw(false, inst_id, set.len, set.data);
|
||||
}
|
||||
if (data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
|
||||
set.len = data->scan_rsp_data_len;
|
||||
memcpy(set.data, data->scan_rsp_data, data->scan_rsp_data_len);
|
||||
BTA_DmBleGapConfigExtAdvDataRaw(true, inst_id, set.len, set.data);
|
||||
}
|
||||
}
|
||||
|
||||
switch (param->adv_type) {
|
||||
case BLE_MESH_ADV_IND:
|
||||
case BLE_MESH_ADV_DIRECT_IND:
|
||||
@@ -983,6 +969,20 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
||||
/* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
|
||||
BTA_DmBleGapExtAdvSetParams(inst_id, &ext_adv_params);
|
||||
|
||||
if (data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
|
||||
param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
|
||||
if (data->adv_data_len) {
|
||||
set.len = data->adv_data_len;
|
||||
memcpy(set.data, data->adv_data, data->adv_data_len);
|
||||
BTA_DmBleGapConfigExtAdvDataRaw(false, inst_id, set.len, set.data);
|
||||
}
|
||||
if (data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
|
||||
set.len = data->scan_rsp_data_len;
|
||||
memcpy(set.data, data->scan_rsp_data, data->scan_rsp_data_len);
|
||||
BTA_DmBleGapConfigExtAdvDataRaw(true, inst_id, set.len, set.data);
|
||||
}
|
||||
}
|
||||
|
||||
BTA_DmBleGapExtAdvEnable(true, 1, &ext_adv);
|
||||
|
||||
#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "mesh/config.h"
|
||||
#include "mesh/buf.h"
|
||||
#include "mesh/timer.h"
|
||||
#include "sys/types.h"
|
||||
|
||||
/**
|
||||
* @brief Bluetooth Mesh Access Layer
|
||||
@@ -151,8 +152,15 @@ struct bt_mesh_elem {
|
||||
#define BLE_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
|
||||
#define BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV 0x1310
|
||||
#define BLE_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311
|
||||
#define BLE_MESH_MODEL_ID_MBT_SRV 0x1400
|
||||
#define BLE_MESH_MODEL_ID_MBT_CLI 0x1401
|
||||
#define BLE_MESH_MODEL_ID_BLOB_SRV 0x1400
|
||||
#define BLE_MESH_MODEL_ID_BLOB_CLI 0x1401
|
||||
#define BLE_MESH_MODEL_ID_DFU_SRV 0x1402
|
||||
#define BLE_MESH_MODEL_ID_DFU_CLI 0x1403
|
||||
#define BLE_MESH_MODEL_ID_DFD_SRV 0x1404
|
||||
#define BLE_MESH_MODEL_ID_DFD_CLI 0x1405
|
||||
|
||||
#define BLE_MESH_MODEL_ID_MBT_SRV BLE_MESH_MODEL_ID_BLOB_SRV
|
||||
#define BLE_MESH_MODEL_ID_MBT_CLI BLE_MESH_MODEL_ID_BLOB_CLI
|
||||
|
||||
typedef struct {
|
||||
uint32_t adv_itvl;
|
||||
@@ -520,6 +528,8 @@ struct bt_mesh_model_pub {
|
||||
.update = _update, \
|
||||
}
|
||||
|
||||
typedef ssize_t (*settings_read_cb)(void *cb_arg, void *data, size_t len);
|
||||
|
||||
/** Model callback functions. */
|
||||
struct bt_mesh_model_cb {
|
||||
/** @brief Model init callback.
|
||||
@@ -613,7 +623,7 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, uint32_t opcode);
|
||||
*
|
||||
* @return 0 on success, or (negative) error code on failure.
|
||||
*/
|
||||
int bt_mesh_model_send(struct bt_mesh_model *model,
|
||||
int bt_mesh_model_send(const struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *msg,
|
||||
const struct bt_mesh_send_cb *cb,
|
||||
@@ -642,7 +652,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model);
|
||||
*
|
||||
* @return Pointer to the element that the given model belongs to.
|
||||
*/
|
||||
struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod);
|
||||
struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod);
|
||||
|
||||
/** @brief Find a SIG model.
|
||||
*
|
||||
|
||||
@@ -430,6 +430,9 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
|
||||
#endif
|
||||
adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND &&
|
||||
adv_rpt->adv_type != BLE_MESH_ADV_IND
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
&& adv_rpt->adv_type != BLE_MESH_EXT_ADV_NONCONN_IND
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
|
||||
&& adv_rpt->adv_type != BLE_MESH_ADV_SCAN_RSP
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -45,10 +45,12 @@
|
||||
* key: "mesh/s/xxxx/b" -> write/read to set/get SIG MODEL Bind AppKey List
|
||||
* key: "mesh/s/xxxx/s" -> write/read to set/get SIG MODEL Subscription List
|
||||
* key: "mesh/s/xxxx/p" -> write/read to set/get SIG MODEL Publication
|
||||
* key: "mesh/s/xxxx/d" -> write/read to set/get SIG MODEL Data
|
||||
* key: "mesh/vnd" -> write/read to set/get all VENDOR MODEL model_keys.
|
||||
* key: "mesh/v/xxxx/b" -> write/read to set/get VENDOR MODEL Bind AppKey List
|
||||
* key: "mesh/v/xxxx/s" -> write/read to set/get VENDOR MODEL Subscription List
|
||||
* key: "mesh/v/xxxx/p" -> write/read to set/get VENDOR MODEL Publication
|
||||
* key: "mesh/v/xxxx/d" -> write/read to set/get VENDOR MODEL Data
|
||||
* key: "mesh/vaddr" -> write/read to set/get all virtual addresses
|
||||
* key: "mesh/va/xxxx" -> write/read to set/get the "xxxx" virtual address
|
||||
* key: "mesh/dkca" -> write/read to set/get Device Key Candidate
|
||||
@@ -2731,3 +2733,40 @@ void bt_mesh_settings_reset(bool erase)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLE_MESH_SETTINGS */
|
||||
|
||||
#define SETTINGS_MAX_DIR_DEPTH 8
|
||||
|
||||
int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
|
||||
const char *name, const void *data,
|
||||
size_t data_len)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
char path[30] = {'\0'};
|
||||
uint16_t model_key = 0U;
|
||||
|
||||
model_key = BLE_MESH_GET_MODEL_KEY(mod->elem_idx, mod->model_idx);
|
||||
sprintf(path, "mesh/%s/%04x/d", vnd ? "v" : "s", model_key);
|
||||
if (name) {
|
||||
strcat(path, "/");
|
||||
strncat(path, name, SETTINGS_MAX_DIR_DEPTH);
|
||||
}
|
||||
|
||||
if (data_len) {
|
||||
err = bt_mesh_save_core_settings(path, data, data_len);
|
||||
if (err) {
|
||||
BT_ERR("Failed to store %s", path);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = bt_mesh_add_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key);
|
||||
if (err) {
|
||||
BT_ERR("Failed to add model data to %s, model_key 0x%04x",
|
||||
vnd ? "mesh/vnd" : "mesh/sig", model_key);
|
||||
}
|
||||
} else {
|
||||
bt_mesh_erase_core_settings(path);
|
||||
bt_mesh_remove_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ void bt_mesh_store_mod_sub(struct bt_mesh_model *mod);
|
||||
void bt_mesh_store_mod_pub(struct bt_mesh_model *mod);
|
||||
void bt_mesh_store_label(void);
|
||||
|
||||
int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
|
||||
const char *name, const void *data,
|
||||
size_t data_len);
|
||||
|
||||
void bt_mesh_clear_role(void);
|
||||
void bt_mesh_clear_net(void);
|
||||
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
@@ -800,16 +800,19 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (tx->ctx->enh.long_pkt_cfg_used == true &&
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE ||
|
||||
tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER) &&
|
||||
msg->len > BLE_MESH_EXT_SDU_UNSEG_MAX) {
|
||||
if (tx->ctx->enh.long_pkt_cfg_used == true) {
|
||||
if (tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE &&
|
||||
msg->len > BLE_MESH_EXT_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
} else if (tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER &&
|
||||
msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
} else {
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
|
||||
@@ -1151,11 +1151,14 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (tx->ctx->enh.long_pkt_cfg_used == true &&
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE ||
|
||||
tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER) &&
|
||||
msg->len > BLE_MESH_EXT_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
if (tx->ctx->enh.long_pkt_cfg_used == true) {
|
||||
if (tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE &&
|
||||
msg->len > BLE_MESH_EXT_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
} else if (tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER &&
|
||||
msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
}
|
||||
} else {
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define _TRANSPORT_H_
|
||||
|
||||
#include "net.h"
|
||||
#include "access.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -183,12 +183,28 @@ static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
|
||||
{
|
||||
int32_t seg_rtx_to = 0, duration = 0, time = 0;
|
||||
uint8_t seg_count = 0, seg_rtx_num = 0;
|
||||
bool need_seg = false;
|
||||
bool need_seg = bt_mesh_tag_send_segmented(ctx->send_tag);
|
||||
uint8_t mic_size = 0;
|
||||
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX ||
|
||||
bt_mesh_tag_send_segmented(ctx->send_tag)) {
|
||||
need_seg = true; /* Needs segmentation */
|
||||
if (!need_seg) {
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (ctx->enh.long_pkt_cfg_used == true) {
|
||||
if ((ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE &&
|
||||
msg->len > BLE_MESH_EXT_SDU_UNSEG_MAX) ||
|
||||
(ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER &&
|
||||
msg->len > BLE_MESH_SDU_UNSEG_MAX)) {
|
||||
need_seg = true; /* Needs segmentation */
|
||||
}
|
||||
} else {
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
need_seg = true; /* Needs segmentation */
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
need_seg = true; /* Needs segmentation */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
mic_size = (need_seg && ctx->send_szmic == BLE_MESH_SEG_SZMIC_LONG &&
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "btc/btc_manage.h"
|
||||
|
||||
#include "btc_ble_mesh_dfu_model.h"
|
||||
#include "esp_ble_mesh_dfu_model_api.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
|
||||
static bool is_get_param_needed(esp_ble_mesh_opcode_t opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK:
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_START:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_dfu_client_get_state(esp_ble_mesh_client_common_param_t *params,
|
||||
esp_ble_mesh_dfu_client_get_t *get)
|
||||
{
|
||||
btc_ble_mesh_dfu_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (params == NULL || params->model == NULL ||
|
||||
params->ctx.net_idx == ESP_BLE_MESH_KEY_UNUSED ||
|
||||
!ESP_BLE_MESH_ADDR_IS_UNICAST(params->ctx.addr) ||
|
||||
(is_get_param_needed(params->opcode) && get == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_DFU_CLIENT;
|
||||
msg.act = BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE;
|
||||
|
||||
arg.dfu_get.params = params;
|
||||
arg.dfu_get.get = get;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfu_client_args_t),
|
||||
btc_ble_mesh_dfu_client_arg_deep_copy,
|
||||
btc_ble_mesh_dfu_client_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_dfu_cli_img_send(esp_ble_mesh_dfu_cli_t *cli,
|
||||
esp_ble_mesh_blob_cli_inputs_t *inputs,
|
||||
esp_ble_mesh_blob_io_t *io,
|
||||
esp_ble_mesh_dfu_cli_xfer_t *xfer)
|
||||
{
|
||||
btc_ble_mesh_dfu_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (cli == NULL || inputs == NULL ||
|
||||
io == NULL || xfer == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_DFU_CLIENT;
|
||||
msg.act = BTC_BLE_MESH_ACT_DFU_CLIENT_IMG_SEND;
|
||||
|
||||
arg.send_arg.cli = cli;
|
||||
arg.send_arg.inputs = inputs;
|
||||
arg.send_arg.io = io;
|
||||
arg.send_arg.xfer = xfer;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfu_client_args_t),
|
||||
NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
uint8_t esp_ble_mesh_dfu_cli_progress(esp_ble_mesh_dfu_cli_t *cli)
|
||||
{
|
||||
if (!cli) {
|
||||
return 0;
|
||||
}
|
||||
return btc_ble_mesh_dfu_cli_progress(cli);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_register_dfu_client_callback(esp_ble_mesh_dfu_client_cb_t callback)
|
||||
{
|
||||
return (btc_profile_cb_set(BTC_PID_DFU_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
void esp_ble_mesh_dfu_srv_verified(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
if (!srv) {
|
||||
return;
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_srv_verified(srv);
|
||||
}
|
||||
|
||||
void esp_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
if (!srv) {
|
||||
return;
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_srv_rejected(srv);
|
||||
}
|
||||
|
||||
void esp_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
if (!srv) {
|
||||
return;
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_srv_cancel(srv);
|
||||
}
|
||||
|
||||
void esp_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
if (!srv) {
|
||||
return;
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_srv_applied(srv);
|
||||
}
|
||||
|
||||
bool esp_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
if (!srv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_srv_is_busy(srv);
|
||||
}
|
||||
|
||||
uint8_t esp_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
if (!srv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_srv_progress(srv);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_ble_mesh_dfu_slot_api.h"
|
||||
#include "btc_ble_mesh_dfu_slot.h"
|
||||
|
||||
int esp_ble_mesh_dfu_slot_count(void)
|
||||
{
|
||||
return btc_ble_mesh_dfu_slot_count();
|
||||
}
|
||||
|
||||
esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_reserve(void)
|
||||
{
|
||||
return btc_ble_mesh_dfu_slot_reserve();
|
||||
}
|
||||
|
||||
int esp_ble_mesh_dfu_slot_info_set(esp_ble_mesh_dfu_slot_t *dfu_slot, size_t size,
|
||||
const uint8_t *metadata, size_t metadata_len)
|
||||
{
|
||||
if (!dfu_slot || !metadata ||
|
||||
metadata_len == 0 ||
|
||||
metadata_len > CONFIG_BLE_MESH_DFU_METADATA_MAXLEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_slot_info_set(dfu_slot, size,
|
||||
metadata, metadata_len);
|
||||
}
|
||||
|
||||
int esp_ble_mesh_dfu_slot_fwid_set(esp_ble_mesh_dfu_slot_t *dfu_slot,
|
||||
const uint8_t *fwid, size_t fwid_len)
|
||||
{
|
||||
if (!dfu_slot || !fwid || fwid_len == 0 ||
|
||||
fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_slot_fwid_set(dfu_slot, fwid,
|
||||
fwid_len);
|
||||
}
|
||||
|
||||
int esp_ble_mesh_dfu_slot_commit(esp_ble_mesh_dfu_slot_t *dfu_slot)
|
||||
{
|
||||
if (!dfu_slot) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_slot_commit(dfu_slot);
|
||||
}
|
||||
|
||||
void esp_ble_mesh_dfu_slot_release(const esp_ble_mesh_dfu_slot_t *dfu_slot)
|
||||
{
|
||||
if (!dfu_slot) {
|
||||
return;
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_slot_release(dfu_slot);
|
||||
}
|
||||
|
||||
int esp_ble_mesh_dfu_slot_del(const esp_ble_mesh_dfu_slot_t *slot)
|
||||
{
|
||||
if (!slot) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_slot_del(slot);
|
||||
}
|
||||
|
||||
void esp_ble_mesh_dfu_slot_del_all(void)
|
||||
{
|
||||
btc_ble_mesh_dfu_slot_del_all();
|
||||
}
|
||||
|
||||
const esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_at(uint16_t img_idx)
|
||||
{
|
||||
return btc_ble_mesh_dfu_slot_at(img_idx);
|
||||
}
|
||||
|
||||
int esp_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, esp_ble_mesh_dfu_slot_t **slot)
|
||||
{
|
||||
if (!fwid || fwid_len == 0 ||
|
||||
fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN ||
|
||||
!slot || !*slot) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_slot_get(fwid, fwid_len, slot);
|
||||
}
|
||||
|
||||
int esp_ble_mesh_dfu_slot_img_idx_get(const esp_ble_mesh_dfu_slot_t *slot)
|
||||
{
|
||||
if (!slot) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_dfu_slot_img_idx_get(slot);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -20,20 +20,20 @@ extern int bt_mesh_get_transfer_progress(void *model, uint16_t unicast_addr,
|
||||
uint8_t *block_percent, uint8_t *chunk_percent);
|
||||
extern int bt_mesh_get_blob_reception_progress(void *model, uint8_t *reception_progress);
|
||||
|
||||
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback)
|
||||
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback) __attribute__((deprecated))
|
||||
{
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
return (btc_profile_cb_set(BTC_PID_MBT_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (input == NULL || input->model == NULL ||
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -51,14 +51,14 @@ esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_ca
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (input == NULL || input->model == NULL ||
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL) ||
|
||||
input->blob_data == NULL) {
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL) ||
|
||||
input->blob_data == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *in
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -97,7 +97,7 @@ esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -118,7 +118,7 @@ esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -139,13 +139,13 @@ esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (input == NULL || input->model == NULL ||
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -163,13 +163,13 @@ esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determi
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (input == NULL || input->model == NULL ||
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
|
||||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -188,13 +188,13 @@ esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t
|
||||
}
|
||||
|
||||
const esp_ble_mesh_blob_receiver_t *esp_ble_mesh_mbt_client_get_blob_receiver(esp_ble_mesh_model_t *model,
|
||||
uint16_t unicast_addr)
|
||||
uint16_t unicast_addr) __attribute__((deprecated))
|
||||
{
|
||||
return (const esp_ble_mesh_blob_receiver_t *)bt_mesh_get_blob_receiver((struct bt_mesh_model *)model,
|
||||
unicast_addr);
|
||||
}
|
||||
|
||||
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model)
|
||||
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model) __attribute__((deprecated))
|
||||
{
|
||||
return (const esp_ble_mesh_blob_receiver_t **)bt_mesh_get_active_blob_receiver((struct bt_mesh_model *)model);
|
||||
}
|
||||
@@ -202,14 +202,14 @@ const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_rec
|
||||
esp_err_t esp_ble_mesh_mbt_client_get_transfer_progress(esp_ble_mesh_model_t *model,
|
||||
uint16_t unicast_addr,
|
||||
uint8_t *block_percent,
|
||||
uint8_t *chunk_percent)
|
||||
uint8_t *chunk_percent) __attribute__((deprecated))
|
||||
{
|
||||
return (bt_mesh_get_transfer_progress((struct bt_mesh_model *)model, unicast_addr,
|
||||
block_percent, chunk_percent) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_set_transfer_ttl(esp_ble_mesh_model_t *model,
|
||||
uint8_t transfer_ttl)
|
||||
uint8_t transfer_ttl) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -231,7 +231,7 @@ esp_err_t esp_ble_mesh_mbt_client_set_transfer_ttl(esp_ble_mesh_model_t *model,
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model)
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -253,7 +253,7 @@ esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_set_app_idx(esp_ble_mesh_model_t *model,
|
||||
uint16_t app_idx)
|
||||
uint16_t app_idx) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -275,7 +275,7 @@ esp_err_t esp_ble_mesh_mbt_client_set_app_idx(esp_ble_mesh_model_t *model,
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model)
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -297,7 +297,7 @@ esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model)
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_set_multicast_addr(esp_ble_mesh_model_t *model,
|
||||
uint16_t multicast_addr)
|
||||
uint16_t multicast_addr) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -319,7 +319,7 @@ esp_err_t esp_ble_mesh_mbt_client_set_multicast_addr(esp_ble_mesh_model_t *model
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model)
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_client_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -342,14 +342,14 @@ esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *mod
|
||||
#endif /* CONFIG_BLE_MESH_MBT_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_MBT_SRV
|
||||
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback)
|
||||
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback) __attribute__((deprecated))
|
||||
{
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
return (btc_profile_cb_set(BTC_PID_MBT_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_server_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -370,7 +370,7 @@ esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initializ
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_server_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -391,7 +391,7 @@ esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_r
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input)
|
||||
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input) __attribute__((deprecated))
|
||||
{
|
||||
btc_ble_mesh_mbt_server_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
@@ -413,7 +413,7 @@ esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_ca
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_mbt_server_get_blob_reception_progress(esp_ble_mesh_model_t *model,
|
||||
uint8_t *reception_progress)
|
||||
uint8_t *reception_progress) __attribute__((deprecated))
|
||||
{
|
||||
return (bt_mesh_get_blob_reception_progress((struct bt_mesh_model *)model,
|
||||
reception_progress) == 0 ? ESP_OK : ESP_FAIL);
|
||||
|
||||
@@ -0,0 +1,696 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_BLE_MESH_BLOB_MODEL_API_H_
|
||||
#define _ESP_BLE_MESH_BLOB_MODEL_API_H_
|
||||
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
#include "esp_ble_mesh_blob_model_api.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV
|
||||
#ifndef _BLE_MESH_BLOB_DEPRECATE_WARN
|
||||
#define _BLE_MESH_BLOB_DEPRECATE_WARN
|
||||
#warning Please note: All APIs published in this document are in Preview version and may undergo significant changes in the future.
|
||||
#endif
|
||||
#endif /* CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_BLE_MESH_BLOB_ID_SIZE 8
|
||||
|
||||
/** @def ESP_BLE_MESH_MODEL_BLOB_CLI
|
||||
*
|
||||
* @brief Define a new BLOB Transfer Client model.
|
||||
*
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a BLOB Transfer Client model.
|
||||
*
|
||||
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
|
||||
*
|
||||
* @return New BLOB Transfer Client model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_MODEL_BLOB_CLI(cli_pub, cli_data) \
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_BLOB_CLI, \
|
||||
NULL, cli_pub, cli_data)
|
||||
|
||||
/** @def ESP_BLE_MESH_MODEL_BLOB_SRV
|
||||
*
|
||||
* @brief Define a new BLOB Transfer Server model.
|
||||
*
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a BLOB Transfer Server model.
|
||||
*
|
||||
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param srv_data Pointer to the unique struct esp_ble_mesh_blob_trans_srv_t.
|
||||
*
|
||||
* @return New BLOB Transfer Server model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_MODEL_BLOB_SRV(srv_pub, srv_data) \
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_BLOB_SRV, \
|
||||
NULL, srv_pub, srv_data)
|
||||
|
||||
|
||||
/** BLOB stream. */
|
||||
typedef struct esp_ble_mesh_blob_io esp_ble_mesh_blob_io_t;
|
||||
|
||||
/** @brief BLOB Transfer Server instance. */
|
||||
typedef struct esp_ble_mesh_blob_srv esp_ble_mesh_blob_srv_t;
|
||||
|
||||
/** @brief BLOB Transfer Server model event handlers. */
|
||||
typedef struct esp_ble_mesh_blob_srv_cb esp_ble_mesh_blob_srv_cb_t;
|
||||
|
||||
/** Target node's Pull mode (Pull BLOB Transfer Mode) context used
|
||||
* while sending chunks to the Target node.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_blob_target_pull esp_ble_mesh_blob_target_pull_t;
|
||||
|
||||
/** BLOB Transfer Client Target node. */
|
||||
typedef struct esp_ble_mesh_blob_target esp_ble_mesh_blob_target_t;
|
||||
|
||||
/** BLOB transfer information. */
|
||||
typedef struct esp_ble_mesh_blob_xfer_info esp_ble_mesh_blob_xfer_info_t;
|
||||
|
||||
/** BLOB Transfer Client transfer inputs. */
|
||||
typedef struct esp_ble_mesh_blob_cli_inputs esp_ble_mesh_blob_cli_inputs_t;
|
||||
|
||||
/** Transfer capabilities of a Target node. */
|
||||
typedef struct esp_ble_mesh_blob_cli_caps esp_ble_mesh_blob_cli_caps_t;
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client model instance.
|
||||
* @note Preview version, the contents of this struct may change in the future.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_blob_cli esp_ble_mesh_blob_cli_t;
|
||||
|
||||
/** Event handler callbacks for the BLOB Transfer Client model. */
|
||||
typedef struct esp_ble_mesh_blob_cli_cb esp_ble_mesh_blob_cli_cb_t;
|
||||
|
||||
/** BLOB transfer. */
|
||||
typedef struct esp_ble_mesh_blob_xfer esp_ble_mesh_blob_xfer_t;
|
||||
|
||||
/** BLOB transfer data block. */
|
||||
typedef struct esp_ble_mesh_blob_block esp_ble_mesh_blob_block_t;
|
||||
|
||||
/** BLOB data chunk. */
|
||||
typedef struct esp_ble_mesh_blob_chunk esp_ble_mesh_blob_chunk_t;
|
||||
|
||||
/** Transfer phase. */
|
||||
typedef enum esp_ble_mesh_blob_xfer_phase {
|
||||
ESP_BLE_MESH_BLOB_XFER_PHASE_INACTIVE, /*!< The BLOB Transfer Server is awaiting configuration. */
|
||||
ESP_BLE_MESH_BLOB_XFER_PHASE_WAITING_FOR_START, /*!< The BLOB Transfer Server is ready to receive a BLOB transfer. */
|
||||
ESP_BLE_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK, /*!< The BLOB Transfer Server is waiting for the next block of data. */
|
||||
ESP_BLE_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK, /*!< The BLOB Transfer Server is waiting for the next chunk of data. */
|
||||
ESP_BLE_MESH_BLOB_XFER_PHASE_COMPLETE, /*!< The BLOB was transferred successfully. */
|
||||
ESP_BLE_MESH_BLOB_XFER_PHASE_SUSPENDED, /*!< The BLOB transfer is paused. */
|
||||
} esp_ble_mesh_blob_xfer_phase_t;
|
||||
|
||||
/** BLOB transfer mode. */
|
||||
typedef enum esp_ble_mesh_blob_xfer_mode {
|
||||
ESP_BLE_MESH_BLOB_XFER_MODE_NONE, /*!< No valid transfer mode. */
|
||||
ESP_BLE_MESH_BLOB_XFER_MODE_PUSH, /*!< Push mode (Push BLOB Transfer Mode). */
|
||||
ESP_BLE_MESH_BLOB_XFER_MODE_PULL, /*!< Pull mode (Pull BLOB Transfer Mode). */
|
||||
ESP_BLE_MESH_BLOB_XFER_MODE_ALL, /*!< Both modes are valid. */
|
||||
} esp_ble_mesh_blob_xfer_mode_t;
|
||||
|
||||
/** BLOB model status codes. */
|
||||
typedef enum esp_ble_mesh_blob_status {
|
||||
/** The message was processed successfully. */
|
||||
ESP_BLE_MESH_BLOB_SUCCESS,
|
||||
/** The Block Number field value is not within the range of blocks being
|
||||
* transferred.
|
||||
*/
|
||||
ESP_BLE_MESH_BLOB_ERR_INVALID_BLOCK_NUM,
|
||||
/** The block size is smaller than the size indicated by the Min Block
|
||||
* Size Log state or is larger than the size indicated by the Max Block
|
||||
* Size Log state.
|
||||
*/
|
||||
ESP_BLE_MESH_BLOB_ERR_INVALID_BLOCK_SIZE,
|
||||
/** The chunk size exceeds the size indicated by the Max Chunk Size
|
||||
* state, or the number of chunks exceeds the number specified by the
|
||||
* Max Total Chunks state.
|
||||
*/
|
||||
ESP_BLE_MESH_BLOB_ERR_INVALID_CHUNK_SIZE,
|
||||
/** The operation cannot be performed while the server is in the current
|
||||
* phase.
|
||||
*/
|
||||
ESP_BLE_MESH_BLOB_ERR_WRONG_PHASE,
|
||||
/** A parameter value in the message cannot be accepted. */
|
||||
ESP_BLE_MESH_BLOB_ERR_INVALID_PARAM,
|
||||
/** The message contains a BLOB ID value that is not expected. */
|
||||
ESP_BLE_MESH_BLOB_ERR_WRONG_BLOB_ID,
|
||||
/** There is not enough space available in memory to receive the BLOB.
|
||||
*/
|
||||
ESP_BLE_MESH_BLOB_ERR_BLOB_TOO_LARGE,
|
||||
/** The transfer mode is not supported by the BLOB Transfer Server
|
||||
* model.
|
||||
*/
|
||||
ESP_BLE_MESH_BLOB_ERR_UNSUPPORTED_MODE,
|
||||
/** An internal error occurred on the node. */
|
||||
ESP_BLE_MESH_BLOB_ERR_INTERNAL,
|
||||
/** The requested information cannot be provided while the server is in
|
||||
* the current phase.
|
||||
*/
|
||||
ESP_BLE_MESH_BLOB_ERR_INFO_UNAVAILABLE,
|
||||
} esp_ble_mesh_blob_status_t;
|
||||
|
||||
/** BLOB Transfer Client state. */
|
||||
typedef enum esp_ble_mesh_blob_cli_state {
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_NONE, /*!< No transfer is active. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_CAPS_GET, /*!< Retrieving transfer capabilities. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_START, /*!< Sending transfer start. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_BLOCK_START, /*!< Sending block start. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_BLOCK_SEND, /*!< Sending block chunks. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_BLOCK_CHECK, /*!< Checking block status. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_XFER_CHECK, /*!< Checking transfer status. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_CANCEL, /*!< Cancelling transfer. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_SUSPENDED, /*!< Transfer is suspended. */
|
||||
ESP_BLE_MESH_BLOB_CLI_STATE_XFER_PROGRESS_GET, /*!< Checking transfer progress. */
|
||||
} esp_ble_mesh_blob_cli_state_t;
|
||||
|
||||
/** BLOB stream interaction mode. */
|
||||
typedef enum esp_ble_mesh_blob_io_mode {
|
||||
ESP_BLE_MESH_BLOB_READ, /*!< Read data from the stream. */
|
||||
ESP_BLE_MESH_BLOB_WRITE, /*!< Write data to the stream. */
|
||||
} esp_ble_mesh_blob_io_mode_t;
|
||||
|
||||
/** BLOB transfer. */
|
||||
struct esp_ble_mesh_blob_xfer {
|
||||
uint64_t id; /*!< BLOB ID. */
|
||||
size_t size; /*!< Total BLOB size in bytes. */
|
||||
esp_ble_mesh_blob_xfer_mode_t mode; /*!< BLOB transfer mode. */
|
||||
uint8_t block_size_log; /*!< Logarithmic representation of the block size. */
|
||||
uint16_t chunk_size; /*!< Base chunk size. May be smaller for the last chunk. */
|
||||
};
|
||||
|
||||
/** BLOB transfer data block. */
|
||||
struct esp_ble_mesh_blob_block {
|
||||
size_t size; /*!< Block size in bytes */
|
||||
off_t offset; /*!< Offset in bytes from the start of the BLOB. */
|
||||
uint16_t number; /*!< Block number */
|
||||
uint16_t chunk_count; /*!< Number of chunks in block. */
|
||||
uint8_t missing[DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX,
|
||||
8)]; /*!< Bitmap of missing chunks. */
|
||||
};
|
||||
|
||||
/** BLOB data chunk. */
|
||||
struct esp_ble_mesh_blob_chunk {
|
||||
off_t offset; /*!< Offset of the chunk data from the start of the block. */
|
||||
size_t size; /*!< Chunk data size. */
|
||||
uint8_t *data; /*!< Chunk data. */
|
||||
};
|
||||
|
||||
/** BLOB stream. */
|
||||
struct esp_ble_mesh_blob_io {
|
||||
/** @brief Open callback.
|
||||
*
|
||||
* Called when the reader is opened for reading.
|
||||
*
|
||||
* @param io BLOB stream.
|
||||
* @param xfer BLOB transfer.
|
||||
* @param mode Direction of the stream (read/write).
|
||||
*
|
||||
* @return 0 on success, or (negative) error code otherwise.
|
||||
*/
|
||||
int (*open)(const esp_ble_mesh_blob_io_t *io,
|
||||
const esp_ble_mesh_blob_xfer_t *xfer,
|
||||
esp_ble_mesh_blob_io_mode_t mode);
|
||||
|
||||
/** @brief Close callback.
|
||||
*
|
||||
* Called when the reader is closed.
|
||||
*
|
||||
* @param io BLOB stream.
|
||||
* @param xfer BLOB transfer.
|
||||
*/
|
||||
void (*close)(const esp_ble_mesh_blob_io_t *io,
|
||||
const esp_ble_mesh_blob_xfer_t *xfer);
|
||||
|
||||
/** @brief Block start callback.
|
||||
*
|
||||
* Called when a new block is opened for sending. Each block is only
|
||||
* sent once, and are always sent in increasing order. The data chunks
|
||||
* inside a single block may be requested out of order and multiple
|
||||
* times.
|
||||
*
|
||||
* @param io BLOB stream.
|
||||
* @param xfer BLOB transfer.
|
||||
* @param block Block that was started.
|
||||
*/
|
||||
int (*block_start)(const esp_ble_mesh_blob_io_t *io,
|
||||
const esp_ble_mesh_blob_xfer_t *xfer,
|
||||
const esp_ble_mesh_blob_block_t *block);
|
||||
|
||||
/** @brief Block end callback.
|
||||
*
|
||||
* Called when the current block has been transmitted in full.
|
||||
* No data from this block will be requested again, and the application
|
||||
* data associated with this block may be discarded.
|
||||
*
|
||||
* @param io BLOB stream.
|
||||
* @param xfer BLOB transfer.
|
||||
* @param block Block that finished sending.
|
||||
*/
|
||||
void (*block_end)(const esp_ble_mesh_blob_io_t *io,
|
||||
const esp_ble_mesh_blob_xfer_t *xfer,
|
||||
const esp_ble_mesh_blob_block_t *block);
|
||||
|
||||
/** @brief Chunk data write callback.
|
||||
*
|
||||
* Used by the BLOB Transfer Server on incoming data.
|
||||
*
|
||||
* Each block is divided into chunks of data. This callback is called
|
||||
* when a new chunk of data is received. Chunks may be received in
|
||||
* any order within their block.
|
||||
*
|
||||
* If the callback returns successfully, this chunk will be marked as
|
||||
* received, and will not be received again unless the block is
|
||||
* restarted due to a transfer suspension. If the callback returns a
|
||||
* non-zero value, the chunk remains unreceived, and the BLOB Transfer
|
||||
* Client will attempt to resend it later.
|
||||
*
|
||||
* Note that the Client will only perform a limited number of attempts
|
||||
* at delivering a chunk before dropping a Target node from the transfer.
|
||||
* The number of retries performed by the Client is implementation
|
||||
* specific.
|
||||
*
|
||||
* @param io BLOB stream.
|
||||
* @param xfer BLOB transfer.
|
||||
* @param block Block the chunk is part of.
|
||||
* @param chunk Received chunk.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code otherwise.
|
||||
*/
|
||||
int (*write)(const esp_ble_mesh_blob_io_t *io,
|
||||
const esp_ble_mesh_blob_xfer_t *xfer,
|
||||
const esp_ble_mesh_blob_block_t *block,
|
||||
const esp_ble_mesh_blob_chunk_t *chunk);
|
||||
|
||||
/** @brief Chunk data read callback.
|
||||
*
|
||||
* Used by the BLOB Transfer Client to fetch outgoing data.
|
||||
*
|
||||
* The Client calls the chunk data request callback to populate a chunk
|
||||
* message going out to the Target nodes. The data request callback
|
||||
* may be called out of order and multiple times for each offset, and
|
||||
* cannot be used as an indication of progress.
|
||||
*
|
||||
* Returning a non-zero status code on the chunk data request callback
|
||||
* results in termination of the transfer.
|
||||
*
|
||||
* @param io BLOB stream.
|
||||
* @param xfer BLOB transfer.
|
||||
* @param block Block the chunk is part of.
|
||||
* @param chunk Chunk to get the data of. The buffer pointer to by the
|
||||
* @c data member should be filled by the callback.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code otherwise.
|
||||
*/
|
||||
int (*read)(const esp_ble_mesh_blob_io_t *io,
|
||||
const esp_ble_mesh_blob_xfer_t *xfer,
|
||||
const esp_ble_mesh_blob_block_t *block,
|
||||
const esp_ble_mesh_blob_chunk_t *chunk);
|
||||
};
|
||||
|
||||
/** @brief BLOB Transfer Server model event handlers.
|
||||
*
|
||||
* All callbacks are optional.
|
||||
*/
|
||||
struct esp_ble_mesh_blob_srv_cb {
|
||||
/** @brief Transfer start callback.
|
||||
*
|
||||
* Called when the transfer has started with the prepared BLOB ID.
|
||||
*
|
||||
* @param srv BLOB Transfer Server instance.
|
||||
* @param ctx Message context for the incoming start message. The
|
||||
* entire transfer will be sent from the same source
|
||||
* address.
|
||||
* @param xfer Transfer parameters.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code to reject the
|
||||
* transfer.
|
||||
*/
|
||||
int (*start)(esp_ble_mesh_blob_srv_t *srv, esp_ble_mesh_msg_ctx_t *ctx,
|
||||
esp_ble_mesh_blob_xfer_t *xfer);
|
||||
|
||||
/** @brief Transfer end callback.
|
||||
*
|
||||
* Called when the transfer ends, either because it was cancelled, or
|
||||
* because it finished successfully. A new transfer may be prepared.
|
||||
*
|
||||
* @note The transfer may end before it's started if the start
|
||||
* parameters are invalid.
|
||||
*
|
||||
* @param srv BLOB Transfer Server instance.
|
||||
* @param id BLOB ID of the cancelled transfer.
|
||||
* @param success Whether the transfer was successful.
|
||||
*/
|
||||
void (*end)(esp_ble_mesh_blob_srv_t *srv, uint64_t id, bool success);
|
||||
|
||||
/** @brief Transfer suspended callback.
|
||||
*
|
||||
* Called if the Server timed out while waiting for a transfer packet.
|
||||
* A suspended transfer may resume later from the start of the current
|
||||
* block. Any received chunks in the current block should be discarded,
|
||||
* they will be received again if the transfer resumes.
|
||||
*
|
||||
* The transfer will call @c resumed again when resuming.
|
||||
*
|
||||
* @note The BLOB Transfer Server does not run a timer in the suspended state,
|
||||
* and it's up to the application to determine whether the
|
||||
* transfer should be permanently cancelled. Without interaction,
|
||||
* the transfer will be suspended indefinitely, and the BLOB Transfer
|
||||
* Server will not accept any new transfers.
|
||||
*
|
||||
* @param srv BLOB Transfer Server instance.
|
||||
*/
|
||||
void (*suspend)(esp_ble_mesh_blob_srv_t *srv);
|
||||
|
||||
/** @brief Transfer resume callback.
|
||||
*
|
||||
* Called if the transfer is resumed after being suspended.
|
||||
*
|
||||
* @param srv BLOB Transfer Server instance.
|
||||
*/
|
||||
void (*resume)(esp_ble_mesh_blob_srv_t *srv);
|
||||
|
||||
/** @brief Transfer recovery callback.
|
||||
*
|
||||
* Called when the Bluetooth mesh subsystem is started if the device is rebooted
|
||||
* in the middle of a transfer.
|
||||
*
|
||||
* Transfers will not be resumed after a reboot if this callback is not
|
||||
* defined.
|
||||
*
|
||||
* @param srv BLOB Transfer Server instance.
|
||||
* @param xfer Transfer to resume.
|
||||
* @param io BLOB stream return parameter. Must be set to a valid
|
||||
* BLOB stream by the callback.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code to abandon the
|
||||
* transfer.
|
||||
*/
|
||||
int (*recover)(esp_ble_mesh_blob_srv_t *srv,
|
||||
esp_ble_mesh_blob_xfer_t *xfer,
|
||||
esp_ble_mesh_blob_io_t **io);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_BLE_MESH_BLOB_SRV)
|
||||
#define ESP_BLE_MESH_BLOB_BLOCKS_MAX \
|
||||
(DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_SIZE_MAX, \
|
||||
CONFIG_BLE_MESH_BLOB_BLOCK_SIZE_MIN))
|
||||
#else
|
||||
#define ESP_BLE_MESH_BLOB_BLOCKS_MAX 1
|
||||
#endif
|
||||
|
||||
/** @brief BLOB Transfer Server instance. */
|
||||
struct esp_ble_mesh_blob_srv {
|
||||
/** Event handler callbacks. */
|
||||
esp_ble_mesh_blob_srv_cb_t *cb;
|
||||
|
||||
/** Runtime state: */
|
||||
esp_ble_mesh_blob_io_t *io;
|
||||
struct k_delayed_work rx_timeout;
|
||||
esp_ble_mesh_blob_block_t block;
|
||||
esp_ble_mesh_model_t *mod;
|
||||
esp_ble_mesh_blob_xfer_phase_t phase;
|
||||
|
||||
/** State of blob serber. */
|
||||
struct esp_ble_mesh_blob_srv_state {
|
||||
esp_ble_mesh_blob_xfer_t xfer;
|
||||
uint16_t cli;
|
||||
uint16_t app_idx;
|
||||
uint16_t timeout_base;
|
||||
uint16_t mtu_size;
|
||||
uint8_t ttl;
|
||||
|
||||
/* Bitfield of pending blocks. */
|
||||
BLE_MESH_ATOMIC_DEFINE(blocks, ESP_BLE_MESH_BLOB_BLOCKS_MAX);
|
||||
} state;
|
||||
|
||||
/* Pull mode (Pull BLOB Transfer Mode) behavior. */
|
||||
struct {
|
||||
uint16_t chunk_idx;
|
||||
struct k_delayed_work report;
|
||||
} pull;
|
||||
};
|
||||
|
||||
/** Target node's Pull mode (Pull BLOB Transfer Mode) context used
|
||||
* while sending chunks to the Target node.
|
||||
*/
|
||||
struct esp_ble_mesh_blob_target_pull {
|
||||
int64_t block_report_timestamp; /*!< Timestamp when the Block Report Timeout Timer expires for this Target node. */
|
||||
uint8_t missing[DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX, 8)]; /*!< Missing chunks reported by this Target node. */
|
||||
};
|
||||
|
||||
/** BLOB Transfer Client Target node. */
|
||||
struct esp_ble_mesh_blob_target {
|
||||
sys_snode_t n; /*!< Linked list node */
|
||||
|
||||
uint16_t addr; /*!< Target node address. */
|
||||
|
||||
/** Target node's Pull mode context.
|
||||
* Needs to be initialized when sending a BLOB in Pull mode.
|
||||
*/
|
||||
esp_ble_mesh_blob_target_pull_t *pull;
|
||||
|
||||
uint8_t status; /*!< BLOB transfer status, see esp_ble_mesh_blob_status. */
|
||||
|
||||
uint8_t procedure_complete: 1, /*!< Procedure has been completed. */
|
||||
acked: 1, /*!< Message has been acknowledged. Not used when sending. */
|
||||
timedout: 1, /*!< Target node didn't respond after specified timeout. */
|
||||
skip: 1; /*!< Skip Target node from broadcast. */
|
||||
};
|
||||
|
||||
|
||||
/** BLOB transfer information. */
|
||||
struct esp_ble_mesh_blob_xfer_info {
|
||||
esp_ble_mesh_blob_status_t status; /*!< BLOB transfer status. */
|
||||
esp_ble_mesh_blob_xfer_mode_t mode; /*!< BLOB transfer mode. */
|
||||
esp_ble_mesh_blob_xfer_phase_t phase; /*!< BLOB transfer phase. */
|
||||
uint64_t id; /*!< BLOB ID. */
|
||||
uint32_t size; /*!< BLOB size in octets. */
|
||||
uint8_t block_size_log; /*!< Logarithmic representation of the block size. */
|
||||
uint16_t mtu_size; /*!< MTU size in octets. */
|
||||
const uint8_t *missing_blocks; /*!< Bit field indicating blocks that were not received. */
|
||||
};
|
||||
|
||||
|
||||
/** BLOB Transfer Client transfer inputs. */
|
||||
struct esp_ble_mesh_blob_cli_inputs {
|
||||
/** Linked list of Target nodes. Each node should point to
|
||||
* esp_ble_mesh_blob_target_t::n.
|
||||
*/
|
||||
sys_slist_t targets;
|
||||
|
||||
/** AppKey index to send with. */
|
||||
uint16_t app_idx;
|
||||
|
||||
/** Group address destination for the BLOB transfer, or
|
||||
* ESP_BLE_MESH_ADDR_UNASSIGNED to send every message to each Target
|
||||
* node individually.
|
||||
*/
|
||||
uint16_t group;
|
||||
|
||||
/** Time to live value of BLOB transfer messages. */
|
||||
uint8_t ttl;
|
||||
|
||||
/** Additional response time for the Target nodes, in 10-second increments.
|
||||
*
|
||||
* The extra time can be used to give the Target nodes more time to respond
|
||||
* to messages from the Client. The actual timeout will be calculated
|
||||
* according to the following formula:
|
||||
*
|
||||
* @verbatim
|
||||
* timeout = 20 seconds + (10 seconds * timeout_base) + (100 ms * TTL)
|
||||
* @endverbatim
|
||||
*
|
||||
* If a Target node fails to respond to a message from the Client within the
|
||||
* configured transfer timeout, the Target node is dropped.
|
||||
*/
|
||||
uint16_t timeout_base;
|
||||
};
|
||||
|
||||
/** Transfer capabilities of a Target node. */
|
||||
struct esp_ble_mesh_blob_cli_caps {
|
||||
size_t max_size; /*!< Max BLOB size. */
|
||||
uint8_t min_block_size_log; /*!< Logarithmic representation of the minimum block size. */
|
||||
uint8_t max_block_size_log; /*!< Logarithmic representation of the maximum block size. */
|
||||
uint16_t max_chunks; /*!< Max number of chunks per block. */
|
||||
uint16_t max_chunk_size; /*!< Max chunk size. */
|
||||
uint16_t mtu_size; /*!< Max MTU size. */
|
||||
esp_ble_mesh_blob_xfer_mode_t modes; /*!< Supported transfer modes. */
|
||||
};
|
||||
|
||||
/** Event handler callbacks for the BLOB Transfer Client model.
|
||||
*
|
||||
* All handlers are optional.
|
||||
*/
|
||||
struct esp_ble_mesh_blob_cli_cb {
|
||||
/** @brief Capabilities retrieval completion callback.
|
||||
*
|
||||
* Called when the capabilities retrieval procedure completes, indicating that
|
||||
* a common set of acceptable transfer parameters have been established
|
||||
* for the given list of Target nodes. All compatible Target nodes have
|
||||
* status code ESP_BLE_MESH_BLOB_SUCCESS.
|
||||
*
|
||||
* @param cli BLOB Transfer Client instance.
|
||||
* @param caps Safe transfer capabilities if the transfer capabilities
|
||||
* of at least one Target node has satisfied the Client, or NULL otherwise.
|
||||
*/
|
||||
void (*caps)(esp_ble_mesh_blob_cli_t *cli,
|
||||
const esp_ble_mesh_blob_cli_caps_t *caps);
|
||||
|
||||
/** @brief Target node loss callback.
|
||||
*
|
||||
* Called whenever a Target node has been lost due to some error in the
|
||||
* transfer. Losing a Target node is not considered a fatal error for
|
||||
* the Client until all Target nodes have been lost.
|
||||
*
|
||||
* @param cli BLOB Transfer Client instance.
|
||||
* @param target Target node that was lost.
|
||||
* @param reason Reason for the Target node loss.
|
||||
*/
|
||||
void (*lost_target)(esp_ble_mesh_blob_cli_t *cli,
|
||||
esp_ble_mesh_blob_target_t *target,
|
||||
esp_ble_mesh_blob_status_t reason);
|
||||
|
||||
/** @brief Transfer is suspended.
|
||||
*
|
||||
* Called when the transfer is suspended due to response timeout from all Target nodes.
|
||||
*
|
||||
* @param cli BLOB Transfer Client instance.
|
||||
*/
|
||||
void (*suspend)(esp_ble_mesh_blob_cli_t *cli);
|
||||
|
||||
/** @brief Transfer end callback.
|
||||
*
|
||||
* Called when the transfer ends.
|
||||
*
|
||||
* @param cli BLOB Transfer Client instance.
|
||||
* @param xfer Completed transfer.
|
||||
* @param success Status of the transfer.
|
||||
* Is @c true if at least one Target
|
||||
* node received the whole transfer.
|
||||
*/
|
||||
void (*end)(esp_ble_mesh_blob_cli_t *cli,
|
||||
const esp_ble_mesh_blob_xfer_t *xfer, bool success);
|
||||
|
||||
/** @brief Transfer progress callback
|
||||
*
|
||||
* The content of @c info is invalidated upon exit from the callback.
|
||||
* Therefore it needs to be copied if it is planned to be used later.
|
||||
*
|
||||
* @param cli BLOB Transfer Client instance.
|
||||
* @param target Target node that responded to the request.
|
||||
* @param info BLOB transfer information.
|
||||
*/
|
||||
void (*xfer_progress)(esp_ble_mesh_blob_cli_t *cli,
|
||||
esp_ble_mesh_blob_target_t *target,
|
||||
const esp_ble_mesh_blob_xfer_info_t *info);
|
||||
|
||||
/** @brief End of Get Transfer Progress procedure.
|
||||
*
|
||||
* Called when all Target nodes have responded or the procedure timed-out.
|
||||
*
|
||||
* @param cli BLOB Transfer Client instance.
|
||||
*/
|
||||
void (*xfer_progress_complete)(esp_ble_mesh_blob_cli_t *cli);
|
||||
};
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
typedef struct {
|
||||
/** Called for every Target node in unicast mode, or once in case of multicast mode. */
|
||||
void (*send)(esp_ble_mesh_blob_cli_t *cli, uint16_t dst);
|
||||
/** Called after every @ref blob_cli_broadcast_ctx::send callback. */
|
||||
void (*send_complete)(esp_ble_mesh_blob_cli_t *cli, uint16_t dst);
|
||||
/** If @ref blob_cli_broadcast_ctx::acked is true, called after all Target nodes
|
||||
* have confirmed reception by @ref blob_cli_broadcast_rsp. Otherwise, called
|
||||
* after transmission has been completed.
|
||||
*/
|
||||
void (*next)(esp_ble_mesh_blob_cli_t *cli);
|
||||
/** If true, every transmission needs to be confirmed by @ref blob_cli_broadcast_rsp before
|
||||
* @ref blob_cli_broadcast_ctx::next is called.
|
||||
*/
|
||||
bool acked;
|
||||
/** If true, the message is always sent in a unicast way. */
|
||||
bool force_unicast;
|
||||
/** If true, non-responsive Target nodes won't be dropped after transfer has timed out. */
|
||||
bool optional;
|
||||
/** Set to true by the BLOB Transfer Client between blob_cli_broadcast
|
||||
* and broadcast_complete calls.
|
||||
*/
|
||||
bool is_inited;
|
||||
/* Defines a time in ms by which the broadcast API postpones sending the message to a next
|
||||
* target or completing the broadcast.
|
||||
*/
|
||||
uint32_t post_send_delay_ms;
|
||||
} esp_blob_cli_broadcast_ctx_t;
|
||||
/** INTERNAL_HIDDEN @endcond */
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client model instance.
|
||||
* @note Preview version, the contents of this struct may change in the future.
|
||||
*/
|
||||
struct esp_ble_mesh_blob_cli {
|
||||
/** Event handler callbacks */
|
||||
const esp_ble_mesh_blob_cli_cb_t *cb;
|
||||
|
||||
/** Runtime state */
|
||||
const esp_ble_mesh_model_t *mod;
|
||||
|
||||
/** Firmware transfer information */
|
||||
struct {
|
||||
esp_ble_mesh_blob_target_t *target;
|
||||
esp_blob_cli_broadcast_ctx_t ctx;
|
||||
struct k_delayed_work retry;
|
||||
/* Represents Client Timeout timer in a timestamp. Used in Pull mode only. */
|
||||
int64_t cli_timestamp;
|
||||
struct k_work complete;
|
||||
uint16_t pending;
|
||||
uint8_t retries;
|
||||
uint8_t sending : 1,
|
||||
cancelled : 1;
|
||||
} tx;
|
||||
|
||||
/** Firmware IO operation callbacks */
|
||||
const esp_ble_mesh_blob_io_t *io;
|
||||
|
||||
/** BLOB Transfer Client transfer inputs. */
|
||||
const esp_ble_mesh_blob_cli_inputs_t *inputs;
|
||||
|
||||
/** BLOB transfer. */
|
||||
const esp_ble_mesh_blob_xfer_t *xfer;
|
||||
|
||||
/** Interval between chunk transmissions, in milliseconds. */
|
||||
uint32_t chunk_interval_ms;
|
||||
|
||||
/** BLOCK count */
|
||||
uint16_t block_count;
|
||||
|
||||
/** CHUNK index */
|
||||
uint16_t chunk_idx;
|
||||
|
||||
/** Max Transfer Unit Size of BLOB Transfer */
|
||||
uint16_t mtu_size;
|
||||
|
||||
/** State of blob client mode transfer */
|
||||
esp_ble_mesh_blob_cli_state_t state;
|
||||
|
||||
/** BLOB transfer data block. */
|
||||
esp_ble_mesh_blob_block_t block;
|
||||
|
||||
/** Transfer capabilities of a Target node. */
|
||||
esp_ble_mesh_blob_cli_caps_t caps;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLE_MESH_BLOB_MODEL_API_H_ */
|
||||
@@ -0,0 +1,999 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_BLE_MESH_DFU_MODEL_API_H_
|
||||
#define _ESP_BLE_MESH_DFU_MODEL_API_H_
|
||||
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
#include "esp_ble_mesh_blob_model_api.h"
|
||||
#include "esp_ble_mesh_dfu_slot_api.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI || CONFIG_BLE_MESH_DFU_SRV
|
||||
#ifndef _BLE_MESH_BLOB_DEPRECATE_WARN
|
||||
#define _BLE_MESH_BLOB_DEPRECATE_WARN
|
||||
#warning Please note: All APIs published in this document are in Preview version and may undergo significant changes in the future.
|
||||
#endif
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI || CONFIG_BLE_MESH_DFU_SRV */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x08)
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_INFO_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x09)
|
||||
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0a)
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0b)
|
||||
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0c)
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_START ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0d)
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_CANCEL ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0e)
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_APPLY ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0f)
|
||||
#define ESP_BLE_MESH_DFU_OP_UPDATE_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x10)
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
/** @def ESP_BLE_MESH_MODEL_DFU_CLI
|
||||
*
|
||||
* @brief Define a new DFU Client model.
|
||||
*
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a DFU Client model.
|
||||
*
|
||||
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
|
||||
*
|
||||
* @return New DFU Client model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_MODEL_DFU_CLI(cli_pub, cli_data) \
|
||||
ESP_BLE_MESH_MODEL_BLOB_CLI(NULL, &(cli_data)->blob), \
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_DFU_CLI, \
|
||||
NULL, cli_pub, cli_data)
|
||||
|
||||
|
||||
/** @def ESP_BLE_MESH_DFU_CLI_INIT
|
||||
*
|
||||
* @brief Initialize a DFU Client model instance.
|
||||
*
|
||||
* @note This macro is used to initialize the DFU Client model.
|
||||
* It sets the callback handlers for the DFU Client.
|
||||
*
|
||||
* @param _handlers Pointer to the callback handler structure (esp_ble_mesh_dfu_cli_cb_t).
|
||||
*
|
||||
* @return An initialized DFU Client model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_DFU_CLI_INIT(_handlers) \
|
||||
{ \
|
||||
.cb = _handlers, \
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
/** @def ESP_BLE_MESH_MODEL_DFU_SRV
|
||||
*
|
||||
* @brief Define a new DFU Server model.
|
||||
*
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a DFU Server model.
|
||||
*
|
||||
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param srv_data Pointer to the unique struct esp_ble_mesh_dfu_trans_srv_t.
|
||||
*
|
||||
* @return New DFU Server model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_MODEL_DFU_SRV(srv_pub, srv_data) \
|
||||
ESP_BLE_MESH_MODEL_BLOB_SRV(NULL, &(srv_data)->blob), \
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_DFU_SRV, \
|
||||
NULL, srv_pub, srv_data)
|
||||
|
||||
|
||||
/** @def ESP_BLE_MESH_DFU_SRV_INIT
|
||||
*
|
||||
* @brief Initialize a DFU Server model instance.
|
||||
*
|
||||
* @note This macro is used to initialize the DFU Server model.
|
||||
* It sets the callback handlers and image information for the DFU Server.
|
||||
*
|
||||
* @param _handlers Pointer to the callback handler structure (esp_ble_mesh_dfu_srv_cb_t).
|
||||
* @param _imgs Pointer to the array of DFU images (esp_ble_mesh_dfu_img_t).
|
||||
* @param _img_count Number of DFU images in the array.
|
||||
*
|
||||
* @return An initialized DFU Server model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_DFU_SRV_INIT(_handlers, _imgs, _img_count) \
|
||||
{ \
|
||||
.cb = _handlers, \
|
||||
.imgs = _imgs, .img_count = _img_count, \
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
|
||||
/** @brief DFU image structure. **/
|
||||
typedef struct esp_ble_mesh_dfu_img esp_ble_mesh_dfu_img_t;
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
/** @brief DFU Client model instance structure.
|
||||
*
|
||||
* This structure represents a DFU (Device Firmware Update) Client model instance.
|
||||
* It contains the necessary fields for managing DFU operations as a client.
|
||||
* Should be initialized with ESP_BLE_MESH_DFU_CLI_INIT.
|
||||
*
|
||||
* @note Preview version, the contents of this struct may change in the future.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_cli esp_ble_mesh_dfu_cli_t;
|
||||
|
||||
/** @brief DFU iteration action enumeration.
|
||||
*
|
||||
* This enumeration defines the possible actions that can be taken
|
||||
* during DFU iteration callbacks. It controls whether to continue
|
||||
* or stop iterating through DFU images.
|
||||
*/
|
||||
typedef enum esp_ble_mesh_dfu_iter esp_ble_mesh_dfu_iter_t;
|
||||
|
||||
/** @brief DFU image callback.
|
||||
*
|
||||
* The image callback is called for every DFU image on the Target node when
|
||||
* calling bt_mesh_dfu_cli_imgs_get.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
* @param ctx Message context of the received message.
|
||||
* @param idx Image index.
|
||||
* @param total Total number of images on the Target node.
|
||||
* @param img Image information for the given image index.
|
||||
* @param cb_data Callback data.
|
||||
*
|
||||
* @retval ESP_BLE_MESH_DFU_ITER_STOP Stop iterating through the image list and
|
||||
* return from bt_mesh_dfu_cli_imgs_get.
|
||||
* @retval ESP_BLE_MESH_DFU_ITER_CONTINUE Continue iterating through the image list
|
||||
* if any images remain.
|
||||
*/
|
||||
typedef esp_ble_mesh_dfu_iter_t (*esp_ble_mesh_dfu_img_cb_t)(esp_ble_mesh_dfu_cli_t *cli,
|
||||
esp_ble_mesh_msg_ctx_t *ctx, uint8_t idx,
|
||||
uint8_t total, const esp_ble_mesh_dfu_img_t *img,
|
||||
void *cb_data);
|
||||
/** @brief DFU image slot structure.
|
||||
*
|
||||
* This structure represents a DFU image slot used for DFU distribution.
|
||||
* It contains information about the firmware image including size,
|
||||
* firmware ID, metadata, and their respective lengths.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_slot esp_ble_mesh_dfu_slot_t;
|
||||
|
||||
/** @brief DFU Target node structure.
|
||||
*
|
||||
* This structure represents a DFU Target node in the mesh network.
|
||||
* It contains information about the target's BLOB transfer status,
|
||||
* image index, expected DFU effect, current status, and phase.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_target esp_ble_mesh_dfu_target_t;
|
||||
|
||||
/** @brief DFU Client callback structure.
|
||||
*
|
||||
* This structure contains callback function pointers for DFU Client events
|
||||
* such as transfer suspension, completion, application, confirmation,
|
||||
* and target node loss.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_cli_cb esp_ble_mesh_dfu_cli_cb_t;
|
||||
|
||||
/** @brief DFU Client model instance structure.
|
||||
*
|
||||
* This structure represents a DFU (Device Firmware Update) Client model instance.
|
||||
* It contains the necessary fields for managing DFU operations as a client.
|
||||
* Should be initialized with ESP_BLE_MESH_DFU_CLI_INIT.
|
||||
*
|
||||
* @note Preview version, the contents of this struct may change in the future.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_cli esp_ble_mesh_dfu_cli_t;
|
||||
|
||||
/** @brief DFU Client BLOB transfer parameters structure.
|
||||
*
|
||||
* This structure contains parameters for BLOB transfer during DFU operations,
|
||||
* including block size logarithmic representation and base chunk size.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_cli_xfer_blob_params esp_ble_mesh_dfu_cli_xfer_blob_params_t;
|
||||
|
||||
/** @brief DFU Client transfer parameters structure.
|
||||
*
|
||||
* This structure contains parameters for DFU transfer operations,
|
||||
* including BLOB ID, image slot, transfer mode, and BLOB parameters.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_cli_xfer esp_ble_mesh_dfu_cli_xfer_t;
|
||||
|
||||
/** @brief Device Firmware Update Info Get parameters structure.
|
||||
*
|
||||
* This structure contains parameters for the Firmware Update Information Get message,
|
||||
* including the first index and entries limit for requesting firmware information.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_device_firmware_update_info_get esp_ble_mesh_device_firmware_update_info_get_t;
|
||||
|
||||
/** @brief Device Firmware Update Metadata Check parameters structure.
|
||||
*
|
||||
* This structure contains parameters for the Firmware Update Metadata Check message,
|
||||
* including the update firmware index and vendor-specific metadata.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_device_firmware_update_metadata_check esp_ble_mesh_device_firmware_update_metadata_check_t;
|
||||
|
||||
/** @brief DFU Client get message union.
|
||||
*
|
||||
* This union contains different parameter structures for various DFU Client
|
||||
* get messages, allowing type-safe access to message-specific parameters.
|
||||
*/
|
||||
typedef union esp_ble_mesh_dfu_client_get esp_ble_mesh_dfu_client_get_t;
|
||||
|
||||
/** @brief DFU Client send arguments structure.
|
||||
*
|
||||
* This structure contains arguments for sending firmware via DFU Client,
|
||||
* including the client instance, transfer inputs, BLOB stream, and transfer parameters.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_cli_send_arg esp_ble_mesh_dfu_cli_send_arg_t;
|
||||
|
||||
/** @brief Firmware information structure.
|
||||
*
|
||||
* This structure contains information about firmware including firmware ID
|
||||
* and update URI for retrieving new firmware.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_firmware_info esp_ble_mesh_firmware_info_t;
|
||||
|
||||
/** @brief Device Firmware Update Info Status response structure.
|
||||
*
|
||||
* This structure contains the response parameters for Firmware Update Information
|
||||
* Status message, including firmware information list count and details.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_device_firmware_update_info_status esp_ble_mesh_device_firmware_update_info_status_t;
|
||||
|
||||
/** @brief Device Firmware Update Metadata Check Status response structure.
|
||||
*
|
||||
* This structure contains the response parameters for Firmware Update Metadata
|
||||
* Check Status message, including status code and additional information.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_device_firmware_metadata_check_status esp_ble_mesh_device_firmware_metadata_check_status_t;
|
||||
|
||||
/** @brief Device Firmware Update Status response structure.
|
||||
*
|
||||
* This structure contains the response parameters for various Firmware Update
|
||||
* Status messages (Get, Start, Cancel, Apply), including status, phase,
|
||||
* TTL, timeout base, BLOB ID, and firmware image index.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_device_firmware_update_status esp_ble_mesh_device_firmware_update_status_t;
|
||||
|
||||
/** @brief DFU Client send callback structure.
|
||||
*
|
||||
* This structure contains the result of sending DFU Client messages,
|
||||
* including error code indicating success or failure.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_client_send_cb esp_ble_mesh_dfu_client_send_cb_t;
|
||||
|
||||
/** @brief DFU Client receive callback union.
|
||||
*
|
||||
* This union contains different response structures for various DFU Client
|
||||
* received status messages, allowing type-safe access to message-specific responses.
|
||||
*/
|
||||
typedef union esp_ble_mesh_dfu_client_recv_cb esp_ble_mesh_dfu_client_recv_cb_t;
|
||||
|
||||
/** @brief DFU Client callback parameters structure.
|
||||
*
|
||||
* This structure contains parameters for DFU Client callbacks, including
|
||||
* common client parameters and a union of send/receive callback data.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_client_cb_param esp_ble_mesh_dfu_client_cb_param_t;
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
/** @brief Firmware Update Server instance structure.
|
||||
*
|
||||
* This structure represents a DFU (Device Firmware Update) Server model instance.
|
||||
* It contains the necessary fields for managing DFU operations as a server.
|
||||
* Should be initialized with ESP_BLE_MESH_DFU_SRV_INIT.
|
||||
*
|
||||
* @note Preview version, the contents of this struct may change in the future.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_srv esp_ble_mesh_dfu_srv_t;
|
||||
|
||||
/** @brief Firmware Update Server callback structure.
|
||||
*
|
||||
* This structure contains callback function pointers for DFU Server events
|
||||
* such as transfer check, start, end, recovery, and apply.
|
||||
*/
|
||||
typedef struct esp_ble_mesh_dfu_srv_cb esp_ble_mesh_dfu_srv_cb_t;
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
|
||||
/** DFU transfer phase. */
|
||||
typedef enum esp_ble_mesh_dfu_phase {
|
||||
/** Ready to start a Receive Firmware procedure. */
|
||||
ESP_BLE_MESH_DFU_PHASE_IDLE,
|
||||
|
||||
/** The Transfer BLOB procedure failed. */
|
||||
ESP_BLE_MESH_DFU_PHASE_TRANSFER_ERR,
|
||||
|
||||
/** The Receive Firmware procedure is being executed. */
|
||||
ESP_BLE_MESH_DFU_PHASE_TRANSFER_ACTIVE,
|
||||
|
||||
/** The Verify Firmware procedure is being executed. */
|
||||
ESP_BLE_MESH_DFU_PHASE_VERIFY,
|
||||
|
||||
/** The Verify Firmware procedure completed successfully. */
|
||||
ESP_BLE_MESH_DFU_PHASE_VERIFY_OK,
|
||||
|
||||
/** The Verify Firmware procedure failed. */
|
||||
ESP_BLE_MESH_DFU_PHASE_VERIFY_FAIL,
|
||||
|
||||
/** The Apply New Firmware procedure is being executed. */
|
||||
ESP_BLE_MESH_DFU_PHASE_APPLYING,
|
||||
|
||||
/** Firmware transfer has been canceled. */
|
||||
ESP_BLE_MESH_DFU_PHASE_TRANSFER_CANCELED,
|
||||
|
||||
/** Firmware applying succeeded. */
|
||||
ESP_BLE_MESH_DFU_PHASE_APPLY_SUCCESS,
|
||||
|
||||
/** Firmware applying failed. */
|
||||
ESP_BLE_MESH_DFU_PHASE_APPLY_FAIL,
|
||||
|
||||
/** Phase of a node was not yet retrieved. */
|
||||
ESP_BLE_MESH_DFU_PHASE_UNKNOWN,
|
||||
} esp_ble_mesh_dfu_phase_t;
|
||||
|
||||
/** Expected effect of a DFU transfer. */
|
||||
typedef enum esp_ble_mesh_dfu_effect {
|
||||
/** No changes to node Composition Data. */
|
||||
ESP_BLE_MESH_DFU_EFFECT_NONE,
|
||||
|
||||
/** Node Composition Data changed and the node does not support remote
|
||||
* provisioning.
|
||||
*/
|
||||
ESP_BLE_MESH_DFU_EFFECT_COMP_CHANGE_NO_RPR,
|
||||
|
||||
/** Node Composition Data changed, and remote provisioning is supported.
|
||||
* The node supports remote provisioning and Composition Data Page
|
||||
* 0x80. Page 0x80 contains different Composition Data than Page 0x0.
|
||||
*/
|
||||
ESP_BLE_MESH_DFU_EFFECT_COMP_CHANGE,
|
||||
|
||||
/** Node will be unprovisioned after the update. */
|
||||
ESP_BLE_MESH_DFU_EFFECT_UNPROV,
|
||||
} esp_ble_mesh_dfu_effect_t;
|
||||
|
||||
/** DFU status. */
|
||||
typedef enum esp_ble_mesh_dfu_status {
|
||||
/** The message was processed successfully. */
|
||||
ESP_BLE_MESH_DFU_SUCCESS,
|
||||
|
||||
/** Insufficient resources on the node */
|
||||
ESP_BLE_MESH_DFU_ERR_RESOURCES,
|
||||
|
||||
/** The operation cannot be performed while the Server is in the current
|
||||
* phase.
|
||||
*/
|
||||
ESP_BLE_MESH_DFU_ERR_WRONG_PHASE,
|
||||
|
||||
/** An internal error occurred on the node. */
|
||||
ESP_BLE_MESH_DFU_ERR_INTERNAL,
|
||||
|
||||
/** The message contains a firmware index value that is not expected. */
|
||||
ESP_BLE_MESH_DFU_ERR_FW_IDX,
|
||||
|
||||
/** The metadata check failed. */
|
||||
ESP_BLE_MESH_DFU_ERR_METADATA,
|
||||
|
||||
/** The Server cannot start a firmware update. */
|
||||
ESP_BLE_MESH_DFU_ERR_TEMPORARILY_UNAVAILABLE,
|
||||
|
||||
/** Another BLOB transfer is in progress. */
|
||||
ESP_BLE_MESH_DFU_ERR_BLOB_XFER_BUSY,
|
||||
} esp_ble_mesh_dfu_status_t;
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
/** Action for DFU iteration callbacks. */
|
||||
enum esp_ble_mesh_dfu_iter {
|
||||
/** Stop iterating. */
|
||||
ESP_BLE_MESH_DFU_ITER_STOP,
|
||||
|
||||
/** Continue iterating. */
|
||||
ESP_BLE_MESH_DFU_ITER_CONTINUE,
|
||||
};
|
||||
|
||||
/** @brief DFU transfer states
|
||||
*
|
||||
* This enumeration defines the various states of a DFU (Device Firmware Update) transfer.
|
||||
* These states track the progress of firmware distribution from idle state through
|
||||
* transfer, verification, application, and confirmation phases.
|
||||
*/
|
||||
typedef enum esp_ble_mesh_dfu_xfer_state {
|
||||
/** Idle state - No DFU transfer is in progress. */
|
||||
ESP_BLE_MESH_DFU_XFER_IDLE,
|
||||
|
||||
/** Transfer state - Firmware data is being transferred to target nodes. */
|
||||
ESP_BLE_MESH_DFU_XFER_TRANSFER,
|
||||
|
||||
/** Refresh state - Transfer is paused or being refreshed. */
|
||||
ESP_BLE_MESH_DFU_XFER_REFRESH,
|
||||
|
||||
/** Verified state - Firmware has been successfully verified on target nodes. */
|
||||
ESP_BLE_MESH_DFU_XFER_VERIFIED,
|
||||
|
||||
/** Apply state - Firmware is being applied on target nodes. */
|
||||
ESP_BLE_MESH_DFU_XFER_APPLY,
|
||||
|
||||
/** Applied state - Firmware has been successfully applied on target nodes. */
|
||||
ESP_BLE_MESH_DFU_XFER_APPLIED,
|
||||
|
||||
/** Confirm state - Waiting for confirmation from target nodes. */
|
||||
ESP_BLE_MESH_DFU_XFER_CONFIRM,
|
||||
|
||||
/** Cancel state - DFU transfer has been cancelled. */
|
||||
ESP_BLE_MESH_DFU_XFER_CANCEL,
|
||||
|
||||
/** Suspended state - DFU transfer has been suspended. */
|
||||
ESP_BLE_MESH_DFU_XFER_SUSPENDED,
|
||||
} esp_ble_mesh_dfu_xfer_state_t;
|
||||
|
||||
/** @brief Callback events of Device Firmware Update Client Model
|
||||
*
|
||||
* This enumeration defines the various callback events that can be generated
|
||||
* by the DFU (Device Firmware Update) Client model. These events are used
|
||||
* to notify the application about different stages and states of the DFU process,
|
||||
* including message sending, timeouts, response reception, and image transfer completion.
|
||||
*/
|
||||
typedef enum {
|
||||
/** DFU Client message sending completed event.
|
||||
* This event is triggered when a DFU Client message has been successfully sent.
|
||||
*/
|
||||
ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT,
|
||||
|
||||
/** DFU Client timeout event.
|
||||
* This event is triggered when a DFU Client operation times out waiting for a response.
|
||||
*/
|
||||
ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT,
|
||||
|
||||
/** DFU Client received Get response event.
|
||||
* This event is triggered when the DFU Client receives a response to a Get message.
|
||||
*/
|
||||
ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT,
|
||||
|
||||
/** DFU Client image send completed event.
|
||||
* This event is triggered when the DFU Client has completed sending a firmware image.
|
||||
*/
|
||||
ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT,
|
||||
|
||||
/** Maximum DFU Client event value (used for bounds checking). */
|
||||
ESP_BLE_MESH_DFU_CLIENT_EVT_MAX,
|
||||
} esp_ble_mesh_dfu_client_cb_event_t;
|
||||
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
/** DFU image instance.
|
||||
*
|
||||
* Each DFU image represents a single updatable firmware image.
|
||||
*/
|
||||
struct esp_ble_mesh_dfu_img {
|
||||
/** Firmware ID. */
|
||||
const void *fwid;
|
||||
|
||||
/** Length of the firmware ID. */
|
||||
size_t fwid_len;
|
||||
|
||||
/** Update URI, or NULL. */
|
||||
const char *uri;
|
||||
};
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
/** DFU image slot for DFU distribution. */
|
||||
struct esp_ble_mesh_dfu_slot {
|
||||
/** Size of the firmware in bytes. */
|
||||
size_t size;
|
||||
/** Length of the firmware ID. */
|
||||
size_t fwid_len;
|
||||
/** Length of the metadata. */
|
||||
size_t metadata_len;
|
||||
/** Firmware ID. */
|
||||
uint8_t fwid[CONFIG_BLE_MESH_DFU_FWID_MAXLEN];
|
||||
/** Metadata. */
|
||||
uint8_t metadata[CONFIG_BLE_MESH_DFU_METADATA_MAXLEN];
|
||||
};
|
||||
|
||||
/** DFU Target node. */
|
||||
struct esp_ble_mesh_dfu_target {
|
||||
/** BLOB Target node */
|
||||
esp_ble_mesh_blob_target_t blob;
|
||||
/** Image index on the Target node */
|
||||
uint8_t img_idx;
|
||||
/** Expected DFU effect, see bt_mesh_dfu_effect. */
|
||||
uint8_t effect;
|
||||
/** Current DFU status, see bt_mesh_dfu_status. */
|
||||
uint8_t status;
|
||||
/** Current DFU phase, see bt_mesh_dfu_phase. */
|
||||
uint8_t phase;
|
||||
};
|
||||
|
||||
/** Firmware Update Client event callbacks. */
|
||||
struct esp_ble_mesh_dfu_cli_cb {
|
||||
/** @brief BLOB transfer is suspended.
|
||||
*
|
||||
* Called when the BLOB transfer is suspended due to response timeout from all Target nodes.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
*/
|
||||
void (*suspended)(esp_ble_mesh_dfu_cli_t *cli);
|
||||
|
||||
/** @brief DFU ended.
|
||||
*
|
||||
* Called when the DFU transfer ends, either because all Target nodes were
|
||||
* lost or because the transfer was completed successfully.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
* @param reason Reason for ending.
|
||||
*/
|
||||
void (*ended)(esp_ble_mesh_dfu_cli_t *cli,
|
||||
esp_ble_mesh_dfu_status_t reason);
|
||||
|
||||
/** @brief DFU transfer applied on all active Target nodes.
|
||||
*
|
||||
* Called at the end of the apply procedure.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
*/
|
||||
void (*applied)(esp_ble_mesh_dfu_cli_t *cli);
|
||||
|
||||
/** @brief DFU transfer confirmed on all active Target nodes.
|
||||
*
|
||||
* Called at the end of the apply procedure.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
*/
|
||||
void (*confirmed)(esp_ble_mesh_dfu_cli_t *cli);
|
||||
|
||||
/** @brief DFU Target node was lost.
|
||||
*
|
||||
* A DFU Target node was dropped from the receivers list. The Target node's
|
||||
* @c status is set to reflect the reason for the failure.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
* @param target DFU Target node that was lost.
|
||||
*/
|
||||
void (*lost_target)(esp_ble_mesh_dfu_cli_t *cli,
|
||||
esp_ble_mesh_dfu_target_t *target);
|
||||
};
|
||||
|
||||
/** Firmware Update Client model instance.
|
||||
* Should be initialized with ESP_BLE_MESH_DFU_CLI_INIT.
|
||||
*
|
||||
* @note Preview version, the contents of this struct may change in the future.
|
||||
*/
|
||||
struct esp_ble_mesh_dfu_cli {
|
||||
/** Callback structure. */
|
||||
const esp_ble_mesh_dfu_cli_cb_t *cb;
|
||||
/** Underlying BLOB Transfer Client. */
|
||||
esp_ble_mesh_blob_cli_t blob;
|
||||
|
||||
/** runtime state */
|
||||
uint32_t op;
|
||||
|
||||
/** ble mesh model instance. */
|
||||
esp_ble_mesh_model_t *mod;
|
||||
|
||||
/** BLOB Transfer information */
|
||||
struct {
|
||||
const esp_ble_mesh_dfu_slot_t *slot;
|
||||
const esp_ble_mesh_blob_io_t *io;
|
||||
esp_ble_mesh_blob_xfer_t blob;
|
||||
uint8_t state;
|
||||
uint8_t flags;
|
||||
} xfer;
|
||||
|
||||
/** Current request */
|
||||
void *req;
|
||||
};
|
||||
|
||||
/** BLOB parameters for Firmware Update Client transfer */
|
||||
struct esp_ble_mesh_dfu_cli_xfer_blob_params {
|
||||
/** Logarithmic representation of the block size. */
|
||||
uint8_t block_size_log;
|
||||
/** Base chunk size. May be smaller for the last chunk. */
|
||||
uint16_t chunk_size;
|
||||
};
|
||||
|
||||
/** Firmware Update Client transfer parameters */
|
||||
struct esp_ble_mesh_dfu_cli_xfer {
|
||||
/** BLOB ID to use for this transfer, or 0 to set it randomly. */
|
||||
uint64_t blob_id;
|
||||
/** DFU image slot to transfer. */
|
||||
const esp_ble_mesh_dfu_slot_t *slot;
|
||||
/** Transfer mode (Push (Push BLOB Transfer Mode) or Pull (Pull BLOB Transfer Mode)) */
|
||||
enum esp_ble_mesh_blob_xfer_mode mode;
|
||||
/** BLOB parameters to be used for the transfer, or NULL to retrieve Target nodes'
|
||||
* capabilities before sending a firmware.
|
||||
*/
|
||||
const esp_ble_mesh_dfu_cli_xfer_blob_params_t *blob_params;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parameters of Device Firmware Update Info Get.
|
||||
*/
|
||||
struct esp_ble_mesh_device_firmware_update_info_get {
|
||||
uint8_t first_index; /*!< Index of the first requested entry from the Firmware Information List state */
|
||||
uint8_t entries_limit; /*!< Maximum number of entries that the server includes in a Firmware Update Information Status message */
|
||||
esp_ble_mesh_dfu_img_cb_t img_cb; /*!< Added by Espressif, callback function used to walkthrough recceived images */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parameters of Device Firmware Update Firmware Metadata Check.
|
||||
*/
|
||||
struct esp_ble_mesh_device_firmware_update_metadata_check {
|
||||
uint8_t update_firmware_index; /*!< Index of the firmware image in the Firmware Information List state to check */
|
||||
struct net_buf_simple *metadata; /*!< Vendor-specific metadata */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Device Firmware Update Client model get message union.
|
||||
* For ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET
|
||||
* ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK
|
||||
* ESP_BLE_MESH_DFU_OP_UPDATE_START
|
||||
* the get_state parameter in the `esp_ble_mesh_dfu_client_get_state` function should not be set to NULL.
|
||||
*/
|
||||
union esp_ble_mesh_dfu_client_get {
|
||||
esp_ble_mesh_device_firmware_update_info_get_t dfu_update_info_get; /*!< For ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET */
|
||||
esp_ble_mesh_device_firmware_update_metadata_check_t dfu_metadata_check; /*!< For ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parameters of Device Firmware Update Client
|
||||
* model to send Firmware.
|
||||
*/
|
||||
struct esp_ble_mesh_dfu_cli_send_arg {
|
||||
esp_ble_mesh_dfu_cli_t *cli; /*!< Device Firmware Update Client model instance */
|
||||
esp_ble_mesh_blob_cli_inputs_t *inputs; /*!< BLOB Transfer Client transfer inputs. */
|
||||
esp_ble_mesh_blob_io_t *io; /*!< BLOB stream. */
|
||||
esp_ble_mesh_dfu_cli_xfer_t *xfer; /*!< Firmware Update Client transfer parameters */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Struct of firmware information.
|
||||
*/
|
||||
struct esp_ble_mesh_firmware_info {
|
||||
struct net_buf_simple *fw_id; /*!< Firmware ID */
|
||||
struct net_buf_simple *update_uri; /*!< URI used to retrieve a new firmware */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Response of Firmware Update Information Get Message
|
||||
*/
|
||||
struct esp_ble_mesh_device_firmware_update_info_status {
|
||||
uint8_t fw_info_list_cnt; /*!< The number of entries in the Firmware Information List */
|
||||
uint8_t first_index; /*!< Index of the first requested entry from the Firmware Information List */
|
||||
esp_ble_mesh_firmware_info_t *fw_info_list; /*!< List of firmware information entries */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Response of Firmware Update Firmware Metadata Check Message
|
||||
*/
|
||||
struct esp_ble_mesh_device_firmware_metadata_check_status {
|
||||
uint8_t status : 3; /*!< Status Code from the firmware metadata check */
|
||||
uint8_t additional_info : 5; /*!< The Firmware Update Additional Information state from the Firmware Update Server (see Section 4.1.3)*/
|
||||
uint8_t update_firmware_image_index; /*!< Index of the firmware image in the Firmware Information List state that was checked*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Response of Firmware Update Get Message,
|
||||
* Firmware Update Start Message,
|
||||
* Firmware Update Cancel Message,
|
||||
* Firmware Update Apply Message.
|
||||
*/
|
||||
struct esp_ble_mesh_device_firmware_update_status {
|
||||
uint8_t status : 3; /*!< Status Code for the requesting message */
|
||||
uint8_t update_phase : 3; /*!< The Update Phase state of the Firmware Update Server */
|
||||
uint8_t update_ttl; /*!< TTL value to use during firmware image transfer */
|
||||
uint8_t additional_info : 5; /*!< The Firmware Update Additional Information state from the Firmware Update Server (see Section 4.1.3)*/
|
||||
uint16_t update_timeout_base; /*!< Used to compute the timeout of the firmware image transfer */
|
||||
uint64_t update_blob_id; /*!< BLOB identifier for the firmware image */
|
||||
uint8_t update_fw_img_idx; /*!< The index of the firmware image in the Firmware Information List state being updated*/
|
||||
};
|
||||
|
||||
/** Result of sending Device Firmware Update Client messages */
|
||||
struct esp_ble_mesh_dfu_client_send_cb {
|
||||
int err_code; /*!< Result of sending a message */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Device Firmware Update Client model received message union
|
||||
*/
|
||||
union esp_ble_mesh_dfu_client_recv_cb {
|
||||
esp_ble_mesh_device_firmware_update_info_status_t dfu_update_info_status; /*!< ESP_BLE_MESH_MODEL_OP_DIRECTED_CONTROL_STATUS */
|
||||
esp_ble_mesh_device_firmware_metadata_check_status_t dfu_metadata_check_status; /*!< ESP_BLE_MESH_MODEL_OP_PATH_METRIC_STATUS */
|
||||
esp_ble_mesh_device_firmware_update_status_t dfu_firmware_update_status; /*!< ESP_BLE_MESH_MODEL_OP_DISCOVERY_TABLE_CAPS_STATUS */
|
||||
};
|
||||
|
||||
/** Device Firmware Update Client model callback parameters */
|
||||
struct esp_ble_mesh_dfu_client_cb_param {
|
||||
esp_ble_mesh_client_common_param_t *params; /*!< Client common parameters, used by all events. */
|
||||
/** Union of DF Client callback */
|
||||
union {
|
||||
esp_ble_mesh_dfu_client_send_cb_t send; /*!< Result of sending a message */
|
||||
esp_ble_mesh_dfu_client_recv_cb_t recv; /*!< Parameters of received status message */
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Bluetooth Mesh Device Firmware Update client and server model functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Device Firmware Update Client model callback function type
|
||||
* @param event: Event type
|
||||
* @param param: Pointer to callback parameter
|
||||
*/
|
||||
typedef void (* esp_ble_mesh_dfu_client_cb_t)(esp_ble_mesh_dfu_client_cb_event_t event,
|
||||
esp_ble_mesh_dfu_client_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief Device Firmware Update Server model callback function type
|
||||
* @param event: Event type
|
||||
* @param param: Pointer to callback parameter
|
||||
*/
|
||||
typedef void (* esp_ble_mesh_dfu_server_cb_t)(esp_ble_mesh_dfu_client_cb_event_t event,
|
||||
esp_ble_mesh_dfu_client_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief Register BLE Mesh Device Firmware Update Client model callback.
|
||||
*
|
||||
* @param callback: Pointer to the callback function.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_register_dfu_client_callback(esp_ble_mesh_dfu_client_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief Get the value of Device Firmware Server model state with the corresponding get message.
|
||||
*
|
||||
* @param params: Pointer to BLE Mesh common client parameters.
|
||||
* @param get: Pointer to a union, each kind of opcode corresponds to one structure inside.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_dfu_client_get_state(esp_ble_mesh_client_common_param_t *params,
|
||||
esp_ble_mesh_dfu_client_get_t *get);
|
||||
|
||||
/** @brief Start distributing a DFU.
|
||||
*
|
||||
* Starts distribution of the firmware in the given slot to the list of DFU
|
||||
* Target nodes in @c ctx. The transfer runs in the background, and its end is
|
||||
* signalled through the bt_mesh_dfu_cli_cb::ended callback.
|
||||
*
|
||||
* @note The BLOB Transfer Client transfer inputs @c targets list must point to a list of
|
||||
* bt_mesh_dfu_target nodes. The contents of `inputs`, `io`, `xfer` must not be changed or
|
||||
* released from the beginning to the end of the transmission.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
* @param inputs BLOB Transfer Client transfer inputs.
|
||||
* @param io BLOB stream to read BLOB from.
|
||||
* @param xfer Firmware Update Client transfer parameters.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_dfu_cli_img_send(esp_ble_mesh_dfu_cli_t *cli,
|
||||
esp_ble_mesh_blob_cli_inputs_t *inputs,
|
||||
esp_ble_mesh_blob_io_t *io,
|
||||
esp_ble_mesh_dfu_cli_xfer_t *xfer);
|
||||
|
||||
/** @brief Get progress as a percentage of completion.
|
||||
*
|
||||
* @param cli Firmware Update Client model instance.
|
||||
*
|
||||
* @return The progress of the current transfer in percent, or 0 if no
|
||||
* transfer is active.
|
||||
*/
|
||||
uint8_t esp_ble_mesh_dfu_cli_progress(esp_ble_mesh_dfu_cli_t *cli);
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
/** @brief Firmware Update Server event callbacks. */
|
||||
struct esp_ble_mesh_dfu_srv_cb {
|
||||
/** @brief Transfer check callback.
|
||||
*
|
||||
* The transfer check can be used to validate the incoming transfer
|
||||
* before it starts. The contents of the metadata is implementation
|
||||
* specific, and should contain all the information the application
|
||||
* needs to determine whether this image should be accepted, and what
|
||||
* the effect of the transfer would be.
|
||||
*
|
||||
* If applying the image will have an effect on the provisioning state
|
||||
* of the mesh stack, this can be communicated through the @c effect
|
||||
* return parameter.
|
||||
*
|
||||
* The metadata check can be performed both as part of starting a new
|
||||
* transfer and as a separate procedure.
|
||||
*
|
||||
* This handler is optional.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
* @param img DFU image the metadata check is performed on.
|
||||
* @param metadata Image metadata.
|
||||
* @param effect Return parameter for the image effect on the
|
||||
* provisioning state of the mesh stack.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code otherwise.
|
||||
*/
|
||||
int (*check)(esp_ble_mesh_dfu_srv_t *srv,
|
||||
const esp_ble_mesh_dfu_img_t *img,
|
||||
struct net_buf_simple *metadata,
|
||||
esp_ble_mesh_dfu_effect_t *effect);
|
||||
|
||||
/** @brief Transfer start callback.
|
||||
*
|
||||
* Called when the Firmware Update Server is ready to start a new DFU transfer.
|
||||
* The application must provide an initialized BLOB stream to be used
|
||||
* during the DFU transfer.
|
||||
*
|
||||
* The following error codes are treated specially, and should be used
|
||||
* to communicate these issues:
|
||||
* - @c -ENOMEM: The device cannot fit this image.
|
||||
* - @c -EBUSY: The application is temporarily unable to accept the
|
||||
* transfer.
|
||||
* - @c -EALREADY: The device has already received and verified this
|
||||
* image, and there's no need to transfer it again. The Firmware Update model
|
||||
* will skip the transfer phase, and mark the image as verified.
|
||||
*
|
||||
* This handler is mandatory.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
* @param img DFU image being updated.
|
||||
* @param metadata Image metadata.
|
||||
* @param io BLOB stream return parameter. Must be set to a
|
||||
* valid BLOB stream by the callback.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code otherwise. Return
|
||||
* codes @c -ENOMEM, @c -EBUSY @c -EALREADY will be passed to
|
||||
* the updater, other error codes are reported as internal
|
||||
* errors.
|
||||
*/
|
||||
int (*start)(esp_ble_mesh_dfu_srv_t *srv,
|
||||
const esp_ble_mesh_dfu_img_t *img,
|
||||
struct net_buf_simple *metadata,
|
||||
const esp_ble_mesh_blob_io_t **io);
|
||||
|
||||
/** @brief Transfer end callback.
|
||||
*
|
||||
* This handler is optional.
|
||||
*
|
||||
* If the transfer is successful, the application should verify the
|
||||
* firmware image, and call either bt_mesh_dfu_srv_verified or
|
||||
* bt_mesh_dfu_srv_rejected depending on the outcome.
|
||||
*
|
||||
* If the transfer fails, the Firmware Update Server will be available for new
|
||||
* transfers immediately after this function returns.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
* @param img DFU image that failed the update.
|
||||
* @param success Whether the DFU transfer was successful.
|
||||
*/
|
||||
void (*end)(esp_ble_mesh_dfu_srv_t *srv,
|
||||
const esp_ble_mesh_dfu_img_t *img, bool success);
|
||||
|
||||
/** @brief Transfer recovery callback.
|
||||
*
|
||||
* If the device reboots in the middle of a transfer, the Firmware Update Server
|
||||
* calls this function when the Bluetooth mesh subsystem is started.
|
||||
*
|
||||
* This callback is optional, but transfers will not be recovered after
|
||||
* a reboot without it.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
* @param img DFU image being updated.
|
||||
* @param io BLOB stream return parameter. Must be set to a valid BLOB
|
||||
* stream by the callback.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code to abandon the
|
||||
* transfer.
|
||||
*/
|
||||
int (*recover)(esp_ble_mesh_dfu_srv_t *srv,
|
||||
const esp_ble_mesh_dfu_img_t *img,
|
||||
const esp_ble_mesh_blob_io_t **io);
|
||||
|
||||
/** @brief Transfer apply callback.
|
||||
*
|
||||
* Called after a transfer has been validated, and the updater sends an
|
||||
* apply message to the Target nodes.
|
||||
*
|
||||
* This handler is optional.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
* @param img DFU image that should be applied.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code otherwise.
|
||||
*/
|
||||
int (*apply)(esp_ble_mesh_dfu_srv_t *srv,
|
||||
const esp_ble_mesh_dfu_img_t *img);
|
||||
};
|
||||
|
||||
/** @brief Firmware Update Server instance.
|
||||
*
|
||||
* Should be initialized with ESP_BLE_MESH_DFU_SRV_INIT.
|
||||
* @note Preview version, the contents of this struct may change in the future.
|
||||
*/
|
||||
struct esp_ble_mesh_dfu_srv {
|
||||
/** Underlying BLOB Transfer Server. */
|
||||
esp_ble_mesh_blob_srv_t blob;
|
||||
/** Callback structure. */
|
||||
const esp_ble_mesh_dfu_srv_cb_t *cb;
|
||||
/** List of updatable images. */
|
||||
const esp_ble_mesh_dfu_img_t *imgs;
|
||||
/** Number of updatable images. */
|
||||
size_t img_count;
|
||||
|
||||
/** Runtime state */
|
||||
esp_ble_mesh_model_t *mod;
|
||||
/** Update information */
|
||||
struct {
|
||||
/* Effect of transfer, @see bt_mesh_dfu_effect. */
|
||||
uint8_t effect;
|
||||
/* Current phase, @see bt_mesh_dfu_phase. */
|
||||
uint8_t phase;
|
||||
uint8_t ttl;
|
||||
uint8_t idx;
|
||||
uint16_t timeout_base;
|
||||
uint16_t meta;
|
||||
} update;
|
||||
};
|
||||
|
||||
/** @brief Accept the received DFU transfer.
|
||||
*
|
||||
* Should be called at the end of a successful DFU transfer.
|
||||
*
|
||||
* If the DFU transfer completes successfully, the application should verify
|
||||
* the image validity (including any image authentication or integrity checks),
|
||||
* and call this function if the image is ready to be applied.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
*/
|
||||
void esp_ble_mesh_dfu_srv_verified(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
/** @brief Reject the received DFU transfer.
|
||||
*
|
||||
* Should be called at the end of a successful DFU transfer.
|
||||
*
|
||||
* If the DFU transfer completes successfully, the application should verify
|
||||
* the image validity (including any image authentication or integrity checks),
|
||||
* and call this function if one of the checks fail.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
*/
|
||||
void esp_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
/** @brief Cancel the ongoing DFU transfer.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
*/
|
||||
void esp_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
/** @brief Confirm that the received DFU transfer was applied.
|
||||
*
|
||||
* Should be called as a result of the `bt_mesh_dfu_srv_cb.apply` callback.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
*/
|
||||
void esp_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
/** @brief Check if the Firmware Update Server is busy processing a transfer.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
*
|
||||
* @return true if a DFU procedure is in progress, false otherwise.
|
||||
*/
|
||||
bool esp_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
/** @brief Get the progress of the current DFU procedure, in percent.
|
||||
*
|
||||
* @param srv Firmware Update Server instance.
|
||||
*
|
||||
* @return The current transfer progress in percent.
|
||||
*/
|
||||
uint8_t esp_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv);
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLE_MESH_DFU_MODEL_API_H_ */
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_BLE_MESH_DFU_SLOT_API_H_
|
||||
#define _ESP_BLE_MESH_DFU_SLOT_API_H_
|
||||
|
||||
#include "esp_ble_mesh_dfu_model_api.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SLOTS
|
||||
#ifndef _BLE_MESH_BLOB_DEPRECATE_WARN
|
||||
#define _BLE_MESH_BLOB_DEPRECATE_WARN
|
||||
#warning Please note: All APIs published in this document are in Preview version and may undergo significant changes in the future.
|
||||
#endif
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
|
||||
|
||||
typedef struct esp_ble_mesh_dfu_slot esp_ble_mesh_dfu_slot_t;
|
||||
|
||||
typedef enum esp_ble_mesh_dfu_iter
|
||||
(*esp_ble_mesh_dfu_slot_cb_t) (const esp_ble_mesh_dfu_slot_t *slot, void *user_data);
|
||||
|
||||
/** @brief Get the number of slots committed to the firmware list.
|
||||
*
|
||||
* @return Number of committed slots.
|
||||
*/
|
||||
int esp_ble_mesh_dfu_slot_count(void);
|
||||
|
||||
/** @brief Reserve a new DFU image slot for a distributable image.
|
||||
*
|
||||
* A DFU image slot represents a single distributable DFU image with all its
|
||||
* metadata. The slot data must be set using esp_ble_mesh_dfu_slot_info_set and
|
||||
* esp_ble_mesh_dfu_slot_fwid_set, and the slot committed using
|
||||
* esp_ble_mesh_dfu_slot_commit for the slot to be considered part of the slot
|
||||
* list.
|
||||
*
|
||||
* @return
|
||||
* - slot : A pointer to the reserved slot
|
||||
* - @c NULL : Slot allocation failed
|
||||
*/
|
||||
esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_reserve(void);
|
||||
|
||||
/** @brief Set the size and metadata for a reserved slot.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot for which to set the
|
||||
* metadata.
|
||||
* @param size The size of the image.
|
||||
* @param metadata Metadata or NULL.
|
||||
* @param metadata_len Length of the metadata, at most @c
|
||||
* CONFIG_BLE_MESH_DFU_METADATA_MAXLEN.
|
||||
*
|
||||
* @return
|
||||
* - 0 : success
|
||||
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter or invalid metadata parameter
|
||||
* - @c ESP_ERR_INVALID_SIZE : metadata length is zero or exceeds @c CONFIG_BLE_MESH_DFU_METADATA_MAXLEN
|
||||
*/
|
||||
int esp_ble_mesh_dfu_slot_info_set(esp_ble_mesh_dfu_slot_t *dfu_slot, size_t size,
|
||||
const uint8_t *metadata, size_t metadata_len);
|
||||
|
||||
/** @brief Set the new fwid for the incoming image for a reserved slot.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot for which to set the fwid.
|
||||
* @param fwid Fwid to set.
|
||||
* @param fwid_len Length of the fwid, at most @c
|
||||
* CONFIG_BLE_MESH_DFU_FWID_MAXLEN.
|
||||
*
|
||||
* @return
|
||||
* - 0 : success
|
||||
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter or invalid fwid parameter
|
||||
* - @c ESP_ERR_INVALID_SIZE : fwid length is zero or exceeds @c CONFIG_BLE_MESH_DFU_FWID_MAXLEN
|
||||
*/
|
||||
int esp_ble_mesh_dfu_slot_fwid_set(esp_ble_mesh_dfu_slot_t *dfu_slot,
|
||||
const uint8_t *fwid, size_t fwid_len);
|
||||
|
||||
/** @brief Commit the reserved slot to the list of slots, and store it
|
||||
* persistently.
|
||||
*
|
||||
* If the commit fails for any reason, the slot will still be in the reserved
|
||||
* state after this call.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot.
|
||||
*
|
||||
* @return
|
||||
* - 0 : success
|
||||
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter or slot has been committed
|
||||
* - @c ESP_ERR_INVALID_SIZE : slot size is zero
|
||||
*/
|
||||
int esp_ble_mesh_dfu_slot_commit(esp_ble_mesh_dfu_slot_t *dfu_slot);
|
||||
|
||||
/** @brief Release a reserved slot so that it can be reserved again.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot.
|
||||
*/
|
||||
void esp_ble_mesh_dfu_slot_release(const esp_ble_mesh_dfu_slot_t *dfu_slot);
|
||||
|
||||
/** @brief Delete a committed DFU image slot.
|
||||
*
|
||||
* @param slot Slot to delete. Must be a valid pointer acquired from this
|
||||
* module.
|
||||
*
|
||||
* @return
|
||||
* - 0 : success
|
||||
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter
|
||||
*/
|
||||
int esp_ble_mesh_dfu_slot_del(const esp_ble_mesh_dfu_slot_t *slot);
|
||||
|
||||
/** @brief Delete all DFU image slots.
|
||||
*/
|
||||
void esp_ble_mesh_dfu_slot_del_all(void);
|
||||
|
||||
/** @brief Get the DFU image slot at the given firmware image list index.
|
||||
*
|
||||
* @param img_idx DFU image slot index.
|
||||
*
|
||||
* @return
|
||||
* - slot : A pointer to the reserved slot
|
||||
* - @c NULL : No slot exists with the given index
|
||||
*/
|
||||
const esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_at(uint16_t img_idx);
|
||||
|
||||
/** @brief Get the committed DFU image slot for the image with the given
|
||||
* firmware ID.
|
||||
*
|
||||
* @param fwid Firmware ID.
|
||||
* @param fwid_len Firmware ID length.
|
||||
* @param slot Slot pointer to fill.
|
||||
*
|
||||
* @return
|
||||
* - index : Slot index
|
||||
* - @c ESP_ERR_INVALID_ARG : invalid fwid parameter or invalid slot parameter
|
||||
* - @c ESP_ERR_INVALID_SIZE : fwid length is zero
|
||||
* - @c ESP_ERR_NOT_FOUND : no slot exists with the given firmware id
|
||||
*/
|
||||
int esp_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, esp_ble_mesh_dfu_slot_t **slot);
|
||||
|
||||
/** @brief Get the index in the firmware image list for the given slot.
|
||||
*
|
||||
* @param slot Slot to find.
|
||||
*
|
||||
* @return
|
||||
* - index : Slot index
|
||||
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter
|
||||
* - @c ESP_ERR_NOT_FOUND : The slot does not exist
|
||||
*/
|
||||
int esp_ble_mesh_dfu_slot_img_idx_get(const esp_ble_mesh_dfu_slot_t *slot);
|
||||
|
||||
#endif /* _ESP_BLE_MESH_FW_SLOT_API_H_ */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,51 +9,86 @@
|
||||
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI
|
||||
#ifndef _BLE_MESH_MBT_DEPRECATE_WARN
|
||||
#define _BLE_MESH_MBT_DEPRECATE_WARN
|
||||
#warning "warning: 'All content in this document, including data structures and APIs, will be deprecated."
|
||||
#endif
|
||||
#endif /* CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_CI_BUILD
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
/** @cond */
|
||||
#if (CONFIG_BLE_MESH_MBT_SRV && CONFIG_BLE_MESH_BLOB_SRV) || \
|
||||
(CONFIG_BLE_MESH_MBT_CLI && CONFIG_BLE_MESH_BLOB_CLI)
|
||||
#error "BLOB Transfer Model and BLOB Model cannot be enabled at the same time"
|
||||
#endif
|
||||
/** @endcond */
|
||||
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x00)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_START ESP_BLE_MESH_MODEL_OP_2(0x83, 0x01)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_CANCEL ESP_BLE_MESH_MODEL_OP_2(0x83, 0x02)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x03)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_BLOCK_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x05)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_BLOCK_START ESP_BLE_MESH_MODEL_OP_2(0x83, 0x04)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_PARTIAL_BLOCK_REPORT ESP_BLE_MESH_MODEL_OP_1(0x65)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_BLOCK_STATUS ESP_BLE_MESH_MODEL_OP_1(0x67)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_CHUNK_TRANSFER ESP_BLE_MESH_MODEL_OP_1(0x66)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_INFORMATION_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x06)
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_MODEL_OP_BLOB_INFORMATION_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x07)
|
||||
|
||||
/** @deprecated This macro will be deprecated in future versions. */
|
||||
#define ESP_BLE_MESH_BLOB_ID_SIZE 8
|
||||
|
||||
/** @def ESP_BLE_MESH_MODEL_MBT_CLI
|
||||
/** @def ESP_BLE_MESH_MODEL_MBT_CLI
|
||||
*
|
||||
* @brief Define a new BLOB Transfer Client model.
|
||||
* @brief Define a new BLOB Transfer Client model.
|
||||
*
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a BLOB Transfer Client model.
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a BLOB Transfer Client model.
|
||||
*
|
||||
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
|
||||
* @deprecated This macro will be deprecated in future versions.
|
||||
*
|
||||
* @return New BLOB Transfer Client model instance.
|
||||
* @param cli_pub Pointer to unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param cli_data Pointer to unique struct esp_ble_mesh_client_t.
|
||||
*
|
||||
* @return New BLOB Transfer Client model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_MODEL_MBT_CLI(cli_pub, cli_data) \
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_MBT_CLI, \
|
||||
NULL, cli_pub, cli_data)
|
||||
|
||||
/** @def ESP_BLE_MESH_MODEL_MBT_SRV
|
||||
/** @def ESP_BLE_MESH_MODEL_MBT_SRV
|
||||
*
|
||||
* @brief Define a new BLOB Transfer Server model.
|
||||
* @brief Define a new BLOB Transfer Server model.
|
||||
*
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a BLOB Transfer Server model.
|
||||
* @note This API needs to be called for each element on which
|
||||
* the application needs to have a BLOB Transfer Server model.
|
||||
*
|
||||
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param srv_data Pointer to the unique struct esp_ble_mesh_blob_trans_srv_t.
|
||||
* @deprecated This macro will be deprecated in future versions.
|
||||
*
|
||||
* @return New BLOB Transfer Server model instance.
|
||||
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
|
||||
* @param srv_data Pointer to the unique struct esp_ble_mesh_blob_trans_srv_t.
|
||||
*
|
||||
* @return New BLOB Transfer Server model instance.
|
||||
*/
|
||||
#define ESP_BLE_MESH_MODEL_MBT_SRV(srv_pub, srv_data) \
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_MBT_SRV, \
|
||||
@@ -61,125 +96,125 @@ extern "C" {
|
||||
|
||||
/** BLOB Transfer Server model context */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
} esp_ble_mesh_mbt_srv_t;
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
} esp_ble_mesh_mbt_srv_t __attribute__((deprecated));
|
||||
|
||||
/** Parameters of BLOB receiver */
|
||||
typedef struct {
|
||||
uint16_t unicast_addr; /*!< Unicast address of the server */
|
||||
uint8_t retrieved_transfer_phase; /*!< Retrieved transfer phase of the server */
|
||||
uint8_t status:4; /*!< Status of the last operation */
|
||||
uint16_t blocks_not_received_len; /*!< Indicates the length which blocks were not received by the server. */
|
||||
uint8_t *blocks_not_received; /*!< Indicates which blocks were not received by the server. */
|
||||
uint16_t missing_chunks_len; /*!< Indicates which chunks were not received in the current block */
|
||||
uint8_t *missing_chunks; /*!< Indicates which chunks were not received by the server in the current block */
|
||||
/* The followings are the additional information contained in status messages. */
|
||||
uint8_t transfer_mode:2; /*!< BLOB transfer mode */
|
||||
uint8_t expected_blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< Expected BLOB identifier list */
|
||||
uint32_t blob_size; /*!< BLOB size in octets */
|
||||
uint8_t block_size_log; /*!< Indicates the block size */
|
||||
uint16_t transfer_mtu_size; /*!< MTU size in octets */
|
||||
bool block_status_recv; /*!< Indicate if Blob Block Status is received as a response. */
|
||||
} esp_ble_mesh_blob_receiver_t; /*!< Structure of BLOB receiver */
|
||||
uint16_t unicast_addr; /*!< Unicast address of the server */
|
||||
uint8_t retrieved_transfer_phase; /*!< Retrieved transfer phase of the server */
|
||||
uint8_t status: 4; /*!< Status of the last operation */
|
||||
uint16_t blocks_not_received_len; /*!< Indicates the length which blocks were not received by the server. */
|
||||
uint8_t *blocks_not_received; /*!< Indicates which blocks were not received by the server. */
|
||||
uint16_t missing_chunks_len; /*!< Indicates which chunks were not received in the current block */
|
||||
uint8_t *missing_chunks; /*!< Indicates which chunks were not received by the server in the current block */
|
||||
/* The following are the additional information contained in status messages. */
|
||||
uint8_t transfer_mode: 2; /*!< BLOB transfer mode */
|
||||
uint8_t expected_blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< Expected BLOB identifier list */
|
||||
uint32_t blob_size; /*!< BLOB size in octets */
|
||||
uint8_t block_size_log; /*!< Indicates the block size */
|
||||
uint16_t transfer_mtu_size; /*!< MTU size in octets */
|
||||
bool block_status_recv; /*!< Indicate if Blob Block Status is received as a response. */
|
||||
} esp_ble_mesh_blob_receiver_t __attribute__((deprecated)); /*!< Structure of BLOB receiver */
|
||||
|
||||
/** Parameters of BLOB Information Status */
|
||||
typedef struct {
|
||||
uint8_t min_block_size_log; /*!< Min Block Size Log */
|
||||
uint8_t max_block_size_log; /*!< Max Block Size Log */
|
||||
uint16_t max_total_chunks; /*!< Max Total Chunks */
|
||||
uint16_t max_chunk_size; /*!< Max Chunk Size */
|
||||
uint32_t max_blob_size; /*!< Max BLOB Size */
|
||||
uint16_t server_mtu_size; /*!< Server MTU size */
|
||||
uint8_t supported_transfer_mode; /*!< Supported Transfer Mode */
|
||||
} esp_ble_mesh_blob_capabilities_t; /*!< Parameters of BLOB Information Status */
|
||||
uint8_t min_block_size_log; /*!< Min Block Size Log */
|
||||
uint8_t max_block_size_log; /*!< Max Block Size Log */
|
||||
uint16_t max_total_chunks; /*!< Max Total Chunks */
|
||||
uint16_t max_chunk_size; /*!< Max Chunk Size */
|
||||
uint32_t max_blob_size; /*!< Max BLOB Size */
|
||||
uint16_t server_mtu_size; /*!< Server MTU size */
|
||||
uint8_t supported_transfer_mode; /*!< Supported Transfer Mode */
|
||||
} esp_ble_mesh_blob_capabilities_t __attribute__((deprecated)); /*!< Parameters of BLOB Information Status */
|
||||
|
||||
/** Parameters of BLOB retrieve capabilities */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
} esp_ble_mesh_retrieve_capabilities_t; /*!< Parameters of BLOB retrieve capabilities */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
} esp_ble_mesh_retrieve_capabilities_t __attribute__((deprecated)); /*!< Parameters of BLOB retrieve capabilities */
|
||||
|
||||
/** Parameters of BLOB transfer */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
|
||||
uint32_t blob_size; /*!< BLOB size in octets */
|
||||
uint8_t *blob_data; /*!< BLOB data */
|
||||
uint8_t transfer_mode; /*!< BLOB transfer mode */
|
||||
uint16_t client_timeout_base; /*!< Time wait for messages from the serve */
|
||||
} esp_ble_mesh_transfer_blob_t; /*!< Parameters of BLOB transfer */
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
|
||||
uint32_t blob_size; /*!< BLOB size in octets */
|
||||
uint8_t *blob_data; /*!< BLOB data */
|
||||
uint8_t transfer_mode; /*!< BLOB transfer mode */
|
||||
uint16_t client_timeout_base; /*!< Time wait for messages from the serve */
|
||||
} esp_ble_mesh_transfer_blob_t __attribute__((deprecated)); /*!< Parameters of BLOB transfer */
|
||||
|
||||
/** Parameters of BLOB Block Status message */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
|
||||
uint16_t block_number; /*!< Block number of the current block */
|
||||
uint16_t chunk_size; /*!< Chunk Size (in octets) for the current block */
|
||||
} esp_ble_mesh_send_block_t; /*!< BLOB Block Status message structure */
|
||||
uint16_t block_number; /*!< Block number of the current block */
|
||||
uint16_t chunk_size; /*!< Chunk Size (in octets) for the current block */
|
||||
} esp_ble_mesh_send_block_t __attribute__((deprecated)); /*!< BLOB Block Status message structure */
|
||||
|
||||
/** Parameters of BLOB send message */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} esp_ble_mesh_send_data_t; /*!< Parameters of BLOB send message */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} esp_ble_mesh_send_data_t __attribute__((deprecated)); /*!< Parameters of BLOB send message */
|
||||
|
||||
/** Parameters of determine Block Status message */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} esp_ble_mesh_determine_block_status_t; /*!< Parameters of determine Block Status message */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} esp_ble_mesh_determine_block_status_t __attribute__((deprecated)); /*!< Parameters of determine Block Status message */
|
||||
|
||||
/** Parameters of determine Block Status message */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
} esp_ble_mesh_determine_transfer_status_t; /*!< Parameters of determine Block Status message */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
} esp_ble_mesh_determine_transfer_status_t __attribute__((deprecated)); /*!< Parameters of determine Block Status message */
|
||||
|
||||
/** Parameters of cancel transfer message */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
|
||||
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
|
||||
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
uint8_t unicast_addr_count; /*!< The count of unicast address */
|
||||
uint16_t *unicast_addr; /*!< Unicast address list */
|
||||
|
||||
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
|
||||
} esp_ble_mesh_cancel_transfer_t; /*!< Parameters of cancel transfer message */
|
||||
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
|
||||
} esp_ble_mesh_cancel_transfer_t __attribute__((deprecated)); /*!< Parameters of cancel transfer message */
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client model procedure result
|
||||
@@ -193,113 +228,113 @@ typedef struct {
|
||||
typedef union {
|
||||
/** Retrieve capabilities status */
|
||||
struct {
|
||||
int error_code; /*!< Result of starting Retrieve Capabilities procedure */
|
||||
esp_ble_mesh_retrieve_capabilities_t input; /*!< Input of starting Retrieve Capabilities procedure */
|
||||
} retrieve_capabilities_status; /*!< Retrieve capabilities status */
|
||||
int error_code; /*!< Result of starting Retrieve Capabilities procedure */
|
||||
esp_ble_mesh_retrieve_capabilities_t input; /*!< Input of starting Retrieve Capabilities procedure */
|
||||
} retrieve_capabilities_status; /*!< Retrieve capabilities status */
|
||||
/** Transfer BLOB status */
|
||||
struct {
|
||||
int error_code; /*!< Result of starting Transfer BLOB procedure */
|
||||
esp_ble_mesh_transfer_blob_t input; /*!< Input of starting Transfer BLOB procedure */
|
||||
} transfer_blob_status; /*!< Transfer BLOB status */
|
||||
int error_code; /*!< Result of starting Transfer BLOB procedure */
|
||||
esp_ble_mesh_transfer_blob_t input; /*!< Input of starting Transfer BLOB procedure */
|
||||
} transfer_blob_status; /*!< Transfer BLOB status */
|
||||
/** Send block status */
|
||||
struct {
|
||||
int error_code; /*!< Result of starting Send Block sub-procedure */
|
||||
esp_ble_mesh_send_block_t input; /*!< Input of starting Send Block sub-procedure */
|
||||
} send_block_status; /*!< Send block status */
|
||||
int error_code; /*!< Result of starting Send Block sub-procedure */
|
||||
esp_ble_mesh_send_block_t input; /*!< Input of starting Send Block sub-procedure */
|
||||
} send_block_status; /*!< Send block status */
|
||||
/** Send data status */
|
||||
struct {
|
||||
int error_code; /*!< Result of starting Send Data sub-procedure */
|
||||
esp_ble_mesh_send_data_t input; /*!< Input of starting Send Data sub-procedure */
|
||||
} send_data_status; /*!< Send data status */
|
||||
int error_code; /*!< Result of starting Send Data sub-procedure */
|
||||
esp_ble_mesh_send_data_t input; /*!< Input of starting Send Data sub-procedure */
|
||||
} send_data_status; /*!< Send data status */
|
||||
/** Determine block status */
|
||||
struct {
|
||||
int error_code; /*!< Result of starting Determine Block Status sub-procedure */
|
||||
esp_ble_mesh_determine_block_status_t input; /*!< Input of starting Determine Block Status sub-procedure */
|
||||
} determine_block_status_status; /*!< Determine block status */
|
||||
int error_code; /*!< Result of starting Determine Block Status sub-procedure */
|
||||
esp_ble_mesh_determine_block_status_t input; /*!< Input of starting Determine Block Status sub-procedure */
|
||||
} determine_block_status_status; /*!< Determine block status */
|
||||
/** Determine transfer status */
|
||||
struct {
|
||||
int error_code; /*!< Result of starting Determine Transfer Status procedure */
|
||||
esp_ble_mesh_determine_transfer_status_t input; /*!< Input of starting Determine Transfer Status procedure */
|
||||
} determine_transfer_status_status; /*!< Determine transfer status */
|
||||
int error_code; /*!< Result of starting Determine Transfer Status procedure */
|
||||
esp_ble_mesh_determine_transfer_status_t input; /*!< Input of starting Determine Transfer Status procedure */
|
||||
} determine_transfer_status_status; /*!< Determine transfer status */
|
||||
/** Cancel transfer status */
|
||||
struct {
|
||||
int error_code; /*!< Result of starting Cancel Transfer procedure */
|
||||
esp_ble_mesh_cancel_transfer_t input; /*!< Input of starting Cancel Transfer procedure */
|
||||
} cancel_transfer_status; /*!< Cancel transfer status */
|
||||
int error_code; /*!< Result of starting Cancel Transfer procedure */
|
||||
esp_ble_mesh_cancel_transfer_t input; /*!< Input of starting Cancel Transfer procedure */
|
||||
} cancel_transfer_status; /*!< Cancel transfer status */
|
||||
/** Retrieve capabilities complete */
|
||||
struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Retrieve Capabilities procedure */
|
||||
} retrieve_capabilities_comp; /*!< Retrieve capabilities complete */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Retrieve Capabilities procedure */
|
||||
} retrieve_capabilities_comp; /*!< Retrieve capabilities complete */
|
||||
/** Transfer BLOB complete */
|
||||
struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Transfer BLOB procedure */
|
||||
} transfer_blob_comp; /*!< Transfer BLOB complete */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Transfer BLOB procedure */
|
||||
} transfer_blob_comp; /*!< Transfer BLOB complete */
|
||||
/** Send block complete */
|
||||
struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Send Block sub-procedure */
|
||||
} send_block_comp; /*!< Send block complete */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Send Block sub-procedure */
|
||||
} send_block_comp; /*!< Send block complete */
|
||||
/** Send data complete */
|
||||
struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Send Data sub-procedure */
|
||||
} send_data_comp; /*!< Send data complete */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Send Data sub-procedure */
|
||||
} send_data_comp; /*!< Send data complete */
|
||||
/** Determine block status complete */
|
||||
struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Determine Block Status sub-procedure */
|
||||
} determine_block_status_comp; /*!< Determine block status complete */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Determine Block Status sub-procedure */
|
||||
} determine_block_status_comp; /*!< Determine block status complete */
|
||||
/** Determine transfer status complete */
|
||||
struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Determine Transfer Status procedure */
|
||||
} determine_transfer_status_comp; /*!< Determine transfer status complete */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Determine Transfer Status procedure */
|
||||
} determine_transfer_status_comp; /*!< Determine transfer status complete */
|
||||
/** Cancel transfer complete */
|
||||
struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Cancel Transfer procedure */
|
||||
} cancel_transfer_comp; /*!< Cancel transfer complete */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t result; /*!< Result of Cancel Transfer procedure */
|
||||
} cancel_transfer_comp; /*!< Cancel transfer complete */
|
||||
/** Set transfer TTL */
|
||||
struct {
|
||||
int error_code; /*!< Result of setting Transfer TTL state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} set_transfer_ttl; /*!< Set transfer TTL */
|
||||
int error_code; /*!< Result of setting Transfer TTL state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} set_transfer_ttl; /*!< Set transfer TTL */
|
||||
/** Clear transfer TTL */
|
||||
struct {
|
||||
int error_code; /*!< Result of clearing Transfer TTL state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
} clear_transfer_ttl; /*!< Clear transfer TTL */
|
||||
int error_code; /*!< Result of clearing Transfer TTL state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
} clear_transfer_ttl; /*!< Clear transfer TTL */
|
||||
/** Set application index */
|
||||
struct {
|
||||
int error_code; /*!< Result of setting AppKey Index state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
} set_app_idx; /*!< Set application index */
|
||||
int error_code; /*!< Result of setting AppKey Index state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint16_t app_idx; /*!< AppKey Index state */
|
||||
} set_app_idx; /*!< Set application index */
|
||||
/** Clear application index */
|
||||
struct {
|
||||
int error_code; /*!< Result of clearing AppKey Index state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
} clear_app_idx; /*!< Clear application index */
|
||||
int error_code; /*!< Result of clearing AppKey Index state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
} clear_app_idx; /*!< Clear application index */
|
||||
/** Set multicast address */
|
||||
struct {
|
||||
int error_code; /*!< Result of setting Multicast Address state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
} set_multicast_addr; /*!< Set multicast address */
|
||||
int error_code; /*!< Result of setting Multicast Address state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
uint16_t multicast_addr; /*!< Multicast Address state */
|
||||
} set_multicast_addr; /*!< Set multicast address */
|
||||
/** Clear multicast address */
|
||||
struct {
|
||||
int error_code; /*!< Result of clearing Multicast Address state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
} clear_multicast_addr; /*!< Clear multicast address */
|
||||
} esp_ble_mesh_mbt_client_cb_value_t; /*!< BLOB Transfer Client model callback values union */
|
||||
int error_code; /*!< Result of clearing Multicast Address state */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
} clear_multicast_addr; /*!< Clear multicast address */
|
||||
} esp_ble_mesh_mbt_client_cb_value_t; /*!< BLOB Transfer Client model callback values union */
|
||||
|
||||
/** BLOB Transfer Client model callback parameters */
|
||||
typedef struct {
|
||||
esp_ble_mesh_mbt_client_cb_value_t value; /*!< BLOB Transfer Client model callback values */
|
||||
} esp_ble_mesh_mbt_client_cb_param_t; /*!< BLOB Transfer Client model callback parameters */
|
||||
esp_ble_mesh_mbt_client_cb_value_t value; /*!< BLOB Transfer Client model callback values */
|
||||
} esp_ble_mesh_mbt_client_cb_param_t __attribute__((deprecated)); /*!< BLOB Transfer Client model callback parameters */
|
||||
|
||||
/**
|
||||
* This enum value is the event of BLOB Transfer Client model.
|
||||
@@ -327,30 +362,30 @@ typedef enum {
|
||||
ESP_BLE_MESH_MBT_CLIENT_SET_MULTICAST_ADDR_COMP_EVT,
|
||||
ESP_BLE_MESH_MBT_CLIENT_CLEAR_MULTICAST_ADDR_COMP_EVT,
|
||||
ESP_BLE_MESH_MBT_CLIENT_EVT_MAX,
|
||||
} esp_ble_mesh_mbt_client_cb_event_t;
|
||||
} esp_ble_mesh_mbt_client_cb_event_t __attribute__((deprecated));
|
||||
|
||||
/** Parameters of initialize BLOB receive */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
|
||||
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
|
||||
uint16_t timeout; /*!< Timeout */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} esp_ble_mesh_initialize_blob_receive_t; /*!< Structure of initialize BLOB receive */
|
||||
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
|
||||
uint16_t timeout; /*!< Timeout */
|
||||
uint8_t transfer_ttl; /*!< Transfer TTL state */
|
||||
} esp_ble_mesh_initialize_blob_receive_t __attribute__((deprecated)); /*!< Structure of initialize BLOB receive */
|
||||
|
||||
/** Parameters of cancel BLOB receive */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
|
||||
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
|
||||
} esp_ble_mesh_cancel_blob_receive_t;/*!< */
|
||||
} esp_ble_mesh_cancel_blob_receive_t __attribute__((deprecated));/*!< */
|
||||
|
||||
/** Parameters of cancel BLOB receive */
|
||||
typedef struct {
|
||||
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
|
||||
|
||||
esp_ble_mesh_blob_capabilities_t caps; /*!< Parameters of BLOB Information Status */
|
||||
} esp_ble_mesh_set_blob_capabilities_t;/*!< */
|
||||
} esp_ble_mesh_set_blob_capabilities_t __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Server model callback value union
|
||||
@@ -358,61 +393,61 @@ typedef struct {
|
||||
typedef union {
|
||||
/** Initialize BLOB receive complete */
|
||||
struct {
|
||||
int error_code; /*!< Result of initializing BLOB receive */
|
||||
esp_ble_mesh_initialize_blob_receive_t input; /*!< Input of initializing BLOB receive */
|
||||
} initialize_blob_receive_comp; /*!< Initialize BLOB receive complete */
|
||||
int error_code; /*!< Result of initializing BLOB receive */
|
||||
esp_ble_mesh_initialize_blob_receive_t input; /*!< Input of initializing BLOB receive */
|
||||
} initialize_blob_receive_comp; /*!< Initialize BLOB receive complete */
|
||||
/** Cancel BLOB receive complete */
|
||||
struct {
|
||||
int error_code; /*!< Result of canceling BLOB receive */
|
||||
esp_ble_mesh_cancel_blob_receive_t input; /*!< Input of canceling BLOB receive */
|
||||
} cancel_blob_receive_comp; /*!< Cancel BLOB receive complete */
|
||||
int error_code; /*!< Result of canceling BLOB receive */
|
||||
esp_ble_mesh_cancel_blob_receive_t input; /*!< Input of canceling BLOB receive */
|
||||
} cancel_blob_receive_comp; /*!< Cancel BLOB receive complete */
|
||||
/** Set BLOB capabilities complete */
|
||||
struct {
|
||||
int error_code; /*!< Result of setting BLOB capabilities */
|
||||
esp_ble_mesh_set_blob_capabilities_t input; /*!< Input of setting BLOB capabilities */
|
||||
} set_blob_capabilities_comp; /*!< Set BLOB capabilities complete */
|
||||
int error_code; /*!< Result of setting BLOB capabilities */
|
||||
esp_ble_mesh_set_blob_capabilities_t input; /*!< Input of setting BLOB capabilities */
|
||||
} set_blob_capabilities_comp; /*!< Set BLOB capabilities complete */
|
||||
/** BLOB transfer get */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Get message context */
|
||||
} blob_transfer_get; /*!< BLOB transfer get */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Get message context */
|
||||
} blob_transfer_get; /*!< BLOB transfer get */
|
||||
/** BLOB transfer start */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Start message context */
|
||||
} blob_transfer_start; /*!< BLOB transfer start */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Start message context */
|
||||
} blob_transfer_start; /*!< BLOB transfer start */
|
||||
/** BLOB transfer cancel */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Cancel message context */
|
||||
} blob_transfer_cancel; /*!< BLOB transfer cancel */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Cancel message context */
|
||||
} blob_transfer_cancel; /*!< BLOB transfer cancel */
|
||||
/** BLOB block get */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Get message context */
|
||||
} blob_block_get; /*!< BLOB block get */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Get message context */
|
||||
} blob_block_get; /*!< BLOB block get */
|
||||
/** BLOB block start */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Start message context */
|
||||
} blob_block_start; /*!< BLOB block start */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Start message context */
|
||||
} blob_block_start; /*!< BLOB block start */
|
||||
/** BLOB chunk transfer */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Chunk Transfer message context */
|
||||
} blob_chunk_transfer; /*!< BLOB chunk transfer */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Chunk Transfer message context */
|
||||
} blob_chunk_transfer; /*!< BLOB chunk transfer */
|
||||
/** BLOB information get */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Information Get message context */
|
||||
} blob_information_get; /*!< BLOB information get */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Information Get message context */
|
||||
} blob_information_get; /*!< BLOB information get */
|
||||
/** Block receive complete */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB block completely */
|
||||
} block_receive_comp; /*!< Block receive complete */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB block completely */
|
||||
} block_receive_comp; /*!< Block receive complete */
|
||||
/** BLOB receive complete */
|
||||
struct {
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB completely */
|
||||
} blob_receive_comp; /*!< BLOB receive complete */
|
||||
} esp_ble_mesh_mbt_server_cb_value_t; /*!< BLOB Transfer Server model callback value union */
|
||||
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB completely */
|
||||
} blob_receive_comp; /*!< BLOB receive complete */
|
||||
} esp_ble_mesh_mbt_server_cb_value_t __attribute__((deprecated)); /*!< BLOB Transfer Server model callback value union */
|
||||
|
||||
/** BLOB Transfer Server model callback parameters */
|
||||
typedef struct {
|
||||
esp_ble_mesh_mbt_server_cb_value_t value; /*!< Value of the received blob transfer messages */
|
||||
} esp_ble_mesh_mbt_server_cb_param_t; /*!< BLOB Transfer Server model callback parameters */
|
||||
esp_ble_mesh_mbt_server_cb_value_t value; /*!< Value of the received blob transfer messages */
|
||||
} esp_ble_mesh_mbt_server_cb_param_t __attribute__((deprecated)); /*!< BLOB Transfer Server model callback parameters */
|
||||
|
||||
/** This enum value is the event of BLOB Transfer Server model */
|
||||
typedef enum {
|
||||
@@ -430,7 +465,7 @@ typedef enum {
|
||||
ESP_BLE_MESH_MBT_SERVER_BLOB_RECEIVE_COMP_EVT,
|
||||
ESP_BLE_MESH_MBT_SERVER_BLOB_RECEIVE_TIMEOUT_EVT,
|
||||
ESP_BLE_MESH_MBT_SERVER_EVT_MAX,
|
||||
} esp_ble_mesh_mbt_server_cb_event_t;
|
||||
} esp_ble_mesh_mbt_server_cb_event_t __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client model callback function type
|
||||
@@ -453,96 +488,116 @@ typedef void (* esp_ble_mesh_mbt_server_cb_t)(esp_ble_mesh_mbt_server_cb_event_t
|
||||
/**
|
||||
* @brief Register BLE Mesh BLOB Transfer Client model callback.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] callback: Pointer to the callback function.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback);
|
||||
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief Register BLE Mesh BLOB Transfer Server model callback.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] callback: Pointer to the callback function.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback);
|
||||
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client starts Retrieve Capabilities procedure.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of Retrieve Capabilities procedure.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client starts Transfer BLOB procedure.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of Transfer BLOB procedure.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client starts Send Block sub-procedure.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of Send Block sub-procedure.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client starts Send Data sub-procedure.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of Send Data sub-procedure.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client starts Determine Block Status sub-procedure.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of Determine Block Status sub-procedure.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client starts Determine Transfer Status procedure.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of Determine Transfer Status procedure.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client starts Cancel Transfer procedure.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of Cancel Transfer procedure.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client gets BLOB receiver.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
* @param[in] unicast_addr: Unicast address of the BLOB receiver.
|
||||
*
|
||||
@@ -550,21 +605,25 @@ esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t
|
||||
*
|
||||
*/
|
||||
const esp_ble_mesh_blob_receiver_t *esp_ble_mesh_mbt_client_get_blob_receiver(esp_ble_mesh_model_t *model,
|
||||
uint16_t unicast_addr);
|
||||
uint16_t unicast_addr) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client gets active BLOB receiver list.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
*
|
||||
* @return Active BLOB receiver list on success or NULL on failure.
|
||||
*
|
||||
*/
|
||||
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model);
|
||||
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client gets BLOB transfer progress.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
* @param[in] unicast_addr: Unicast address of the BLOB receiver.
|
||||
* @param[in] block_percent: Block reception percent to be updated.
|
||||
@@ -576,11 +635,13 @@ const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_rec
|
||||
esp_err_t esp_ble_mesh_mbt_client_get_transfer_progress(esp_ble_mesh_model_t *model,
|
||||
uint16_t unicast_addr,
|
||||
uint8_t *block_percent,
|
||||
uint8_t *chunk_percent);
|
||||
uint8_t *chunk_percent) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client sets Transfer TTL state.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
* @param[in] transfer_ttl: Transfer TTL state value.
|
||||
*
|
||||
@@ -588,21 +649,25 @@ esp_err_t esp_ble_mesh_mbt_client_get_transfer_progress(esp_ble_mesh_model_t *mo
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_set_transfer_ttl(esp_ble_mesh_model_t *model,
|
||||
uint8_t transfer_ttl);
|
||||
uint8_t transfer_ttl) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client clear Transfer TTL state.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model);
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client sets AppKey Index state.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
* @param[in] app_idx: AppKey Index state value.
|
||||
*
|
||||
@@ -610,21 +675,25 @@ esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_set_app_idx(esp_ble_mesh_model_t *model,
|
||||
uint16_t app_idx);
|
||||
uint16_t app_idx) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client clear AppKey Index state.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model);
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client sets Multicast Address state.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
* @param[in] multicast_addr: Multicast Address state value.
|
||||
*
|
||||
@@ -632,51 +701,61 @@ esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model);
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_set_multicast_addr(esp_ble_mesh_model_t *model,
|
||||
uint16_t multicast_addr);
|
||||
uint16_t multicast_addr) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Client clear Multicast Address state.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Client model.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model);
|
||||
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Server initializes BLOB receive.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of initializing BLOB receive.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Server cancels BLOB receive.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of cancelling BLOB receive.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Server sets BLOB capabilities.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] input: The input of setting BLOB capabilities.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input);
|
||||
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief BLOB Transfer Server gets current BLOB reception progress.
|
||||
*
|
||||
* @deprecated This function will be deprecated in future versions.
|
||||
*
|
||||
* @param[in] model: BLOB Transfer Server model.
|
||||
* @param[in] reception_progress: Reception progress to be updated.
|
||||
*
|
||||
@@ -684,7 +763,11 @@ esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_ca
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_mbt_server_get_blob_reception_progress(esp_ble_mesh_model_t *model,
|
||||
uint8_t *reception_progress);
|
||||
uint8_t *reception_progress) __attribute__((deprecated));
|
||||
|
||||
#if CONFIG_IDF_CI_BUILD
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "btc_ble_mesh_model_common.h"
|
||||
#include "btc_ble_mesh_dfu_model.h"
|
||||
#include "esp_ble_mesh_dfu_model_api.h"
|
||||
#include "mesh_v1.1/dfu/dfu_cli.h"
|
||||
#include "mesh_v1.1/dfu/dfu_srv.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
/* Device Firmware Update Client model related functions */
|
||||
|
||||
static inline void btc_ble_mesh_dfu_client_cb_to_app(btc_ble_mesh_dfu_client_cb_evt_t event,
|
||||
esp_ble_mesh_dfu_client_cb_param_t *param)
|
||||
{
|
||||
esp_ble_mesh_dfu_client_cb_t btc_ble_mesh_cb =
|
||||
btc_profile_cb_get(BTC_PID_DFU_CLIENT);
|
||||
if (btc_ble_mesh_cb) {
|
||||
btc_ble_mesh_cb(event, param);
|
||||
}
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
btc_ble_mesh_dfu_client_args_t *dst = p_dest;
|
||||
btc_ble_mesh_dfu_client_args_t *src = p_src;
|
||||
|
||||
if (!msg || !dst || !src) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE: {
|
||||
dst->dfu_get.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t));
|
||||
if (dst->dfu_get.params) {
|
||||
memcpy(dst->dfu_get.params, src->dfu_get.params,
|
||||
sizeof(esp_ble_mesh_client_common_param_t));
|
||||
} else {
|
||||
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
if (src->dfu_get.get) {
|
||||
dst->dfu_get.get = bt_mesh_calloc(sizeof(esp_ble_mesh_dfu_client_get_t));
|
||||
if (dst->dfu_get.get) {
|
||||
memcpy(dst->dfu_get.get, src->dfu_get.get,
|
||||
sizeof(esp_ble_mesh_dfu_client_get_t));
|
||||
if (src->dfu_get.params->opcode == ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK) {
|
||||
if (src->dfu_get.get->dfu_metadata_check.metadata) {
|
||||
dst->dfu_get.get->dfu_metadata_check.metadata = bt_mesh_alloc_buf(src->dfu_get.get->dfu_metadata_check.metadata->len);
|
||||
if (dst->dfu_get.get->dfu_metadata_check.metadata) {
|
||||
net_buf_simple_add_mem(dst->dfu_get.get->dfu_metadata_check.metadata,
|
||||
src->dfu_get.get->dfu_metadata_check.metadata->data,
|
||||
src->dfu_get.get->dfu_metadata_check.metadata->len);
|
||||
} else {
|
||||
BT_ERR("Out of memory for metadata");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
BT_ERR("Metadata should be exists");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BT_DBG("%s, Unknown act %d", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_client_arg_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
btc_ble_mesh_dfu_client_args_t *arg = NULL;
|
||||
|
||||
if (!msg) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
arg = (btc_ble_mesh_dfu_client_args_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE:
|
||||
if (arg->dfu_get.params) {
|
||||
bt_mesh_free(arg->dfu_get.params);
|
||||
}
|
||||
if (arg->dfu_get.get) {
|
||||
bt_mesh_free(arg->dfu_get.get);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_ble_mesh_dfu_client_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
esp_ble_mesh_dfu_client_cb_param_t *p_dest_data = p_dest;
|
||||
esp_ble_mesh_dfu_client_cb_param_t *p_src_data = p_src;
|
||||
uint16_t length = 0;
|
||||
|
||||
if (!msg || !p_src_data || !p_dest_data) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_src_data->params) {
|
||||
p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t));
|
||||
if (!p_dest_data->params) {
|
||||
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
|
||||
}
|
||||
|
||||
switch (msg->act) {
|
||||
case ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT:
|
||||
if (p_src_data->params) {
|
||||
switch (p_src_data->params->opcode) {
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
|
||||
if (p_src_data->recv.dfu_update_info_status.fw_info_list_cnt) {
|
||||
length = p_src_data->recv.dfu_update_info_status.fw_info_list_cnt * sizeof(esp_ble_mesh_firmware_info_t);
|
||||
p_dest_data->recv.dfu_update_info_status.fw_info_list = bt_mesh_calloc(length);
|
||||
if (!p_dest_data->recv.dfu_update_info_status.fw_info_list) {
|
||||
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
|
||||
return;
|
||||
}
|
||||
memcpy(p_dest_data->recv.dfu_update_info_status.fw_info_list,
|
||||
p_src_data->recv.dfu_update_info_status.fw_info_list,
|
||||
length);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT:
|
||||
case ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT:
|
||||
case ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_ble_mesh_dfu_client_free_req_data(btc_msg_t *msg)
|
||||
{
|
||||
esp_ble_mesh_dfu_client_cb_param_t *arg = NULL;
|
||||
|
||||
if (!msg) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->act >= ESP_BLE_MESH_DFU_CLIENT_EVT_MAX) {
|
||||
BT_ERR("%s, Invalid event %d", msg->act);
|
||||
return;
|
||||
}
|
||||
|
||||
arg = (esp_ble_mesh_dfu_client_cb_param_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT:
|
||||
if (arg->params) {
|
||||
switch (arg->params->opcode) {
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
|
||||
bt_mesh_free(arg->recv.dfu_update_info_status.fw_info_list);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT:
|
||||
case ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT:
|
||||
case ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT:
|
||||
break;
|
||||
default:
|
||||
BT_WARN("Unprocessed event %d", msg->act);
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg->params) {
|
||||
bt_mesh_free(arg->params);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void btc_ble_mesh_dfu_client_cb(esp_ble_mesh_dfu_client_cb_param_t *cb_params, uint8_t act)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
/* If corresponding callback is not registered, event will not be posted. */
|
||||
if (!btc_profile_cb_get(BTC_PID_DFU_CLIENT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_DFU_CLIENT;
|
||||
msg.act = act;
|
||||
|
||||
btc_transfer_context(&msg, cb_params, sizeof(esp_ble_mesh_dfu_client_cb_param_t),
|
||||
btc_ble_mesh_dfu_client_copy_req_data,
|
||||
btc_ble_mesh_dfu_client_free_req_data);
|
||||
}
|
||||
|
||||
void bt_mesh_dfu_client_cb_evt_to_btc(uint32_t opcode, uint8_t event,
|
||||
struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
const uint8_t *val, size_t len)
|
||||
{
|
||||
esp_ble_mesh_dfu_client_cb_param_t cb_params = {0};
|
||||
esp_ble_mesh_client_common_param_t params = {0};
|
||||
uint8_t act = 0;
|
||||
|
||||
if (!model || !ctx || len > sizeof(cb_params.recv)) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case BTC_BLE_MESH_EVT_DFU_CLIENT_TIMEOUT:
|
||||
act = ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT;
|
||||
break;
|
||||
case BTC_BLE_MESH_EVT_DFU_CLIENT_RECV_GET_RSP:
|
||||
act = ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT;
|
||||
break;
|
||||
case BTC_BLE_MESH_EVT_DFU_CLIENT_IMG_SEND_CMP:
|
||||
act = ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT;
|
||||
break;
|
||||
default:
|
||||
BT_ERR("Unknown Device Firmware Update client event type %d", event);
|
||||
return;
|
||||
}
|
||||
|
||||
params.opcode = opcode;
|
||||
params.model = (esp_ble_mesh_model_t *)model;
|
||||
params.ctx.net_idx = ctx->net_idx;
|
||||
params.ctx.app_idx = ctx->app_idx;
|
||||
params.ctx.addr = ctx->addr;
|
||||
params.ctx.recv_ttl = ctx->recv_ttl;
|
||||
params.ctx.recv_op = ctx->recv_op;
|
||||
params.ctx.recv_dst = ctx->recv_dst;
|
||||
params.ctx.recv_rssi = ctx->recv_rssi;
|
||||
params.ctx.send_ttl = ctx->send_ttl;
|
||||
|
||||
cb_params.params = ¶ms;
|
||||
|
||||
if (val && len) {
|
||||
memcpy(&cb_params.recv, val, len);
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_client_cb(&cb_params, act);
|
||||
}
|
||||
|
||||
static int btc_ble_mesh_dfu_client_get_state(esp_ble_mesh_client_common_param_t *params,
|
||||
esp_ble_mesh_dfu_client_get_t *get)
|
||||
{
|
||||
bt_mesh_client_common_param_t param = {0};
|
||||
struct bt_mesh_dfu_cli *dfu_cli = NULL;
|
||||
|
||||
if (params == NULL ||
|
||||
params->model == NULL ||
|
||||
params->model->user_data == NULL) {
|
||||
BT_ERR("%s, Invalid parameter %d %p %p", __func__, params == NULL, params->model, params->model->user_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dfu_cli = (struct bt_mesh_dfu_cli *)params->model->user_data;
|
||||
|
||||
switch (params->opcode) {
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK:
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_START:
|
||||
if (get == NULL) {
|
||||
BT_ERR("Invalid Device Firmware Update Get");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
btc_ble_mesh_set_client_common_param(params, ¶m, false);
|
||||
|
||||
switch (param.opcode) {
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
|
||||
return bt_mesh_dfu_cli_imgs_get(dfu_cli, ¶m.ctx, (bt_mesh_dfu_img_cb_t) get->dfu_update_info_get.img_cb,
|
||||
NULL, get->dfu_update_info_get.first_index,
|
||||
get->dfu_update_info_get.entries_limit);
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK:
|
||||
return bt_mesh_dfu_cli_metadata_check(dfu_cli, ¶m.ctx, get->dfu_metadata_check.update_firmware_index,
|
||||
get->dfu_metadata_check.metadata);
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_GET:
|
||||
return bt_mesh_dfu_cli_status_get(dfu_cli, ¶m.ctx);
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_START:
|
||||
// automatic start
|
||||
return 0;
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_CANCEL:
|
||||
return bt_mesh_dfu_cli_cancel(dfu_cli, ¶m.ctx);
|
||||
case ESP_BLE_MESH_DFU_OP_UPDATE_APPLY:
|
||||
return bt_mesh_dfu_cli_apply(dfu_cli);
|
||||
default:
|
||||
BT_ERR("Invalid Device firmware Get opcode 0x%04x", param.opcode);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_client_call_handler(btc_msg_t *msg)
|
||||
{
|
||||
esp_ble_mesh_dfu_client_cb_param_t cb = {0};
|
||||
btc_ble_mesh_dfu_client_args_t *arg = NULL;
|
||||
|
||||
if (!msg) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
arg = (btc_ble_mesh_dfu_client_args_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE:
|
||||
cb.params = arg->dfu_get.params;
|
||||
cb.send.err_code = btc_ble_mesh_dfu_client_get_state(arg->dfu_get.params,
|
||||
arg->dfu_get.get);
|
||||
btc_ble_mesh_dfu_client_cb(&cb,
|
||||
ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT);
|
||||
break;
|
||||
case BTC_BLE_MESH_ACT_DFU_CLIENT_IMG_SEND:
|
||||
cb.send.err_code = bt_mesh_dfu_cli_send((struct bt_mesh_dfu_cli *)arg->send_arg.cli,
|
||||
(struct bt_mesh_blob_cli_inputs *)arg->send_arg.inputs,
|
||||
(struct bt_mesh_blob_io *)arg->send_arg.io,
|
||||
(struct bt_mesh_dfu_cli_xfer *)arg->send_arg.xfer);
|
||||
btc_ble_mesh_dfu_client_cb(&cb,
|
||||
ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_client_arg_deep_free(msg);
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_client_cb_handler(btc_msg_t *msg)
|
||||
{
|
||||
esp_ble_mesh_dfu_client_cb_param_t *arg = NULL;
|
||||
|
||||
if (!msg) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
arg = (esp_ble_mesh_dfu_client_cb_param_t *)msg->arg;
|
||||
|
||||
if (msg->act < ESP_BLE_MESH_DFU_CLIENT_EVT_MAX) {
|
||||
btc_ble_mesh_dfu_client_cb_to_app(msg->act, arg);
|
||||
} else {
|
||||
BT_ERR("%s, Unknown act %d", __func__, msg->act);
|
||||
}
|
||||
|
||||
btc_ble_mesh_dfu_client_free_req_data(msg);
|
||||
}
|
||||
|
||||
uint8_t btc_ble_mesh_dfu_cli_progress(struct esp_ble_mesh_dfu_cli *cli)
|
||||
{
|
||||
return bt_mesh_dfu_cli_progress((struct bt_mesh_dfu_cli *)cli);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
|
||||
void btc_ble_mesh_dfu_srv_verified(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
bt_mesh_dfu_srv_verified((struct bt_mesh_dfu_srv *)srv);
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
bt_mesh_dfu_srv_rejected((struct bt_mesh_dfu_srv *)srv);
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
bt_mesh_dfu_srv_cancel((struct bt_mesh_dfu_srv *)srv);
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
bt_mesh_dfu_srv_applied((struct bt_mesh_dfu_srv *)srv);
|
||||
}
|
||||
|
||||
bool btc_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
return bt_mesh_dfu_srv_is_busy((struct bt_mesh_dfu_srv *)srv);
|
||||
}
|
||||
|
||||
uint8_t btc_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv)
|
||||
{
|
||||
return bt_mesh_dfu_srv_progress((struct bt_mesh_dfu_srv *)srv);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "dfu_slot.h"
|
||||
#include "esp_ble_mesh_dfu_model_api.h"
|
||||
#include "esp_ble_mesh_dfu_slot_api.h"
|
||||
#include "btc_ble_mesh_dfu_slot.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SLOTS
|
||||
int btc_ble_mesh_dfu_slot_count(void)
|
||||
{
|
||||
return bt_mesh_dfu_slot_count();
|
||||
}
|
||||
|
||||
struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_reserve(void)
|
||||
{
|
||||
return (struct esp_ble_mesh_dfu_slot *)bt_mesh_dfu_slot_reserve();
|
||||
}
|
||||
|
||||
int btc_ble_mesh_dfu_slot_info_set(struct esp_ble_mesh_dfu_slot *dfu_slot, size_t size,
|
||||
const uint8_t *metadata, size_t metadata_len)
|
||||
{
|
||||
return bt_mesh_dfu_slot_info_set((struct bt_mesh_dfu_slot *) dfu_slot, size,
|
||||
metadata, metadata_len);
|
||||
}
|
||||
|
||||
int btc_ble_mesh_dfu_slot_fwid_set(struct esp_ble_mesh_dfu_slot *dfu_slot,
|
||||
const uint8_t *fwid, size_t fwid_len)
|
||||
{
|
||||
return bt_mesh_dfu_slot_fwid_set((struct bt_mesh_dfu_slot *) dfu_slot, fwid,
|
||||
fwid_len);
|
||||
}
|
||||
|
||||
int btc_ble_mesh_dfu_slot_commit(struct esp_ble_mesh_dfu_slot *dfu_slot)
|
||||
{
|
||||
return bt_mesh_dfu_slot_commit((struct bt_mesh_dfu_slot *) dfu_slot);
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_slot_release(const struct esp_ble_mesh_dfu_slot *dfu_slot)
|
||||
{
|
||||
bt_mesh_dfu_slot_release((const struct bt_mesh_dfu_slot *)dfu_slot);
|
||||
}
|
||||
|
||||
int btc_ble_mesh_dfu_slot_del(const struct esp_ble_mesh_dfu_slot *slot)
|
||||
{
|
||||
return bt_mesh_dfu_slot_del((const struct bt_mesh_dfu_slot *)slot);
|
||||
}
|
||||
|
||||
void btc_ble_mesh_dfu_slot_del_all(void)
|
||||
{
|
||||
bt_mesh_dfu_slot_del_all();
|
||||
}
|
||||
|
||||
const struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_at(uint16_t img_idx)
|
||||
{
|
||||
return (const struct esp_ble_mesh_dfu_slot *)bt_mesh_dfu_slot_at(img_idx);
|
||||
}
|
||||
|
||||
int btc_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct esp_ble_mesh_dfu_slot **slot)
|
||||
{
|
||||
return bt_mesh_dfu_slot_get(fwid, fwid_len, (struct bt_mesh_dfu_slot **)slot);
|
||||
}
|
||||
|
||||
int btc_ble_mesh_dfu_slot_img_idx_get(const struct esp_ble_mesh_dfu_slot *slot)
|
||||
{
|
||||
return bt_mesh_dfu_slot_img_idx_get((const struct bt_mesh_dfu_slot *)slot);
|
||||
}
|
||||
|
||||
size_t btc_ble_mesh_dfu_slot_foreach(esp_ble_mesh_dfu_slot_cb_t cb, void *user_data)
|
||||
{
|
||||
return bt_mesh_dfu_slot_foreach((bt_mesh_dfu_slot_cb_t)cb, user_data);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BTC_BLE_MESH_DFU_MODEL_H_
|
||||
#define _BTC_BLE_MESH_DFU_MODEL_H_
|
||||
|
||||
#include "btc/btc_manage.h"
|
||||
#include "esp_ble_mesh_dfu_model_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_CLI
|
||||
typedef enum {
|
||||
BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE,
|
||||
BTC_BLE_MESH_ACT_DFU_CLIENT_IMG_SEND,
|
||||
BTC_BLE_MESH_ACT_DFU_CLIENT_MAX,
|
||||
} btc_ble_mesh_dfu_client_act_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
esp_ble_mesh_client_common_param_t *params;
|
||||
esp_ble_mesh_dfu_client_get_t *get;
|
||||
} dfu_get;
|
||||
struct {
|
||||
struct esp_ble_mesh_dfu_cli *cli;
|
||||
struct esp_ble_mesh_blob_cli_inputs *inputs;
|
||||
struct esp_ble_mesh_blob_io *io;
|
||||
struct esp_ble_mesh_dfu_cli_xfer *xfer;
|
||||
} send_arg;
|
||||
} btc_ble_mesh_dfu_client_args_t;
|
||||
|
||||
typedef enum {
|
||||
BTC_BLE_MESH_EVT_DFU_CLIENT_TIMEOUT,
|
||||
BTC_BLE_MESH_EVT_DFU_CLIENT_RECV_GET_RSP,
|
||||
BTC_BLE_MESH_EVT_DFU_CLIENT_IMG_SEND_CMP,
|
||||
BTC_BLE_MESH_EVT_DFU_CLIENT_MAX,
|
||||
} btc_ble_mesh_dfu_client_cb_evt_t;
|
||||
|
||||
void btc_ble_mesh_dfu_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
void btc_ble_mesh_dfu_client_arg_deep_free(btc_msg_t *msg);
|
||||
void bt_mesh_dfu_client_cb_evt_to_btc(uint32_t opcode, uint8_t event,
|
||||
struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx,
|
||||
const uint8_t *val, size_t len);
|
||||
void btc_ble_mesh_dfu_client_call_handler(btc_msg_t *msg);
|
||||
void btc_ble_mesh_dfu_client_cb_handler(btc_msg_t *msg);
|
||||
uint8_t btc_ble_mesh_dfu_cli_progress(struct esp_ble_mesh_dfu_cli *cli);
|
||||
#endif /* CONFIG_BLE_MESH_DFU_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SRV
|
||||
|
||||
void btc_ble_mesh_dfu_srv_verified(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
void btc_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
void btc_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
void btc_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
bool btc_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv);
|
||||
|
||||
uint8_t btc_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv);
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BTC_BLE_MESH_DFU_MODEL_H_ */
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BTC_BLE_MESH_DFU_SLOT_H_
|
||||
#define _BTC_BLE_MESH_DFU_SLOT_H_
|
||||
|
||||
int btc_ble_mesh_dfu_slot_count(void);
|
||||
|
||||
struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_reserve(void);
|
||||
|
||||
int btc_ble_mesh_dfu_slot_info_set(struct esp_ble_mesh_dfu_slot *dfu_slot, size_t size,
|
||||
const uint8_t *metadata, size_t metadata_len);
|
||||
|
||||
int btc_ble_mesh_dfu_slot_fwid_set(struct esp_ble_mesh_dfu_slot *dfu_slot,
|
||||
const uint8_t *fwid, size_t fwid_len);
|
||||
|
||||
int btc_ble_mesh_dfu_slot_commit(struct esp_ble_mesh_dfu_slot *dfu_slot);
|
||||
|
||||
void btc_ble_mesh_dfu_slot_release(const struct esp_ble_mesh_dfu_slot *dfu_slot);
|
||||
|
||||
int btc_ble_mesh_dfu_slot_del(const struct esp_ble_mesh_dfu_slot *slot);
|
||||
|
||||
void btc_ble_mesh_dfu_slot_del_all(void);
|
||||
|
||||
const struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_at(uint16_t img_idx);
|
||||
|
||||
int btc_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct esp_ble_mesh_dfu_slot **slot);
|
||||
|
||||
int btc_ble_mesh_dfu_slot_img_idx_get(const struct esp_ble_mesh_dfu_slot *slot);
|
||||
|
||||
size_t btc_ble_mesh_dfu_slot_foreach(esp_ble_mesh_dfu_slot_cb_t cb, void *user_data);
|
||||
|
||||
#endif /* _BTC_BLE_MESH_DFU_SLOT_H_ */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -14,6 +14,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_CI_BUILD
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BTC_BLE_MESH_ACT_MBT_CLIENT_RETRIEVE_CAPABILITIES,
|
||||
BTC_BLE_MESH_ACT_MBT_CLIENT_TRANSFER_BLOB,
|
||||
@@ -136,6 +141,10 @@ void bt_mesh_mbt_server_cb_evt_to_btc(uint8_t event,
|
||||
struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx);
|
||||
|
||||
#if CONFIG_IDF_CI_BUILD
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "access.h"
|
||||
|
||||
/* @todo: adapt to dfd client */
|
||||
#if CONFIG_BLE_MESH_DFD_SRV
|
||||
#define BT_MESH_DFD_OP_RECEIVERS_ADD BLE_MESH_MODEL_OP_2(0x83, 0x11)
|
||||
#define BT_MESH_DFD_OP_RECEIVERS_DELETE_ALL BLE_MESH_MODEL_OP_2(0x83, 0x12)
|
||||
#define BT_MESH_DFD_OP_RECEIVERS_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x13)
|
||||
#define BT_MESH_DFD_OP_RECEIVERS_GET BLE_MESH_MODEL_OP_2(0x83, 0x14)
|
||||
#define BT_MESH_DFD_OP_RECEIVERS_LIST BLE_MESH_MODEL_OP_2(0x83, 0x15)
|
||||
#define BT_MESH_DFD_OP_CAPABILITIES_GET BLE_MESH_MODEL_OP_2(0x83, 0x16)
|
||||
#define BT_MESH_DFD_OP_CAPABILITIES_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x17)
|
||||
#define BT_MESH_DFD_OP_GET BLE_MESH_MODEL_OP_2(0x83, 0x18)
|
||||
#define BT_MESH_DFD_OP_START BLE_MESH_MODEL_OP_2(0x83, 0x19)
|
||||
#define BT_MESH_DFD_OP_SUSPEND BLE_MESH_MODEL_OP_2(0x83, 0x1a)
|
||||
#define BT_MESH_DFD_OP_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x1b)
|
||||
#define BT_MESH_DFD_OP_APPLY BLE_MESH_MODEL_OP_2(0x83, 0x1c)
|
||||
#define BT_MESH_DFD_OP_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x1d)
|
||||
#define BT_MESH_DFD_OP_UPLOAD_GET BLE_MESH_MODEL_OP_2(0x83, 0x1e)
|
||||
#define BT_MESH_DFD_OP_UPLOAD_START BLE_MESH_MODEL_OP_2(0x83, 0x1f)
|
||||
#define BT_MESH_DFD_OP_UPLOAD_START_OOB BLE_MESH_MODEL_OP_2(0x83, 0x20)
|
||||
#define BT_MESH_DFD_OP_UPLOAD_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x21)
|
||||
#define BT_MESH_DFD_OP_UPLOAD_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x22)
|
||||
#define BT_MESH_DFD_OP_FW_GET BLE_MESH_MODEL_OP_2(0x83, 0x23)
|
||||
#define BT_MESH_DFD_OP_FW_GET_BY_INDEX BLE_MESH_MODEL_OP_2(0x83, 0x24)
|
||||
#define BT_MESH_DFD_OP_FW_DELETE BLE_MESH_MODEL_OP_2(0x83, 0x25)
|
||||
#define BT_MESH_DFD_OP_FW_DELETE_ALL BLE_MESH_MODEL_OP_2(0x83, 0x26)
|
||||
#define BT_MESH_DFD_OP_FW_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x27)
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BLE_MESH_v11_DFD_SRV_INTERNAL_H__
|
||||
#define _BLE_MESH_v11_DFD_SRV_INTERNAL_H__
|
||||
|
||||
#include "mesh_v1.1/dfu/dfd_srv.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFD_SRV
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct bt_mesh_dfd_start_params {
|
||||
uint16_t app_idx, timeout_base, slot_idx, group;
|
||||
enum bt_mesh_blob_xfer_mode xfer_mode;
|
||||
uint8_t ttl;
|
||||
bool apply;
|
||||
};
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_receiver_add(struct bt_mesh_dfd_srv *srv, uint16_t addr,
|
||||
uint8_t img_idx);
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_receivers_delete_all(struct bt_mesh_dfd_srv *srv);
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv,
|
||||
struct bt_mesh_dfd_start_params *params);
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_suspend(struct bt_mesh_dfd_srv *srv);
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_cancel(struct bt_mesh_dfd_srv *srv,
|
||||
struct bt_mesh_msg_ctx *ctx);
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_apply(struct bt_mesh_dfd_srv *srv);
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, size_t *fwid_len,
|
||||
const uint8_t **fwid);
|
||||
|
||||
enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete_all(struct bt_mesh_dfd_srv *srv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* _BLE_MESH_v11_DFD_SRV_INTERNAL_H__ */
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "mesh/buf.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SRV || CONFIG_BLE_MESH_DFU_CLI
|
||||
#define BLE_MESH_DFU_OP_UPDATE_INFO_GET BLE_MESH_MODEL_OP_2(0x83, 0x08)
|
||||
#define BLE_MESH_DFU_OP_UPDATE_INFO_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x09)
|
||||
|
||||
#define BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK BLE_MESH_MODEL_OP_2(0x83, 0x0a)
|
||||
#define BLE_MESH_DFU_OP_UPDATE_METADATA_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x0b)
|
||||
|
||||
#define BLE_MESH_DFU_OP_UPDATE_GET BLE_MESH_MODEL_OP_2(0x83, 0x0c)
|
||||
#define BLE_MESH_DFU_OP_UPDATE_START BLE_MESH_MODEL_OP_2(0x83, 0x0d)
|
||||
#define BLE_MESH_DFU_OP_UPDATE_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x0e)
|
||||
#define BLE_MESH_DFU_OP_UPDATE_APPLY BLE_MESH_MODEL_OP_2(0x83, 0x0f)
|
||||
#define BLE_MESH_DFU_OP_UPDATE_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x10)
|
||||
|
||||
#define DFU_UPDATE_INFO_STATUS_MSG_MINLEN (4 + CONFIG_BLE_MESH_DFU_FWID_MAXLEN + \
|
||||
CONFIG_BLE_MESH_DFU_URI_MAXLEN)
|
||||
#define DFU_UPDATE_START_MSG_MAXLEN (12 + CONFIG_BLE_MESH_DFU_METADATA_MAXLEN)
|
||||
|
||||
static inline uint16_t dfu_metadata_checksum(struct net_buf_simple *buf)
|
||||
{
|
||||
/* Simple Fletcher-16 checksum to ensure duplicate start messages don't
|
||||
* have different metadata.
|
||||
*/
|
||||
struct net_buf_simple_state state;
|
||||
uint8_t sum[2] = {0, 0};
|
||||
|
||||
net_buf_simple_save(buf, &state);
|
||||
|
||||
while (buf->len) {
|
||||
uint8_t byte = net_buf_simple_pull_u8(buf);
|
||||
|
||||
sum[0] += byte;
|
||||
sum[1] += sum[0];
|
||||
}
|
||||
|
||||
net_buf_simple_restore(buf, &state);
|
||||
|
||||
return (sum[0] << 8U) | sum[1];
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SRV || CONFIG_BLE_MESH_DFU_CLI */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "crypto.h"
|
||||
#include "access.h"
|
||||
#include "mesh/byteorder.h"
|
||||
#include "mesh/buf.h"
|
||||
#include "mesh_v1.1/dfu/dfu_metadata.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_METADATA
|
||||
int bt_mesh_dfu_metadata_decode(struct net_buf_simple *buf,
|
||||
struct bt_mesh_dfu_metadata *metadata)
|
||||
{
|
||||
if (buf->len < 12) {
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
metadata->fw_ver.major = net_buf_simple_pull_u8(buf);
|
||||
metadata->fw_ver.minor = net_buf_simple_pull_u8(buf);
|
||||
metadata->fw_ver.revision = net_buf_simple_pull_le16(buf);
|
||||
metadata->fw_ver.build_num = net_buf_simple_pull_le32(buf);
|
||||
metadata->fw_size = net_buf_simple_pull_le24(buf);
|
||||
metadata->fw_core_type = net_buf_simple_pull_u8(buf);
|
||||
|
||||
if (metadata->fw_core_type & BLE_MESH_DFU_FW_CORE_TYPE_APP) {
|
||||
if (buf->len < 6) {
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
metadata->comp_hash = net_buf_simple_pull_le32(buf);
|
||||
metadata->elems = net_buf_simple_pull_le16(buf);
|
||||
}
|
||||
|
||||
metadata->user_data = buf->len > 0 ? buf->data : NULL;
|
||||
metadata->user_data_len = buf->len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_metadata_encode(const struct bt_mesh_dfu_metadata *metadata,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
size_t md_len_min = 12 + metadata->user_data_len;
|
||||
|
||||
if (metadata->fw_core_type & BLE_MESH_DFU_FW_CORE_TYPE_APP) {
|
||||
md_len_min += 6;
|
||||
}
|
||||
|
||||
if (net_buf_simple_tailroom(buf) < md_len_min) {
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
net_buf_simple_add_u8(buf, metadata->fw_ver.major);
|
||||
net_buf_simple_add_u8(buf, metadata->fw_ver.minor);
|
||||
net_buf_simple_add_le16(buf, metadata->fw_ver.revision);
|
||||
net_buf_simple_add_le32(buf, metadata->fw_ver.build_num);
|
||||
net_buf_simple_add_le24(buf, metadata->fw_size);
|
||||
net_buf_simple_add_u8(buf, metadata->fw_core_type);
|
||||
net_buf_simple_add_le32(buf, metadata->comp_hash);
|
||||
net_buf_simple_add_le16(buf, metadata->elems);
|
||||
|
||||
if (metadata->user_data_len > 0) {
|
||||
net_buf_simple_add_mem(buf, metadata->user_data, metadata->user_data_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_metadata_comp_hash_get(struct net_buf_simple *buf, uint8_t *key, uint32_t *hash)
|
||||
{
|
||||
uint8_t mac[16];
|
||||
int err;
|
||||
struct bt_mesh_sg sg = {.data = buf->data, .len = buf->len};
|
||||
|
||||
/* The implementation of this function is the same as function `bt_mesh_aes_cmac_raw_key` in Zephyr. */
|
||||
err = bt_mesh_aes_cmac(key, &sg, 1, mac);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*hash = sys_get_le32(mac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_metadata_comp_hash_local_get(uint8_t *key, uint32_t *hash)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(buf, BLE_MESH_TX_SDU_MAX);
|
||||
int err;
|
||||
|
||||
err = bt_mesh_get_comp_data(&buf, 0, 0, true);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = bt_mesh_dfu_metadata_comp_hash_get(&buf, key, hash);
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DFU_METADATA */
|
||||
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "dfu_slot.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mesh/common.h"
|
||||
#include "mesh/utils.h"
|
||||
#include "settings_nvs.h"
|
||||
#include "settings.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_DFU_SLOTS
|
||||
#define SLOT_ENTRY_BUFLEN 25
|
||||
|
||||
#define DFU_SLOT_SETTINGS_PATH "mesh/dfu/s"
|
||||
|
||||
#define HEADER_SIZE offsetof(struct slot, slot.fwid)
|
||||
|
||||
#define PROP_HEADER "h"
|
||||
#define PROP_FWID "id"
|
||||
#define PROP_METADATA "m"
|
||||
#define SETTINGS_NAME_END '='
|
||||
#define SETTINGS_NAME_SEPARATOR '/'
|
||||
|
||||
static sys_slist_t list;
|
||||
|
||||
static struct slot {
|
||||
uint32_t idx;
|
||||
struct bt_mesh_dfu_slot slot;
|
||||
sys_snode_t n;
|
||||
} slots[CONFIG_BLE_MESH_DFU_SLOT_CNT];
|
||||
|
||||
static uint32_t slot_index;
|
||||
|
||||
inline int settings_name_next(const char *name, const char **next)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (next) {
|
||||
*next = NULL;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* name might come from flash directly, in flash the name would end
|
||||
* with '=' or '\0' depending how storage is done. Flash reading is
|
||||
* limited to what can be read
|
||||
*/
|
||||
while ((*name != '\0') && (*name != SETTINGS_NAME_END) &&
|
||||
(*name != SETTINGS_NAME_SEPARATOR)) {
|
||||
rc++;
|
||||
name++;
|
||||
}
|
||||
|
||||
if (*name == SETTINGS_NAME_SEPARATOR) {
|
||||
if (next) {
|
||||
*next = name + 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_SETTINGS
|
||||
static char *slot_entry_encode(uint16_t idx, char buf[SLOT_ENTRY_BUFLEN],
|
||||
const char *property)
|
||||
{
|
||||
snprintf(buf, SLOT_ENTRY_BUFLEN, DFU_SLOT_SETTINGS_PATH "/%x/%s", idx,
|
||||
property);
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool slot_eq(const struct bt_mesh_dfu_slot *slot,
|
||||
const uint8_t *fwid, size_t fwid_len)
|
||||
{
|
||||
return (slot->fwid_len == fwid_len) &&
|
||||
!memcmp(fwid, slot->fwid, fwid_len);
|
||||
}
|
||||
|
||||
static bool is_slot_committed(struct slot *slot_to_check)
|
||||
{
|
||||
struct slot *s;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
if (s == slot_to_check) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int slot_store(const struct slot *slot_to_store)
|
||||
{
|
||||
int err = 0;
|
||||
#if CONFIG_BLE_MESH_SETTINGS
|
||||
uint16_t idx = ARRAY_INDEX(slots, slot_to_store);
|
||||
char buf[SLOT_ENTRY_BUFLEN];
|
||||
|
||||
err = bt_mesh_save_core_settings(slot_entry_encode(idx, buf, PROP_HEADER),
|
||||
(uint8_t *)slot_to_store, HEADER_SIZE);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = bt_mesh_save_core_settings(slot_entry_encode(idx, buf, PROP_FWID),
|
||||
slot_to_store->slot.fwid, slot_to_store->slot.fwid_len);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = bt_mesh_save_core_settings(slot_entry_encode(idx, buf, PROP_METADATA),
|
||||
slot_to_store->slot.metadata, slot_to_store->slot.metadata_len);
|
||||
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static void slot_erase(struct slot *slot_to_erase)
|
||||
{
|
||||
#if CONFIG_BLE_MESH_SETTINGS
|
||||
uint16_t idx = ARRAY_INDEX(slots, slot_to_erase);
|
||||
char buf[SLOT_ENTRY_BUFLEN];
|
||||
|
||||
bt_mesh_erase_core_settings(slot_entry_encode(idx, buf, PROP_HEADER));
|
||||
bt_mesh_erase_core_settings(slot_entry_encode(idx, buf, PROP_FWID));
|
||||
bt_mesh_erase_core_settings(slot_entry_encode(idx, buf, PROP_METADATA));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void slot_index_defrag(void)
|
||||
{
|
||||
slot_index = 0;
|
||||
struct slot *s;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
s->idx = ++slot_index;
|
||||
slot_store(s);
|
||||
}
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_slot_count(void)
|
||||
{
|
||||
int cnt = 0;
|
||||
sys_snode_t *n;
|
||||
|
||||
SYS_SLIST_FOR_EACH_NODE(&list, n) {
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void)
|
||||
{
|
||||
struct slot *slot = NULL;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(slots); ++i) {
|
||||
if (slots[i].idx == 0) {
|
||||
slot = &slots[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!slot) {
|
||||
BT_WARN("No space");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (slot_index == UINT32_MAX) {
|
||||
slot_index_defrag();
|
||||
}
|
||||
|
||||
slot->slot.fwid_len = 0;
|
||||
slot->slot.metadata_len = 0;
|
||||
slot->slot.size = 0;
|
||||
slot->idx = ++slot_index;
|
||||
|
||||
BT_DBG("Reserved slot #%u", slot - &slots[0]);
|
||||
|
||||
return &slot->slot;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size,
|
||||
const uint8_t *metadata, size_t metadata_len)
|
||||
{
|
||||
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
|
||||
|
||||
if (metadata_len > CONFIG_BLE_MESH_DFU_METADATA_MAXLEN) {
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
if (slot->idx == 0 || is_slot_committed(slot)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
slot->slot.size = size;
|
||||
slot->slot.metadata_len = metadata_len;
|
||||
memcpy(slot->slot.metadata, metadata, metadata_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot,
|
||||
const uint8_t *fwid, size_t fwid_len)
|
||||
{
|
||||
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
|
||||
|
||||
if (fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN) {
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
if (slot->idx == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_slot_committed(slot)) {
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(slots); i++) {
|
||||
if (slots[i].idx != 0 &&
|
||||
slot_eq(&slots[i].slot, fwid, fwid_len)) {
|
||||
return -EALREADY;
|
||||
}
|
||||
}
|
||||
|
||||
slot->slot.fwid_len = fwid_len;
|
||||
memcpy(slot->slot.fwid, fwid, fwid_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_slot_commit(struct bt_mesh_dfu_slot *dfu_slot)
|
||||
{
|
||||
int err;
|
||||
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
|
||||
|
||||
if (slot->idx == 0 ||
|
||||
slot->slot.fwid_len == 0 ||
|
||||
slot->slot.size == 0 ||
|
||||
is_slot_committed(slot)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = slot_store(slot);
|
||||
if (err) {
|
||||
BT_WARN("Store failed (err: %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
sys_slist_append(&list, &slot->n);
|
||||
|
||||
BT_DBG("Stored slot #%u: %s", ARRAY_INDEX(slots, slot),
|
||||
bt_hex(slot->slot.fwid, slot->slot.fwid_len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bt_mesh_dfu_slot_release(const struct bt_mesh_dfu_slot *dfu_slot)
|
||||
{
|
||||
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
|
||||
|
||||
if (is_slot_committed(slot)) {
|
||||
return;
|
||||
}
|
||||
|
||||
slot->idx = 0;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *dfu_slot)
|
||||
{
|
||||
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
|
||||
|
||||
if (!sys_slist_find_and_remove(&list, &slot->n)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int idx = ARRAY_INDEX(slots, slot);
|
||||
|
||||
BT_DBG("%u", idx);
|
||||
|
||||
slot_erase(slot);
|
||||
slot->idx = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bt_mesh_dfu_slot_del_all(void)
|
||||
{
|
||||
struct slot *s;
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
slot_erase(s);
|
||||
s->idx = 0;
|
||||
}
|
||||
|
||||
sys_slist_init(&list);
|
||||
}
|
||||
|
||||
const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx)
|
||||
{
|
||||
struct slot *s;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
if (!img_idx--) {
|
||||
return &s->slot;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct bt_mesh_dfu_slot **slot)
|
||||
{
|
||||
struct slot *s;
|
||||
int idx = 0;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
if (slot_eq(&s->slot, fwid, fwid_len)) {
|
||||
if (slot) {
|
||||
*slot = &s->slot;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *dfu_slot)
|
||||
{
|
||||
struct slot *s;
|
||||
int idx = 0;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
if (&s->slot == dfu_slot) {
|
||||
return idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
size_t bt_mesh_dfu_slot_foreach(bt_mesh_dfu_slot_cb_t cb, void *user_data)
|
||||
{
|
||||
enum bt_mesh_dfu_iter iter;
|
||||
size_t cnt = 0;
|
||||
struct slot *s;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
cnt++;
|
||||
|
||||
if (!cb) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iter = cb(&s->slot, user_data);
|
||||
if (iter != BLE_MESH_DFU_ITER_CONTINUE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int slot_data_load(const char *key, size_t len_rd,
|
||||
settings_read_cb read_cb, void *cb_arg)
|
||||
{
|
||||
const char *prop;
|
||||
size_t len;
|
||||
uint16_t idx;
|
||||
|
||||
idx = strtol(key, NULL, 16);
|
||||
|
||||
if (idx >= ARRAY_SIZE(slots)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = settings_name_next(key, &prop);
|
||||
|
||||
if (!strncmp(prop, PROP_HEADER, len)) {
|
||||
if (read_cb(cb_arg, &slots[idx], HEADER_SIZE) > 0) {
|
||||
struct slot *s, *prev = NULL;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
|
||||
if (s->idx > slots[idx].idx) {
|
||||
break;
|
||||
}
|
||||
|
||||
prev = s;
|
||||
}
|
||||
|
||||
if (prev == NULL) {
|
||||
sys_slist_prepend(&list, &slots[idx].n);
|
||||
} else {
|
||||
sys_slist_insert(&list, &prev->n, &slots[idx].n);
|
||||
}
|
||||
|
||||
if (slots[idx].idx >= slot_index) {
|
||||
slot_index = slots[idx].idx + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strncmp(prop, PROP_FWID, len)) {
|
||||
if (read_cb(cb_arg, &slots[idx].slot.fwid,
|
||||
sizeof(slots[idx].slot.fwid)) < 0) {
|
||||
slots[idx].idx = 0;
|
||||
sys_slist_find_and_remove(&list, &slots[idx].n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
slots[idx].slot.fwid_len = len_rd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strncmp(prop, PROP_METADATA, len)) {
|
||||
if (read_cb(cb_arg, &slots[idx].slot.metadata,
|
||||
sizeof(slots[idx].slot.metadata)) < 0) {
|
||||
slots[idx].idx = 0;
|
||||
sys_slist_find_and_remove(&list, &slots[idx].n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
slots[idx].slot.metadata_len = len_rd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "mesh_v1.1/dfu/dfu.h"
|
||||
#if CONFIG_BLE_MESH_DFU_SLOTS
|
||||
/** @brief Slot iteration callback.
|
||||
*
|
||||
* @param slot A valid DFU image slot.
|
||||
* @param user_data User data passed to @ref bt_mesh_dfu_slot_foreach.
|
||||
*
|
||||
* @return Iteration action determining next step.
|
||||
*/
|
||||
typedef enum bt_mesh_dfu_iter(*bt_mesh_dfu_slot_cb_t)
|
||||
(const struct bt_mesh_dfu_slot *slot, void *user_data);
|
||||
|
||||
/** @brief Get the number of slots committed to the firmware list.
|
||||
*
|
||||
* @return Number of committed slots.
|
||||
*/
|
||||
int bt_mesh_dfu_slot_count(void);
|
||||
|
||||
/** @brief Reserve a new DFU image slot for a distributable image.
|
||||
*
|
||||
* A DFU image slot represents a single distributable DFU image with all its
|
||||
* metadata. The slot data must be set using @ref bt_mesh_dfu_slot_info_set and
|
||||
* @ref bt_mesh_dfu_slot_fwid_set, and the slot committed using
|
||||
* @ref bt_mesh_dfu_slot_commit for the slot to be considered part of the slot
|
||||
* list.
|
||||
*
|
||||
* @return A pointer to the reserved slot, or NULL if allocation failed.
|
||||
*/
|
||||
struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void);
|
||||
|
||||
/** @brief Set the size and metadata for a reserved slot.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot for which to set the
|
||||
* metadata.
|
||||
* @param size The size of the image.
|
||||
* @param metadata Metadata or NULL.
|
||||
* @param metadata_len Length of the metadata, at most @c
|
||||
* CONFIG_BLE_MESH_DFU_METADATA_MAXLEN.
|
||||
*
|
||||
* @return 0 on success, (negative) error code otherwise.
|
||||
*/
|
||||
int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size,
|
||||
const uint8_t *metadata, size_t metadata_len);
|
||||
|
||||
/** @brief Set the new fwid for the incoming image for a reserved slot.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot for which to set the fwid.
|
||||
* @param fwid Fwid to set.
|
||||
* @param fwid_len Length of the fwid, at most @c
|
||||
* CONFIG_BLE_MESH_DFU_FWID_MAXLEN.
|
||||
*
|
||||
* @return 0 on success, (negative) error code otherwise.
|
||||
*/
|
||||
int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot,
|
||||
const uint8_t *fwid, size_t fwid_len);
|
||||
|
||||
/** @brief Commit the reserved slot to the list of slots, and store it
|
||||
* persistently.
|
||||
*
|
||||
* If the commit fails for any reason, the slot will still be in the reserved
|
||||
* state after this call.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot.
|
||||
*
|
||||
* @return 0 on success, (negative) error code otherwise.
|
||||
*/
|
||||
int bt_mesh_dfu_slot_commit(struct bt_mesh_dfu_slot *dfu_slot);
|
||||
|
||||
/** @brief Release a reserved slot so that it can be reserved again.
|
||||
*
|
||||
* @param dfu_slot Pointer to the reserved slot.
|
||||
*/
|
||||
void bt_mesh_dfu_slot_release(const struct bt_mesh_dfu_slot *dfu_slot);
|
||||
|
||||
/** @brief Delete a committed DFU image slot.
|
||||
*
|
||||
* @param slot Slot to delete. Must be a valid pointer acquired from this
|
||||
* module.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code on failure.
|
||||
*/
|
||||
int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *slot);
|
||||
|
||||
/** @brief Delete all DFU image slots.
|
||||
*
|
||||
* @return 0 on success, or (negative) error code on failure.
|
||||
*/
|
||||
void bt_mesh_dfu_slot_del_all(void);
|
||||
|
||||
/** @brief Get the DFU image slot at the given firmware image list index.
|
||||
*
|
||||
* @param idx DFU image slot index.
|
||||
*
|
||||
* @return The DFU image slot at the given index, or NULL if no slot exists with the
|
||||
* given index.
|
||||
*/
|
||||
const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx);
|
||||
|
||||
/** @brief Get the committed DFU image slot for the image with the given
|
||||
* firmware ID.
|
||||
*
|
||||
* @param fwid Firmware ID.
|
||||
* @param fwid_len Firmware ID length.
|
||||
* @param slot Slot pointer to fill.
|
||||
*
|
||||
* @return Slot index on success, or negative error code on failure.
|
||||
*/
|
||||
int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct bt_mesh_dfu_slot **slot);
|
||||
|
||||
/** @brief Get the index in the firmware image list for the given slot.
|
||||
*
|
||||
* @param slot Slot to find.
|
||||
*
|
||||
* @return Slot index on success, or negative error code on failure.
|
||||
*/
|
||||
int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *slot);
|
||||
|
||||
/** @brief Iterate through all DFU image slots.
|
||||
*
|
||||
* Calls the callback for every DFU image slot or until the callback returns
|
||||
* something other than @ref BLE_MESH_DFU_ITER_CONTINUE.
|
||||
*
|
||||
* @param cb Callback to call for each slot, or NULL to just count the
|
||||
* number of slots.
|
||||
* @param user_data User data to pass to the callback.
|
||||
*
|
||||
* @return The number of slots iterated over.
|
||||
*/
|
||||
size_t bt_mesh_dfu_slot_foreach(bt_mesh_dfu_slot_cb_t cb, void *user_data);
|
||||
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user