first commit

This commit is contained in:
2026-05-22 22:05:03 +03:00
commit 43393d2692
33463 changed files with 9249702 additions and 0 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+479
View File
@@ -0,0 +1,479 @@
dependencies:
chmorgan/esp-libhelix-mp3:
component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53
dependencies:
- name: idf
require: private
version: '>=4.1.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.0.3
espressif/cbor:
component_hash: dad9ca860963e930366510a10b422b3125a4fb27b979712ed65efcbcd742de50
dependencies:
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 0.6.1~4
espressif/esp-dsp:
component_hash: 42dce32d46ac93dc11f60d368e29a830e9661c7345d794b8a45c343479cae636
dependencies:
- name: idf
require: private
version: '>=4.2'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.7.0
espressif/esp-modbus:
component_hash: 5d5e90b9e55721a8a194b301ad8102d4affb647f47b74cd413ff7d1ce2c1169c
dependencies:
- name: idf
require: private
version: '>=4.3'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.0.18
espressif/esp-nn:
component_hash: f4633a02f05fef53b80de65ade1f733ebdef637e4c8b8be4eb11f5e27f6d9f3e
dependencies:
- name: idf
require: private
version: '>=4.2'
source:
registry_url: https://components.espressif.com
type: service
version: 1.1.2
espressif/esp-serial-flasher:
component_hash: dcc42a16712a1a636509cf0bf90e14032d7f2141784b533613b267b6aa318d52
dependencies: []
source:
registry_url: https://components.espressif.com
type: service
version: 0.0.11
espressif/esp-tflite-micro:
component_hash: 57aa3889d3c7b7a513f716c2cb8707476a5bf42971d63a6f6d38a5616d862e57
dependencies:
- name: espressif/esp-nn
registry_url: https://components.espressif.com
require: private
version: '>=1.1.1'
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.3.5
espressif/esp-zboss-lib:
component_hash: 321883d142421f65009972408287441794250057668a11abbdfd8bec77c3309a
dependencies:
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.6.4
espressif/esp-zigbee-lib:
component_hash: fa0812e6743e2a7d999af9f44ccdcea17ccb1e80f98d6b2956f44687503a88fd
dependencies:
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.6.8
espressif/esp32-camera:
component_hash: b0136a78a7d049446f9f2752eceab787d6f68f532ab3bbe1b0fca411b80a6bb4
dependencies:
- name: idf
version: '>=5.1'
- name: espressif/esp_jpeg
public: true
version: ^1.3.1
source:
git: https://github.com/espressif/esp32-camera.git
path: .
type: git
version: fb7b85b2b79fb039551c67d295e884d2b1eb907b
espressif/esp_delta_ota:
component_hash: 147161b602ef51e9f6649eb6d90c4d4ac3c94228cb264fa0e68be7877180462d
dependencies:
- name: idf
require: private
version: '>=4.3'
source:
registry_url: https://components.espressif.com
type: service
version: 1.1.4
espressif/esp_diag_data_store:
component_hash: c1e5cf62f545d2b136db299f4df1b228b9840be5bc3410c9ad2d2a882b5c0d64
dependencies:
- name: idf
require: private
version: '>=4.1'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.0.2
espressif/esp_diagnostics:
component_hash: 5ea8e8da8217ed9ed778db3973139e726e17cd27ef5cf6429c787d19226c79f3
dependencies:
- name: idf
require: private
version: '>=4.1'
- name: espressif/rmaker_common
registry_url: https://components.espressif.com
require: private
version: ~1.4.0
source:
registry_url: https://components.espressif.com/
type: service
version: 1.2.1
espressif/esp_encrypted_img:
component_hash: 1c34d5b0e70a3878e63fe2bedb00824bcf83c30d9b020029c38400d0d14fe182
dependencies:
- name: idf
require: private
version: '>=4.4'
source:
registry_url: https://components.espressif.com
type: service
version: 2.1.0
espressif/esp_insights:
component_hash: 4015c524b9955528f941268cf080174076b195800de910d061efc46113bc2e0c
dependencies:
- name: idf
require: private
version: '>=4.1'
- name: espressif/cbor
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=5.0
version: ~0.6
- name: espressif/esp_diag_data_store
registry_url: https://components.espressif.com
require: private
version: 1.0.2
- name: espressif/esp_diagnostics
registry_url: https://components.espressif.com
require: private
version: 1.2.1
- name: espressif/rmaker_common
registry_url: https://components.espressif.com
require: private
version: ~1.4.0
source:
registry_url: https://components.espressif.com/
type: service
version: 1.2.2
espressif/esp_jpeg:
component_hash: defb83669293cbf86d0fa86b475ba5517aceed04ed70db435388c151ab37b5d7
dependencies:
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.3.1
espressif/esp_matter:
component_hash: cf6d98263aeb9852ce2af50c6fa64bd5c39bbbd13119132b0c8d768cba1f53ef
dependencies:
- name: espressif/esp_delta_ota
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=4.3
version: ^1.1.0
- name: espressif/esp_encrypted_img
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=4.4
version: 2.1.0
- name: espressif/esp_insights
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=5.0
- if: target != esp32h2
version: 1.2.2
- name: espressif/esp_rcp_update
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=5.0
version: 1.2.0
- name: espressif/esp_secure_cert_mgr
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=4.3
version: ^2.5.0
- name: espressif/esp_wifi_remote
registry_url: https://components.espressif.com
require: private
rules:
- if: target in [esp32p4]
version: '>=0.1.12'
- name: espressif/json_generator
registry_url: https://components.espressif.com
require: private
version: ~1.1.0
- name: espressif/json_parser
registry_url: https://components.espressif.com
require: private
version: ~1.0.0
- name: espressif/mdns
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=5.0
- if: target != esp32h2
version: ^1.1.0
source:
registry_url: https://components.espressif.com/
type: service
version: 1.4.1
espressif/esp_modem:
component_hash: 07b6ca85dc0c1edbcd76f650005c74067001db138db6bfa106bf05567adca4af
dependencies:
- name: idf
require: private
version: '>=4.1'
source:
registry_url: https://components.espressif.com/
type: service
version: 2.0.0
espressif/esp_rainmaker:
component_hash: f6fe458fc7a0102ee2879f0247da4b41419e6c07de12031f66e5e9454d25baaa
dependencies:
- name: espressif/esp_rcp_update
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >= 5.1
version: ~1.2.0
- name: espressif/esp_schedule
registry_url: https://components.espressif.com
require: private
version: ~1.2.0
- name: espressif/esp_secure_cert_mgr
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=4.3
version: ^2.2.1
- name: espressif/json_generator
registry_url: https://components.espressif.com
require: private
version: ~1.1.1
- name: espressif/json_parser
registry_url: https://components.espressif.com
require: private
version: ~1.0.3
- name: espressif/mdns
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=5.0
version: ^1.2.0
- name: espressif/network_provisioning
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >= 5.1
version: ~1.0.0
- name: espressif/rmaker_common
registry_url: https://components.espressif.com
require: private
version: ~1.4.6
source:
registry_url: https://components.espressif.com/
type: service
version: 1.5.2
espressif/esp_rcp_update:
component_hash: c10afbd54a17f27eed880e61262b161656e6d36ad63376c307f9273e99d0abcd
dependencies:
- name: espressif/esp-serial-flasher
registry_url: https://components.espressif.com
require: private
version: ~0.0.0
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com
type: service
version: 1.2.0
espressif/esp_schedule:
component_hash: e202a9c688f7f1ab601efb91d682e4bcfaebc508dcceee1a1e0a0d2d1ca75a26
dependencies:
- name: espressif/rmaker_common
registry_url: https://components.espressif.com
require: private
version: ~1.4.2
source:
registry_url: https://components.espressif.com
type: service
version: 1.2.0
espressif/esp_secure_cert_mgr:
component_hash: 29248e402b2014394228b289a3c02fdb1dc43168ef18fc83449a868dfbc2341f
dependencies:
- name: idf
require: private
version: '>=4.3'
source:
registry_url: https://components.espressif.com
type: service
version: 2.8.0
espressif/jsmn:
component_hash: d80350c41bbaa827c98a25b6072df00884e72f54885996fab4a4f0aebce6b6c3
dependencies:
- name: idf
require: private
version: '>=4.3'
source:
registry_url: https://components.espressif.com
type: service
version: 1.1.0
espressif/json_generator:
component_hash: 45033e1c199b13f1c8c1b544fb7d4e2df6a8e3071ebdcb1b22582b61a7974ff2
dependencies: []
source:
registry_url: https://components.espressif.com
type: service
version: 1.1.2
espressif/json_parser:
component_hash: d74b81729ad06ec11ff5eb5b1b0d7df1d00e6027fc11471f4b139c70dcf1b1e4
dependencies:
- name: espressif/jsmn
registry_url: https://components.espressif.com
require: private
rules:
- if: idf_version >=5.0
version: ~1.1
source:
registry_url: https://components.espressif.com
type: service
version: 1.0.3
espressif/lan867x:
component_hash: 651c9d6e3d96acb08bd5066144b12a12e94df0a6241127a0538d8680689de2c4
dependencies:
- name: espressif/lan86xx_common
registry_url: https://components.espressif.com
require: private
version: '*'
- name: idf
require: private
version: '>=5.3'
source:
registry_url: https://components.espressif.com/
type: service
targets:
- esp32
- esp32p4
version: 2.0.0
espressif/lan86xx_common:
component_hash: 6dcb1be9f43ae940979bd628fa5bee278949b66c545e1fe2321e486102e81026
dependencies:
- name: idf
require: private
version: '>=5.2'
source:
registry_url: https://components.espressif.com
type: service
version: 1.0.0
espressif/libsodium:
component_hash: 6ee084dee7a4d664498274870aa65391c9ec9d38dcdb34d2ad2b8518726f8b5e
dependencies:
- name: idf
require: private
version: '>=4.2'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.0.20~3
espressif/mdns:
component_hash: 29e47564b1a7ee778135e17fbbf2a2773f71c97ebabfe626c8eda7c958a7ad16
dependencies:
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.9.1
espressif/network_provisioning:
component_hash: ef2e10182fd1861e68b821491916327c25416ca7ae70e5a6e43313dbc71fe993
dependencies:
- name: idf
require: private
version: '>=5.1'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.0.2
espressif/qrcode:
component_hash: 3b493771bc5d6ad30cbf87c25bf784aada8a08c941504355b55d6b75518ed7bc
dependencies: []
source:
registry_url: https://components.espressif.com/
type: service
version: 0.1.0~2
espressif/rmaker_common:
component_hash: a3a1df881278d0351fc850b77792fe8a196ddd6dcacbea203d606329cc6a0239
dependencies: []
source:
registry_url: https://components.espressif.com/
type: service
version: 1.4.6
idf:
source:
type: idf
version: 5.5.2
joltwallet/littlefs:
component_hash: dcea25bcef2de023f089f5f01e8d8c46ad1b8ffef75861ad5ffb4098555839df
dependencies:
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.20.4
direct_dependencies:
- chmorgan/esp-libhelix-mp3
- espressif/cbor
- espressif/esp-dsp
- espressif/esp-modbus
- espressif/esp-tflite-micro
- espressif/esp-zboss-lib
- espressif/esp-zigbee-lib
- espressif/esp32-camera
- espressif/esp_diag_data_store
- espressif/esp_diagnostics
- espressif/esp_insights
- espressif/esp_matter
- espressif/esp_modem
- espressif/esp_rainmaker
- espressif/lan867x
- espressif/libsodium
- espressif/mdns
- espressif/network_provisioning
- espressif/qrcode
- espressif/rmaker_common
- idf
- joltwallet/littlefs
manifest_hash: 16e91a50a02d62dfe8c6588e19e154d6282c788a5e05795047f0cf203347e290
target: esp32
version: 2.0.0
File diff suppressed because it is too large Load Diff
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
-mlongcalls -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=deprecated-declarations -Wno-error=extra -Wno-unused-parameter -Wno-sign-compare -Wno-enum-conversion -gdwarf-4 -ggdb -mdisable-hardware-atomics -freorder-blocks -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -DCHIP_HAVE_CONFIG_H
+1
View File
@@ -0,0 +1 @@
-mlongcalls -Wno-frame-address -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=deprecated-declarations -Wno-error=extra -Wno-unused-parameter -Wno-sign-compare -Wno-enum-conversion -gdwarf-4 -ggdb -mdisable-hardware-atomics -freorder-blocks -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu17 -Wno-old-style-declaration -DCHIP_HAVE_CONFIG_H -Wno-strict-prototypes
+1
View File
@@ -0,0 +1 @@
-mlongcalls -Wno-frame-address -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy -ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=deprecated-declarations -Wno-error=extra -Wno-unused-parameter -Wno-sign-compare -Wno-enum-conversion -gdwarf-4 -ggdb -mdisable-hardware-atomics -freorder-blocks -Wwrite-strings -fstack-protector -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu++2b -fexceptions -fno-rtti -fuse-cxa-atexit -std=gnu++2a -DCHIP_HAVE_CONFIG_H
+1
View File
@@ -0,0 +1 @@
-DESP32_ARDUINO_LIB_BUILDER -DESP_MDNS_VERSION_NUMBER=\"1.9.1\" -DESP_PLATFORM -DIDF_VER=\"v5.5.2-729-g87912cd291\" -DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\" -DMD5_ENABLED=1 -DOPENTHREAD_CONFIG_FILE=\"openthread-core-esp32x-spinel-config.h\" -DOPENTHREAD_PROJECT_LIB_CONFIG_FILE=\"openthread-core-esp32x-spinel-config.h\" -DSERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 -DSERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -DSOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ -DUNITY_INCLUDE_CONFIG_H -D_GLIBCXX_HAVE_POSIX_SEMAPHORE -D_GLIBCXX_USE_POSIX_SEMAPHORE -D_GNU_SOURCE -D_POSIX_READER_WRITER_LOCKS -DTF_LITE_STATIC_MEMORY -DCHIP_CONFIG_SOFTWARE_VERSION_NUMBER=0 -DCHIP_DNSSD_DEFAULT_PLATFORM=true -DCHIP_DNSSD_DEFAULT_NONE=false -DCHIP_DNSSD_DEFAULT_MINIMAL=false
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
-mlongcalls -Wno-frame-address -nostartfiles -Wl,--cref -Wl,--defsym=IDF_TARGET_ESP32=0 -Wl,--no-warn-rwx-segments -Wl,--orphan-handling=warn -fno-rtti -fno-lto -Wl,--gc-sections -Wl,--warn-common -u nvs_sec_provider_include_impl -Wl,--wrap=log_printf -u ld_include_hli_vectors_bt -u _Z5setupv -u _Z4loopv -u esp_app_desc -u esp_efuse_startup_include_func -u ld_include_highint_hdl -u start_app -u start_app_other_cores -u __ubsan_include -u esp_system_include_startup_funcs -Wl,--wrap=longjmp -u __assert_func -u esp_dport_access_reg_read -u esp_security_init_include_impl -Wl,--undefined=FreeRTOS_openocd_params -u app_main -u esp_libc_include_heap_impl -u esp_libc_include_reent_syscalls_impl -u esp_libc_include_syscalls_impl -u esp_libc_include_pthread_impl -u esp_libc_include_assert_impl -u esp_libc_include_getentropy_impl -u esp_libc_include_init_funcs -u esp_libc_init_funcs -u pthread_include_pthread_impl -u pthread_include_pthread_cond_var_impl -u pthread_include_pthread_local_storage_impl -u pthread_include_pthread_rwlock_impl -u pthread_include_pthread_semaphore_impl -u __cxa_guard_dummy -u __cxx_init_dummy -u esp_timer_init_include_func -u uart_vfs_include_dev_init -u include_esp_phy_override -u esp_vfs_include_console_register -u vfs_include_syscalls_impl -u esp_vfs_include_nullfs_register -u esp_system_include_coredump_init
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
-T esp32.rom.redefined.ld -T esp32.peripherals.ld -T esp32.rom.ld -T esp32.rom.api.ld -T esp32.rom.libgcc.ld -T esp32.rom.newlib-data.ld -T esp32.rom.syscalls.ld -T memory.ld -T sections.ld
@@ -0,0 +1,279 @@
/*
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_APP_TRACE_H_
#define ESP_APP_TRACE_H_
#include <stdarg.h>
#include "esp_err.h"
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
#ifdef __cplusplus
extern "C" {
#endif
/**
* Application trace data destinations bits.
*/
typedef enum {
ESP_APPTRACE_DEST_JTAG = 1, ///< JTAG destination
ESP_APPTRACE_DEST_TRAX = ESP_APPTRACE_DEST_JTAG, ///< xxx_TRAX name is obsolete, use more common xxx_JTAG
ESP_APPTRACE_DEST_UART, ///< UART destination
ESP_APPTRACE_DEST_MAX = ESP_APPTRACE_DEST_UART+1,
ESP_APPTRACE_DEST_NUM
} esp_apptrace_dest_t;
/**
* @brief Initializes application tracing module.
*
* @note Should be called before any esp_apptrace_xxx call.
*
* @return ESP_OK on success, otherwise see esp_err_t
*/
esp_err_t esp_apptrace_init(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 buf Address of buffer to use for down channel (host to target) data.
* @param size Size of the buffer.
*/
void 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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @brief vprintf-like function to send log messages to host.
*
* @param fmt Address of format string.
* @param ap List of arguments.
*
* @return Number of bytes written.
*/
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);
/**
* @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. TRAX 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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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.
* @param stream File handle returned by esp_apptrace_fopen.
*
* @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);
/**
* @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.
* @param stream File handle returned by esp_apptrace_fopen.
*
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @brief Triggers gcov info dump.
* This function waits for the host to connect to target before dumping data.
*/
void esp_gcov_dump(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,192 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_APP_TRACE_UTIL_H_
#define ESP_APP_TRACE_UTIL_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "freertos/FreeRTOS.h"
#include "esp_err.h"
#include "esp_timer.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.
*
* @param tmo Pointer to timeout structure to be initialized.
* @param user_tmo Timeout value (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
*/
static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_tmo)
{
tmo->start = esp_timer_get_time();
tmo->tmo = user_tmo == ESP_APPTRACE_TMO_INFINITE ? (int64_t)-1 : (int64_t)user_tmo;
tmo->elapsed = 0;
}
/**
* @brief Checks timeout for expiration.
*
* @param tmo Pointer to timeout structure.
*
* @return number of remaining us till tmo.
*/
esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo);
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;
}
/**
* @brief Tries to acquire lock in specified time period.
*
* @param lock Pointer to lock structure.
* @param tmo Pointer to timeout struct.
*
* @return ESP_OK on success, otherwise \see esp_err_t
*/
esp_err_t esp_apptrace_lock_take(esp_apptrace_lock_t *lock, esp_apptrace_tmo_t *tmo);
/**
* @brief Releases lock.
*
* @param lock Pointer to lock structure.
*
* @return ESP_OK on success, otherwise \see esp_err_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 shrinked 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.
*
* @param rb Pointer to ring buffer structure to be initialized.
* @param data Pointer to buffer to be used as ring buffer's data storage.
* @param size Size of buffer to be used as ring buffer's data storage.
*/
static inline void esp_apptrace_rb_init(esp_apptrace_rb_t *rb, uint8_t *data, uint32_t size)
{
rb->data = data;
rb->size = rb->cur_size = size;
rb->rd = 0;
rb->wr = 0;
}
/**
* @brief Allocates memory chunk in ring buffer.
*
* @param rb Pointer to ring buffer structure.
* @param size Size of the memory to allocate.
*
* @return Pointer to the allocated memory or NULL in case of failure.
*/
uint8_t *esp_apptrace_rb_produce(esp_apptrace_rb_t *rb, uint32_t size);
/**
* @brief Consumes memory chunk in ring buffer.
*
* @param rb Pointer to ring buffer structure.
* @param size Size of the memory to consume.
*
* @return Pointer to consumed memory chunk or NULL in case of failure.
*/
uint8_t *esp_apptrace_rb_consume(esp_apptrace_rb_t *rb, uint32_t size);
/**
* @brief Gets size of memory which can consumed with single call to esp_apptrace_rb_consume().
*
* @param rb Pointer to ring buffer structure.
*
* @return Size of memory which can consumed.
*
* @note Due to read pointer wrapping returned size can be less then the total size of available data.
*/
uint32_t esp_apptrace_rb_read_size_get(esp_apptrace_rb_t *rb);
/**
* @brief Gets size of memory which can produced with single call to esp_apptrace_rb_produce().
*
* @param rb Pointer to ring buffer structure.
*
* @return Size of memory which can produced.
*
* @note Due to write pointer wrapping returned size can be less then the total size of available data.
*/
uint32_t esp_apptrace_rb_write_size_get(esp_apptrace_rb_t *rb);
int esp_apptrace_log_lock(void);
void esp_apptrace_log_unlock(void);
#define ESP_APPTRACE_LOG( format, ... ) \
do { \
esp_apptrace_log_lock(); \
esp_rom_printf(format, ##__VA_ARGS__); \
esp_apptrace_log_unlock(); \
} while(0)
#define ESP_APPTRACE_LOG_LEV( _L_, level, format, ... ) \
do { \
if (LOG_LOCAL_LEVEL >= level) { \
ESP_APPTRACE_LOG(LOG_FORMAT(_L_, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); \
} \
} while(0)
#define ESP_APPTRACE_LOGE( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_ERROR, format, ##__VA_ARGS__)
#define ESP_APPTRACE_LOGW( format, ... ) ESP_APPTRACE_LOG_LEV(W, ESP_LOG_WARN, format, ##__VA_ARGS__)
#define ESP_APPTRACE_LOGI( format, ... ) ESP_APPTRACE_LOG_LEV(I, ESP_LOG_INFO, format, ##__VA_ARGS__)
#define ESP_APPTRACE_LOGD( format, ... ) ESP_APPTRACE_LOG_LEV(D, ESP_LOG_DEBUG, format, ##__VA_ARGS__)
#define ESP_APPTRACE_LOGV( format, ... ) ESP_APPTRACE_LOG_LEV(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__)
#define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif //ESP_APP_TRACE_UTIL_H_
@@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_SYSVIEW_TRACE_H_
#define ESP_SYSVIEW_TRACE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include "esp_err.h"
#include "SEGGER_RTT.h" // SEGGER_RTT_ESP_Flush
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
/**
* @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.
*
* @return ESP_OK.
*/
static inline esp_err_t esp_sysview_flush(uint32_t tmo)
{
SEGGER_RTT_ESP_Flush(0, tmo);
return ESP_OK;
}
/**
* @brief vprintf-like function to sent log messages to the host.
*
* @param format Address of format string.
* @param args List of arguments.
*
* @return Number of bytes written.
*/
int esp_sysview_vprintf(const char * format, va_list args);
/**
* @brief Starts SystemView heap tracing.
*
* @param tmo Timeout (in us) to wait for the host to be connected. Use -1 to wait forever.
*
* @return ESP_OK on success, ESP_ERR_TIMEOUT if operation has been timed out.
*/
esp_err_t esp_sysview_heap_trace_start(uint32_t tmo);
/**
* @brief Stops SystemView heap tracing.
*
* @return ESP_OK.
*/
esp_err_t esp_sysview_heap_trace_stop(void);
/**
* @brief Sends heap allocation event to the host.
*
* @param addr Address of allocated block.
* @param size Size of allocated block.
* @param callers Pointer to array with callstack addresses.
* Array size must be CONFIG_HEAP_TRACING_STACK_DEPTH.
*/
void esp_sysview_heap_trace_alloc(void *addr, uint32_t size, const void *callers);
/**
* @brief Sends heap de-allocation event to the host.
*
* @param addr Address of de-allocated block.
* @param callers Pointer to array with callstack addresses.
* Array size must be CONFIG_HEAP_TRACING_STACK_DEPTH.
*/
void esp_sysview_heap_trace_free(void *addr, const void *callers);
#ifdef __cplusplus
}
#endif
#endif //ESP_SYSVIEW_TRACE_H_
@@ -0,0 +1,459 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _OTA_OPS_H
#define _OTA_OPS_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "esp_err.h"
#include "esp_partition.h"
#include "esp_app_desc.h"
#include "esp_bootloader_desc.h"
#include "esp_flash_partitions.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define OTA_SIZE_UNKNOWN 0xffffffff /*!< Used for esp_ota_begin() if new image size is unknown */
#define OTA_WITH_SEQUENTIAL_WRITES 0xfffffffe /*!< Used for esp_ota_begin() if new image size is unknown and erase can be done in incremental manner (assuming write operation is in continuous sequence) */
#define ESP_ERR_OTA_BASE 0x1500 /*!< Base error code for ota_ops api */
#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< Error if request was to write or erase the current running partition */
#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< Error if OTA data partition contains invalid content */
#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< Error if OTA app image is invalid */
#define ESP_ERR_OTA_SMALL_SEC_VER (ESP_ERR_OTA_BASE + 0x04) /*!< Error if the firmware has a secure version less than the running firmware. */
#define ESP_ERR_OTA_ROLLBACK_FAILED (ESP_ERR_OTA_BASE + 0x05) /*!< Error if flash does not have valid firmware in passive partition and hence rollback is not possible */
#define ESP_ERR_OTA_ROLLBACK_INVALID_STATE (ESP_ERR_OTA_BASE + 0x06) /*!< Error if current active firmware is still marked in pending validation state (ESP_OTA_IMG_PENDING_VERIFY), essentially first boot of firmware image post upgrade and hence firmware upgrade is not possible */
/**
* @brief Opaque handle for an application OTA update
*
* esp_ota_begin() returns a handle which is then used for subsequent
* calls to esp_ota_write() and esp_ota_end().
*/
typedef uint32_t esp_ota_handle_t;
/**
* @brief Return esp_app_desc structure. This structure includes app version.
*
* @note This API is present for backward compatibility reasons. Alternative function
* with the same functionality is `esp_app_get_description`
*
* Return description for running app.
* @return Pointer to esp_app_desc structure.
*/
const esp_app_desc_t *esp_ota_get_app_description(void) __attribute__((deprecated("Please use esp_app_get_description instead")));
/**
* @brief Fill the provided buffer with SHA256 of the ELF file, formatted as hexadecimal, null-terminated.
* If the buffer size is not sufficient to fit the entire SHA256 in hex plus a null terminator,
* the largest possible number of bytes will be written followed by a null.
*
* @note This API is present for backward compatibility reasons. Alternative function
* with the same functionality is `esp_app_get_elf_sha256`
*
* @param dst Destination buffer
* @param size Size of the buffer
* @return Number of bytes written to dst (including null terminator)
*/
int esp_ota_get_app_elf_sha256(char* dst, size_t size) __attribute__((deprecated("Please use esp_app_get_elf_sha256 instead")));
/**
* @brief Commence an OTA update writing to the specified partition.
* The specified partition is erased to the specified image size.
*
* If image size is not yet known, pass OTA_SIZE_UNKNOWN which will
* cause the entire partition to be erased.
*
* On success, this function allocates memory that remains in use
* until esp_ota_end() is called with the returned handle.
*
* Note: If the rollback option is enabled and the running application has the ESP_OTA_IMG_PENDING_VERIFY state then
* it will lead to the ESP_ERR_OTA_ROLLBACK_INVALID_STATE error. Confirm the running app before to run download a new app,
* use esp_ota_mark_app_valid_cancel_rollback() function for it (this should be done as early as possible when you first download a new application).
*
* Note: Rollback is applicable only for app type partitions.
* Note: For Rollback - The OTA data slot corresponding to the last boot application partition will be invalidated.
*
* @param partition Pointer to info for partition which will receive the OTA update. Required.
* This is considered as the staging partition (where OTA is downloaded), be default this also considered as the final partition which supposed to be updated.
* The final partition can be overwritten using esp_ota_set_final_partition() after calling esp_ota_begin() to relocate contents to the final destination partition.
* @param image_size Size of new OTA app image. Partition will be erased in order to receive this size of image. If 0 or OTA_SIZE_UNKNOWN, the entire partition is erased.
* @param out_handle On success, returns a handle which should be used for subsequent esp_ota_write() and esp_ota_end() calls.
* @return
* - ESP_OK: OTA operation commenced successfully.
* - ESP_ERR_INVALID_ARG: partition or out_handle arguments were NULL, or partition doesn't point to an OTA app partition.
* - ESP_ERR_NO_MEM: Cannot allocate memory for OTA operation.
* - ESP_ERR_OTA_PARTITION_CONFLICT: Partition holds the currently running firmware, cannot update in place.
* - ESP_ERR_NOT_FOUND: Partition argument not found in partition table.
* - ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data.
* - ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size.
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
* - ESP_ERR_OTA_ROLLBACK_INVALID_STATE: If the running app has not confirmed state. Before performing an update, the application must be valid.
*/
esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle);
/**
* @brief Resume an interrupted OTA update by continuing to write to the specified partition.
*
* This function is used when an OTA update was previously started and needs to be resumed after an interruption.
* It continues the OTA process from the specified offset within the partition.
*
* Unlike esp_ota_begin(), this function does not erase the partition which receives the OTA update, but rather expects that part of the image
* has already been written correctly, and it resumes writing from the given offset.
*
* @param partition Pointer to info for the partition which is receiving the OTA update. Required.
* @param erase_size Specifies how much flash memory to erase before resuming OTA, depending on whether a sequential write or a bulk erase is being used.
* @param image_offset Offset from where to resume the OTA process. Should be set to the number of bytes already written.
* @param out_handle On success, returns a handle that should be used for subsequent esp_ota_write() and esp_ota_end() calls.
*
* @return
* - ESP_OK: OTA operation resumed successfully.
* - ESP_ERR_INVALID_ARG: partition, out_handle were NULL or image_offset arguments is negative, or partition doesn't point to an OTA app partition.
* - ESP_ERR_NO_MEM: Cannot allocate memory for OTA operation.
* - ESP_ERR_OTA_PARTITION_CONFLICT: Partition holds the currently running firmware, cannot update in place.
* - ESP_ERR_NOT_FOUND: Partition argument not found in partition table.
* - ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data.
* - ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size.
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
*/
esp_err_t esp_ota_resume(const esp_partition_t *partition, const size_t erase_size, const size_t image_offset, esp_ota_handle_t *out_handle);
/**
* @brief Set the final destination partition for OTA update
*
* This function configures the specified final partition as the destination for the OTA update.
* It also allows setting a flag to indicate if the image should be copied from the staging
* partition to the final partition after the OTA update completes. Otherwise, copying will need
* to be handled by custom code using esp_partition_copy().
*
* @note This can be called after esp_ota_begin() and before the OTA update has started (before esp_ota_write()).
*
* @param handle OTA update handle obtained from esp_ota_begin().
* @param final Pointer to the final destination partition where the new image will be verified and potentially finalized.
* This partition must not be NULL.
* @param finalize_with_copy Boolean flag indicating if the downloaded image should be copied
* from the staging partition to the final partition upon completion.
* Set to False if you intend to perform the final copy process manually later.
*
* @return
* - ESP_OK: final destination partition set successfully.
* - ESP_ERR_INVALID_STATE: Once the OTA update has started, changing the final destination partition is prohibited.
* - ESP_ERR_INVALID_ARG: Invalid arguments were passed (e.g., final partition is NULL).
* - ESP_ERR_NOT_FOUND: OTA handle not found or final partition verification failed.
*/
esp_err_t esp_ota_set_final_partition(esp_ota_handle_t handle, const esp_partition_t *final, bool finalize_with_copy);
/**
* @brief Write OTA update data to partition
*
* This function can be called multiple times as
* data is received during the OTA operation. Data is written
* sequentially to the partition.
*
* @param handle Handle obtained from esp_ota_begin
* @param data Data buffer to write
* @param size Size of data buffer in bytes.
*
* @return
* - ESP_OK: Data was written to flash successfully, or size = 0
* - ESP_ERR_INVALID_ARG: handle is invalid.
* - ESP_ERR_OTA_VALIDATE_FAILED: First byte of image contains invalid image magic byte.
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
* - ESP_ERR_INVALID_SIZE: if write would go out of bounds of the partition
* - or one of error codes from lower-level flash driver.
*/
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
/**
* @brief Write OTA update data to partition at an offset
*
* This function can write data in non-contiguous manner.
* If flash encryption is enabled, data should be 16 bytes aligned.
*
* @param handle Handle obtained from esp_ota_begin
* @param data Data buffer to write
* @param size Size of data buffer in bytes
* @param offset Offset in flash partition
*
* @note While performing OTA, if the packets arrive out of order, esp_ota_write_with_offset() can be used to write data in non-contiguous manner.
* Use of esp_ota_write_with_offset() in combination with esp_ota_write() is not recommended.
*
* @return
* - ESP_OK: Data was written to flash successfully.
* - ESP_ERR_INVALID_ARG: handle is invalid.
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
*/
esp_err_t esp_ota_write_with_offset(esp_ota_handle_t handle, const void *data, size_t size, uint32_t offset);
/**
* @brief Finish OTA update and validate newly written app image.
*
* @param handle Handle obtained from esp_ota_begin().
*
* @note After calling esp_ota_end(), the handle is no longer valid and any memory associated with it is freed (regardless of result).
* @note If either the final or staging partitions were for the bootloader, then at the end of this function,
* the bootloader is reset to its default offset: esp_image_bootloader_offset_set(ESP_PRIMARY_BOOTLOADER_OFFSET)
*
* If the finalize_with_copy option is set, the staging partition will be copied to the final partition at the end of this function.
* Otherwise, copying will need to be handled by custom code using esp_partition_copy().
*
* @return
* - ESP_OK: Newly written OTA app image is valid.
* - ESP_ERR_NOT_FOUND: OTA handle was not found.
* - ESP_ERR_INVALID_ARG: Handle was never written to.
* - ESP_ERR_OTA_VALIDATE_FAILED: OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.)
* - ESP_ERR_INVALID_STATE: If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash.
*/
esp_err_t esp_ota_end(esp_ota_handle_t handle);
/**
* @brief Abort OTA update, free the handle and memory associated with it.
*
* @param handle obtained from esp_ota_begin().
*
* @return
* - ESP_OK: Handle and its associated memory is freed successfully.
* - ESP_ERR_NOT_FOUND: OTA handle was not found.
*/
esp_err_t esp_ota_abort(esp_ota_handle_t handle);
/**
* @brief Configure OTA data for a new boot partition
*
* @note If this function returns ESP_OK, calling esp_restart() will boot the newly configured app partition.
*
* @param partition Pointer to info for partition containing app image to boot.
*
* @return
* - ESP_OK: OTA data updated, next reboot will use specified partition.
* - ESP_ERR_INVALID_ARG: partition argument was NULL or didn't point to a valid OTA partition of type "app".
* - ESP_ERR_OTA_VALIDATE_FAILED: Partition contained invalid app image. Also returned if secure boot is enabled and signature validation failed.
* - ESP_ERR_NOT_FOUND: OTA data partition not found.
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash erase or write failed.
*/
esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
/**
* @brief Get partition info of currently configured boot app
*
* If esp_ota_set_boot_partition() has been called, the partition which was set by that function will be returned.
*
* If esp_ota_set_boot_partition() has not been called, the result is usually the same as esp_ota_get_running_partition().
* The two results are not equal if the configured boot partition does not contain a valid app (meaning that the running partition
* will be an app that the bootloader chose via fallback).
*
* If the OTA data partition is not present or not valid then the result is the first app partition found in the
* partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition.
*
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the
* returned partition contains a bootable image.
*
* @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application.
*/
const esp_partition_t* esp_ota_get_boot_partition(void);
/**
* @brief Get partition info of currently running app
*
* This function is different to esp_ota_get_boot_partition() in that
* it ignores any change of selected boot partition caused by
* esp_ota_set_boot_partition(). Only the app whose code is currently
* running will have its partition information returned.
*
* The partition returned by this function may also differ from esp_ota_get_boot_partition() if the configured boot
* partition is somehow invalid, and the bootloader fell back to a different app partition at boot.
*
* @return Pointer to info for partition structure, or NULL if no partition is found or flash read operation failed. Returned pointer is valid for the lifetime of the application.
*/
const esp_partition_t* esp_ota_get_running_partition(void);
/**
* @brief Return the next OTA app partition which should be written with a new firmware.
*
* Call this function to find an OTA app partition which can be passed to esp_ota_begin().
*
* Finds next partition round-robin, starting from the current running partition.
*
* @param start_from If set, treat this partition info as describing the current running partition. Can be NULL, in which case esp_ota_get_running_partition() is used to find the currently running partition. The result of this function is never the same as this argument.
*
* @return Pointer to info for partition which should be updated next. NULL result indicates invalid OTA data partition, or that no eligible OTA app slot partition was found.
*
*/
const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *start_from);
/**
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
*
* Returns a description for the requested app partition.
* @param[in] partition Pointer to app partition. (only app partition)
* @param[out] app_desc Structure of info about app.
* @return
* - ESP_OK Successful.
* - ESP_ERR_NOT_FOUND app_desc structure is not found. Magic word is incorrect.
* - ESP_ERR_NOT_SUPPORTED Partition is not application.
* - ESP_ERR_INVALID_ARG Arguments is NULL or if partition's offset exceeds partition size.
* - ESP_ERR_INVALID_SIZE Read would go out of bounds of the partition.
* - or one of error codes from lower-level flash driver.
*/
esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc);
/**
* @brief Returns the description structure of the bootloader.
*
* @param[in] bootloader_partition Pointer to bootloader partition.
* If NULL, then the PRIMARY bootloader is used (the default location).
* offset = CONFIG_BOOTLOADER_OFFSET_IN_FLASH,
* size = CONFIG_PARTITION_TABLE_OFFSET - CONFIG_BOOTLOADER_OFFSET_IN_FLASH,
* @param[out] desc Structure of info about bootloader.
* @return
* - ESP_OK Successful.
* - ESP_ERR_NOT_FOUND Description structure is not found in the bootloader image. Magic byte is incorrect.
* - ESP_ERR_INVALID_ARG Arguments is NULL.
* - ESP_ERR_INVALID_SIZE Read would go out of bounds of the partition.
* - or one of error codes from lower-level flash driver.
*/
esp_err_t esp_ota_get_bootloader_description(const esp_partition_t *bootloader_partition, esp_bootloader_desc_t *desc);
/**
* @brief Invalidate the OTA data slot associated with the last boot application partition.
*
* This function erases the OTA data slot corresponding to the last boot application partition,
* making the partition invalid for booting in future. The application partition itself
* is not erased, preserving its contents.
*
* @return
* - ESP_OK: Successfully invalidated the OTA data slot.
* - ESP_FAIL: Failed to invalidate the OTA data slot (e.g., invalid parameters, no OTA data partition, or other errors).
* - Other error codes from `esp_partition_erase_range`.
*/
esp_err_t esp_ota_invalidate_inactive_ota_data_slot(void);
/**
* @brief Returns number of ota partitions provided in partition table.
*
* @return
* - Number of OTA partitions
*/
uint8_t esp_ota_get_app_partition_count(void);
/**
* @brief This function is called to indicate that the running app is working well.
*
* @return
* - ESP_OK: if successful.
*/
esp_err_t esp_ota_mark_app_valid_cancel_rollback(void);
/**
* @brief This function is called to roll back to the previously workable app without reboot.
*
* Checks applications on a flash drive that can be booted in case of rollback.
* If the flash does not have at least one app (except the running app) then rollback is not possible.
* @return
* - ESP_OK: if successful.
* - ESP_FAIL: if not successful.
* - ESP_ERR_OTA_ROLLBACK_FAILED: The rollback is not possible because the available OTA partitions
* on the flash do not contain a valid application.
*/
esp_err_t esp_ota_mark_app_invalid_rollback(void);
/**
* @brief This function is called to roll back to the previously workable app with reboot.
*
* Equivalent to calling esp_ota_mark_app_invalid_rollback(), and, if successful, followed by esp_restart().
*
* @return
* - ESP_FAIL: if not successful.
* - ESP_ERR_OTA_ROLLBACK_FAILED: The rollback is not possible due to flash does not have any apps.
*/
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot(void);
/**
* @brief Returns last partition with invalid state (ESP_OTA_IMG_INVALID or ESP_OTA_IMG_ABORTED).
*
* @return partition.
*/
const esp_partition_t* esp_ota_get_last_invalid_partition(void);
/**
* @brief Returns state for given partition.
*
* @param[in] partition Pointer to partition.
* @param[out] ota_state state of partition (if this partition has a record in otadata).
* @return
* - ESP_OK: Successful.
* - ESP_ERR_INVALID_ARG: partition or ota_state arguments were NULL.
* - ESP_ERR_NOT_SUPPORTED: partition is not ota.
* - ESP_ERR_NOT_FOUND: Partition table does not have otadata or state was not found for given partition.
*/
esp_err_t esp_ota_get_state_partition(const esp_partition_t *partition, esp_ota_img_states_t *ota_state);
/**
* @brief Erase previous boot app partition and corresponding otadata select for this partition.
*
* When current app is marked to as valid then you can erase previous app partition.
* @return
* - ESP_OK: Successful, otherwise ESP_ERR.
*/
esp_err_t esp_ota_erase_last_boot_app_partition(void);
/**
* @brief Checks applications on the slots which can be booted in case of rollback.
*
* These applications should be valid (marked in otadata as not UNDEFINED, INVALID or ABORTED and crc is good) and be able booted,
* and secure_version of app >= secure_version of efuse (if anti-rollback is enabled).
*
* @return
* - True: Returns true if the slots have at least one app (except the running app).
* - False: The rollback is not possible.
*/
bool esp_ota_check_rollback_is_possible(void);
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 && (CONFIG_SECURE_BOOT_V2_ENABLED || __DOXYGEN__)
/**
* Secure Boot V2 public key indexes.
*/
typedef enum {
SECURE_BOOT_PUBLIC_KEY_INDEX_0, /*!< Points to the 0th index of the Secure Boot v2 public key */
SECURE_BOOT_PUBLIC_KEY_INDEX_1, /*!< Points to the 1st index of the Secure Boot v2 public key */
SECURE_BOOT_PUBLIC_KEY_INDEX_2 /*!< Points to the 2nd index of the Secure Boot v2 public key */
} esp_ota_secure_boot_public_key_index_t;
/**
* @brief Revokes the signature digest denoted by the given index. This should be called in the application only after the rollback logic otherwise the device may end up in unrecoverable state.
*
* Relevant for Secure boot v2 on ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6, ESP32-H2 where up to 3 key digests can be stored (Key \#N-1, Key \#N, Key \#N+1).
* When a key used to sign an app is invalidated, an OTA update is to be sent with an app signed with at least one of the other two keys which has not been revoked already.
* After successfully booting the OTA app should call this function to revoke Key \#N-1.
*
* @param index - The index of the signature block to be revoked
*
* @return
* - ESP_OK: If revocation is successful.
* - ESP_ERR_INVALID_ARG: If the index of the public key to be revoked is incorrect.
* - ESP_FAIL: If secure boot v2 has not been enabled.
*/
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index);
#endif /* SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 */
#ifdef __cplusplus
}
#endif
#endif /* OTA_OPS_H */
@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <esp_err.h>
#include "spi_flash_mmap.h" /* including in bootloader for error values */
#include "esp_private/spi_flash_os.h"
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "bootloader_flash_override.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Read flash ID by sending RDID command (0x9F)
* @return flash raw ID
* mfg_id = (ID >> 16) & 0xFF;
flash_id = ID & 0xffff;
*/
uint32_t bootloader_read_flash_id(void);
/**
* @brief Startup flow recommended by XMC. Call at startup before any erase/write operation.
*
* @return ESP_OK When startup successfully, otherwise ESP_FAIL (indicating you should reboot before erase/write).
*/
esp_err_t bootloader_flash_xmc_startup(void);
/**
* @brief Unlock Flash write protect.
* Please do not call this function in SDK.
*
* @note This can be overridden because it's attribute weak, when there is a same name symbol.
*/
esp_err_t bootloader_flash_unlock(void);
/**
* @brief Unlock Flash write protect.
* This is alias to `bootloader_flash_unlock`.
* Please do not call this function in SDK.
*/
esp_err_t bootloader_flash_unlock_default(void);
/**
* @brief Reset the flash chip (66H + 99H).
*
* @return ESP_OK if success, otherwise ESP_FAIL.
*/
esp_err_t bootloader_flash_reset_chip(void);
/**
* @brief Check if octal flash mode is enabled in eFuse
*
* @return True if flash is in octal mode, false else
*/
bool bootloader_flash_is_octal_mode_enabled(void);
/**
* @brief Get the spi flash working mode.
*
* @return The mode of flash working mode, see `esp_rom_spiflash_read_mode_t`
*/
esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,93 @@
/*
* SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "esp_image_format.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Update the flash id in g_rom_flashchip(global esp_rom_spiflash_chip_t structure).
*
* @return None
*/
void bootloader_flash_update_id(void);
/**
* @brief Update the flash size in g_rom_flashchip (global esp_rom_spiflash_chip_t structure).
*
* @param size The size to store, in bytes.
* @return None
*/
void bootloader_flash_update_size(uint32_t size);
/**
* @brief Set the flash CS setup and hold time.
*
* @note CS setup time is recomemded to be 1.5T, and CS hold time is recommended to be 2.5T.
* cs_setup = 1, cs_setup_time = 0; cs_hold = 1, cs_hold_time = 1.
*
* @return None
*/
void bootloader_flash_cs_timing_config(void);
/**
* @brief Configure SPI flash clock.
*
* @note This function only set clock frequency for SPI0.
*
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
*
* @return None
*/
void bootloader_flash_clock_config(const esp_image_header_t* pfhdr);
/**
* @brief Configure SPI flash gpio, include the IO matrix and drive strength configuration.
*
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
*
* @return None
*/
void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr);
#ifdef CONFIG_IDF_TARGET_ESP32
/**
* @brief Configure SPI flash read dummy based on different mode and frequency.
*
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
*
* @return None
*/
void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr);
#else
// The meaning has changed on this chip. Deprecated, Call `bootloader_configure_spi_pins()` and `bootloader_flash_set_dummy_out()` directly.
void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr) __attribute__((deprecated));
#endif
#ifdef CONFIG_IDF_TARGET_ESP32
/**
* @brief Return the pin number used for custom SPI flash and/or SPIRAM WP pin
*
* Can be determined by eFuse values in most cases, or overriden in configuration
*
* This value is only meaningful if the other SPI flash pins are overriden via eFuse.
*
* This value is only meaningful if flash is set to QIO or QOUT mode, or if
* SPIRAM is enabled.
*
* @return Pin number to use, or -1 if the default should be kept
*/
int bootloader_flash_get_wp_pin(void);
#endif
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,130 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned (*bootloader_flash_read_status_fn_t)(void);
typedef void (*bootloader_flash_write_status_fn_t)(unsigned);
typedef struct __attribute__((packed))
{
const char *manufacturer;
uint8_t mfg_id; /* 8-bit JEDEC manufacturer ID */
uint16_t flash_id; /* 16-bit JEDEC flash chip ID */
uint16_t id_mask; /* Bits to match on in flash chip ID */
bootloader_flash_read_status_fn_t read_status_fn;
bootloader_flash_write_status_fn_t write_status_fn;
uint8_t status_qio_bit;
} bootloader_qio_info_t;
/**
* @brief Read 8 bit status using RDSR command
*
* @return Value of SR1.
*/
unsigned bootloader_read_status_8b_rdsr(void);
/**
* @brief Read 8 bit status (second byte) using RDSR2 command
*
* @return Value of SR2
*/
unsigned bootloader_read_status_8b_rdsr2(void);
/**
* @brief Read 8 bit status (third byte) using RDSR3 command
*
* @return Value of SR3
*/
unsigned bootloader_read_status_8b_rdsr3(void);
/**
* @brief Read 16 bit status using RDSR & RDSR2 (low and high bytes)
*
* @return Value of SR2#SR1.
*/
unsigned bootloader_read_status_16b_rdsr_rdsr2(void);
/**
* @brief Write 8 bit status using WRSR
*/
void bootloader_write_status_8b_wrsr(unsigned new_status);
/**
* @brief Write 8 bit status (second byte) using WRSR2.
*/
void bootloader_write_status_8b_wrsr2(unsigned new_status);
/**
* @brief Write 8 bit status (third byte) using WRSR3.
*/
void bootloader_write_status_8b_wrsr3(unsigned new_status);
/**
* @brief Write 16 bit status using WRSR, (both write SR1 and SR2)
*/
void bootloader_write_status_16b_wrsr(unsigned new_status);
/**
* @brief Read 8 bit status of XM25QU64A.
*
* @return Value of 8 bit SR.
*/
unsigned bootloader_read_status_8b_xmc25qu64a(void);
/**
* @brief Write 8 bit status for XM25QU64A
*/
void bootloader_write_status_8b_xmc25qu64a(unsigned new_status);
/* Array of known flash chips and data to enable Quad I/O mode
Manufacturer & flash ID can be tested by running "esptool.py
flash_id"
If manufacturer ID matches, and flash ID ORed with flash ID mask
matches, enable_qio_mode() will execute "Read Cmd", test if bit
number "QIE Bit" is set, and if not set it will call "Write Cmd"
with this bit set.
Searching of this table stops when the first match is found.
*/
extern const bootloader_qio_info_t* bootloader_flash_qe_support_list;
/**
* @brief The bootloader flash qe list count number.
*/
extern uint8_t bootloader_flash_qe_list_count;
/**
* @brief Unlock Flash write protect.
* Please do not call this function in SDK.
*
* @note This can be overridden because it's attribute weak, when there is a same name symbol.
*/
esp_err_t bootloader_flash_unlock(void);
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH || CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
/**
* @brief Enable 32bits address flash(larger than 16MB) can map to cache.
*
* @param flash_mode SPI flash working mode.
*
* @note This can be overridden because it's attribute weak, when there is a same name symbol.
*/
void __attribute__((weak)) bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode);
#endif
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,205 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BOOTLOADER_FLASH_H
#define __BOOTLOADER_FLASH_H
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <esp_err.h>
#include <spi_flash_mmap.h> /* including in bootloader for error values */
#include "sdkconfig.h"
#include "bootloader_flash.h"
#include "soc/ext_mem_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FLASH_SECTOR_SIZE 0x1000
#define FLASH_BLOCK_SIZE 0x10000
#define MMAP_ALIGNED_MASK (SPI_FLASH_MMU_PAGE_SIZE - 1)
#define MMU_FLASH_MASK (~(SPI_FLASH_MMU_PAGE_SIZE - 1))
#define MMU_FLASH_MASK_FROM_VAL(PAGE_SZ) (~((PAGE_SZ) - 1))
#define MMU_DROM_END_ENTRY_VADDR_FROM_VAL(PAGE_SZ) (SOC_DRAM_FLASH_ADDRESS_HIGH - (PAGE_SZ))
/**
* MMU mapping must always be in the unit of a SPI_FLASH_MMU_PAGE_SIZE
* This macro is a helper for you to get needed page nums to be mapped. e.g.:
* Let's say SPI_FLASH_MMU_PAGE_SIZE is 64KB.
* - v_start = 0x4200_0004
* - size = 4 * 64KB
*
* You should map from 0x4200_0000, then map 5 pages.
*/
#define GET_REQUIRED_MMU_PAGES(size, v_start) ((size + (v_start - (v_start & MMU_FLASH_MASK)) + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE)
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
Suitable for use with the bootloader_execute_flash_command static function.
*/
#define CMD_RDID 0x9F
#define CMD_WRSR 0x01
#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */
#define CMD_WRSR3 0x11 /* Not all SPI flash uses this command */
#define CMD_WREN 0x06
#define CMD_WRENVSR 0x50 /* Flash write enable for volatile SR bits */
#define CMD_WRDI 0x04
#define CMD_RDSR 0x05
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
#define CMD_RDSR3 0x15 /* Not all SPI flash uses this command */
#define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */
#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */
#define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */
#define CMD_RESETEN 0x66
#define CMD_RESET 0x99
#define CMD_FASTRD_QIO_4B 0xEC
#define CMD_FASTRD_QUAD_4B 0x6C
#define CMD_FASTRD_DIO_4B 0xBC
#define CMD_FASTRD_DUAL_4B 0x3C
#define CMD_FASTRD_4B 0x0C
#define CMD_SLOWRD_4B 0x13
/* Provide a Flash API for bootloader_support code,
that can be used from bootloader or app code.
This header is available to source code in the bootloader &
bootloader_support components only.
*/
/**
* @brief Get number of free pages
*
* @return Number of free pages
*/
uint32_t bootloader_mmap_get_free_pages(void);
/**
* @brief Map a region of flash to data memory
*
* @important In bootloader code, only one region can be bootloader_mmaped at once. The previous region must be bootloader_munmapped before another region is mapped.
*
* @important In app code, these functions are not thread safe.
*
* Call bootloader_munmap once for each successful call to bootloader_mmap.
*
* In esp-idf app, this function maps directly to spi_flash_mmap.
*
* @param offset - Starting flash offset to map to memory.
* @param length - Length of data to map.
*
* @return Pointer to mapped data memory (at src_addr), or NULL
* if an allocation error occurred.
*/
const void *bootloader_mmap(uint32_t src_addr, uint32_t size);
/**
* @brief Unmap a previously mapped region of flash
*
* Call bootloader_munmap once for each successful call to bootloader_mmap.
*/
void bootloader_munmap(const void *mapping);
/**
* @brief Read data from Flash.
*
*
* @note All of src, dest and size have to be 4-byte aligned.
*
* @param src source address of the data in Flash.
* @param dest pointer to the destination buffer
* @param size length of data
* @param allow_decrypt If true and flash encryption is enabled, data on flash
* will be decrypted transparently as part of the read.
*
* @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure,
* ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout.
*/
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size, bool allow_decrypt);
/**
* @brief Write data to Flash.
*
* @note All of dest_addr, src and size have to be 4-byte aligned. If write_encrypted is set, dest_addr and size must be 32-byte aligned.
*
* @note In bootloader, when write_encrypted == true, the src buffer is encrypted in place.
*
* @note [ESP-TEE] Using this API from the TEE will return an error if the dest_addr lies
* within the active TEE partition range.
*
* @param dest_addr Destination address to write in Flash.
* @param src Pointer to the data to write to flash
* @param size Length of data in bytes.
* @param write_encrypted If true, data will be written encrypted on flash.
*
* @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure,
* ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout.
*/
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted);
/**
* @brief Erase the Flash sector.
*
* @param sector Sector number, the count starts at sector 0, 4KB per sector.
*
* @return esp_err_t
*/
esp_err_t bootloader_flash_erase_sector(size_t sector);
/**
* @brief Erase the Flash range.
*
* @note [ESP-TEE] Using this API from the TEE will return an error if the start_addr lies
* within the active TEE partition range.
*
* @param start_addr start address of flash offset
* @param size sector aligned size to be erased
*
* @return esp_err_t
*/
esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size);
/**
* @brief Execute a user command on the flash
*
* @param command The command value to execute.
* @param mosi_data MOSI data to send
* @param mosi_len Length of MOSI data, in bits
* @param miso_len Length of MISO data to receive, in bits
* @return Received MISO data
*/
uint32_t bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len);
/**
* @brief Read the SFDP of the flash
*
* @param sfdp_addr Address of the parameter to read
* @param miso_byte_num Bytes to read
* @return The read SFDP, little endian, 4 bytes at most
*/
uint32_t bootloader_flash_read_sfdp(uint32_t sfdp_addr, unsigned int miso_byte_num);
/**
* @brief Enable the flash write protect (WEL bit).
*/
void bootloader_enable_wp(void);
/**
* @brief Once this function is called,
* any on-going internal operations will be terminated and the device will return to its default power-on
* state and lose all the current volatile settings, such as Volatile Status Register bits, Write Enable Latch
* (WEL) status, Program/Erase Suspend status, etc.
*/
void bootloader_spi_flash_reset(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <esp_err.h>
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize spi_flash in bootloader and print flash info
*
* @return ESP_OK on success, otherwise see esp_err_t
*/
esp_err_t bootloader_init_spi_flash(void);
#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
/**
* @brief Config all flash related stuff according to the header. The consistency of all flash configs is ensured.
*
* @return None
*/
void bootloader_flash_hardware_init(void);
#endif
/**
* @brief Initialise mspi core clock
*/
void bootloader_init_mspi_clock(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Enable Quad I/O mode in bootloader (if configured)
*
* Queries attached SPI flash ID and sends correct SPI flash
* commands to enable QIO or QOUT mode, then enables this mode.
*/
void bootloader_enable_qio_mode(void);
/**
* @brief Read flash ID by sending 0x9F command
* @return flash raw ID
* mfg_id = (ID >> 16) & 0xFF;
flash_id = ID & 0xffff;
*/
uint32_t bootloader_read_flash_id(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Configure clocks for early boot
*
* Called by bootloader, or by the app if the bootloader version is old (pre v2.1).
*/
void bootloader_clock_configure(void);
/** @brief Return the rated maximum frequency of this chip
*/
int bootloader_clock_get_rated_freq_mhz(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,295 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_flash_partitions.h"
#include "esp_image_format.h"
#ifdef __cplusplus
extern "C" {
#endif
// Type of hold a GPIO in low state
typedef enum {
GPIO_LONG_HOLD = 1, /*!< The long hold GPIO */
GPIO_SHORT_HOLD = -1, /*!< The short hold GPIO */
GPIO_NOT_HOLD = 0 /*!< If the GPIO input is not low */
} esp_comm_gpio_hold_t;
typedef enum {
ESP_IMAGE_BOOTLOADER,
ESP_IMAGE_APPLICATION
} esp_image_type;
/**
* @brief Check if the chip revision meets the image requirements.
*
* This function verifies whether the actual chip revision satisfies the minimum
* and optionally the maximum chip revision requirements specified in the image.
*
* @param image_header Pointer to the image header containing revision details.
* @param check_max_revision If true, also checks the maximum chip revision requirements.
*
* @return true if the chip revision meets the requirements, false otherwise.
*/
bool bootloader_common_check_chip_revision_validity(const esp_image_header_t *image_header, bool check_max_revision);
/**
* @brief Read ota_info partition and fill array from two otadata structures.
*
* @param[in] ota_info It is a pointer to the OTA data partition.
* The "otadata" partition (Type = "data" and SubType = "ota")
* is defined in the CSV partition table.
* @param[out] two_otadata Pointer to array of OTA selection structure.
* @return - ESP_OK: On success
* - ESP_ERR_NOT_FOUND: Partition table does not have otadata partition
* - ESP_FAIL: On failure
*/
esp_err_t bootloader_common_read_otadata(const esp_partition_pos_t *ota_info, esp_ota_select_entry_t *two_otadata);
/**
* @brief Calculate crc for the OTA data select.
*
* @param[in] s The OTA data select.
* @return Returns crc value.
*/
uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s);
/**
* @brief Verifies the validity of the OTA data select
*
* @param[in] s The OTA data select.
* @return Returns true on valid, false otherwise.
*/
bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s);
/**
* @brief Returns true if OTADATA is not marked as bootable partition.
*
* @param[in] s The OTA data select.
* @return Returns true if OTADATA invalid, false otherwise.
*/
bool bootloader_common_ota_select_invalid(const esp_ota_select_entry_t *s);
/**
* @brief Check if a GPIO input is held low for a long period, short period, or not
* at all.
*
* This function will configure the specified GPIO as an input with internal pull-up enabled.
*
* If the GPIO input is held low continuously for delay_sec period then it is a long hold.
* If the GPIO input is held low for less period then it is a short hold.
*
* @param[in] num_pin Number of the GPIO input.
* @param[in] delay_sec Input must be driven low for at least this long, continuously.
* @return esp_comm_gpio_hold_t Type of low level hold detected, if any.
*/
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec);
/**
* @brief Check if a GPIO input is held low or high for a long period, short period, or not
* at all.
*
* This function will configure the specified GPIO as an input with internal pull-up enabled.
*
* If the GPIO input is held at 'level' continuously for delay_sec period then it is a long hold.
* If the GPIO input is held at 'level' for less period then it is a short hold.
*
* @param[in] num_pin Number of the GPIO input.
* @param[in] delay_sec Input must be driven to 'level' for at least this long, continuously.
* @param[in] level Input pin level to trigger on hold
* @return esp_comm_gpio_hold_t Type of hold detected, if any.
*/
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio_level(uint32_t num_pin, uint32_t delay_sec, bool level);
/**
* @brief Erase the partition data that is specified in the transferred list.
*
* @param[in] list_erase String containing a list of cleared partitions. Like this "nvs, phy". The string must be null-terminal.
* @param[in] ota_data_erase If true then the OTA data partition will be cleared (if there is it in partition table).
* @return Returns true on success, false otherwise.
*/
bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_data_erase);
/**
* @brief Determines if the list contains the label
*
* @param[in] list A string of names delimited by commas or spaces. Like this "nvs, phy, data". The string must be null-terminated.
* @param[in] label The substring that will be searched in the list.
* @return Returns true if the list contains the label, false otherwise.
*/
bool bootloader_common_label_search(const char *list, char *label);
/**
* @brief Configure default SPI pin modes and drive strengths
*
* @param drv GPIO drive level (determined by clock frequency)
*/
void bootloader_configure_spi_pins(int drv);
/**
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
*
* This function can be used to return the SHA-256 digest of application, bootloader and data partitions.
* For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content.
* The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID.
* For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image.
* For other partition types, the result is the SHA-256 of the entire partition.
*
* @param[in] address Address of partition.
* @param[in] size Size of partition.
* @param[in] type Type of partition. For applications the type is 0, otherwise type is data.
* @param[out] out_sha_256 Returned SHA-256 digest for a given partition.
*
* @return
* - ESP_OK: In case of successful operation.
* - ESP_ERR_INVALID_ARG: The size was 0 or the sha_256 was NULL.
* - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation.
* - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image.
* - ESP_FAIL: An allocation error occurred.
*/
esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);
/**
* @brief Returns the number of active otadata.
*
* @param[in] two_otadata Pointer on array from two otadata structures.
*
* @return The number of active otadata (0 or 1).
* - -1: If it does not have active otadata.
*/
int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata);
/**
* @brief Returns the number of active otadata.
*
* @param[in] two_otadata Pointer on array from two otadata structures.
* @param[in] valid_two_otadata Pointer on array from two bools. True means select.
* @param[in] max True - will select the maximum ota_seq number, otherwise the minimum.
*
* @return The number of active otadata (0 or 1).
* - -1: If it does not have active otadata.
*/
int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max);
/**
* @brief Get chip package
*
* @return Chip package number
*/
uint32_t bootloader_common_get_chip_ver_pkg(void);
/**
* @brief Check if the image (bootloader and application) has valid chip ID and revision
*
* @param[in] img_hdr: image header
* @param[in] type: image type, bootloader or application
* @return
* - ESP_OK: image and chip are matched well
* - ESP_FAIL: image doesn't match to the chip
*/
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type);
#if !CONFIG_IDF_TARGET_ESP32
/**
* @brief Check the eFuse block revision
*
* @param[in] min_rev_full The required minimum revision of the eFuse block
* @param[in] max_rev_full The required maximum revision of the eFuse block
* @return
* - ESP_OK: The eFuse block revision is in the required range.
* - ESP_OK: DISABLE_BLK_VERSION_MAJOR has been set in the eFuse of the SoC. No requirements shall be checked at this time.
* - ESP_FAIL: The eFuse block revision of this chip does not match the requirement of the current image.
*/
esp_err_t bootloader_common_check_efuse_blk_validity(uint32_t min_rev_full, uint32_t max_rev_full);
#endif // !CONFIG_IDF_TARGET_ESP32
/**
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
*/
void bootloader_common_vddsdio_configure(void);
#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
/**
* @brief Returns partition from rtc_retain_mem
*
* Uses to get the partition of application which was worked before to go to the deep sleep.
* This partition was stored in rtc_retain_mem.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return partition: If rtc_retain_mem is valid.
* - NULL: If it is not valid.
*/
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void);
/**
* @brief Update the partition and reboot_counter in rtc_retain_mem.
*
* This function saves the partition of application for fast booting from the deep sleep.
* An algorithm uses this partition to avoid reading the otadata and does not validate an image.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @param[in] partition App partition description. Can be NULL, in this case rtc_retain_mem.partition is not updated.
* @param[in] reboot_counter If true then update reboot_counter.
*
*/
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter);
/**
* @brief Reset entire rtc_retain_mem.
*
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*/
void bootloader_common_reset_rtc_retain_mem(void);
/**
* @brief Returns reboot_counter from rtc_retain_mem
*
* The reboot_counter counts the number of reboots. Reset only when power is off.
* The very first launch of the application will be from 1.
* Overflow is not possible, it will stop at the value UINT16_MAX.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return reboot_counter: 1..65535
* - 0: If rtc_retain_mem is not valid.
*/
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void);
/**
* @brief Returns True if Factory reset has happened
*
* Reset the status after reading it.
*
* @return True: Factory reset has happened
* False: No Factory reset
*/
bool bootloader_common_get_rtc_retain_mem_factory_reset_state(void);
/**
* @brief Sets Factory reset status
*/
void bootloader_common_set_rtc_retain_mem_factory_reset_state(void);
/**
* @brief Returns rtc_retain_mem
*
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return rtc_retain_mem
*/
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void);
#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void bootloader_init_mem(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,244 @@
/*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc.h"
#include "soc/ext_mem_defs.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
/** The content of this file is to be kept in sync with the common section of esp_memory_utils.h **/
/**
* @brief Check if the IRAM and DRAM are separate or using the same memory space
*
* @return true if the DRAM and IRAM are sharing the same memory space, false otherwise
*/
__attribute__((always_inline))
inline static bool esp_dram_match_iram(void) {
return ((SOC_DRAM_LOW == SOC_IRAM_LOW) && (SOC_DRAM_HIGH == SOC_IRAM_HIGH));
}
/**
* @brief Check if the RTC IRAM and RTC DRAM are separate or using the same memory space
*
* @return true if the RTC DRAM and RTC IRAM are sharing the same memory space, false otherwise
*/
__attribute__((always_inline))
inline static bool esp_rtc_dram_match_rtc_iram(void) {
#if SOC_RTC_FAST_MEM_SUPPORTED
return ((SOC_RTC_IRAM_LOW == SOC_RTC_DRAM_LOW) && (SOC_RTC_IRAM_HIGH == SOC_RTC_DRAM_HIGH));
#else
return false;
#endif
}
/**
* @brief Check if the pointer is in iram
*
* @param p pointer
*
* @return true: is in iram; false: not in iram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_iram(const void *p) {
#if CONFIG_IDF_TARGET_ESP32 && CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH);
#else
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
#endif
}
/**
* @brief Check if the pointer is in dram
*
* @param p pointer
*
* @return true: is in dram; false: not in dram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_dram(const void *p) {
return ((intptr_t)p >= SOC_DRAM_LOW && (intptr_t)p < SOC_DRAM_HIGH);
}
/**
* @brief Check if the pointer is in diram_dram
*
* @param p pointer
*
* @return true: is in diram_dram; false: not in diram_dram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_diram_dram(const void *p) {
return ((intptr_t)p >= SOC_DIRAM_DRAM_LOW && (intptr_t)p < SOC_DIRAM_DRAM_HIGH);
}
/**
* @brief Check if the pointer is in diram_iram
*
* @param p pointer
*
* @return true: is in diram_iram; false: not in diram_iram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_diram_iram(const void *p) {
// TODO: IDF-5980 esp32c6 D/I RAM share the same address
#if SOC_DIRAM_IRAM_LOW == SOC_DIRAM_DRAM_LOW
(void)p;
return false;
#else
return ((intptr_t)p >= SOC_DIRAM_IRAM_LOW && (intptr_t)p < SOC_DIRAM_IRAM_HIGH);
#endif
}
/**
* @brief Check if the pointer is in rtc_iram_fast
*
* @param p pointer
*
* @return true: is in rtc_iram_fast; false: not in rtc_iram_fast
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
#if SOC_RTC_FAST_MEM_SUPPORTED
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
#else
(void)p;
return false;
#endif
}
/**
* @brief Check if the pointer is in rtc_dram_fast
*
* @param p pointer
*
* @return true: is in rtc_dram_fast; false: not in rtc_dram_fast
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_rtc_dram_fast(const void *p) {
#if SOC_RTC_FAST_MEM_SUPPORTED
return ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH);
#else
(void)p;
return false;
#endif
}
/**
* @brief Check if the pointer is in rtc_slow
*
* @param p pointer
*
* @return true: is in rtc_slow; false: not in rtc_slow
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_rtc_slow(const void *p) {
#if SOC_RTC_SLOW_MEM_SUPPORTED
return ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH);
#else
return false;
#endif
}
/* Convert a D/IRAM DRAM pointer to equivalent word address in IRAM
- Address must be word aligned
- Address must pass esp_ptr_in_diram_dram() test, or result will be invalid pointer
*/
__attribute__((always_inline))
inline static void * esp_ptr_diram_dram_to_iram(const void *p) {
#if SOC_DIRAM_INVERTED
return (void *) ( SOC_DIRAM_IRAM_LOW + (SOC_DIRAM_DRAM_HIGH - (intptr_t)p) - 4);
#else
return (void *) ( SOC_DIRAM_IRAM_LOW + ((intptr_t)p - SOC_DIRAM_DRAM_LOW) );
#endif
}
/* Convert a RTC DRAM pointer to equivalent word address in RTC IRAM
- Address must be word aligned
- Address must pass esp_ptr_in_rtc_dram_fast() test, or result will be invalid pointer
*/
__attribute__((always_inline))
inline static void * esp_ptr_rtc_dram_to_iram(const void *p) {
intptr_t ptr = (intptr_t)p;
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
return (void *) ( SOC_RTC_IRAM_LOW + (ptr - SOC_RTC_DRAM_LOW) );
#else
return (void *) ptr;
#endif
}
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
- Address must be word aligned
- Address must pass esp_ptr_in_diram_iram() test, or result will be invalid pointer
*/
__attribute__((always_inline))
inline static void * esp_ptr_diram_iram_to_dram(const void *p) {
#if SOC_DIRAM_INVERTED
return (void *) ( SOC_DIRAM_DRAM_LOW + (SOC_DIRAM_IRAM_HIGH - (intptr_t)p) - 4);
#else
return (void *) ( SOC_DIRAM_DRAM_LOW + ((intptr_t)p - SOC_DIRAM_IRAM_LOW) );
#endif
}
#if SOC_MEM_TCM_SUPPORTED
/**
* @brief Check if the pointer is in TCM
*
* @param p pointer
*
* @return true: is in TCM; false: not in TCM
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_tcm(const void *p) {
return ((intptr_t)p >= SOC_TCM_LOW && (intptr_t)p < SOC_TCM_HIGH);
}
#endif //#if SOC_MEM_TCM_SUPPORTED
/** End of the common section that has to be in sync with esp_memory_utils.h **/
/**
* @brief Check if the pointer is in PSRAM vaddr space
*
* @note This function is only used when in bootloader, where the PSRAM isn't initialised.
* This function simply check if the pointer is the in the PSRAM vaddr space.
* The PSRAM vaddr space is not always the same as the actual PSRAM vaddr range used in APP
*
* @param p pointer
*
* @return true: is in PSRAM; false: not in PSRAM
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_extram(const void *p) {
bool valid = false;
#if SOC_IRAM_PSRAM_ADDRESS_LOW
valid |= ((intptr_t)p >= SOC_IRAM_PSRAM_ADDRESS_LOW && (intptr_t)p < SOC_IRAM_PSRAM_ADDRESS_HIGH);
#endif
#if SOC_DRAM_PSRAM_ADDRESS_LOW
valid |= ((intptr_t)p >= SOC_DRAM_PSRAM_ADDRESS_LOW && (intptr_t)p < SOC_DRAM_PSRAM_ADDRESS_HIGH);
#endif
return valid;
}
/** Don't add new functions below **/
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Enable an entropy source for RNG if RF subsystem is disabled
*
* @warning This function is not safe to use if any other subsystem is accessing the RF subsystem or
* the ADC at the same time!
*
* The exact internal entropy source mechanism depends on the chip in use but
* all SoCs use the SAR ADC to continuously mix random bits (an internal
* noise reading) into the HWRNG. Consult the SoC Technical Reference
* Manual for more information.
*
* Can also be called from app code, if true random numbers are required without initialized RF subsystem.
* This might be the case in early startup code of the application when the RF subsystem has not
* started yet or if the RF subsystem should not be enabled for power saving.
*
* Consult ESP-IDF Programming Guide "Random Number Generation" section for
* details.
*/
void bootloader_random_enable(void);
/**
* @brief Disable entropy source for RNG
*
* Disables internal entropy source. Must be called after
* bootloader_random_enable() and before RF subsystem features, ADC, or
* I2S (ESP32 only) are initialized.
*
* Consult the ESP-IDF Programming Guide "Random Number Generation"
* section for details.
*/
void bootloader_random_disable(void);
/**
* @brief Fill buffer with 'length' random bytes
*
* @note If this function is being called from app code only, and never
* from the bootloader, then it's better to call esp_fill_random().
*
* @param buffer Pointer to buffer
* @param length This many bytes of random data will be copied to buffer
*/
void bootloader_fill_random(void *buffer, size_t length);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Check if half-open intervals overlap
*
* @param start1 interval 1 start
* @param end1 interval 1 end
* @param start2 interval 2 start
* @param end2 interval 2 end
* @return true iff [start1; end1) overlaps [start2; end2)
*/
static inline bool bootloader_util_regions_overlap(
const intptr_t start1, const intptr_t end1,
const intptr_t start2, const intptr_t end2)
{
assert(end1 > start1);
assert(end2 > start2);
return (end1 > start2 && end2 > start1);
}
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_flash_partitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Fetch the currently running TEE partition
*
* @param[in] tee_ota_info TEE OTA data partition
*
* @return Subtype of the running TEE partition, or -1 if an error occurred
*/
int bootloader_utility_tee_get_boot_partition(const esp_partition_pos_t *tee_ota_info);
/**
* @brief Set a new TEE boot partition in the TEE OTA data
*
* @param[in] tee_ota_info TEE OTA data partition
* @param[in] tee_try_part Partition table entry for the new boot partition
*
* @return ESP_OK on success, or an error code otherwise
*/
esp_err_t bootloader_utility_tee_set_boot_partition(const esp_partition_pos_t *tee_ota_info, const esp_partition_info_t *tee_try_part);
/**
* @brief Fetch the next TEE partition for update
*
* @param[in] tee_ota_info TEE OTA data partition
*
* @return Subtype of the next TEE partition for update, or -1 if an error occurred
*/
int bootloader_utility_tee_get_next_update_partition(const esp_partition_pos_t *tee_ota_info);
/**
* @brief Mark the current TEE app as valid and cancel update rollback
*
* @param[in] tee_ota_info TEE OTA data partition
*
* @return ESP_OK on success, or an error code otherwise
*/
esp_err_t bootloader_utility_tee_mark_app_valid_and_cancel_rollback(const esp_partition_pos_t *tee_ota_info);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,126 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <inttypes.h>
#include "esp_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief ESP chip ID
*
*/
typedef enum {
ESP_CHIP_ID_ESP32 = 0x0000, /*!< chip ID: ESP32 */
ESP_CHIP_ID_ESP32S2 = 0x0002, /*!< chip ID: ESP32-S2 */
ESP_CHIP_ID_ESP32C3 = 0x0005, /*!< chip ID: ESP32-C3 */
ESP_CHIP_ID_ESP32S3 = 0x0009, /*!< chip ID: ESP32-S3 */
ESP_CHIP_ID_ESP32C2 = 0x000C, /*!< chip ID: ESP32-C2 */
ESP_CHIP_ID_ESP32C6 = 0x000D, /*!< chip ID: ESP32-C6 */
ESP_CHIP_ID_ESP32H2 = 0x0010, /*!< chip ID: ESP32-H2 */
ESP_CHIP_ID_ESP32P4 = 0x0012, /*!< chip ID: ESP32-P4 */
ESP_CHIP_ID_ESP32C5 = 0x0017, /*!< chip ID: ESP32-C5 */
ESP_CHIP_ID_ESP32C61= 0x0014, /*!< chip ID: ESP32-C61 */
ESP_CHIP_ID_ESP32H21= 0x0019, /*!< chip ID: ESP32-H21 */
ESP_CHIP_ID_ESP32H4 = 0x001C, /*!< chip ID: ESP32-H4 */
ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */
} __attribute__((packed)) esp_chip_id_t;
/** @cond */
ESP_STATIC_ASSERT(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
/** @endcond */
/**
* @brief SPI flash mode, used in esp_image_header_t
*/
typedef enum {
ESP_IMAGE_SPI_MODE_QIO, /*!< SPI mode QIO */
ESP_IMAGE_SPI_MODE_QOUT, /*!< SPI mode QOUT */
ESP_IMAGE_SPI_MODE_DIO, /*!< SPI mode DIO */
ESP_IMAGE_SPI_MODE_DOUT, /*!< SPI mode DOUT */
ESP_IMAGE_SPI_MODE_FAST_READ, /*!< SPI mode FAST_READ */
ESP_IMAGE_SPI_MODE_SLOW_READ /*!< SPI mode SLOW_READ */
} esp_image_spi_mode_t;
/**
* @brief SPI flash clock division factor.
*/
typedef enum {
ESP_IMAGE_SPI_SPEED_DIV_2, /*!< The SPI flash clock frequency is divided by 2 of the clock source */
ESP_IMAGE_SPI_SPEED_DIV_3, /*!< The SPI flash clock frequency is divided by 3 of the clock source */
ESP_IMAGE_SPI_SPEED_DIV_4, /*!< The SPI flash clock frequency is divided by 4 of the clock source */
ESP_IMAGE_SPI_SPEED_DIV_1 = 0xF /*!< The SPI flash clock frequency equals to the clock source */
} esp_image_spi_freq_t;
/**
* @brief Supported SPI flash sizes
*/
typedef enum {
ESP_IMAGE_FLASH_SIZE_1MB = 0, /*!< SPI flash size 1 MB */
ESP_IMAGE_FLASH_SIZE_2MB, /*!< SPI flash size 2 MB */
ESP_IMAGE_FLASH_SIZE_4MB, /*!< SPI flash size 4 MB */
ESP_IMAGE_FLASH_SIZE_8MB, /*!< SPI flash size 8 MB */
ESP_IMAGE_FLASH_SIZE_16MB, /*!< SPI flash size 16 MB */
ESP_IMAGE_FLASH_SIZE_32MB, /*!< SPI flash size 32 MB */
ESP_IMAGE_FLASH_SIZE_64MB, /*!< SPI flash size 64 MB */
ESP_IMAGE_FLASH_SIZE_128MB, /*!< SPI flash size 128 MB */
ESP_IMAGE_FLASH_SIZE_MAX /*!< SPI flash size MAX */
} esp_image_flash_size_t;
#define ESP_IMAGE_HEADER_MAGIC 0xE9 /*!< The magic word for the esp_image_header_t structure. */
/**
* @brief Main header of binary image
*/
typedef struct {
uint8_t magic; /*!< Magic word ESP_IMAGE_HEADER_MAGIC */
uint8_t segment_count; /*!< Count of memory segments */
uint8_t spi_mode; /*!< flash read mode (esp_image_spi_mode_t as uint8_t) */
uint8_t spi_speed: 4; /*!< flash frequency (esp_image_spi_freq_t as uint8_t) */
uint8_t spi_size: 4; /*!< flash chip size (esp_image_flash_size_t as uint8_t) */
uint32_t entry_addr; /*!< Entry address */
uint8_t wp_pin; /*!< WP pin when SPI pins set via efuse (read by ROM bootloader,
* the IDF bootloader uses software to configure the WP
* pin and sets this field to 0xEE=disabled) */
uint8_t spi_pin_drv[3]; /*!< Drive settings for the SPI flash pins (read by ROM bootloader) */
esp_chip_id_t chip_id; /*!< Chip identification number */
uint8_t min_chip_rev; /*!< Minimal chip revision supported by image
* After the Major and Minor revision eFuses were introduced into the chips, this field is no longer used.
* But for compatibility reasons, we keep this field and the data in it.
* Use min_chip_rev_full instead.
* The software interprets this as a Major version for most of the chips and as a Minor version for the ESP32-C3.
*/
uint16_t min_chip_rev_full; /*!< Minimal chip revision supported by image, in format: major * 100 + minor */
uint16_t max_chip_rev_full; /*!< Maximal chip revision supported by image, in format: major * 100 + minor */
uint8_t reserved[4]; /*!< Reserved bytes in additional header space, currently unused */
uint8_t hash_appended; /*!< If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum.
* Included in image length. This digest
* is separate to secure boot and only used for detecting corruption.
* For secure boot signed images, the signature
* is appended after this (and the simple hash is included in the signed data). */
} __attribute__((packed)) esp_image_header_t;
/** @cond */
ESP_STATIC_ASSERT(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes");
/** @endcond */
/**
* @brief Header of binary image segment
*/
typedef struct {
uint32_t load_addr; /*!< Address of segment */
uint32_t data_len; /*!< Length of data */
} esp_image_segment_header_t;
#define ESP_IMAGE_MAX_SEGMENTS 16 /*!< Max count of segments in the image. */
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#warning esp_flash_data_types.h has been merged into esp_flash_partitions.h, please include esp_flash_partitions.h instead
#include "esp_flash_partitions.h"
@@ -0,0 +1,227 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "esp_err.h"
#include "soc/soc_caps.h"
#include "hal/efuse_ll.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
/* @brief Flash encryption mode based on efuse values
*/
typedef enum {
ESP_FLASH_ENC_MODE_DISABLED, // flash encryption is not enabled (flash crypt cnt=0)
ESP_FLASH_ENC_MODE_DEVELOPMENT, // flash encryption is enabled but for Development (reflash over UART allowed)
ESP_FLASH_ENC_MODE_RELEASE // flash encryption is enabled for Release (reflash over UART disabled)
} esp_flash_enc_mode_t;
/**
* @file esp_partition.h
* @brief Support functions for flash encryption features
*
* Can be compiled as part of app or bootloader code.
*/
/** @brief Is flash encryption currently enabled in hardware?
*
* Flash encryption is enabled if the FLASH_CRYPT_CNT efuse has an odd number of bits set.
*
* @return true if flash encryption is enabled.
*/
bool esp_flash_encryption_enabled(void);
/* @brief Update on-device flash encryption
*
* Intended to be called as part of the bootloader process if flash
* encryption is enabled in device menuconfig.
*
* If FLASH_CRYPT_CNT efuse parity is 1 (ie odd number of bits set),
* then return ESP_OK immediately (indicating flash encryption is enabled
* and functional).
*
* If FLASH_CRYPT_CNT efuse parity is 0 (ie even number of bits set),
* assume the flash has just been written with plaintext that needs encrypting.
*
* The following regions of flash are encrypted in place:
*
* - The bootloader image, if a valid plaintext image is found.[*]
* - The partition table, if a valid plaintext table is found.
* - Any app partition that contains a valid plaintext app image.
* - Any other partitions with the "encrypt" flag set. [**]
*
* After the re-encryption process completes, a '1' bit is added to the
* FLASH_CRYPT_CNT value (setting the parity to 1) and the EFUSE is re-burned.
*
* [*] If reflashing bootloader with secure boot enabled, pre-encrypt
* the bootloader before writing it to flash or secure boot will fail.
*
* [**] For this reason, if serial re-flashing a previous flashed
* device with secure boot enabled and using FLASH_CRYPT_CNT to
* trigger re-encryption, you must simultaneously re-flash plaintext
* content to all partitions with the "encrypt" flag set or this
* data will be corrupted (encrypted twice).
*
* @note The post-condition of this function is that all
* partitions that should be encrypted are encrypted.
*
* @note Take care not to power off the device while this function
* is running, or the partition currently being encrypted will be lost.
*
* @note RTC_WDT will reset while encryption operations will be performed (if RTC_WDT is configured).
*
* @return ESP_OK if all operations succeeded, ESP_ERR_INVALID_STATE
* if a fatal error occurred during encryption of all partitions.
*/
esp_err_t esp_flash_encrypt_check_and_update(void);
/** @brief Returns the Flash Encryption state and prints it
*
* @return True - Flash Encryption is enabled
* False - Flash Encryption is not enabled
*/
bool esp_flash_encrypt_state(void);
/** @brief Checks if the first initialization was done
*
* If the first initialization was done then FLASH_CRYPT_CNT != 0
*
* @return true - the first initialization was done
* false - the first initialization was NOT done
*/
bool esp_flash_encrypt_initialized_once(void);
/** @brief The first initialization of Flash Encryption key and related eFuses
*
* @return ESP_OK if all operations succeeded
*/
esp_err_t esp_flash_encrypt_init(void);
/** @brief Encrypts flash content
*
* @return ESP_OK if all operations succeeded
*/
esp_err_t esp_flash_encrypt_contents(void);
/** @brief Activates Flash encryption on the chip
*
* It burns FLASH_CRYPT_CNT eFuse based on the CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE option.
*
* @return ESP_OK if all operations succeeded
*/
esp_err_t esp_flash_encrypt_enable(void);
/** @brief Returns True if the write protection of FLASH_CRYPT_CNT is set
*
* @param print_error Print error if it is write protected
*
* @return true - if FLASH_CRYPT_CNT is write protected
*/
bool esp_flash_encrypt_is_write_protected(bool print_error);
/** @brief Encrypt-in-place a block of flash sectors
*
* @note This function resets RTC_WDT between operations with sectors.
* @param src_addr Source offset in flash. Should be multiple of 4096 bytes.
* @param data_length Length of data to encrypt in bytes. Will be rounded up to next multiple of 4096 bytes.
*
* @return ESP_OK if all operations succeeded, ESP_ERR_FLASH_OP_FAIL
* if SPI flash fails, ESP_ERR_FLASH_OP_TIMEOUT if flash times out.
*/
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
/** @brief Write protect FLASH_CRYPT_CNT
*
* Intended to be called as a part of boot process if flash encryption
* is enabled but secure boot is not used. This should protect against
* serial re-flashing of an unauthorised code in absence of secure boot.
*
* @note On ESP32 V3 only, write protecting FLASH_CRYPT_CNT will also prevent
* disabling UART Download Mode. If both are wanted, call
* esp_efuse_disable_rom_download_mode() before calling this function.
*
*/
void esp_flash_write_protect_crypt_cnt(void);
/** @brief Return the flash encryption mode
*
* The API is called during boot process but can also be called by
* application to check the current flash encryption mode of ESP32
*
* @return
*/
esp_flash_enc_mode_t esp_get_flash_encryption_mode(void);
/** @brief Check the flash encryption mode during startup
*
* @note This function is called automatically during app startup,
* it doesn't need to be called from the app.
*
* Verifies the flash encryption config during startup:
*
* - Correct any insecure flash encryption settings if hardware
* Secure Boot is enabled.
* - Log warnings if the efuse config doesn't match the project
* config in any way
*/
void esp_flash_encryption_init_checks(void);
#if BOOTLOADER_BUILD && CONFIG_SECURE_FLASH_ENC_ENABLED
/** @brief Set all secure eFuse features related to flash encryption
*
* @return
* - ESP_OK - On success
*/
esp_err_t esp_flash_encryption_enable_secure_features(void);
#if CONFIG_SOC_KEY_MANAGER_FE_KEY_DEPLOY
/** @brief Enable the key manager for flash encryption
*
* @return
* - ESP_OK - On success
*/
esp_err_t esp_flash_encryption_enable_key_mgr(void);
#endif // CONFIG_SOC_KEY_MANAGER_FE_KEY_DEPLOY
#endif /* BOOTLOADER_BUILD && CONFIG_SECURE_FLASH_ENC_ENABLED */
/** @brief Returns the verification status for all physical security features of flash encryption in release mode
*
* If the device has flash encryption feature configured in the release mode,
* then it is highly recommended to call this API in the application startup code.
* This API verifies the sanity of the eFuse configuration against
* the release (production) mode of the flash encryption feature.
*
* @return
* - True - all eFuses are configured correctly
* - False - not all eFuses are configured correctly.
*/
bool esp_flash_encryption_cfg_verify_release_mode(void);
/** @brief Switches Flash Encryption from "Development" to "Release"
*
* If already in "Release" mode, the function will do nothing.
* If flash encryption efuse is not enabled yet then abort.
* It burns:
* - "disable encrypt in dl mode"
* - set FLASH_CRYPT_CNT efuse to max
*
* In case of the targets that support the XTS-AES peripheral's pseudo rounds function,
* this API would configure the pseudo rounds level efuse bit to level low if the efuse bit
* is not set already.
*/
void esp_flash_encryption_set_release_mode(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,135 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#include "esp_types.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_PARTITION_MAGIC 0x50AA
#define ESP_PARTITION_MAGIC_MD5 0xEBEB
#define PART_TYPE_APP 0x00
#define PART_SUBTYPE_FACTORY 0x00
#define PART_SUBTYPE_OTA_FLAG 0x10
#define PART_SUBTYPE_OTA_MASK 0x0f
#define PART_SUBTYPE_TEST 0x20
#define PART_SUBTYPE_TEE_0 0x30
#define PART_SUBTYPE_TEE_1 0x31
#define PART_TYPE_DATA 0x01
#define PART_SUBTYPE_DATA_OTA 0x00
#define PART_SUBTYPE_DATA_RF 0x01
#define PART_SUBTYPE_DATA_WIFI 0x02
#define PART_SUBTYPE_DATA_NVS_KEYS 0x04
#define PART_SUBTYPE_DATA_EFUSE_EM 0x05
#define PART_TYPE_BOOTLOADER 0x02
#define PART_SUBTYPE_BOOTLOADER_PRIMARY 0x00
#define PART_SUBTYPE_BOOTLOADER_OTA 0x01
#define PART_SUBTYPE_BOOTLOADER_RECOVERY 0x02
#define PART_TYPE_PARTITION_TABLE 0x03
#define PART_SUBTYPE_PARTITION_TABLE_PRIMARY 0x00
#define PART_SUBTYPE_PARTITION_TABLE_OTA 0x01
#define PART_SUBTYPE_DATA_TEE_OTA 0x90
#define PART_TYPE_END 0xff
#define PART_SUBTYPE_END 0xff
#define PART_FLAG_ENCRYPTED (1<<0)
#define PART_FLAG_READONLY (1<<1)
/* The md5sum value is found this many bytes after the ESP_PARTITION_MAGIC_MD5 offset */
#define ESP_PARTITION_MD5_OFFSET 16
/* Pre-partition table fixed flash offsets */
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
#define ESP_BOOTLOADER_OFFSET CONFIG_BOOTLOADER_OFFSET_IN_FLASH /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
#define ESP_PRIMARY_BOOTLOADER_OFFSET CONFIG_BOOTLOADER_OFFSET_IN_FLASH /* Offset of Primary bootloader image. */
#define ESP_PARTITION_TABLE_OFFSET CONFIG_PARTITION_TABLE_OFFSET /* Offset of partition table. Backwards-compatible name.*/
#define ESP_PRIMARY_PARTITION_TABLE_OFFSET CONFIG_PARTITION_TABLE_OFFSET /* Offset of partition table. */
#define ESP_PARTITION_TABLE_SIZE (0x1000) /* The partition table occupies 1 sector of flash (SPI_FLASH_SEC_SIZE) */
#define ESP_BOOTLOADER_SIZE (ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET)
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
/// OTA_DATA states for checking operability of the app.
typedef enum {
ESP_OTA_IMG_NEW = 0x0U, /*!< Monitor the first boot. In bootloader this state is changed to ESP_OTA_IMG_PENDING_VERIFY. */
ESP_OTA_IMG_PENDING_VERIFY = 0x1U, /*!< First boot for this app was. If while the second boot this state is then it will be changed to ABORTED. */
ESP_OTA_IMG_VALID = 0x2U, /*!< App was confirmed as workable. App can boot and work without limits. */
ESP_OTA_IMG_INVALID = 0x3U, /*!< App was confirmed as non-workable. This app will not selected to boot at all. */
ESP_OTA_IMG_ABORTED = 0x4U, /*!< App could not confirm the workable or non-workable. In bootloader IMG_PENDING_VERIFY state will be changed to IMG_ABORTED. This app will not selected to boot at all. */
ESP_OTA_IMG_UNDEFINED = 0xFFFFFFFFU, /*!< Undefined. App can boot and work without limits. */
} esp_ota_img_states_t;
/* OTA selection structure (two copies in the OTA data partition.)
Size of 32 bytes is friendly to flash encryption */
typedef struct {
uint32_t ota_seq;
uint8_t seq_label[20];
uint32_t ota_state;
uint32_t crc; /* CRC32 of ota_seq field only */
} esp_ota_select_entry_t;
typedef struct {
uint32_t offset;
uint32_t size;
} esp_partition_pos_t;
/* Structure which describes the layout of partition table entry.
* See docs/partition_tables.rst for more information about individual fields.
*/
typedef struct {
uint16_t magic;
uint8_t type;
uint8_t subtype;
esp_partition_pos_t pos;
uint8_t label[16];
uint32_t flags;
} esp_partition_info_t;
/* @brief Verify the partition table
*
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
* @param log_errors Log errors if the partition table is invalid.
* @param num_partitions If result is ESP_OK, num_partitions is updated with total number of partitions (not including terminating entry).
*
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
*/
esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
/**
* Check whether the region on the main flash is not read-only.
*
* @param addr Start address of the region
* @param size Size of the region
*
* @return true if the region is safe to write, otherwise false.
*/
bool esp_partition_is_flash_region_writable(size_t addr, size_t size);
/**
* Check whether the region on the main flash is safe to write.
*
* @param addr Start address of the region
* @param size Size of the region
*
* @return true if the region is safe to write, otherwise false.
*/
bool esp_partition_main_flash_region_safe(size_t addr, size_t size);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,232 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <esp_err.h>
#include "esp_flash_partitions.h"
#include "esp_app_format.h"
#include "esp_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_ERR_IMAGE_BASE 0x2000
#define ESP_ERR_IMAGE_FLASH_FAIL (ESP_ERR_IMAGE_BASE + 1)
#define ESP_ERR_IMAGE_INVALID (ESP_ERR_IMAGE_BASE + 2)
/* Support for app/bootloader image parsing
Can be compiled as part of app or bootloader code.
*/
#define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */
/* Structure to hold on-flash image metadata */
typedef struct {
uint32_t start_addr; /* Start address of image */
esp_image_header_t image; /* Header for entire image */
esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
uint32_t image_len; /* Length of image on flash, in bytes */
uint8_t image_digest[32]; /* appended SHA-256 digest */
uint32_t secure_version; /* secure version for anti-rollback, it is covered by sha256 (set if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y) */
uint32_t mmu_page_size; /* Flash MMU page size per binary header */
} esp_image_metadata_t;
typedef enum {
ESP_IMAGE_VERIFY, /* Verify image contents, not load to memory, load metadata. Print errors. */
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, not load to memory, load metadata. Don't print errors. */
#ifdef BOOTLOADER_BUILD
ESP_IMAGE_LOAD, /* Verify image contents, load to memory, load metadata. Print errors. */
ESP_IMAGE_LOAD_NO_VALIDATE, /* Not verify image contents, load to memory, load metadata. Print errors. */
#endif
} esp_image_load_mode_t;
typedef struct {
esp_partition_pos_t partition; /*!< Partition of application which worked before goes to the deep sleep. */
uint16_t reboot_counter; /*!< Reboot counter. Reset only when power is off. */
union {
struct {
uint8_t factory_reset_state : 1; /* True when Factory reset has occurred */
uint8_t reserve : 7; /* Reserve */
};
uint8_t val;
} flags;
uint8_t reserve; /*!< Reserve */
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
uint8_t custom[CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE]; /*!< Reserve for custom propose */
#endif
uint32_t crc; /*!< Check sum crc32 */
} rtc_retain_mem_t;
ESP_STATIC_ASSERT(offsetof(rtc_retain_mem_t, crc) == sizeof(rtc_retain_mem_t) - sizeof(uint32_t), "CRC field must be the last field of rtc_retain_mem_t structure");
#ifdef CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
/* The custom field must be the penultimate field */
ESP_STATIC_ASSERT(offsetof(rtc_retain_mem_t, custom) == sizeof(rtc_retain_mem_t) - sizeof(uint32_t) - CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE,
"custom field in rtc_retain_mem_t structure must be the field before the CRC one");
#endif
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif
ESP_STATIC_ASSERT(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM
/**
* @brief Verify an app/bootloader image.
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param mode Mode of operation (verify, silent verify, or load).
* @param part Partition to load the app/bootloader from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Get metadata of app/bootloader
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app/bootloader from.
* @param[out] metadata Pointer to the image metadata structure which is be filled in by this function.
* Fields will all be initialised by this function.
*
* @return
* - ESP_OK if filling of metadata was successful
*/
esp_err_t esp_image_get_metadata(const esp_partition_pos_t *part, esp_image_metadata_t *metadata);
/**
* @brief Verify and load an app image (available only in space of bootloader).
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Load an app image without verification (available only in space of bootloader).
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Verify the PRIMARY bootloader image.
*
* @param[out] If result is ESP_OK and this pointer is non-NULL, it
* will be set to the length of the bootloader image.
*
* @return As per esp_image_load_metadata().
*/
esp_err_t esp_image_verify_bootloader(uint32_t *length);
/**
* @brief Verify the PRIMARY bootloader image.
*
* @param[out] Metadata for the image. Only valid if result is ESP_OK.
*
* @return As per esp_image_load_metadata().
*/
esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data);
/**
* @brief Get the flash size of the image
*
* @param app_flash_size The value configured in the image header
* @return Actual size, in bytes.
*/
int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size);
/**
* @brief Get the ota bootloader offset
*
* The esp_image_verify functions use the offset to distinguish between application and bootloader verifications.
* The application must set the OTA bootloader offset before running any verification functions for the OTA bootloader partition.
*
* @return ota Bootloader offset. UINT32_MAX - not set.
*/
uint32_t esp_image_bootloader_offset_get(void);
/**
* @brief Set the ota bootloader offset
*
* The esp_image_verify functions use the offset to distinguish between application and bootloader verifications.
* The application must set the OTA bootloader offset before running any verification functions for the OTA bootloader partition.
*
* @param offset ota Bootloader offset
*/
void esp_image_bootloader_offset_set(const uint32_t offset);
typedef struct {
uint32_t drom_addr;
uint32_t drom_load_addr;
uint32_t drom_size;
uint32_t irom_addr;
uint32_t irom_load_addr;
uint32_t irom_size;
} esp_image_flash_mapping_t;
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,391 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <esp_err.h>
#include "soc/efuse_periph.h"
#include "soc/soc_caps.h"
#include "esp_image_format.h"
#include "esp_rom_efuse.h"
#include "sdkconfig.h"
#include "esp_rom_crc.h"
#include "hal/efuse_ll.h"
#if !CONFIG_IDF_TARGET_LINUX
#include "rom/secure_boot.h"
#endif
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED
#if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS)
#error "internal sdkconfig error, secure boot should always enable all signature options"
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Support functions for secure boot features.
Can be compiled as part of app or bootloader code.
*/
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
#define ESP_SECURE_BOOT_DIGEST_LEN 48
#else /* !CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */
#define ESP_SECURE_BOOT_DIGEST_LEN 32
#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */
/* SHA-256 length of the public key digest */
#define ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN 32
/* Length of the public key digest that is stored in efuses */
#if CONFIG_IDF_TARGET_ESP32C2
#define ESP_SECURE_BOOT_KEY_DIGEST_LEN ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN / 2
#else
#define ESP_SECURE_BOOT_KEY_DIGEST_LEN ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN
#endif
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#endif
/**
* @brief Secure Boot Signature Block Version field
*/
typedef enum {
ESP_SECURE_BOOT_V1_ECDSA = 0, /*!< Secure Boot v1 */
ESP_SECURE_BOOT_V2_RSA = 2, /*!< Secure Boot v2 with RSA key */
ESP_SECURE_BOOT_V2_ECDSA = 3, /*!< Secure Boot v2 with ECDSA key */
} esp_secure_boot_sig_scheme_t;
#if CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
#define ESP_SECURE_BOOT_SCHEME ESP_SECURE_BOOT_V1_ECDSA
#elif CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
#define ESP_SECURE_BOOT_SCHEME ESP_SECURE_BOOT_V2_RSA
#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
#define ESP_SECURE_BOOT_SCHEME ESP_SECURE_BOOT_V2_ECDSA
#endif
#if CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
/** @brief Get the selected secure boot scheme key type
*
* @return key type for the selected secure boot scheme
*/
static inline const char* esp_secure_boot_get_scheme_name(esp_secure_boot_sig_scheme_t scheme)
{
switch (scheme) {
case ESP_SECURE_BOOT_V2_RSA:
return "RSA";
case ESP_SECURE_BOOT_V1_ECDSA:
case ESP_SECURE_BOOT_V2_ECDSA:
return "ECDSA";
default:
return "Unknown";
}
}
#endif
/** @brief Is secure boot currently enabled in hardware?
*
* This means that the ROM bootloader code will only boot
* a verified secure bootloader from now on.
*
* @return true if secure boot is enabled.
*/
static inline bool esp_secure_boot_enabled(void)
{
#if CONFIG_IDF_TARGET_ESP32
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
return efuse_ll_get_secure_boot_v1_en();
#else
return esp_efuse_read_field_bit(ESP_EFUSE_ABS_DONE_0);
#endif
#elif CONFIG_SECURE_BOOT_V2_ENABLED
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
return efuse_ll_get_secure_boot_v2_en();
#else
return esp_efuse_read_field_bit(ESP_EFUSE_ABS_DONE_1);
#endif
#endif
#else
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
return efuse_ll_get_secure_boot_v2_en();
#else
return esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
#endif
#endif
return false; /* Secure Boot not enabled in menuconfig */
}
/** @brief Generate secure digest from bootloader image
*
* @important This function is intended to be called from bootloader code only.
*
* This function is only used in the context of the Secure Boot V1 scheme.
*
* If secure boot is not yet enabled for bootloader, this will:
* 1) generate the secure boot key and burn it on EFUSE
* (without enabling R/W protection)
* 2) generate the digest from bootloader and save it
* to flash address 0x0
*
* If first boot gets interrupted after calling this function
* but before esp_secure_boot_permanently_enable() is called, then
* the key burned on EFUSE will not be regenerated, unless manually
* done using espefuse.py tool
*
* @return ESP_OK if secure boot digest is generated
* successfully or found to be already present
*/
esp_err_t esp_secure_boot_generate_digest(void);
/** @brief Enable secure boot V1 if it is not already enabled.
*
* @important If this function succeeds, secure boot V1 is permanently
* enabled on the chip via efuse.
*
* @important This function is intended to be called from bootloader code only.
*
* @important In case of Secure Boot V1, this will enable r/w protection
* of secure boot key on EFUSE, therefore it is to be ensured that
* esp_secure_boot_generate_digest() is called before this .If secure boot is not
* yet enabled for bootloader, this will
* 1) enable R/W protection of secure boot key on EFUSE
* 2) enable secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse.
*
* This function does not verify secure boot of the bootloader (the
* ROM bootloader does this.)
*
* Will fail if efuses have been part-burned in a way that indicates
* secure boot should not or could not be correctly enabled.
*
* @return ESP_ERR_INVALID_STATE if efuse state doesn't allow
* secure boot to be enabled cleanly. ESP_OK if secure boot
* is enabled on this chip from now on.
*/
esp_err_t esp_secure_boot_permanently_enable(void);
/** @brief Enables secure boot V2 if it is not already enabled.
*
* @important If this function succeeds, secure boot V2 is permanently
* enabled on the chip via efuse.
*
* @important This function is intended to be called from bootloader code only.
*
* @important In case of Secure Boot V2, this will enable write protection
* of secure boot key on EFUSE in BLK2. .If secure boot is not
* yet enabled for bootloader, this will
* 1) enable W protection of secure boot key on EFUSE
* 2) enable secure boot by blowing the EFUSE_RD_ABS_DONE_1 efuse.
*
* This function does not verify secure boot of the bootloader (the
* ROM bootloader does this.)
*
* @param image_data Image metadata of the application to be loaded.
*
* Will fail if efuses have been part-burned in a way that indicates
* secure boot should not or could not be correctly enabled.
*
* @return ESP_ERR_INVALID_STATE if efuse state doesn't allow
* secure boot to be enabled cleanly. ESP_OK if secure boot
* is enabled on this chip from now on.
*/
esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *image_data);
/** @brief Verify the secure boot signature appended to some binary data in flash.
*
* For ECDSA Scheme (Secure Boot V1) - deterministic ECDSA w/ SHA256 image
* For RSA Scheme (Secure Boot V2) - RSA-PSS Verification of the SHA-256 image digest
* For ECDSA Scheme (Secure Boot V2) - ECDSA Verification of the SHA-256 / SHA-384 (in case of ECDSA-P384 secure boot key) image digest
*
* Public key is compiled into the calling program in the ECDSA Scheme.
* See the apt docs/security/secure-boot-v1.rst or docs/security/secure-boot-v2.rst for details.
*
* @param src_addr Starting offset of the data in flash.
* @param length Length of data in bytes. Signature is appended -after- length bytes.
*
* If flash encryption is enabled, the image will be transparently decrypted while being verified.
*
* @note This function doesn't have any fault injection resistance so should not be called
* during a secure boot itself (but can be called when verifying an update, etc.)
*
* @return ESP_OK if signature is valid, ESP_ERR_INVALID_STATE if
* signature fails, ESP_FAIL for other failures (ie can't read flash).
*/
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length);
/** @brief Secure boot verification block, on-flash data format. */
typedef struct {
uint32_t version;
uint8_t signature[64];
} esp_secure_boot_sig_block_t;
/** @brief Get the size of the secure boot signature block
*
* This is the size of the signature block appended to a signed image.
*
* @return Size of the secure boot signature block in bytes
*/
static inline uint32_t esp_secure_boot_sig_block_size(void)
{
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
return sizeof(ets_secure_boot_signature_t);
#elif defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
return sizeof(esp_secure_boot_sig_block_t);
#else
return 0;
#endif
}
/** @brief Verify the ECDSA secure boot signature block for Secure Boot V1.
*
* Calculates Deterministic ECDSA w/ SHA256 based on the SHA256 hash of the image. ECDSA signature
* verification must be enabled in project configuration to use this function.
*
* Similar to esp_secure_boot_verify_signature(), but can be used when the digest is precalculated.
* @param sig_block Pointer to ECDSA signature block data
* @param image_digest Pointer to 32 byte buffer holding SHA-256 hash.
* @param verified_digest Pointer to 32 byte buffer that will receive verified digest if verification completes. (Used during bootloader implementation only, result is invalid otherwise.)
*
*/
esp_err_t esp_secure_boot_verify_ecdsa_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest);
#if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_FULL >= 300
#if CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
/** @brief Verify the secure boot signature block for Secure Boot V2.
*
* Performs RSA-PSS or ECDSA verification of the SHA-256 / SHA-384 image based on the public key
* in the signature block, compared against the public key digest stored in efuse.
*
* Similar to esp_secure_boot_verify_signature(), but can be used when the digest is precalculated.
* @param[in] sig_block Pointer to signature block data
* @param[in] image_digest Pointer to 32/48 byte buffer holding SHA-256/SHA-384 hash.
* @param[out] verified_digest Pointer to 32/48 byte buffer that will receive verified digest if verification completes. (Used during bootloader implementation only, result is invalid otherwise.)
*
*/
esp_err_t esp_secure_boot_verify_sbv2_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest);
#endif /* CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT */
/**
* @brief Structure to hold public key digests calculated from the signature blocks of a single image.
*
* Each image can have one or more signature blocks (up to SECURE_BOOT_NUM_BLOCKS). Each signature block includes a public key.
*/
typedef struct {
uint8_t key_digests[SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS][ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN]; /* SHA of the public key components in the signature block */
unsigned num_digests; /* Number of valid digests, starting at index 0 */
} esp_image_sig_public_key_digests_t;
#endif // !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_FULL >= 300
/** @brief Legacy ECDSA verification function
*
* @note Deprecated, call either esp_secure_boot_verify_ecdsa_signature_block() or esp_secure_boot_verify_rsa_signature_block() instead.
*
* @param sig_block Pointer to ECDSA signature block data
* @param image_digest Pointer to 32 byte buffer holding SHA-256 hash.
*/
esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest)
__attribute__((deprecated("use esp_secure_boot_verify_ecdsa_signature_block instead")));
#define FLASH_OFFS_SECURE_BOOT_IV_DIGEST 0
/** @brief Secure boot IV+digest header */
typedef struct {
uint8_t iv[128];
uint8_t digest[64];
} esp_secure_boot_iv_digest_t;
/** @brief Check the secure boot V2 during startup
*
* @note This function is called automatically during app startup,
* it doesn't need to be called from the app.
*
* Verifies the secure boot config during startup:
*
* - Correct any insecure secure boot settings
*/
void esp_secure_boot_init_checks(void);
#if !BOOTLOADER_BUILD && (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
/** @brief Scan the current running app for signature blocks
*
* @note This function doesn't verify that the signatures are valid or the
* corresponding public keys are trusted, it only reads the number of signature
* blocks present and optionally calculates the digests of the public keys
* provided in the signature blocks.
*
* @param digest_public_keys If true, the key_digests fields in the
* public_key_digests structure will be filled with the digests of the public
* key provided in each signature block. Note that if Secure Boot V2 is enabled,
* each public key will only be trusted if the same digest is also present in
* eFuse (but this is not checked by this function).
*
* @param public_key_digests[out] Structure is initialized with the num_digests
* field set to the number of signatures found. If digest_public_keys is set,
* the public key digests are also calculated and stored here.
*
* @return
* - ESP_OK - At least one signature was found
* - ESP_ERR_NOT_FOUND - No signatures were found, num_digests value will be zero
* - ESP_FAIL - An error occurred trying to read the signature blocks from flash
*/
esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests);
#endif // !BOOTLOADER_BUILD && (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
/** @brief Set all secure eFuse features related to secure_boot
*
* @note
* This API needs to be called in the eFuse batch mode.
* i.e. A call to esp_efuse_batch_write_begin() should be made prior to calling this API to start the batch mode
* After the API has been executed a call to esp_efuse_batch_write_commit()/esp_efuse_batch_write_cancel()
* should be made accordingly.
* @return
* - ESP_OK - Successfully
*/
esp_err_t esp_secure_boot_enable_secure_features(void);
/** @brief Returns the verification status for all physical security features of secure boot in release mode
*
* If the device has secure boot feature configured in the release mode,
* then it is highly recommended to call this API in the application startup code.
* This API verifies the sanity of the eFuse configuration against
* the release (production) mode of the secure boot feature.
*
* @return
* - True - all eFuses are configured correctly
* - False - not all eFuses are configured correctly.
*/
bool esp_secure_boot_cfg_verify_release_mode(void);
#if !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
/** @brief Returns the verification status of the image pointed by the part_pos argument against the public key digest present at index `efuse_digest_index`
*
* @param index[in] Index of public key digest present in efuse against which the image is to be verified
* @param part_pos[in] It is a pointer to the bootloader/app partition.
*
* @return
* - ESP_OK - if the image can be verified by the key at efuse_index.
* - ESP_FAIL - if the image cannot be verified by the key at efuse_index.
* - ESP_ERR_INVALID_ARG: Error in the passed arguments.
*/
esp_err_t esp_secure_boot_verify_with_efuse_digest_index(int efuse_digest_index, esp_partition_pos_t *part_pos);
#endif // !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "esp_flash_partitions.h"
#include "esp_image_format.h"
#ifdef __cplusplus
extern "C" {
#endif
// TEE otadata magic is derived from sha256 of "tee_ota" string
#define TEE_OTADATA_MAGIC 0x4337e1e1
/* TEE OTA selection structure (two copies in the TEE OTA data partition) */
typedef struct {
uint32_t magic; // A magic byte for otadata structure
uint8_t version; // OTA image version
uint8_t boot_partition; // Default boot partition
uint8_t ota_state; // OTA_DATA states for checking operability of the app
uint8_t reserved_1; // Reserved field 1
uint32_t reserved_2[5]; // Reserved fields 2
uint32_t crc; // CRC32 of all fields in the structure
} __attribute__((packed)) esp_tee_ota_select_entry_t;
ESP_STATIC_ASSERT(offsetof(esp_tee_ota_select_entry_t, crc) == sizeof(esp_tee_ota_select_entry_t) - sizeof(uint32_t));
// OTA_DATA states for checking operability of the app.
typedef enum {
ESP_TEE_OTA_IMG_NEW = 0x00U, /*!< Monitor the first boot - the bootloader changes the state to PENDING_VERIFY. */
ESP_TEE_OTA_IMG_PENDING_VERIFY = 0x33U, /*!< If encountered during the second boot, the bootloader changes the state to INVALID. */
ESP_TEE_OTA_IMG_INVALID = 0x55U, /*!< App was confirmed as workable - can boot and work without limits. */
ESP_TEE_OTA_IMG_VALID = 0xAAU, /*!< App was confirmed as non-workable - will not selected to boot at all. */
ESP_TEE_OTA_IMG_UNDEFINED = 0xFFU, /*!< Undefined. */
} esp_tee_ota_img_states_t;
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,436 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_BLUFI_API_H__
#define __ESP_BLUFI_API_H__
#include "esp_err.h"
#include "esp_wifi_types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ESP_BLUFI_EVENT_INIT_FINISH = 0, /*<! When BLUFI init complete, this event happen */
ESP_BLUFI_EVENT_DEINIT_FINISH, /*<! When BLUFI deinit complete, this event happen */
ESP_BLUFI_EVENT_SET_WIFI_OPMODE, /*<! When Phone set ESP32 wifi operation mode(AP/STA/AP_STA), this event happen */
ESP_BLUFI_EVENT_BLE_CONNECT, /*<! When Phone connect to ESP32 with BLE, this event happen */
ESP_BLUFI_EVENT_BLE_DISCONNECT, /*<! When Phone disconnect with BLE, this event happen */
ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP, /*<! When Phone request ESP32's STA connect to AP, this event happen */
ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP, /*<! When Phone request ESP32's STA disconnect from AP, this event happen */
ESP_BLUFI_EVENT_GET_WIFI_STATUS, /*<! When Phone get ESP32 wifi status, this event happen */
ESP_BLUFI_EVENT_DEAUTHENTICATE_STA, /*<! When Phone deauthenticate sta from SOFTAP, this event happen */
/* recv data */
ESP_BLUFI_EVENT_RECV_STA_BSSID, /*<! When Phone send STA BSSID to ESP32 to connect, this event happen */
ESP_BLUFI_EVENT_RECV_STA_SSID, /*<! When Phone send STA SSID to ESP32 to connect, this event happen */
ESP_BLUFI_EVENT_RECV_STA_PASSWD, /*<! When Phone send STA PASSWORD to ESP32 to connect, this event happen */
ESP_BLUFI_EVENT_RECV_SOFTAP_SSID, /*<! When Phone send SOFTAP SSID to ESP32 to start SOFTAP, this event happen */
ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD, /*<! When Phone send SOFTAP PASSWORD to ESP32 to start SOFTAP, this event happen */
ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM, /*<! When Phone send SOFTAP max connection number to ESP32 to start SOFTAP, this event happen */
ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE, /*<! When Phone send SOFTAP authentication mode to ESP32 to start SOFTAP, this event happen */
ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL, /*<! When Phone send SOFTAP channel to ESP32 to start SOFTAP, this event happen */
ESP_BLUFI_EVENT_RECV_USERNAME, /*<! When Phone send username to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_CA_CERT, /*<! When Phone send CA certificate to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_CLIENT_CERT, /*<! When Phone send Client certificate to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_SERVER_CERT, /*<! When Phone send Server certificate to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY, /*<! When Phone send Client Private key to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY, /*<! When Phone send Server Private key to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE, /*<! When Phone send Disconnect key to ESP32, this event happen */
ESP_BLUFI_EVENT_GET_WIFI_LIST, /*<! When Phone send get wifi list command to ESP32, this event happen */
ESP_BLUFI_EVENT_REPORT_ERROR, /*<! When Blufi report error, this event happen */
ESP_BLUFI_EVENT_RECV_CUSTOM_DATA, /*<! When Phone send custom data to ESP32, this event happen */
} esp_blufi_cb_event_t;
/// BLUFI config status
typedef enum {
ESP_BLUFI_STA_CONN_SUCCESS = 0x00,
ESP_BLUFI_STA_CONN_FAIL = 0x01,
ESP_BLUFI_STA_CONNECTING = 0x02,
ESP_BLUFI_STA_NO_IP = 0x03,
} esp_blufi_sta_conn_state_t;
/// BLUFI init status
typedef enum {
ESP_BLUFI_INIT_OK = 0,
ESP_BLUFI_INIT_FAILED,
} esp_blufi_init_state_t;
/// BLUFI deinit status
typedef enum {
ESP_BLUFI_DEINIT_OK = 0,
ESP_BLUFI_DEINIT_FAILED,
} esp_blufi_deinit_state_t;
typedef enum {
ESP_BLUFI_SEQUENCE_ERROR = 0,
ESP_BLUFI_CHECKSUM_ERROR,
ESP_BLUFI_DECRYPT_ERROR,
ESP_BLUFI_ENCRYPT_ERROR,
ESP_BLUFI_INIT_SECURITY_ERROR,
ESP_BLUFI_DH_MALLOC_ERROR,
ESP_BLUFI_DH_PARAM_ERROR,
ESP_BLUFI_READ_PARAM_ERROR,
ESP_BLUFI_MAKE_PUBLIC_ERROR,
ESP_BLUFI_DATA_FORMAT_ERROR,
ESP_BLUFI_CALC_MD5_ERROR,
ESP_BLUFI_WIFI_SCAN_FAIL,
ESP_BLUFI_MSG_STATE_ERROR,
} esp_blufi_error_state_t;
/**
* @brief BLUFI extra information structure
*/
typedef struct {
//station
uint8_t sta_bssid[6]; /*!< BSSID of station interface */
bool sta_bssid_set; /*!< is BSSID of station interface set */
uint8_t *sta_ssid; /*!< SSID of station interface */
int sta_ssid_len; /*!< length of SSID of station interface */
uint8_t *sta_passwd; /*!< password of station interface */
int sta_passwd_len; /*!< length of password of station interface */
uint8_t *softap_ssid; /*!< SSID of softap interface */
int softap_ssid_len; /*!< length of SSID of softap interface */
uint8_t *softap_passwd; /*!< password of station interface */
int softap_passwd_len; /*!< length of password of station interface */
uint8_t softap_authmode; /*!< authentication mode of softap interface */
bool softap_authmode_set; /*!< is authentication mode of softap interface set */
uint8_t softap_max_conn_num; /*!< max connection number of softap interface */
bool softap_max_conn_num_set; /*!< is max connection number of softap interface set */
uint8_t softap_channel; /*!< channel of softap interface */
bool softap_channel_set; /*!< is channel of softap interface set */
uint8_t sta_max_conn_retry; /*!< max retry of sta establish connection */
bool sta_max_conn_retry_set; /*!< is max retry of sta establish connection set */
uint8_t sta_conn_end_reason; /*!< reason of sta connection end */
bool sta_conn_end_reason_set; /*!< is reason of sta connection end set */
int8_t sta_conn_rssi; /*!< rssi of sta connection */
bool sta_conn_rssi_set; /*!< is rssi of sta connection set */
} esp_blufi_extra_info_t;
/** @brief Description of an WiFi AP */
typedef struct {
uint8_t ssid[33]; /**< SSID of AP */
int8_t rssi; /**< signal strength of AP */
} esp_blufi_ap_record_t;
/// Bluetooth address length
#define ESP_BLUFI_BD_ADDR_LEN 6
/// Bluetooth device address
typedef uint8_t esp_blufi_bd_addr_t[ESP_BLUFI_BD_ADDR_LEN];
/**
* @brief BLUFI callback parameters union
*/
typedef union {
/**
* @brief ESP_BLUFI_EVENT_INIT_FINISH
*/
struct blufi_init_finish_evt_param {
esp_blufi_init_state_t state; /*!< Initial status */
} init_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */
/**
* @brief ESP_BLUFI_EVENT_DEINIT_FINISH
*/
struct blufi_deinit_finish_evt_param {
esp_blufi_deinit_state_t state; /*!< De-initial status */
} deinit_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_DEINIT_FINISH */
/**
* @brief ESP_BLUFI_EVENT_SET_WIFI_MODE
*/
struct blufi_set_wifi_mode_evt_param {
wifi_mode_t op_mode; /*!< Wifi operation mode */
} wifi_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */
/**
* @brief ESP_BLUFI_EVENT_CONNECT
*/
struct blufi_connect_evt_param {
esp_blufi_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */
uint8_t server_if; /*!< server interface */
uint16_t conn_id; /*!< Connection id */
} connect; /*!< Blufi callback param of ESP_BLUFI_EVENT_CONNECT */
/**
* @brief ESP_BLUFI_EVENT_DISCONNECT
*/
struct blufi_disconnect_evt_param {
esp_blufi_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */
} disconnect; /*!< Blufi callback param of ESP_BLUFI_EVENT_DISCONNECT */
/* ESP_BLUFI_EVENT_REQ_WIFI_CONNECT */ /* No callback param */
/* ESP_BLUFI_EVENT_REQ_WIFI_DISCONNECT */ /* No callback param */
/**
* @brief ESP_BLUFI_EVENT_RECV_STA_BSSID
*/
struct blufi_recv_sta_bssid_evt_param {
uint8_t bssid[6]; /*!< BSSID */
} sta_bssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_BSSID */
/**
* @brief ESP_BLUFI_EVENT_RECV_STA_SSID
*/
struct blufi_recv_sta_ssid_evt_param {
uint8_t *ssid; /*!< SSID */
int ssid_len; /*!< SSID length */
} sta_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_SSID */
/**
* @brief
* ESP_BLUFI_EVENT_RECV_STA_PASSWD
*/
struct blufi_recv_sta_passwd_evt_param {
uint8_t *passwd; /*!< Password */
int passwd_len; /*!< Password Length */
} sta_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_PASSWD */
/**
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_SSID
*/
struct blufi_recv_softap_ssid_evt_param {
uint8_t *ssid; /*!< SSID */
int ssid_len; /*!< SSID length */
} softap_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_SSID */
/**
* @brief
* ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD
*/
struct blufi_recv_softap_passwd_evt_param {
uint8_t *passwd; /*!< Password */
int passwd_len; /*!< Password Length */
} softap_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD */
/**
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM
*/
struct blufi_recv_softap_max_conn_num_evt_param {
int max_conn_num; /*!< SSID */
} softap_max_conn_num; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM */
/**
* @brief
* ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE
*/
struct blufi_recv_softap_auth_mode_evt_param {
wifi_auth_mode_t auth_mode; /*!< Authentication mode */
} softap_auth_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE */
/**
* @brief
* ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL
*/
struct blufi_recv_softap_channel_evt_param {
uint8_t channel; /*!< Authentication mode */
} softap_channel; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL */
/**
* @brief ESP_BLUFI_EVENT_RECV_USERNAME
*/
struct blufi_recv_username_evt_param {
uint8_t *name; /*!< Username point */
int name_len; /*!< Username length */
} username; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_USERNAME*/
/**
* @brief ESP_BLUFI_EVENT_RECV_CA_CERT
*/
struct blufi_recv_ca_evt_param {
uint8_t *cert; /*!< CA certificate point */
int cert_len; /*!< CA certificate length */
} ca; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CA_CERT */
/**
* ESP_BLUFI_EVENT_RECV_CLIENT_CERT
*/
struct blufi_recv_client_cert_evt_param {
uint8_t *cert; /*!< Client certificate point */
int cert_len; /*!< Client certificate length */
} client_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_CERT */
/**
* ESP_BLUFI_EVENT_RECV_SERVER_CERT
*/
struct blufi_recv_server_cert_evt_param {
uint8_t *cert; /*!< Client certificate point */
int cert_len; /*!< Client certificate length */
} server_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_CERT */
/**
* ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY
*/
struct blufi_recv_client_pkey_evt_param {
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */
int pkey_len; /*!< Client Private key length */
} client_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY */
/**
* ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY
*/
struct blufi_recv_server_pkey_evt_param {
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */
int pkey_len; /*!< Client Private key length */
} server_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY */
/**
* @brief
* ESP_BLUFI_EVENT_REPORT_ERROR
*/
struct blufi_get_error_evt_param {
esp_blufi_error_state_t state; /*!< Blufi error state */
} report_error; /*!< Blufi callback param of ESP_BLUFI_EVENT_REPORT_ERROR */
/**
* @brief
* ESP_BLUFI_EVENT_RECV_CUSTOM_DATA
*/
struct blufi_recv_custom_data_evt_param {
uint8_t *data; /*!< Custom data */
uint32_t data_len; /*!< Custom data Length */
} custom_data; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CUSTOM_DATA */
} esp_blufi_cb_param_t;
/**
* @brief BLUFI event callback function type
* @param event : Event type
* @param param : Point to callback parameter, currently is union type
*/
typedef void (* esp_blufi_event_cb_t)(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
/* security function declare */
/**
* @brief BLUFI negotiate data handler
* @param data : data from phone
* @param len : length of data from phone
* @param output_data : data want to send to phone
* @param output_len : length of data want to send to phone
* @param need_free : output reporting if memory needs to be freed or not *
*/
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
/**
* @brief BLUFI encrypt the data after negotiate a share key
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
* @param crypt_data : plain text and encrypted data, the encrypt function must support autochthonous encrypt
* @param crypt_len : length of plain text
* @return Nonnegative number is encrypted length, if error, return negative number;
*/
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
/**
* @brief BLUFI decrypt the data after negotiate a share key
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
* @param crypt_data : encrypted data and plain text, the encrypt function must support autochthonous decrypt
* @param crypt_len : length of encrypted text
* @return Nonnegative number is decrypted length, if error, return negative number;
*/
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
/**
* @brief BLUFI checksum
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
* @param data : data need to checksum
* @param len : length of data
*/
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len);
/**
* @brief BLUFI callback functions type
*/
typedef struct {
esp_blufi_event_cb_t event_cb; /*!< BLUFI event callback */
esp_blufi_negotiate_data_handler_t negotiate_data_handler; /*!< BLUFI negotiate data function for negotiate share key */
esp_blufi_encrypt_func_t encrypt_func; /*!< BLUFI encrypt data function with share key generated by negotiate_data_handler */
esp_blufi_decrypt_func_t decrypt_func; /*!< BLUFI decrypt data function with share key generated by negotiate_data_handler */
esp_blufi_checksum_func_t checksum_func; /*!< BLUFI check sum function (FCS) */
} esp_blufi_callbacks_t;
/**
*
* @brief This function is called to receive blufi callback event
*
* @param[in] callbacks: callback functions
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);
/**
*
* @brief This function is called to initialize blufi_profile
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_profile_init(void);
/**
*
* @brief This function is called to de-initialize blufi_profile
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_profile_deinit(void);
/**
*
* @brief This function is called to send wifi connection report
* @param opmode : wifi opmode
* @param sta_conn_state : station is already in connection or not
* @param softap_conn_num : softap connection number
* @param extra_info : extra information, such as sta_ssid, softap_ssid and etc.
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info);
/**
*
* @brief This function is called to send wifi list
* @param apCount : wifi list count
* @param list : wifi list
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list);
/**
*
* @brief Get BLUFI profile version
*
* @return Most 8bit significant is Great version, Least 8bit is Sub version
*
*/
uint16_t esp_blufi_get_version(void);
/**
*
* @brief This function is called to send blufi error information
* @param state : error state
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state);
/**
*
* @brief This function is called to custom data
* @param data : custom data value
* @param data_len : the length of custom data
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLUFI_API_ */
@@ -0,0 +1,56 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BLE_LOG_H__
#define __BLE_LOG_H__
/* ------- */
/* BLE Log */
/* ------- */
/* INCLUDE */
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/* TYPEDEF */
/* CRITICAL:
* The number of BLE Log source code will directly determine the number of statistic manager
* memory requirements, keep it as less as possible; it's recommended to use subcode for more
* log data structure decoding */
typedef enum {
/* Internal */
BLE_LOG_SRC_INTERNAL = 0,
/* Custom */
BLE_LOG_SRC_CUSTOM,
/* BLE Stack */
BLE_LOG_SRC_LL_TASK,
BLE_LOG_SRC_LL_HCI,
BLE_LOG_SRC_LL_ISR,
BLE_LOG_SRC_HOST,
BLE_LOG_SRC_HCI,
BLE_LOG_SRC_ENCODE,
BLE_LOG_SRC_MAX,
} ble_log_src_t;
/* INTERFACE */
bool ble_log_init(void);
void ble_log_deinit(void);
bool ble_log_enable(bool enable);
void ble_log_flush(void);
bool ble_log_write_hex(ble_log_src_t src_code, const uint8_t *addr, size_t len);
void ble_log_dump_to_console(void);
#if CONFIG_BLE_LOG_LL_ENABLED
void ble_log_write_hex_ll(uint32_t len, const uint8_t *addr,
uint32_t len_append, const uint8_t *addr_append, uint32_t flag);
#endif /* CONFIG_BLE_LOG_LL_ENABLED */
#if CONFIG_BLE_LOG_TS_ENABLED
bool ble_log_sync_enable(bool enable);
#endif /* CONFIG_BLE_LOG_TS_ENABLED */
#endif /* __BLE_LOG_H__ */
@@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_SPI_OUT_H__
#define __BT_SPI_OUT_H__
#include <stdarg.h>
#include <string.h>
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "freertos/semphr.h"
#include "esp_heap_caps.h"
#include "esp_task.h"
// Public enums
enum {
BLE_LOG_SPI_OUT_SOURCE_ESP = 0,
BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY,
BLE_LOG_SPI_OUT_SOURCE_BLUEDROID,
BLE_LOG_SPI_OUT_SOURCE_NIMBLE,
BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM,
BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM,
BLE_LOG_SPI_OUT_SOURCE_ESP_ISR,
BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY_ISR,
BLE_LOG_SPI_OUT_SOURCE_LL_HCI,
BLE_LOG_SPI_OUT_SOURCE_LE_AUDIO,
BLE_LOG_SPI_OUT_SOURCE_MESH,
BLE_LOG_SPI_OUT_SOURCE_USER = 0x10,
BLE_LOG_SPI_OUT_SOURCE_SSC = 0xFD,
BLE_LOG_SPI_OUT_SOURCE_SYNC,
BLE_LOG_SPI_OUT_SOURCE_LOSS,
};
#define BLE_LOG_SPI_OUT_LEVEL_NONE 0
#define BLE_LOG_SPI_OUT_LEVEL_ERROR 1
#define BLE_LOG_SPI_OUT_LEVEL_WARN 2
#define BLE_LOG_SPI_OUT_LEVEL_INFO 3
#define BLE_LOG_SPI_OUT_LEVEL_DEBUG 4
#define BLE_LOG_SPI_OUT_LEVEL_VERBOSE 5
#define BLE_LOG_SPI_OUT_STR(x) #x
#define BLE_LOG_SPI_OUT_XSTR(x) BLE_LOG_SPI_OUT_STR(x)
#define BLE_LOG_SPI_OUT_BUILD_PREFIX(LEVEL, TAG) "[" BLE_LOG_SPI_OUT_XSTR(LEVEL) "][" TAG "]"
// Public functions
int ble_log_spi_out_init(void);
void ble_log_spi_out_deinit(void);
void ble_log_spi_out_timer_control(bool enable);
int ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len);
void ble_log_spi_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,\
const uint8_t *addr_append, uint32_t flag);
void ble_log_spi_out_ll_log_ev_proc(void);
void ble_log_spi_out_ts_sync_start(void);
void ble_log_spi_out_ts_sync_stop(void);
void ble_log_spi_out_dump_all(void);
void ble_log_spi_out_enable(bool enable);
void ble_log_spi_out_flush(void);
void ble_log_spi_out_le_audio_write(const uint8_t *addr, uint16_t len);
int ble_log_spi_out_host_write(uint8_t source, const char *prefix, const char *format, ...);
int ble_log_spi_out_hci_write(uint8_t source, const uint8_t *addr, uint16_t len);
int ble_log_spi_out_mesh_write(const char *prefix, const char *format, ...);
#endif // __BT_SPI_OUT_H__
@@ -0,0 +1,35 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_SPI_OUT_H__
#define __BT_SPI_OUT_H__
#include <stdarg.h>
#include <string.h>
#include "driver/uhci.h"
#include "driver/uart.h"
#include "driver/uart_vfs.h"
#include "esp_rom_uart.h"
#include "esp_timer.h"
#include "freertos/semphr.h"
// Public enums
enum {
BLE_LOG_UHCI_OUT_SOURCE_ESP = 0,
BLE_LOG_UHCI_OUT_SOURCE_ESP_ISR = 6,
BLE_LOG_UHCI_OUT_SOURCE_LL_HCI = 8,
BLE_LOG_UHCI_OUT_SOURCE_USER = 0x10,
BLE_LOG_UHCI_OUT_SOURCE_LOSS = 0xFF,
};
// Public functions
int ble_log_uhci_out_init(void);
void ble_log_uhci_out_deinit(void);
void ble_log_uhci_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,
const uint8_t *addr_append, uint32_t flag);
void ble_log_uhci_out_ll_log_ev_proc(void);
void ble_log_uhci_out_dump_all(void);
#endif // __BT_SPI_OUT_H__
@@ -0,0 +1,209 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BLUFI_INT_H__
#define __BLUFI_INT_H__
#include "btc/btc_task.h"
#include "esp_blufi_api.h"
#ifdef __cplusplus
extern "C" {
#endif
#if (BLUFI_INCLUDED == TRUE)
#define BTC_BLUFI_GREAT_VER 0x01 //Version + Subversion
#define BTC_BLUFI_SUB_VER 0x03 //Version + Subversion
#define BTC_BLUFI_VERSION ((BTC_BLUFI_GREAT_VER<<8)|BTC_BLUFI_SUB_VER) //Version + Subversion
typedef UINT8 tGATT_IF;
/* service engine control block */
typedef struct {
/* Protocol reference */
tGATT_IF gatt_if;
UINT8 srvc_inst;
UINT16 handle_srvc;
UINT16 handle_char_p2e;
UINT16 handle_char_e2p;
UINT16 handle_descr_e2p;
UINT16 conn_id;
BOOLEAN is_connected;
BD_ADDR remote_bda;
UINT32 trans_id;
UINT8 congest;
UINT16 frag_size;
// Deprecated: This macro will be removed in the future
#define BLUFI_PREPAIR_BUF_MAX_SIZE 1024
#define BLUFI_PREPARE_BUF_MAX_SIZE 1024
uint8_t *prepare_buf;
int prepare_len;
/* Control reference */
esp_blufi_callbacks_t *cbs;
BOOLEAN enabled;
uint8_t send_seq;
uint8_t recv_seq;
uint8_t sec_mode;
uint8_t *aggr_buf;
uint16_t total_len;
uint16_t offset;
} tBLUFI_ENV;
/* BLUFI protocol */
struct blufi_hdr{
uint8_t type;
uint8_t fc;
uint8_t seq;
uint8_t data_len;
uint8_t data[0];
};
typedef struct blufi_hdr blufi_hd_t;
struct blufi_frag_hdr {
uint8_t type;
uint8_t fc;
uint8_t seq;
uint8_t data_len;
uint16_t total_len;
uint8_t content[0];
};
typedef struct blufi_frag_hdr blufi_frag_hdr_t;
#if GATT_DYNAMIC_MEMORY == FALSE
extern tBLUFI_ENV blufi_env;
#else
extern tBLUFI_ENV *blufi_env_ptr;
#define blufi_env (*blufi_env_ptr)
#endif
#define BLUFI_DATA_SEC_MODE_CHECK_MASK 0x01
#define BLUFI_DATA_SEC_MODE_ENC_MASK 0x02
#define BLUFI_CTRL_SEC_MODE_CHECK_MASK 0x10
#define BLUFI_CTRL_SEC_MODE_ENC_MASK 0x20
#define BLUFI_MAX_DATA_LEN 255
// packet type
#define BLUFI_TYPE_MASK 0x03
#define BLUFI_TYPE_SHIFT 0
#define BLUFI_SUBTYPE_MASK 0xFC
#define BLUFI_SUBTYPE_SHIFT 2
#define BLUFI_GET_TYPE(type) ((type) & BLUFI_TYPE_MASK)
#define BLUFI_GET_SUBTYPE(type) (((type) & BLUFI_SUBTYPE_MASK) >>BLUFI_SUBTYPE_SHIFT)
#define BLUFI_BUILD_TYPE(type, subtype) (((type) & BLUFI_TYPE_MASK) | ((subtype)<<BLUFI_SUBTYPE_SHIFT))
#define BLUFI_TYPE_CTRL 0x0
#define BLUFI_TYPE_CTRL_SUBTYPE_ACK 0x00
#define BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE 0x01
#define BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE 0x02
#define BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP 0x03
#define BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP 0x04
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS 0x05
#define BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA 0x06
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION 0x07
#define BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE 0x08
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST 0x09
#define BLUFI_TYPE_DATA 0x1
#define BLUFI_TYPE_DATA_SUBTYPE_NEG 0x00
#define BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID 0x01
#define BLUFI_TYPE_DATA_SUBTYPE_STA_SSID 0x02
#define BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD 0x03
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID 0x04
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD 0x05
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM 0x06
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE 0x07
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL 0x08
#define BLUFI_TYPE_DATA_SUBTYPE_USERNAME 0x09
#define BLUFI_TYPE_DATA_SUBTYPE_CA 0x0a
#define BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT 0x0b
#define BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT 0x0c
#define BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY 0x0d
#define BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY 0x0e
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP 0x0f
#define BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION 0x10
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST 0x11
#define BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO 0x12
#define BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA 0x13
#define BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY 0x14
#define BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON 0x15
#define BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI 0x16
#define BLUFI_TYPE_IS_CTRL(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_CTRL)
#define BLUFI_TYPE_IS_DATA(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_DATA)
#define BLUFI_TYPE_IS_CTRL_ACK(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_ACK)
#define BLUFI_TYPE_IS_CTRL_START_NEG(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_START_NEG)
#define BLUFI_TYPE_IS_CTRL_STOP_NEG(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_STOP_NEG)
#define BLUFI_TYPE_IS_CTRL_SET_WIFI_OPMODE(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE)
#define BLUFI_TYPE_IS_CTRL_CONN_WIFI(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP)
#define BLUFI_TYPE_IS_CTRL_DISCONN_WIFI(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP)
#define BLUFI_TYPE_IS_CTRL_GET_WIFI_STATUS(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS)
#define BLUFI_TYPE_IS_CTRL_DEAUTHENTICATE_STA(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA)
#define BLUFI_TYPE_IS_CTRL_GET_VERSION(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION)
#define BLUFI_TYPE_IS_DATA_NEG(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_NEG)
#define BLUFI_TYPE_IS_DATA_STA_BSSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID)
#define BLUFI_TYPE_IS_DATA_STA_SSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_SSID)
#define BLUFI_TYPE_IS_DATA_STA_PASSWD(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD)
#define BLUFI_TYPE_IS_DATA_SOFTAP_SSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID)
#define BLUFI_TYPE_IS_DATA_SOFTAP_PASSWD(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD)
#define BLUFI_TYPE_IS_DATA_SOFTAP_MAX_CONN_NUM(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM)
#define BLUFI_TYPE_IS_DATA_SOFTAP_AUTH_MODE(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE)
#define BLUFI_TYPE_IS_DATA_SOFTAP_CHANNEL(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL)
#define BLUFI_TYPE_IS_DATA_USERNAME(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_USERNAME)
#define BLUFI_TYPE_IS_DATA_CA(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CA)
#define BLUFI_TYPE_IS_DATA_CLEINT_CERT(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT)
#define BLUFI_TYPE_IS_DATA_SERVER_CERT(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT)
#define BLUFI_TYPE_IS_DATA_CLIENT_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY)
#define BLUFI_TYPE_IS_DATA_SERVER_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY)
#define BLUFI_TYPE_IS_DATA_ERROR_INFO(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO)
// packet frame control
#define BLUFI_FC_ENC_MASK 0x01
#define BLUFI_FC_CHECK_MASK 0x02
#define BLUFI_FC_DIR_MASK 0x04
#define BLUFI_FC_REQ_ACK_MASK 0x08
#define BLUFI_FC_FRAG_MASK 0x10
#define BLUFI_FC_ENC 0x01
#define BLUFI_FC_CHECK 0x02
#define BLUFI_FC_DIR_P2E 0x00
#define BLUFI_FC_DIR_E2P 0x04
#define BLUFI_FC_REQ_ACK 0x08
#define BLUFI_FC_FRAG 0x10
#define BLUFI_FC_IS_ENC(fc) ((fc) & BLUFI_FC_ENC_MASK)
#define BLUFI_FC_IS_CHECK(fc) ((fc) & BLUFI_FC_CHECK_MASK)
#define BLUFI_FC_IS_DIR_P2E(fc) ((fc) & BLUFI_FC_DIR_P2E_MASK)
#define BLUFI_FC_IS_DIR_E2P(fc) (!((fc) & BLUFI_DIR_P2E_MASK))
#define BLUFI_FC_IS_REQ_ACK(fc) ((fc) & BLUFI_FC_REQ_ACK_MASK)
#define BLUFI_FC_IS_FRAG(fc) ((fc) & BLUFI_FC_FRAG_MASK)
/* default GATT MTU size over LE link
*/
#define GATT_DEF_BLE_MTU_SIZE 23
/* BLUFI HEADER + TOTAL(REMAIN) LENGTH + CRC + L2CAP RESERVED */
#define BLUFI_MTU_RESERVED_SIZE (sizeof(struct blufi_hdr) + 2 + 2 + 3)
#define BLUFI_FRAG_DATA_DEFAULT_LEN (GATT_DEF_BLE_MTU_SIZE - BLUFI_MTU_RESERVED_SIZE)
//function declare
void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len);
void btc_blufi_send_encap(uint8_t type, uint8_t *data, int data_len);
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks);
void btc_blufi_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_blufi_cb_deep_free(btc_msg_t *msg);
#endif ///BLUFI_INCLUDED == TRUE
#ifdef __cplusplus
}
#endif
#endif /* __BLUFI_INT_H__ */
@@ -0,0 +1,126 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_BLUFI_H__
#define __ESP_BLUFI_H__
#include "esp_blufi_api.h"
#include "esp_err.h"
#ifdef CONFIG_BT_NIMBLE_ENABLED
#include "nimble/ble.h"
#include "host/ble_gap.h"
#include "modlog/modlog.h"
#endif
#ifdef CONFIG_BT_BLUEDROID_ENABLED
#include "esp_gap_ble_api.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define BLUFI_APP_UUID 0xFFFF
#define BLUFI_DEVICE_NAME "BLUFI_DEVICE"
#ifdef CONFIG_BT_NIMBLE_ENABLED
struct ble_hs_cfg;
struct ble_gatt_register_ctxt;
struct gatt_value {
struct os_mbuf *buf;
uint16_t val_handle;
uint8_t type;
void *ptr;
};
#define SERVER_MAX_VALUES 3
#define MAX_VAL_SIZE 512
extern struct gatt_value gatt_values[SERVER_MAX_VALUES];
/* GATT server callback */
void esp_blufi_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
/* Initialise gatt server */
int esp_blufi_gatt_svr_init(void);
int esp_blufi_gatt_svr_deinit(void);
void esp_blufi_btc_init(void);
void esp_blufi_btc_deinit(void);
#endif
#ifdef CONFIG_BT_BLUEDROID_ENABLED
/**
* @brief Close a connection a remote device.
*
* @param[in] gatts_if: GATT server access interface
* @param[in] conn_id: connection ID to be closed.
*
* @return
* - ESP_OK : success
* - other : failed
*
*/
esp_err_t esp_blufi_close(uint8_t gatts_if, uint16_t conn_id);
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
#endif
/* Initialise blufi profile */
uint8_t esp_blufi_init(void);
/* start advertising */
void bleprph_advertise(void);
/* send notifications */
void esp_blufi_send_notify(void *arg);
/* Deinitialise blufi */
void esp_blufi_deinit(void);
/* disconnect */
void esp_blufi_disconnect(void);
/* Stop advertisement */
void esp_blufi_adv_stop(void);
/* Start advertisement */
void esp_blufi_adv_start(void);
/* Start advertisement with specified name. if the name is NULL just start advertisement */
void esp_blufi_adv_start_with_name(const char *name);
void esp_blufi_send_encap(void *arg);
/*
* @brief Initiate BLE security request with the connected peer device.
*
* This function triggers the BLE Security Manager Protocol (SMP) procedure
* to establish a secure, encrypted connection with the specified remote device.
* It should be called after a BLE connection is established.
*
* @param[in] remote_bda Bluetooth device address of the connected peer.
*
* @return
* - ESP_OK: Security request initiated successfully
* - ESP_FAIL: Security request failed
* - ESP_ERR_INVALID_STATE: BluFi BLE SMP is not enabled
*/
esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda);
#ifdef CONFIG_BT_NIMBLE_ENABLED
/**
* @brief Handle gap event for BluFi.
* This function can be called inside custom use gap event handler.
* It provide minimal event management for BluFi purpose.
*
* @param[in] event The type of event being signalled.
* @param[in] arg Application-specified argument. Currently unused
* @return int 0 in case of success.
* Other in case of failure.
*/
int esp_blufi_handle_gap_events(struct ble_gap_event *event, void *arg);
#endif
#ifdef __cplusplus
}
#endif
#endif/* _ESP_BLUFI_ */
@@ -0,0 +1,111 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BTC_BLUFI_PRF_H__
#define __BTC_BLUFI_PRF_H__
#include "blufi_int.h"
#include "btc/btc_task.h"
#include "esp_blufi_api.h"
#include "esp_err.h"
#ifdef CONFIG_BT_BLUEDROID_ENABLED
#include "stack/gatt_api.h"
#define ESP_BLUFI_ERROR GATT_ERROR
#define ESP_BLUFI_SUCCESS GATT_SUCCESS
#else
#define ESP_BLUFI_ERROR 0x85
#define ESP_BLUFI_SUCCESS 0x00
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */
//define the blufi serivce uuid
#define BLUFI_SERVICE_UUID 0xFFFF
//define the blufi Char uuid (PHONE to ESP32)
#define BLUFI_CHAR_P2E_UUID 0xFF01
//define the blufi Char uuid (ESP32 to PHONE)
#define BLUFI_CHAR_E2P_UUID 0xFF02
//define the blufi Descriptor uuid (ESP32 to PHONE)
#define BLUFI_DESCR_E2P_UUID GATT_UUID_CHAR_CLIENT_CONFIG
//define the blufi APP ID
#define BLUFI_APP_UUID 0xFFFF
#define BLUFI_HDL_NUM 6
struct pkt_info{
uint8_t *pkt;
int pkt_len;
};
static const tBT_UUID blufi_srvc_uuid = {LEN_UUID_16, {BLUFI_SERVICE_UUID}};
static const tBT_UUID blufi_char_uuid_p2e = {LEN_UUID_16, {BLUFI_CHAR_P2E_UUID}};
static const tBT_UUID blufi_char_uuid_e2p = {LEN_UUID_16, {BLUFI_CHAR_E2P_UUID}};
static const tBT_UUID blufi_descr_uuid_e2p = {LEN_UUID_16, {BLUFI_DESCR_E2P_UUID}};
static const tBT_UUID blufi_app_uuid = {LEN_UUID_16, {BLUFI_APP_UUID}};
typedef enum {
BTC_BLUFI_ACT_INIT = 0,
BTC_BLUFI_ACT_DEINIT,
BTC_BLUFI_ACT_SEND_CFG_REPORT,
BTC_BLUFI_ACT_SEND_WIFI_LIST,
BTC_BLUFI_ACT_SEND_ERR_INFO,
BTC_BLUFI_ACT_SEND_CUSTOM_DATA,
} btc_blufi_act_t;
typedef union {
struct blufi_cfg_report {
wifi_mode_t opmode;
esp_blufi_sta_conn_state_t sta_conn_state;
uint8_t softap_conn_num;
esp_blufi_extra_info_t *extra_info;
int extra_info_len;
} wifi_conn_report;
/*
BTC_BLUFI_ACT_SEND_WIFI_LIST
*/
struct blufi_wifi_list {
uint16_t apCount;
esp_blufi_ap_record_t *list;
} wifi_list;
/*
BTC_BLUFI_ACT_SEND_ERR_INFO
*/
struct blufi_error_infor {
esp_blufi_error_state_t state;
} blufi_err_infor;
/*
BTC_BLUFI_ACT_SEND_CUSTOM_DATA
*/
struct blufi_custom_data {
uint8_t *data;
uint32_t data_len;
} custom_data;
} btc_blufi_args_t;
void btc_blufi_cb_to_app(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
void btc_blufi_cb_handler(btc_msg_t *msg);
void btc_blufi_call_handler(btc_msg_t *msg);
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks);
void btc_blufi_recv_handler(uint8_t *data, int len);
void btc_blufi_send_notify(uint8_t *pkt, int pkt_len);
void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_blufi_call_deep_free(btc_msg_t *msg);
uint16_t btc_blufi_get_version(void);
#ifdef __cplusplus
}
#endif
#endif /* __BTC_BLUFI_PRF_H__ */
@@ -0,0 +1,109 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_BT_HCI_LOG_H__
#define __ESP_BT_HCI_LOG_H__
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define HCI_LOG_DATA_TYPE_COMMAND (1)
#define HCI_LOG_DATA_TYPE_H2C_ACL (2)
#define HCI_LOG_DATA_TYPE_SCO (3)
#define HCI_LOG_DATA_TYPE_EVENT (4)
#define HCI_LOG_DATA_TYPE_ADV (5)
#define HCI_LOG_DATA_TYPE_SELF_DEFINE (6)
#define HCI_LOG_DATA_TYPE_C2H_ACL (7)
#define HCI_LOG_DATA_TYPE_ISO_DATA (8)
/**
*
* @brief This function is called to record self-defining data
* @param string : data identification
* @param data : data
* @param data_len : the length of data
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t bt_hci_log_record_custom_data(char *string, uint8_t *data, uint8_t data_len);
/**
*
* @brief This function is called to print all hci data record
*
*
* @return None
*
*/
void bt_hci_log_hci_data_show(void);
/**
*
* @brief This function is called to print all adv report
*
*
* @return None
*
*/
void bt_hci_log_hci_adv_show(void);
/**
*
* @brief This function is called to init hci log env
*
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t bt_hci_log_init(void);
/**
*
* @brief This function is called to deinit hci debug mode,
* and can only be called internally by Bluetooth
*
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t bt_hci_log_deinit(void);
/**
*
* @brief This function is called to record hci data without adv report event,
* and can only be called internally by Bluetooth
*
* @param str : data type, define in bt_data_type_to_str()
* @param data : data
* @param data_len : the length of data
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t bt_hci_log_record_hci_data(uint8_t data_type, uint8_t *data, uint16_t data_len);
/**
*
* @brief This function is called to record hci adv report event only
* and can only be called internally by Bluetooth
*
* @param str : data type, define in bt_data_type_to_str()
* @param data : data
* @param data_len : the length of data
* @return ESP_OK - success, other - failed
*
*/
esp_err_t bt_hci_log_record_hci_adv(uint8_t data_type, uint8_t *data, uint8_t data_len);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BT_HCI_LOG_H__ */
@@ -0,0 +1,85 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _ALARM_H_
#define _ALARM_H_
#include <stdint.h>
#include "esp_timer.h"
#include "bt_user_config.h"
typedef struct alarm_t osi_alarm_t;
typedef uint64_t period_ms_t;
typedef esp_timer_cb_t osi_alarm_callback_t;
typedef enum {
OSI_ALARM_ERR_PASS = 0,
OSI_ALARM_ERR_FAIL = -1,
OSI_ALARM_ERR_INVALID_ARG = -2,
OSI_ALARM_ERR_INVALID_STATE = -3,
} osi_alarm_err_t;
#define ALARM_CBS_NUM UC_ALARM_MAX_NUM
#define ALARM_ID_BASE 1000
int osi_alarm_create_mux(void);
int osi_alarm_delete_mux(void);
void osi_alarm_init(void);
void osi_alarm_deinit(void);
// Creates a new alarm object. The returned object must be freed by calling
// |alarm_free|. Returns NULL on failure.
osi_alarm_t *osi_alarm_new(const char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire);
// Frees an alarm object created by |alarm_new|. |alarm| may be NULL. If the
// alarm is pending, it will be cancelled. It is not safe to call |alarm_free|
// from inside the callback of |alarm|.
void osi_alarm_free(osi_alarm_t *alarm);
// Sets an alarm to fire |cb| after the given |deadline|. Note that |deadline| is the
// number of milliseconds relative to the current time. |data| is a context variable
// for the callback and may be NULL. |cb| will be called back in the context of an
// unspecified thread (i.e. it will not be called back in the same thread as the caller).
// |alarm| and |cb| may not be NULL.
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout);
// Sets an periodic alarm to fire |cb| each given |period|.
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period);
// This function cancels the |alarm| if it was previously set. When this call
// returns, the caller has a guarantee that the callback is not in progress and
// will not be called if it hasn't already been called. This function is idempotent.
// |alarm| may not be NULL.
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm);
// Figure out how much time until next expiration.
// Returns 0 if not armed. |alarm| may not be NULL.
// only for oneshot alarm, not for periodic alarm
// TODO: Remove this function once PM timers can be re-factored
period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm);
// Alarm-related state cleanup
//void alarm_cleanup(void);
uint32_t osi_time_get_os_boottime_ms(void);
// This function returns whether the given |alarm| is active or not.
// Return true if active, false otherwise.
bool osi_alarm_is_active(osi_alarm_t *alarm);
#endif /*_ALARM_H_*/
@@ -0,0 +1,129 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _ALLOCATOR_H_
#define _ALLOCATOR_H_
#include <stddef.h>
#include <stdlib.h>
#include "bt_common.h"
#include "esp_heap_caps.h"
#if HEAP_MEMORY_STATS
int osi_mem_init(void);
void osi_mem_deinit(void);
#endif
char *osi_strdup(const char *str);
void *osi_malloc_func(size_t size);
void *osi_calloc_func(size_t size);
void osi_free_func(void *ptr);
// Memory alloc function without print and assertion
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
#define osi_malloc_base(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#define osi_calloc_base(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#else
#define osi_malloc_base(size) malloc((size))
#define osi_calloc_base(size) calloc(1, (size))
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
#if HEAP_MEMORY_DEBUG
void osi_mem_dbg_init(void);
void osi_mem_dbg_record(void *p, int size, const char *func, int line);
void osi_mem_dbg_clean(void *p, const char *func, int line);
void osi_mem_dbg_show(void);
uint32_t osi_mem_dbg_get_max_size(void);
uint32_t osi_mem_dbg_get_current_size(void);
void osi_men_dbg_set_section_start(uint8_t index);
void osi_men_dbg_set_section_end(uint8_t index);
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index);
#define osi_malloc(size) \
({ \
void *p; \
p = osi_malloc_base(size); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#define osi_calloc(size) \
({ \
void *p; \
p = osi_calloc_base(size); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#if 0
#define osi_malloc(size) \
do { \
void *p; \
\
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
#else \
p = malloc((size)); \
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
}while(0)
#define osi_calloc(size) \
do { \
void *p; \
\
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
p = heap_caps_calloc_prefer(1, size, 2, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
#else \
p = calloc(1, (size)); \
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
} while(0)
#endif
#define osi_free(ptr) \
do { \
void *tmp_point = (void *)(ptr); \
osi_mem_dbg_clean(tmp_point, __func__, __LINE__); \
free(tmp_point); \
} while (0)
#else
// Memory alloc function with print and assertion when fails
#define osi_malloc(size) osi_malloc_func((size))
#define osi_calloc(size) osi_calloc_func((size))
#define osi_free(p) osi_free_func((p))
#endif /* HEAP_MEMORY_DEBUG */
#define FREE_AND_RESET(a) \
do { \
if (a) { \
osi_free(a); \
a = NULL; \
} \
}while (0)
#endif /* _ALLOCATOR_H_ */
@@ -0,0 +1,59 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _BUFFER_H_
#define _BUFFER_H_
#include <stdbool.h>
#include <stddef.h>
typedef struct buffer_t buffer_t;
// Returns a new buffer of |size| bytes. Returns NULL if a buffer could not be
// allocated. |size| must be non-zero. The caller must release this buffer with
// |buffer_free|.
buffer_t *buffer_new(size_t size);
// Creates a new reference to the buffer |buf|. A reference is indistinguishable
// from the original: writes to the original will be reflected in the reference
// and vice versa. In other words, this function creates an alias to |buf|. The
// caller must release the returned buffer with |buffer_free|. Note that releasing
// the returned buffer does not release |buf|. |buf| must not be NULL.
buffer_t *buffer_new_ref(const buffer_t *buf);
// Creates a new reference to the last |slice_size| bytes of |buf|. See
// |buffer_new_ref| for a description of references. |slice_size| must be
// greater than 0 and may be at most |buffer_length|
// (0 < slice_size <= buffer_length). |buf| must not be NULL.
buffer_t *buffer_new_slice(const buffer_t *buf, size_t slice_size);
// Frees a buffer object. |buf| may be NULL.
void buffer_free(buffer_t *buf);
// Returns a pointer to a writeable memory region for |buf|. All references
// and slices that share overlapping bytes will also be written to when
// writing to the returned pointer. The caller may safely write up to
// |buffer_length| consecutive bytes starting at the address returned by
// this function. |buf| must not be NULL.
void *buffer_ptr(const buffer_t *buf);
// Returns the length of the writeable memory region referred to by |buf|.
// |buf| must not be NULL.
size_t buffer_length(const buffer_t *buf);
#endif /*_BUFFER_H_*/
@@ -0,0 +1,145 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
// This module implements a configuration parser. Clients can query the
// contents of a configuration file through the interface provided here.
// The current implementation is read-only; mutations are only kept in
// memory. This parser supports the INI file format.
// Implementation notes:
// - Key/value pairs that are not within a section are assumed to be under
// the |CONFIG_DEFAULT_SECTION| section.
// - Multiple sections with the same name will be merged as if they were in
// a single section.
// - Empty sections with no key/value pairs will be treated as if they do
// not exist. In other words, |config_has_section| will return false for
// empty sections.
// - Duplicate keys in a section will overwrite previous values.
// - All strings are case sensitive.
#include <stdbool.h>
// The default section name to use if a key/value pair is not defined within
// a section.
#define CONFIG_DEFAULT_SECTION "Global"
typedef struct config_t config_t;
typedef struct config_section_node_t config_section_node_t;
// Creates a new config object with no entries (i.e. not backed by a file).
// This function returns a config object or NULL on error. Clients must call
// |config_free| on the returned handle when it is no longer required.
config_t *config_new_empty(void);
// Loads the specified file and returns a handle to the config file. If there
// was a problem loading the file or allocating memory, this function returns
// NULL. Clients must call |config_free| on the returned handle when it is no
// longer required. |filename| must not be NULL and must point to a readable
// file on the filesystem.
config_t *config_new(const char *filename);
// Frees resources associated with the config file. No further operations may
// be performed on the |config| object after calling this function. |config|
// may be NULL.
void config_free(config_t *config);
// Returns true if the config file contains a section named |section|. If
// the section has no key/value pairs in it, this function will return false.
// |config| and |section| must not be NULL.
bool config_has_section(const config_t *config, const char *section);
// Returns true if the config file has a key named |key| under |section|.
// Returns false otherwise. |config|, |section|, and |key| must not be NULL.
bool config_has_key(const config_t *config, const char *section, const char *key);
// Returns true if the config file has a key named |key| and the key_value.
// Returns false otherwise. |config|, |key|, and |key_value| must not be NULL.
bool config_has_key_in_section(config_t *config, const char *key, char *key_value);
// Returns the integral value for a given |key| in |section|. If |section|
// or |key| do not exist, or the value cannot be fully converted to an integer,
// this function returns |def_value|. |config|, |section|, and |key| must not
// be NULL.
int config_get_int(const config_t *config, const char *section, const char *key, int def_value);
// Returns the boolean value for a given |key| in |section|. If |section|
// or |key| do not exist, or the value cannot be converted to a boolean, this
// function returns |def_value|. |config|, |section|, and |key| must not be NULL.
bool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value);
// Returns the string value for a given |key| in |section|. If |section| or
// |key| do not exist, this function returns |def_value|. The returned string
// is owned by the config module and must not be freed. |config|, |section|,
// and |key| must not be NULL. |def_value| may be NULL.
const char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value);
// Sets an integral value for the |key| in |section|. If |key| or |section| do
// not already exist, this function creates them. |config|, |section|, and |key|
// must not be NULL.
void config_set_int(config_t *config, const char *section, const char *key, int value);
// Sets a boolean value for the |key| in |section|. If |key| or |section| do
// not already exist, this function creates them. |config|, |section|, and |key|
// must not be NULL.
void config_set_bool(config_t *config, const char *section, const char *key, bool value);
// Sets a string value for the |key| in |section|. If |key| or |section| do
// not already exist, this function creates them. |config|, |section|, |key|, and
// |value| must not be NULL.
void config_set_string(config_t *config, const char *section, const char *key, const char *value, bool insert_back);
// Removes |section| from the |config| (and, as a result, all keys in the section).
// Returns true if |section| was found and removed from |config|, false otherwise.
// Neither |config| nor |section| may be NULL.
bool config_remove_section(config_t *config, const char *section);
// Updates |section| to be the first section in |config|. Return true if |section| is in
// |config| and updated successfully, false otherwise.
// Neither |config| nor |section| may be NULL.
bool config_update_newest_section(config_t *config, const char *section);
// Removes one specific |key| residing in |section| of the |config|. Returns true
// if the section and key were found and the key was removed, false otherwise.
// None of |config|, |section|, or |key| may be NULL.
bool config_remove_key(config_t *config, const char *section, const char *key);
// Returns an iterator to the first section in the config file. If there are no
// sections, the iterator will equal the return value of |config_section_end|.
// The returned pointer must be treated as an opaque handle and must not be freed.
// The iterator is invalidated on any config mutating operation. |config| may not
// be NULL.
const config_section_node_t *config_section_begin(const config_t *config);
// Returns an iterator to one past the last section in the config file. It does not
// represent a valid section, but can be used to determine if all sections have been
// iterated over. The returned pointer must be treated as an opaque handle and must
// not be freed and must not be iterated on (must not call |config_section_next| on
// it). |config| may not be NULL.
const config_section_node_t *config_section_end(const config_t *config);
// Moves |iter| to the next section. If there are no more sections, |iter| will
// equal the value of |config_section_end|. |iter| may not be NULL and must be
// a pointer returned by either |config_section_begin| or |config_section_next|.
const config_section_node_t *config_section_next(const config_section_node_t *iter);
// Returns the name of the section referred to by |iter|. The returned pointer is
// owned by the config module and must not be freed by the caller. The pointer will
// remain valid until |config_free| is called. |iter| may not be NULL and must not
// equal the value returned by |config_section_end|.
const char *config_section_name(const config_section_node_t *iter);
// Saves |config| to a file given by |filename|. Note that this could be a destructive
// operation: if |filename| already exists, it will be overwritten. The config
// module does not preserve comments or formatting so if a config file was opened
// with |config_new| and subsequently overwritten with |config_save|, all comments
// and special formatting in the original file will be lost. Neither |config| nor
// |filename| may be NULL.
bool config_save(const config_t *config, const char *filename);
#endif /* #ifndef __CONFIG_H__ */
@@ -0,0 +1,83 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _FIXED_PKT_QUEUE_H_
#define _FIXED_PKT_QUEUE_H_
#include "osi/pkt_queue.h"
#include "osi/semaphore.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FIXED_PKT_QUEUE_SIZE_MAX
#define FIXED_PKT_QUEUE_SIZE_MAX 254
#endif
#define FIXED_PKT_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
struct fixed_pkt_queue_t;
typedef struct fixed_pkt_queue_t fixed_pkt_queue_t;
typedef void (*fixed_pkt_queue_free_cb)(pkt_linked_item_t *data);
typedef void (*fixed_pkt_queue_cb)(fixed_pkt_queue_t *queue);
// Creates a new fixed queue with the given |capacity|. If more elements than
// |capacity| are added to the queue, the caller is blocked until space is
// made available in the queue. Returns NULL on failure. The caller must free
// the returned queue with |fixed_pkt_queue_free|.
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity);
// Freeing a queue that is currently in use (i.e. has waiters
// blocked on it) results in undefined behaviour.
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb);
// Returns a value indicating whether the given |queue| is empty. If |queue|
// is NULL, the return value is true.
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue);
// Returns the length of the |queue|. If |queue| is NULL, the return value
// is 0.
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue);
// Returns the maximum number of elements this queue may hold. |queue| may
// not be NULL.
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue);
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
// If enqueue failed, it will return false, otherwise return true
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout);
// Dequeues the next element from |queue|. If the queue is currently empty,
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
// If dequeue failed, it will return NULL, otherwise return a point.
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout);
// Returns the first element from |queue|, if present, without dequeuing it.
// This function will never block the caller. Returns NULL if there are no
// elements in the queue or |queue| is NULL.
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue);
// Registers |queue| with |reactor| for dequeue operations. When there is an element
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
// |context| may be NULL.
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb);
// Unregisters the dequeue ready callback for |queue| from whichever reactor
// it is registered with, if any. This function is idempotent.
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue);
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,125 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _FIXED_QUEUE_H_
#define _FIXED_QUEUE_H_
#include <stdbool.h>
#include "osi/list.h"
#include "osi/semaphore.h"
#ifndef QUEUE_SIZE_MAX
#define QUEUE_SIZE_MAX 254
#endif
#define FIXED_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
struct fixed_queue_t;
typedef struct fixed_queue_t fixed_queue_t;
//typedef struct reactor_t reactor_t;
typedef void (*fixed_queue_free_cb)(void *data);
typedef void (*fixed_queue_cb)(fixed_queue_t *queue);
// Creates a new fixed queue with the given |capacity|. If more elements than
// |capacity| are added to the queue, the caller is blocked until space is
// made available in the queue. Returns NULL on failure. The caller must free
// the returned queue with |fixed_queue_free|.
fixed_queue_t *fixed_queue_new(size_t capacity);
// Freeing a queue that is currently in use (i.e. has waiters
// blocked on it) results in undefined behaviour.
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb);
// Returns a value indicating whether the given |queue| is empty. If |queue|
// is NULL, the return value is true.
bool fixed_queue_is_empty(fixed_queue_t *queue);
// Returns the length of the |queue|. If |queue| is NULL, the return value
// is 0.
size_t fixed_queue_length(fixed_queue_t *queue);
// Returns the maximum number of elements this queue may hold. |queue| may
// not be NULL.
size_t fixed_queue_capacity(fixed_queue_t *queue);
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
// If enqueue failed, it will return false, otherwise return true
bool fixed_queue_enqueue(fixed_queue_t *queue, void *data, uint32_t timeout);
// Dequeues the next element from |queue|. If the queue is currently empty,
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
// If dequeue failed, it will return NULL, otherwise return a point.
void *fixed_queue_dequeue(fixed_queue_t *queue, uint32_t timeout);
// Returns the first element from |queue|, if present, without dequeuing it.
// This function will never block the caller. Returns NULL if there are no
// elements in the queue or |queue| is NULL.
void *fixed_queue_try_peek_first(fixed_queue_t *queue);
// Returns the last element from |queue|, if present, without dequeuing it.
// This function will never block the caller. Returns NULL if there are no
// elements in the queue or |queue| is NULL.
void *fixed_queue_try_peek_last(fixed_queue_t *queue);
// Tries to remove a |data| element from the middle of the |queue|. This
// function will never block the caller. If the queue is empty or NULL, this
// function returns NULL immediately. |data| may not be NULL. If the |data|
// element is found in the queue, a pointer to the removed data is returned,
// otherwise NULL.
void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data);
// Returns the iterateable list with all entries in the |queue|. This function
// will never block the caller. |queue| may not be NULL.
//
// NOTE: The return result of this function is not thread safe: the list could
// be modified by another thread, and the result would be unpredictable.
// TODO: The usage of this function should be refactored, and the function
// itself should be removed.
list_t *fixed_queue_get_list(fixed_queue_t *queue);
// This function returns a valid file descriptor. Callers may perform one
// operation on the fd: select(2). If |select| indicates that the file
// descriptor is readable, the caller may call |fixed_queue_enqueue| without
// blocking. The caller must not close the returned file descriptor. |queue|
// may not be NULL.
//int fixed_queue_get_enqueue_fd(const fixed_queue_t *queue);
// This function returns a valid file descriptor. Callers may perform one
// operation on the fd: select(2). If |select| indicates that the file
// descriptor is readable, the caller may call |fixed_queue_dequeue| without
// blocking. The caller must not close the returned file descriptor. |queue|
// may not be NULL.
//int fixed_queue_get_dequeue_fd(const fixed_queue_t *queue);
// Registers |queue| with |reactor| for dequeue operations. When there is an element
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
// |context| may be NULL.
void fixed_queue_register_dequeue(fixed_queue_t *queue, fixed_queue_cb ready_cb);
// Unregisters the dequeue ready callback for |queue| from whichever reactor
// it is registered with, if any. This function is idempotent.
void fixed_queue_unregister_dequeue(fixed_queue_t *queue);
void fixed_queue_process(fixed_queue_t *queue);
list_t *fixed_queue_get_list(fixed_queue_t *queue);
#endif
@@ -0,0 +1,53 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef __FUTURE_H__
#define __FUTURE_H__
#include "osi/semaphore.h"
struct future {
bool ready_can_be_called;
osi_sem_t semaphore; // NULL semaphore means immediate future
void *result;
};
typedef struct future future_t;
#define FUTURE_SUCCESS ((void *)1)
#define FUTURE_FAIL ((void *)0)
// Constructs a new future_t object. Returns NULL on failure.
future_t *future_new(void);
// Constructs a new future_t object with an immediate |value|. No waiting will
// occur in the call to |future_await| because the value is already present.
// Returns NULL on failure.
future_t *future_new_immediate(void *value);
// Signals that the |future| is ready, passing |value| back to the context
// waiting for the result. Must only be called once for every future.
// |future| may not be NULL.
void future_ready(future_t *future, void *value);
// Waits for the |future| to be ready. Returns the value set in |future_ready|.
// Frees the future before return. |future| may not be NULL.
void *future_await(future_t *async_result);
//Free the future if this "future" is not used
void future_free(future_t *future);
#endif /* __FUTURE_H__ */
@@ -0,0 +1,37 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _HASH_FUNCTIONS_H_
#define _HASH_FUNCTIONS_H_
#include "osi/hash_map.h"
typedef unsigned char hash_key_t[4];
hash_index_t hash_function_naive(const void *key);
hash_index_t hash_function_integer(const void *key);
// Hashes a pointer based only on its address value
hash_index_t hash_function_pointer(const void *key);
hash_index_t hash_function_string(const void *key);
void hash_function_blob(const unsigned char *s, unsigned int len, hash_key_t h);
#endif /* _HASH_FUNCTIONS_H_ */
@@ -0,0 +1,111 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _HASH_MAP_H_
#define _HASH_MAP_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
struct hash_map_t;
typedef struct hash_map_t hash_map_t;
typedef struct hash_map_entry_t {
const void *key;
void *data;
const hash_map_t *hash_map;
} hash_map_entry_t;
typedef size_t hash_index_t;
// Takes a key structure and returns a hash value.
typedef hash_index_t (*hash_index_fn)(const void *key);
typedef bool (*hash_map_iter_cb)(hash_map_entry_t *hash_entry, void *context);
typedef bool (*key_equality_fn)(const void *x, const void *y);
typedef void (*key_free_fn)(void *data);
typedef void (*data_free_fn)(void *data);
// Returns a new, empty hash_map. Returns NULL if not enough memory could be allocated
// for the hash_map structure. The returned hash_map must be freed with |hash_map_free|.
// The |num_bucket| specifies the number of hashable buckets for the map and must not
// be zero. The |hash_fn| specifies a hash function to be used and must not be NULL.
// The |key_fn| and |data_fn| are called whenever a hash_map element is removed from
// the hash_map. They can be used to release resources held by the hash_map element,
// e.g. memory or file descriptor. |key_fn| and |data_fn| may be NULL if no cleanup
// is necessary on element removal. |equality_fn| is used to check for key equality.
// If |equality_fn| is NULL, default pointer equality is used.
hash_map_t *hash_map_new(
size_t size,
hash_index_fn hash_fn,
key_free_fn key_fn,
data_free_fn data_fn,
key_equality_fn equality_fn);
// Frees the hash_map. This function accepts NULL as an argument, in which case it
// behaves like a no-op.
void hash_map_free(hash_map_t *hash_map);
// Returns true if the hash_map is empty (has no elements), false otherwise.
// Note that a NULL |hash_map| is not the same as an empty |hash_map|. This function
// does not accept a NULL |hash_map|.
//bool hash_map_is_empty(const hash_map_t *hash_map);
// Returns the number of elements in the hash map. This function does not accept a
// NULL |hash_map|.
//size_t hash_map_size(const hash_map_t *hash_map);
// Returns the number of buckets in the hash map. This function does not accept a
// NULL |hash_map|.
//size_t hash_map_num_buckets(const hash_map_t *hash_map);
// Returns true if the hash_map has a valid entry for the presented key.
// This function does not accept a NULL |hash_map|.
bool hash_map_has_key(const hash_map_t *hash_map, const void *key);
// Returns the element indexed by |key| in the hash_map without removing it. |hash_map|
// may not be NULL. Returns NULL if no entry indexed by |key|.
void *hash_map_get(const hash_map_t *hash_map, const void *key);
// Sets the value |data| indexed by |key| into the |hash_map|. Neither |data| nor
// |hash_map| may be NULL. This function does not make copies of |data| nor |key|
// so the pointers must remain valid at least until the element is removed from the
// hash_map or the hash_map is freed. Returns true if |data| could be set, false
// otherwise (e.g. out of memory).
bool hash_map_set(hash_map_t *hash_map, const void *key, void *data);
// Removes data indexed by |key| from the hash_map. |hash_map| may not be NULL.
// If |key_fn| or |data_fn| functions were specified in |hash_map_new|, they
// will be called back with |key| or |data| respectively. This function returns true
// if |key| was found in the hash_map and removed, false otherwise.
bool hash_map_erase(hash_map_t *hash_map, const void *key);
// Removes all elements in the hash_map. Calling this function will return the hash_map
// to the same state it was in after |hash_map_new|. |hash_map| may not be NULL.
void hash_map_clear(hash_map_t *hash_map);
// Iterates through the entire |hash_map| and calls |callback| for each data
// element and passes through the |context| argument. If the hash_map is
// empty, |callback| will never be called. It is not safe to mutate the
// hash_map inside the callback. Neither |hash_map| nor |callback| may be NULL.
// If |callback| returns false, the iteration loop will immediately exit.
void hash_map_foreach(hash_map_t *hash_map, hash_map_iter_cb callback, void *context);
#endif /* _HASH_MAP_H_ */
@@ -0,0 +1,121 @@
#ifndef _LIST_H_
#define _LIST_H_
#include <stdbool.h>
#include <stddef.h>
struct list_node_t;
typedef struct list_node_t list_node_t;
struct list_t;
typedef struct list_t list_t;
typedef void (*list_free_cb)(void *data);
typedef bool (*list_iter_cb)(void *data, void *context);
// Returns a new, empty list. Returns NULL if not enough memory could be allocated
// for the list structure. The returned list must be freed with |list_free|. The
// |callback| specifies a function to be called whenever a list element is removed
// from the list. It can be used to release resources held by the list element, e.g.
// memory or file descriptor. |callback| may be NULL if no cleanup is necessary on
// element removal.
list_t *list_new(list_free_cb callback);
list_node_t *list_free_node(list_t *list, list_node_t *node);
// similar with list_free_node, this function doesn't free the node data
list_node_t *list_delete_node(list_t *list, list_node_t *node);
// Frees the list. This function accepts NULL as an argument, in which case it
// behaves like a no-op.
void list_free(list_t *list);
// Returns true if |list| is empty (has no elements), false otherwise.
// |list| may not be NULL.
bool list_is_empty(const list_t *list);
// Returns true if the list contains |data|, false otherwise.
// |list| may not be NULL.
bool list_contains(const list_t *list, const void *data);
// Returns list_node which contains |data|, NULL otherwise.
// |list| may not be NULL.
list_node_t *list_get_node(const list_t *list, const void *data);
// Returns the length of the |list|. |list| may not be NULL.
size_t list_length(const list_t *list);
// Returns the first element in the list without removing it. |list| may not
// be NULL or empty.
void *list_front(const list_t *list);
// Returns the last element in the list without removing it. |list| may not
// be NULL or empty.
void *list_back(const list_t *list);
list_node_t *list_back_node(const list_t *list);
// Inserts |data| after |prev_node| in |list|. |data|, |list|, and |prev_node|
// may not be NULL. This function does not make a copy of |data| so the pointer
// must remain valid at least until the element is removed from the list or the
// list is freed. Returns true if |data| could be inserted, false otherwise
// (e.g. out of memory).
bool list_insert_after(list_t *list, list_node_t *prev_node, void *data);
// Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL.
// This function does not make a copy of |data| so the pointer must remain valid
// at least until the element is removed from the list or the list is freed.
// Returns true if |data| could be inserted, false otherwise (e.g. out of memory).
bool list_prepend(list_t *list, void *data);
// Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL.
// This function does not make a copy of |data| so the pointer must remain valid
// at least until the element is removed from the list or the list is freed.
// Returns true if |data| could be inserted, false otherwise (e.g. out of memory).
bool list_append(list_t *list, void *data);
// Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data|
// is inserted multiple times in the list, this function will only remove the first
// instance. If a free function was specified in |list_new|, it will be called back
// with |data|. This function returns true if |data| was found in the list and removed,
// false otherwise.
//list_node_t list_remove_node(list_t *list, list_node_t *prev_node, list_node_t *node);
//list_node_t list_insert_node(list_t *list, list_node_t *prev_node, list_node_t *node);
bool list_remove(list_t *list, void *data);
// similar with list_remove, but do not free the node data
bool list_delete(list_t *list, void *data);
// Removes all elements in the list. Calling this function will return the list to the
// same state it was in after |list_new|. |list| may not be NULL.
void list_clear(list_t *list);
// Iterates through the entire |list| and calls |callback| for each data element.
// If the list is empty, |callback| will never be called. It is safe to mutate the
// list inside the callback. If an element is added before the node being visited,
// there will be no callback for the newly-inserted node. Neither |list| nor
// |callback| may be NULL.
list_node_t *list_foreach(const list_t *list, list_iter_cb callback, void *context);
// Returns an iterator to the first element in |list|. |list| may not be NULL.
// The returned iterator is valid as long as it does not equal the value returned
// by |list_end|.
list_node_t *list_begin(const list_t *list);
// Returns an iterator that points past the end of the list. In other words,
// this function returns the value of an invalid iterator for the given list.
// When an iterator has the same value as what's returned by this function, you
// may no longer call |list_next| with the iterator. |list| may not be NULL.
list_node_t *list_end(const list_t *list);
// Given a valid iterator |node|, this function returns the next value for the
// iterator. If the returned value equals the value returned by |list_end|, the
// iterator has reached the end of the list and may no longer be used for any
// purpose.
list_node_t *list_next(const list_node_t *node);
// Returns the value stored at the location pointed to by the iterator |node|.
// |node| must not equal the value returned by |list_end|.
void *list_node(const list_node_t *node);
#endif /* _LIST_H_ */
@@ -0,0 +1,52 @@
/******************************************************************************
*
* Copyright (C) 2015 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef __MUTEX_H__
#define __MUTEX_H__
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "osi/semaphore.h"
#define OSI_MUTEX_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
#define osi_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define osi_mutex_set_invalid( x ) ( ( *x ) = NULL )
typedef SemaphoreHandle_t osi_mutex_t;
int osi_mutex_new(osi_mutex_t *mutex);
int osi_mutex_lock(osi_mutex_t *mutex, uint32_t timeout);
void osi_mutex_unlock(osi_mutex_t *mutex);
void osi_mutex_free(osi_mutex_t *mutex);
/* Just for a global mutex */
int osi_mutex_global_init(void);
void osi_mutex_global_deinit(void);
void osi_mutex_global_lock(void);
void osi_mutex_global_unlock(void);
#endif /* __MUTEX_H__ */
@@ -0,0 +1,16 @@
#ifndef _OSI_H_
#define _OSI_H_
#include <stdbool.h>
#include <stdint.h>
#define UNUSED_ATTR __attribute__((unused))
#define CONCAT(a, b) a##b
#define COMPILE_ASSERT(x)
int osi_init(void);
void osi_deinit(void);
#endif /*_OSI_H_*/
@@ -0,0 +1,88 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _PKT_LIST_H_
#define _PKT_LIST_H_
#include "sys/queue.h"
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct pkt_queue;
typedef struct pkt_linked_item {
STAILQ_ENTRY(pkt_linked_item) next;
uint8_t data[];
} pkt_linked_item_t;
#define BT_PKT_LINKED_HDR_SIZE (sizeof (pkt_linked_item_t))
typedef void (*pkt_queue_free_cb)(pkt_linked_item_t *item);
/*
* brief: create a pkt_queue instance. pkt_queue is a wrapper class of a FIFO implemented by single linked list.
* The enqueue and dequeue operations of the FIFO are protected against race conditions of multiple tasks
* return: NULL if not enough memory, otherwise a valid pointer
*/
struct pkt_queue *pkt_queue_create(void);
/*
* brief: enqueue one item to the FIFO
* param queue: pkt_queue instance created using pkt_queue_create
* param item: the item to be enqueued to the FIFO
* return: true if enqueued successfully, false when the arguments passed in are invalid
*/
bool pkt_queue_enqueue(struct pkt_queue *queue, pkt_linked_item_t *item);
/*
* brief: dequeue one item for the FIFO
* param queue: pkt_queue instance created using pkt_queue_create
* return: pointer of type pkt_linked_item_t dequeued, NULL if the queue is empty or upon exception
*/
pkt_linked_item_t *pkt_queue_dequeue(struct pkt_queue *queue);
/*
* brief: get the pointer of the first item from the FIFO but not get it dequeued
* param queue: pkt_queue instance created using pkt_queue_create
* return: pointer of the first item in the FIFO, NULL if the FIFO is empty
*/
pkt_linked_item_t *pkt_queue_try_peek_first(struct pkt_queue *queue);
/*
* brief: retrieve the number of items existing in the FIFO
* param queue: pkt_queue instance created using pkt_queue_create
* return: total number of items in the FIFO
*/
size_t pkt_queue_length(const struct pkt_queue *queue);
/*
* brief: retrieve the status whether the FIFO is empty
* param queue: pkt_queue instance created using pkt_queue_create
* return: false if the FIFO is not empty, otherwise true
*/
bool pkt_queue_is_empty(const struct pkt_queue *queue);
/*
* brief: delete the item in the FIFO one by one
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default
*/
void pkt_queue_flush(struct pkt_queue *queue, pkt_queue_free_cb free_cb);
/*
* brief: delete the items in the FIFO and then destroy the pkt_queue instance.
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default
*/
void pkt_queue_destroy(struct pkt_queue *queue, pkt_queue_free_cb free_cb);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,43 @@
/******************************************************************************
*
* Copyright (C) 2015 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef __SEMAPHORE_H__
#define __SEMAPHORE_H__
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#define OSI_SEM_MAX_TIMEOUT 0xffffffffUL
typedef SemaphoreHandle_t osi_sem_t;
#define osi_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define osi_sem_set_invalid( x ) ( ( *x ) = NULL )
int osi_sem_new(osi_sem_t *sem, uint32_t max_count, uint32_t init_count);
void osi_sem_free(osi_sem_t *sem);
int osi_sem_take(osi_sem_t *sem, uint32_t timeout);
void osi_sem_give(osi_sem_t *sem);
#endif /* __SEMAPHORE_H__ */
@@ -0,0 +1,120 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __THREAD_H__
#define __THREAD_H__
#include "freertos/FreeRTOSConfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "osi/semaphore.h"
#include "esp_task.h"
#include "bt_common.h"
#define OSI_THREAD_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
struct osi_thread;
struct osi_event;
typedef struct osi_thread osi_thread_t;
typedef void (*osi_thread_func_t)(void *context);
typedef enum {
OSI_THREAD_CORE_0 = 0,
OSI_THREAD_CORE_1,
OSI_THREAD_CORE_AFFINITY,
} osi_thread_core_t;
/*
* brief: Create a thread or task
* param name: thread name
* param stack_size: thread stack size
* param priority: thread priority
* param core: the CPU core which this thread run, OSI_THREAD_CORE_AFFINITY means unspecific CPU core
* param work_queue_num: speicify queue number, the queue[0] has highest priority, and the priority is decrease by index
* return : if create successfully, return thread handler; otherwise return NULL.
*/
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[]);
/*
* brief: Destroy a thread or task
* param thread: point of thread handler
*/
void osi_thread_free(osi_thread_t *thread);
/*
* brief: Post an msg to a thread and told the thread call the function
* param thread: point of thread handler
* param func: callback function that called by target thread
* param context: argument of callback function
* param queue_idx: the queue which the msg send to
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
* return : if post successfully, return true, otherwise return false
*/
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout);
/*
* brief: Set the priority of thread
* param thread: point of thread handler
* param priority: priority
* return : if set successfully, return true, otherwise return false
*/
bool osi_thread_set_priority(osi_thread_t *thread, int priority);
/* brief: Get thread name
* param thread: point of thread handler
* return: constant point of thread name
*/
const char *osi_thread_name(osi_thread_t *thread);
/* brief: Get the size of the specified queue
* param thread: point of thread handler
* param wq_idx: the queue index of the thread
* return: queue size
*/
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
/*
* brief: Create an osi_event struct and register the handler function and its argument
* An osi_event is a kind of work that can be posted to the workqueue of osi_thread to process,
* but the work can have at most one instance the thread workqueue before it is processed. This
* allows the "single post, multiple data processing" jobs.
* param func: the handler to process the job
* param context: the argument to be passed to the handler function when the job is being processed
* return: NULL if no memory, otherwise a valid struct pointer
*/
struct osi_event *osi_event_create(osi_thread_func_t func, void *context);
/*
* brief: Bind an osi_event to a specific work queue for an osi_thread.
* After binding is completed, a function call of API osi_thread_post_event will send a work
* to the workqueue of the thread, with specified queue index.
* param func: event: the pointer to osi_event that is created using osi_event_create
* param thread: the pointer to osi_thread that is created using osi_thread_create
* param queue_idx: the index of the workqueue of the specified osi_thread, with range starting from 0 to work_queue_num - 1
* return: true if osi_event binds to the thread's workqueue successfully, otherwise false
*/
bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx);
/*
* brief: Destroy the osi_event struct created by osi_event_create and free the allocated memory
* param event: the pointer to osi_event
*/
void osi_event_delete(struct osi_event* event);
/*
* brief: try sending a work to the binded thread's workqueue, so that it can be handled by the worker thread
* param event: pointer to osi_event, created by osi_event_create
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
* return: true if the message is enqueued to the thread workqueue, otherwise failed
* note: if the return value of function is false, it is the case that the workqueue of the thread is full, and users
* are expected to post the event sometime later to get the work handled.
*/
bool osi_thread_post_event(struct osi_event *event, uint32_t timeout);
#endif /* __THREAD_H__ */
@@ -0,0 +1,134 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief -- Interface to an AES-128 implementation.
*
* Overview: AES-128 is a NIST approved block cipher specified in
* FIPS 197. Block ciphers are deterministic algorithms that
* perform a transformation specified by a symmetric key in fixed-
* length data sets, also called blocks.
*
* Security: AES-128 provides approximately 128 bits of security.
*
* Usage: 1) call tc_aes128_set_encrypt/decrypt_key to set the key.
*
* 2) call tc_aes_encrypt/decrypt to process the data.
*/
#ifndef __TC_AES_H__
#define __TC_AES_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define Nb (4) /* number of columns (32-bit words) comprising the state */
#define Nk (4) /* number of 32-bit words comprising the key */
#define Nr (10) /* number of rounds */
#define TC_AES_BLOCK_SIZE (Nb*Nk)
#define TC_AES_KEY_SIZE (Nb*Nk)
typedef struct tc_aes_key_sched_struct {
unsigned int words[Nb*(Nr+1)];
} *TCAesKeySched_t;
/**
* @brief Set AES-128 encryption key
* Uses key k to initialize s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL
* @note This implementation skips the additional steps required for keys
* larger than 128 bits, and must not be used for AES-192 or
* AES-256 key schedule -- see FIPS 197 for details
* @param s IN/OUT -- initialized struct tc_aes_key_sched_struct
* @param k IN -- points to the AES key
*/
int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k);
/**
* @brief AES-128 Encryption procedure
* Encrypts contents of in buffer into out buffer under key;
* schedule s
* @note Assumes s was initialized by aes_set_encrypt_key;
* out and in point to 16 byte buffers
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: out == NULL or in == NULL or s == NULL
* @param out IN/OUT -- buffer to receive ciphertext block
* @param in IN -- a plaintext block to encrypt
* @param s IN -- initialized AES key schedule
*/
int tc_aes_encrypt(uint8_t *out, const uint8_t *in,
const TCAesKeySched_t s);
/**
* @brief Set the AES-128 decryption key
* Uses key k to initialize s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL
* @note This is the implementation of the straightforward inverse cipher
* using the cipher documented in FIPS-197 figure 12, not the
* equivalent inverse cipher presented in Figure 15
* @warning This routine skips the additional steps required for keys larger
* than 128, and must not be used for AES-192 or AES-256 key
* schedule -- see FIPS 197 for details
* @param s IN/OUT -- initialized struct tc_aes_key_sched_struct
* @param k IN -- points to the AES key
*/
int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k);
/**
* @brief AES-128 Encryption procedure
* Decrypts in buffer into out buffer under key schedule s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: out is NULL or in is NULL or s is NULL
* @note Assumes s was initialized by aes_set_encrypt_key
* out and in point to 16 byte buffers
* @param out IN/OUT -- buffer to receive ciphertext block
* @param in IN -- a plaintext block to encrypt
* @param s IN -- initialized AES key schedule
*/
int tc_aes_decrypt(uint8_t *out, const uint8_t *in,
const TCAesKeySched_t s);
#ifdef __cplusplus
}
#endif
#endif /* __TC_AES_H__ */
@@ -0,0 +1,155 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to a CBC mode implementation.
*
* Overview: CBC (for "cipher block chaining") mode is a NIST approved mode of
* operation defined in SP 800-38a. It can be used with any block
* cipher to provide confidentiality of strings whose lengths are
* multiples of the block_size of the underlying block cipher.
* TinyCrypt hard codes AES as the block cipher.
*
* Security: CBC mode provides data confidentiality given that the maximum
* number q of blocks encrypted under a single key satisfies
* q < 2^63, which is not a practical constraint (it is considered a
* good practice to replace the encryption when q == 2^56). CBC mode
* provides NO data integrity.
*
* CBC mode assumes that the IV value input into the
* tc_cbc_mode_encrypt is randomly generated. The TinyCrypt library
* provides HMAC-PRNG module, which generates suitable IVs. Other
* methods for generating IVs are acceptable, provided that the
* values of the IVs generated appear random to any adversary,
* including someone with complete knowledge of the system design.
*
* The randomness property on which CBC mode's security depends is
* the unpredictability of the IV. Since it is unpredictable, this
* means in practice that CBC mode requires that the IV is stored
* somehow with the ciphertext in order to recover the plaintext.
*
* TinyCrypt CBC encryption prepends the IV to the ciphertext,
* because this affords a more efficient (few buffers) decryption.
* Hence tc_cbc_mode_encrypt assumes the ciphertext buffer is always
* 16 bytes larger than the plaintext buffer.
*
* Requires: AES-128
*
* Usage: 1) call tc_cbc_mode_encrypt to encrypt data.
*
* 2) call tc_cbc_mode_decrypt to decrypt data.
*
*/
#ifndef __TC_CBC_MODE_H__
#define __TC_CBC_MODE_H__
#include <tinycrypt/aes.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief CBC encryption procedure
* CBC encrypts inlen bytes of the in buffer into the out buffer
* using the encryption key schedule provided, prepends iv to out
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL or
* in == NULL or
* ctr == NULL or
* sched == NULL or
* inlen == 0 or
* (inlen % TC_AES_BLOCK_SIZE) != 0 or
* (outlen % TC_AES_BLOCK_SIZE) != 0 or
* outlen != inlen + TC_AES_BLOCK_SIZE
* @note Assumes: - sched has been configured by aes_set_encrypt_key
* - iv contains a 16 byte random string
* - out buffer is large enough to hold the ciphertext + iv
* - out buffer is a contiguous buffer
* - in holds the plaintext and is a contiguous buffer
* - inlen gives the number of bytes in the in buffer
* @param out IN/OUT -- buffer to receive the ciphertext
* @param outlen IN -- length of ciphertext buffer in bytes
* @param in IN -- plaintext to encrypt
* @param inlen IN -- length of plaintext buffer in bytes
* @param iv IN -- the IV for the this encrypt/decrypt
* @param sched IN -- AES key schedule for this encrypt
*/
int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, const uint8_t *iv,
const TCAesKeySched_t sched);
/**
* @brief CBC decryption procedure
* CBC decrypts inlen bytes of the in buffer into the out buffer
* using the provided encryption key schedule
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL or
* in == NULL or
* sched == NULL or
* inlen == 0 or
* outlen == 0 or
* (inlen % TC_AES_BLOCK_SIZE) != 0 or
* (outlen % TC_AES_BLOCK_SIZE) != 0 or
* outlen != inlen + TC_AES_BLOCK_SIZE
* @note Assumes:- in == iv + ciphertext, i.e. the iv and the ciphertext are
* contiguous. This allows for a very efficient decryption
* algorithm that would not otherwise be possible
* - sched was configured by aes_set_decrypt_key
* - out buffer is large enough to hold the decrypted plaintext
* and is a contiguous buffer
* - inlen gives the number of bytes in the in buffer
* @param out IN/OUT -- buffer to receive decrypted data
* @param outlen IN -- length of plaintext buffer in bytes
* @param in IN -- ciphertext to decrypt, including IV
* @param inlen IN -- length of ciphertext buffer in bytes
* @param iv IN -- the IV for the this encrypt/decrypt
* @param sched IN -- AES key schedule for this decrypt
*
*/
int tc_cbc_mode_decrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, const uint8_t *iv,
const TCAesKeySched_t sched);
#ifdef __cplusplus
}
#endif
#endif /* __TC_CBC_MODE_H__ */
@@ -0,0 +1,215 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to a CCM mode implementation.
*
* Overview: CCM (for "Counter with CBC-MAC") mode is a NIST approved mode of
* operation defined in SP 800-38C.
*
* TinyCrypt CCM implementation accepts:
*
* 1) Both non-empty payload and associated data (it encrypts and
* authenticates the payload and also authenticates the associated
* data);
* 2) Non-empty payload and empty associated data (it encrypts and
* authenticates the payload);
* 3) Non-empty associated data and empty payload (it degenerates to
* an authentication mode on the associated data).
*
* TinyCrypt CCM implementation accepts associated data of any length
* between 0 and (2^16 - 2^8) bytes.
*
* Security: The mac length parameter is an important parameter to estimate the
* security against collision attacks (that aim at finding different
* messages that produce the same authentication tag). TinyCrypt CCM
* implementation accepts any even integer between 4 and 16, as
* suggested in SP 800-38C.
*
* RFC-3610, which also specifies CCM, presents a few relevant
* security suggestions, such as: it is recommended for most
* applications to use a mac length greater than 8. Besides, the
* usage of the same nonce for two different messages which are
* encrypted with the same key destroys the security of CCM mode.
*
* Requires: AES-128
*
* Usage: 1) call tc_ccm_config to configure.
*
* 2) call tc_ccm_mode_encrypt to encrypt data and generate tag.
*
* 3) call tc_ccm_mode_decrypt to decrypt data and verify tag.
*/
#ifndef __TC_CCM_MODE_H__
#define __TC_CCM_MODE_H__
#include <tinycrypt/aes.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* max additional authenticated size in bytes: 2^16 - 2^8 = 65280 */
#define TC_CCM_AAD_MAX_BYTES 0xff00
/* max message size in bytes: 2^(8L) = 2^16 = 65536 */
#define TC_CCM_PAYLOAD_MAX_BYTES 0x10000
/* struct tc_ccm_mode_struct represents the state of a CCM computation */
typedef struct tc_ccm_mode_struct {
TCAesKeySched_t sched; /* AES key schedule */
uint8_t *nonce; /* nonce required by CCM */
unsigned int mlen; /* mac length in bytes (parameter t in SP-800 38C) */
} *TCCcmMode_t;
/**
* @brief CCM configuration procedure
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* c == NULL or
* sched == NULL or
* nonce == NULL or
* mlen != {4, 6, 8, 10, 12, 16}
* @param c -- CCM state
* @param sched IN -- AES key schedule
* @param nonce IN - nonce
* @param nlen -- nonce length in bytes
* @param mlen -- mac length in bytes (parameter t in SP-800 38C)
*/
int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce,
unsigned int nlen, unsigned int mlen);
/**
* @brief CCM tag generation and encryption procedure
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL or
* c == NULL or
* ((plen > 0) and (payload == NULL)) or
* ((alen > 0) and (associated_data == NULL)) or
* (alen >= TC_CCM_AAD_MAX_BYTES) or
* (plen >= TC_CCM_PAYLOAD_MAX_BYTES) or
* (olen < plen + maclength)
*
* @param out OUT -- encrypted data
* @param olen IN -- output length in bytes
* @param associated_data IN -- associated data
* @param alen IN -- associated data length in bytes
* @param payload IN -- payload
* @param plen IN -- payload length in bytes
* @param c IN -- CCM state
*
* @note: out buffer should be at least (plen + c->mlen) bytes long.
*
* @note: The sequence b for encryption is formatted as follows:
* b = [FLAGS | nonce | counter ], where:
* FLAGS is 1 byte long
* nonce is 13 bytes long
* counter is 2 bytes long
* The byte FLAGS is composed by the following 8 bits:
* 0-2 bits: used to represent the value of q-1
* 3-7 btis: always 0's
*
* @note: The sequence b for authentication is formatted as follows:
* b = [FLAGS | nonce | length(mac length)], where:
* FLAGS is 1 byte long
* nonce is 13 bytes long
* length(mac length) is 2 bytes long
* The byte FLAGS is composed by the following 8 bits:
* 0-2 bits: used to represent the value of q-1
* 3-5 bits: mac length (encoded as: (mlen-2)/2)
* 6: Adata (0 if alen == 0, and 1 otherwise)
* 7: always 0
*/
int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen,
const uint8_t *associated_data,
unsigned int alen, const uint8_t *payload,
unsigned int plen, TCCcmMode_t c);
/**
* @brief CCM decryption and tag verification procedure
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL or
* c == NULL or
* ((plen > 0) and (payload == NULL)) or
* ((alen > 0) and (associated_data == NULL)) or
* (alen >= TC_CCM_AAD_MAX_BYTES) or
* (plen >= TC_CCM_PAYLOAD_MAX_BYTES) or
* (olen < plen - c->mlen)
*
* @param out OUT -- decrypted data
* @param associated_data IN -- associated data
* @param alen IN -- associated data length in bytes
* @param payload IN -- payload
* @param plen IN -- payload length in bytes
* @param c IN -- CCM state
*
* @note: out buffer should be at least (plen - c->mlen) bytes long.
*
* @note: The sequence b for encryption is formatted as follows:
* b = [FLAGS | nonce | counter ], where:
* FLAGS is 1 byte long
* nonce is 13 bytes long
* counter is 2 bytes long
* The byte FLAGS is composed by the following 8 bits:
* 0-2 bits: used to represent the value of q-1
* 3-7 btis: always 0's
*
* @note: The sequence b for authentication is formatted as follows:
* b = [FLAGS | nonce | length(mac length)], where:
* FLAGS is 1 byte long
* nonce is 13 bytes long
* length(mac length) is 2 bytes long
* The byte FLAGS is composed by the following 8 bits:
* 0-2 bits: used to represent the value of q-1
* 3-5 bits: mac length (encoded as: (mlen-2)/2)
* 6: Adata (0 if alen == 0, and 1 otherwise)
* 7: always 0
*/
int tc_ccm_decryption_verification(uint8_t *out, unsigned int olen,
const uint8_t *associated_data,
unsigned int alen, const uint8_t *payload, unsigned int plen,
TCCcmMode_t c);
#ifdef __cplusplus
}
#endif
#endif /* __TC_CCM_MODE_H__ */
@@ -0,0 +1,198 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to a CMAC implementation.
*
* Overview: CMAC is defined NIST in SP 800-38B, and is the standard algorithm
* for computing a MAC using a block cipher. It can compute the MAC
* for a byte string of any length. It is distinguished from CBC-MAC
* in the processing of the final message block; CMAC uses a
* different technique to compute the final message block is full
* size or only partial, while CBC-MAC uses the same technique for
* both. This difference permits CMAC to be applied to variable
* length messages, while all messages authenticated by CBC-MAC must
* be the same length.
*
* Security: AES128-CMAC mode of operation offers 64 bits of security against
* collision attacks. Note however that an external attacker cannot
* generate the tags him/herself without knowing the MAC key. In this
* sense, to attack the collision property of AES128-CMAC, an
* external attacker would need the cooperation of the legal user to
* produce an exponentially high number of tags (e.g. 2^64) to
* finally be able to look for collisions and benefit from them. As
* an extra precaution, the current implementation allows to at most
* 2^48 calls to the tc_cmac_update function before re-calling
* tc_cmac_setup (allowing a new key to be set), as suggested in
* Appendix B of SP 800-38B.
*
* Requires: AES-128
*
* Usage: This implementation provides a "scatter-gather" interface, so that
* the CMAC value can be computed incrementally over a message
* scattered in different segments throughout memory. Experience shows
* this style of interface tends to minimize the burden of programming
* correctly. Like all symmetric key operations, it is session
* oriented.
*
* To begin a CMAC session, use tc_cmac_setup to initialize a struct
* tc_cmac_struct with encryption key and buffer. Our implementation
* always assume that the AES key to be the same size as the block
* cipher block size. Once setup, this data structure can be used for
* many CMAC computations.
*
* Once the state has been setup with a key, computing the CMAC of
* some data requires three steps:
*
* (1) first use tc_cmac_init to initialize a new CMAC computation.
* (2) next mix all of the data into the CMAC computation state using
* tc_cmac_update. If all of the data resides in a single data
* segment then only one tc_cmac_update call is needed; if data
* is scattered throughout memory in n data segments, then n calls
* will be needed. CMAC IS ORDER SENSITIVE, to be able to detect
* attacks that swap bytes, so the order in which data is mixed
* into the state is critical!
* (3) Once all of the data for a message has been mixed, use
* tc_cmac_final to compute the CMAC tag value.
*
* Steps (1)-(3) can be repeated as many times as you want to CMAC
* multiple messages. A practical limit is 2^48 1K messages before you
* have to change the key.
*
* Once you are done computing CMAC with a key, it is a good idea to
* destroy the state so an attacker cannot recover the key; use
* tc_cmac_erase to accomplish this.
*/
#ifndef __TC_CMAC_MODE_H__
#define __TC_CMAC_MODE_H__
#include <tinycrypt/aes.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* padding for last message block */
#define TC_CMAC_PADDING 0x80
/* struct tc_cmac_struct represents the state of a CMAC computation */
typedef struct tc_cmac_struct {
/* initialization vector */
uint8_t iv[TC_AES_BLOCK_SIZE];
/* used if message length is a multiple of block_size bytes */
uint8_t K1[TC_AES_BLOCK_SIZE];
/* used if message length isn't a multiple block_size bytes */
uint8_t K2[TC_AES_BLOCK_SIZE];
/* where to put bytes that didn't fill a block */
uint8_t leftover[TC_AES_BLOCK_SIZE];
/* identifies the encryption key */
unsigned int keyid;
/* next available leftover location */
unsigned int leftover_offset;
/* AES key schedule */
TCAesKeySched_t sched;
/* calls to tc_cmac_update left before re-key */
uint64_t countdown;
} *TCCmacState_t;
/**
* @brief Configures the CMAC state to use the given AES key
* @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state
* returns TC_CRYPTO_FAIL (0) if:
* s == NULL or
* key == NULL
*
* @param s IN/OUT -- the state to set up
* @param key IN -- the key to use
* @param sched IN -- AES key schedule
*/
int tc_cmac_setup(TCCmacState_t s, const uint8_t *key,
TCAesKeySched_t sched);
/**
* @brief Erases the CMAC state
* @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state
* returns TC_CRYPTO_FAIL (0) if:
* s == NULL
*
* @param s IN/OUT -- the state to erase
*/
int tc_cmac_erase(TCCmacState_t s);
/**
* @brief Initializes a new CMAC computation
* @return returns TC_CRYPTO_SUCCESS (1) after having initialized the CMAC state
* returns TC_CRYPTO_FAIL (0) if:
* s == NULL
*
* @param s IN/OUT -- the state to initialize
*/
int tc_cmac_init(TCCmacState_t s);
/**
* @brief Incrementally computes CMAC over the next data segment
* @return returns TC_CRYPTO_SUCCESS (1) after successfully updating the CMAC state
* returns TC_CRYPTO_FAIL (0) if:
* s == NULL or
* if data == NULL when dlen > 0
*
* @param s IN/OUT -- the CMAC state
* @param data IN -- the next data segment to MAC
* @param dlen IN -- the length of data in bytes
*/
int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t dlen);
/**
* @brief Generates the tag from the CMAC state
* @return returns TC_CRYPTO_SUCCESS (1) after successfully generating the tag
* returns TC_CRYPTO_FAIL (0) if:
* tag == NULL or
* s == NULL
*
* @param tag OUT -- the CMAC tag
* @param s IN -- CMAC state
*/
int tc_cmac_final(uint8_t *tag, TCCmacState_t s);
#ifdef __cplusplus
}
#endif
#endif /* __TC_CMAC_MODE_H__ */
@@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief -- Interface to constants.
*
*/
#ifndef __TC_CONSTANTS_H__
#define __TC_CONSTANTS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#ifndef NULL
#define NULL ((void *)0)
#endif
#define TC_CRYPTO_SUCCESS 1
#define TC_CRYPTO_FAIL 0
#define TC_ZERO_BYTE 0x00
#ifdef __cplusplus
}
#endif
#endif /* __TC_CONSTANTS_H__ */
@@ -0,0 +1,112 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to CTR mode.
*
* Overview: CTR (pronounced "counter") mode is a NIST approved mode of
* operation defined in SP 800-38a. It can be used with any
* block cipher to provide confidentiality of strings of any
* length. TinyCrypt hard codes AES128 as the block cipher.
*
* Security: CTR mode achieves confidentiality only if the counter value is
* never reused with a same encryption key. If the counter is
* repeated, than an adversary might be able to defeat the scheme.
*
* A usual method to ensure different counter values refers to
* initialize the counter in a given value (0, for example) and
* increases it every time a new block is enciphered. This naturally
* leaves to a limitation on the number q of blocks that can be
* enciphered using a same key: q < 2^(counter size).
*
* TinyCrypt uses a counter of 32 bits. This means that after 2^32
* block encryptions, the counter will be reused (thus losing CBC
* security). 2^32 block encryptions should be enough for most of
* applications targeting constrained devices. Applications intended
* to encrypt a larger number of blocks must replace the key after
* 2^32 block encryptions.
*
* CTR mode provides NO data integrity.
*
* Requires: AES-128
*
* Usage: 1) call tc_ctr_mode to process the data to encrypt/decrypt.
*
*/
#ifndef __TC_CTR_MODE_H__
#define __TC_CTR_MODE_H__
#include <tinycrypt/aes.h>
#include <tinycrypt/constants.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief CTR mode encryption/decryption procedure.
* CTR mode encrypts (or decrypts) inlen bytes from in buffer into out buffer
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL or
* in == NULL or
* ctr == NULL or
* sched == NULL or
* inlen == 0 or
* outlen == 0 or
* inlen != outlen
* @note Assumes:- The current value in ctr has NOT been used with sched
* - out points to inlen bytes
* - in points to inlen bytes
* - ctr is an integer counter in littleEndian format
* - sched was initialized by aes_set_encrypt_key
* @param out OUT -- produced ciphertext (plaintext)
* @param outlen IN -- length of ciphertext buffer in bytes
* @param in IN -- data to encrypt (or decrypt)
* @param inlen IN -- length of input data in bytes
* @param ctr IN/OUT -- the current counter value
* @param sched IN -- an initialized AES key schedule
*/
int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched);
#ifdef __cplusplus
}
#endif
#endif /* __TC_CTR_MODE_H__ */
@@ -0,0 +1,172 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ctr_prng.h - TinyCrypt interface to a CTR-PRNG implementation */
/*
* Copyright (c) 2016, Chris Morrison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to a CTR-PRNG implementation.
*
* Overview: A pseudo-random number generator (PRNG) generates a sequence
* of numbers that have a distribution close to the one expected
* for a sequence of truly random numbers. The NIST Special
* Publication 800-90A specifies several mechanisms to generate
* sequences of pseudo random numbers, including the CTR-PRNG one
* which is based on AES. TinyCrypt implements CTR-PRNG with
* AES-128.
*
* Security: A cryptographically secure PRNG depends on the existence of an
* entropy source to provide a truly random seed as well as the
* security of the primitives used as the building blocks (AES-128
* in this instance).
*
* Requires: - AES-128
*
* Usage: 1) call tc_ctr_prng_init to seed the prng context
*
* 2) call tc_ctr_prng_reseed to mix in additional entropy into
* the prng context
*
* 3) call tc_ctr_prng_generate to output the pseudo-random data
*
* 4) call tc_ctr_prng_uninstantiate to zero out the prng context
*/
#ifndef __TC_CTR_PRNG_H__
#define __TC_CTR_PRNG_H__
#include <tinycrypt/aes.h>
#define TC_CTR_PRNG_RESEED_REQ -1
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
/* updated each time another BLOCKLEN_BYTES bytes are produced */
uint8_t V[TC_AES_BLOCK_SIZE];
/* updated whenever the PRNG is reseeded */
struct tc_aes_key_sched_struct key;
/* number of requests since initialization/reseeding */
uint64_t reseedCount;
} TCCtrPrng_t;
/**
* @brief CTR-PRNG initialization procedure
* Initializes prng context with entropy and personalization string (if any)
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* ctx == NULL,
* entropy == NULL,
* entropyLen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE)
* @note Only the first (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes of
* both the entropy and personalization inputs are used -
* supplying additional bytes has no effect.
* @param ctx IN/OUT -- the PRNG context to initialize
* @param entropy IN -- entropy used to seed the PRNG
* @param entropyLen IN -- entropy length in bytes
* @param personalization IN -- personalization string used to seed the PRNG
* (may be null)
* @param plen IN -- personalization length in bytes
*
*/
int tc_ctr_prng_init(TCCtrPrng_t * const ctx,
uint8_t const * const entropy,
unsigned int entropyLen,
uint8_t const * const personalization,
unsigned int pLen);
/**
* @brief CTR-PRNG reseed procedure
* Mixes entropy and additional_input into the prng context
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* ctx == NULL,
* entropy == NULL,
* entropylen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE)
* @note It is better to reseed an existing prng context rather than
* re-initialise, so that any existing entropy in the context is
* presereved. This offers some protection against undetected failures
* of the entropy source.
* @note Assumes tc_ctr_prng_init has been called for ctx
* @param ctx IN/OUT -- the PRNG state
* @param entropy IN -- entropy to mix into the prng
* @param entropylen IN -- length of entropy in bytes
* @param additional_input IN -- additional input to the prng (may be null)
* @param additionallen IN -- additional input length in bytes
*/
int tc_ctr_prng_reseed(TCCtrPrng_t * const ctx,
uint8_t const * const entropy,
unsigned int entropyLen,
uint8_t const * const additional_input,
unsigned int additionallen);
/**
* @brief CTR-PRNG generate procedure
* Generates outlen pseudo-random bytes into out buffer, updates prng
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CTR_PRNG_RESEED_REQ (-1) if a reseed is needed
* returns TC_CRYPTO_FAIL (0) if:
* ctx == NULL,
* out == NULL,
* outlen >= 2^16
* @note Assumes tc_ctr_prng_init has been called for ctx
* @param ctx IN/OUT -- the PRNG context
* @param additional_input IN -- additional input to the prng (may be null)
* @param additionallen IN -- additional input length in bytes
* @param out IN/OUT -- buffer to receive output
* @param outlen IN -- size of out buffer in bytes
*/
int tc_ctr_prng_generate(TCCtrPrng_t * const ctx,
uint8_t const * const additional_input,
unsigned int additionallen,
uint8_t * const out,
unsigned int outlen);
/**
* @brief CTR-PRNG uninstantiate procedure
* Zeroes the internal state of the supplied prng context
* @return none
* @param ctx IN/OUT -- the PRNG context
*/
void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx);
#ifdef __cplusplus
}
#endif
#endif /* __TC_CTR_PRNG_H__ */
@@ -0,0 +1,551 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ecc.h - TinyCrypt interface to common ECC functions */
/* Copyright (c) 2014, Kenneth MacKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief -- Interface to common ECC functions.
*
* Overview: This software is an implementation of common functions
* necessary to elliptic curve cryptography. This implementation uses
* curve NIST p-256.
*
* Security: The curve NIST p-256 provides approximately 128 bits of security.
*
*/
#ifndef __TC_UECC_H__
#define __TC_UECC_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Word size (4 bytes considering 32-bits architectures) */
#define uECC_WORD_SIZE 4
/* setting max number of calls to prng: */
#ifndef uECC_RNG_MAX_TRIES
#define uECC_RNG_MAX_TRIES 64
#endif
/* defining data types to store word and bit counts: */
typedef int8_t wordcount_t;
typedef int16_t bitcount_t;
/* defining data type for comparison result: */
typedef int8_t cmpresult_t;
/* defining data type to store ECC coordinate/point in 32bits words: */
typedef unsigned int uECC_word_t;
/* defining data type to store an ECC coordinate/point in 64bits words: */
typedef uint64_t uECC_dword_t;
/* defining masks useful for ecc computations: */
#define HIGH_BIT_SET 0x80000000
#define uECC_WORD_BITS 32
#define uECC_WORD_BITS_SHIFT 5
#define uECC_WORD_BITS_MASK 0x01F
/* Number of words of 32 bits to represent an element of the the curve p-256: */
#define NUM_ECC_WORDS 8
/* Number of bytes to represent an element of the the curve p-256: */
#define NUM_ECC_BYTES (uECC_WORD_SIZE*NUM_ECC_WORDS)
/* structure that represents an elliptic curve (e.g. p256):*/
struct uECC_Curve_t;
typedef const struct uECC_Curve_t * uECC_Curve;
struct uECC_Curve_t {
wordcount_t num_words;
wordcount_t num_bytes;
bitcount_t num_n_bits;
uECC_word_t p[NUM_ECC_WORDS];
uECC_word_t n[NUM_ECC_WORDS];
uECC_word_t G[NUM_ECC_WORDS * 2];
uECC_word_t b[NUM_ECC_WORDS];
void (*double_jacobian)(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t * Z1,
uECC_Curve curve);
void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve);
void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product);
};
/*
* @brief computes doubling of point ion jacobian coordinates, in place.
* @param X1 IN/OUT -- x coordinate
* @param Y1 IN/OUT -- y coordinate
* @param Z1 IN/OUT -- z coordinate
* @param curve IN -- elliptic curve
*/
void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1,
uECC_word_t * Z1, uECC_Curve curve);
/*
* @brief Computes x^3 + ax + b. result must not overlap x.
* @param result OUT -- x^3 + ax + b
* @param x IN -- value of x
* @param curve IN -- elliptic curve
*/
void x_side_default(uECC_word_t *result, const uECC_word_t *x,
uECC_Curve curve);
/*
* @brief Computes result = product % curve_p
* from http://www.nsa.gov/ia/_files/nist-routines.pdf
* @param result OUT -- product % curve_p
* @param product IN -- value to be reduced mod curve_p
*/
void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int *product);
/* Bytes to words ordering: */
#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e
#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a
#define BITS_TO_WORDS(num_bits) \
((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
#define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8)
/* definition of curve NIST p-256: */
static const struct uECC_Curve_t curve_secp256r1 = {
NUM_ECC_WORDS,
NUM_ECC_BYTES,
256, /* num_n_bits */ {
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00),
BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF)
}, {
BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3),
BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF)
}, {
BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4),
BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77),
BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8),
BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B),
BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB),
BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B),
BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E),
BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F)
}, {
BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B),
BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65),
BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3),
BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A)
},
&double_jacobian_default,
&x_side_default,
&vli_mmod_fast_secp256r1
};
uECC_Curve uECC_secp256r1(void);
/*
* @brief Generates a random integer in the range 0 < random < top.
* Both random and top have num_words words.
* @param random OUT -- random integer in the range 0 < random < top
* @param top IN -- upper limit
* @param num_words IN -- number of words
* @return a random integer in the range 0 < random < top
*/
int uECC_generate_random_int(uECC_word_t *random, const uECC_word_t *top,
wordcount_t num_words);
/* uECC_RNG_Function type
* The RNG function should fill 'size' random bytes into 'dest'. It should
* return 1 if 'dest' was filled with random data, or 0 if the random data could
* not be generated. The filled-in values should be either truly random, or from
* a cryptographically-secure PRNG.
*
* A correctly functioning RNG function must be set (using uECC_set_rng())
* before calling uECC_make_key() or uECC_sign().
*
* Setting a correctly functioning RNG function improves the resistance to
* side-channel attacks for uECC_shared_secret().
*
* A correct RNG function is set by default. If you are building on another
* POSIX-compliant system that supports /dev/random or /dev/urandom, you can
* define uECC_POSIX to use the predefined RNG.
*/
typedef int(*uECC_RNG_Function)(uint8_t *dest, unsigned int size);
/*
* @brief Set the function that will be used to generate random bytes. The RNG
* function should return 1 if the random data was generated, or 0 if the random
* data could not be generated.
*
* @note On platforms where there is no predefined RNG function, this must be
* called before uECC_make_key() or uECC_sign() are used.
*
* @param rng_function IN -- function that will be used to generate random bytes
*/
void uECC_set_rng(uECC_RNG_Function rng_function);
/*
* @brief provides current uECC_RNG_Function.
* @return Returns the function that will be used to generate random bytes.
*/
uECC_RNG_Function uECC_get_rng(void);
/*
* @brief computes the size of a private key for the curve in bytes.
* @param curve IN -- elliptic curve
* @return size of a private key for the curve in bytes.
*/
int uECC_curve_private_key_size(uECC_Curve curve);
/*
* @brief computes the size of a public key for the curve in bytes.
* @param curve IN -- elliptic curve
* @return the size of a public key for the curve in bytes.
*/
int uECC_curve_public_key_size(uECC_Curve curve);
/*
* @brief Compute the corresponding public key for a private key.
* @param private_key IN -- The private key to compute the public key for
* @param public_key OUT -- Will be filled in with the corresponding public key
* @param curve
* @return Returns 1 if key was computed successfully, 0 if an error occurred.
*/
int uECC_compute_public_key(const uint8_t *private_key,
uint8_t *public_key, uECC_Curve curve);
/*
* @brief Compute public-key.
* @return corresponding public-key.
* @param result OUT -- public-key
* @param private_key IN -- private-key
* @param curve IN -- elliptic curve
*/
uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
uECC_word_t *private_key, uECC_Curve curve);
/*
* @brief Regularize the bitcount for the private key so that attackers cannot
* use a side channel attack to learn the number of leading zeros.
* @return Regularized k
* @param k IN -- private-key
* @param k0 IN/OUT -- regularized k
* @param k1 IN/OUT -- regularized k
* @param curve IN -- elliptic curve
*/
uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0,
uECC_word_t *k1, uECC_Curve curve);
/*
* @brief Point multiplication algorithm using Montgomery's ladder with co-Z
* coordinates. See http://eprint.iacr.org/2011/338.pdf.
* @note Result may overlap point.
* @param result OUT -- returns scalar*point
* @param point IN -- elliptic curve point
* @param scalar IN -- scalar
* @param initial_Z IN -- initial value for z
* @param num_bits IN -- number of bits in scalar
* @param curve IN -- elliptic curve
*/
void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
const uECC_word_t * scalar, const uECC_word_t * initial_Z,
bitcount_t num_bits, uECC_Curve curve);
/*
* @brief Constant-time comparison to zero - secure way to compare long integers
* @param vli IN -- very long integer
* @param num_words IN -- number of words in the vli
* @return 1 if vli == 0, 0 otherwise.
*/
uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words);
/*
* @brief Check if 'point' is the point at infinity
* @param point IN -- elliptic curve point
* @param curve IN -- elliptic curve
* @return if 'point' is the point at infinity, 0 otherwise.
*/
uECC_word_t EccPoint_isZero(const uECC_word_t *point, uECC_Curve curve);
/*
* @brief computes the sign of left - right, in constant time.
* @param left IN -- left term to be compared
* @param right IN -- right term to be compared
* @param num_words IN -- number of words
* @return the sign of left - right
*/
cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right,
wordcount_t num_words);
/*
* @brief computes sign of left - right, not in constant time.
* @note should not be used if inputs are part of a secret
* @param left IN -- left term to be compared
* @param right IN -- right term to be compared
* @param num_words IN -- number of words
* @return the sign of left - right
*/
cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, const uECC_word_t *right,
wordcount_t num_words);
/*
* @brief Computes result = (left - right) % mod.
* @note Assumes that (left < mod) and (right < mod), and that result does not
* overlap mod.
* @param result OUT -- (left - right) % mod
* @param left IN -- leftright term in modular subtraction
* @param right IN -- right term in modular subtraction
* @param mod IN -- mod
* @param num_words IN -- number of words
*/
void uECC_vli_modSub(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right, const uECC_word_t *mod,
wordcount_t num_words);
/*
* @brief Computes P' = (x1', y1', Z3), P + Q = (x3, y3, Z3) or
* P => P', Q => P + Q
* @note assumes Input P = (x1, y1, Z), Q = (x2, y2, Z)
* @param X1 IN -- x coordinate of P
* @param Y1 IN -- y coordinate of P
* @param X2 IN -- x coordinate of Q
* @param Y2 IN -- y coordinate of Q
* @param curve IN -- elliptic curve
*/
void XYcZ_add(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t * X2,
uECC_word_t * Y2, uECC_Curve curve);
/*
* @brief Computes (x1 * z^2, y1 * z^3)
* @param X1 IN -- previous x1 coordinate
* @param Y1 IN -- previous y1 coordinate
* @param Z IN -- z value
* @param curve IN -- elliptic curve
*/
void apply_z(uECC_word_t * X1, uECC_word_t * Y1, const uECC_word_t * const Z,
uECC_Curve curve);
/*
* @brief Check if bit is set.
* @return Returns nonzero if bit 'bit' of vli is set.
* @warning It is assumed that the value provided in 'bit' is within the
* boundaries of the word-array 'vli'.
* @note The bit ordering layout assumed for vli is: {31, 30, ..., 0},
* {63, 62, ..., 32}, {95, 94, ..., 64}, {127, 126,..., 96} for a vli consisting
* of 4 uECC_word_t elements.
*/
uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit);
/*
* @brief Computes result = product % mod, where product is 2N words long.
* @param result OUT -- product % mod
* @param mod IN -- module
* @param num_words IN -- number of words
* @warning Currently only designed to work for curve_p or curve_n.
*/
void uECC_vli_mmod(uECC_word_t *result, uECC_word_t *product,
const uECC_word_t *mod, wordcount_t num_words);
/*
* @brief Computes modular product (using curve->mmod_fast)
* @param result OUT -- (left * right) mod % curve_p
* @param left IN -- left term in product
* @param right IN -- right term in product
* @param curve IN -- elliptic curve
*/
void uECC_vli_modMult_fast(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right, uECC_Curve curve);
/*
* @brief Computes result = left - right.
* @note Can modify in place.
* @param result OUT -- left - right
* @param left IN -- left term in subtraction
* @param right IN -- right term in subtraction
* @param num_words IN -- number of words
* @return borrow
*/
uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right, wordcount_t num_words);
/*
* @brief Constant-time comparison function(secure way to compare long ints)
* @param left IN -- left term in comparison
* @param right IN -- right term in comparison
* @param num_words IN -- number of words
* @return Returns 0 if left == right, 1 otherwise.
*/
uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right,
wordcount_t num_words);
/*
* @brief Computes (left * right) % mod
* @param result OUT -- (left * right) % mod
* @param left IN -- left term in product
* @param right IN -- right term in product
* @param mod IN -- mod
* @param num_words IN -- number of words
*/
void uECC_vli_modMult(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right, const uECC_word_t *mod,
wordcount_t num_words);
/*
* @brief Computes (1 / input) % mod
* @note All VLIs are the same size.
* @note See "Euclid's GCD to Montgomery Multiplication to the Great Divide"
* @param result OUT -- (1 / input) % mod
* @param input IN -- value to be modular inverted
* @param mod IN -- mod
* @param num_words -- number of words
*/
void uECC_vli_modInv(uECC_word_t *result, const uECC_word_t *input,
const uECC_word_t *mod, wordcount_t num_words);
/*
* @brief Sets dest = src.
* @param dest OUT -- destination buffer
* @param src IN -- origin buffer
* @param num_words IN -- number of words
*/
void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src,
wordcount_t num_words);
/*
* @brief Computes (left + right) % mod.
* @note Assumes that (left < mod) and right < mod), and that result does not
* overlap mod.
* @param result OUT -- (left + right) % mod.
* @param left IN -- left term in addition
* @param right IN -- right term in addition
* @param mod IN -- mod
* @param num_words IN -- number of words
*/
void uECC_vli_modAdd(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right, const uECC_word_t *mod,
wordcount_t num_words);
/*
* @brief Counts the number of bits required to represent vli.
* @param vli IN -- very long integer
* @param max_words IN -- number of words
* @return number of bits in given vli
*/
bitcount_t uECC_vli_numBits(const uECC_word_t *vli,
const wordcount_t max_words);
/*
* @brief Erases (set to 0) vli
* @param vli IN -- very long integer
* @param num_words IN -- number of words
*/
void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words);
/*
* @brief check if it is a valid point in the curve
* @param point IN -- point to be checked
* @param curve IN -- elliptic curve
* @return 0 if point is valid
* @exception returns -1 if it is a point at infinity
* @exception returns -2 if x or y is smaller than p,
* @exception returns -3 if y^2 != x^3 + ax + b.
*/
int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve);
/*
* @brief Check if a public key is valid.
* @param public_key IN -- The public key to be checked.
* @return returns 0 if the public key is valid
* @exception returns -1 if it is a point at infinity
* @exception returns -2 if x or y is smaller than p,
* @exception returns -3 if y^2 != x^3 + ax + b.
* @exception returns -4 if public key is the group generator.
*
* @note Note that you are not required to check for a valid public key before
* using any other uECC functions. However, you may wish to avoid spending CPU
* time computing a shared secret or verifying a signature using an invalid
* public key.
*/
int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve);
/*
* @brief Converts an integer in uECC native format to big-endian bytes.
* @param bytes OUT -- bytes representation
* @param num_bytes IN -- number of bytes
* @param native IN -- uECC native representation
*/
void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
const unsigned int *native);
/*
* @brief Converts big-endian bytes to an integer in uECC native format.
* @param native OUT -- uECC native representation
* @param bytes IN -- bytes representation
* @param num_bytes IN -- number of bytes
*/
void uECC_vli_bytesToNative(unsigned int *native, const uint8_t *bytes,
int num_bytes);
#ifdef __cplusplus
}
#endif
#endif /* __TC_UECC_H__ */
@@ -0,0 +1,135 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (c) 2014, Kenneth MacKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief -- Interface to EC-DH implementation.
*
* Overview: This software is an implementation of EC-DH. This implementation
* uses curve NIST p-256.
*
* Security: The curve NIST p-256 provides approximately 128 bits of security.
*/
#ifndef __TC_ECC_DH_H__
#define __TC_ECC_DH_H__
#include <tinycrypt/ecc.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Create a public/private key pair.
* @return returns TC_CRYPTO_SUCCESS (1) if the key pair was generated successfully
* returns TC_CRYPTO_FAIL (0) if error while generating key pair
*
* @param p_public_key OUT -- Will be filled in with the public key. Must be at
* least 2 * the curve size (in bytes) long. For curve secp256r1, p_public_key
* must be 64 bytes long.
* @param p_private_key OUT -- Will be filled in with the private key. Must be as
* long as the curve order (for secp256r1, p_private_key must be 32 bytes long).
*
* @note side-channel countermeasure: algorithm strengthened against timing
* attack.
* @warning A cryptographically-secure PRNG function must be set (using
* uECC_set_rng()) before calling uECC_make_key().
*/
int uECC_make_key(uint8_t *p_public_key, uint8_t *p_private_key, uECC_Curve curve);
#ifdef ENABLE_TESTS
/**
* @brief Create a public/private key pair given a specific d.
*
* @note THIS FUNCTION SHOULD BE CALLED ONLY FOR TEST PURPOSES. Refer to
* uECC_make_key() function for real applications.
*/
int uECC_make_key_with_d(uint8_t *p_public_key, uint8_t *p_private_key,
unsigned int *d, uECC_Curve curve);
#endif
/**
* @brief Compute a shared secret given your secret key and someone else's
* public key.
* @return returns TC_CRYPTO_SUCCESS (1) if the shared secret was computed successfully
* returns TC_CRYPTO_FAIL (0) otherwise
*
* @param p_secret OUT -- Will be filled in with the shared secret value. Must be
* the same size as the curve size (for curve secp256r1, secret must be 32 bytes
* long.
* @param p_public_key IN -- The public key of the remote party.
* @param p_private_key IN -- Your private key.
*
* @warning It is recommended to use the output of uECC_shared_secret() as the
* input of a recommended Key Derivation Function (see NIST SP 800-108) in
* order to produce a cryptographically secure symmetric key.
*/
int uECC_shared_secret(const uint8_t *p_public_key, const uint8_t *p_private_key,
uint8_t *p_secret, uECC_Curve curve);
#ifdef __cplusplus
}
#endif
#endif /* __TC_ECC_DH_H__ */
@@ -0,0 +1,145 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ecc_dh.h - TinyCrypt interface to EC-DSA implementation */
/*
* Copyright (c) 2014, Kenneth MacKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief -- Interface to EC-DSA implementation.
*
* Overview: This software is an implementation of EC-DSA. This implementation
* uses curve NIST p-256.
*
* Security: The curve NIST p-256 provides approximately 128 bits of security.
*
* Usage: - To sign: Compute a hash of the data you wish to sign (SHA-2 is
* recommended) and pass it in to ecdsa_sign function along with your
* private key and a random number. You must use a new non-predictable
* random number to generate each new signature.
* - To verify a signature: Compute the hash of the signed data using
* the same hash as the signer and pass it to this function along with
* the signer's public key and the signature values (r and s).
*/
#ifndef __TC_ECC_DSA_H__
#define __TC_ECC_DSA_H__
#include <tinycrypt/ecc.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Generate an ECDSA signature for a given hash value.
* @return returns TC_CRYPTO_SUCCESS (1) if the signature generated successfully
* returns TC_CRYPTO_FAIL (0) if an error occurred.
*
* @param p_private_key IN -- Your private key.
* @param p_message_hash IN -- The hash of the message to sign.
* @param p_hash_size IN -- The size of p_message_hash in bytes.
* @param p_signature OUT -- Will be filled in with the signature value. Must be
* at least 2 * curve size long (for secp256r1, signature must be 64 bytes long).
*
* @warning A cryptographically-secure PRNG function must be set (using
* uECC_set_rng()) before calling uECC_sign().
* @note Usage: Compute a hash of the data you wish to sign (SHA-2 is
* recommended) and pass it in to this function along with your private key.
* @note side-channel countermeasure: algorithm strengthened against timing
* attack.
*/
int uECC_sign(const uint8_t *p_private_key, const uint8_t *p_message_hash,
unsigned p_hash_size, uint8_t *p_signature, uECC_Curve curve);
#ifdef ENABLE_TESTS
/*
* THIS FUNCTION SHOULD BE CALLED FOR TEST PURPOSES ONLY.
* Refer to uECC_sign() function for real applications.
*/
int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
unsigned int hash_size, uECC_word_t *k, uint8_t *signature,
uECC_Curve curve);
#endif
/**
* @brief Verify an ECDSA signature.
* @return returns TC_SUCCESS (1) if the signature is valid
* returns TC_FAIL (0) if the signature is invalid.
*
* @param p_public_key IN -- The signer's public key.
* @param p_message_hash IN -- The hash of the signed data.
* @param p_hash_size IN -- The size of p_message_hash in bytes.
* @param p_signature IN -- The signature values.
*
* @note Usage: Compute the hash of the signed data using the same hash as the
* signer and pass it to this function along with the signer's public key and
* the signature values (hash_size and signature).
*/
int uECC_verify(const uint8_t *p_public_key, const uint8_t *p_message_hash,
unsigned int p_hash_size, const uint8_t *p_signature, uECC_Curve curve);
#ifdef __cplusplus
}
#endif
#endif /* __TC_ECC_DSA_H__ */
@@ -0,0 +1,85 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Copyright (c) 2014, Kenneth MacKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* uECC_platform_specific.h -- Interface to platform specific functions
*/
#ifndef __UECC_PLATFORM_SPECIFIC_H_
#define __UECC_PLATFORM_SPECIFIC_H_
/*
* The RNG function should fill 'size' random bytes into 'dest'. It should
* return 1 if 'dest' was filled with random data, or 0 if the random data could
* not be generated. The filled-in values should be either truly random, or from
* a cryptographically-secure PRNG.
*
* A cryptographically-secure PRNG function must be set (using uECC_set_rng())
* before calling uECC_make_key() or uECC_sign().
*
* Setting a cryptographically-secure PRNG function improves the resistance to
* side-channel attacks for uECC_shared_secret().
*
* A correct PRNG function is set by default (default_RNG_defined = 1) and works
* for some platforms, such as Unix and Linux. For other platforms, you may need
* to provide another PRNG function.
*/
#define default_RNG_defined 0
int default_CSPRNG(uint8_t *dest, unsigned int size);
#endif /* __UECC_PLATFORM_SPECIFIC_H_ */
@@ -0,0 +1,143 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to an HMAC implementation.
*
* Overview: HMAC is a message authentication code based on hash functions.
* TinyCrypt hard codes SHA-256 as the hash function. A message
* authentication code based on hash functions is also called a
* keyed cryptographic hash function since it performs a
* transformation specified by a key in an arbitrary length data
* set into a fixed length data set (also called tag).
*
* Security: The security of the HMAC depends on the length of the key and
* on the security of the hash function. Note that HMAC primitives
* are much less affected by collision attacks than their
* corresponding hash functions.
*
* Requires: SHA-256
*
* Usage: 1) call tc_hmac_set_key to set the HMAC key.
*
* 2) call tc_hmac_init to initialize a struct hash_state before
* processing the data.
*
* 3) call tc_hmac_update to process the next input segment;
* tc_hmac_update can be called as many times as needed to process
* all of the segments of the input; the order is important.
*
* 4) call tc_hmac_final to out put the tag.
*/
#ifndef __TC_HMAC_H__
#define __TC_HMAC_H__
#include <tinycrypt/sha256.h>
#ifdef __cplusplus
extern "C" {
#endif
struct tc_hmac_state_struct {
/* the internal state required by h */
struct tc_sha256_state_struct hash_state;
/* HMAC key schedule */
uint8_t key[2*TC_SHA256_BLOCK_SIZE];
};
typedef struct tc_hmac_state_struct *TCHmacState_t;
/**
* @brief HMAC set key procedure
* Configures ctx to use key
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if
* ctx == NULL or
* key == NULL or
* key_size == 0
* @param ctx IN/OUT -- the struct tc_hmac_state_struct to initial
* @param key IN -- the HMAC key to configure
* @param key_size IN -- the HMAC key size
*/
int tc_hmac_set_key(TCHmacState_t ctx, const uint8_t *key,
unsigned int key_size);
/**
* @brief HMAC init procedure
* Initializes ctx to begin the next HMAC operation
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL
* @param ctx IN/OUT -- struct tc_hmac_state_struct buffer to init
*/
int tc_hmac_init(TCHmacState_t ctx);
/**
* @brief HMAC update procedure
* Mixes data_length bytes addressed by data into state
* @return returns TC_CRYPTO_SUCCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL
* @note Assumes state has been initialized by tc_hmac_init
* @param ctx IN/OUT -- state of HMAC computation so far
* @param data IN -- data to incorporate into state
* @param data_length IN -- size of data in bytes
*/
int tc_hmac_update(TCHmacState_t ctx, const void *data,
unsigned int data_length);
/**
* @brief HMAC final procedure
* Writes the HMAC tag into the tag buffer
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* tag == NULL or
* ctx == NULL or
* key == NULL or
* taglen != TC_SHA256_DIGEST_SIZE
* @note ctx is erased before exiting. This should never be changed/removed.
* @note Assumes the tag buffer is at least sizeof(hmac_tag_size(state)) bytes
* state has been initialized by tc_hmac_init
* @param tag IN/OUT -- buffer to receive computed HMAC tag
* @param taglen IN -- size of tag in bytes
* @param ctx IN/OUT -- the HMAC state for computing tag
*/
int tc_hmac_final(uint8_t *tag, unsigned int taglen, TCHmacState_t ctx);
#ifdef __cplusplus
}
#endif
#endif /*__TC_HMAC_H__*/
@@ -0,0 +1,168 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to an HMAC-PRNG implementation.
*
* Overview: A pseudo-random number generator (PRNG) generates a sequence
* of numbers that have a distribution close to the one expected
* for a sequence of truly random numbers. The NIST Special
* Publication 800-90A specifies several mechanisms to generate
* sequences of pseudo random numbers, including the HMAC-PRNG one
* which is based on HMAC. TinyCrypt implements HMAC-PRNG with
* certain modifications from the NIST SP 800-90A spec.
*
* Security: A cryptographically secure PRNG depends on the existence of an
* entropy source to provide a truly random seed as well as the
* security of the primitives used as the building blocks (HMAC and
* SHA256, for TinyCrypt).
*
* The NIST SP 800-90A standard tolerates a null personalization,
* while TinyCrypt requires a non-null personalization. This is
* because a personalization string (the host name concatenated
* with a time stamp, for example) is easily computed and might be
* the last line of defense against failure of the entropy source.
*
* Requires: - SHA-256
* - HMAC
*
* Usage: 1) call tc_hmac_prng_init to set the HMAC key and process the
* personalization data.
*
* 2) call tc_hmac_prng_reseed to process the seed and additional
* input.
*
* 3) call tc_hmac_prng_generate to out put the pseudo-random data.
*/
#ifndef __TC_HMAC_PRNG_H__
#define __TC_HMAC_PRNG_H__
#include <tinycrypt/sha256.h>
#include <tinycrypt/hmac.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TC_HMAC_PRNG_RESEED_REQ -1
struct tc_hmac_prng_struct {
/* the HMAC instance for this PRNG */
struct tc_hmac_state_struct h;
/* the PRNG key */
uint8_t key[TC_SHA256_DIGEST_SIZE];
/* PRNG state */
uint8_t v[TC_SHA256_DIGEST_SIZE];
/* calls to tc_hmac_prng_generate left before re-seed */
unsigned int countdown;
};
typedef struct tc_hmac_prng_struct *TCHmacPrng_t;
/**
* @brief HMAC-PRNG initialization procedure
* Initializes prng with personalization, disables tc_hmac_prng_generate
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* prng == NULL,
* personalization == NULL,
* plen > MAX_PLEN
* @note Assumes: - personalization != NULL.
* The personalization is a platform unique string (e.g., the host
* name) and is the last line of defense against failure of the
* entropy source
* @warning NIST SP 800-90A specifies 3 items as seed material during
* initialization: entropy seed, personalization, and an optional
* nonce. TinyCrypts requires instead a non-null personalization
* (which is easily computed) and indirectly requires an entropy
* seed (since the reseed function is mandatorily called after
* init)
* @param prng IN/OUT -- the PRNG state to initialize
* @param personalization IN -- personalization string
* @param plen IN -- personalization length in bytes
*/
int tc_hmac_prng_init(TCHmacPrng_t prng,
const uint8_t *personalization,
unsigned int plen);
/**
* @brief HMAC-PRNG reseed procedure
* Mixes seed into prng, enables tc_hmac_prng_generate
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* prng == NULL,
* seed == NULL,
* seedlen < MIN_SLEN,
* seendlen > MAX_SLEN,
* additional_input != (const uint8_t *) 0 && additionallen == 0,
* additional_input != (const uint8_t *) 0 && additionallen > MAX_ALEN
* @note Assumes:- tc_hmac_prng_init has been called for prng
* - seed has sufficient entropy.
*
* @param prng IN/OUT -- the PRNG state
* @param seed IN -- entropy to mix into the prng
* @param seedlen IN -- length of seed in bytes
* @param additional_input IN -- additional input to the prng
* @param additionallen IN -- additional input length in bytes
*/
int tc_hmac_prng_reseed(TCHmacPrng_t prng, const uint8_t *seed,
unsigned int seedlen, const uint8_t *additional_input,
unsigned int additionallen);
/**
* @brief HMAC-PRNG generate procedure
* Generates outlen pseudo-random bytes into out buffer, updates prng
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_HMAC_PRNG_RESEED_REQ (-1) if a reseed is needed
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL,
* prng == NULL,
* outlen == 0,
* outlen >= MAX_OUT
* @note Assumes tc_hmac_prng_init has been called for prng
* @param out IN/OUT -- buffer to receive output
* @param outlen IN -- size of out buffer in bytes
* @param prng IN/OUT -- the PRNG state
*/
int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng);
#ifdef __cplusplus
}
#endif
#endif /* __TC_HMAC_PRNG_H__ */
@@ -0,0 +1,135 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* sha256.h - TinyCrypt interface to a SHA-256 implementation */
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to a SHA-256 implementation.
*
* Overview: SHA-256 is a NIST approved cryptographic hashing algorithm
* specified in FIPS 180. A hash algorithm maps data of arbitrary
* size to data of fixed length.
*
* Security: SHA-256 provides 128 bits of security against collision attacks
* and 256 bits of security against pre-image attacks. SHA-256 does
* NOT behave like a random oracle, but it can be used as one if
* the string being hashed is prefix-free encoded before hashing.
*
* Usage: 1) call tc_sha256_init to initialize a struct
* tc_sha256_state_struct before hashing a new string.
*
* 2) call tc_sha256_update to hash the next string segment;
* tc_sha256_update can be called as many times as needed to hash
* all of the segments of a string; the order is important.
*
* 3) call tc_sha256_final to out put the digest from a hashing
* operation.
*/
#ifndef __TC_SHA256_H__
#define __TC_SHA256_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TC_SHA256_BLOCK_SIZE (64)
#define TC_SHA256_DIGEST_SIZE (32)
#define TC_SHA256_STATE_BLOCKS (TC_SHA256_DIGEST_SIZE/4)
struct tc_sha256_state_struct {
unsigned int iv[TC_SHA256_STATE_BLOCKS];
uint64_t bits_hashed;
uint8_t leftover[TC_SHA256_BLOCK_SIZE];
size_t leftover_offset;
};
typedef struct tc_sha256_state_struct *TCSha256State_t;
/**
* @brief SHA256 initialization procedure
* Initializes s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if s == NULL
* @param s Sha256 state struct
*/
int tc_sha256_init(TCSha256State_t s);
/**
* @brief SHA256 update procedure
* Hashes data_length bytes addressed by data into state s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* s == NULL,
* s->iv == NULL,
* data == NULL
* @note Assumes s has been initialized by tc_sha256_init
* @warning The state buffer 'leftover' is left in memory after processing
* If your application intends to have sensitive data in this
* buffer, remind to erase it after the data has been processed
* @param s Sha256 state struct
* @param data message to hash
* @param datalen length of message to hash
*/
int tc_sha256_update (TCSha256State_t s, const uint8_t *data, size_t datalen);
/**
* @brief SHA256 final procedure
* Inserts the completed hash computation into digest
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* s == NULL,
* s->iv == NULL,
* digest == NULL
* @note Assumes: s has been initialized by tc_sha256_init
* digest points to at least TC_SHA256_DIGEST_SIZE bytes
* @warning The state buffer 'leftover' is left in memory after processing
* If your application intends to have sensitive data in this
* buffer, remind to erase it after the data has been processed
* @param digest unsigned eight bit integer
* @param Sha256 state struct
*/
int tc_sha256_final(uint8_t *digest, TCSha256State_t s);
#ifdef __cplusplus
}
#endif
#endif /* __TC_SHA256_H__ */
@@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* utils.h - TinyCrypt interface to platform-dependent run-time operations */
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief Interface to platform-dependent run-time operations.
*
*/
#ifndef __TC_UTILS_H__
#define __TC_UTILS_H__
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Copy the the buffer 'from' to the buffer 'to'.
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* from_len > to_len.
*
* @param to OUT -- destination buffer
* @param to_len IN -- length of destination buffer
* @param from IN -- origin buffer
* @param from_len IN -- length of origin buffer
*/
unsigned int _copy(uint8_t *to, unsigned int to_len,
const uint8_t *from, unsigned int from_len);
/**
* @brief Set the value 'val' into the buffer 'to', 'len' times.
*
* @param to OUT -- destination buffer
* @param val IN -- value to be set in 'to'
* @param len IN -- number of times the value will be copied
*/
void _set(void *to, uint8_t val, unsigned int len);
/*
* @brief AES specific doubling function, which utilizes
* the finite field used by AES.
* @return Returns a^2
*
* @param a IN/OUT -- value to be doubled
*/
uint8_t _double_byte(uint8_t a);
/*
* @brief Constant-time algorithm to compare if two sequences of bytes are equal
* @return Returns 0 if equal, and non-zero otherwise
*
* @param a IN -- sequence of bytes a
* @param b IN -- sequence of bytes b
* @param size IN -- size of sequences a and b
*/
int _compare(const uint8_t *a, const uint8_t *b, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* __TC_UTILS_H__ */
@@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#if SOC_ECC_SUPPORTED
int esp_tinycrypt_verify_ecc_point(const uint8_t *pk_x, const uint8_t *pk_y, uint8_t length);
int esp_tinycrypt_calc_ecc_mult(const uint8_t *p_x, const uint8_t *p_y, const uint8_t *scalar,
uint8_t *r_x, uint8_t *r_y, uint8_t num_bytes, bool verify_first);
#endif /* SOC_ECC_SUPPORTED */
@@ -0,0 +1,253 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_BLE_API_H_
#define _ESP_BLE_MESH_BLE_API_H_
#include "esp_ble_mesh_defs.h"
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
#include "host/ble_gap.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** This enum value is the event of BLE operations */
typedef enum {
ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT, /*!< Start BLE advertising completion event */
ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT, /*!< Stop BLE advertising completion event */
ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT, /*!< Start BLE scanning completion event */
ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT, /*!< Stop BLE scanning completion event */
ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT, /*!< Scanning BLE advertising packets event */
ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT, /*!< Scan parameters update completion event */
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT, /*!< NIMBLE GAP event */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED */
ESP_BLE_MESH_BLE_EVT_MAX,
} esp_ble_mesh_ble_cb_event_t;
/** Context of BLE advertising report. */
typedef struct {
uint8_t addr[6]; /*!< Device address */
uint8_t addr_type; /*!< Device address type */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t adv_type __attribute__((deprecated("`event_type` should be used to determine the advertising type"))); /*!< advertising type */
#else
uint8_t adv_type; /*!< Advertising type */
#endif
uint8_t *data; /*!< Advertising data */
uint16_t length; /*!< Advertising data length */
int8_t rssi; /*!< RSSI of the advertising packet */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t event_type; /*!< Extended advertising event type */
uint8_t primary_phy; /*!< Extended advertising primary PHY */
uint8_t secondary_phy; /*!< Extended advertising secondary PHY */
uint8_t sid; /*!< Extended advertising set ID */
uint8_t tx_power; /*!< Extended advertising TX power */
uint8_t dir_addr_type; /*!< Direct address type */
uint8_t dir_addr[6]; /*!< Direct address */
uint8_t data_status; /*!< Data type */
uint16_t per_adv_interval; /*!< Periodic advertising interval */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
} esp_ble_mesh_ble_adv_rpt_t;
/** BLE operation callback parameters */
typedef union {
/**
* @brief ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of starting BLE advertising */
uint8_t index; /*!< Index of the BLE advertising */
} start_ble_advertising_comp; /*!< Event parameters of ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT */
/**
* @brief ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of stopping BLE advertising */
uint8_t index; /*!< Index of the BLE advertising */
} stop_ble_advertising_comp; /*!< Event parameters of ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT */
/**
* @brief ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of starting BLE scanning */
} start_ble_scan_comp; /*!< Event parameters of ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT */
/**
* @brief ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of stopping BLE scanning */
} stop_ble_scan_comp; /*!< Event parameters of ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT */
/**
* @brief Event parameters of ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT
*/
esp_ble_mesh_ble_adv_rpt_t scan_ble_adv_pkt;
/**
* @brief Event parameter of ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT
*/
struct ble_mesh_scan_params_update_comp_param {
int err_code; /*!< Indicates the result of updating scan parameters */
} scan_params_update_comp; /*!< Event parameter of ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT */
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
/**
* @brief Event parameters of ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT
* @note The execution environment of this event is different
* from other BLE Mesh events, as it runs in the NimBLE Host's
* execution environment.
*/
struct ble_mesh_nimble_gap_event_evt_param {
struct ble_gap_event event; /*!< GAP event parameters for NimBLE Host */
void *arg; /*!< User parameters */
} nimble_gap_evt; /*!< Event parameters of ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED */
} esp_ble_mesh_ble_cb_param_t;
/**
* @brief BLE scanning callback function type
*
* @param event: BLE scanning callback event type
* @param param: BLE scanning callback parameter
*/
typedef void (* esp_ble_mesh_ble_cb_t)(esp_ble_mesh_ble_cb_event_t event,
esp_ble_mesh_ble_cb_param_t *param);
/**
* @brief Register BLE scanning callback.
*
* @param[in] callback: Pointer to the BLE scanning callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_ble_callback(esp_ble_mesh_ble_cb_t callback);
/** Count for sending BLE advertising packet infinitely */
#define ESP_BLE_MESH_BLE_ADV_INFINITE 0xFFFF
/*!< This enum value is the priority of BLE advertising packet */
typedef enum {
ESP_BLE_MESH_BLE_ADV_PRIO_LOW,
ESP_BLE_MESH_BLE_ADV_PRIO_HIGH,
} esp_ble_mesh_ble_adv_priority_t;
/** Context of BLE advertising parameters. */
typedef struct {
uint16_t interval; /*!< BLE advertising interval */
uint8_t adv_type; /*!< BLE advertising type */
uint8_t own_addr_type; /*!< Own address type */
uint8_t peer_addr_type; /*!< Peer address type */
uint8_t peer_addr[BD_ADDR_LEN]; /*!< Peer address */
uint16_t duration; /*!< Duration is milliseconds */
uint16_t period; /*!< Period in milliseconds */
uint16_t count; /*!< Number of advertising duration */
uint8_t priority:2; /*!< Priority of BLE advertising packet */
} esp_ble_mesh_ble_adv_param_t;
/** Context of BLE advertising data. */
typedef struct {
uint8_t adv_data_len; /*!< Advertising data length */
uint8_t adv_data[31]; /*!< Advertising data */
uint8_t scan_rsp_data_len; /*!< Scan response data length */
uint8_t scan_rsp_data[31]; /*!< Scan response data */
} esp_ble_mesh_ble_adv_data_t;
/**
* @brief This function is called to start BLE advertising with the corresponding data
* and parameters while BLE Mesh is working at the same time.
*
* @note 1. When this function is called, the BLE advertising packet will be posted to
* the BLE mesh adv queue in the mesh stack and waited to be sent.
* 2. In the BLE advertising parameters, the "duration" means the time used for
* sending the BLE advertising packet each time, it shall not be smaller than the
* advertising interval. When the packet is sent successfully, it will be posted
* to the adv queue again after the "period" time if the "count" is bigger than 0.
* The "count" means how many durations the packet will be sent after it is sent
* successfully for the first time. And if the "count" is set to 0xFFFF, which
* means the packet will be sent infinitely.
* 3. The "priority" means the priority of BLE advertising packet compared with
* BLE Mesh packets. Currently two options (i.e. low/high) are provided. If the
* "priority" is high, the BLE advertising packet will be posted to the front of
* adv queue. Otherwise it will be posted to the back of adv queue.
*
* @param[in] param: Pointer to the BLE advertising parameters
* @param[in] data: Pointer to the BLE advertising data and scan response data
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_start_ble_advertising(const esp_ble_mesh_ble_adv_param_t *param,
const esp_ble_mesh_ble_adv_data_t *data);
/**
* @brief This function is called to stop BLE advertising with the corresponding index.
*
* @param[in] index: Index of BLE advertising
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_stop_ble_advertising(uint8_t index);
/** Context of BLE scanning parameters. */
typedef struct {
uint32_t duration; /*!< Duration used to scan normal BLE advertising packets */
} esp_ble_mesh_ble_scan_param_t;
/**
* @brief This function is called to start scanning normal BLE advertising packets
* and notifying the packets to the application layer.
*
* @param[in] param: Pointer to the BLE scanning parameters
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param);
/**
* @brief This function is called to stop notifying normal BLE advertising packets
* to the application layer.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_stop_ble_scanning(void);
/**
* @brief Update BLE Mesh scan parameters.
*
* @note
* 1. This function shall be used after ESP BLE Mesh is initialized!
* Parameters `scan_interval` and `uncoded_scan_window` must both
* be multiples of 8.
*
* 2. If the config BLE_MESH_USE_BLE_50 is enabled, within the scan_interval:
* - If uncoded_scan_window is not zero, the scan_interval is divided into
* two parts:
* - uncoded_scan_window: Used for performing uncoded scanning.
* - (scan_interval - uncoded_scan_window): The remaining time is
* used for coded scanning (coded_scan).
* - If uncoded_scan_window is set to 0, it means the entire scan_interval
* is used for coded scanning.
* - If uncoded_scan_window is equal to scan_interval, it means the entire
* scan_interval is used for uncoded scanning.
*
* @param[in] scan_param: Scan parameters
*
* @return
* - ESP_OK: Success
* - ESP_FAIL: Invalid parameters or unable transfer this command to the stack
*/
esp_err_t esp_ble_mesh_scan_params_update(esp_ble_mesh_scan_param_t *scan_param);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_BLE_API_H_ */
@@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_COMMON_API_H_
#define _ESP_BLE_MESH_COMMON_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize BLE Mesh module.
* This API initializes provisioning capabilities and composition data information.
*
* @note After calling this API, the device needs to call esp_ble_mesh_prov_enable()
* to enable provisioning functionality again.
*
* @param[in] prov: Pointer to the device provisioning capabilities. This pointer must
* remain valid during the lifetime of the BLE Mesh device.
* @param[in] comp: Pointer to the device composition data information. This pointer
* must remain valid during the lifetime of the BLE Mesh device.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp);
/**
* @brief De-initialize BLE Mesh module.
*
* @note
* 1. This function shall be invoked after esp_ble_mesh_client_model_deinit().
* 2. This function is strictly forbidden to run in any BTC Task Context
* (e.g. registered Mesh Event Callback).
*
* @param[in] param: Pointer to the structure of BLE Mesh deinit parameters.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_COMMON_API_H_ */
@@ -0,0 +1,225 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
#define _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get the model publish period, the unit is ms.
*
* @param[in] model: Model instance pointer.
*
* @return Publish period value on success, 0 or (negative) error code from errno.h on failure.
*
*/
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model);
/**
* @brief Get the address of the primary element.
*
* @return Address of the primary element on success, or
* ESP_BLE_MESH_ADDR_UNASSIGNED on failure which means the device has not been provisioned.
*
*/
uint16_t esp_ble_mesh_get_primary_element_address(void);
/**
* @brief Check if the model has subscribed to the given group address.
* Note: E.g., once a status message is received and the destination address
* is a group address, the model uses this API to check if it is successfully subscribed
* to the given group address.
*
* @param[in] model: Pointer to the model.
* @param[in] group_addr: Group address.
*
* @return Pointer to the group address within the Subscription List of the model on success, or
* NULL on failure which means the model has not subscribed to the given group address.
* Note: With the pointer to the group address returned, you can reset the group address
* to 0x0000 in order to unsubscribe the model from the group.
*
*/
uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model,
uint16_t group_addr);
/**
* @brief Find the BLE Mesh element pointer via the element address.
*
* @param[in] element_addr: Element address.
*
* @return Pointer to the element on success, or NULL on failure.
*
*/
esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr);
/**
* @brief Get the number of elements that have been registered.
*
* @return Number of elements.
*
*/
uint8_t esp_ble_mesh_get_element_count(void);
/**
* @brief Find the Vendor specific model with the given element,
* the company ID and the Vendor Model ID.
*
* @param[in] element: Element to which the model belongs.
* @param[in] company_id: A 16-bit company identifier assigned by the Bluetooth SIG.
* @param[in] model_id: A 16-bit vendor-assigned model identifier.
*
* @return Pointer to the Vendor Model on success, or NULL on failure which means the Vendor Model is not found.
*
*/
esp_ble_mesh_model_t *esp_ble_mesh_find_vendor_model(const esp_ble_mesh_elem_t *element,
uint16_t company_id, uint16_t model_id);
/**
* @brief Find the SIG model with the given element and Model id.
*
* @param[in] element: Element to which the model belongs.
* @param[in] model_id: SIG model identifier.
*
* @return Pointer to the SIG Model on success, or NULL on failure which means the SIG Model is not found.
*
*/
esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(const esp_ble_mesh_elem_t *element,
uint16_t model_id);
/**
* @brief Get the Composition data which has been registered.
*
* @return Pointer to the Composition data on success, or NULL on failure which means the Composition data is not initialized.
*
*/
const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void);
/**
* @brief A local model of node or Provisioner subscribes a group address.
*
* @note This function shall not be invoked before node is provisioned or Provisioner is enabled.
*
* @param[in] element_addr: Unicast address of the element to which the model belongs.
* @param[in] company_id: A 16-bit company identifier.
* @param[in] model_id: A 16-bit model identifier.
* @param[in] group_addr: The group address to be subscribed.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_model_subscribe_group_addr(uint16_t element_addr, uint16_t company_id,
uint16_t model_id, uint16_t group_addr);
/**
* @brief A local model of node or Provisioner unsubscribes a group address.
*
* @note This function shall not be invoked before node is provisioned or Provisioner is enabled.
*
* @param[in] element_addr: Unicast address of the element to which the model belongs.
* @param[in] company_id: A 16-bit company identifier.
* @param[in] model_id: A 16-bit model identifier.
* @param[in] group_addr: The subscribed group address.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_model_unsubscribe_group_addr(uint16_t element_addr, uint16_t company_id,
uint16_t model_id, uint16_t group_addr);
/**
* @brief This function is called by Node to get the local NetKey.
*
* @param[in] net_idx: NetKey index.
*
* @return NetKey on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_node_get_local_net_key(uint16_t net_idx);
/**
* @brief This function is called by Node to get the local AppKey.
*
* @param[in] app_idx: AppKey index.
*
* @return AppKey on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_node_get_local_app_key(uint16_t app_idx);
/**
* @brief This function is called by Node to add a local NetKey.
*
* @param[in] net_key: NetKey to be added.
* @param[in] net_idx: NetKey Index.
*
* @note This function can only be called after the device is provisioned.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx);
/**
* @brief This function is called by Node to add a local AppKey.
*
* @param[in] app_key: AppKey to be added.
* @param[in] net_idx: NetKey Index.
* @param[in] app_idx: AppKey Index.
*
* @note The net_idx must be an existing one.
* This function can only be called after the device is provisioned.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx);
/**
* @brief This function is called by Node to bind AppKey to model locally.
*
* @param[in] element_addr: Node local element address
* @param[in] company_id: Node local company id
* @param[in] model_id: Node local model id
* @param[in] app_idx: Node local appkey index
*
* @note If going to bind app_key with local vendor model, the company_id
* shall be set to 0xFFFF.
* This function can only be called after the device is provisioned.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_bind_app_key_to_local_model(uint16_t element_addr, uint16_t company_id,
uint16_t model_id, uint16_t app_idx);
/**
* @brief This function used to enable directed forwarding and directed forwarding relay on self.
*
* @param[in] net_idx: NetKey Index.
* @param[in] directed_forwarding: Enable or Disable directed forwarding.
* @param[in] directed_forwarding_relay: Enable or Disable directed forwarding relay.
*
* @note If the directed forwarding was set to disable, the directed forwarding relay
* must also be set to disable.
*
* @return ESP_OK on success or error code otherwise.
*
*/
#if CONFIG_BLE_MESH_DF_SRV
esp_err_t esp_ble_mesh_enable_directed_forwarding(uint16_t net_idx, bool directed_forwarding,
bool directed_forwarding_relay);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_ */
@@ -0,0 +1,61 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_LOW_POWER_API_H_
#define _ESP_BLE_MESH_LOW_POWER_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Enable BLE Mesh device LPN functionality.
*
* @note This API enables LPN functionality. Once called, the proper
* Friend Request will be sent.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_enable(void);
/**
* @brief Disable BLE Mesh device LPN functionality.
*
* @param[in] force: when disabling LPN functionality, use this flag to indicate
* whether directly clear corresponding information or just
* send friend clear to disable it if friendship has already
* been established.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_disable(bool force);
/**
* @brief LPN tries to poll messages from the Friend Node.
*
* @note The Friend Poll message is sent by a Low Power node to ask the Friend
* node to send a message that it has stored for the Low Power node.
* Users can call this API to send Friend Poll message manually. If this
* API is not invoked, the bottom layer of the Low Power node will send
* Friend Poll before the PollTimeout timer expires.
* If the corresponding Friend Update is received and MD is set to 0,
* which means there are no messages for the Low Power node, then the
* Low Power node will stop scanning.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_poll(void);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_LOW_POWER_API_H_ */
@@ -0,0 +1,697 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_NETWORKING_API_H_
#define _ESP_BLE_MESH_NETWORKING_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @brief: event, event code of user-defined model events; param, parameters of user-defined model events */
typedef void (* esp_ble_mesh_model_cb_t)(esp_ble_mesh_model_cb_event_t event,
esp_ble_mesh_model_cb_param_t *param);
/**
* @brief Register BLE Mesh callback for user-defined models' operations.
* This callback can report the following events generated for the user-defined models:
* - Call back the messages received by user-defined client and server models to the
* application layer;
* - If users call esp_ble_mesh_server/client_model_send, this callback notifies the
* application layer of the send_complete event;
* - If user-defined client model sends a message that requires response, and the response
* message is received after the timer expires, the response message will be reported
* to the application layer as published by a peer device;
* - If the user-defined client model fails to receive the response message during a specified
* period of time, a timeout event will be reported to the application layer.
*
* @note The client models (i.e. Config Client model, Health Client model, Generic
* Client models, Sensor Client model, Scene Client model and Lighting Client models)
* that have been realized internally have their specific register functions.
* For example, esp_ble_mesh_register_config_client_callback is the register
* function for Config Client Model.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb_t callback);
/**
* @brief Add the message opcode to the beginning of the model message
* before sending or publishing the model message.
*
* @note This API is only used to set the opcode of the message.
*
* @param[in] data: Pointer to the message data.
* @param[in] opcode: The message opcode.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_model_msg_opcode_init(uint8_t *data, uint32_t opcode);
/**
* @brief Initialize the user-defined client model. All user-defined client models
* shall call this function to initialize the client model internal data.
* Node: Before calling this API, the op_pair_size and op_pair variables within
* the user_data(defined using esp_ble_mesh_client_t_) of the client model
* need to be initialized.
*
* @param[in] model: BLE Mesh Client model to which the message belongs.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model);
/**
* @brief De-initialize the user-defined client model.
*
* @note This function shall be invoked before esp_ble_mesh_deinit() is called.
*
* @param[in] model: Pointer of the Client model.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model);
/**
* @brief Send server model messages(such as server model status messages).
*
* @param[in] model: BLE Mesh Server Model to which the message belongs.
* @param[in] ctx: Message context, includes keys, TTL, etc.
* @param[in] opcode: Message opcode.
* @param[in] length: Message length (exclude the message opcode).
* @param[in] data: Parameters of Access Payload (exclude the message opcode) to be sent.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx,
uint32_t opcode,
uint16_t length, uint8_t *data);
/**
* @brief Send client model message (such as model get, set, etc).
*
* @param[in] model: BLE Mesh Client Model to which the message belongs.
* @param[in] ctx: Message context, includes keys, TTL, etc.
* @param[in] opcode: Message opcode.
* @param[in] length: Message length (exclude the message opcode).
* @param[in] data: Parameters of the Access Payload (exclude the message opcode) to be sent.
* @param[in] msg_timeout: Time to get response to the message (in milliseconds).
* @param[in] need_rsp: TRUE if the opcode requires the peer device to reply, FALSE otherwise.
* @param[in] device_role: Role of the device (Node/Provisioner) that sends the message.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx,
uint32_t opcode,
uint16_t length, uint8_t *data,
int32_t msg_timeout, bool need_rsp,
esp_ble_mesh_dev_role_t device_role);
/**
* @brief Send a model publication message.
*
* @note Before calling this function, the user needs to ensure that the model
* publication message (@ref esp_ble_mesh_model_pub_t.msg) contains a valid
* message to be sent. And if users want to update the publishing message,
* this API should be called in ESP_BLE_MESH_MODEL_PUBLISH_UPDATE_EVT
* with the message updated.
*
*
* @param[in] model: Mesh (client) Model publishing the message.
* @param[in] opcode: Message opcode.
* @param[in] length: Message length (exclude the message opcode).
* @param[in] data: Parameters of the Access Payload (exclude the message opcode) to be sent.
* @param[in] device_role: Role of the device (node/provisioner) publishing the message of the type esp_ble_mesh_dev_role_t.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcode,
uint16_t length, uint8_t *data,
esp_ble_mesh_dev_role_t device_role);
/**
* @brief Update a server model state value. If the model publication
* state is set properly (e.g. publish address is set to a valid
* address), it will publish corresponding status message.
*
* @note Currently this API is used to update bound state value, not
* for all server model states.
*
* @param[in] model: Server model which is going to update the state.
* @param[in] type: Server model state type.
* @param[in] value: Server model state value.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_server_model_update_state(esp_ble_mesh_model_t *model,
esp_ble_mesh_server_state_type_t type,
esp_ble_mesh_server_state_value_t *value);
/**
* @brief Reset the provisioning procedure of the local BLE Mesh node.
*
* @note All provisioning information in this node will be deleted and the node
* needs to be re-provisioned. The API function esp_ble_mesh_node_prov_enable()
* needs to be called to start a new provisioning procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_local_reset(void);
/**
* @brief This function is called to set the node (provisioned device) name.
*
* @param[in] index: Index of the node in the node queue.
* @param[in] name: Name (end by '\0') to be set for the node.
*
* @note index is obtained from the parameters of ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_node_name(uint16_t index, const char *name);
/**
* @brief This function is called to get the node (provisioned device) name.
*
* @param[in] index: Index of the node in the node queue.
*
* @note index is obtained from the parameters of ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT.
*
* @return Node name on success, or NULL on failure.
*
*/
const char *esp_ble_mesh_provisioner_get_node_name(uint16_t index);
/**
* @brief This function is called to get the node (provisioned device) index.
*
* @param[in] name: Name of the node (end by '\0').
*
* @return Node index on success, or an invalid value (0xFFFF) on failure.
*
*/
uint16_t esp_ble_mesh_provisioner_get_node_index(const char *name);
/**
* @brief This function is called to store the Composition Data of the node.
*
* @param[in] unicast_addr: Element address of the node
* @param[in] data: Pointer of Composition Data
* @param[in] length: Length of Composition Data
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_store_node_comp_data(uint16_t unicast_addr,
uint8_t *data, uint16_t length);
/**
* @brief This function is called to get the provisioned node information
* with the node device uuid.
*
* @param[in] uuid: Device UUID of the node
*
* @return Pointer of the node info struct or NULL on failure.
*
*/
esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_with_uuid(const uint8_t uuid[16]);
/**
* @brief This function is called to get the provisioned node information
* with the node unicast address.
*
* @param[in] unicast_addr: Unicast address of the node
*
* @return Pointer of the node info struct or NULL on failure.
*
*/
esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_with_addr(uint16_t unicast_addr);
/**
* @brief This function is called to get the provisioned node information
* with the node name.
*
* @param[in] name: Name of the node (end by '\0').
*
* @return Pointer of the node info struct or NULL on failure.
*
*/
esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_with_name(const char *name);
/**
* @brief This function is called by Provisioner to get provisioned node count.
*
* @return Number of the provisioned nodes.
*
*/
uint16_t esp_ble_mesh_provisioner_get_prov_node_count(void);
/**
* @brief This function is called by Provisioner to get the entry of the node table.
*
* @note After invoking the function to get the entry of nodes, users can use the "for"
* loop combined with the macro CONFIG_BLE_MESH_MAX_PROV_NODES to get each node's
* information. Before trying to read the node's information, users need to check
* if the node exists, i.e. if the *(esp_ble_mesh_node_t **node) is NULL.
* For example:
* ```
* const esp_ble_mesh_node_t **entry = esp_ble_mesh_provisioner_get_node_table_entry();
* for (int i = 0; i < CONFIG_BLE_MESH_MAX_PROV_NODES; i++) {
* const esp_ble_mesh_node_t *node = entry[i];
* if (node) {
* ......
* }
* }
* ```
*
* @return Pointer to the start of the node table.
*
*/
const esp_ble_mesh_node_t **esp_ble_mesh_provisioner_get_node_table_entry(void);
/**
* @brief This function is called to delete the provisioned node information
* with the node device uuid.
*
* @param[in] uuid: Device UUID of the node
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_delete_node_with_uuid(const uint8_t uuid[16]);
/**
* @brief This function is called to delete the provisioned node information
* with the node unicast address.
*
* @param[in] unicast_addr: Unicast address of the node
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_delete_node_with_addr(uint16_t unicast_addr);
/**
* @brief This function is called to add a local AppKey for Provisioner.
*
* @param[in] app_key: The app key to be set for the local BLE Mesh stack.
* @param[in] net_idx: The network key index.
* @param[in] app_idx: The app key index.
*
* @note app_key: If set to NULL, app_key will be generated internally.
* net_idx: Should be an existing one.
* app_idx: If it is going to be generated internally, it should be set to
* 0xFFFF, and the new app_idx will be reported via an event.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16],
uint16_t net_idx, uint16_t app_idx);
/**
* @brief This function is used to update a local AppKey for Provisioner.
*
* @param[in] app_key: Value of the AppKey.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] app_idx: The AppKey Index
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_update_local_app_key(const uint8_t app_key[16],
uint16_t net_idx, uint16_t app_idx);
/**
* @brief This function is called by Provisioner to get the local app key value.
*
* @param[in] net_idx: Network key index.
* @param[in] app_idx: Application key index.
*
* @return App key on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_provisioner_get_local_app_key(uint16_t net_idx, uint16_t app_idx);
/**
* @brief This function is called by Provisioner to bind own model with proper app key.
*
* @param[in] element_addr: Provisioner local element address
* @param[in] app_idx: Provisioner local appkey index
* @param[in] model_id: Provisioner local model id
* @param[in] company_id: Provisioner local company id
*
* @note company_id: If going to bind app_key with local vendor model, company_id
* should be set to 0xFFFF.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_bind_app_key_to_local_model(uint16_t element_addr, uint16_t app_idx,
uint16_t model_id, uint16_t company_id);
/**
* @brief This function is called by Provisioner to add local network key.
*
* @param[in] net_key: The network key to be added to the Provisioner local BLE Mesh stack.
* @param[in] net_idx: The network key index.
*
* @note net_key: If set to NULL, net_key will be generated internally.
* net_idx: If it is going to be generated internally, it should be set to
* 0xFFFF, and the new net_idx will be reported via an event.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx);
/**
* @brief This function is called by Provisioner to update a local network key.
*
* @param[in] net_key: Value of the NetKey.
* @param[in] net_idx: The NetKey Index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_update_local_net_key(const uint8_t net_key[16], uint16_t net_idx);
/**
* @brief This function is called by Provisioner to get the local network key value.
*
* @param[in] net_idx: Network key index.
*
* @return Network key on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx);
/**
* @brief This function is called by Provisioner to enable or disable receiving
* heartbeat messages.
*
* @note If enabling receiving heartbeat message successfully, the filter will
* be an empty rejectlist by default, which means all heartbeat messages
* received by the Provisioner will be reported to the application layer.
*
* @param[in] enable: Enable or disable receiving heartbeat messages.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_recv_heartbeat(bool enable);
/**
* @brief This function is called by Provisioner to set the heartbeat filter type.
*
* @note 1. If the filter type is not the same with the current value, then all the
* filter entries will be cleaned.
* 2. If the previous type is rejectlist, and changed to acceptlist, then the
* filter will be an empty acceptlist, which means no heartbeat messages
* will be reported. Users need to add SRC or DST into the filter entry,
* then heartbeat messages from the SRC or to the DST will be reported.
*
* @param[in] type: Heartbeat filter type (acceptlist or rejectlist).
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_type(uint8_t type);
/**
* @brief This function is called by Provisioner to add or remove a heartbeat filter entry.
*
* @note 1. If the operation is "ADD", the "hb_src" can be set to the SRC (can only be a
* unicast address) of heartbeat messages, and the "hb_dst" can be set to the
* DST (unicast address or group address), at least one of them needs to be set.
* - If only one of them is set, the filter entry will only use the configured
* SRC or DST to filter heartbeat messages.
* - If both of them are set, the SRC and DST will both be used to decide if a
* heartbeat message will be handled.
* - If SRC or DST already exists in some filter entry, then the corresponding
* entry will be cleaned firstly, then a new entry will be allocated to store
* the information.
* 2. If the operation is "REMOVE", the "hb_src" can be set to the SRC (can only be
* a unicast address) of heartbeat messages, and the "hb_dst" can be set to the
* DST (unicast address or group address), at least one of them needs to be set.
* - The filter entry with the same SRC or DST will be removed.
*
* @param[in] op: Add or REMOVE
* @param[in] info: Heartbeat filter entry information, including:
* hb_src - Heartbeat source address;
* hb_dst - Heartbeat destination address;
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, esp_ble_mesh_heartbeat_filter_info_t *info);
/**
* @brief This function is called by Provisioner to directly erase the mesh
* information from nvs namespace.
*
* @note This function can be invoked when the mesh stack is not initialized
* or has been de-initialized.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_direct_erase_settings(void);
/**
* @brief This function is called by Provisioner to open a nvs namespace
* for storing mesh information.
*
* @note Before open another nvs namespace, the previously opened nvs
* namespace must be closed firstly.
*
* @param[in] index: Settings index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_open_settings_with_index(uint8_t index);
/**
* @brief This function is called by Provisioner to open a nvs namespace
* for storing mesh information.
*
* @note Before open another nvs namespace, the previously opened nvs
* namespace must be closed firstly.
*
* @param[in] uid: Settings user id.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_open_settings_with_uid(const char *uid);
/**
* @brief This function is called by Provisioner to close a nvs namespace
* which is opened previously for storing mesh information.
*
* @note 1. Before closing the nvs namespace, it must be open.
* 2. When the function is invoked, the Provisioner functionality
* will be disabled firstly, and:
* a) If the "erase" flag is set to false, the mesh information
* will be cleaned (e.g. removing NetKey, AppKey, nodes, etc)
* from the mesh stack.
* b) If the "erase" flag is set to true, the mesh information
* stored in the nvs namespace will also be erased besides
* been cleaned from the mesh stack.
* 3. If Provisioner tries to work properly again, we can invoke the
* open function to open a new nvs namespace or a previously added
* one, and restore the mesh information from it if not erased.
* 4. The working process shall be as following:
* a) Open settings A
* b) Start to provision and control nodes
* c) Close settings A
* d) Open settings B
* e) Start to provision and control other nodes
* f) Close settings B
* g) ......
*
* @param[in] index: Settings index.
* @param[in] erase: Indicate if erasing mesh information.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_close_settings_with_index(uint8_t index, bool erase);
/**
* @brief This function is called by Provisioner to close a nvs namespace
* which is opened previously for storing mesh information.
*
* @note 1. Before closing the nvs namespace, it must be open.
* 2. When the function is invoked, the Provisioner functionality
* will be disabled firstly, and:
* a) If the "erase" flag is set to false, the mesh information
* will be cleaned (e.g. removing NetKey, AppKey, nodes, etc)
* from the mesh stack.
* b) If the "erase" flag is set to true, the mesh information
* stored in the nvs namespace will also be erased besides
* been cleaned from the mesh stack.
* 3. If Provisioner tries to work properly again, we can invoke the
* open function to open a new nvs namespace or a previously added
* one, and restore the mesh information from it if not erased.
* 4. The working process shall be as following:
* a) Open settings A
* b) Start to provision and control nodes
* c) Close settings A
* d) Open settings B
* e) Start to provision and control other nodes
* f) Close settings B
* g) ......
*
* @param[in] uid: Settings user id.
* @param[in] erase: Indicate if erasing mesh information.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_close_settings_with_uid(const char *uid, bool erase);
/**
* @brief This function is called by Provisioner to erase the mesh information
* and settings user id from a nvs namespace.
*
* @note When this function is called, the nvs namespace must not be open.
* This function is used to erase the mesh information and settings
* user id which are not used currently.
*
* @param[in] index: Settings index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_delete_settings_with_index(uint8_t index);
/**
* @brief This function is called by Provisioner to erase the mesh information
* and settings user id from a nvs namespace.
*
* @note When this function is called, the nvs namespace must not be open.
* This function is used to erase the mesh information and settings
* user id which are not used currently.
*
* @param[in] uid: Settings user id.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_delete_settings_with_uid(const char *uid);
/**
* @brief This function is called by Provisioner to get settings user id.
*
* @param[in] index: Settings index.
*
* @return Setting user id on success or NULL on failure.
*
*/
const char *esp_ble_mesh_provisioner_get_settings_uid(uint8_t index);
/**
* @brief This function is called by Provisioner to get settings index.
*
* @param[in] uid: Settings user id.
*
* @return Settings index.
*
*/
uint8_t esp_ble_mesh_provisioner_get_settings_index(const char *uid);
/**
* @brief This function is called by Provisioner to get the number of free
* settings user id.
*
* @return Number of free settings user id.
*
*/
uint8_t esp_ble_mesh_provisioner_get_free_settings_count(void);
/**
* @brief This function is called to get fast provisioning application key.
*
* @param[in] net_idx: Network key index.
* @param[in] app_idx: Application key index.
*
* @return Application key on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx);
#if CONFIG_BLE_MESH_CERT_BASED_PROV
/**
* @brief This function is called by provisioner to send provisioning records
* get message.
*
* @param[in] link_idx: The provisioning link index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_send_prov_records_get(uint16_t link_idx);
/**
* @brief This function is called by provisioner to send provisioning record
* request message.
*
* @param[in] link_idx: The provisioning link index.
* @param[in] record_id: The record identity.
* @param[in] frag_offset: The starting offset of the fragment.
* @param[in] max_size: The max record fragment size.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_send_prov_record_req(uint16_t link_idx, uint16_t record_id,
uint16_t frag_offset, uint16_t max_size);
/**
* @brief This function is called by provisioner to send provisioning invite
* message.
*
* @param[in] link_idx: The provisioning link index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_send_prov_invite(uint16_t link_idx);
/**
* @brief This function is called by provisioner to send link close
*
* @param[in] link_idx: The provisioning link index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_send_link_close(uint16_t link_idx);
#endif /* #if CONFIG_BLE_MESH_CERT_BASED_PROV */
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_NETWORKING_API_H_ */
@@ -0,0 +1,394 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_PROVISIONING_API_H_
#define _ESP_BLE_MESH_PROVISIONING_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @brief: event, event code of provisioning events; param, parameters of provisioning events */
typedef void (* esp_ble_mesh_prov_cb_t)(esp_ble_mesh_prov_cb_event_t event,
esp_ble_mesh_prov_cb_param_t *param);
/**
* @brief Register BLE Mesh provisioning callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb_t callback);
/**
* @brief Check if a device has been provisioned.
*
* @return TRUE if the device is provisioned, FALSE if the device is unprovisioned.
*
*/
bool esp_ble_mesh_node_is_provisioned(void);
/**
* @brief Enable specific provisioning bearers to get the device ready for provisioning.
*
* @note PB-ADV: send unprovisioned device beacon.
* PB-GATT: send connectable advertising packets.
*
* @param bearers: Bit-wise OR of provisioning bearers.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_prov_enable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Disable specific provisioning bearers to make a device inaccessible for provisioning.
*
* @param bearers: Bit-wise OR of provisioning bearers.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_prov_disable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Unprovisioned device set own oob public key & private key pair.
*
* @note In order to avoid suffering brute-forcing attack (CVE-2020-26559).
* The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
* use an out-of-band mechanism to exchange the public keys.
* So as an unprovisioned device, it should use this function to input
* the Public Key exchanged through the out-of-band mechanism.
*
* @param[in] pub_key_x: Unprovisioned device's Public Key X(Little Endian)
* @param[in] pub_key_y: Unprovisioned device's Public Key Y(Little Endian)
* @param[in] private_key: Unprovisioned device's Private Key(Little Endian)
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_node_set_oob_pub_key(uint8_t pub_key_x[32], uint8_t pub_key_y[32],
uint8_t private_key[32]);
/**
* @brief Provide provisioning input OOB number.
*
* @note This is intended to be called if the user has received ESP_BLE_MESH_NODE_PROV_INPUT_EVT
* with ESP_BLE_MESH_ENTER_NUMBER as the action.
*
* @param[in] number: Number input by device.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_input_number(uint32_t number);
/**
* @brief Provide provisioning input OOB string.
*
* @note This is intended to be called if the user has received ESP_BLE_MESH_NODE_PROV_INPUT_EVT
* with ESP_BLE_MESH_ENTER_STRING as the action.
*
* @param[in] string: String input by device.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_input_string(const char *string);
/**
* @brief Using this function, an unprovisioned device can set its own device name,
* which will be broadcasted in its advertising data.
*
* @param[in] name: Unprovisioned device name
*
* @note This API applicable to PB-GATT mode only by setting the name to the scan response data,
* it doesn't apply to PB-ADV mode.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name);
/**
* @brief Provisioner inputs unprovisioned device's oob public key.
*
* @note In order to avoid suffering brute-forcing attack (CVE-2020-26559).
* The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
* use an out-of-band mechanism to exchange the public keys.
*
* @param[in] link_idx: The provisioning link index
* @param[in] pub_key_x: Unprovisioned device's Public Key X
* @param[in] pub_key_y: Unprovisioned device's Public Key Y
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_provisioner_read_oob_pub_key(uint8_t link_idx, uint8_t pub_key_x[32],
uint8_t pub_key_y[32]);
/**
* @brief Provide provisioning input OOB string.
*
* This is intended to be called after the esp_ble_mesh_prov_t prov_input_num
* callback has been called with ESP_BLE_MESH_ENTER_STRING as the action.
*
* @param[in] string: String input by Provisioner.
* @param[in] link_idx: The provisioning link index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link_idx);
/**
* @brief Provide provisioning input OOB number.
*
* This is intended to be called after the esp_ble_mesh_prov_t prov_input_num
* callback has been called with ESP_BLE_MESH_ENTER_NUMBER as the action.
*
* @param[in] number: Number input by Provisioner.
* @param[in] link_idx: The provisioning link index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_input_number(uint32_t number, uint8_t link_idx);
/**
* @brief Enable one or more provisioning bearers.
*
* @param[in] bearers: Bit-wise OR of provisioning bearers.
*
* @note PB-ADV: Enable BLE scan.
* PB-GATT: Initialize corresponding BLE Mesh Proxy info.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_prov_enable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Disable one or more provisioning bearers.
*
* @param[in] bearers: Bit-wise OR of provisioning bearers.
*
* @note PB-ADV: Disable BLE scan.
* PB-GATT: Break any existing BLE Mesh Provisioning connections.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_prov_disable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Add unprovisioned device info to the unprov_dev queue.
*
* @param[in] add_dev: Pointer to a struct containing the device information
* @param[in] flags: Flags indicate several operations on the device information
* - Remove device information from queue after device has been provisioned (BIT0)
* - Start provisioning immediately after device is added to queue (BIT1)
* - Device can be removed if device queue is full (BIT2)
*
* @return ESP_OK on success or error code otherwise.
*
* @note: 1. Currently address type only supports public address and static random address.
* 2. If device UUID and/or device address as well as address type already exist in the
* device queue, but the bearer is different from the existing one, add operation
* will also be successful and it will update the provision bearer supported by
* the device.
* 3. For example, if the Provisioner wants to add an unprovisioned device info before
* receiving its unprovisioned device beacon or Mesh Provisioning advertising packets,
* the Provisioner can use this API to add the device info with each one or both of
* device UUID and device address added. When the Provisioner gets the device's
* advertising packets, it will start provisioning the device internally.
* - In this situation, the Provisioner can set bearers with each one or both of
* ESP_BLE_MESH_PROV_ADV and ESP_BLE_MESH_PROV_GATT enabled, and cannot set flags
* with ADD_DEV_START_PROV_NOW_FLAG enabled.
* 4. Another example is when the Provisioner receives the unprovisioned device's beacon or
* Mesh Provisioning advertising packets, the advertising packets will be reported on to
* the application layer using the callback registered by the function
* esp_ble_mesh_register_prov_callback. And in the callback, the Provisioner
* can call this API to start provisioning the device.
* - If the Provisioner uses PB-ADV to provision, either one or both of device UUID and
* device address can be added, bearers shall be set with ESP_BLE_MESH_PROV_ADV
* enabled and the flags shall be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
* - If the Provisioner uses PB-GATT to provision, both the device UUID and device
* address need to be added, bearers shall be set with ESP_BLE_MESH_PROV_GATT enabled,
* and the flags shall be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
* - If the Provisioner just wants to store the unprovisioned device info when receiving
* its advertising packets and start to provision it the next time (e.g. after receiving
* its advertising packets again), then it can add the device info with either one or both
* of device UUID and device address included. Bearers can be set with either one or both
* of ESP_BLE_MESH_PROV_ADV and ESP_BLE_MESH_PROV_GATT enabled (recommend to enable the
* bearer which will receive its advertising packets, because if the other bearer is
* enabled, the Provisioner is not aware if the device supports the bearer), and flags
* cannot be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
* - Note: ESP_BLE_MESH_PROV_ADV, ESP_BLE_MESH_PROV_GATT and ADD_DEV_START_PROV_NOW_FLAG
* can not be enabled at the same time.
*
*/
esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t *add_dev,
esp_ble_mesh_dev_add_flag_t flags);
/** @brief Provision an unprovisioned device and assign a fixed unicast address for it in advance.
*
* @param[in] uuid: Device UUID of the unprovisioned device
* @param[in] addr: Device address of the unprovisioned device
* @param[in] addr_type: Device address type of the unprovisioned device
* @param[in] bearer: Provisioning bearer going to be used by Provisioner
* @param[in] oob_info: OOB info of the unprovisioned device
* @param[in] unicast_addr: Unicast address going to be allocated for the unprovisioned device
*
* @return Zero on success or (negative) error code otherwise.
*
* @note: 1. Currently address type only supports public address and static random address.
* 2. Bearer must be equal to ESP_BLE_MESH_PROV_ADV or ESP_BLE_MESH_PROV_GATT, since
* Provisioner will start to provision a device immediately once this function is
* invoked. And the input bearer must be identical with the one within the parameters
* of the ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT event.
* 3. If this function is used by a Provisioner to provision devices, the application
* should take care of the assigned unicast address and avoid overlap of the unicast
* addresses of different nodes.
* 4. Recommend to use only one of the functions "esp_ble_mesh_provisioner_add_unprov_dev"
* and "esp_ble_mesh_provisioner_prov_device_with_addr" by a Provisioner.
*/
esp_err_t esp_ble_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16],
esp_ble_mesh_bd_addr_t addr,
esp_ble_mesh_addr_type_t addr_type,
esp_ble_mesh_prov_bearer_t bearer,
uint16_t oob_info, uint16_t unicast_addr);
/**
* @brief Delete device from queue, and reset current provisioning link with the device.
*
* @note If the device is in the queue, remove it from the queue; if the device is
* being provisioned, terminate the provisioning procedure. Either one of the
* device address or device UUID can be used as input.
*
* @param[in] del_dev: Pointer to a struct containing the device information.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_dev);
/**
* @brief Callback for Provisioner that received advertising packets from unprovisioned devices which are
* not in the unprovisioned device queue.
*
* Report on the unprovisioned device beacon and mesh provisioning service adv data to application.
*
* @param[in] addr: Pointer to the unprovisioned device address.
* @param[in] addr_type: Unprovisioned device address type.
* @param[in] adv_type: Adv packet type(ADV_IND or ADV_NONCONN_IND).
* @param[in] dev_uuid: Unprovisioned device UUID pointer.
* @param[in] oob_info: OOB information of the unprovisioned device.
* @param[in] bearer: Adv packet received from PB-GATT or PB-ADV bearer.
*
*/
typedef void (*esp_ble_mesh_prov_adv_cb_t)(const esp_ble_mesh_bd_addr_t addr, const esp_ble_mesh_addr_type_t addr_type,
const uint8_t adv_type, const uint8_t *dev_uuid,
uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer);
/**
* @brief This function is called by Provisioner to set the part of the device UUID
* to be compared before starting to provision.
*
* @param[in] match_val: Value to be compared with the part of the device UUID.
* @param[in] match_len: Length of the compared match value.
* @param[in] offset: Offset of the device UUID to be compared (based on zero).
* @param[in] prov_after_match: Flag used to indicate whether provisioner should start to provision
* the device immediately if the part of the UUID matches.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, uint8_t match_len,
uint8_t offset, bool prov_after_match);
/**
* @brief This function is called by Provisioner to set provisioning data information
* before starting to provision.
*
* @param[in] prov_data_info: Pointer to a struct containing net_idx or flags or iv_index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_info_t *prov_data_info);
/**
* @brief This function is called by Provisioner to set static oob value used for provisioning.
*
* @note The Bluetooth SIG recommends that mesh implementations enforce a randomly selected
* AuthValue using all of the available bits, where permitted by the implementation.
* A large entropy helps ensure that a brute-force of the AuthValue, even a static
* AuthValue, cannot normally be completed in a reasonable time (CVE-2020-26557).
*
* AuthValues selected using a cryptographically secure random or pseudorandom number
* generator and having the maximum permitted entropy (128-bits) will be most difficult
* to brute-force. AuthValues with reduced entropy or generated in a predictable manner
* will not grant the same level of protection against this vulnerability. Selecting a
* new AuthValue with each provisioning attempt can also make it more difficult to launch
* a brute-force attack by requiring the attacker to restart the search with each
* provisioning attempt (CVE-2020-26556).
*
* @param[in] value: Pointer to the static oob value.
* @param[in] length: Length of the static oob value.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_static_oob_value(const uint8_t *value, uint8_t length);
/**
* @brief This function is called by Provisioner to set own Primary element address.
*
* @note This API must be invoked when BLE Mesh initialization is completed successfully,
* and can be invoked before Provisioner functionality is enabled.
* Once this API is invoked successfully, the prov_unicast_addr value in the struct
* esp_ble_mesh_prov_t will be ignored, and Provisioner will use this address as its
* own primary element address.
* And if the unicast address going to assigned for the next unprovisioned device is
* smaller than the input address + element number of Provisioner, then the address
* for the next unprovisioned device will be recalculated internally.
*
* @param[in] addr: Unicast address of the Primary element of Provisioner.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_primary_elem_addr(uint16_t addr);
/**
* @brief This function is called to set provisioning data information before starting
* fast provisioning.
*
* @param[in] fast_prov_info: Pointer to a struct containing unicast address range, net_idx, etc.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_prov_info);
/**
* @brief This function is called to start/suspend/exit fast provisioning.
*
* @param[in] action: fast provisioning action (i.e. enter, suspend, exit).
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_set_fast_prov_action(esp_ble_mesh_fast_prov_action_t action);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_PROVISIONING_API_H_ */
@@ -0,0 +1,170 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_PROXY_API_H_
#define _ESP_BLE_MESH_PROXY_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_BLE_MESH_PROXY_CLI_DIRECTED_FORWARDING_ENABLE 0x01
#define ESP_BLE_MESH_PROXY_CLI_DIRECTED_FORWARDING_DISABLE 0x00
/**
* @brief Enable advertising with Node Identity.
*
* @note This API requires that GATT Proxy support be enabled. Once called,
* each subnet starts advertising using Node Identity for the next 60
* seconds, and after 60s Network ID will be advertised.
* Under normal conditions, the BLE Mesh Proxy Node Identity and
* Network ID advertising will be enabled automatically by BLE Mesh
* stack after the device is provisioned.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_identity_enable(void);
/**
* @brief Enable BLE Mesh GATT Proxy Service.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_gatt_enable(void);
/**
* @brief Disconnect the BLE Mesh GATT Proxy connection if there is any, and
* disable the BLE Mesh GATT Proxy Service.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_gatt_disable(void);
/**
* @brief Enable advertising with Private Node Identity.
*
* @note This API requires that GATT Proxy support be enabled. Once called,
* each subnet starts advertising using Private Node Identity for the
* next 60 seconds, and after 60s Private Network ID will be advertised.
* Under normal conditions, the BLE Mesh Proxy Node Identity, Network
* ID advertising, Proxy Private Node Identity and Private Network
* ID advertising will be enabled automatically by BLE Mesh stack
* after the device is provisioned.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_private_proxy_identity_enable(void);
/**
* @brief Disable advertising with Private Node Identity.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_private_proxy_identity_disable(void);
/**
* @brief Proxy Client creates a connection with the Proxy Server.
*
* @param[in] addr: Device address of the Proxy Server.
* @param[in] addr_type: Device address type(public or static random).
* @param[in] net_idx: NetKey Index related with Network ID in the Mesh Proxy
* advertising packet.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_connect(esp_ble_mesh_bd_addr_t addr,
esp_ble_mesh_addr_type_t addr_type,
uint16_t net_idx);
/**
* @brief Proxy Client terminates a connection with the Proxy Server.
*
* @param[in] conn_handle: Proxy connection handle.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_disconnect(uint8_t conn_handle);
/**
* @brief Proxy Client sets the filter type of the Proxy Server.
*
* @param[in] conn_handle: Proxy connection handle.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] filter_type: whitelist or blacklist.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_set_filter_type(uint8_t conn_handle, uint16_t net_idx,
esp_ble_mesh_proxy_filter_type_t filter_type);
/**
* @brief Proxy Client adds address to the Proxy Server filter list.
*
* @param[in] conn_handle: Proxy connection handle.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] addr: Pointer to the filter address.
* @param[in] addr_num: Number of the filter address.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_add_filter_addr(uint8_t conn_handle, uint16_t net_idx,
uint16_t *addr, uint16_t addr_num);
/**
* @brief Proxy Client removes address from the Proxy Server filter list.
*
* @param[in] conn_handle: Proxy connection handle.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] addr: Pointer to the filter address.
* @param[in] addr_num: Number of the filter address.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_remove_filter_addr(uint8_t conn_handle, uint16_t net_idx,
uint16_t *addr, uint16_t addr_num);
/**
* @brief Proxy Client sets whether or not the Directed Proxy Server uses directed forwarding
* for Directed Proxy Client messages.
*
* @param[in] conn_handle: Proxy connection handle.
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] use_directed: Whether or not to send message by directed forwarding.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_directed_proxy_set(uint8_t conn_handle, uint16_t net_idx,
uint8_t use_directed);
/**
* @brief Proxy Client sends Solicitation PDU.
*
* @param[in] net_idx: Corresponding NetKey Index.
* @param[in] ssrc: Solicitation SRC, shall be one of its element address.
* @param[in] dst: Solicitation DST (TBD).
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_send_solic_pdu(uint8_t net_idx, uint16_t ssrc, uint16_t dst);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_PROXY_API_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,832 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_CONFIG_MODEL_API_H_
#define _ESP_BLE_MESH_CONFIG_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @def ESP_BLE_MESH_MODEL_CFG_SRV
*
* @brief Define a new Config Server Model.
*
* @note The Config Server Model can only be included by a Primary Element.
*
* @param srv_data Pointer to a unique Config Server Model user_data.
*
* @return New Config Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_CFG_SRV(srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_CONFIG_SRV, \
NULL, NULL, srv_data)
/** @def ESP_BLE_MESH_MODEL_CFG_CLI
*
* @brief Define a new Config Client Model.
*
* @note The Config Client Model can only be included by a Primary Element.
*
* @param cli_data Pointer to a unique struct esp_ble_mesh_client_t.
*
* @return New Config Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_CFG_CLI(cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_CONFIG_CLI, \
NULL, NULL, cli_data)
/** Configuration Server Model context */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to Configuration Server Model */
uint8_t net_transmit; /*!< Network Transmit state */
uint8_t relay; /*!< Relay Mode state */
uint8_t relay_retransmit; /*!< Relay Retransmit state */
uint8_t beacon; /*!< Secure Network Beacon state */
uint8_t gatt_proxy; /*!< GATT Proxy state */
uint8_t friend_state; /*!< Friend state */
uint8_t default_ttl; /*!< Default TTL */
/** Heartbeat Publication */
struct {
struct k_delayed_work timer; /*!< Heartbeat Publication timer */
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint16_t count; /*!< Number of Heartbeat messages to be sent */
uint8_t period; /*!< Period for sending Heartbeat messages */
uint8_t ttl; /*!< TTL to be used when sending Heartbeat messages */
uint16_t feature; /*!< Bit field indicating features that trigger Heartbeat messages when changed */
uint16_t net_idx; /*!< NetKey Index used by Heartbeat Publication */
} heartbeat_pub;
/** Heartbeat Subscription */
struct {
int64_t expiry; /*!< Timestamp when Heartbeat subscription period is expired */
uint16_t src; /*!< Source address for Heartbeat messages */
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint16_t count; /*!< Number of Heartbeat messages received */
uint8_t min_hops; /*!< Minimum hops when receiving Heartbeat messages */
uint8_t max_hops; /*!< Maximum hops when receiving Heartbeat messages */
/** Optional heartbeat subscription tracking function */
esp_ble_mesh_cb_t heartbeat_recv_cb;
} heartbeat_sub;
} esp_ble_mesh_cfg_srv_t;
/** Parameters of Config Composition Data Get. */
typedef struct {
uint8_t page; /*!< Page number of the Composition Data. */
} esp_ble_mesh_cfg_composition_data_get_t;
/** Parameters of Config Model Publication Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_pub_get_t;
/** Parameters of Config SIG Model Subscription Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
} esp_ble_mesh_cfg_sig_model_sub_get_t;
/** Parameters of Config Vendor Model Subscription Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_vnd_model_sub_get_t;
/** Parameters of Config AppKey Get. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_app_key_get_t;
/** Parameters of Config Node Identity Get. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_node_identity_get_t;
/** Parameters of Config SIG Model App Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
} esp_ble_mesh_cfg_sig_model_app_get_t;
/** Parameters of Config Vendor Model App Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_vnd_model_app_get_t;
/** Parameters of Config Key Refresh Phase Get. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_kr_phase_get_t;
/** Parameters of Config Low Power Node PollTimeout Get. */
typedef struct {
uint16_t lpn_addr; /*!< The unicast address of the Low Power node */
} esp_ble_mesh_cfg_lpn_polltimeout_get_t;
/** Parameters of Config Beacon Set. */
typedef struct {
uint8_t beacon; /*!< New Secure Network Beacon state */
} esp_ble_mesh_cfg_beacon_set_t;
/** Parameters of Config Default TTL Set. */
typedef struct {
uint8_t ttl; /*!< The default TTL state value */
} esp_ble_mesh_cfg_default_ttl_set_t;
/** Parameters of Config Friend Set. */
typedef struct {
uint8_t friend_state; /*!< The friend state value */
} esp_ble_mesh_cfg_friend_set_t;
/** Parameters of Config GATT Proxy Set. */
typedef struct {
uint8_t gatt_proxy; /*!< The GATT Proxy state value */
} esp_ble_mesh_cfg_gatt_proxy_set_t;
/** Parameters of Config Relay Set. */
typedef struct {
uint8_t relay; /*!< The relay value */
uint8_t relay_retransmit; /*!< The relay retransmit value */
} esp_ble_mesh_cfg_relay_set_t;
/** Parameters of Config NetKey Add. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t net_key[16]; /*!< The network key value */
} esp_ble_mesh_cfg_net_key_add_t;
/** Parameters of Config AppKey Add. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint16_t app_idx; /*!< The app key index */
uint8_t app_key[16]; /*!< The app key value */
} esp_ble_mesh_cfg_app_key_add_t;
/** Parameters of Config Model App Bind. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_app_idx; /*!< Index of the app key to bind with the model */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_app_bind_t;
/** Parameters of Config Model Publication Set. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t publish_addr; /*!< Value of the publish address */
uint16_t publish_app_idx; /*!< Index of the application key */
bool cred_flag; /*!< Value of the Friendship Credential Flag */
uint8_t publish_ttl; /*!< Default TTL value for the publishing messages */
uint8_t publish_period; /*!< Period for periodic status publishing */
uint8_t publish_retransmit; /*!< Number of retransmissions and number of 50-millisecond steps between retransmissions */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_pub_set_t;
/** Parameters of Config Model Subscription Add. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t sub_addr; /*!< The address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_add_t;
/** Parameters of Config Model Subscription Delete. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t sub_addr; /*!< The address to be removed from the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_delete_t;
/** Parameters of Config Model Subscription Overwrite. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t sub_addr; /*!< The address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_overwrite_t;
/** Parameters of Config Model Subscription Virtual Address Add. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< The Label UUID of the virtual address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_va_add_t;
/** Parameters of Config Model Subscription Virtual Address Delete. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< The Label UUID of the virtual address to be removed from the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_va_delete_t;
/** Parameters of Config Model Subscription Virtual Address Overwrite. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< The Label UUID of the virtual address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_va_overwrite_t;
/** Parameters of Config Model Publication Virtual Address Set. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< Value of the Label UUID publish address */
uint16_t publish_app_idx; /*!< Index of the application key */
bool cred_flag; /*!< Value of the Friendship Credential Flag */
uint8_t publish_ttl; /*!< Default TTL value for the publishing messages */
uint8_t publish_period; /*!< Period for periodic status publishing */
uint8_t publish_retransmit; /*!< Number of retransmissions and number of 50-millisecond steps between retransmissions */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_pub_va_set_t;
/** Parameters of Config Model Subscription Delete All. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_delete_all_t;
/** Parameters of Config NetKey Update. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t net_key[16]; /*!< The network key value */
} esp_ble_mesh_cfg_net_key_update_t;
/** Parameters of Config NetKey Delete. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_net_key_delete_t;
/** Parameters of Config AppKey Update. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint16_t app_idx; /*!< The app key index */
uint8_t app_key[16]; /*!< The app key value */
} esp_ble_mesh_cfg_app_key_update_t;
/** Parameters of Config AppKey Delete. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint16_t app_idx; /*!< The app key index */
} esp_ble_mesh_cfg_app_key_delete_t;
/** Parameters of Config Node Identity Set. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t identity; /*!< New Node Identity state */
} esp_ble_mesh_cfg_node_identity_set_t;
/** Parameters of Config Model App Unbind. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_app_idx; /*!< Index of the app key to bind with the model */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_app_unbind_t;
/** Parameters of Config Key Refresh Phase Set. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t transition; /*!< New Key Refresh Phase Transition */
} esp_ble_mesh_cfg_kr_phase_set_t;
/** Parameters of Config Network Transmit Set. */
typedef struct {
uint8_t net_transmit; /*!< Network Transmit State */
} esp_ble_mesh_cfg_net_transmit_set_t;
/** Parameters of Config Model Heartbeat Publication Set. */
typedef struct {
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint8_t count; /*!< Number of Heartbeat messages to be sent */
uint8_t period; /*!< Period for sending Heartbeat messages */
uint8_t ttl; /*!< TTL to be used when sending Heartbeat messages */
uint16_t feature; /*!< Bit field indicating features that trigger Heartbeat messages when changed */
uint16_t net_idx; /*!< NetKey Index */
} esp_ble_mesh_cfg_heartbeat_pub_set_t;
/** Parameters of Config Model Heartbeat Subscription Set. */
typedef struct {
uint16_t src; /*!< Source address for Heartbeat messages */
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint8_t period; /*!< Period for receiving Heartbeat messages */
} esp_ble_mesh_cfg_heartbeat_sub_set_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_BEACON_GET
* ESP_BLE_MESH_MODEL_OP_COMPOSITION_DATA_GET
* ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_GET
* ESP_BLE_MESH_MODEL_OP_GATT_PROXY_GET
* ESP_BLE_MESH_MODEL_OP_RELAY_GET
* ESP_BLE_MESH_MODEL_OP_MODEL_PUB_GET
* ESP_BLE_MESH_MODEL_OP_FRIEND_GET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_GET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_GET
* the get_state parameter in the esp_ble_mesh_config_client_get_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_cfg_model_pub_get_t model_pub_get; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_PUB_GET. */
esp_ble_mesh_cfg_composition_data_get_t comp_data_get; /*!< For ESP_BLE_MESH_MODEL_OP_COMPOSITION_DATA_GET. */
esp_ble_mesh_cfg_sig_model_sub_get_t sig_model_sub_get; /*!< For ESP_BLE_MESH_MODEL_OP_SIG_MODEL_SUB_GET */
esp_ble_mesh_cfg_vnd_model_sub_get_t vnd_model_sub_get; /*!< For ESP_BLE_MESH_MODEL_OP_VENDOR_MODEL_SUB_GET */
esp_ble_mesh_cfg_app_key_get_t app_key_get; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_GET. */
esp_ble_mesh_cfg_node_identity_get_t node_identity_get; /*!< For ESP_BLE_MESH_MODEL_OP_NODE_IDENTITY_GET. */
esp_ble_mesh_cfg_sig_model_app_get_t sig_model_app_get; /*!< For ESP_BLE_MESH_MODEL_OP_SIG_MODEL_APP_GET */
esp_ble_mesh_cfg_vnd_model_app_get_t vnd_model_app_get; /*!< For ESP_BLE_MESH_MODEL_OP_VENDOR_MODEL_APP_GET */
esp_ble_mesh_cfg_kr_phase_get_t kr_phase_get; /*!< For ESP_BLE_MESH_MODEL_OP_KEY_REFRESH_PHASE_GET */
esp_ble_mesh_cfg_lpn_polltimeout_get_t lpn_pollto_get; /*!< For ESP_BLE_MESH_MODEL_OP_LPN_POLLTIMEOUT_GET */
} esp_ble_mesh_cfg_client_get_state_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_BEACON_SET
* ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_SET
* ESP_BLE_MESH_MODEL_OP_GATT_PROXY_SET
* ESP_BLE_MESH_MODEL_OP_RELAY_SET
* ESP_BLE_MESH_MODEL_OP_MODEL_PUB_SET
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_ADD
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_DELETE
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_OVERWRITE
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_OVERWRITE
* ESP_BLE_MESH_MODEL_OP_NET_KEY_ADD
* ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD
* ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND
* ESP_BLE_MESH_MODEL_OP_NODE_RESET
* ESP_BLE_MESH_MODEL_OP_FRIEND_SET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_SET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_SET
* the set_state parameter in the esp_ble_mesh_config_client_set_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_cfg_beacon_set_t beacon_set; /*!< For ESP_BLE_MESH_MODEL_OP_BEACON_SET */
esp_ble_mesh_cfg_default_ttl_set_t default_ttl_set; /*!< For ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_SET */
esp_ble_mesh_cfg_friend_set_t friend_set; /*!< For ESP_BLE_MESH_MODEL_OP_FRIEND_SET */
esp_ble_mesh_cfg_gatt_proxy_set_t gatt_proxy_set; /*!< For ESP_BLE_MESH_MODEL_OP_GATT_PROXY_SET */
esp_ble_mesh_cfg_relay_set_t relay_set; /*!< For ESP_BLE_MESH_MODEL_OP_RELAY_SET */
esp_ble_mesh_cfg_net_key_add_t net_key_add; /*!< For ESP_BLE_MESH_MODEL_OP_NET_KEY_ADD */
esp_ble_mesh_cfg_app_key_add_t app_key_add; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD */
esp_ble_mesh_cfg_model_app_bind_t model_app_bind; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND */
esp_ble_mesh_cfg_model_pub_set_t model_pub_set; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_PUB_SET */
esp_ble_mesh_cfg_model_sub_add_t model_sub_add; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD */
esp_ble_mesh_cfg_model_sub_delete_t model_sub_delete; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE */
esp_ble_mesh_cfg_model_sub_overwrite_t model_sub_overwrite; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_OVERWRITE */
esp_ble_mesh_cfg_model_sub_va_add_t model_sub_va_add; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_ADD */
esp_ble_mesh_cfg_model_sub_va_delete_t model_sub_va_delete; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_DELETE */
esp_ble_mesh_cfg_model_sub_va_overwrite_t model_sub_va_overwrite; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_OVERWRITE */
esp_ble_mesh_cfg_heartbeat_pub_set_t heartbeat_pub_set; /*!< For ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_SET */
esp_ble_mesh_cfg_heartbeat_sub_set_t heartbeat_sub_set; /*!< For ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_SET */
esp_ble_mesh_cfg_model_pub_va_set_t model_pub_va_set; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_PUB_VIRTUAL_ADDR_SET */
esp_ble_mesh_cfg_model_sub_delete_all_t model_sub_delete_all; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE_ALL */
esp_ble_mesh_cfg_net_key_update_t net_key_update; /*!< For ESP_BLE_MESH_MODEL_OP_NET_KEY_UPDATE */
esp_ble_mesh_cfg_net_key_delete_t net_key_delete; /*!< For ESP_BLE_MESH_MODEL_OP_NET_KEY_DELETE */
esp_ble_mesh_cfg_app_key_update_t app_key_update; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_UPDATE */
esp_ble_mesh_cfg_app_key_delete_t app_key_delete; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_DELETE */
esp_ble_mesh_cfg_node_identity_set_t node_identity_set; /*!< For ESP_BLE_MESH_MODEL_OP_NODE_IDENTITY_SET */
esp_ble_mesh_cfg_model_app_unbind_t model_app_unbind; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_APP_UNBIND */
esp_ble_mesh_cfg_kr_phase_set_t kr_phase_set; /*!< For ESP_BLE_MESH_MODEL_OP_KEY_REFRESH_PHASE_SET */
esp_ble_mesh_cfg_net_transmit_set_t net_transmit_set; /*!< For ESP_BLE_MESH_MODEL_OP_NETWORK_TRANSMIT_SET */
} esp_ble_mesh_cfg_client_set_state_t;
/** Parameter of Config Beacon Status */
typedef struct {
uint8_t beacon; /*!< Secure Network Beacon state value */
} esp_ble_mesh_cfg_beacon_status_cb_t;
/** Parameters of Config Composition Data Status */
typedef struct {
uint8_t page; /*!< Page number of the Composition Data */
struct net_buf_simple *composition_data; /*!< Pointer to Composition Data for the identified page */
} esp_ble_mesh_cfg_comp_data_status_cb_t;
/** Parameter of Config Default TTL Status */
typedef struct {
uint8_t default_ttl; /*!< Default TTL state value */
} esp_ble_mesh_cfg_default_ttl_status_cb_t;
/** Parameter of Config GATT Proxy Status */
typedef struct {
uint8_t gatt_proxy; /*!< GATT Proxy state value */
} esp_ble_mesh_cfg_gatt_proxy_status_cb_t;
/** Parameters of Config Relay Status */
typedef struct {
uint8_t relay; /*!< Relay state value */
uint8_t retransmit; /*!< Relay retransmit value(number of retransmissions and number of 10-millisecond steps between retransmissions) */
} esp_ble_mesh_cfg_relay_status_cb_t;
/** Parameters of Config Model Publication Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t publish_addr; /*!< Value of the publish address */
uint16_t app_idx; /*!< Index of the application key */
bool cred_flag; /*!< Value of the Friendship Credential Flag */
uint8_t ttl; /*!< Default TTL value for the outgoing messages */
uint8_t period; /*!< Period for periodic status publishing */
uint8_t transmit; /*!< Number of retransmissions and number of 50-millisecond steps between retransmissions */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_cfg_model_pub_status_cb_t;
/** Parameters of Config Model Subscription Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t sub_addr; /*!< Value of the address */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_cfg_model_sub_status_cb_t;
/** Parameters of Config NetKey Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
} esp_ble_mesh_cfg_net_key_status_cb_t;
/** Parameters of Config AppKey Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
uint16_t app_idx; /*!< Index of the application key */
} esp_ble_mesh_cfg_app_key_status_cb_t;
/** Parameters of Config Model App Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t app_idx; /*!< Index of the application key */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_cfg_mod_app_status_cb_t;
/** Parameter of Config Friend Status */
typedef struct {
uint8_t friend_state; /*!< Friend state value */
} esp_ble_mesh_cfg_friend_status_cb_t;
/** Parameters of Config Heartbeat Publication Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint8_t count; /*!< Number of Heartbeat messages remaining to be sent */
uint8_t period; /*!< Period for sending Heartbeat messages */
uint8_t ttl; /*!< TTL to be used when sending Heartbeat messages */
uint16_t features; /*!< Features that trigger Heartbeat messages when changed */
uint16_t net_idx; /*!< Index of the NetKey */
} esp_ble_mesh_cfg_hb_pub_status_cb_t;
/** Parameters of Config Heartbeat Subscription Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t src; /*!< Source address for Heartbeat messages */
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint8_t period; /*!< Remaining Period for processing Heartbeat messages */
uint8_t count; /*!< Number of Heartbeat messages received */
uint8_t min_hops; /*!< Minimum hops when receiving Heartbeat messages */
uint8_t max_hops; /*!< Maximum hops when receiving Heartbeat messages */
} esp_ble_mesh_cfg_hb_sub_status_cb_t;
/** Parameters of Config Network Transmit Status */
typedef struct {
uint8_t net_trans_count: 3; /*!< Number of transmissions for each Network PDU originating from the node */
uint8_t net_trans_step : 5; /*!< Maximum hops when receiving Heartbeat messages */
} esp_ble_mesh_cfg_net_trans_status_cb_t;
/** Parameters of Config SIG/Vendor Subscription List */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
struct net_buf_simple *sub_addr; /*!< A block of all addresses from the Subscription List */
} esp_ble_mesh_cfg_model_sub_list_cb_t;
/** Parameter of Config NetKey List */
typedef struct {
struct net_buf_simple *net_idx; /*!< A list of NetKey Indexes known to the node */
} esp_ble_mesh_cfg_net_key_list_cb_t;
/** Parameters of Config AppKey List */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< NetKey Index of the NetKey that the AppKeys are bound to */
struct net_buf_simple *app_idx; /*!< A list of AppKey indexes that are bound to the NetKey identified by NetKeyIndex */
} esp_ble_mesh_cfg_app_key_list_cb_t;
/** Parameters of Config Node Identity Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
uint8_t identity; /*!< Node Identity state */
} esp_ble_mesh_cfg_node_id_status_cb_t;
/** Parameters of Config SIG/Vendor Model App List */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
struct net_buf_simple *app_idx; /*!< All AppKey indexes bound to the Model */
} esp_ble_mesh_cfg_model_app_list_cb_t;
/** Parameters of Config Key Refresh Phase Status */
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
uint8_t phase; /*!< Key Refresh Phase state */
} esp_ble_mesh_cfg_kr_phase_status_cb_t;
/** Parameters of Config Low Power Node PollTimeout Status */
typedef struct {
uint16_t lpn_addr; /*!< The unicast address of the Low Power node */
int32_t poll_timeout; /*!< The current value of the PollTimeout timer of the Low Power node */
} esp_ble_mesh_cfg_lpn_pollto_status_cb_t;
/**
* @brief Configuration Client Model received message union
*/
typedef union {
esp_ble_mesh_cfg_beacon_status_cb_t beacon_status; /*!< The beacon status value */
esp_ble_mesh_cfg_comp_data_status_cb_t comp_data_status; /*!< The composition data status value */
esp_ble_mesh_cfg_default_ttl_status_cb_t default_ttl_status; /*!< The default_ttl status value */
esp_ble_mesh_cfg_gatt_proxy_status_cb_t gatt_proxy_status; /*!< The gatt_proxy status value */
esp_ble_mesh_cfg_relay_status_cb_t relay_status; /*!< The relay status value */
esp_ble_mesh_cfg_model_pub_status_cb_t model_pub_status; /*!< The model publication status value */
esp_ble_mesh_cfg_model_sub_status_cb_t model_sub_status; /*!< The model subscription status value */
esp_ble_mesh_cfg_net_key_status_cb_t netkey_status; /*!< The netkey status value */
esp_ble_mesh_cfg_app_key_status_cb_t appkey_status; /*!< The appkey status value */
esp_ble_mesh_cfg_mod_app_status_cb_t model_app_status; /*!< The model app status value */
esp_ble_mesh_cfg_friend_status_cb_t friend_status; /*!< The friend status value */
esp_ble_mesh_cfg_hb_pub_status_cb_t heartbeat_pub_status; /*!< The heartbeat publication status value */
esp_ble_mesh_cfg_hb_sub_status_cb_t heartbeat_sub_status; /*!< The heartbeat subscription status value */
esp_ble_mesh_cfg_net_trans_status_cb_t net_transmit_status; /*!< The network transmit status value */
esp_ble_mesh_cfg_model_sub_list_cb_t model_sub_list; /*!< The model subscription list value */
esp_ble_mesh_cfg_net_key_list_cb_t netkey_list; /*!< The network key index list value */
esp_ble_mesh_cfg_app_key_list_cb_t appkey_list; /*!< The application key index list value */
esp_ble_mesh_cfg_node_id_status_cb_t node_identity_status; /*!< The node identity status value */
esp_ble_mesh_cfg_model_app_list_cb_t model_app_list; /*!< The model application key index list value */
esp_ble_mesh_cfg_kr_phase_status_cb_t kr_phase_status; /*!< The key refresh phase status value */
esp_ble_mesh_cfg_lpn_pollto_status_cb_t lpn_timeout_status; /*!< The low power node poll timeout status value */
} esp_ble_mesh_cfg_client_common_cb_param_t;
/** Configuration Client Model callback parameters */
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters */
esp_ble_mesh_cfg_client_common_cb_param_t status_cb; /*!< The config status message callback values */
} esp_ble_mesh_cfg_client_cb_param_t;
/** This enum value is the event of Configuration Client Model */
typedef enum {
ESP_BLE_MESH_CFG_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_CFG_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_CFG_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_CFG_CLIENT_EVT_MAX,
} esp_ble_mesh_cfg_client_cb_event_t;
/**
* @brief Configuration Server model related context.
*/
/** Parameters of Config Model Publication Set */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t pub_addr; /*!< Publish Address */
uint16_t app_idx; /*!< AppKey Index */
bool cred_flag; /*!< Friendship Credential Flag */
uint8_t pub_ttl; /*!< Publish TTL */
uint8_t pub_period; /*!< Publish Period */
uint8_t pub_retransmit; /*!< Publish Retransmit */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_mod_pub_set_t;
/** Parameters of Config Model Publication Virtual Address Set */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint8_t label_uuid[16]; /*!< Label UUID */
uint16_t app_idx; /*!< AppKey Index */
bool cred_flag; /*!< Friendship Credential Flag */
uint8_t pub_ttl; /*!< Publish TTL */
uint8_t pub_period; /*!< Publish Period */
uint8_t pub_retransmit; /*!< Publish Retransmit */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_mod_pub_va_set_t;
/** Parameters of Config Model Subscription Add */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t sub_addr; /*!< Subscription Address */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_sub_add_t;
/** Parameters of Config Model Subscription Delete */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t sub_addr; /*!< Subscription Address */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_sub_delete_t;
/** Parameters of Config NetKey Add */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint8_t net_key[16]; /*!< NetKey */
} esp_ble_mesh_state_change_cfg_netkey_add_t;
/** Parameters of Config NetKey Update */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint8_t net_key[16]; /*!< NetKey */
} esp_ble_mesh_state_change_cfg_netkey_update_t;
/** Parameter of Config NetKey Delete */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
} esp_ble_mesh_state_change_cfg_netkey_delete_t;
/** Parameters of Config AppKey Add */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint16_t app_idx; /*!< AppKey Index */
uint8_t app_key[16]; /*!< AppKey */
} esp_ble_mesh_state_change_cfg_appkey_add_t;
/** Parameters of Config AppKey Update */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint16_t app_idx; /*!< AppKey Index */
uint8_t app_key[16]; /*!< AppKey */
} esp_ble_mesh_state_change_cfg_appkey_update_t;
/** Parameters of Config AppKey Delete */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint16_t app_idx; /*!< AppKey Index */
} esp_ble_mesh_state_change_cfg_appkey_delete_t;
/** Parameters of Config Model App Bind */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t app_idx; /*!< AppKey Index */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_app_bind_t;
/** Parameters of Config Model App Unbind */
typedef struct {
uint16_t element_addr; /*!< Element Address */
uint16_t app_idx; /*!< AppKey Index */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_state_change_cfg_model_app_unbind_t;
/** Parameters of Config Key Refresh Phase Set */
typedef struct {
uint16_t net_idx; /*!< NetKey Index */
uint8_t kr_phase; /*!< New Key Refresh Phase Transition */
} esp_ble_mesh_state_change_cfg_kr_phase_set_t;
/**
* @brief Configuration Server model state change value union
*/
typedef union {
/**
* The recv_op in ctx can be used to decide which state is changed.
*/
esp_ble_mesh_state_change_cfg_mod_pub_set_t mod_pub_set; /*!< Config Model Publication Set */
esp_ble_mesh_state_change_cfg_mod_pub_va_set_t mod_pub_va_set; /*!< Config Model Publication Virtual Address Set */
esp_ble_mesh_state_change_cfg_model_sub_add_t mod_sub_add; /*!< Config Model Subscription Add */
esp_ble_mesh_state_change_cfg_model_sub_delete_t mod_sub_delete; /*!< Config Model Subscription Delete */
esp_ble_mesh_state_change_cfg_netkey_add_t netkey_add; /*!< Config NetKey Add */
esp_ble_mesh_state_change_cfg_netkey_update_t netkey_update; /*!< Config NetKey Update */
esp_ble_mesh_state_change_cfg_netkey_delete_t netkey_delete; /*!< Config NetKey Delete */
esp_ble_mesh_state_change_cfg_appkey_add_t appkey_add; /*!< Config AppKey Add */
esp_ble_mesh_state_change_cfg_appkey_update_t appkey_update; /*!< Config AppKey Update */
esp_ble_mesh_state_change_cfg_appkey_delete_t appkey_delete; /*!< Config AppKey Delete */
esp_ble_mesh_state_change_cfg_model_app_bind_t mod_app_bind; /*!< Config Model App Bind */
esp_ble_mesh_state_change_cfg_model_app_unbind_t mod_app_unbind; /*!< Config Model App Unbind */
esp_ble_mesh_state_change_cfg_kr_phase_set_t kr_phase_set; /*!< Config Key Refresh Phase Set */
} esp_ble_mesh_cfg_server_state_change_t;
/**
* @brief Configuration Server model callback value union
*/
typedef union {
esp_ble_mesh_cfg_server_state_change_t state_change; /*!< ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT */
} esp_ble_mesh_cfg_server_cb_value_t;
/** Configuration Server model callback parameters */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the server model structure */
esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received message */
esp_ble_mesh_cfg_server_cb_value_t value; /*!< Value of the received configuration messages */
} esp_ble_mesh_cfg_server_cb_param_t;
/** This enum value is the event of Configuration Server model */
typedef enum {
ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT,
ESP_BLE_MESH_CFG_SERVER_EVT_MAX,
} esp_ble_mesh_cfg_server_cb_event_t;
/**
* @brief Bluetooth Mesh Config Client and Server Model functions.
*/
/**
* @brief Configuration Client Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_cfg_client_cb_t)(esp_ble_mesh_cfg_client_cb_event_t event,
esp_ble_mesh_cfg_client_cb_param_t *param);
/**
* @brief Configuration Server Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_cfg_server_cb_t)(esp_ble_mesh_cfg_server_cb_event_t event,
esp_ble_mesh_cfg_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Config Client Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_config_client_callback(esp_ble_mesh_cfg_client_cb_t callback);
/**
* @brief Register BLE Mesh Config Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_config_server_callback(esp_ble_mesh_cfg_server_cb_t callback);
/**
* @brief Get the value of Config Server Model states using the Config Client Model get messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_opcode_config_client_get_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_config_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_get_state_t *get_state);
/**
* @brief Set the value of the Configuration Server Model states using the Config Client Model set messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_opcode_config_client_set_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_config_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_set_state_t *set_state);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_CONFIG_MODEL_API_H_ */
@@ -0,0 +1,406 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_HEALTH_MODEL_API_H_
#define _ESP_BLE_MESH_HEALTH_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @def ESP_BLE_MESH_MODEL_HEALTH_SRV
*
* @brief Define a new Health Server Model.
*
* @note The Health Server Model can only be included by a Primary Element.
*
* @param srv Pointer to the unique struct esp_ble_mesh_health_srv_t.
* @param pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
*
* @return New Health Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_HEALTH_SRV(srv, pub) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_HEALTH_SRV, \
NULL, pub, srv)
/** @def ESP_BLE_MESH_MODEL_HEALTH_CLI
*
* @brief Define a new Health Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Health Client Model.
*
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Health Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_HEALTH_CLI(cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_HEALTH_CLI, \
NULL, NULL, cli_data)
/** @def ESP_BLE_MESH_HEALTH_PUB_DEFINE
*
* A helper to define a health publication context
*
* @param _name Name given to the publication context variable.
* @param _max Maximum number of faults the element can have.
* @param _role Role of the device which contains the model.
*/
#define ESP_BLE_MESH_HEALTH_PUB_DEFINE(_name, _max, _role) \
ESP_BLE_MESH_MODEL_PUB_DEFINE(_name, (1 + 3 + (_max)), _role)
/**
* SIG identifier of Health Fault Test.
* 0x01 ~ 0xFF: Vendor Specific Test.
*/
#define ESP_BLE_MESH_HEALTH_STANDARD_TEST 0x00
/**
* Fault values of Health Fault Test.
* 0x33 ~ 0x7F: Reserved for Future Use.
* 0x80 ~ 0xFF: Vendor Specific Warning/Error.
*/
#define ESP_BLE_MESH_NO_FAULT 0x00
#define ESP_BLE_MESH_BATTERY_LOW_WARNING 0x01
#define ESP_BLE_MESH_BATTERY_LOW_ERROR 0x02
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_LOW_WARNING 0x03
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_LOW_ERROR 0x04
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_HIGH_WARNING 0x05
#define ESP_BLE_MESH_SUPPLY_VOLTAGE_TOO_HIGH_ERROR 0x06
#define ESP_BLE_MESH_POWER_SUPPLY_INTERRUPTED_WARNING 0x07
#define ESP_BLE_MESH_POWER_SUPPLY_INTERRUPTED_ERROR 0x08
#define ESP_BLE_MESH_NO_LOAD_WARNING 0x09
#define ESP_BLE_MESH_NO_LOAD_ERROR 0x0A
#define ESP_BLE_MESH_OVERLOAD_WARNING 0x0B
#define ESP_BLE_MESH_OVERLOAD_ERROR 0x0C
#define ESP_BLE_MESH_OVERHEAT_WARNING 0x0D
#define ESP_BLE_MESH_OVERHEAT_ERROR 0x0E
#define ESP_BLE_MESH_CONDENSATION_WARNING 0x0F
#define ESP_BLE_MESH_CONDENSATION_ERROR 0x10
#define ESP_BLE_MESH_VIBRATION_WARNING 0x11
#define ESP_BLE_MESH_VIBRATION_ERROR 0x12
#define ESP_BLE_MESH_CONFIGURATION_WARNING 0x13
#define ESP_BLE_MESH_CONFIGURATION_ERROR 0x14
#define ESP_BLE_MESH_ELEMENT_NOT_CALIBRATED_WARNING 0x15
#define ESP_BLE_MESH_ELEMENT_NOT_CALIBRATED_ERROR 0x16
#define ESP_BLE_MESH_MEMORY_WARNING 0x17
#define ESP_BLE_MESH_MEMORY_ERROR 0x18
#define ESP_BLE_MESH_SELF_TEST_WARNING 0x19
#define ESP_BLE_MESH_SELF_TEST_ERROR 0x1A
#define ESP_BLE_MESH_INPUT_TOO_LOW_WARNING 0x1B
#define ESP_BLE_MESH_INPUT_TOO_LOW_ERROR 0x1C
#define ESP_BLE_MESH_INPUT_TOO_HIGH_WARNING 0x1D
#define ESP_BLE_MESH_INPUT_TOO_HIGH_ERROR 0x1E
#define ESP_BLE_MESH_INPUT_NO_CHANGE_WARNING 0x1F
#define ESP_BLE_MESH_INPUT_NO_CHANGE_ERROR 0x20
#define ESP_BLE_MESH_ACTUATOR_BLOCKED_WARNING 0x21
#define ESP_BLE_MESH_ACTUATOR_BLOCKED_ERROR 0x22
#define ESP_BLE_MESH_HOUSING_OPENED_WARNING 0x23
#define ESP_BLE_MESH_HOUSING_OPENED_ERROR 0x24
#define ESP_BLE_MESH_TAMPER_WARNING 0x25
#define ESP_BLE_MESH_TAMPER_ERROR 0x26
#define ESP_BLE_MESH_DEVICE_MOVED_WARNING 0x27
#define ESP_BLE_MESH_DEVICE_MOVED_ERROR 0x28
#define ESP_BLE_MESH_DEVICE_DROPPED_WARNING 0x29
#define ESP_BLE_MESH_DEVICE_DROPPED_ERROR 0x2A
#define ESP_BLE_MESH_OVERFLOW_WARNING 0x2B
#define ESP_BLE_MESH_OVERFLOW_ERROR 0x2C
#define ESP_BLE_MESH_EMPTY_WARNING 0x2D
#define ESP_BLE_MESH_EMPTY_ERROR 0x2E
#define ESP_BLE_MESH_INTERNAL_BUS_WARNING 0x2F
#define ESP_BLE_MESH_INTERNAL_BUS_ERROR 0x30
#define ESP_BLE_MESH_MECHANISM_JAMMED_WARNING 0x31
#define ESP_BLE_MESH_MECHANISM_JAMMED_ERROR 0x32
/** ESP BLE Mesh Health Server callback */
typedef struct {
/** Clear health registered faults. Initialized by the stack. */
esp_ble_mesh_cb_t fault_clear;
/** Run a specific health test. Initialized by the stack. */
esp_ble_mesh_cb_t fault_test;
/** Health attention on callback. Initialized by the stack. */
esp_ble_mesh_cb_t attention_on;
/** Health attention off callback. Initialized by the stack. */
esp_ble_mesh_cb_t attention_off;
} esp_ble_mesh_health_srv_cb_t;
#define ESP_BLE_MESH_HEALTH_FAULT_ARRAY_SIZE 32
/** ESP BLE Mesh Health Server test Context */
typedef struct {
uint8_t id_count; /*!< Number of Health self-test ID */
const uint8_t *test_ids; /*!< Array of Health self-test IDs */
uint16_t company_id; /*!< Company ID used to identify the Health Fault state */
uint8_t prev_test_id; /*!< Current test ID of the health fault test */
uint8_t current_faults[ESP_BLE_MESH_HEALTH_FAULT_ARRAY_SIZE]; /*!< Array of current faults */
uint8_t registered_faults[ESP_BLE_MESH_HEALTH_FAULT_ARRAY_SIZE]; /*!< Array of registered faults */
} __attribute__((packed)) esp_ble_mesh_health_test_t;
/** ESP BLE Mesh Health Server Model Context */
typedef struct {
/** Pointer to Health Server Model */
esp_ble_mesh_model_t *model;
/** Health callback struct */
esp_ble_mesh_health_srv_cb_t health_cb;
/** Attention Timer state */
struct k_delayed_work attention_timer;
/** Attention Timer start flag */
bool attention_timer_start;
/** Health Server fault test */
esp_ble_mesh_health_test_t health_test;
} esp_ble_mesh_health_srv_t;
/** Parameter of Health Fault Get */
typedef struct {
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_get_t;
/** Parameter of Health Attention Set */
typedef struct {
uint8_t attention; /*!< Value of the Attention Timer state */
} esp_ble_mesh_health_attention_set_t;
/** Parameter of Health Period Set */
typedef struct {
uint8_t fast_period_divisor; /*!< Divider for the Publish Period */
} esp_ble_mesh_health_period_set_t;
/** Parameter of Health Fault Test */
typedef struct {
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
uint8_t test_id; /*!< ID of a specific test to be performed */
} esp_ble_mesh_health_fault_test_t;
/** Parameter of Health Fault Clear */
typedef struct {
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_clear_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_GET
* ESP_BLE_MESH_MODEL_OP_ATTENTION_GET
* ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_GET
* the get_state parameter in the esp_ble_mesh_health_client_get_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_health_fault_get_t fault_get; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_GET. */
} esp_ble_mesh_health_client_get_state_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR
* ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR_UNACK
* ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST
* ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST_UNACK
* ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET
* ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET_UNACK
* ESP_BLE_MESH_MODEL_OP_ATTENTION_SET
* ESP_BLE_MESH_MODEL_OP_ATTENTION_SET_UNACK
* the set_state parameter in the esp_ble_mesh_health_client_set_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_health_attention_set_t attention_set; /*!< For ESP_BLE_MESH_MODEL_OP_ATTENTION_SET or ESP_BLE_MESH_MODEL_OP_ATTENTION_SET_UNACK. */
esp_ble_mesh_health_period_set_t period_set; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET or ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET_UNACK. */
esp_ble_mesh_health_fault_test_t fault_test; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST or ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST_UNACK. */
esp_ble_mesh_health_fault_clear_t fault_clear; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR or ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR_UNACK. */
} esp_ble_mesh_health_client_set_state_t;
/** Parameters of Health Current Status */
typedef struct {
uint8_t test_id; /*!< ID of a most recently performed test */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
struct net_buf_simple *fault_array; /*!< FaultArray field contains a sequence of 1-octet fault values */
} esp_ble_mesh_health_current_status_cb_t;
/** Parameters of Health Fault Status */
typedef struct {
uint8_t test_id; /*!< ID of a most recently performed test */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
struct net_buf_simple *fault_array; /*!< FaultArray field contains a sequence of 1-octet fault values */
} esp_ble_mesh_health_fault_status_cb_t;
/** Parameter of Health Period Status */
typedef struct {
uint8_t fast_period_divisor; /*!< Divider for the Publish Period */
} esp_ble_mesh_health_period_status_cb_t;
/** Parameter of Health Attention Status */
typedef struct {
uint8_t attention; /*!< Value of the Attention Timer state */
} esp_ble_mesh_health_attention_status_cb_t;
/**
* @brief Health Client Model received message union
*/
typedef union {
esp_ble_mesh_health_current_status_cb_t current_status; /*!< The health current status value */
esp_ble_mesh_health_fault_status_cb_t fault_status; /*!< The health fault status value */
esp_ble_mesh_health_period_status_cb_t period_status; /*!< The health period status value */
esp_ble_mesh_health_attention_status_cb_t attention_status; /*!< The health attention status value */
} esp_ble_mesh_health_client_common_cb_param_t;
/** Health Client Model callback parameters */
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_health_client_common_cb_param_t status_cb; /*!< The health message status callback values */
} esp_ble_mesh_health_client_cb_param_t;
/** This enum value is the event of Health Client Model */
typedef enum {
ESP_BLE_MESH_HEALTH_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_EVT_MAX,
} esp_ble_mesh_health_client_cb_event_t;
/** Parameter of publishing Health Current Status completion event */
typedef struct {
int error_code; /*!< The result of publishing Health Current Status */
esp_ble_mesh_elem_t *element; /*!< Pointer to the element which contains the Health Server Model */
} esp_ble_mesh_health_fault_update_comp_cb_t;
/** Parameters of Health Fault Clear event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_clear_cb_t;
/** Parameters of Health Fault Test event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
uint8_t test_id; /*!< ID of a specific test to be performed */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_test_cb_t;
/** Parameter of Health Attention On event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
uint8_t time; /*!< Duration of attention timer on (in seconds) */
} esp_ble_mesh_health_attention_on_cb_t;
/** Parameter of Health Attention Off event */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Health Server Model */
} esp_ble_mesh_health_attention_off_cb_t;
/**
* @brief Health Server Model callback parameters union
*/
typedef union {
esp_ble_mesh_health_fault_update_comp_cb_t fault_update_comp; /*!< ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT */
esp_ble_mesh_health_fault_clear_cb_t fault_clear; /*!< ESP_BLE_MESH_HEALTH_SERVER_FAULT_CLEAR_EVT */
esp_ble_mesh_health_fault_test_cb_t fault_test; /*!< ESP_BLE_MESH_HEALTH_SERVER_FAULT_TEST_EVT */
esp_ble_mesh_health_attention_on_cb_t attention_on; /*!< ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_ON_EVT */
esp_ble_mesh_health_attention_off_cb_t attention_off; /*!< ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_OFF_EVT */
} esp_ble_mesh_health_server_cb_param_t;
/** This enum value is the event of Health Server Model */
typedef enum {
ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMP_EVT,
ESP_BLE_MESH_HEALTH_SERVER_FAULT_CLEAR_EVT,
ESP_BLE_MESH_HEALTH_SERVER_FAULT_TEST_EVT,
ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_ON_EVT,
ESP_BLE_MESH_HEALTH_SERVER_ATTENTION_OFF_EVT,
ESP_BLE_MESH_HEALTH_SERVER_EVT_MAX,
} esp_ble_mesh_health_server_cb_event_t;
/**
* @brief Bluetooth Mesh Health Client and Server Model function.
*/
/**
* @brief Health Client Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_health_client_cb_t)(esp_ble_mesh_health_client_cb_event_t event,
esp_ble_mesh_health_client_cb_param_t *param);
/**
* @brief Health Server Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_health_server_cb_t)(esp_ble_mesh_health_server_cb_event_t event,
esp_ble_mesh_health_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Health Model callback, the callback will report Health Client & Server Model events.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_health_client_callback(esp_ble_mesh_health_client_cb_t callback);
/**
* @brief Register BLE Mesh Health Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_health_server_callback(esp_ble_mesh_health_server_cb_t callback);
/**
* @brief This function is called to get the Health Server states using the Health Client Model get messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_opcode_health_client_get_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_health_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_get_state_t *get_state);
/**
* @brief This function is called to set the Health Server states using the Health Client Model set messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_opcode_health_client_set_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_health_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_set_state_t *set_state);
/**
* @brief This function is called by the Health Server Model to update the context of its Health Current status.
*
* @param[in] element: The element to which the Health Server Model belongs.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_health_server_fault_update(esp_ble_mesh_elem_t *element);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_HEALTH_MODEL_API_H_ */
@@ -0,0 +1,709 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Bluetooth Mesh Sensor Client Model APIs.
*/
#ifndef _ESP_BLE_MESH_SENSOR_MODEL_API_H_
#define _ESP_BLE_MESH_SENSOR_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @def ESP_BLE_MESH_MODEL_SENSOR_CLI
*
* @brief Define a new Sensor Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Sensor 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 Sensor Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_SENSOR_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SENSOR_CLI, \
NULL, cli_pub, cli_data)
/**
* @brief Bluetooth Mesh Sensor Client Model Get and Set parameters structure.
*/
/** Parameters of Sensor Descriptor Get */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property ID of a sensor (optional) */
} esp_ble_mesh_sensor_descriptor_get_t;
/** Parameter of Sensor Cadence Get */
typedef struct {
uint16_t property_id; /*!< Property ID of a sensor */
} esp_ble_mesh_sensor_cadence_get_t;
/** Parameters of Sensor Cadence Set */
typedef struct {
uint16_t property_id; /*!< Property ID for the sensor */
uint8_t fast_cadence_period_divisor : 7, /*!< Divisor for the publish period */
status_trigger_type : 1; /*!< The unit and format of the Status Trigger Delta fields */
struct net_buf_simple *status_trigger_delta_down; /*!< Delta down value that triggers a status message */
struct net_buf_simple *status_trigger_delta_up; /*!< Delta up value that triggers a status message */
uint8_t status_min_interval; /*!< Minimum interval between two consecutive Status messages */
struct net_buf_simple *fast_cadence_low; /*!< Low value for the fast cadence range */
struct net_buf_simple *fast_cadence_high; /*!< Fast value for the fast cadence range */
} esp_ble_mesh_sensor_cadence_set_t;
/** Parameter of Sensor Settings Get */
typedef struct {
uint16_t sensor_property_id; /*!< Property ID of a sensor */
} esp_ble_mesh_sensor_settings_get_t;
/** Parameters of Sensor Setting Get */
typedef struct {
uint16_t sensor_property_id; /*!< Property ID of a sensor */
uint16_t sensor_setting_property_id; /*!< Setting ID identifying a setting within a sensor */
} esp_ble_mesh_sensor_setting_get_t;
/** Parameters of Sensor Setting Set */
typedef struct {
uint16_t sensor_property_id; /*!< Property ID identifying a sensor */
uint16_t sensor_setting_property_id; /*!< Setting ID identifying a setting within a sensor */
struct net_buf_simple *sensor_setting_raw; /*!< Raw value for the setting */
} esp_ble_mesh_sensor_setting_set_t;
/** Parameters of Sensor Get */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property ID for the sensor (optional) */
} esp_ble_mesh_sensor_get_t;
/** Parameters of Sensor Column Get */
typedef struct {
uint16_t property_id; /*!< Property identifying a sensor */
struct net_buf_simple *raw_value_x; /*!< Raw value identifying a column */
} esp_ble_mesh_sensor_column_get_t;
/** Parameters of Sensor Series Get */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property identifying a sensor */
struct net_buf_simple *raw_value_x1; /*!< Raw value identifying a starting column (optional) */
struct net_buf_simple *raw_value_x2; /*!< Raw value identifying an ending column (C.1) */
} esp_ble_mesh_sensor_series_get_t;
/**
* @brief Sensor Client Model get message union
*/
typedef union {
esp_ble_mesh_sensor_descriptor_get_t descriptor_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET */
esp_ble_mesh_sensor_cadence_get_t cadence_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET */
esp_ble_mesh_sensor_settings_get_t settings_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET */
esp_ble_mesh_sensor_setting_get_t setting_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_GET */
esp_ble_mesh_sensor_get_t sensor_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_GET */
esp_ble_mesh_sensor_column_get_t column_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET */
esp_ble_mesh_sensor_series_get_t series_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET */
} esp_ble_mesh_sensor_client_get_state_t;
/**
* @brief Sensor Client Model set message union
*/
typedef union {
esp_ble_mesh_sensor_cadence_set_t cadence_set; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET & ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK */
esp_ble_mesh_sensor_setting_set_t setting_set; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET & ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK */
} esp_ble_mesh_sensor_client_set_state_t;
/**
* @brief Bluetooth Mesh Sensor Client Model Get and Set callback parameters structure.
*/
/** Parameter of Sensor Descriptor Status */
typedef struct {
struct net_buf_simple *descriptor; /*!< Sequence of 8-octet sensor descriptors (optional) */
} esp_ble_mesh_sensor_descriptor_status_cb_t;
/** Parameters of Sensor Cadence Status */
typedef struct {
uint16_t property_id; /*!< Property for the sensor */
struct net_buf_simple *sensor_cadence_value; /*!< Value of sensor cadence state */
} esp_ble_mesh_sensor_cadence_status_cb_t;
/** Parameters of Sensor Settings Status */
typedef struct {
uint16_t sensor_property_id; /*!< Property ID identifying a sensor */
struct net_buf_simple *sensor_setting_property_ids; /*!< A sequence of N sensor setting property IDs (optional) */
} esp_ble_mesh_sensor_settings_status_cb_t;
/** Parameters of Sensor Setting Status */
typedef struct {
bool op_en; /*!< Indicate id optional parameters are included */
uint16_t sensor_property_id; /*!< Property ID identifying a sensor */
uint16_t sensor_setting_property_id; /*!< Setting ID identifying a setting within a sensor */
uint8_t sensor_setting_access; /*!< Read/Write access rights for the setting (optional) */
struct net_buf_simple *sensor_setting_raw; /*!< Raw value for the setting */
} esp_ble_mesh_sensor_setting_status_cb_t;
/** Parameter of Sensor Status */
typedef struct {
struct net_buf_simple *marshalled_sensor_data; /*!< Value of sensor data state (optional) */
} esp_ble_mesh_sensor_status_cb_t;
/** Parameters of Sensor Column Status */
typedef struct {
uint16_t property_id; /*!< Property identifying a sensor and the Y axis */
struct net_buf_simple *sensor_column_value; /*!< Left values of sensor column status */
} esp_ble_mesh_sensor_column_status_cb_t;
/** Parameters of Sensor Series Status */
typedef struct {
uint16_t property_id; /*!< Property identifying a sensor and the Y axis */
struct net_buf_simple *sensor_series_value; /*!< Left values of sensor series status */
} esp_ble_mesh_sensor_series_status_cb_t;
/**
* @brief Sensor Client Model received message union
*/
typedef union {
esp_ble_mesh_sensor_descriptor_status_cb_t descriptor_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS */
esp_ble_mesh_sensor_cadence_status_cb_t cadence_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS */
esp_ble_mesh_sensor_settings_status_cb_t settings_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS */
esp_ble_mesh_sensor_setting_status_cb_t setting_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS */
esp_ble_mesh_sensor_status_cb_t sensor_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_STATUS */
esp_ble_mesh_sensor_column_status_cb_t column_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS */
esp_ble_mesh_sensor_series_status_cb_t series_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS */
} esp_ble_mesh_sensor_client_status_cb_t;
/** Sensor Client Model callback parameters */
typedef struct {
int error_code; /*!< 0: success,
* otherwise failure. For the error code values please refer to errno.h file.
* A negative sign is added to the standard error codes in errno.h. */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_sensor_client_status_cb_t status_cb; /*!< The sensor status message callback values */
} esp_ble_mesh_sensor_client_cb_param_t;
/** This enum value is the event of Sensor Client Model */
typedef enum {
ESP_BLE_MESH_SENSOR_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_EVT_MAX,
} esp_ble_mesh_sensor_client_cb_event_t;
/**
* @brief Bluetooth Mesh Sensor Client Model function.
*/
/**
* @brief Sensor Client Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_sensor_client_cb_t)(esp_ble_mesh_sensor_client_cb_event_t event,
esp_ble_mesh_sensor_client_cb_param_t *param);
/**
* @brief Register BLE Mesh Sensor Client Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_sensor_client_callback(esp_ble_mesh_sensor_client_cb_t callback);
/**
* @brief Get the value of Sensor Server Model states using the Sensor Client Model get messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_sensor_message_opcode_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to sensor get message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_sensor_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_sensor_client_get_state_t *get_state);
/**
* @brief Set the value of Sensor Server Model states using the Sensor Client Model set messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_sensor_message_opcode_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to sensor set message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_sensor_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_sensor_client_set_state_t *set_state);
/**
* @brief Sensor Server Models related context.
*/
/** @def ESP_BLE_MESH_MODEL_SENSOR_SRV
*
* @brief Define a new Sensor Server Model.
*
* @note 1. The Sensor Server model is a root model. When this model is present
* on an element, the corresponding Sensor Setup Server model shall
* also be present.
* 2. This model shall support model publication and model subscription.
*
* @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_sensor_srv_t.
*
* @return New Sensor Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SENSOR_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SENSOR_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SENSOR_SETUP_SRV
*
* @brief Define a new Sensor Setup Server Model.
*
* @note 1. The Sensor Setup Server model extends the Sensor Server model.
* 2. This model shall support model publication and model subscription.
*
* @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_sensor_setup_srv_t.
*
* @return New Sensor Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SENSOR_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV, \
NULL, srv_pub, srv_data)
#define ESP_BLE_MESH_INVALID_SENSOR_PROPERTY_ID 0x0000 /*!< Invalid Sensor Property ID */
#define ESP_BLE_MESH_SENSOR_PROPERTY_ID_LEN 0x02 /*!< Length of Sensor Property ID */
#define ESP_BLE_MESH_SENSOR_DESCRIPTOR_LEN 0x08 /*!< Length of Sensor Descriptor state */
#define ESP_BLE_MESH_SENSOR_UNSPECIFIED_POS_TOLERANCE 0x000 /*!< Unspecified Sensor Positive Tolerance */
#define ESP_BLE_MESH_SENSOR_UNSPECIFIED_NEG_TOLERANCE 0x000 /*!< Unspecified Sensor Negative Tolerance */
#define ESP_BLE_MESH_SENSOR_NOT_APPL_MEASURE_PERIOD 0x00 /*!< Not applicable Sensor Measurement Period */
#define ESP_BLE_MESH_SENSOR_NOT_APPL_UPDATE_INTERVAL 0x00 /*!< Not applicable Sensor Update Interval */
#define ESP_BLE_MESH_INVALID_SENSOR_SETTING_PROPERTY_ID 0x0000 /*!< Invalid Sensor Setting Property ID */
#define ESP_BLE_MESH_SENSOR_SETTING_PROPERTY_ID_LEN 0x02 /*!< Length of Sensor Setting Property ID */
#define ESP_BLE_MESH_SENSOR_SETTING_ACCESS_LEN 0x01 /*!< Length of Sensor Setting Access */
#define ESP_BLE_MESH_SENSOR_SETTING_ACCESS_READ 0x01 /*!< Sensor Setting Access - Read */
#define ESP_BLE_MESH_SENSOR_SETTING_ACCESS_READ_WRITE 0x03 /*!< Sensor Setting Access - Read & Write */
#define ESP_BLE_MESH_SENSOR_DIVISOR_TRIGGER_TYPE_LEN 0x01 /*!< Length of Sensor Divisor Trigger Type */
#define ESP_BLE_MESH_SENSOR_STATUS_MIN_INTERVAL_LEN 0x01 /*!< Length of Sensor Status Min Interval */
#define ESP_BLE_MESH_SENSOR_PERIOD_DIVISOR_MAX_VALUE 15 /*!< Maximum value of Sensor Period Divisor */
#define ESP_BLE_MESH_SENSOR_STATUS_MIN_INTERVAL_MAX 26 /*!< Maximum value of Sensor Status Min Interval */
/**
* Sensor Status Trigger Type - Format Type of the characteristic
* that the Sensor Property ID state references
*/
#define ESP_BLE_MESH_SENSOR_STATUS_TRIGGER_TYPE_CHAR 0
/** Sensor Status Trigger Type - Format Type "uint16" */
#define ESP_BLE_MESH_SENSOR_STATUS_TRIGGER_TYPE_UINT16 1
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_A 0x00 /*!< Sensor Data Format A */
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_B 0x01 /*!< Sensor Data Format B */
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_A_MPID_LEN 0x02 /*!< MPID length of Sensor Data Format A */
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_B_MPID_LEN 0x03 /*!< MPID length of Sensor Data Format B */
/**
* Zero length of Sensor Data.
*
* Note:
* The Length field is a 1-based uint7 value (valid range 0x00x7F,
* representing range of 1127). The value 0x7F represents a length
* of zero.
*/
#define ESP_BLE_MESH_SENSOR_DATA_ZERO_LEN 0x7F
/** @def ESP_BLE_MESH_GET_SENSOR_DATA_FORMAT
*
* @brief Get format of the sensor data.
*
* @note Multiple sensor data may be concatenated. Make sure the _data pointer is
* updated before getting the format of the corresponding sensor data.
*
* @param _data Pointer to the start of the sensor data.
*
* @return Format of the sensor data.
*/
#define ESP_BLE_MESH_GET_SENSOR_DATA_FORMAT(_data) (((_data)[0]) & BIT_MASK(1))
/** @def ESP_BLE_MESH_GET_SENSOR_DATA_LENGTH
*
* @brief Get length of the sensor data.
*
* @note Multiple sensor data may be concatenated. Make sure the _data pointer is
* updated before getting the length of the corresponding sensor data.
*
* @param _data Pointer to the start of the sensor data.
* @param _fmt Format of the sensor data.
*
* @return Length (zero-based) of the sensor data.
*/
#define ESP_BLE_MESH_GET_SENSOR_DATA_LENGTH(_data, _fmt) \
(((_fmt) == ESP_BLE_MESH_SENSOR_DATA_FORMAT_A) ? ((((_data)[0]) >> 1) & BIT_MASK(4)) : ((((_data)[0]) >> 1) & BIT_MASK(7)))
/** @def ESP_BLE_MESH_GET_SENSOR_DATA_PROPERTY_ID
*
* @brief Get Sensor Property ID of the sensor data.
*
* @note Multiple sensor data may be concatenated. Make sure the _data pointer is
* updated before getting Sensor Property ID of the corresponding sensor data.
*
* @param _data Pointer to the start of the sensor data.
* @param _fmt Format of the sensor data.
*
* @return Sensor Property ID of the sensor data.
*/
#define ESP_BLE_MESH_GET_SENSOR_DATA_PROPERTY_ID(_data, _fmt) \
(((_fmt) == ESP_BLE_MESH_SENSOR_DATA_FORMAT_A) ? ((((_data)[1]) << 3) | (((_data)[0]) >> 5)) : ((((_data)[2]) << 8) | ((_data)[1])))
/** @def ESP_BLE_MESH_SENSOR_DATA_FORMAT_A_MPID
*
* @brief Generate a MPID value for sensor data with Format A.
*
* @note 1. The Format field is 0b0 and indicates that Format A is used.
* 2. The Length field is a 1-based uint4 value (valid range 0x00xF,
* representing range of 116).
* 3. The Property ID is an 11-bit bit field representing 11 LSb of a Property ID.
* 4. This format may be used for Property Values that are not longer than 16
* octets and for Property IDs less than 0x0800.
*
* @param _len Length of Sensor Raw value.
* @param _id Sensor Property ID.
*
* @return 2-octet MPID value for sensor data with Format A.
*
*/
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_A_MPID(_len, _id) \
((((_id) & BIT_MASK(11)) << 5) | (((_len) & BIT_MASK(4)) << 1) | ESP_BLE_MESH_SENSOR_DATA_FORMAT_A)
/** @def ESP_BLE_MESH_SENSOR_DATA_FORMAT_B_MPID
*
* @brief Generate a MPID value for sensor data with Format B.
*
* @note 1. The Format field is 0b1 and indicates Format B is used.
* 2. The Length field is a 1-based uint7 value (valid range 0x00x7F, representing
* range of 1127). The value 0x7F represents a length of zero.
* 3. The Property ID is a 16-bit bit field representing a Property ID.
* 4. This format may be used for Property Values not longer than 128 octets and for
* any Property IDs. Property values longer than 128 octets are not supported by
* the Sensor Status message.
* 5. Exclude the generated 1-octet value, the 2-octet Sensor Property ID
*
* @param _len Length of Sensor Raw value.
* @param _id Sensor Property ID.
*
* @return 3-octet MPID value for sensor data with Format B.
*
*/
#define ESP_BLE_MESH_SENSOR_DATA_FORMAT_B_MPID(_len, _id) \
(((_id) << 8) | (((_len) & BIT_MASK(7)) << 1) | ESP_BLE_MESH_SENSOR_DATA_FORMAT_B)
/** This enum value is value of Sensor Sampling Function */
enum esp_ble_mesh_sensor_sample_func {
ESP_BLE_MESH_SAMPLE_FUNC_UNSPECIFIED,
ESP_BLE_MESH_SAMPLE_FUNC_INSTANTANEOUS,
ESP_BLE_MESH_SAMPLE_FUNC_ARITHMETIC_MEAN,
ESP_BLE_MESH_SAMPLE_FUNC_RMS,
ESP_BLE_MESH_SAMPLE_FUNC_MAXIMUM,
ESP_BLE_MESH_SAMPLE_FUNC_MINIMUM,
ESP_BLE_MESH_SAMPLE_FUNC_ACCUMULATED,
ESP_BLE_MESH_SAMPLE_FUNC_COUNT,
};
/** Parameters of Sensor Descriptor state */
typedef struct {
uint32_t positive_tolerance : 12, /*!< The value of Sensor Positive Tolerance field */
negative_tolerance : 12, /*!< The value of Sensor Negative Tolerance field */
sampling_function : 8; /*!< The value of Sensor Sampling Function field */
uint8_t measure_period; /*!< The value of Sensor Measurement Period field */
uint8_t update_interval; /*!< The value of Sensor Update Interval field */
} esp_ble_mesh_sensor_descriptor_t;
/** Parameters of Sensor Setting state */
typedef struct {
uint16_t property_id; /*!< The value of Sensor Setting Property ID field */
uint8_t access; /*!< The value of Sensor Setting Access field */
struct net_buf_simple *raw; /*!< The value of Sensor Setting Raw field */
} esp_ble_mesh_sensor_setting_t;
/** Parameters of Sensor Cadence state */
typedef struct {
uint8_t period_divisor : 7, /*!< The value of Fast Cadence Period Divisor field */
trigger_type : 1; /*!< The value of Status Trigger Type field */
/**
* Note:
* The parameter "size" in trigger_delta_down, trigger_delta_up, fast_cadence_low &
* fast_cadence_high indicates the exact length of these four parameters, and they
* are associated with the Sensor Property ID. Users need to initialize the "size"
* precisely.
*/
struct net_buf_simple *trigger_delta_down; /*!< The value of Status Trigger Delta Down field */
struct net_buf_simple *trigger_delta_up; /*!< The value of Status Trigger Delta Up field */
uint8_t min_interval; /*!< The value of Status Min Interval field */
struct net_buf_simple *fast_cadence_low; /*!< The value of Fast Cadence Low field */
struct net_buf_simple *fast_cadence_high; /*!< The value of Fast Cadence High field */
} esp_ble_mesh_sensor_cadence_t;
/** Parameters of Sensor Data state */
typedef struct {
/**
* Format A: The Length field is a 1-based uint4 value (valid range 0x00xF,
* representing range of 1 16).
* Format B: The Length field is a 1-based uint7 value (valid range 0x00x7F,
* representing range of 1 127). The value 0x7F represents a
* length of zero.
*/
uint8_t format : 1, /*!< The value of the Sensor Data format */
length : 7; /*!< The value of the Sensor Data length */
struct net_buf_simple *raw_value; /*!< The value of Sensor Data raw value */
} esp_ble_mesh_sensor_data_t;
/** Parameters of Sensor Series Column state */
typedef struct {
struct net_buf_simple *raw_value_x; /*!< The value of Sensor Raw Value X field */
struct net_buf_simple *column_width; /*!< The value of Sensor Column Width field */
struct net_buf_simple *raw_value_y; /*!< The value of Sensor Raw Value Y field */
} esp_ble_mesh_sensor_series_column_t;
/** Parameters of Sensor states */
typedef struct {
uint16_t sensor_property_id; /*!< The value of Sensor Property ID field */
/* Constant throughout the lifetime of an element */
esp_ble_mesh_sensor_descriptor_t descriptor; /*!< Parameters of the Sensor Descriptor state */
/**
* Multiple Sensor Setting states may be present for each sensor.
* The Sensor Setting Property ID values shall be unique for each
* Sensor Property ID that identifies a sensor within an element.
*/
const uint8_t setting_count; /*!< */
esp_ble_mesh_sensor_setting_t *settings; /*!< Parameters of the Sensor Setting state */
/**
* The Sensor Cadence state may be not supported by sensors based
* on device properties referencing "non-scalar characteristics"
* such as "histograms" or "composite characteristics".
*/
esp_ble_mesh_sensor_cadence_t *cadence; /*!< Parameters of the Sensor Cadence state */
esp_ble_mesh_sensor_data_t sensor_data; /*!< Parameters of the Sensor Data state */
esp_ble_mesh_sensor_series_column_t series_column; /*!< Parameters of the Sensor Series Column state */
} esp_ble_mesh_sensor_state_t;
/** User data of Sensor Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Sensor Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
const uint8_t state_count; /*!< Sensor state count */
esp_ble_mesh_sensor_state_t *states; /*!< Parameters of the Sensor states */
} esp_ble_mesh_sensor_srv_t;
/** User data of Sensor Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Sensor Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
const uint8_t state_count; /*!< Sensor state count */
esp_ble_mesh_sensor_state_t *states; /*!< Parameters of the Sensor states */
} esp_ble_mesh_sensor_setup_srv_t;
/** Parameters of Sensor Cadence Set state change event */
typedef struct {
uint16_t property_id; /*!< The value of Sensor Property ID state */
uint8_t period_divisor : 7, /*!< The value of Fast Cadence Period Divisor state */
trigger_type : 1; /*!< The value of Status Trigger Type state */
struct net_buf_simple *trigger_delta_down; /*!< The value of Status Trigger Delta Down state */
struct net_buf_simple *trigger_delta_up; /*!< The value of Status Trigger Delta Up state */
uint8_t min_interval; /*!< The value of Status Min Interval state */
struct net_buf_simple *fast_cadence_low; /*!< The value of Fast Cadence Low state */
struct net_buf_simple *fast_cadence_high; /*!< The value of Fast Cadence High state */
} esp_ble_mesh_state_change_sensor_cadence_set_t;
/** Parameters of Sensor Setting Set state change event */
typedef struct {
uint16_t property_id; /*!< The value of Sensor Property ID state */
uint16_t setting_property_id; /*!< The value of Sensor Setting Property ID state */
struct net_buf_simple *setting_value; /*!< The value of Sensor Property Value state */
} esp_ble_mesh_state_change_sensor_setting_set_t;
/**
* @brief Sensor Server Model state change value union
*/
typedef union {
/**
* The recv_op in ctx can be used to decide which state is changed.
*/
esp_ble_mesh_state_change_sensor_cadence_set_t sensor_cadence_set; /*!< Sensor Cadence Set */
esp_ble_mesh_state_change_sensor_setting_set_t sensor_setting_set; /*!< Sensor Setting Set */
} esp_ble_mesh_sensor_server_state_change_t;
/** Context of the received Sensor Descriptor Get message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property ID of a sensor (optional) */
} esp_ble_mesh_server_recv_sensor_descriptor_get_t;
/** Context of the received Sensor Cadence Get message */
typedef struct {
uint16_t property_id; /*!< Property ID of a sensor */
} esp_ble_mesh_server_recv_sensor_cadence_get_t;
/** Context of the received Sensor Settings Get message */
typedef struct {
uint16_t property_id; /*!< Property ID of a sensor */
} esp_ble_mesh_server_recv_sensor_settings_get_t;
/** Context of the received Sensor Setting Get message */
typedef struct {
uint16_t property_id; /*!< Property ID of a sensor */
uint16_t setting_property_id; /*!< Setting ID identifying a setting within a sensor */
} esp_ble_mesh_server_recv_sensor_setting_get_t;
/** Context of the received Sensor Get message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property ID for the sensor (optional) */
} esp_ble_mesh_server_recv_sensor_get_t;
/** Context of the received Sensor Column Get message */
typedef struct {
uint16_t property_id; /*!< Property identifying a sensor */
struct net_buf_simple *raw_value_x; /*!< Raw value identifying a column */
} esp_ble_mesh_server_recv_sensor_column_get_t;
/** Context of the received Sensor Series Get message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t property_id; /*!< Property identifying a sensor */
struct net_buf_simple *raw_value; /*!< Raw value containing X1 and X2 (optional) */
} esp_ble_mesh_server_recv_sensor_series_get_t;
/**
* @brief Sensor Server Model received get message union
*/
typedef union {
esp_ble_mesh_server_recv_sensor_descriptor_get_t sensor_descriptor; /*!< Sensor Descriptor Get */
esp_ble_mesh_server_recv_sensor_cadence_get_t sensor_cadence; /*!< Sensor Cadence Get */
esp_ble_mesh_server_recv_sensor_settings_get_t sensor_settings; /*!< Sensor Settings Get */
esp_ble_mesh_server_recv_sensor_setting_get_t sensor_setting; /*!< Sensor Setting Get */
esp_ble_mesh_server_recv_sensor_get_t sensor_data; /*!< Sensor Get */
esp_ble_mesh_server_recv_sensor_column_get_t sensor_column; /*!< Sensor Column Get */
esp_ble_mesh_server_recv_sensor_series_get_t sensor_series; /*!< Sensor Series Get */
} esp_ble_mesh_sensor_server_recv_get_msg_t;
/** Context of the received Sensor Cadence Set message */
typedef struct {
uint16_t property_id; /*!< Property ID for the sensor */
struct net_buf_simple *cadence; /*!< Value of Sensor Cadence state */
} esp_ble_mesh_server_recv_sensor_cadence_set_t;
/** Context of the received Sensor Setting Set message */
typedef struct {
uint16_t property_id; /*!< Property ID identifying a sensor */
uint16_t setting_property_id; /*!< Setting ID identifying a setting within a sensor */
struct net_buf_simple *setting_raw; /*!< Raw value for the setting */
} esp_ble_mesh_server_recv_sensor_setting_set_t;
/**
* @brief Sensor Server Model received set message union
*/
typedef union {
esp_ble_mesh_server_recv_sensor_cadence_set_t sensor_cadence; /*!< Sensor Cadence Set */
esp_ble_mesh_server_recv_sensor_setting_set_t sensor_setting; /*!< Sensor Setting Set */
} esp_ble_mesh_sensor_server_recv_set_msg_t;
/**
* @brief Sensor Server Model callback value union
*/
typedef union {
esp_ble_mesh_sensor_server_state_change_t state_change; /*!< ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT */
esp_ble_mesh_sensor_server_recv_get_msg_t get; /*!< ESP_BLE_MESH_SENSOR_SERVER_RECV_GET_MSG_EVT */
esp_ble_mesh_sensor_server_recv_set_msg_t set; /*!< ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT */
} esp_ble_mesh_sensor_server_cb_value_t;
/** Sensor Server Model callback parameters */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to Sensor Server Models */
esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received messages */
esp_ble_mesh_sensor_server_cb_value_t value; /*!< Value of the received Sensor Messages */
} esp_ble_mesh_sensor_server_cb_param_t;
/** This enum value is the event of Sensor Server Model */
typedef enum {
/**
* 1. When get_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, no event will be
* callback to the application layer when Sensor Get messages are received.
* 2. When set_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, this event will
* be callback to the application layer when Sensor Set/Set Unack messages
* are received.
*/
ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT,
/**
* When get_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Sensor Get messages are received.
*/
ESP_BLE_MESH_SENSOR_SERVER_RECV_GET_MSG_EVT,
/**
* When set_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Sensor Set/Set Unack messages are received.
*/
ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT,
ESP_BLE_MESH_SENSOR_SERVER_EVT_MAX,
} esp_ble_mesh_sensor_server_cb_event_t;
/**
* @brief Bluetooth Mesh Sensor Server Model function.
*/
/**
* @brief Sensor Server Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_sensor_server_cb_t)(esp_ble_mesh_sensor_server_cb_event_t event,
esp_ble_mesh_sensor_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Sensor Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_sensor_server_callback(esp_ble_mesh_sensor_server_cb_t callback);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_SENSOR_MODEL_API_H_ */
@@ -0,0 +1,911 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Bluetooth Mesh Time and Scene Client Model APIs.
*/
#ifndef _ESP_BLE_MESH_TIME_SCENE_MODEL_API_H_
#define _ESP_BLE_MESH_TIME_SCENE_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @def ESP_BLE_MESH_MODEL_TIME_CLI
*
* @brief Define a new Time Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Time 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 Time Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_TIME_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_TIME_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_SCENE_CLI
*
* @brief Define a new Scene Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Scene 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 Scene Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCENE_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCENE_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_SCHEDULER_CLI
*
* @brief Define a new Scheduler Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Scheduler 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 Scheduler Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCHEDULER_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCHEDULER_CLI, \
NULL, cli_pub, cli_data)
/**
* @brief Bluetooth Mesh Time Scene Client Model Get and Set parameters structure.
*/
/** Parameters of Time Set */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t sub_second; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_time_set_t;
/** Parameters of Time Zone Set */
typedef struct {
uint8_t time_zone_offset_new; /*!< Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /*!< TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_time_zone_set_t;
/** Parameters of TAI-UTC Delta Set */
typedef struct {
uint16_t tai_utc_delta_new : 15; /*!< Upcoming difference between TAI and UTC in seconds */
uint16_t padding : 1; /*!< Always 0b0. Other values are Prohibited. */
uint8_t tai_delta_change[5]; /*!< TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_tai_utc_delta_set_t;
/** Parameter of Time Role Set */
typedef struct {
uint8_t time_role; /*!< The Time Role for the element */
} esp_ble_mesh_time_role_set_t;
/** Parameter of Scene Store */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be stored */
} esp_ble_mesh_scene_store_t;
/** Parameters of Scene Recall */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t scene_number; /*!< The number of scenes to be recalled */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_scene_recall_t;
/** Parameter of Scene Delete */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be deleted */
} esp_ble_mesh_scene_delete_t;
/** Parameter of Scheduler Action Get */
typedef struct {
uint8_t index; /*!< Index of the Schedule Register entry to get */
} esp_ble_mesh_scheduler_act_get_t;
/** Parameters of Scheduler Action Set */
typedef struct {
uint64_t index : 4; /*!< Index of the Schedule Register entry to set */
uint64_t year : 7; /*!< Scheduled year for the action */
uint64_t month : 12; /*!< Scheduled month for the action */
uint64_t day : 5; /*!< Scheduled day of the month for the action */
uint64_t hour : 5; /*!< Scheduled hour for the action */
uint64_t minute : 6; /*!< Scheduled minute for the action */
uint64_t second : 6; /*!< Scheduled second for the action */
uint64_t day_of_week : 7; /*!< Schedule days of the week for the action */
uint64_t action : 4; /*!< Action to be performed at the scheduled time */
uint64_t trans_time : 8; /*!< Transition time for this action */
uint16_t scene_number; /*!< Transition time for this action */
} esp_ble_mesh_scheduler_act_set_t;
/**
* @brief Time Scene Client Model get message union
*/
typedef union {
esp_ble_mesh_scheduler_act_get_t scheduler_act_get; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET */
} esp_ble_mesh_time_scene_client_get_state_t;
/**
* @brief Time Scene Client Model set message union
*/
typedef union {
esp_ble_mesh_time_set_t time_set; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_SET */
esp_ble_mesh_time_zone_set_t time_zone_set; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ZONE_SET */
esp_ble_mesh_tai_utc_delta_set_t tai_utc_delta_set; /*!< For ESP_BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET */
esp_ble_mesh_time_role_set_t time_role_set; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ROLE_SET */
esp_ble_mesh_scene_store_t scene_store; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_STORE & ESP_BLE_MESH_MODEL_OP_SCENE_STORE_UNACK */
esp_ble_mesh_scene_recall_t scene_recall; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_RECALL & ESP_BLE_MESH_MODEL_OP_SCENE_RECALL_UNACK */
esp_ble_mesh_scene_delete_t scene_delete; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_DELETE & ESP_BLE_MESH_MODEL_OP_SCENE_DELETE_UNACK */
esp_ble_mesh_scheduler_act_set_t scheduler_act_set; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET & ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET_UNACK */
} esp_ble_mesh_time_scene_client_set_state_t;
/**
* @brief Bluetooth Mesh Time Scene Client Model Get and Set callback parameters structure.
*/
/** Parameters of Time Status */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t sub_second; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_time_status_cb_t;
/** Parameters of Time Zone Status */
typedef struct {
uint8_t time_zone_offset_curr; /*!< Current local time zone offset */
uint8_t time_zone_offset_new; /*!< Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /*!< TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_time_zone_status_cb_t;
/** Parameters of TAI-UTC Delta Status */
typedef struct {
uint16_t tai_utc_delta_curr : 15; /*!< Current difference between TAI and UTC in seconds */
uint16_t padding_1 : 1; /*!< Always 0b0. Other values are Prohibited. */
uint16_t tai_utc_delta_new : 15; /*!< Upcoming difference between TAI and UTC in seconds */
uint16_t padding_2 : 1; /*!< Always 0b0. Other values are Prohibited. */
uint8_t tai_delta_change[5]; /*!< TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_tai_utc_delta_status_cb_t;
/** Parameter of Time Role Status */
typedef struct {
uint8_t time_role; /*!< The Time Role for the element */
} esp_ble_mesh_time_role_status_cb_t;
/** Parameters of Scene Status */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint8_t status_code; /*!< Status code of the last operation */
uint16_t current_scene; /*!< Scene Number of the current scene */
uint16_t target_scene; /*!< Scene Number of the target scene (optional) */
uint8_t remain_time; /*!< Time to complete state transition (C.1) */
} esp_ble_mesh_scene_status_cb_t;
/** Parameters of Scene Register Status */
typedef struct {
uint8_t status_code; /*!< Status code for the previous operation */
uint16_t current_scene; /*!< Scene Number of the current scene */
struct net_buf_simple *scenes; /*!< A list of scenes stored within an element */
} esp_ble_mesh_scene_register_status_cb_t;
/** Parameter of Scheduler Status */
typedef struct {
uint16_t schedules; /*!< Bit field indicating defined Actions in the Schedule Register */
} esp_ble_mesh_scheduler_status_cb_t;
/** Parameters of Scheduler Action Status */
typedef struct {
uint64_t index : 4; /*!< Enumerates (selects) a Schedule Register entry */
uint64_t year : 7; /*!< Scheduled year for the action */
uint64_t month : 12; /*!< Scheduled month for the action */
uint64_t day : 5; /*!< Scheduled day of the month for the action */
uint64_t hour : 5; /*!< Scheduled hour for the action */
uint64_t minute : 6; /*!< Scheduled minute for the action */
uint64_t second : 6; /*!< Scheduled second for the action */
uint64_t day_of_week : 7; /*!< Schedule days of the week for the action */
uint64_t action : 4; /*!< Action to be performed at the scheduled time */
uint64_t trans_time : 8; /*!< Transition time for this action */
uint16_t scene_number; /*!< Transition time for this action */
} esp_ble_mesh_scheduler_act_status_cb_t;
/**
* @brief Time Scene Client Model received message union
*/
typedef union {
esp_ble_mesh_time_status_cb_t time_status; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_STATUS */
esp_ble_mesh_time_zone_status_cb_t time_zone_status; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ZONE_STATUS */
esp_ble_mesh_tai_utc_delta_status_cb_t tai_utc_delta_status; /*!< For ESP_BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS */
esp_ble_mesh_time_role_status_cb_t time_role_status; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ROLE_STATUS */
esp_ble_mesh_scene_status_cb_t scene_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_STATUS */
esp_ble_mesh_scene_register_status_cb_t scene_register_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS */
esp_ble_mesh_scheduler_status_cb_t scheduler_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_STATUS */
esp_ble_mesh_scheduler_act_status_cb_t scheduler_act_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS */
} esp_ble_mesh_time_scene_client_status_cb_t;
/** Time Scene Client Model callback parameters */
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_time_scene_client_status_cb_t status_cb; /*!< The scene status message callback values */
} esp_ble_mesh_time_scene_client_cb_param_t;
/** This enum value is the event of Time Scene Client Model */
typedef enum {
ESP_BLE_MESH_TIME_SCENE_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_EVT_MAX,
} esp_ble_mesh_time_scene_client_cb_event_t;
/**
* @brief Bluetooth Mesh Time Scene Client Model function.
*/
/**
* @brief Time Scene Client Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_time_scene_client_cb_t)(esp_ble_mesh_time_scene_client_cb_event_t event,
esp_ble_mesh_time_scene_client_cb_param_t *param);
/**
* @brief Register BLE Mesh Time Scene Client Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_time_scene_client_callback(esp_ble_mesh_time_scene_client_cb_t callback);
/**
* @brief Get the value of Time Scene Server Model states using the Time Scene Client Model get messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_time_scene_message_opcode_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to time scene get message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_time_scene_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_time_scene_client_get_state_t *get_state);
/**
* @brief Set the value of Time Scene Server Model states using the Time Scene Client Model set messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to esp_ble_mesh_time_scene_message_opcode_t in esp_ble_mesh_defs.h
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to time scene set message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_time_scene_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_time_scene_client_set_state_t *set_state);
/**
* @brief Time Scene Server Models related context.
*/
/** @def ESP_BLE_MESH_MODEL_TIME_SRV
*
* @brief Define a new Time Server Model.
*
* @note 1. The Time Server model is a root model. When this model is present on an
* Element, the corresponding Time Setup Server model shall also be present.
* 2. This model shall support model publication and model subscription.
*
* @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_time_srv_t.
*
* @return New Time Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_TIME_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_TIME_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_TIME_SETUP_SRV
*
* @brief Define a new Time Setup Server Model.
*
* @note 1. The Time Setup Server model extends the Time Server model. Time is
* sensitive information that is propagated across a mesh network.
* 2. Only an authorized Time Client should be allowed to change the Time
* and Time Role states. A dedicated application key Bluetooth SIG
* Proprietary should be used on the Time Setup Server to restrict
* access to the server to only authorized Time Clients.
* 3. This model does not support subscribing nor publishing.
*
* @param srv_data Pointer to the unique struct esp_ble_mesh_time_setup_srv_t.
*
* @return New Time Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_TIME_SETUP_SRV(srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_TIME_SETUP_SRV, \
NULL, NULL, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCENE_SRV
*
* @brief Define a new Scene Server Model.
*
* @note 1. The Scene Server model is a root model. When this model is present
* on an Element, the corresponding Scene Setup Server model shall
* also be present.
* 2. This model shall support model publication and model subscription.
* 3. The model may be present only on the Primary element of a node.
*
* @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_scene_srv_t.
*
* @return New Scene Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCENE_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCENE_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCENE_SETUP_SRV
*
* @brief Define a new Scene Setup Server Model.
*
* @note 1. The Scene Setup Server model extends the Scene Server model and
* the Generic Default Transition Time Server model.
* 2. This model shall support model subscription.
* 3. The model may be present only on the Primary element of a node.
*
* @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_scene_setup_srv_t.
*
* @return New Scene Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCENE_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCENE_SETUP_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCHEDULER_SRV
*
* @brief Define a new Scheduler Server Model.
*
* @note 1. The Scheduler Server model extends the Scene Server model. When
* this model is present on an Element, the corresponding Scheduler
* Setup Server model shall also be present.
* 2. This model shall support model publication and model subscription.
* 3. The model may be present only on the Primary element of a node.
* 4. The model requires the Time Server model shall be present on the element.
*
* @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_scheduler_srv_t.
*
* @return New Scheduler Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCHEDULER_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCHEDULER_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_MODEL_SCHEDULER_SETUP_SRV
*
* @brief Define a new Scheduler Setup Server Model.
*
* @note 1. The Scheduler Setup Server model extends the Scheduler Server and
* the Scene Setup Server models.
* 2. This model shall support model subscription.
* 3. The model may be present only on the Primary element of a node.
*
* @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_scheduler_setup_srv_t.
*
* @return New Scheduler Setup Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCHEDULER_SETUP_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV, \
NULL, srv_pub, srv_data)
#define ESP_BLE_MESH_UNKNOWN_TAI_SECONDS 0x0000000000 /*!< Unknown TAI Seconds */
#define ESP_BLE_MESH_UNKNOWN_TAI_ZONE_CHANGE 0x0000000000 /*!< Unknown TAI of Zone Change */
#define ESP_BLE_MESH_UNKNOWN_TAI_DELTA_CHANGE 0x0000000000 /*!< Unknown TAI of Delta Change */
#define ESP_BLE_MESH_TAI_UTC_DELTA_MAX_VALUE 0x7FFF /*!< Maximum TAI-UTC Delta value */
#define ESP_BLE_MESH_TAI_SECONDS_LEN 0x05 /*!< Length of TAI Seconds */
#define ESP_BLE_MESH_TAI_OF_ZONE_CHANGE_LEN 0x05 /*!< Length of TAI of Zone Change */
#define ESP_BLE_MESH_TAI_OF_DELTA_CHANGE_LEN 0x05 /*!< Length of TAI of Delta Change */
#define ESP_BLE_MESH_INVALID_SCENE_NUMBER 0x0000 /*!< Invalid Scene Number */
#define ESP_BLE_MESH_SCENE_NUMBER_LEN 0x02 /*!< Length of the Scene Number */
#define ESP_BLE_MESH_SCHEDULE_YEAR_ANY_YEAR 0x64 /*!< Any year of the Scheduled year */
#define ESP_BLE_MESH_SCHEDULE_DAY_ANY_DAY 0x00 /*!< Any day of the Scheduled day */
#define ESP_BLE_MESH_SCHEDULE_HOUR_ANY_HOUR 0x18 /*!< Any hour of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_HOUR_ONCE_A_DAY 0x19 /*!< Any hour of the Scheduled Day */
#define ESP_BLE_MESH_SCHEDULE_SEC_ANY_OF_HOUR 0x3C /*!< Any minute of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_15_MIN 0x3D /*!< Every 15 minutes of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_20_MIN 0x3E /*!< Every 20 minutes of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_ONCE_AN_HOUR 0x3F /*!< Once of the Scheduled hour */
#define ESP_BLE_MESH_SCHEDULE_SEC_ANY_OF_MIN 0x3C /*!< Any second of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_15_SEC 0x3D /*!< Every 15 seconds of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_SEC_EVERY_20_SEC 0x3E /*!< Every 20 seconds of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_SEC_ONCE_AN_MIN 0x3F /*!< Once of the Scheduled minute */
#define ESP_BLE_MESH_SCHEDULE_ACT_TURN_OFF 0x00 /*!< Scheduled Action - Turn Off */
#define ESP_BLE_MESH_SCHEDULE_ACT_TURN_ON 0x01 /*!< Scheduled Action - Turn On */
#define ESP_BLE_MESH_SCHEDULE_ACT_SCENE_RECALL 0x02 /*!< Scheduled Action - Scene Recall */
#define ESP_BLE_MESH_SCHEDULE_ACT_NO_ACTION 0x0F /*!< Scheduled Action - No Action */
#define ESP_BLE_MESH_SCHEDULE_SCENE_NO_SCENE 0x0000 /*!< Scheduled Scene - No Scene */
#define ESP_BLE_MESH_SCHEDULE_ENTRY_MAX_INDEX 0x0F /*!< Maximum number of Scheduled entries */
#define ESP_BLE_MESH_TIME_NONE 0x00 /*!< Time Role - None */
#define ESP_BLE_MESH_TIME_AUTHORITY 0x01 /*!< Time Role - Mesh Time Authority */
#define ESP_BLE_MESH_TIME_RELAY 0x02 /*!< Time Role - Mesh Time Relay */
#define ESP_BLE_MESH_TIME_CLIENT 0x03 /*!< Time Role - Mesh Time Client */
#define ESP_BLE_MESH_SCENE_SUCCESS 0x00 /*!< Scene operation - Success */
#define ESP_BLE_MESH_SCENE_REG_FULL 0x01 /*!< Scene operation - Scene Register Full */
#define ESP_BLE_MESH_SCENE_NOT_FOUND 0x02 /*!< Scene operation - Scene Not Found */
/** Parameters of Time state */
typedef struct {
struct {
uint8_t tai_seconds[5]; /*!< The value of the TAI Seconds state */
uint8_t subsecond; /*!< The value of the Subsecond field */
uint8_t uncertainty; /*!< The value of the Uncertainty field */
uint8_t time_zone_offset_curr; /*!< The value of the Time Zone Offset Current field */
uint8_t time_zone_offset_new; /*!< The value of the Time Zone Offset New state */
uint8_t tai_zone_change[5]; /*!< The value of the TAI of Zone Change field */
uint16_t time_authority : 1, /*!< The value of the Time Authority bit */
tai_utc_delta_curr : 15; /*!< The value of the TAI-UTC Delta Current state */
uint16_t tai_utc_delta_new : 15; /*!< The value of the TAI-UTC Delta New state */
uint8_t tai_delta_change[5]; /*!< The value of the TAI of Delta Change field */
} time; /*!< Parameters of the Time state */
uint8_t time_role; /*!< The value of the Time Role state */
} esp_ble_mesh_time_state_t;
/** User data of Time Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Time Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_time_state_t *state; /*!< Parameters of the Time state */
} esp_ble_mesh_time_srv_t;
/** User data of Time Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Time Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_time_state_t *state; /*!< Parameters of the Time state */
} esp_ble_mesh_time_setup_srv_t;
/**
* 1. Scene Store is an operation of storing values of a present state of an element.
* 2. The structure and meaning of the stored state is determined by a model. States
* to be stored are specified by each model.
* 3. The Scene Store operation shall persistently store all values of all states
* marked as Stored with Scene for all models present on all elements of a node.
* 4. If a model is extending another model, the extending model shall determine the
* Stored with Scene behavior of that model.
*/
/** Parameters of Scene Register state */
typedef struct {
uint16_t scene_number; /*!< The value of the Scene Number */
uint8_t scene_type; /*!< The value of the Scene Type */
/**
* Scene value may use a union to represent later, the union contains
* structures of all the model states which can be stored in a scene.
*/
struct net_buf_simple *scene_value; /*!< The value of the Scene Value */
} esp_ble_mesh_scene_register_t;
/**
* Parameters of Scenes state.
*
* Scenes serve as memory banks for storage of states (e.g., a power level
* or a light level/color). Values of states of an element can be stored
* as a scene and can be recalled later from the scene memory.
*
* A scene is represented by a Scene Number, which is a 16-bit non-zero,
* mesh-wide value. (There can be a maximum of 65535 scenes in a mesh
* network.) The meaning of a scene, as well as the state storage container
* associated with it, are determined by a model.
*
* The Scenes state change may start numerous parallel model transitions.
* In that case, each individual model handles the transition internally.
*
* The scene transition is defined as a group of individual model transitions
* started by a Scene Recall operation. The scene transition is in progress
* when at least one transition from the group of individual model transitions
* is in progress.
*/
typedef struct {
const uint16_t scene_count; /*!< The Scenes state's scene count */
esp_ble_mesh_scene_register_t *scenes; /*!< Parameters of the Scenes state */
/**
* The Current Scene state is a 16-bit value that contains either the Scene
* Number of the currently active scene or a value of 0x0000 when no scene
* is active.
*
* When a Scene Store operation or a Scene Recall operation completes with
* success, the Current Scene state value shall be to the Scene Number used
* during that operation.
*
* When the Current Scene Number is deleted from a Scene Register state as a
* result of Scene Delete operation, the Current Scene state shall be set to
* 0x0000.
*
* When any of the element's state that is marked as “Stored with Scene” has
* changed not as a result of a Scene Recall operation, the value of the
* Current Scene state shall be set to 0x0000.
*
* When a scene transition is in progress, the value of the Current Scene
* state shall be set to 0x0000.
*/
uint16_t current_scene; /*!< The value of the Current Scene state */
/**
* The Target Scene state is a 16-bit value that contains the target Scene
* Number when a scene transition is in progress.
*
* When the scene transition is in progress and the target Scene Number is
* deleted from a Scene Register state as a result of Scene Delete operation,
* the Target Scene state shall be set to 0x0000.
*
* When the scene transition is in progress and a new Scene Number is stored
* in the Scene Register as a result of Scene Store operation, the Target
* Scene state shall be set to the new Scene Number.
*
* When the scene transition is not in progress, the value of the Target Scene
* state shall be set to 0x0000.
*/
uint16_t target_scene; /*!< The value of the Target Scene state */
/* Indicate the status code for the last operation */
uint8_t status_code; /*!< The status code of the last scene operation */
/* Indicate if scene transition is in progress */
bool in_progress; /*!< Indicate if the scene transition is in progress */
} esp_ble_mesh_scenes_state_t;
/** User data of Scene Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scene Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scenes_state_t *state; /*!< Parameters of the Scenes state */
esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
} esp_ble_mesh_scene_srv_t;
/** User data of Scene Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scene Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scenes_state_t *state; /*!< Parameters of the Scenes state */
} esp_ble_mesh_scene_setup_srv_t;
/** Parameters of Scheduler Register state */
typedef struct {
bool in_use; /*!< Indicate if the registered schedule is in use */
uint64_t year : 7, /*!< The value of Scheduled year for the action */
month : 12, /*!< The value of Scheduled month for the action */
day : 5, /*!< The value of Scheduled day of the month for the action */
hour : 5, /*!< The value of Scheduled hour for the action */
minute : 6, /*!< The value of Scheduled minute for the action */
second : 6, /*!< The value of Scheduled second for the action */
day_of_week : 7, /*!< The value of Schedule days of the week for the action */
action : 4, /*!< The value of Action to be performed at the scheduled time */
trans_time : 8; /*!< The value of Transition time for this action */
uint16_t scene_number; /*!< The value of Scene Number to be used for some actions */
} esp_ble_mesh_schedule_register_t;
/** Parameters of Scheduler state */
typedef struct {
const uint8_t schedule_count; /*!< Scheduler count */
esp_ble_mesh_schedule_register_t *schedules; /*!< Up to 16 scheduled entries */
} esp_ble_mesh_scheduler_state_t;
/** User data of Scheduler Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scheduler Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scheduler_state_t *state; /*!< Parameters of the Scheduler state */
} esp_ble_mesh_scheduler_srv_t;
/** User data of Scheduler Setup Server Model */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the Scheduler Setup Server Model. Initialized internally. */
esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
esp_ble_mesh_scheduler_state_t *state; /*!< Parameters of the Scheduler state */
} esp_ble_mesh_scheduler_setup_srv_t;
/** Parameters of Time Set state change event */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta_curr : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset_curr; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_state_change_time_set_t;
/** Parameters of Time Status state change event */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta_curr : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset_curr; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_state_change_time_status_t;
/** Parameters of Time Zone Set state change event */
typedef struct {
uint8_t time_zone_offset_new; /*!< Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /*!< TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_state_change_time_zone_set_t;
/** Parameters of TAI UTC Delta Set state change event */
typedef struct {
uint16_t tai_utc_delta_new : 15; /*!< Upcoming difference between TAI and UTC in seconds */
uint8_t tai_delta_change[5]; /*!< TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_state_change_tai_utc_delta_set_t;
/** Parameter of Time Role Set state change event */
typedef struct {
uint8_t time_role; /*!< The Time Role for the element */
} esp_ble_mesh_state_change_time_role_set_t;
/** Parameter of Scene Store state change event */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be stored */
} esp_ble_mesh_state_change_scene_store_t;
/** Parameter of Scene Recall state change event */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be recalled */
} esp_ble_mesh_state_change_scene_recall_t;
/** Parameter of Scene Delete state change event */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be deleted */
} esp_ble_mesh_state_change_scene_delete_t;
/** Parameter of Scheduler Action Set state change event */
typedef struct {
uint64_t index : 4; /*!< Index of the Schedule Register entry to set */
uint64_t year : 7; /*!< Scheduled year for the action */
uint64_t month : 12; /*!< Scheduled month for the action */
uint64_t day : 5; /*!< Scheduled day of the month for the action */
uint64_t hour : 5; /*!< Scheduled hour for the action */
uint64_t minute : 6; /*!< Scheduled minute for the action */
uint64_t second : 6; /*!< Scheduled second for the action */
uint64_t day_of_week : 7; /*!< Schedule days of the week for the action */
uint64_t action : 4; /*!< Action to be performed at the scheduled time */
uint64_t trans_time : 8; /*!< Transition time for this action */
uint16_t scene_number; /*!< Scene number to be used for some actions */
} esp_ble_mesh_state_change_scheduler_act_set_t;
/**
* @brief Time Scene Server Model state change value union
*/
typedef union {
/**
* The recv_op in ctx can be used to decide which state is changed.
*/
esp_ble_mesh_state_change_time_set_t time_set; /*!< Time Set */
esp_ble_mesh_state_change_time_status_t time_status; /*!< Time Status */
esp_ble_mesh_state_change_time_zone_set_t time_zone_set; /*!< Time Zone Set */
esp_ble_mesh_state_change_tai_utc_delta_set_t tai_utc_delta_set; /*!< TAI UTC Delta Set */
esp_ble_mesh_state_change_time_role_set_t time_role_set; /*!< Time Role Set */
esp_ble_mesh_state_change_scene_store_t scene_store; /*!< Scene Store */
esp_ble_mesh_state_change_scene_recall_t scene_recall; /*!< Scene Recall */
esp_ble_mesh_state_change_scene_delete_t scene_delete; /*!< Scene Delete */
esp_ble_mesh_state_change_scheduler_act_set_t scheduler_act_set; /*!< Scheduler Action Set */
} esp_ble_mesh_time_scene_server_state_change_t;
/** Context of the received Scheduler Action Get message */
typedef struct {
uint8_t index; /*!< Index of the Schedule Register entry to get */
} esp_ble_mesh_server_recv_scheduler_act_get_t;
/**
* @brief Time Scene Server Model received get message union
*/
typedef union {
esp_ble_mesh_server_recv_scheduler_act_get_t scheduler_act; /*!< Scheduler Action Get */
} esp_ble_mesh_time_scene_server_recv_get_msg_t;
/** Context of the received Time Set message */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_server_recv_time_set_t;
/** Context of the received Time Zone Set message */
typedef struct {
uint8_t time_zone_offset_new; /*!< Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /*!< TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_server_recv_time_zone_set_t;
/** Context of the received TAI UTC Delta Set message */
typedef struct {
uint16_t tai_utc_delta_new : 15; /*!< Upcoming difference between TAI and UTC in seconds */
uint16_t padding : 1; /*!< Always 0b0. Other values are Prohibited. */
uint8_t tai_delta_change[5]; /*!< TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_server_recv_tai_utc_delta_set_t;
/** Context of the received Time Role Set message */
typedef struct {
uint8_t time_role; /*!< The Time Role for the element */
} esp_ble_mesh_server_recv_time_role_set_t;
/** Context of the received Scene Store message */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be stored */
} esp_ble_mesh_server_recv_scene_store_t;
/** Context of the received Scene Recall message */
typedef struct {
bool op_en; /*!< Indicate if optional parameters are included */
uint16_t scene_number; /*!< The number of scenes to be recalled */
uint8_t tid; /*!< Transaction ID */
uint8_t trans_time; /*!< Time to complete state transition (optional) */
uint8_t delay; /*!< Indicate message execution delay (C.1) */
} esp_ble_mesh_server_recv_scene_recall_t;
/** Context of the received Scene Delete message */
typedef struct {
uint16_t scene_number; /*!< The number of scenes to be deleted */
} esp_ble_mesh_server_recv_scene_delete_t;
/** Context of the received Scheduler Action Set message */
typedef struct {
uint64_t index : 4; /*!< Index of the Schedule Register entry to set */
uint64_t year : 7; /*!< Scheduled year for the action */
uint64_t month : 12; /*!< Scheduled month for the action */
uint64_t day : 5; /*!< Scheduled day of the month for the action */
uint64_t hour : 5; /*!< Scheduled hour for the action */
uint64_t minute : 6; /*!< Scheduled minute for the action */
uint64_t second : 6; /*!< Scheduled second for the action */
uint64_t day_of_week : 7; /*!< Schedule days of the week for the action */
uint64_t action : 4; /*!< Action to be performed at the scheduled time */
uint64_t trans_time : 8; /*!< Transition time for this action */
uint16_t scene_number; /*!< Scene number to be used for some actions */
} esp_ble_mesh_server_recv_scheduler_act_set_t;
/**
* @brief Time Scene Server Model received set message union
*/
typedef union {
esp_ble_mesh_server_recv_time_set_t time; /*!< Time Set */
esp_ble_mesh_server_recv_time_zone_set_t time_zone; /*!< Time Zone Set */
esp_ble_mesh_server_recv_tai_utc_delta_set_t tai_utc_delta; /*!< TAI-UTC Delta Set */
esp_ble_mesh_server_recv_time_role_set_t time_role; /*!< Time Role Set */
esp_ble_mesh_server_recv_scene_store_t scene_store; /*!< Scene Store/Scene Store Unack */
esp_ble_mesh_server_recv_scene_recall_t scene_recall; /*!< Scene Recall/Scene Recall Unack */
esp_ble_mesh_server_recv_scene_delete_t scene_delete; /*!< Scene Delete/Scene Delete Unack */
esp_ble_mesh_server_recv_scheduler_act_set_t scheduler_act; /*!< Scheduler Action Set/Scheduler Action Set Unack */
} esp_ble_mesh_time_scene_server_recv_set_msg_t;
/** Context of the received Time Status message */
typedef struct {
uint8_t tai_seconds[5]; /*!< The current TAI time in seconds */
uint8_t subsecond; /*!< The sub-second time in units of 1/256 second */
uint8_t uncertainty; /*!< The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /*!< 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /*!< Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /*!< The local time zone offset in 15-minute increments */
} esp_ble_mesh_server_recv_time_status_t;
/**
* @brief Time Scene Server Model received status message union
*/
typedef union {
esp_ble_mesh_server_recv_time_status_t time_status; /*!< Time Status */
} esp_ble_mesh_time_scene_server_recv_status_msg_t;
/**
* @brief Time Scene Server Model callback value union
*/
typedef union {
esp_ble_mesh_time_scene_server_state_change_t state_change; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_STATE_CHANGE_EVT */
esp_ble_mesh_time_scene_server_recv_get_msg_t get; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_GET_MSG_EVT */
esp_ble_mesh_time_scene_server_recv_set_msg_t set; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_SET_MSG_EVT */
esp_ble_mesh_time_scene_server_recv_status_msg_t status; /*!< ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_STATUS_MSG_EVT */
} esp_ble_mesh_time_scene_server_cb_value_t;
/** Time Scene Server Model callback parameters */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to Time and Scenes Server Models */
esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received messages */
esp_ble_mesh_time_scene_server_cb_value_t value; /*!< Value of the received Time and Scenes Messages */
} esp_ble_mesh_time_scene_server_cb_param_t;
/** This enum value is the event of Time Scene Server Model */
typedef enum {
/**
* 1. When get_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, no event will be
* callback to the application layer when Time Scene Get messages are received.
* 2. When set_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, this event will
* be callback to the application layer when Time Scene Set/Set Unack messages
* are received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_STATE_CHANGE_EVT,
/**
* When get_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Time Scene Get messages are received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_GET_MSG_EVT,
/**
* When set_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
* callback to the application layer when Time Scene Set/Set Unack messages are received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_SET_MSG_EVT,
/**
* When status_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will
* be callback to the application layer when TIme Status message is received.
*/
ESP_BLE_MESH_TIME_SCENE_SERVER_RECV_STATUS_MSG_EVT,
ESP_BLE_MESH_TIME_SCENE_SERVER_EVT_MAX,
} esp_ble_mesh_time_scene_server_cb_event_t;
/**
* @brief Bluetooth Mesh Time and Scenes Server Model function.
*/
/**
* @brief Time Scene Server Model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_time_scene_server_cb_t)(esp_ble_mesh_time_scene_server_cb_event_t event,
esp_ble_mesh_time_scene_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Time and Scenes Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_time_scene_server_callback(esp_ble_mesh_time_scene_server_cb_t callback);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_TIME_SCENE_MODEL_API_H_ */
@@ -0,0 +1,85 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_BLE_H_
#define _BTC_BLE_MESH_BLE_H_
#include <stdint.h>
#include "btc/btc_manage.h"
#include "mesh/adapter.h"
#include "esp_ble_mesh_ble_api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint8_t addr[6]; /*!< Device address */
uint8_t addr_type; /*!< Device address type */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t adv_type __attribute__((deprecated("`event_type` should be used to determine the advertising type"))); /*!< advertising type */
#else
uint8_t adv_type; /*!< Advertising type */
#endif
uint8_t *data; /*!< Advertising data */
uint16_t length; /*!< Advertising data length */
int8_t rssi; /*!< RSSI of the advertising packet */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t event_type; /*!< Extended advertising event type */
uint8_t primary_phy; /*!< Extended advertising primary PHY */
uint8_t secondary_phy; /*!< Extended advertising secondary PHY */
uint8_t sid; /*!< Extended advertising set ID */
uint8_t tx_power; /*!< Extended advertising TX power */
uint8_t dir_addr_type; /*!< Direct address type */
uint8_t dir_addr[6]; /*!< Direct address */
uint8_t data_status; /*!< Data type */
uint16_t per_adv_interval; /*!< Periodic advertising interval */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
} bt_mesh_ble_adv_report_t;
typedef union {
struct {
esp_ble_mesh_ble_adv_param_t param;
esp_ble_mesh_ble_adv_data_t data;
} start_ble_adv;
struct {
uint8_t index;
} stop_ble_adv;
struct {
esp_ble_mesh_ble_scan_param_t param;
} start_ble_scan;
struct {
/* RFU */
} stop_ble_scan;
struct ble_mesh_scan_params {
uint16_t scan_interval;
uint16_t uncoded_scan_window;
} scan_params;
} btc_ble_mesh_ble_args_t;
typedef enum {
BTC_BLE_MESH_ACT_START_BLE_ADV,
BTC_BLE_MESH_ACT_STOP_BLE_ADV,
BTC_BLE_MESH_ACT_START_BLE_SCAN,
BTC_BLE_MESH_ACT_STOP_BLE_SCAN,
BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS,
} btc_ble_mesh_ble_act_t;
void bt_mesh_ble_scan_cb_evt_to_btc(bt_mesh_ble_adv_report_t *adv_report);
#if CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50
void bt_mesh_ble_nimble_evt_to_btc(struct ble_gap_event *event, void *arg);
#endif /* CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50 */
void btc_ble_mesh_ble_call_handler(btc_msg_t *msg);
void btc_ble_mesh_ble_cb_handler(btc_msg_t *msg);
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_BLE_H_ */
@@ -0,0 +1,76 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_CONFIG_MODEL_H_
#define _BTC_BLE_MESH_CONFIG_MODEL_H_
#include "btc/btc_manage.h"
#include "esp_ble_mesh_config_model_api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
BTC_BLE_MESH_ACT_CONFIG_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_CONFIG_CLIENT_SET_STATE,
BTC_BLE_MESH_ACT_CONFIG_CLIENT_MAX,
} btc_ble_mesh_config_client_act_t;
typedef union {
struct ble_mesh_cfg_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_cfg_client_get_state_t *get_state;
} cfg_client_get_state;
struct ble_mesh_cfg_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_cfg_client_set_state_t *set_state;
} cfg_client_set_state;
} btc_ble_mesh_config_client_args_t;
typedef enum {
BTC_BLE_MESH_EVT_CONFIG_CLIENT_GET_STATE,
BTC_BLE_MESH_EVT_CONFIG_CLIENT_SET_STATE,
BTC_BLE_MESH_EVT_CONFIG_CLIENT_PUBLISH,
BTC_BLE_MESH_EVT_CONFIG_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_CONFIG_CLIENT_MAX,
} btc_ble_mesh_config_client_evt_t;
void btc_ble_mesh_config_client_call_handler(btc_msg_t *msg);
void btc_ble_mesh_config_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_config_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_config_client_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_config_client_publish_callback(uint32_t opcode,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
void bt_mesh_config_client_cb_evt_to_btc(uint32_t opcode, uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
void btc_ble_mesh_config_server_cb_handler(btc_msg_t *msg);
typedef enum {
BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_CONFIG_SERVER_MAX,
} btc_ble_mesh_config_server_evt_t;
void bt_mesh_config_server_cb_evt_to_btc(uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_CONFIG_MODEL_H_ */
@@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_GENERIC_MODEL_H_
#define _BTC_BLE_MESH_GENERIC_MODEL_H_
#include "btc/btc_manage.h"
#include "esp_ble_mesh_generic_model_api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE,
BTC_BLE_MESH_ACT_GENERIC_CLIENT_MAX,
} btc_ble_mesh_generic_client_act_t;
typedef union {
struct ble_mesh_generic_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_generic_client_get_state_t *get_state;
} generic_client_get_state;
struct ble_mesh_generic_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_generic_client_set_state_t *set_state;
} generic_client_set_state;
} btc_ble_mesh_generic_client_args_t;
typedef enum {
BTC_BLE_MESH_EVT_GENERIC_CLIENT_GET_STATE,
BTC_BLE_MESH_EVT_GENERIC_CLIENT_SET_STATE,
BTC_BLE_MESH_EVT_GENERIC_CLIENT_PUBLISH,
BTC_BLE_MESH_EVT_GENERIC_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_GENERIC_CLIENT_MAX,
} btc_ble_mesh_generic_client_evt_t;
void btc_ble_mesh_generic_client_call_handler(btc_msg_t *msg);
void btc_ble_mesh_generic_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_generic_client_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_generic_client_publish_callback(uint32_t opcode,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
void bt_mesh_generic_client_cb_evt_to_btc(uint32_t opcode, uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
typedef enum {
BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG,
BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG,
BTC_BLE_MESH_EVT_GENERIC_SERVER_MAX,
} btc_ble_mesh_generic_server_evt_t;
void bt_mesh_generic_server_cb_evt_to_btc(uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
void btc_ble_mesh_generic_server_cb_handler(btc_msg_t *msg);
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_GENERIC_MODEL_H_ */
@@ -0,0 +1,90 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_HEALTH_MODEL_H_
#define _BTC_BLE_MESH_HEALTH_MODEL_H_
#include "btc/btc_manage.h"
#include "esp_ble_mesh_health_model_api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
BTC_BLE_MESH_ACT_HEALTH_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_HEALTH_CLIENT_SET_STATE,
BTC_BLE_MESH_ACT_HEALTH_CLIENT_MAX,
} btc_ble_mesh_health_client_act_t;
typedef union {
struct ble_mesh_health_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_health_client_get_state_t *get_state;
} health_client_get_state;
struct ble_mesh_health_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_health_client_set_state_t *set_state;
} health_client_set_state;
} btc_ble_mesh_health_client_args_t;
typedef enum {
BTC_BLE_MESH_EVT_HEALTH_CLIENT_GET_STATE,
BTC_BLE_MESH_EVT_HEALTH_CLIENT_SET_STATE,
BTC_BLE_MESH_EVT_HEALTH_CLIENT_PUBLISH,
BTC_BLE_MESH_EVT_HEALTH_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_HEALTH_CLIENT_MAX,
} btc_ble_mesh_health_client_evt_t;
void btc_ble_mesh_health_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_health_client_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_health_client_call_handler(btc_msg_t *msg);
void btc_ble_mesh_health_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_health_publish_callback(uint32_t opcode,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
void bt_mesh_health_client_cb_evt_to_btc(uint32_t opcode, uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, uint16_t len);
typedef enum {
BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE,
BTC_BLE_MESH_ACT_HEALTH_SERVER_MAX,
} btc_ble_mesh_health_server_act_t;
typedef union {
struct ble_mesh_health_server_fault_update_args {
esp_ble_mesh_elem_t *element;
} health_fault_update;
} btc_ble_mesh_health_server_args_t;
void btc_ble_mesh_health_server_call_handler(btc_msg_t *msg);
void btc_ble_mesh_health_server_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_health_server_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_health_server_fault_clear(struct bt_mesh_model *model, uint16_t company_id);
void btc_ble_mesh_health_server_fault_test(struct bt_mesh_model *model,
uint8_t test_id, uint16_t company_id);
void btc_ble_mesh_health_server_attention_on(struct bt_mesh_model *model, uint8_t time);
void btc_ble_mesh_health_server_attention_off(struct bt_mesh_model *model);
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_HEALTH_MODEL_H_ */
@@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_LIGHTING_MODEL_H_
#define _BTC_BLE_MESH_LIGHTING_MODEL_H_
#include "btc/btc_manage.h"
#include "esp_ble_mesh_lighting_model_api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
BTC_BLE_MESH_ACT_LIGHTING_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_LIGHTING_CLIENT_SET_STATE,
BTC_BLE_MESH_ACT_LIGHTING_CLIENT_MAX,
} btc_ble_mesh_lighting_client_act_t;
typedef union {
struct ble_mesh_light_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_light_client_get_state_t *get_state;
} light_client_get_state;
struct ble_mesh_light_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_light_client_set_state_t *set_state;
} light_client_set_state;
} btc_ble_mesh_lighting_client_args_t;
typedef enum {
BTC_BLE_MESH_EVT_LIGHTING_CLIENT_GET_STATE,
BTC_BLE_MESH_EVT_LIGHTING_CLIENT_SET_STATE,
BTC_BLE_MESH_EVT_LIGHTING_CLIENT_PUBLISH,
BTC_BLE_MESH_EVT_LIGHTING_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_LIGHTING_CLIENT_MAX,
} btc_ble_mesh_lighting_client_evt_t;
void btc_ble_mesh_lighting_client_call_handler(btc_msg_t *msg);
void btc_ble_mesh_lighting_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_lighting_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_lighting_client_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_lighting_client_publish_callback(uint32_t opcode,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
void bt_mesh_lighting_client_cb_evt_to_btc(uint32_t opcode, uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
typedef enum {
BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_STATUS_MSG,
BTC_BLE_MESH_EVT_LIGHTING_SERVER_MAX,
} btc_ble_mesh_lighting_server_evt_t;
void bt_mesh_lighting_server_cb_evt_to_btc(uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
void btc_ble_mesh_lighting_server_cb_handler(btc_msg_t *msg);
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_LIGHTING_MODEL_H_ */
@@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_MODEL_COMMON_H_
#define _BTC_BLE_MESH_MODEL_COMMON_H_
#include "btc/btc_manage.h"
#include "mesh/access.h"
#include "mesh/client_common.h"
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline void btc_ble_mesh_msg_ctx_copy(struct bt_mesh_msg_ctx *dst,
const struct bt_mesh_msg_ctx *src,
bool use_dev_key)
{
if (dst == NULL ||
src == NULL) {
return;
}
dst->net_idx = src->net_idx;
dst->app_idx = use_dev_key ? BLE_MESH_KEY_DEV : src->app_idx;
dst->addr = src->addr;
dst->send_szmic = src->send_szmic;
dst->send_ttl = src->send_ttl;
dst->send_cred = src->send_cred;
dst->send_tag = src->send_tag;
if (src->enh.adv_cfg_used) {
dst->enh.adv_cfg_used = src->enh.adv_cfg_used;
dst->enh.adv_cfg.adv_cnt = src->enh.adv_cfg.adv_cnt;
dst->enh.adv_cfg.adv_itvl = src->enh.adv_cfg.adv_itvl;
dst->enh.adv_cfg.channel_map = src->enh.adv_cfg.channel_map;
}
#if CONFIG_BLE_MESH_EXT_ADV
if (src->enh.ext_adv_cfg_used) {
dst->enh.ext_adv_cfg_used = src->enh.ext_adv_cfg_used;
dst->enh.ext_adv_cfg.primary_phy = src->enh.ext_adv_cfg.primary_phy;
dst->enh.ext_adv_cfg.secondary_phy = src->enh.ext_adv_cfg.secondary_phy;
dst->enh.ext_adv_cfg.include_tx_power = src->enh.ext_adv_cfg.include_tx_power;
dst->enh.ext_adv_cfg.tx_power = src->enh.ext_adv_cfg.tx_power;
}
#if CONFIG_BLE_MESH_LONG_PACKET
if (src->enh.long_pkt_cfg_used) {
dst->enh.long_pkt_cfg_used = src->enh.long_pkt_cfg_used;
dst->enh.long_pkt_cfg = src->enh.long_pkt_cfg;
}
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
#endif /* CONFIG_BLE_MESH_EXT_ADV */
}
static inline void btc_ble_mesh_set_client_common_param(esp_ble_mesh_client_common_param_t *input,
bt_mesh_client_common_param_t *output,
bool use_dev_key)
{
if (input && output) {
output->opcode = input->opcode;
output->model = (struct bt_mesh_model *)input->model;
output->msg_timeout = input->msg_timeout;
btc_ble_mesh_msg_ctx_copy(&output->ctx, (const struct bt_mesh_msg_ctx *)&input->ctx, use_dev_key);
}
}
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_MODEL_COMMON_H_ */
@@ -0,0 +1,434 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_PROV_H_
#define _BTC_BLE_MESH_PROV_H_
#include "btc/btc_manage.h"
#include "mesh/byteorder.h"
#include "mesh/config.h"
#include "mesh/main.h"
#include "fast_prov.h"
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
BTC_BLE_MESH_ACT_MESH_INIT = 0,
BTC_BLE_MESH_ACT_PROV_ENABLE,
BTC_BLE_MESH_ACT_PROV_DISABLE,
BTC_BLE_MESH_ACT_NODE_RESET,
BTC_BLE_MESH_ACT_SET_OOB_PUB_KEY,
BTC_BLE_MESH_ACT_INPUT_NUMBER,
BTC_BLE_MESH_ACT_INPUT_STRING,
BTC_BLE_MESH_ACT_SET_DEVICE_NAME,
BTC_BLE_MESH_ACT_PROXY_IDENTITY_ENABLE,
BTC_BLE_MESH_ACT_PRIVATE_PROXY_IDENTITY_ENABLE,
BTC_BLE_MESH_ACT_PRIVATE_PROXY_IDENTITY_DISABLE,
BTC_BLE_MESH_ACT_PROXY_GATT_ENABLE,
BTC_BLE_MESH_ACT_PROXY_GATT_DISABLE,
BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_NET_KEY,
BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_APP_KEY,
BTC_BLE_MESH_ACT_NODE_BIND_APP_KEY_TO_MODEL,
BTC_BLE_MESH_ACT_PROVISIONER_READ_OOB_PUB_KEY,
BTC_BLE_MESH_ACT_PROVISIONER_INPUT_STR,
BTC_BLE_MESH_ACT_PROVISIONER_INPUT_NUM,
BTC_BLE_MESH_ACT_PROVISIONER_ENABLE,
BTC_BLE_MESH_ACT_PROVISIONER_DISABLE,
BTC_BLE_MESH_ACT_PROVISIONER_DEV_ADD,
BTC_BLE_MESH_ACT_PROVISIONER_PROV_DEV_WITH_ADDR,
BTC_BLE_MESH_ACT_PROVISIONER_DEV_DEL,
BTC_BLE_MESH_ACT_PROVISIONER_SET_DEV_UUID_MATCH,
BTC_BLE_MESH_ACT_PROVISIONER_SET_PROV_DATA_INFO,
BTC_BLE_MESH_ACT_PROVISIONER_SET_STATIC_OOB_VAL,
BTC_BLE_MESH_ACT_PROVISIONER_SET_PRIMARY_ELEM_ADDR,
BTC_BLE_MESH_ACT_PROVISIONER_SET_NODE_NAME,
BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_APP_KEY,
BTC_BLE_MESH_ACT_PROVISIONER_UPDATE_LOCAL_APP_KEY,
BTC_BLE_MESH_ACT_PROVISIONER_BIND_LOCAL_MOD_APP,
BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY,
BTC_BLE_MESH_ACT_PROVISIONER_UPDATE_LOCAL_NET_KEY,
BTC_BLE_MESH_ACT_PROVISIONER_STORE_NODE_COMP_DATA,
BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_UUID,
BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_ADDR,
BTC_BLE_MESH_ACT_PROVISIONER_ENABLE_HEARTBEAT_RECV,
BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE,
BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_INFO,
BTC_BLE_MESH_ACT_PROVISIONER_DIRECT_ERASE_SETTINGS,
BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_INDEX,
BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_UID,
BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX,
BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_UID,
BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_INDEX,
BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_UID,
BTC_BLE_MESH_ACT_PROVISIONER_SEND_PROV_RECORDS_GET,
BTC_BLE_MESH_ACT_PROVISIONER_SEND_PROV_RECORD_REQUEST,
BTC_BLE_MESH_ACT_PROVISIONER_SEND_PROV_INVITE,
BTC_BLE_MESH_ACT_PROVISIONER_SEND_LINK_CLOSE,
BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO,
BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION,
BTC_BLE_MESH_ACT_LPN_ENABLE,
BTC_BLE_MESH_ACT_LPN_DISABLE,
BTC_BLE_MESH_ACT_LPN_POLL,
BTC_BLE_MESH_ACT_PROXY_CLIENT_CONNECT,
BTC_BLE_MESH_ACT_PROXY_CLIENT_DISCONNECT,
BTC_BLE_MESH_ACT_PROXY_CLIENT_SET_FILTER_TYPE,
BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR,
BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR,
BTC_BLE_MESH_ACT_PROXY_CLIENT_DIRECTED_PROXY_SET,
BTC_BLE_MESH_ACT_PROXY_CLIENT_SEND_SOLIC_PDU,
BTC_BLE_MESH_ACT_MODEL_SUBSCRIBE_GROUP_ADDR,
BTC_BLE_MESH_ACT_MODEL_UNSUBSCRIBE_GROUP_ADDR,
BTC_BLE_MESH_ACT_DEINIT_MESH,
} btc_ble_mesh_prov_act_t;
typedef enum {
BTC_BLE_MESH_ACT_MODEL_PUBLISH,
BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND,
BTC_BLE_MESH_ACT_SERVER_MODEL_UPDATE_STATE,
} btc_ble_mesh_model_act_t;
typedef union {
struct ble_mesh_init_args {
esp_ble_mesh_prov_t *prov;
esp_ble_mesh_comp_t *comp;
SemaphoreHandle_t semaphore;
} mesh_init;
struct ble_mesh_node_prov_enable_args {
esp_ble_mesh_prov_bearer_t bearers;
} node_prov_enable;
struct ble_mesh_node_prov_disable_args {
esp_ble_mesh_prov_bearer_t bearers;
} node_prov_disable;
struct ble_mesh_set_oob_pub_key_args {
uint8_t pub_key_x[32];
uint8_t pub_key_y[32];
uint8_t private_key[32];
} set_oob_pub_key;
struct ble_mesh_node_input_num_args {
uint32_t number;
} input_number;
struct ble_mesh_node_input_str_args {
char string[8];
} input_string;
struct ble_mesh_set_device_name_args {
char name[ESP_BLE_MESH_DEVICE_NAME_MAX_LEN + 1];
} set_device_name;
struct ble_mesh_node_add_local_net_key_args {
uint8_t net_key[16];
uint16_t net_idx;
} node_add_local_net_key;
struct ble_mesh_node_add_local_app_key_args {
uint8_t app_key[16];
uint16_t net_idx;
uint16_t app_idx;
} node_add_local_app_key;
struct ble_mesh_node_bind_local_mod_app_args {
uint16_t element_addr;
uint16_t company_id;
uint16_t model_id;
uint16_t app_idx;
} node_local_mod_app_bind;
struct ble_mesh_provisioner_read_oob_pub_key_args {
uint8_t link_idx;
uint8_t pub_key_x[32];
uint8_t pub_key_y[32];
} provisioner_read_oob_pub_key;
struct ble_mesh_provisioner_input_str_args {
char string[8];
uint8_t link_idx;
} provisioner_input_str;
struct ble_mesh_provisioner_input_num_args {
uint32_t number;
uint8_t link_idx;
} provisioner_input_num;
struct ble_mesh_provisioner_enable_args {
esp_ble_mesh_prov_bearer_t bearers;
} provisioner_enable;
struct ble_mesh_provisioner_disable_args {
esp_ble_mesh_prov_bearer_t bearers;
} provisioner_disable;
struct ble_mesh_provisioner_dev_add_args {
esp_ble_mesh_unprov_dev_add_t add_dev;
esp_ble_mesh_dev_add_flag_t flags;
} provisioner_dev_add;
struct ble_mesh_provisioner_prov_dev_with_addr_args {
uint8_t uuid[16];
esp_ble_mesh_bd_addr_t addr;
esp_ble_mesh_addr_type_t addr_type;
esp_ble_mesh_prov_bearer_t bearer;
uint16_t oob_info;
uint16_t unicast_addr;
} provisioner_prov_dev_with_addr;
struct ble_mesh_provisioner_dev_del_args {
esp_ble_mesh_device_delete_t del_dev;
} provisioner_dev_del;
struct ble_mesh_provisioner_set_dev_uuid_match_args {
uint8_t offset;
uint8_t match_len;
uint8_t match_val[16];
bool prov_after_match;
} set_dev_uuid_match;
struct ble_mesh_provisioner_set_prov_net_idx_args {
esp_ble_mesh_prov_data_info_t prov_data;
} set_prov_data_info;
struct ble_mesh_provisioner_set_static_oob_val_args {
uint8_t value[16];
uint8_t length;
} set_static_oob_val;
struct ble_mesh_provisioner_set_primary_elem_addr_args {
uint16_t addr;
} set_primary_elem_addr;
struct ble_mesh_provisioner_set_node_name_args {
uint16_t index;
char name[ESP_BLE_MESH_NODE_NAME_MAX_LEN + 1];
} set_node_name;
struct ble_mesh_provisioner_add_local_app_key_args {
uint8_t app_key[16];
uint16_t net_idx;
uint16_t app_idx;
} add_local_app_key;
struct ble_mesh_provisioner_update_local_app_key_args {
uint8_t app_key[16];
uint16_t net_idx;
uint16_t app_idx;
} update_local_app_key;
struct ble_mesh_provisioner_bind_local_mod_app_args {
uint16_t elem_addr;
uint16_t model_id;
uint16_t cid;
uint16_t app_idx;
} local_mod_app_bind;
struct ble_mesh_provisioner_add_local_net_key_args {
uint8_t net_key[16];
uint16_t net_idx;
} add_local_net_key;
struct ble_mesh_provisioner_update_local_net_key_args {
uint8_t net_key[16];
uint16_t net_idx;
} update_local_net_key;
struct ble_mesh_provisioner_store_node_comp_data_args {
uint16_t unicast_addr;
uint16_t length;
uint8_t *data;
} store_node_comp_data;
struct ble_mesh_provisioner_delete_node_with_uuid_args {
uint8_t uuid[16];
} delete_node_with_uuid;
struct ble_mesh_provisioner_delete_node_with_addr_args {
uint16_t unicast_addr;
} delete_node_with_addr;
struct {
bool enable;
} enable_heartbeat_recv;
struct {
uint8_t type;
} set_heartbeat_filter_type;
struct {
uint8_t op;
uint16_t hb_src;
uint16_t hb_dst;
} set_heartbeat_filter_info;
struct {
uint8_t index;
} open_settings_with_index;
struct {
char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1];
} open_settings_with_uid;
struct {
uint8_t index;
bool erase;
} close_settings_with_index;
struct {
char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1];
bool erase;
} close_settings_with_uid;
struct {
uint8_t index;
} delete_settings_with_index;
struct {
char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1];
} delete_settings_with_uid;
struct {
uint16_t link_idx;
} send_prov_records_get;
struct {
uint16_t link_idx;
uint16_t record_id;
uint16_t frag_offset;
uint16_t max_size;
} send_prov_record_req;
struct {
uint16_t link_idx;
} send_prov_invite;
struct {
uint16_t link_idx;
} send_link_close;
struct ble_mesh_set_fast_prov_info_args {
uint16_t unicast_min;
uint16_t unicast_max;
uint16_t net_idx;
uint8_t flags;
uint32_t iv_index;
uint8_t offset;
uint8_t match_len;
uint8_t match_val[16];
} set_fast_prov_info;
struct ble_mesh_set_fast_prov_action_args {
uint8_t action;
} set_fast_prov_action;
struct ble_mesh_lpn_enable_args {
/* RFU */
} lpn_enable;
struct ble_mesh_lpn_disable_args {
bool force;
} lpn_disable;
struct ble_mesh_lpn_poll_args {
/* RFU */
} lpn_poll;
struct ble_mesh_proxy_client_connect_args {
uint8_t addr[6];
uint8_t addr_type;
uint16_t net_idx;
} proxy_client_connect;
struct ble_mesh_proxy_client_disconnect_args {
uint8_t conn_handle;
} proxy_client_disconnect;
struct ble_mesh_proxy_client_set_filter_type_args {
uint8_t conn_handle;
uint16_t net_idx;
uint8_t filter_type;
} proxy_client_set_filter_type;
struct ble_mesh_proxy_client_add_filter_addr_args {
uint8_t conn_handle;
uint16_t net_idx;
uint16_t addr_num;
uint16_t *addr;
} proxy_client_add_filter_addr;
struct ble_mesh_proxy_client_remove_filter_addr_args {
uint8_t conn_handle;
uint16_t net_idx;
uint16_t addr_num;
uint16_t *addr;
} proxy_client_remove_filter_addr;
struct ble_mesh_proxy_client_directed_proxy_set_args {
uint8_t conn_handle;
uint16_t net_idx;
uint8_t use_directed;
} proxy_client_directed_proxy_set;
struct {
uint16_t net_idx;
uint16_t ssrc;
uint16_t dst;
} proxy_client_send_solic_pdu;
struct ble_mesh_model_sub_group_addr_args {
uint16_t element_addr;
uint16_t company_id;
uint16_t model_id;
uint16_t group_addr;
} model_sub_group_addr;
struct ble_mesh_model_unsub_group_addr_args {
uint16_t element_addr;
uint16_t company_id;
uint16_t model_id;
uint16_t group_addr;
} model_unsub_group_addr;
struct ble_mesh_deinit_args {
esp_ble_mesh_deinit_param_t param;
SemaphoreHandle_t semaphore;
} mesh_deinit;
} btc_ble_mesh_prov_args_t;
typedef union {
struct ble_mesh_model_publish_args {
esp_ble_mesh_model_t *model;
uint8_t device_role __attribute__((deprecated));
} model_publish;
struct ble_mesh_model_send_args {
esp_ble_mesh_model_t *model;
esp_ble_mesh_msg_ctx_t *ctx;
uint32_t opcode;
bool need_rsp;
uint16_t length;
uint8_t *data;
uint8_t device_role __attribute__((deprecated));
int32_t msg_timeout;
} model_send;
struct ble_mesh_server_model_update_state_args {
esp_ble_mesh_model_t *model;
esp_ble_mesh_server_state_type_t type;
esp_ble_mesh_server_state_value_t *value;
} model_update_state;
} btc_ble_mesh_model_args_t;
void btc_ble_mesh_prov_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_prov_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_model_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_model_arg_deep_free(btc_msg_t *msg);
const uint8_t *btc_ble_mesh_node_get_local_net_key(uint16_t net_idx);
const uint8_t *btc_ble_mesh_node_get_local_app_key(uint16_t app_idx);
esp_ble_mesh_node_t *btc_ble_mesh_provisioner_get_node_with_uuid(const uint8_t uuid[16]);
esp_ble_mesh_node_t *btc_ble_mesh_provisioner_get_node_with_addr(uint16_t unicast_addr);
esp_ble_mesh_node_t *btc_ble_mesh_provisioner_get_node_with_name(const char *name);
uint16_t btc_ble_mesh_provisioner_get_prov_node_count(void);
const esp_ble_mesh_node_t **btc_ble_mesh_provisioner_get_node_table_entry(void);
int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model);
int btc_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model);
int32_t btc_ble_mesh_model_pub_period_get(esp_ble_mesh_model_t *mod);
uint16_t btc_ble_mesh_get_primary_addr(void);
uint16_t *btc_ble_mesh_model_find_group(esp_ble_mesh_model_t *mod, uint16_t addr);
esp_ble_mesh_elem_t *btc_ble_mesh_elem_find(uint16_t addr);
uint8_t btc_ble_mesh_elem_count(void);
esp_ble_mesh_model_t *btc_ble_mesh_model_find_vnd(const esp_ble_mesh_elem_t *elem,
uint16_t company, uint16_t id);
esp_ble_mesh_model_t *btc_ble_mesh_model_find(const esp_ble_mesh_elem_t *elem, uint16_t id);
const esp_ble_mesh_comp_t *btc_ble_mesh_comp_get(void);
const char *btc_ble_mesh_provisioner_get_settings_uid(uint8_t index);
uint8_t btc_ble_mesh_provisioner_get_settings_index(const char *uid);
uint8_t btc_ble_mesh_provisioner_get_free_settings_count(void);
void btc_ble_mesh_model_call_handler(btc_msg_t *msg);
void btc_ble_mesh_model_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_prov_call_handler(btc_msg_t *msg);
void btc_ble_mesh_prov_cb_handler(btc_msg_t *msg);
#if CONFIG_BLE_MESH_DF_SRV
int btc_ble_mesh_enable_directed_forwarding(uint16_t net_idx, bool directed_forwarding,
bool directed_forwarding_relay);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_PROV_H_ */
@@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_SENSOR_MODEL_H_
#define _BTC_BLE_MESH_SENSOR_MODEL_H_
#include "btc/btc_manage.h"
#include "esp_ble_mesh_sensor_model_api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
BTC_BLE_MESH_ACT_SENSOR_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_SENSOR_CLIENT_SET_STATE,
BTC_BLE_MESH_ACT_SENSOR_CLIENT_MAX,
} btc_ble_mesh_sensor_client_act_t;
typedef union {
struct ble_mesh_sensor_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_sensor_client_get_state_t *get_state;
} sensor_client_get_state;
struct ble_mesh_sensor_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_sensor_client_set_state_t *set_state;
} sensor_client_set_state;
} btc_ble_mesh_sensor_client_args_t;
typedef enum {
BTC_BLE_MESH_EVT_SENSOR_CLIENT_GET_STATE,
BTC_BLE_MESH_EVT_SENSOR_CLIENT_SET_STATE,
BTC_BLE_MESH_EVT_SENSOR_CLIENT_PUBLISH,
BTC_BLE_MESH_EVT_SENSOR_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_SENSOR_CLIENT_MAX,
} btc_ble_mesh_sensor_client_evt_t;
void btc_ble_mesh_sensor_client_call_handler(btc_msg_t *msg);
void btc_ble_mesh_sensor_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_sensor_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_sensor_client_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_sensor_client_publish_callback(uint32_t opcode,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
void bt_mesh_sensor_client_cb_evt_to_btc(uint32_t opcode, uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
typedef enum {
BTC_BLE_MESH_EVT_SENSOR_SERVER_STATE_CHANGE,
BTC_BLE_MESH_EVT_SENSOR_SERVER_RECV_GET_MSG,
BTC_BLE_MESH_EVT_SENSOR_SERVER_RECV_SET_MSG,
BTC_BLE_MESH_EVT_SENSOR_SERVER_MAX,
} btc_ble_mesh_sensor_server_evt_t;
void bt_mesh_sensor_server_cb_evt_to_btc(uint8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
void btc_ble_mesh_sensor_server_cb_handler(btc_msg_t *msg);
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_SENSOR_MODEL_H_ */

Some files were not shown because too many files have changed in this diff Show More