Compare commits

..

1 Commits

Author SHA1 Message Date
Angus Gratton
c8315e0110 version: Update to v4.4-dev 2021-02-10 16:07:24 +11:00
862 changed files with 10844 additions and 23646 deletions

View File

@@ -1,17 +0,0 @@
name: Create zip file with recursive source clone for release
on:
push:
tags:
- v*
jobs:
release_zips:
name: Create release zip file
runs-on: ubuntu-20.04
steps:
- name: Create a recursive clone source zip
uses: espressif/github-actions/release_zips@master
env:
RELEASE_PROJECT_NAME: ESP-IDF
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

8
.gitmodules vendored
View File

@@ -7,8 +7,8 @@
path = components/esptool_py/esptool
url = ../../espressif/esptool.git
[submodule "components/bt/controller/lib_esp32"]
path = components/bt/controller/lib_esp32
[submodule "components/bt/controller/lib"]
path = components/bt/controller/lib
url = ../../espressif/esp32-bt-lib.git
[submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"]
@@ -90,7 +90,3 @@
[submodule "components/cmock/CMock"]
path = components/cmock/CMock
url = ../../ThrowTheSwitch/CMock.git
[submodule "components/bt/controller/lib_esp32c3_family"]
path = components/bt/controller/lib_esp32c3_family
url = ../../espressif/esp32c3-bt-lib.git

View File

@@ -9,7 +9,7 @@ entries:
SEGGER_SYSVIEW_Config_FreeRTOS (noflash)
SEGGER_SYSVIEW_FreeRTOS (noflash)
[mapping:app_trace_driver]
[mapping:driver]
archive: libdriver.a
entries:
if SYSVIEW_TS_SOURCE_TIMER_00 = y || SYSVIEW_TS_SOURCE_TIMER_01 = y

View File

@@ -41,6 +41,16 @@
#include "esp_efuse.h"
#include "esp_attr.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/crc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/crc.h"
#include "esp32s2/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/crc.h"
#include "esp32c3/rom/secure_boot.h"
#endif
#define SUB_TYPE_ID(i) (i & 0x0F)
/* Partial_data is word aligned so no reallocation is necessary for encrypted flash write */

View File

@@ -274,10 +274,6 @@ menu "Bootloader config"
config BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
bool "Skip image validation when exiting deep sleep"
# note: dependencies for this config item are different to other "skip image validation"
# options, allowing to turn on "allow insecure options" and have secure boot with
# "skip validation when existing deep sleep". Keeping this to avoid a breaking change,
# but - as noted in help - it invalidates the integrity of Secure Boot checks
depends on (SECURE_BOOT && SECURE_BOOT_INSECURE) || !SECURE_BOOT
default n
help
@@ -290,48 +286,6 @@ menu "Bootloader config"
partition as this would skip the validation upon first load of the new
OTA partition.
It is possible to enable this option with Secure Boot if "allow insecure
options" is enabled, however it's strongly recommended to NOT enable it as
it may allow a Secure Boot bypass.
config BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
bool "Skip image validation from power on reset (READ HELP FIRST)"
# only available if both Secure Boot and Check Signature on Boot are disabled
depends on !SECURE_SIGNED_ON_BOOT
default n
help
Some applications need to boot very quickly from power on. By default, the entire app binary
is read from flash and verified which takes up a significant portion of the boot time.
Enabling this option will skip validation of the app when the SoC boots from power on.
Note that in this case it's not possible for the bootloader to detect if an app image is
corrupted in the flash, therefore it's not possible to safely fall back to a different app
partition. Flash corruption of this kind is unlikely but can happen if there is a serious
firmware bug or physical damage.
Following other reset types, the bootloader will still validate the app image. This increases
the chances that flash corruption resulting in a crash can be detected following soft reset, and
the bootloader will fall back to a valid app image. To increase the chances of successfully recovering
from a flash corruption event, keep the option BOOTLOADER_WDT_ENABLE enabled and consider also enabling
BOOTLOADER_WDT_DISABLE_IN_USER_CODE - then manually disable the RTC Watchdog once the app is running.
In addition, enable both the Task and Interrupt watchdog timers with reset options set.
config BOOTLOADER_SKIP_VALIDATE_ALWAYS
bool "Skip image validation always (READ HELP FIRST)"
# only available if both Secure Boot and Check Signature on Boot are disabled
depends on !SECURE_SIGNED_ON_BOOT
default n
select BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
select BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
help
Selecting this option prevents the bootloader from ever validating the app image before
booting it. Any flash corruption of the selected app partition will make the entire SoC
unbootable.
Although flash corruption is a very rare case, it is not recommended to select this option.
Consider selecting "Skip image validation from power on reset" instead. However, if boot time
is the only important factor then it can be enabled.
config BOOTLOADER_RESERVE_RTC_SIZE
hex
default 0x10 if BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP || BOOTLOADER_CUSTOM_RESERVE_RTC
@@ -424,7 +378,7 @@ menu "Security features"
1. ECDSA based secure boot scheme. (Only choice for Secure Boot V1)
Supported in ESP32 and ESP32-ECO3.
2. The RSA based secure boot scheme. (Only choice for Secure Boot V2)
Supported in ESP32-ECO3 (ESP32 Chip Revision 3 onwards), ESP32-S2, ESP32-C3, ESP32-S3.
Supported in ESP32-ECO3. (ESP32 Chip Revision 3 onwards)
config SECURE_SIGNED_APPS_ECDSA_SCHEME
bool "ECDSA"
@@ -436,7 +390,7 @@ menu "Security features"
config SECURE_SIGNED_APPS_RSA_SCHEME
bool "RSA"
depends on SECURE_BOOT_SUPPORTS_RSA && (SECURE_SIGNED_APPS_NO_SECURE_BOOT || SECURE_BOOT_V2_ENABLED)
depends on SECURE_BOOT_SUPPORTS_RSA && SECURE_BOOT_V2_ENABLED
help
Appends the RSA-3072 based Signature block to the application.
Refer to <Secure Boot Version 2 documentation link> before enabling.
@@ -445,7 +399,7 @@ menu "Security features"
config SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT
bool "Bootloader verifies app signatures"
default n
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT && SECURE_SIGNED_APPS_ECDSA_SCHEME
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT
help
If this option is set, the bootloader will be compiled with code to verify that an app is signed before
booting it.
@@ -471,7 +425,7 @@ menu "Security features"
config SECURE_BOOT
bool "Enable hardware Secure Boot in bootloader (READ DOCS FIRST)"
default n
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || ESP32C3_REV_MIN_3
depends on !IDF_TARGET_ESP32C3 # IDF-2647
help
Build a bootloader which enables Secure Boot on first boot.
@@ -488,7 +442,7 @@ menu "Security features"
help
Select the Secure Boot Version. Depends on the Chip Revision.
Secure Boot V2 is the new RSA based secure boot scheme.
Supported in ESP32-ECO3 (ESP32 Chip Revision 3 onwards), ESP32-S2, ESP32-C3 ECO3.
Supported in ESP32-ECO3. (ESP32 Chip Revision 3 onwards)
Secure Boot V1 is the AES based secure boot scheme.
Supported in ESP32 and ESP32-ECO3.
@@ -502,6 +456,8 @@ menu "Security features"
config SECURE_BOOT_V2_ENABLED
bool "Enable Secure Boot version 2"
depends on SECURE_BOOT_SUPPORTS_RSA
select SECURE_ENABLE_SECURE_ROM_DL_MODE if !IDF_TARGET_ESP32 && !SECURE_INSECURE_ALLOW_DL_MODE && !SECURE_DISABLE_ROM_DL_MODE # NOERROR
select SECURE_DISABLE_ROM_DL_MODE if ESP32_REV_MIN_3 && !SECURE_INSECURE_ALLOW_DL_MODE
help
Build a bootloader which enables Secure Boot version 2 on first boot.
Refer to Secure Boot V2 section of the ESP-IDF Programmer's Guide for this version before enabling.
@@ -670,6 +626,8 @@ menu "Security features"
config SECURE_FLASH_ENCRYPTION_MODE_RELEASE
bool "Release"
select SECURE_ENABLE_SECURE_ROM_DL_MODE if SECURE_TARGET_HAS_SECURE_ROM_DL_MODE && !SECURE_DISABLE_ROM_DL_MODE # NOERROR
endchoice
menu "Potentially insecure options"
@@ -734,6 +692,19 @@ menu "Security features"
key digest, causing an immediate denial of service and possibly allowing an additional fault
injection attack to bypass the signature protection.
config SECURE_INSECURE_ALLOW_DL_MODE
bool "Don't automatically restrict UART download mode"
depends on SECURE_BOOT_INSECURE && SECURE_BOOT_V2_ENABLED
default N
help
By default, enabling either flash encryption in release mode or secure boot will automatically
disable UART download mode on ESP32 ECO3, or enable secure download mode on newer chips.
This is recommended to reduce the attack surface of the chip.
To allow the full UART download mode to stay enabled, enable this option and ensure
the options SECURE_DISABLE_ROM_DL_MODE and SECURE_ENABLE_SECURE_ROM_DL_MODE are disabled as applicable.
This is not recommended.
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
bool "Leave UART bootloader encryption enabled"
depends on SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
@@ -781,58 +752,47 @@ menu "Security features"
endmenu # Potentially Insecure
choice SECURE_UART_ROM_DL_MODE
bool "UART ROM download mode"
default SECURE_ENABLE_SECURE_ROM_DL_MODE if SECURE_TARGET_HAS_SECURE_ROM_DL_MODE && !SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT # NOERROR
default SECURE_INSECURE_ALLOW_DL_MODE
depends on SECURE_BOOT_V2_ENABLED || SECURE_FLASH_ENC_ENABLED
config SECURE_DISABLE_ROM_DL_MODE
bool "Permanently disable ROM Download Mode"
depends on !IDF_TARGET_ESP32 || ESP32_REV_MIN_3
default n
help
If set, during startup the app will burn an eFuse bit to permanently disable the UART ROM
Download Mode. This prevents any future use of esptool.py, espefuse.py and similar tools.
config SECURE_DISABLE_ROM_DL_MODE
bool "UART ROM download mode (Permanently disabled (recommended))"
help
If set, during startup the app will burn an eFuse bit to permanently disable the UART ROM
Download Mode. This prevents any future use of esptool.py, espefuse.py and similar tools.
Once disabled, if the SoC is booted with strapping pins set for ROM Download Mode
then an error is printed instead.
Once disabled, if the SoC is booted with strapping pins set for ROM Download Mode
then an error is printed instead.
It is recommended to enable this option in any production application where Flash
Encryption and/or Secure Boot is enabled and access to Download Mode is not required.
It is recommended to enable this option in any production application where Flash
Encryption and/or Secure Boot is enabled and access to Download Mode is not required.
It is also possible to permanently disable Download Mode by calling
esp_efuse_disable_rom_download_mode() at runtime.
It is also possible to permanently disable Download Mode by calling
esp_efuse_disable_rom_download_mode() at runtime.
config SECURE_ENABLE_SECURE_ROM_DL_MODE
bool "Permanently switch to ROM UART Secure Download mode"
depends on SECURE_TARGET_HAS_SECURE_ROM_DL_MODE && !SECURE_DISABLE_ROM_DL_MODE
select ESPTOOLPY_NO_STUB
help
If set, during startup the app will burn an eFuse bit to permanently switch the UART ROM
Download Mode into a separate Secure Download mode. This option can only work if
Download Mode is not already disabled by eFuse.
config SECURE_ENABLE_SECURE_ROM_DL_MODE
bool "UART ROM download mode (Permanently switch to Secure mode (recommended))"
depends on SECURE_TARGET_HAS_SECURE_ROM_DL_MODE
select ESPTOOLPY_NO_STUB
help
If set, during startup the app will burn an eFuse bit to permanently switch the UART ROM
Download Mode into a separate Secure Download mode. This option can only work if
Download Mode is not already disabled by eFuse.
Secure Download mode limits the use of Download Mode functions to simple flash read,
write and erase operations, plus a command to return a summary of currently enabled
security features.
Secure Download mode limits the use of Download Mode functions to simple flash read,
write and erase operations, plus a command to return a summary of currently enabled
security features.
Secure Download mode is not compatible with the esptool.py flasher stub feature,
espefuse.py, read/writing memory or registers, encrypted download, or any other
features that interact with unsupported Download Mode commands.
Secure Download mode is not compatible with the esptool.py flasher stub feature,
espefuse.py, read/writing memory or registers, encrypted download, or any other
features that interact with unsupported Download Mode commands.
Secure Download mode should be enabled in any application where Flash Encryption
and/or Secure Boot is enabled. Disabling this option does not immediately cancel
the benefits of the security features, but it increases the potential "attack
surface" for an attacker to try and bypass them with a successful physical attack.
Secure Download mode should be enabled in any application where Flash Encryption
and/or Secure Boot is enabled. Disabling this option does not immediately cancel
the benefits of the security features, but it increases the potential "attack
surface" for an attacker to try and bypass them with a successful physical attack.
It is also possible to enable secure download mode at runtime by calling
esp_efuse_enable_rom_secure_download_mode()
It is also possible to enable secure download mode at runtime by calling
esp_efuse_enable_rom_secure_download_mode()
config SECURE_INSECURE_ALLOW_DL_MODE
bool "UART ROM download mode (Enabled (not recommended))"
help
This is a potentially insecure option.
Enabling this option will allow the full UART download mode to stay enabled.
This option SHOULD NOT BE ENABLED for production use cases.
endchoice
endmenu # Security features

View File

@@ -17,8 +17,6 @@ CONFIG_SECURE_BOOT_SIGNING_KEY ?=
SECURE_BOOT_SIGNING_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOT_SIGNING_KEY)))
export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component
BOOTLOADER_SIGNED_BIN ?=
# Has a matching value in bootloader_support esp_flash_partitions.h
BOOTLOADER_OFFSET := 0x1000

View File

@@ -28,11 +28,10 @@ set(COMPONENTS
micro-ecc
main
efuse
esp_system
newlib)
esp_system)
set(BOOTLOADER_BUILD 1)
include("${IDF_PATH}/tools/cmake/project.cmake")
set(common_req log esp_rom esp_common esp_hw_support hal newlib)
set(common_req log esp_rom esp_common esp_hw_support hal)
if(LEGACY_INCLUDE_COMMON_HEADERS)
list(APPEND common_req soc hal)
endif()
@@ -54,9 +53,6 @@ string(REPLACE ";" " " esptoolpy_write_flash
string(REPLACE ";" " " espsecurepy "${ESPSECUREPY}")
string(REPLACE ";" " " espefusepy "${ESPEFUSEPY}")
# Suppress warning: "Manually-specified variables were not used by the project: SECURE_BOOT_SIGNING_KEY"
set(ignore_signing_key "${SECURE_BOOT_SIGNING_KEY}")
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
if(CONFIG_SECURE_BOOTLOADER_KEY_ENCODING_192BIT)
set(key_digest_len 192)

View File

@@ -8,7 +8,7 @@ endif
PROJECT_NAME := bootloader
COMPONENTS := esp_hw_support esptool_py bootloader_support log spi_flash micro-ecc soc main efuse esp_rom hal xtensa
COMPONENTS := esp_hw_support esptool_py bootloader_support log spi_flash micro-ecc soc main efuse esp_rom hal
# Clear C and CXX from top level project
CFLAGS =

View File

@@ -52,7 +52,7 @@ SECTIONS
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
@@ -167,14 +167,6 @@ SECTIONS
*(.fini.literal)
*(.fini)
*(.gnu.version)
/** CPU will try to prefetch up to 16 bytes of
* of instructions. This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += 16;
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg

View File

@@ -40,7 +40,7 @@ SECTIONS
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
@@ -156,14 +156,6 @@ SECTIONS
*(.fini.literal)
*(.fini)
*(.gnu.version)
/** CPU will try to prefetch up to 16 bytes of
* of instructions. This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += 16;
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg

View File

@@ -39,7 +39,7 @@ SECTIONS
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
@@ -155,14 +155,6 @@ SECTIONS
*(.fini.literal)
*(.fini)
*(.gnu.version)
/** CPU will try to prefetch up to 16 bytes of
* of instructions. This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += 16;
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg

View File

@@ -40,7 +40,7 @@ SECTIONS
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
@@ -156,14 +156,6 @@ SECTIONS
*(.fini.literal)
*(.fini)
*(.gnu.version)
/** CPU will try to prefetch up to 16 bytes of
* of instructions. This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += 16;
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg

View File

@@ -9,7 +9,6 @@ set(srcs
"src/bootloader_utility.c"
"src/esp_image_format.c"
"src/flash_encrypt.c"
"src/secure_boot.c"
"src/flash_partitions.c"
"src/flash_qio_mode.c"
"src/bootloader_flash_config_${IDF_TARGET}.c"
@@ -35,28 +34,16 @@ else()
"src/idf/bootloader_sha.c")
set(include_dirs "include")
set(priv_include_dirs "include_bootloader")
set(priv_requires spi_flash mbedtls efuse app_update)
set(priv_requires spi_flash mbedtls efuse)
endif()
if(BOOTLOADER_BUILD)
if(CONFIG_SECURE_SIGNED_ON_BOOT)
if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
list(APPEND srcs "src/secure_boot_v1/secure_boot_signatures_bootloader.c")
endif()
if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME)
list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_bootloader.c")
endif()
endif()
else()
if(CONFIG_SECURE_SIGNED_ON_UPDATE)
if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
list(APPEND srcs "src/secure_boot_v1/secure_boot_signatures_app.c")
endif()
if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME)
list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_app.c")
endif()
if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME)
if(BOOTLOADER_BUILD)
list(APPEND srcs
"src/${IDF_TARGET}/secure_boot_signatures.c")
else()
list(APPEND srcs
"src/idf/secure_boot_signatures.c")
endif()
endif()

View File

@@ -7,9 +7,7 @@ else
COMPONENT_PRIV_INCLUDEDIRS := include_bootloader
endif
COMPONENT_SRCDIRS := src \
src/secure_boot_v2 \
src/secure_boot_v1
COMPONENT_SRCDIRS := src
ifndef IS_BOOTLOADER_BUILD
COMPONENT_SRCDIRS += src/idf # idf sub-directory contains platform agnostic IDF versions
@@ -35,27 +33,12 @@ COMPONENT_OBJEXCLUDE += src/bootloader_flash_config_esp32s2.o \
src/bootloader_random_esp32s3.o \
src/bootloader_random_esp32c3.o
ifdef IS_BOOTLOADER_BUILD
ifndef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
COMPONENT_OBJEXCLUDE += src/secure_boot_v1/secure_boot_signatures_bootloader.o
endif
ifndef CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
COMPONENT_OBJEXCLUDE += src/secure_boot_v2/secure_boot_signatures_bootloader.o
endif
COMPONENT_OBJEXCLUDE += src/secure_boot_v1/secure_boot_signatures_app.o \
src/secure_boot_v2/secure_boot_signatures_app.o
else
ifndef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
COMPONENT_OBJEXCLUDE += src/secure_boot_v1/secure_boot_signatures_app.o
endif
ifndef CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
COMPONENT_OBJEXCLUDE += src/secure_boot_v2/secure_boot_signatures_app.o
endif
COMPONENT_OBJEXCLUDE += src/secure_boot_v1/secure_boot_signatures_bootloader.o \
src/secure_boot_v2/secure_boot_signatures_bootloader.o
endif # IS_BOOTLOADER_BUILD
ifndef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
ifndef CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
COMPONENT_OBJEXCLUDE += src/$(IDF_TARGET)/secure_boot_signatures.o \
src/idf/secure_boot_signatures.o
endif
endif
ifndef CONFIG_SECURE_BOOT
COMPONENT_OBJEXCLUDE += src/$(IDF_TARGET)/secure_boot.o

View File

@@ -106,20 +106,6 @@ _Static_assert(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved
*/
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
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app 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).
*

View File

@@ -19,22 +19,17 @@
#include "esp_image_format.h"
#include "esp_rom_efuse.h"
#include "sdkconfig.h"
#include "esp_rom_crc.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/efuse.h"
#include "esp32/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/efuse.h"
#include "esp32s2/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/efuse.h"
#include "esp32c3/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/efuse.h"
#include "esp32s3/rom/secure_boot.h"
#endif
typedef struct ets_secure_boot_signature ets_secure_boot_signature_t;
#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"
@@ -50,8 +45,6 @@ extern "C" {
Can be compiled as part of app or bootloader code.
*/
#define ESP_SECURE_BOOT_DIGEST_LEN 32
/** @brief Is secure boot currently enabled in hardware?
*
* This means that the ROM bootloader code will only boot
@@ -188,16 +181,6 @@ typedef struct {
*/
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_3
/**
* @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[SECURE_BOOT_NUM_BLOCKS][ESP_SECURE_BOOT_DIGEST_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;
/** @brief Verify the RSA secure boot signature block for Secure Boot V2.
*
@@ -211,7 +194,6 @@ typedef struct {
*
*/
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest);
#endif // !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_3
/** @brief Legacy ECDSA verification function
*
@@ -232,45 +214,6 @@ typedef struct {
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
/** @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 occured 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
#ifdef __cplusplus
}
#endif

View File

@@ -30,7 +30,6 @@
#include "soc/gpio_periph.h"
#include "soc/rtc.h"
#include "soc/efuse_reg.h"
#include "soc/soc_memory_layout.h"
#include "hal/gpio_ll.h"
#include "esp_image_format.h"
#include "bootloader_sha.h"
@@ -77,9 +76,7 @@ esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hd
}
uint8_t revision = bootloader_common_get_chip_revision();
if (revision < img_hdr->min_chip_rev) {
/* To fix this error, please update mininum supported chip revision from configuration,
* located in TARGET (e.g. ESP32) specific options under "Component config" menu */
ESP_LOGE(TAG, "This chip is revision %d but the application is configured for minimum revision %d. Can't run.", revision, img_hdr->min_chip_rev);
ESP_LOGE(TAG, "can't run on lower chip revision, expected %d, found %d", revision, img_hdr->min_chip_rev);
err = ESP_FAIL;
} else if (revision != img_hdr->min_chip_rev) {
#ifdef BOOTLOADER_BUILD
@@ -141,18 +138,7 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR;
#if !IS_BOOTLOADER_BUILD
/* The app needs to be told this memory is reserved, important if configured to use RTC memory as heap.
Note that keeping this macro here only works when other symbols in this file are referenced by the app, as
this feature is otherwise 100% part of the bootloader. However this seems to happen in all apps.
*/
SOC_RESERVE_MEMORY_REGION(RTC_RETAIN_MEM_ADDR, RTC_RETAIN_MEM_ADDR + sizeof(rtc_retain_mem_t), rtc_retain_mem);
#endif
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)(SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t));
static bool check_rtc_retain_mem(void)
{

View File

@@ -21,7 +21,6 @@
#include "soc/gpio_sig_map.h"
#include "soc/rtc.h"
#include "hal/clk_gate_ll.h"
#include "hal/gpio_hal.h"
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/usb/cdc_acm.h"
#include "esp32s2/rom/usb/usb_common.h"
@@ -70,8 +69,8 @@ void bootloader_console_init(void)
uart_tx_gpio != UART_NUM_0_TXD_DIRECT_GPIO_NUM ||
uart_rx_gpio != UART_NUM_0_RXD_DIRECT_GPIO_NUM) {
// Change default UART pins back to GPIOs
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0RXD_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0TXD_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, PIN_FUNC_GPIO);
// Route GPIO signals to/from pins
const uint32_t tx_idx = uart_periph_signal[uart_num].tx_sig;
const uint32_t rx_idx = uart_periph_signal[uart_num].rx_sig;

View File

@@ -25,7 +25,6 @@
#include "soc/spi_reg.h"
#include "soc/soc_caps.h"
#include "soc/soc_pins.h"
#include "hal/gpio_hal.h"
#include "flash_qio_mode.h"
#include "bootloader_common.h"
#include "bootloader_flash_config.h"
@@ -88,7 +87,7 @@ void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302) {
// For ESP32D2WD or ESP32-PICO series,the SPI pins are already configured
// flash clock signal should come from IO MUX.
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else {
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
@@ -103,14 +102,14 @@ void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
esp_rom_gpio_connect_out_signal(SPI_IOMUX_PIN_NUM_HD, SPIHD_OUT_IDX, 0, 0);
esp_rom_gpio_connect_in_signal(SPI_IOMUX_PIN_NUM_HD, SPIHD_IN_IDX, 0);
//select pin function gpio
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
// flash clock signal should come from IO MUX.
// set drive ability for clock
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
uint32_t flash_id = g_rom_flashchip.device_id;

View File

@@ -24,7 +24,7 @@
#include "soc/efuse_reg.h"
#include "soc/spi_reg.h"
#include "soc/spi_mem_reg.h"
#include "soc/soc_caps.h"
#include "soc/spi_caps.h"
#include "flash_qio_mode.h"
#include "bootloader_flash_config.h"
#include "bootloader_common.h"

View File

@@ -34,7 +34,6 @@
#include "soc/io_mux_reg.h"
#include "soc/rtc.h"
#include "soc/spi_periph.h"
#include "hal/gpio_hal.h"
#include "esp32/rom/cache.h"
#include "esp_rom_gpio.h"
@@ -62,7 +61,7 @@ void bootloader_configure_spi_pins(int drv)
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302) {
// For ESP32D2WD or ESP32-PICO series,the SPI pins are already configured
// flash clock signal should come from IO MUX.
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else {
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
@@ -77,14 +76,14 @@ void bootloader_configure_spi_pins(int drv)
esp_rom_gpio_connect_out_signal(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
esp_rom_gpio_connect_in_signal(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
//select pin function gpio
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
// flash clock signal should come from IO MUX.
// set drive ability for clock
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32 || CONFIG_SPIRAM_TYPE_ESPPSRAM64

View File

@@ -19,6 +19,7 @@
#include "esp_log.h"
#include "esp32/rom/cache.h"
#include "esp_rom_crc.h"
#include "soc/efuse_periph.h"
#include "soc/rtc_periph.h"
@@ -222,12 +223,16 @@ esp_err_t esp_secure_boot_permanently_enable(void)
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
static const char *TAG = "secure_boot_v2";
#define SIG_BLOCK_MAGIC_BYTE 0xe7
#define CRC_SIGN_BLOCK_LEN 1196
#define SIG_BLOCK_PADDING 4096
#define DIGEST_LEN 32
static esp_err_t validate_signature_block(const ets_secure_boot_signature_t *sig_block, uint8_t *digest)
{
uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)sig_block, CRC_SIGN_BLOCK_LEN);
if (sig_block->block[0].magic_byte == ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC
&& sig_block->block[0].block_crc == crc
&& !memcmp(digest, sig_block->block[0].image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
if (sig_block->block[0].magic_byte == SIG_BLOCK_MAGIC_BYTE && sig_block->block[0].block_crc == crc && !memcmp(digest, sig_block->block[0].image_digest, DIGEST_LEN)) {
ESP_LOGI(TAG, "valid signature block found");
return ESP_OK;
}
@@ -238,7 +243,7 @@ static esp_err_t secure_boot_v2_digest_generate(uint32_t flash_offset, uint32_t
{
esp_err_t ret = ESP_FAIL;
uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t image_digest[DIGEST_LEN] = {0};
size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
if (ret != ESP_OK) {
@@ -261,7 +266,7 @@ static esp_err_t secure_boot_v2_digest_generate(uint32_t flash_offset, uint32_t
}
/* Verifying Signature block */
uint8_t verified_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t verified_digest[DIGEST_LEN] = {0};
/* Generating the SHA of the public key components in the signature block */
bootloader_sha256_handle_t sig_block_sha;
@@ -313,7 +318,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
return ret;
}
uint8_t boot_pub_key_digest[ESP_SECURE_BOOT_DIGEST_LEN];
uint8_t boot_pub_key_digest[DIGEST_LEN];
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2;
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2;
@@ -345,7 +350,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
}
ESP_LOGI(TAG, "Burning public key hash to efuse.");
ret = esp_efuse_write_block(EFUSE_BLK2, boot_pub_key_digest, 0, (ESP_SECURE_BOOT_DIGEST_LEN * 8));
ret = esp_efuse_write_block(EFUSE_BLK2, boot_pub_key_digest, 0, (DIGEST_LEN * 8));
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Writing public key hash to efuse failed.");
return ret;
@@ -361,7 +366,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
efuse_blk2_digest[5] = efuse_blk2_r5;
efuse_blk2_digest[6] = efuse_blk2_r6;
efuse_blk2_digest[7] = efuse_blk2_r7;
memcpy(boot_pub_key_digest, efuse_blk2_digest, ESP_SECURE_BOOT_DIGEST_LEN);
memcpy(boot_pub_key_digest, efuse_blk2_digest, DIGEST_LEN);
ESP_LOGW(TAG, "Using pre-loaded secure boot v2 public key digest in EFUSE block 2");
}
@@ -375,7 +380,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
efuse_key_write_protected = true;
}
uint8_t app_pub_key_digest[ESP_SECURE_BOOT_DIGEST_LEN];
uint8_t app_pub_key_digest[DIGEST_LEN];
ret = secure_boot_v2_digest_generate(image_data->start_addr, image_data->image_len - SIG_BLOCK_PADDING, app_pub_key_digest);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Application signature block is invalid.");
@@ -383,7 +388,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
}
/* Confirming if the public key in the bootloader's signature block matches with the one in the application's signature block */
if (memcmp(boot_pub_key_digest, app_pub_key_digest, ESP_SECURE_BOOT_DIGEST_LEN) != 0) {
if (memcmp(boot_pub_key_digest, app_pub_key_digest, DIGEST_LEN) != 0) {
ESP_LOGE(TAG, "Application not signed with a valid private key.");
return ESP_FAIL;
}

View File

@@ -0,0 +1,184 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp_spi_flash.h"
#include "esp_fault.h"
#include "esp32/rom/sha.h"
#include "uECC_verify_antifault.h"
#include <sys/param.h>
#include <string.h>
static const char *TAG = "secure_boot";
#define DIGEST_LEN 32
#ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
extern const uint8_t signature_verification_key_start[] asm("_binary_signature_verification_key_bin_start");
extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end");
#define SIGNATURE_VERIFICATION_KEYLEN 64
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[DIGEST_LEN];
uint8_t verified_digest[DIGEST_LEN] = { 0 }; /* ignored in this function */
const esp_secure_boot_sig_block_t *sigblock;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
esp_err_t err = bootloader_sha256_flash_contents(src_addr, length, digest);
if (err != ESP_OK) {
return err;
}
// Map the signature block
sigblock = (const esp_secure_boot_sig_block_t *) bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
if(!sigblock) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
return ESP_FAIL;
}
// Verify the signature
err = esp_secure_boot_verify_ecdsa_signature_block(sigblock, digest, verified_digest);
// Unmap
bootloader_munmap(sigblock);
return err;
}
esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest)
{
uint8_t verified_digest[DIGEST_LEN] = { 0 };
return esp_secure_boot_verify_ecdsa_signature_block(sig_block, image_digest, verified_digest);
}
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)
{
ptrdiff_t keylen;
keylen = signature_verification_key_end - signature_verification_key_start;
if (keylen != SIGNATURE_VERIFICATION_KEYLEN) {
ESP_LOGE(TAG, "Embedded public verification key has wrong length %d", keylen);
return ESP_FAIL;
}
if (sig_block->version != 0) {
ESP_LOGE(TAG, "image has invalid signature version field 0x%08x", sig_block->version);
return ESP_FAIL;
}
ESP_LOGD(TAG, "Verifying secure boot signature");
bool is_valid;
is_valid = uECC_verify_antifault(signature_verification_key_start,
image_digest,
DIGEST_LEN,
sig_block->signature,
uECC_secp256r1(),
verified_digest);
ESP_LOGD(TAG, "Verification result %d", is_valid);
return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID;
}
#elif CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[DIGEST_LEN] = {0};
uint8_t verified_digest[DIGEST_LEN] = {0}; // ignored in this function
const uint8_t *data;
/* Padding to round off the input to the nearest 4k boundary */
int padded_length = ALIGN_UP(length, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "verifying src_addr 0x%x length", src_addr, padded_length);
data = bootloader_mmap(src_addr, padded_length + sizeof(ets_secure_boot_signature_t));
if (data == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, padded_length);
return ESP_FAIL;
}
/* Calculate digest of main image */
esp_err_t err = bootloader_sha256_flash_contents(src_addr, padded_length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, padded_length);
bootloader_munmap(data);
return err;
}
const ets_secure_boot_signature_t *sig_block = (const ets_secure_boot_signature_t *)(data + padded_length);
err = esp_secure_boot_verify_rsa_signature_block(sig_block, digest, verified_digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Secure Boot V2 verification failed.");
}
bootloader_munmap(data);
return err;
}
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest)
{
secure_boot_v2_status_t r;
uint8_t efuse_trusted_digest[DIGEST_LEN] = {0}, sig_block_trusted_digest[DIGEST_LEN] = {0};
memcpy(efuse_trusted_digest, (uint8_t *)EFUSE_BLK2_RDATA0_REG, DIGEST_LEN); /* EFUSE_BLK2_RDATA0_REG - Stores the Secure Boot Public Key Digest */
if (!ets_use_secure_boot_v2()) {
ESP_LOGI(TAG, "Secure Boot eFuse bit(ABS_DONE_1) not yet programmed.");
/* Generating the SHA of the public key components in the signature block */
bootloader_sha256_handle_t sig_block_sha;
sig_block_sha = bootloader_sha256_start();
bootloader_sha256_data(sig_block_sha, &sig_block->block[0].key, sizeof(sig_block->block[0].key));
bootloader_sha256_finish(sig_block_sha, (unsigned char *)sig_block_trusted_digest);
#if CONFIG_SECURE_BOOT_V2_ENABLED
if (memcmp(efuse_trusted_digest, sig_block_trusted_digest, DIGEST_LEN) != 0) {
/* Most likely explanation for this is that BLK2 is empty, and we're going to burn it
after we verify that the signature is valid. However, if BLK2 is not empty then we need to
fail here.
*/
bool all_zeroes = true;
for (int i = 0; i < DIGEST_LEN; i++) {
all_zeroes = all_zeroes && (efuse_trusted_digest[i] == 0);
}
if (!all_zeroes) {
ESP_LOGE(TAG, "Different public key digest burned to eFuse BLK2");
return ESP_ERR_INVALID_STATE;
}
}
ESP_FAULT_ASSERT(!ets_use_secure_boot_v2());
#endif
memcpy(efuse_trusted_digest, sig_block_trusted_digest, DIGEST_LEN);
}
ESP_LOGI(TAG, "Verifying with RSA-PSS...");
r = ets_secure_boot_verify_signature(sig_block, image_digest, efuse_trusted_digest, verified_digest);
if (r != SBV2_SUCCESS) {
ESP_LOGE(TAG, "Secure Boot V2 verification failed.");
}
return (r == SBV2_SUCCESS) ? ESP_OK : ESP_ERR_IMAGE_INVALID;
}
#endif

View File

@@ -264,33 +264,24 @@ static void bootloader_super_wdt_auto_feed(void)
static inline void bootloader_hardware_init(void)
{
// This check is always included in the bootloader so it can
// print the minimum revision error message later in the boot
if (bootloader_common_get_chip_revision() < 3) {
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_IPH, 1);
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
}
// TODO ESP32-C3 IDF-2452
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_IPH, 1);
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
}
/* There happend clock glitch reset for some chip when testing wifi[BIT0] and brownout reset when chip startup[BIT1].
* But super_watch_dog_reset function is ok, so open it[BIT2].
* Whether this api will deleted or not depends on analog design & test result when ECO chip come back.
*/
static inline void bootloader_glitch_reset_disable(void)
{
/*
For origin chip & ECO1: only support swt reset;
For ECO2: fix brownout reset bug, support swt & brownout reset;
For ECO3: fix clock glitch reset bug, support all reset, include: swt & brownout & clock glitch reset.
*/
uint8_t chip_version = bootloader_common_get_chip_revision();
if (chip_version < 2) {
REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST);
} else if (chip_version == 2) {
REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST | RTC_CNTL_FIB_BOR_RST);
}
// TODO ESP32-C3 IDF-2453
REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, BIT2);
}
esp_err_t bootloader_init(void)
{
esp_err_t ret = ESP_OK;
bootloader_hardware_init();
bootloader_glitch_reset_disable();
bootloader_super_wdt_auto_feed();

View File

@@ -31,11 +31,17 @@
static const char *TAG = "secure_boot_v2";
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
#define SIG_BLOCK_MAGIC_BYTE 0xe7
#define CRC_SIGN_BLOCK_LEN 1196
#define SIG_BLOCK_PADDING 4096
#define DIGEST_LEN 32
/* A signature block is valid when it has correct magic byte, crc and image digest. */
static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
{
uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN);
if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
if (block->magic_byte != SIG_BLOCK_MAGIC_BYTE) {
// All signature blocks have been parsed, no new signature block present.
ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
return ESP_FAIL;
@@ -44,7 +50,7 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
return ESP_FAIL;
}
if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
if (memcmp(image_digest, block->image_digest, DIGEST_LEN)) {
ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
return ESP_FAIL;
} else {
@@ -55,6 +61,19 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
return ESP_FAIL;
}
/* 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.
Different to the ROM ets_secure_boot_key_digests_t structure which holds pointers to eFuse data with digests,
in this data structure the digest data is included.
*/
typedef struct {
uint8_t key_digests[SECURE_BOOT_NUM_BLOCKS][DIGEST_LEN];
unsigned num_digests; /* Number of valid digests, starting at index 0 */
} image_sig_public_key_digests_t;
/* Generates the public key digests of the valid public keys in an image's
signature block, verifies each signature, and stores the key digests in the
public_key_digests structure.
@@ -70,16 +89,16 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
@return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
- ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
*/
static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, image_sig_public_key_digests_t *public_key_digests)
{
esp_err_t ret;
uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t image_digest[DIGEST_LEN] = {0};
uint8_t __attribute__((aligned(4))) key_digest[DIGEST_LEN] = {0};
size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
bzero(public_key_digests, sizeof(image_sig_public_key_digests_t));
ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
if (ret != ESP_OK) {
@@ -110,7 +129,7 @@ static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uin
bootloader_sha256_finish(sig_block_sha, key_digest);
// Check we can verify the image using this signature and this key
uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
uint8_t temp_verified_digest[DIGEST_LEN];
bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
if (!verified) {
@@ -123,7 +142,7 @@ static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uin
}
ESP_LOGD(TAG, "Signature block (%d) is verified", i);
/* Copy the key digest to the buffer provided by the caller */
memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
memcpy((void *)public_key_digests->key_digests[i], key_digest, DIGEST_LEN);
public_key_digests->num_digests++;
}
@@ -154,8 +173,8 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
if (!has_secure_boot_digest) {
esp_image_sig_public_key_digests_t boot_key_digests = {0};
esp_image_sig_public_key_digests_t app_key_digests = {0};
image_sig_public_key_digests_t boot_key_digests = {0};
image_sig_public_key_digests_t app_key_digests = {0};
/* Generate the bootloader public key digests */
ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
@@ -215,7 +234,7 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
}
for (int j = 0; j < app_key_digests.num_digests; j++) {
if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN)) {
if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], DIGEST_LEN)) {
ESP_LOGI(TAG, "Application key(%d) matches with bootloader key(%d).", j, i);
match = true;
}

View File

@@ -0,0 +1,94 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include <string.h>
#include "esp_fault.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp32c3/rom/secure_boot.h"
static const char* TAG = "secure_boot";
#define DIGEST_LEN 32
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[DIGEST_LEN];
uint8_t verified_digest[DIGEST_LEN] = { 0 }; /* Note: this function doesn't do any anti-FI checks on this buffer */
const uint8_t *data;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
/* Padding to round off the input to the nearest 4k boundary */
int padded_length = ALIGN_UP(length, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "verifying src_addr 0x%x length", src_addr, padded_length);
data = bootloader_mmap(src_addr, length + sizeof(struct ets_secure_boot_sig_block));
if (data == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(ets_secure_boot_signature_t));
return ESP_FAIL;
}
/* Calculate digest of main image */
esp_err_t err = bootloader_sha256_flash_contents(src_addr, padded_length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, padded_length);
bootloader_munmap(data);
return err;
}
const ets_secure_boot_signature_t *sig = (const ets_secure_boot_signature_t *)(data + length);
int r = esp_secure_boot_verify_rsa_signature_block(sig, digest, verified_digest);
bootloader_munmap(data);
return (r == ETS_OK) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest)
{
ets_secure_boot_key_digests_t trusted_keys;
ets_secure_boot_key_digests_t trusted_key_copies[2];
ETS_STATUS r;
ets_secure_boot_status_t sb_result;
memset(&trusted_keys, 0, sizeof(ets_secure_boot_key_digests_t));
memset(trusted_key_copies, 0, 2 * sizeof(ets_secure_boot_key_digests_t));
if (!esp_secure_boot_enabled()) {
return ESP_OK;
}
r = ets_secure_boot_read_key_digests(&trusted_keys);
if (r != ETS_OK) {
ESP_LOGI(TAG, "Could not read secure boot digests!");
return ESP_FAIL;
}
// Create the copies for FI checks (assuming result is ETS_OK, if it's not then it'll fail the fault check anyhow)
ets_secure_boot_read_key_digests(&trusted_key_copies[0]);
ets_secure_boot_read_key_digests(&trusted_key_copies[1]);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[0], sizeof(ets_secure_boot_key_digests_t)) == 0);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[1], sizeof(ets_secure_boot_key_digests_t)) == 0);
ESP_LOGI(TAG, "Verifying with RSA-PSS boot...");
sb_result = ets_secure_boot_verify_signature(sig_block, image_digest, &trusted_keys, verified_digest);
return (sb_result == SB_SUCCESS) ? ESP_OK : ESP_FAIL;
}

View File

@@ -31,11 +31,17 @@
static const char *TAG = "secure_boot_v2";
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
#define SIG_BLOCK_MAGIC_BYTE 0xe7
#define CRC_SIGN_BLOCK_LEN 1196
#define SIG_BLOCK_PADDING 4096
#define DIGEST_LEN 32
/* A signature block is valid when it has correct magic byte, crc and image digest. */
static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
{
uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN);
if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
if (block->magic_byte != SIG_BLOCK_MAGIC_BYTE) {
// All signature blocks have been parsed, no new signature block present.
ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
return ESP_FAIL;
@@ -44,7 +50,7 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
return ESP_FAIL;
}
if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
if (memcmp(image_digest, block->image_digest, DIGEST_LEN)) {
ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
return ESP_FAIL;
} else {
@@ -55,6 +61,19 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
return ESP_FAIL;
}
/* 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.
Different to the ROM ets_secure_boot_key_digests_t structure which holds pointers to eFuse data with digests,
in this data structure the digest data is included.
*/
typedef struct {
uint8_t key_digests[SECURE_BOOT_NUM_BLOCKS][DIGEST_LEN];
unsigned num_digests; /* Number of valid digests, starting at index 0 */
} image_sig_public_key_digests_t;
/* Generates the public key digests of the valid public keys in an image's
signature block, verifies each signature, and stores the key digests in the
public_key_digests structure.
@@ -70,16 +89,16 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
@return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
- ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
*/
static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, image_sig_public_key_digests_t *public_key_digests)
{
esp_err_t ret;
uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t image_digest[DIGEST_LEN] = {0};
uint8_t __attribute__((aligned(4))) key_digest[DIGEST_LEN] = {0};
size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
bzero(public_key_digests, sizeof(image_sig_public_key_digests_t));
ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
if (ret != ESP_OK) {
@@ -110,7 +129,7 @@ static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uin
bootloader_sha256_finish(sig_block_sha, key_digest);
// Check we can verify the image using this signature and this key
uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
uint8_t temp_verified_digest[DIGEST_LEN];
bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
if (!verified) {
@@ -123,7 +142,7 @@ static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uin
}
ESP_LOGD(TAG, "Signature block (%d) is verified", i);
/* Copy the key digest to the buffer provided by the caller */
memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
memcpy((void *)public_key_digests->key_digests[i], key_digest, DIGEST_LEN);
public_key_digests->num_digests++;
}
@@ -154,8 +173,8 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
if (!has_secure_boot_digest) {
esp_image_sig_public_key_digests_t boot_key_digests = {0};
esp_image_sig_public_key_digests_t app_key_digests = {0};
image_sig_public_key_digests_t boot_key_digests = {0};
image_sig_public_key_digests_t app_key_digests = {0};
/* Generate the bootloader public key digests */
ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
@@ -215,7 +234,7 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
}
for (int j = 0; j < app_key_digests.num_digests; j++) {
if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN)) {
if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], DIGEST_LEN)) {
ESP_LOGI(TAG, "Application key(%d) matches with bootloader key(%d).", j, i);
match = true;
}

View File

@@ -0,0 +1,93 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include <string.h>
#include "esp_fault.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp32s2/rom/secure_boot.h"
static const char* TAG = "secure_boot";
#define DIGEST_LEN 32
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[DIGEST_LEN];
uint8_t verified_digest[DIGEST_LEN] = { 0 }; /* Note: this function doesn't do any anti-FI checks on this buffer */
const uint8_t *data;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
/* Padding to round off the input to the nearest 4k boundary */
int padded_length = ALIGN_UP(length, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "verifying src_addr 0x%x length", src_addr, padded_length);
data = bootloader_mmap(src_addr, length + sizeof(struct ets_secure_boot_sig_block));
if (data == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(ets_secure_boot_signature_t));
return ESP_FAIL;
}
/* Calculate digest of main image */
esp_err_t err = bootloader_sha256_flash_contents(src_addr, padded_length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, padded_length);
bootloader_munmap(data);
return err;
}
const ets_secure_boot_signature_t *sig = (const ets_secure_boot_signature_t *)(data + length);
int r = esp_secure_boot_verify_rsa_signature_block(sig, digest, verified_digest);
bootloader_munmap(data);
return (r == ETS_OK) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest)
{
ets_secure_boot_key_digests_t trusted_keys;
ets_secure_boot_key_digests_t trusted_key_copies[2];
ETS_STATUS r;
ets_secure_boot_status_t sb_result;
memset(&trusted_keys, 0, sizeof(ets_secure_boot_key_digests_t));
memset(trusted_key_copies, 0, 2 * sizeof(ets_secure_boot_key_digests_t));
if (!esp_secure_boot_enabled()) {
return ESP_OK;
}
r = ets_secure_boot_read_key_digests(&trusted_keys);
if (r != ETS_OK) {
ESP_LOGI(TAG, "Could not read secure boot digests!");
return ESP_FAIL;
}
// Create the copies for FI checks (assuming result is ETS_OK, if it's not then it'll fail the fault check anyhow)
ets_secure_boot_read_key_digests(&trusted_key_copies[0]);
ets_secure_boot_read_key_digests(&trusted_key_copies[1]);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[0], sizeof(ets_secure_boot_key_digests_t)) == 0);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[1], sizeof(ets_secure_boot_key_digests_t)) == 0);
ESP_LOGI(TAG, "Verifying with RSA-PSS boot...");
sb_result = ets_secure_boot_verify_signature(sig_block, image_digest, &trusted_keys, verified_digest);
return (sb_result == SB_SUCCESS) ? ESP_OK : ESP_FAIL;
}

View File

@@ -31,11 +31,17 @@
static const char *TAG = "secure_boot_v2";
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
#define SIG_BLOCK_MAGIC_BYTE 0xe7
#define CRC_SIGN_BLOCK_LEN 1196
#define SIG_BLOCK_PADDING 4096
#define DIGEST_LEN 32
/* A signature block is valid when it has correct magic byte, crc and image digest. */
static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
{
uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN);
if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
if (block->magic_byte != SIG_BLOCK_MAGIC_BYTE) {
// All signature blocks have been parsed, no new signature block present.
ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
return ESP_FAIL;
@@ -44,7 +50,7 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
return ESP_FAIL;
}
if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
if (memcmp(image_digest, block->image_digest, DIGEST_LEN)) {
ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
return ESP_FAIL;
} else {
@@ -55,6 +61,19 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
return ESP_FAIL;
}
/* 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.
Different to the ROM ets_secure_boot_key_digests_t structure which holds pointers to eFuse data with digests,
in this data structure the digest data is included.
*/
typedef struct {
uint8_t key_digests[SECURE_BOOT_NUM_BLOCKS][DIGEST_LEN];
unsigned num_digests; /* Number of valid digests, starting at index 0 */
} image_sig_public_key_digests_t;
/* Generates the public key digests of the valid public keys in an image's
signature block, verifies each signature, and stores the key digests in the
public_key_digests structure.
@@ -70,16 +89,16 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
@return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
- ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
*/
static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, image_sig_public_key_digests_t *public_key_digests)
{
esp_err_t ret;
uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t image_digest[DIGEST_LEN] = {0};
uint8_t __attribute__((aligned(4))) key_digest[DIGEST_LEN] = {0};
size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
bzero(public_key_digests, sizeof(image_sig_public_key_digests_t));
ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
if (ret != ESP_OK) {
@@ -110,7 +129,7 @@ static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uin
bootloader_sha256_finish(sig_block_sha, key_digest);
// Check we can verify the image using this signature and this key
uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
uint8_t temp_verified_digest[DIGEST_LEN];
bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
if (!verified) {
@@ -123,7 +142,7 @@ static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uin
}
ESP_LOGD(TAG, "Signature block (%d) is verified", i);
/* Copy the key digest to the buffer provided by the caller */
memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
memcpy((void *)public_key_digests->key_digests[i], key_digest, DIGEST_LEN);
public_key_digests->num_digests++;
}
@@ -154,8 +173,8 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
if (!has_secure_boot_digest) {
esp_image_sig_public_key_digests_t boot_key_digests = {0};
esp_image_sig_public_key_digests_t app_key_digests = {0};
image_sig_public_key_digests_t boot_key_digests = {0};
image_sig_public_key_digests_t app_key_digests = {0};
/* Generate the bootloader public key digests */
ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
@@ -215,7 +234,7 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
}
for (int j = 0; j < app_key_digests.num_digests; j++) {
if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN)) {
if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], DIGEST_LEN)) {
ESP_LOGI(TAG, "Application key(%d) matches with bootloader key(%d).", j, i);
match = true;
}

View File

@@ -0,0 +1,93 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "sdkconfig.h"
#include "esp_fault.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp32s3/rom/secure_boot.h"
static const char* TAG = "secure_boot";
#define DIGEST_LEN 32
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[DIGEST_LEN];
uint8_t verified_digest[DIGEST_LEN] = { 0 }; /* Note: this function doesn't do any anti-FI checks on this buffer */
const uint8_t *data;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
/* Padding to round off the input to the nearest 4k boundary */
int padded_length = ALIGN_UP(length, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "verifying src_addr 0x%x length", src_addr, padded_length);
data = bootloader_mmap(src_addr, length + sizeof(struct ets_secure_boot_sig_block));
if (data == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(ets_secure_boot_signature_t));
return ESP_FAIL;
}
/* Calculate digest of main image */
esp_err_t err = bootloader_sha256_flash_contents(src_addr, padded_length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, padded_length);
bootloader_munmap(data);
return err;
}
const ets_secure_boot_signature_t *sig = (const ets_secure_boot_signature_t *)(data + length);
int r = esp_secure_boot_verify_rsa_signature_block(sig, digest, verified_digest);
bootloader_munmap(data);
return (r == ETS_OK) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest)
{
ets_secure_boot_key_digests_t trusted_keys;
ets_secure_boot_key_digests_t trusted_key_copies[2];
ETS_STATUS r;
ets_secure_boot_status_t sb_result;
memset(&trusted_keys, 0, sizeof(ets_secure_boot_key_digests_t));
memset(trusted_key_copies, 0, 2 * sizeof(ets_secure_boot_key_digests_t));
if (!esp_secure_boot_enabled()) {
return ESP_OK;
}
r = ets_secure_boot_read_key_digests(&trusted_keys);
if (r != ETS_OK) {
ESP_LOGI(TAG, "Could not read secure boot digests!");
return ESP_FAIL;
}
// Create the copies for FI checks (assuming result is ETS_OK, if it's not then it'll fail the fault check anyhow)
ets_secure_boot_read_key_digests(&trusted_key_copies[0]);
ets_secure_boot_read_key_digests(&trusted_key_copies[1]);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[0], sizeof(ets_secure_boot_key_digests_t)) == 0);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[1], sizeof(ets_secure_boot_key_digests_t)) == 0);
ESP_LOGI(TAG, "Verifying with RSA-PSS boot...");
sb_result = ets_secure_boot_verify_signature(sig_block, image_digest, &trusted_keys, verified_digest);
return (sb_result == SB_SUCCESS) ? ESP_OK : ESP_FAIL;
}

View File

@@ -327,24 +327,11 @@ err:
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#if !defined(BOOTLOADER_BUILD)
return ESP_FAIL;
#ifdef BOOTLOADER_BUILD
return image_load(ESP_IMAGE_LOAD, part, data);
#else
esp_image_load_mode_t mode = ESP_IMAGE_LOAD;
#if !defined(CONFIG_SECURE_BOOT)
/* Skip validation under particular configurations */
#if CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS
mode = ESP_IMAGE_LOAD_NO_VALIDATE;
#elif CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
if (rtc_get_reset_reason(0) == POWERON_RESET) {
mode = ESP_IMAGE_LOAD_NO_VALIDATE;
}
#endif // CONFIG_BOOTLOADER_SKIP_...
#endif // CONFIG_SECURE_BOOT
return image_load(mode, part, data);
#endif // BOOTLOADER_BUILD
return ESP_FAIL;
#endif
}
esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data)
@@ -361,45 +348,6 @@ esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t
return image_load(mode, part, data);
}
esp_err_t esp_image_get_metadata(const esp_partition_pos_t *part, esp_image_metadata_t *metadata)
{
if (metadata == NULL || part == NULL || part->size > SIXTEEN_MB) {
return ESP_ERR_INVALID_ARG;
}
memset(metadata, 0, sizeof(esp_image_metadata_t));
metadata->start_addr = part->offset;
esp_err_t err = bootloader_flash_read(metadata->start_addr, &metadata->image, sizeof(esp_image_header_t), true);
if (err != ESP_OK) {
return err;
}
uint32_t next_addr = metadata->start_addr + sizeof(esp_image_header_t);
for (int i = 0; i < metadata->image.segment_count; i++) {
esp_image_segment_header_t *header = &metadata->segments[i];
err = process_segment(i, next_addr, header, true, false, NULL, NULL);
if (err != ESP_OK) {
return err;
}
next_addr += sizeof(esp_image_segment_header_t);
metadata->segment_data[i] = next_addr;
next_addr += header->data_len;
}
metadata->image_len = next_addr - metadata->start_addr;
// checksum
uint32_t unpadded_length = metadata->image_len;
uint32_t length = unpadded_length + 1; // Add a byte for the checksum
length = (length + 15) & ~15; // Pad to next full 16 byte block
if (metadata->image.hash_appended) {
// Account for the hash in the total image length
length += HASH_LEN;
}
metadata->image_len = length;
return ESP_OK;
}
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
{
esp_err_t err = ESP_OK;
@@ -860,18 +808,18 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han
// Use hash to verify signature block
esp_err_t err = ESP_ERR_IMAGE_INVALID;
#if defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) || defined(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME)
const void *sig_block;
ESP_FAULT_ASSERT(memcmp(image_digest, verified_digest, HASH_LEN) != 0); /* sanity check that these values start differently */
#ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
ESP_FAULT_ASSERT(memcmp(image_digest, verified_digest, HASH_LEN) != 0); /* sanity check that these values start differently */
sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t));
err = esp_secure_boot_verify_ecdsa_signature_block(sig_block, image_digest, verified_digest);
#else
#elif CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
ESP_FAULT_ASSERT(memcmp(image_digest, verified_digest, HASH_LEN) != 0); /* sanity check that these values start differently */
sig_block = bootloader_mmap(end, sizeof(ets_secure_boot_signature_t));
err = esp_secure_boot_verify_rsa_signature_block(sig_block, image_digest, verified_digest);
#endif
bootloader_munmap(sig_block);
#endif // CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME or CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
if (err != ESP_OK) {
ESP_LOGE(TAG, "Secure boot signature verification failed");

View File

@@ -0,0 +1,339 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "mbedtls/sha256.h"
#include "mbedtls/x509.h"
#include "mbedtls/md.h"
#include "mbedtls/platform.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include <string.h>
#include <sys/param.h>
#include "esp_secure_boot.h"
#ifdef CONFIG_IDF_TARGET_ESP32S2
#include <esp32s2/rom/secure_boot.h>
#elif CONFIG_IDF_TARGET_ESP32C3
#include <esp32c3/rom/secure_boot.h>
#endif
#define DIGEST_LEN 32
#ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
static const char *TAG = "secure_boot_v1";
extern const uint8_t signature_verification_key_start[] asm("_binary_signature_verification_key_bin_start");
extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end");
#define SIGNATURE_VERIFICATION_KEYLEN 64
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[DIGEST_LEN];
uint8_t verified_digest[DIGEST_LEN];
const esp_secure_boot_sig_block_t *sigblock;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
esp_err_t err = bootloader_sha256_flash_contents(src_addr, length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, length);
return err;
}
// Map the signature block and verify the signature
sigblock = (const esp_secure_boot_sig_block_t *)bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
if (sigblock == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
return ESP_FAIL;
}
err = esp_secure_boot_verify_ecdsa_signature_block(sigblock, digest, verified_digest);
bootloader_munmap(sigblock);
return err;
}
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 !(defined(CONFIG_MBEDTLS_ECDSA_C) && defined(CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED))
ESP_LOGE(TAG, "Signature verification requires ECDSA & SECP256R1 curve enabled");
return ESP_ERR_NOT_SUPPORTED;
#else
ptrdiff_t keylen;
/* Note: in IDF app image verification we don't add any fault injection resistance, boot-time checks only */
memset(verified_digest, 0, DIGEST_LEN);
keylen = signature_verification_key_end - signature_verification_key_start;
if (keylen != SIGNATURE_VERIFICATION_KEYLEN) {
ESP_LOGE(TAG, "Embedded public verification key has wrong length %d", keylen);
return ESP_FAIL;
}
if (sig_block->version != 0) {
ESP_LOGE(TAG, "image has invalid signature version field 0x%08x", sig_block->version);
return ESP_FAIL;
}
ESP_LOGD(TAG, "Verifying secure boot signature");
int ret;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
/* Extract r and s components from RAW ECDSA signature of 64 bytes */
#define ECDSA_INTEGER_LEN 32
ret = mbedtls_mpi_read_binary(&r, &sig_block->signature[0], ECDSA_INTEGER_LEN);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(1), err:%d", ret);
return ESP_FAIL;
}
ret = mbedtls_mpi_read_binary(&s, &sig_block->signature[ECDSA_INTEGER_LEN], ECDSA_INTEGER_LEN);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(2), err:%d", ret);
mbedtls_mpi_free(&r);
return ESP_FAIL;
}
/* Initialise ECDSA context */
mbedtls_ecdsa_context ecdsa_context;
mbedtls_ecdsa_init(&ecdsa_context);
mbedtls_ecp_group_load(&ecdsa_context.grp, MBEDTLS_ECP_DP_SECP256R1);
size_t plen = mbedtls_mpi_size(&ecdsa_context.grp.P);
if (keylen != 2 * plen) {
ESP_LOGE(TAG, "Incorrect ECDSA key length %d", keylen);
ret = ESP_FAIL;
goto cleanup;
}
/* Extract X and Y components from ECDSA public key */
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.Q.X, signature_verification_key_start, plen));
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.Q.Y, signature_verification_key_start + plen, plen));
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ecdsa_context.Q.Z, 1));
ret = mbedtls_ecdsa_verify(&ecdsa_context.grp, image_digest, DIGEST_LEN, &ecdsa_context.Q, &r, &s);
ESP_LOGD(TAG, "Verification result %d", ret);
cleanup:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa_context);
return ret == 0 ? ESP_OK : ESP_ERR_IMAGE_INVALID;
#endif // CONFIG_MBEDTLS_ECDSA_C && CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED
}
#elif CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
static const char *TAG = "secure_boot_v2";
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
#define RSA_KEY_SIZE 384 /* RSA 3072 Bits */
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1
inline static bool digest_matches(const void *trusted, const void *computed)
{
if (trusted == NULL) {
return false;
}
// 'trusted' is probably a pointer to read-only efuse registers,
// which only support word reads. memcmp() cannot be guaranteed
// to do word reads, so we make a local copy here (we know that
// memcpy() will do word operations if it can).
uint8_t __attribute__((aligned(4))) trusted_local[ETS_DIGEST_LEN];
uint8_t __attribute__((aligned(4))) computed_local[ETS_DIGEST_LEN];
memcpy(trusted_local, trusted, ETS_DIGEST_LEN);
memcpy(computed_local, computed, ETS_DIGEST_LEN);
return memcmp(trusted_local, computed_local, ETS_DIGEST_LEN) == 0;
}
#endif /* SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 */
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[DIGEST_LEN] = {0};
uint8_t verified_digest[DIGEST_LEN] = {0};
/* Rounding off length to the upper 4k boundary */
uint32_t padded_length = ALIGN_UP(length, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
esp_err_t err = bootloader_sha256_flash_contents(src_addr, padded_length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, padded_length);
return err;
}
const ets_secure_boot_signature_t *sig_block = bootloader_mmap(src_addr + padded_length, sizeof(ets_secure_boot_signature_t));
if (sig_block == NULL) {
ESP_LOGE(TAG, "Failed to mmap data at offset 0x%x", src_addr + padded_length);
return ESP_FAIL;
}
err = esp_secure_boot_verify_rsa_signature_block(sig_block, digest, verified_digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Secure Boot V2 verification failed.");
}
bootloader_munmap(sig_block);
return err;
}
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest)
{
uint8_t i = 0;
#if CONFIG_SECURE_BOOT_V2_ENABLED /* Verify key against efuse block */
uint8_t sig_block_key_digest[SECURE_BOOT_NUM_BLOCKS][DIGEST_LEN] = {0};
/* Note: in IDF verification we don't add any fault injection resistance, as we don't expect this to be called
during boot-time verification. */
memset(verified_digest, 0, DIGEST_LEN);
/* Generating the SHA of the public key components in the signature block */
for (i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
bootloader_sha256_handle_t sig_block_sha;
sig_block_sha = bootloader_sha256_start();
bootloader_sha256_data(sig_block_sha, &sig_block->block[i].key, sizeof(sig_block->block[i].key));
bootloader_sha256_finish(sig_block_sha, (unsigned char *)sig_block_key_digest[i]);
}
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == 1
uint8_t efuse_trusted_digest[DIGEST_LEN] = {0};
memcpy(efuse_trusted_digest, (uint8_t *) EFUSE_BLK2_RDATA0_REG, sizeof(efuse_trusted_digest));
if (memcmp(efuse_trusted_digest, sig_block_key_digest[0], DIGEST_LEN) != 0) {
const uint8_t zeroes[DIGEST_LEN] = {0};
/* Can't continue if secure boot is enabled, OR if a different digest is already written in efuse BLK2
(If BLK2 is empty and Secure Boot is disabled then we assume that it will be enabled later.)
*/
if (esp_secure_boot_enabled() || memcmp(efuse_trusted_digest, zeroes, DIGEST_LEN) != 0) {
ESP_LOGE(TAG, "Public key digest in eFuse BLK2 and the signature block don't match.");
return ESP_FAIL;
}
}
#elif SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1
bool match = false;
ets_secure_boot_key_digests_t efuse_trusted_digest;
ETS_STATUS r;
r = ets_secure_boot_read_key_digests(&efuse_trusted_digest);
if (r != 0) {
ESP_LOGI(TAG, "Could not read secure boot digests!");
return ESP_FAIL;
}
#endif /* SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS */
#endif /* CONFIG_SECURE_BOOT_V2_ENABLED */
ESP_LOGI(TAG, "Verifying with RSA-PSS...");
int ret = 0;
mbedtls_rsa_context pk;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
unsigned char *sig_be = calloc(1, RSA_KEY_SIZE);
unsigned char *buf = calloc(1, RSA_KEY_SIZE);
if (sig_be == NULL || buf == NULL) {
return ESP_ERR_NO_MEM;
}
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x\n", ret);
goto exit;
}
for (i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1
for (uint8_t j = 0; j < SECURE_BOOT_NUM_BLOCKS; j++) {
if (digest_matches(efuse_trusted_digest.key_digests[j], sig_block_key_digest[i])) {
ESP_LOGI(TAG, "eFuse key matches(%d) matches the application key(%d).", j, i);
match = true;
break;
}
}
if (match == false) {
continue; // Skip the public keys whose digests don't match.
}
# endif // SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1
const mbedtls_mpi N = { .s = 1,
.n = sizeof(sig_block->block[i].key.n)/sizeof(mbedtls_mpi_uint),
.p = (void *)sig_block->block[i].key.n,
};
const mbedtls_mpi e = { .s = 1,
.n = sizeof(sig_block->block[i].key.e)/sizeof(mbedtls_mpi_uint), // 1
.p = (void *)&sig_block->block[i].key.e,
};
mbedtls_rsa_init(&pk, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
ret = mbedtls_rsa_import(&pk, &N, NULL, NULL, NULL, &e);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_rsa_import, err: %d", ret);
goto exit;
}
ret = mbedtls_rsa_complete(&pk);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_rsa_complete, err: %d", ret);
goto exit;
}
ret = mbedtls_rsa_check_pubkey(&pk);
if (ret != 0) {
ESP_LOGI(TAG, "Key is not an RSA key -%0x", -ret);
goto exit;
}
/* Signature needs to be byte swapped into BE representation */
for (int j = 0; j < RSA_KEY_SIZE; j++) {
sig_be[RSA_KEY_SIZE- j - 1] = sig_block->block[i].signature[j];
}
ret = mbedtls_rsa_public( &pk, sig_be, buf);
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_rsa_public failed, err: %d", ret);
goto exit;
}
ret = mbedtls_rsa_rsassa_pss_verify( &pk, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, DIGEST_LEN,
image_digest, sig_be);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_rsa_rsassa_pss_verify, err: %d", ret);
} else {
ESP_LOGI(TAG, "Signature verified successfully!");
}
exit:
mbedtls_rsa_free(&pk);
if (ret == 0) {
break;
}
}
free(sig_be);
free(buf);
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == 1
return (ret != 0) ? ESP_ERR_IMAGE_INVALID: ESP_OK;
#elif SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1
return (ret != 0 || match == false) ? ESP_ERR_IMAGE_INVALID: ESP_OK;
#endif /* CONFIG_IDF_TARGET_ESP32 */
}
#endif

View File

@@ -1,57 +0,0 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <strings.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_secure_boot.h"
#ifndef BOOTLOADER_BUILD
static __attribute__((unused)) const char *TAG = "secure_boot";
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
static void rsa_check_signature_on_update_check(void)
{
// We rely on the keys used to sign this app to verify the next app on OTA, so make sure there is at
// least one to avoid a stuck firmware
esp_image_sig_public_key_digests_t digests = { 0 };
esp_err_t err = esp_secure_boot_get_signature_blocks_for_running_app(false, &digests);
if (err != ESP_OK || digests.num_digests == 0) {
ESP_LOGE(TAG, "This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update.");
abort();
}
#if CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT && SECURE_BOOT_NUM_BLOCKS > 1
if (digests.num_digests > 1) {
ESP_LOGW(TAG, "App has %d signatures. Only the first position of signature blocks is used to verify any update", digests.num_digests);
}
#endif
}
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
void esp_secure_boot_init_checks(void)
{
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
rsa_check_signature_on_update_check();
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
}
#endif // not BOOTLOADER_BUILD

View File

@@ -1,136 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "mbedtls/sha256.h"
#include "mbedtls/x509.h"
#include "mbedtls/md.h"
#include "mbedtls/platform.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include <string.h>
#include <sys/param.h>
#ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
static const char *TAG = "secure_boot_v1";
extern const uint8_t signature_verification_key_start[] asm("_binary_signature_verification_key_bin_start");
extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end");
#define SIGNATURE_VERIFICATION_KEYLEN 64
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[ESP_SECURE_BOOT_DIGEST_LEN];
uint8_t verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
const esp_secure_boot_sig_block_t *sigblock;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
esp_err_t err = bootloader_sha256_flash_contents(src_addr, length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, length);
return err;
}
// Map the signature block and verify the signature
sigblock = (const esp_secure_boot_sig_block_t *)bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
if (sigblock == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
return ESP_FAIL;
}
err = esp_secure_boot_verify_ecdsa_signature_block(sigblock, digest, verified_digest);
bootloader_munmap(sigblock);
return err;
}
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 !(defined(CONFIG_MBEDTLS_ECDSA_C) && defined(CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED))
ESP_LOGE(TAG, "Signature verification requires ECDSA & SECP256R1 curve enabled");
return ESP_ERR_NOT_SUPPORTED;
#else
ptrdiff_t keylen;
/* Note: in IDF app image verification we don't add any fault injection resistance, boot-time checks only */
memset(verified_digest, 0, ESP_SECURE_BOOT_DIGEST_LEN);
keylen = signature_verification_key_end - signature_verification_key_start;
if (keylen != SIGNATURE_VERIFICATION_KEYLEN) {
ESP_LOGE(TAG, "Embedded public verification key has wrong length %d", keylen);
return ESP_FAIL;
}
if (sig_block->version != 0) {
ESP_LOGE(TAG, "image has invalid signature version field 0x%08x", sig_block->version);
return ESP_FAIL;
}
ESP_LOGD(TAG, "Verifying secure boot signature");
int ret;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
/* Extract r and s components from RAW ECDSA signature of 64 bytes */
#define ECDSA_INTEGER_LEN 32
ret = mbedtls_mpi_read_binary(&r, &sig_block->signature[0], ECDSA_INTEGER_LEN);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(1), err:%d", ret);
return ESP_FAIL;
}
ret = mbedtls_mpi_read_binary(&s, &sig_block->signature[ECDSA_INTEGER_LEN], ECDSA_INTEGER_LEN);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(2), err:%d", ret);
mbedtls_mpi_free(&r);
return ESP_FAIL;
}
/* Initialise ECDSA context */
mbedtls_ecdsa_context ecdsa_context;
mbedtls_ecdsa_init(&ecdsa_context);
mbedtls_ecp_group_load(&ecdsa_context.grp, MBEDTLS_ECP_DP_SECP256R1);
size_t plen = mbedtls_mpi_size(&ecdsa_context.grp.P);
if (keylen != 2 * plen) {
ESP_LOGE(TAG, "Incorrect ECDSA key length %d", keylen);
ret = ESP_FAIL;
goto cleanup;
}
/* Extract X and Y components from ECDSA public key */
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.Q.X, signature_verification_key_start, plen));
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.Q.Y, signature_verification_key_start + plen, plen));
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ecdsa_context.Q.Z, 1));
ret = mbedtls_ecdsa_verify(&ecdsa_context.grp, image_digest, ESP_SECURE_BOOT_DIGEST_LEN, &ecdsa_context.Q, &r, &s);
ESP_LOGD(TAG, "Verification result %d", ret);
cleanup:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa_context);
return ret == 0 ? ESP_OK : ESP_ERR_IMAGE_INVALID;
#endif // CONFIG_MBEDTLS_ECDSA_C && CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED
}
#endif // CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME

View File

@@ -1,100 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp_spi_flash.h"
#include "esp_fault.h"
#include "esp32/rom/sha.h"
#include "uECC_verify_antifault.h"
#include <sys/param.h>
#include <string.h>
static const char *TAG = "secure_boot";
#ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
extern const uint8_t signature_verification_key_start[] asm("_binary_signature_verification_key_bin_start");
extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end");
#define SIGNATURE_VERIFICATION_KEYLEN 64
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[ESP_SECURE_BOOT_DIGEST_LEN];
uint8_t verified_digest[ESP_SECURE_BOOT_DIGEST_LEN] = { 0 }; /* ignored in this function */
const esp_secure_boot_sig_block_t *sigblock;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
esp_err_t err = bootloader_sha256_flash_contents(src_addr, length, digest);
if (err != ESP_OK) {
return err;
}
// Map the signature block
sigblock = (const esp_secure_boot_sig_block_t *) bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
if(!sigblock) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
return ESP_FAIL;
}
// Verify the signature
err = esp_secure_boot_verify_ecdsa_signature_block(sigblock, digest, verified_digest);
// Unmap
bootloader_munmap(sigblock);
return err;
}
esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest)
{
uint8_t verified_digest[ESP_SECURE_BOOT_DIGEST_LEN] = { 0 };
return esp_secure_boot_verify_ecdsa_signature_block(sig_block, image_digest, verified_digest);
}
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)
{
ptrdiff_t keylen;
keylen = signature_verification_key_end - signature_verification_key_start;
if (keylen != SIGNATURE_VERIFICATION_KEYLEN) {
ESP_LOGE(TAG, "Embedded public verification key has wrong length %d", keylen);
return ESP_FAIL;
}
if (sig_block->version != 0) {
ESP_LOGE(TAG, "image has invalid signature version field 0x%08x", sig_block->version);
return ESP_FAIL;
}
ESP_LOGD(TAG, "Verifying secure boot signature");
bool is_valid;
is_valid = uECC_verify_antifault(signature_verification_key_start,
image_digest,
ESP_SECURE_BOOT_DIGEST_LEN,
sig_block->signature,
uECC_secp256r1(),
verified_digest);
ESP_LOGD(TAG, "Verification result %d", is_valid);
return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID;
}
#endif // CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME

View File

@@ -1,294 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "mbedtls/sha256.h"
#include "mbedtls/x509.h"
#include "mbedtls/md.h"
#include "mbedtls/platform.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include <string.h>
#include <sys/param.h>
#include "esp_secure_boot.h"
#include "esp_ota_ops.h"
// Secure boot V2 for app
_Static_assert(SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == SECURE_BOOT_NUM_BLOCKS,
"Parts of this code rely on the max number of signatures appended to an image"
"being the same as the max number of trusted keys.");
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
static const char *TAG = "secure_boot_v2";
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
/* A signature block is valid when it has correct magic byte, crc. */
static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block)
{
if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC
|| block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) {
return ESP_FAIL;
}
return ESP_OK;
}
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)
{
esp_image_metadata_t metadata;
const esp_partition_t* running_app_part = esp_ota_get_running_partition();
if (running_app_part == NULL) {
ESP_LOGE(TAG, "Cannot get running partition");
return ESP_FAIL;
}
const esp_partition_pos_t part_pos = {
.offset = running_app_part->address,
.size = running_app_part->size,
};
esp_err_t err = esp_image_get_metadata(&part_pos, &metadata);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error reading metadata from running app (err=0x%x)", err);
return ESP_FAIL;
}
memset(public_key_digests, 0, sizeof(esp_image_sig_public_key_digests_t));
// Generating the SHA of the public key components in the signature block
// metadata.image_len doesn't include any padding to start of the signature sector, so pad it here
size_t sig_block_addr = metadata.start_addr + ALIGN_UP(metadata.image_len, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "reading signatures for app address 0x%x sig block address 0x%x", part_pos.offset, sig_block_addr);
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
ets_secure_boot_sig_block_t block;
size_t addr = sig_block_addr + sizeof(ets_secure_boot_sig_block_t) * i;
esp_err_t err = bootloader_flash_read(addr, &block, sizeof(ets_secure_boot_sig_block_t), true);
if (err == ESP_OK) {
if (validate_signature_block(&block) == ESP_OK) {
if (digest_public_keys) {
bootloader_sha256_handle_t sig_block_sha = bootloader_sha256_start();
bootloader_sha256_data(sig_block_sha, &block.key, sizeof(block.key));
bootloader_sha256_finish(sig_block_sha, public_key_digests->key_digests[i]);
}
public_key_digests->num_digests++;
}
} else {
ESP_LOGE(TAG, "Secure boot sign blocks cannot be read from a running app (err=0x%x)", err);
return ESP_FAIL;
}
}
if (public_key_digests->num_digests > 0) {
return ESP_OK;
}
ESP_LOGE(TAG, "No signatures were found for the running app");
return ESP_ERR_NOT_FOUND;
}
static esp_err_t get_secure_boot_key_digests(esp_image_sig_public_key_digests_t *public_key_digests)
{
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
// Gets key digests from running app
ESP_LOGI(TAG, "Take trusted digest key(s) from running app");
return esp_secure_boot_get_signature_blocks_for_running_app(true, public_key_digests);
#elif CONFIG_SECURE_BOOT_V2_ENABLED
ESP_LOGI(TAG, "Take trusted digest key(s) from eFuse block(s)");
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1
// Read key digests from efuse
ets_secure_boot_key_digests_t efuse_trusted;
if (ets_secure_boot_read_key_digests(&efuse_trusted) == ETS_OK) {
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
if (efuse_trusted.key_digests[i] != NULL) {
memcpy(public_key_digests->key_digests[i], (uint8_t *)efuse_trusted.key_digests[i], ESP_SECURE_BOOT_DIGEST_LEN);
public_key_digests->num_digests++;
}
}
}
if (public_key_digests->num_digests > 0) {
return ESP_OK;
}
return ESP_ERR_NOT_FOUND;
#else
memcpy(public_key_digests->key_digests[0], (uint8_t *)EFUSE_BLK2_RDATA0_REG, ESP_SECURE_BOOT_DIGEST_LEN);
public_key_digests->num_digests = 1;
return ESP_OK;
#endif // SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS
#endif // CONFIG_SECURE_BOOT_V2_ENABLED
}
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t verified_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
/* Rounding off length to the upper 4k boundary */
uint32_t padded_length = ALIGN_UP(length, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
esp_err_t err = bootloader_sha256_flash_contents(src_addr, padded_length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, padded_length);
return err;
}
const ets_secure_boot_signature_t *sig_block = bootloader_mmap(src_addr + padded_length, sizeof(ets_secure_boot_signature_t));
if (sig_block == NULL) {
ESP_LOGE(TAG, "Failed to mmap data at offset 0x%x", src_addr + padded_length);
return ESP_FAIL;
}
err = esp_secure_boot_verify_rsa_signature_block(sig_block, digest, verified_digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Secure Boot V2 verification failed.");
}
bootloader_munmap(sig_block);
return err;
}
// This verify function is called only from app, during ota update.
// This function is compiled in case when CONFIG_SECURE_BOOT_V2_ENABLED==y or CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT==y.
// if CONFIG_SECURE_BOOT_V2_ENABLED==y and key digests from eFuse are missing, then FAIL (eFuse blocks should be set).
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest)
{
bool any_trusted_key = false;
/* Note: in IDF verification we don't add any fault injection resistance, as we don't expect this to be called
during boot-time verification. */
memset(verified_digest, 0, ESP_SECURE_BOOT_DIGEST_LEN);
esp_image_sig_public_key_digests_t trusted = {0};
if (get_secure_boot_key_digests(&trusted) != ESP_OK) {
ESP_LOGE(TAG, "Could not read secure boot digests!");
return ESP_FAIL;
}
int ret = 0;
mbedtls_rsa_context pk;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const unsigned rsa_key_size = sizeof(sig_block->block[0].signature);
unsigned char *sig_be = calloc(1, rsa_key_size);
unsigned char *buf = calloc(1, rsa_key_size);
if (sig_be == NULL || buf == NULL) {
return ESP_ERR_NO_MEM;
}
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x\n", ret);
goto exit;
}
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
const unsigned secure_boot_num_blocks = 1;
#else
const unsigned secure_boot_num_blocks = SECURE_BOOT_NUM_BLOCKS;
#endif
for (unsigned app_blk_idx = 0; app_blk_idx < secure_boot_num_blocks; app_blk_idx++) {
uint8_t app_blk_digest[ESP_SECURE_BOOT_DIGEST_LEN] = { 0 };
const ets_secure_boot_sig_block_t *app_blk = &sig_block->block[app_blk_idx];
const ets_secure_boot_sig_block_t *trusted_block = NULL;
if (validate_signature_block(app_blk) != ESP_OK) {
continue; // Skip invalid signature blocks
}
/* Generate the SHA of the public key components in the signature block */
bootloader_sha256_handle_t sig_block_sha = bootloader_sha256_start();
bootloader_sha256_data(sig_block_sha, &app_blk->key, sizeof(app_blk->key));
bootloader_sha256_finish(sig_block_sha, app_blk_digest);
/* Check if the key is one we trust */
for (unsigned trusted_key_idx = 0; trusted_key_idx < secure_boot_num_blocks; trusted_key_idx++) {
if (memcmp(app_blk_digest, trusted.key_digests[trusted_key_idx], ESP_SECURE_BOOT_DIGEST_LEN) == 0) {
ESP_LOGI(TAG, "#%d app key digest == #%d trusted key digest", app_blk_idx, trusted_key_idx);
trusted_block = app_blk;
any_trusted_key = true;
break;
}
ESP_LOGV(TAG, "not trusting app sig %d trust idx %d", app_blk_idx, trusted_key_idx);
}
if (trusted_block == NULL) {
continue; // Skip the signature blocks with no trusted digest
}
ESP_LOGI(TAG, "Verifying with RSA-PSS...");
const mbedtls_mpi N = { .s = 1,
.n = sizeof(trusted_block->key.n)/sizeof(mbedtls_mpi_uint),
.p = (void *)trusted_block->key.n,
};
const mbedtls_mpi e = { .s = 1,
.n = sizeof(trusted_block->key.e)/sizeof(mbedtls_mpi_uint), // 1
.p = (void *)&trusted_block->key.e,
};
mbedtls_rsa_init(&pk, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
ret = mbedtls_rsa_import(&pk, &N, NULL, NULL, NULL, &e);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_rsa_import, err: %d", ret);
goto exit;
}
ret = mbedtls_rsa_complete(&pk);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_rsa_complete, err: %d", ret);
goto exit;
}
ret = mbedtls_rsa_check_pubkey(&pk);
if (ret != 0) {
ESP_LOGI(TAG, "Key is not an RSA key -%0x", -ret);
goto exit;
}
/* Signature needs to be byte swapped into BE representation */
for (int j = 0; j < rsa_key_size; j++) {
sig_be[rsa_key_size - j - 1] = trusted_block->signature[j];
}
ret = mbedtls_rsa_public( &pk, sig_be, buf);
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_rsa_public failed, err: %d", ret);
goto exit;
}
ret = mbedtls_rsa_rsassa_pss_verify( &pk, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, ESP_SECURE_BOOT_DIGEST_LEN,
image_digest, sig_be);
if (ret != 0) {
ESP_LOGE(TAG, "Failed mbedtls_rsa_rsassa_pss_verify, err: %d", ret);
} else {
ESP_LOGI(TAG, "Signature verified successfully!");
}
exit:
mbedtls_rsa_free(&pk);
if (ret == 0) {
break;
}
}
free(sig_be);
free(buf);
return (ret != 0 || any_trusted_key == false) ? ESP_ERR_IMAGE_INVALID: ESP_OK;
}
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT

View File

@@ -1,172 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include <string.h>
#include "esp_fault.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
// Secure boot V2 for bootloader.
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_BOOT_V2_ENABLED
static const char* TAG = "secure_boot_v2";
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
uint8_t digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t verified_digest[ESP_SECURE_BOOT_DIGEST_LEN] = { 0 }; /* Note: this function doesn't do any anti-FI checks on this buffer */
/* Rounding off length to the upper 4k boundary */
uint32_t padded_length = ALIGN_UP(length, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
/* Calculate digest of main image */
esp_err_t err = bootloader_sha256_flash_contents(src_addr, padded_length, digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Digest calculation failed 0x%x, 0x%x", src_addr, padded_length);
return err;
}
const ets_secure_boot_signature_t *sig_block = bootloader_mmap(src_addr + padded_length, sizeof(ets_secure_boot_signature_t));
if (sig_block == NULL) {
ESP_LOGE(TAG, "Failed to mmap data at offset 0x%x", src_addr + padded_length);
return ESP_FAIL;
}
err = esp_secure_boot_verify_rsa_signature_block(sig_block, digest, verified_digest);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Secure Boot V2 verification failed.");
}
bootloader_munmap(sig_block);
return err;
}
/* A signature block is valid when it has correct magic byte, crc. */
static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block)
{
if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC
|| block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) {
return ESP_FAIL;
}
return ESP_OK;
}
static esp_err_t get_secure_boot_key_digests(esp_image_sig_public_key_digests_t *public_key_digests)
{
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1
// Read key digests from efuse
ets_secure_boot_key_digests_t trusted_keys;
ets_secure_boot_key_digests_t trusted_key_copies[2];
ETS_STATUS ets_ret;
memset(&trusted_keys, 0, sizeof(ets_secure_boot_key_digests_t));
memset(trusted_key_copies, 0, 2 * sizeof(ets_secure_boot_key_digests_t));
ets_ret = ets_secure_boot_read_key_digests(&trusted_keys);
// Create the copies for FI checks (assuming result is ETS_OK, if it's not then it'll fail the fault check anyhow)
ets_secure_boot_read_key_digests(&trusted_key_copies[0]);
ets_secure_boot_read_key_digests(&trusted_key_copies[1]);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[0], sizeof(ets_secure_boot_key_digests_t)) == 0);
ESP_FAULT_ASSERT(memcmp(&trusted_keys, &trusted_key_copies[1], sizeof(ets_secure_boot_key_digests_t)) == 0);
if (ets_ret == ETS_OK) {
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
if (trusted_keys.key_digests[i] != NULL) {
memcpy(public_key_digests->key_digests[i], (uint8_t *)trusted_keys.key_digests[i], ESP_SECURE_BOOT_DIGEST_LEN);
public_key_digests->num_digests++;
}
}
if (public_key_digests->num_digests > 0) {
return ESP_OK;
}
}
return ESP_ERR_NOT_FOUND;
#else
bool all_zeroes = true;
uint32_t *reg = (uint32_t*)&public_key_digests->key_digests[0];
for (int i = 0; i < ESP_SECURE_BOOT_DIGEST_LEN / 4; i++) {
*(reg + i) = REG_READ(EFUSE_BLK2_RDATA0_REG + i * 4);
all_zeroes = all_zeroes && (*(reg + i) == 0);
}
if (all_zeroes) {
return ESP_ERR_NOT_FOUND;
}
public_key_digests->num_digests = 1;
return ESP_OK;
#endif // SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS
}
// if CONFIG_SECURE_BOOT_V2_ENABLED==y and key digests from eFuse are missing, then it is the first boot,
// trusted.key_digests are filled from app sig_block.
esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest)
{
esp_image_sig_public_key_digests_t trusted = {0};
bool efuse_keys_are_not_set = false;
if (get_secure_boot_key_digests(&trusted) != ESP_OK) {
if (esp_secure_boot_enabled()) {
ESP_LOGE(TAG, "Could not read eFuse secure boot digests!");
return ESP_FAIL;
} else {
ESP_LOGI(TAG, "Secure boot V2 is not enabled yet and eFuse digest keys are not set");
efuse_keys_are_not_set = true;
ESP_FAULT_ASSERT(!esp_secure_boot_enabled());
}
}
if (!esp_secure_boot_enabled()) {
// It is the first boot. eFuse secure boot bit is not set yet. eFuse block(s) can be written or not.
// Generating the SHA of the public key components in the signature block
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
if (validate_signature_block(&sig_block->block[i]) == ESP_OK) {
if (efuse_keys_are_not_set) {
// if efuse key digests are not in eFuse yet due to it is the first boot
// then use digests from app to skip error in ets_secure_boot_verify_signature().
bootloader_sha256_handle_t sig_block_sha = bootloader_sha256_start();
bootloader_sha256_data(sig_block_sha, &sig_block->block[i].key, sizeof(sig_block->block[i].key));
bootloader_sha256_finish(sig_block_sha, trusted.key_digests[i]);
}
}
}
ESP_FAULT_ASSERT(!esp_secure_boot_enabled());
}
ESP_LOGI(TAG, "Verifying with RSA-PSS...");
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == 1
int sb_result = ets_secure_boot_verify_signature(sig_block, image_digest, trusted.key_digests[0], verified_digest);
#else
ets_secure_boot_key_digests_t trusted_key_digests;
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
trusted_key_digests.key_digests[i] = &trusted.key_digests[i];
}
int sb_result = ets_secure_boot_verify_signature(sig_block, image_digest, &trusted_key_digests, verified_digest);
#endif
if (sb_result != SB_SUCCESS) {
ESP_LOGE(TAG, "Secure Boot V2 verification failed.");
return ESP_ERR_IMAGE_INVALID;
} else {
ESP_LOGI(TAG, "Signature verified successfully!");
return ESP_OK;
}
}
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_BOOT_V2_ENABLED

View File

@@ -589,15 +589,13 @@ idf_component_register(SRCS "${srcs}"
if(CONFIG_BT_ENABLED)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
if(CONFIG_IDF_TARGET_ESP32)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32/esp32")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib/esp32")
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
elseif(CONFIG_IDF_TARGET_ESP32C3)
target_link_libraries(${COMPONENT_LIB} INTERFACE
"-L${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32c3")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib/esp32c3")
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app btbb)
elseif(CONFIG_IDF_TARGET_ESP32S3)
target_link_libraries(${COMPONENT_LIB} INTERFACE
"-L${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32s3")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib/esp32s3")
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app btbb)
endif()
endif()

View File

@@ -9,13 +9,13 @@ COMPONENT_ADD_INCLUDEDIRS := include
LIBS := btdm_app
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/controller/lib_esp32/esp32 \
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/controller/lib/esp32 \
$(addprefix -l,$(LIBS))
# re-link program if BT binary libs change
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/controller/lib_esp32/esp32/lib%.a,$(LIBS))
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/controller/lib/esp32/lib%.a,$(LIBS))
COMPONENT_SUBMODULES += controller/lib_esp32
COMPONENT_SUBMODULES += controller/lib
# TODO: annotate fallthroughs in Bluedroid code with comments

View File

@@ -176,14 +176,6 @@ struct osi_funcs_t {
int (* _coex_register_bt_cb)(coex_func_cb_t cb);
uint32_t (* _coex_bb_reset_lock)(void);
void (* _coex_bb_reset_unlock)(uint32_t restore);
int (* _coex_schm_register_btdm_callback)(void *callback);
void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status);
void (* _coex_schm_status_bit_set)(uint32_t type, uint32_t status);
uint32_t (* _coex_schm_interval_get)(void);
uint8_t (* _coex_schm_curr_period_get)(void);
void *(* _coex_schm_curr_phase_get)(void);
int (* _coex_wifi_channel_get)(uint8_t *primary, uint8_t *secondary);
int (* _coex_register_wifi_channel_change_callback)(void *cb);
uint32_t _magic;
};
@@ -232,14 +224,6 @@ extern int coex_bt_release(uint32_t event);
extern int coex_register_bt_cb(coex_func_cb_t cb);
extern uint32_t coex_bb_reset_lock(void);
extern void coex_bb_reset_unlock(uint32_t restore);
extern int coex_schm_register_btdm_callback(void *callback);
extern void coex_schm_status_bit_clear(uint32_t type, uint32_t status);
extern void coex_schm_status_bit_set(uint32_t type, uint32_t status);
extern uint32_t coex_schm_interval_get(void);
extern uint8_t coex_schm_curr_period_get(void);
extern void * coex_schm_curr_phase_get(void);
extern int coex_wifi_channel_get(uint8_t *primary, uint8_t *secondary);
extern int coex_register_wifi_channel_change_callback(void *cb);
extern void coex_ble_adv_priority_high_set(bool high);
extern char _bss_start_btdm;
@@ -310,14 +294,7 @@ static int coex_bt_release_wrapper(uint32_t event);
static int coex_register_bt_cb_wrapper(coex_func_cb_t cb);
static uint32_t coex_bb_reset_lock_wrapper(void);
static void coex_bb_reset_unlock_wrapper(uint32_t restore);
static int coex_schm_register_btdm_callback_wrapper(void *callback);
static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status);
static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status);
static uint32_t coex_schm_interval_get_wrapper(void);
static uint8_t coex_schm_curr_period_get_wrapper(void);
static void * coex_schm_curr_phase_get_wrapper(void);
static int coex_wifi_channel_get_wrapper(uint8_t *primary, uint8_t *secondary);
static int coex_register_wifi_channel_change_callback_wrapper(void *cb);
/* Local variable definition
***************************************************************************
*/
@@ -371,14 +348,6 @@ static const struct osi_funcs_t osi_funcs_ro = {
._coex_register_bt_cb = coex_register_bt_cb_wrapper,
._coex_bb_reset_lock = coex_bb_reset_lock_wrapper,
._coex_bb_reset_unlock = coex_bb_reset_unlock_wrapper,
._coex_schm_register_btdm_callback = coex_schm_register_btdm_callback_wrapper,
._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper,
._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper,
._coex_schm_interval_get = coex_schm_interval_get_wrapper,
._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper,
._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
._coex_wifi_channel_get = coex_wifi_channel_get_wrapper,
._coex_register_wifi_channel_change_callback = coex_register_wifi_channel_change_callback_wrapper,
._magic = OSI_MAGIC_VALUE,
};
@@ -1032,7 +1001,7 @@ static void coex_bt_wakeup_request_end(void)
return;
}
static int IRAM_ATTR coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration)
int IRAM_ATTR coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_bt_request(event, latency, duration);
@@ -1041,7 +1010,7 @@ static int IRAM_ATTR coex_bt_request_wrapper(uint32_t event, uint32_t latency, u
#endif
}
static int IRAM_ATTR coex_bt_release_wrapper(uint32_t event)
int IRAM_ATTR coex_bt_release_wrapper(uint32_t event)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_bt_release(event);
@@ -1050,7 +1019,7 @@ static int IRAM_ATTR coex_bt_release_wrapper(uint32_t event)
#endif
}
static int coex_register_bt_cb_wrapper(coex_func_cb_t cb)
int coex_register_bt_cb_wrapper(coex_func_cb_t cb)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_register_bt_cb(cb);
@@ -1059,7 +1028,7 @@ static int coex_register_bt_cb_wrapper(coex_func_cb_t cb)
#endif
}
static uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void)
uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_bb_reset_lock();
@@ -1068,81 +1037,13 @@ static uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void)
#endif
}
static void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore)
void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore)
{
#if CONFIG_SW_COEXIST_ENABLE
coex_bb_reset_unlock(restore);
#endif
}
static int coex_schm_register_btdm_callback_wrapper(void *callback)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_register_btdm_callback(callback);
#else
return 0;
#endif
}
static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status)
{
#if CONFIG_SW_COEXIST_ENABLE
coex_schm_status_bit_clear(type, status);
#endif
}
static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status)
{
#if CONFIG_SW_COEXIST_ENABLE
coex_schm_status_bit_set(type, status);
#endif
}
static uint32_t coex_schm_interval_get_wrapper(void)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_interval_get();
#else
return 0;
#endif
}
static uint8_t coex_schm_curr_period_get_wrapper(void)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_curr_period_get();
#else
return 1;
#endif
}
static void * coex_schm_curr_phase_get_wrapper(void)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_curr_phase_get();
#else
return NULL;
#endif
}
static int coex_wifi_channel_get_wrapper(uint8_t *primary, uint8_t *secondary)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_wifi_channel_get(primary, secondary);
#else
return -1;
#endif
}
static int coex_register_wifi_channel_change_callback_wrapper(void *cb)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_register_wifi_channel_change_callback(cb);
#else
return -1;
#endif
}
bool esp_vhci_host_check_send_available(void)
{
return API_vhci_host_check_send_available();
@@ -1541,12 +1442,16 @@ esp_err_t esp_bt_controller_deinit(void)
static void bt_shutdown(void)
{
esp_err_t ret = ESP_OK;
ESP_LOGD(BTDM_LOG_TAG, "stop Bluetooth");
ESP_LOGD(BTDM_LOG_TAG, "stop/deinit bt");
ret = esp_bt_controller_disable();
if (ESP_OK != ret) {
ESP_LOGW(BTDM_LOG_TAG, "controller disable ret=%d", ret);
}
ret = esp_bt_controller_deinit();
if (ESP_OK != ret) {
ESP_LOGW(BTDM_LOG_TAG, "controller deinit ret=%d", ret);
}
return;
}

View File

@@ -7,8 +7,7 @@ config BT_CTRL_BLE_MAX_ACT
default 10
range 1 10
help
BLE maximum activities of bluetooth controllerboth of connections,
scan , sync and adv(periodic adv, multi-adv).
BLE maximum instances of bluetooth controller.
config BT_CTRL_BLE_MAX_ACT_EFF
int
@@ -127,20 +126,10 @@ config BT_CTRL_RX_ANTENNA_INDEX_EFF
choice BT_CTRL_DFT_TX_POWER_LEVEL
prompt "BLE default Tx power level"
default BT_CTRL_DFT_TX_POWER_LEVEL_P3
default BT_CTRL_DFT_TX_POWER_LEVEL_P9
help
Specify default Tx power level
config BT_CTRL_DFT_TX_POWER_LEVEL_N27
bool "-27dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_N24
bool "-24dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_N21
bool "-21dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_N18
bool "-18dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_N15
bool "-15dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_N12
bool "-12dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_N9
@@ -157,32 +146,18 @@ choice BT_CTRL_DFT_TX_POWER_LEVEL
bool "+6dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_P9
bool "+9dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_P12
bool "+12dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_P15
bool "+15dBm"
config BT_CTRL_DFT_TX_POWER_LEVEL_P18
bool "+18dBm"
endchoice
config BT_CTRL_DFT_TX_POWER_LEVEL_EFF
int
default 0 if BT_CTRL_DFT_TX_POWER_LEVEL_N27
default 1 if BT_CTRL_DFT_TX_POWER_LEVEL_N24
default 2 if BT_CTRL_DFT_TX_POWER_LEVEL_N21
default 3 if BT_CTRL_DFT_TX_POWER_LEVEL_N18
default 4 if BT_CTRL_DFT_TX_POWER_LEVEL_N15
default 5 if BT_CTRL_DFT_TX_POWER_LEVEL_N12
default 6 if BT_CTRL_DFT_TX_POWER_LEVEL_N9
default 7 if BT_CTRL_DFT_TX_POWER_LEVEL_N6
default 8 if BT_CTRL_DFT_TX_POWER_LEVEL_N3
default 9 if BT_CTRL_DFT_TX_POWER_LEVEL_N0
default 10 if BT_CTRL_DFT_TX_POWER_LEVEL_P3
default 11 if BT_CTRL_DFT_TX_POWER_LEVEL_P6
default 12 if BT_CTRL_DFT_TX_POWER_LEVEL_P9
default 13 if BT_CTRL_DFT_TX_POWER_LEVEL_P12
default 14 if BT_CTRL_DFT_TX_POWER_LEVEL_P15
default 15 if BT_CTRL_DFT_TX_POWER_LEVEL_P18
default 0 if BT_CTRL_DFT_TX_POWER_LEVEL_N12
default 1 if BT_CTRL_DFT_TX_POWER_LEVEL_N9
default 2 if BT_CTRL_DFT_TX_POWER_LEVEL_N6
default 3 if BT_CTRL_DFT_TX_POWER_LEVEL_N3
default 4 if BT_CTRL_DFT_TX_POWER_LEVEL_N0
default 5 if BT_CTRL_DFT_TX_POWER_LEVEL_P3
default 6 if BT_CTRL_DFT_TX_POWER_LEVEL_P6
default 7 if BT_CTRL_DFT_TX_POWER_LEVEL_P9
default 0
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP

View File

@@ -212,7 +212,6 @@ extern void btdm_controller_disable(void);
extern uint8_t btdm_controller_get_mode(void);
extern const char *btdm_controller_get_compile_version(void);
extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
/* Sleep */
extern void btdm_controller_enable_sleep(bool enable);
extern uint8_t btdm_controller_get_sleep_mode(void);
@@ -741,16 +740,13 @@ static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
}
#endif
int event = (int) param;
if (event == BTDM_ASYNC_WAKEUP_SRC_VHCI || event == BTDM_ASYNC_WAKEUP_SRC_DISA) {
btdm_wakeup_request();
}
btdm_wakeup_request();
if (s_lp_cntl.wakeup_timer_required && s_lp_stat.wakeup_timer_started) {
esp_timer_stop(s_btdm_slp_tmr);
s_lp_stat.wakeup_timer_started = 0;
}
int event = (int) param;
if (event == BTDM_ASYNC_WAKEUP_SRC_VHCI || event == BTDM_ASYNC_WAKEUP_SRC_DISA) {
semphr_give_wrapper(s_wakeup_req_sem);
}
@@ -1335,51 +1331,14 @@ esp_bt_controller_status_t esp_bt_controller_get_status(void)
/* extra functions */
esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level)
{
esp_err_t stat = ESP_FAIL;
switch (power_type) {
case ESP_BLE_PWR_TYPE_ADV:
case ESP_BLE_PWR_TYPE_SCAN:
case ESP_BLE_PWR_TYPE_DEFAULT:
if (ble_txpwr_set(power_type, power_level) == 0) {
stat = ESP_OK;
}
break;
default:
stat = ESP_ERR_NOT_SUPPORTED;
break;
}
return stat;
ESP_LOGW(BTDM_LOG_TAG, "%s not implemented, return OK", __func__);
return ESP_OK;
}
esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type)
{
esp_power_level_t lvl;
switch (power_type) {
case ESP_BLE_PWR_TYPE_ADV:
case ESP_BLE_PWR_TYPE_SCAN:
lvl = (esp_power_level_t)ble_txpwr_get(power_type);
break;
case ESP_BLE_PWR_TYPE_CONN_HDL0:
case ESP_BLE_PWR_TYPE_CONN_HDL1:
case ESP_BLE_PWR_TYPE_CONN_HDL2:
case ESP_BLE_PWR_TYPE_CONN_HDL3:
case ESP_BLE_PWR_TYPE_CONN_HDL4:
case ESP_BLE_PWR_TYPE_CONN_HDL5:
case ESP_BLE_PWR_TYPE_CONN_HDL6:
case ESP_BLE_PWR_TYPE_CONN_HDL7:
case ESP_BLE_PWR_TYPE_CONN_HDL8:
case ESP_BLE_PWR_TYPE_DEFAULT:
lvl = (esp_power_level_t)ble_txpwr_get(ESP_BLE_PWR_TYPE_DEFAULT);
break;
default:
lvl = ESP_PWR_LVL_INVALID;
break;
}
return lvl;
ESP_LOGW(BTDM_LOG_TAG, "%s not implemented, return 0", __func__);
return 0;
}
esp_err_t esp_bt_sleep_enable (void)

View File

@@ -751,18 +751,7 @@ static int prov_auth(uint8_t method, uint8_t action, uint8_t size)
uint32_t num = 0U;
bt_mesh_rand(&num, sizeof(num));
if (output == BLE_MESH_BLINK ||
output == BLE_MESH_BEEP ||
output == BLE_MESH_VIBRATE) {
/** NOTE: According to the Bluetooth Mesh Profile Specification
* Section 5.4.2.4, blink, beep and vibrate should be a random
* integer between 0 and 10^size.
*/
num = (num % (div[size - 1] - 1)) + 1;
} else {
num %= div[size - 1];
}
num %= div[size - 1];
sys_put_be32(num, &link.auth[12]);
(void)memset(link.auth, 0, 12);

View File

@@ -1954,17 +1954,7 @@ static int prov_auth(const uint8_t idx, uint8_t method, uint8_t action, uint8_t
uint32_t num = 0U;
bt_mesh_rand(&num, sizeof(num));
if (input == BLE_MESH_PUSH ||
input == BLE_MESH_TWIST) {
/** NOTE: According to the Bluetooth Mesh Profile Specification
* Section 5.4.2.4, push and twist should be a random integer
* between 0 and 10^size.
*/
num = (num % (div[size - 1] - 1)) + 1;
} else {
num %= div[size - 1];
}
num %= div[size - 1];
sys_put_be32(num, &link[idx].auth[12]);
memset(link[idx].auth, 0, 12);
@@ -2067,7 +2057,7 @@ int bt_mesh_provisioner_set_oob_input_data(const uint8_t idx, const uint8_t *val
memset(link[idx].auth, 0, 16);
if (num_flag) {
/* Provisioner inputs number */
sys_memcpy_swap(link[idx].auth + 12, val, sizeof(uint32_t));
memcpy(link[idx].auth + 12, val, sizeof(uint32_t));
} else {
/* Provisioner inputs string */
memcpy(link[idx].auth, val, link[idx].auth_size);
@@ -2104,7 +2094,7 @@ int bt_mesh_provisioner_set_oob_output_data(const uint8_t idx, const uint8_t *nu
if (num_flag) {
/* Provisioner output number */
memset(link[idx].auth, 0, 16);
sys_memcpy_swap(link[idx].auth + 16 - size, num, size);
memcpy(link[idx].auth + 16 - size, num, size);
} else {
/* Provisioner output string */
memset(link[idx].auth, 0, 16);

View File

@@ -143,16 +143,6 @@ config BT_BLE_BLUFI_ENABLE
help
This option can be close when the app does not require blufi function.
config BT_GATT_SR_PROFILES
int "Max GATT Server Profiles"
depends on BT_GATTS_ENABLE && BT_BLUEDROID_ENABLED
range 1 32
default 8
help
Maximum GATT Server Profiles Count
choice BT_GATTS_SEND_SERVICE_CHANGE_MODE
prompt "GATTS Service Change Mode"
default BT_GATTS_SEND_SERVICE_CHANGE_AUTO
@@ -193,14 +183,6 @@ config BT_GATTC_CACHE_NVS_FLASH
help
This select can save gattc cache data to nvs flash
config BT_GATTC_CONNECT_RETRY_COUNT
int "The number of attempts to reconnect if the connection establishment failed"
depends on BT_GATTC_ENABLE
range 0 7
default 3
help
The number of attempts to reconnect if the connection establishment failed
config BT_BLE_SMP_ENABLE
bool "Include BLE security module(SMP)"
depends on BT_BLE_ENABLED
@@ -963,6 +945,7 @@ menu "BT DEBUG LOG LEVEL"
endmenu #BT DEBUG LOG LEVEL
config BT_ACL_CONNECTIONS
int "BT/BLE MAX ACL CONNECTIONS(1~7)"
depends on BT_BLUEDROID_ENABLED
@@ -971,13 +954,6 @@ config BT_ACL_CONNECTIONS
help
Maximum BT/BLE connection count
config BT_MULTI_CONNECTION_ENBALE
bool "Enable BLE multi-conections"
depends on BT_BLUEDROID_ENABLED
default y
help
Enable this option if there are multiple connections
config BT_ALLOCATION_FROM_SPIRAM_FIRST
bool "BT/BLE will first malloc the memory from the PSRAM"
depends on BT_BLUEDROID_ENABLED
@@ -1028,20 +1004,10 @@ config BT_BLE_ESTAB_LINK_CONN_TOUT
config BT_BLE_RPA_SUPPORTED
bool "Update RPA to Controller"
depends on BT_BLUEDROID_ENABLED
default y if (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
default n if IDF_TARGET_ESP32
depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3))
default y
help
This enables controller RPA list function.
For ESP32, ESP32 only support network privacy mode. If this option is enabled, ESP32 will only accept
advertising packets from peer devices that contain private address, HW will not receive the advertising
packets contain identity address after IRK changed. If this option is disabled, address resolution will
be performed in the host, so the functions that require controller to resolve address in the white list
cannot be used. This option is disabled by default on ESP32, please enable or disable this option according
to your own needs.
For ESP32C3 and esp32s3, devices support network privacy mode and device privacy mode, users can switch the
two modes according to their own needs. So this option is enabled by default.
config BT_BLE_50_FEATURES_SUPPORTED
bool "Enable BLE 5.0 features"

View File

@@ -133,8 +133,7 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (name == NULL || strlen(name) > ESP_SPP_SERVER_NAME_MAX) {
LOG_ERROR("Invalid server name!\n");
if (strlen(name) > ESP_SPP_SERVER_NAME_MAX) {
return ESP_ERR_INVALID_ARG;
}
@@ -158,34 +157,13 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
esp_err_t esp_spp_stop_srv(void)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_STOP_SRV;
arg.stop_srv.scn = BTC_SPP_INVALID_SCN;
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_spp_stop_srv_scn(uint8_t scn)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((scn == 0) || (scn >= PORT_MAX_RFC_PORTS)) {
LOG_ERROR("Invalid SCN!\n");
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_STOP_SRV;
arg.stop_srv.scn = scn;
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
return (btc_transfer_context(&msg, NULL, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -301,7 +301,6 @@ typedef void (* esp_blufi_event_cb_t)(esp_blufi_cb_event_t event, esp_blufi_cb_p
* @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);
@@ -312,7 +311,7 @@ typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8
* @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);
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len);
/**
* @brief BLUFI decrypt the data after negotiate a share key

View File

@@ -259,7 +259,7 @@ typedef union {
/**
* @brief GATT Client callback function type
* @param event : Event type
* @param gattc_if : GATT client access interface, normally
* @param gatts_if : GATT client access interface, normally
* different gattc_if correspond to different profile
* @param param : Point to callback parameter, currently is union type
*/
@@ -313,7 +313,7 @@ esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if);
* @param[in] gattc_if: Gatt client access interface.
* @param[in] remote_bda: remote device bluetooth device address.
* @param[in] remote_addr_type: remote device bluetooth device the address type.
* @param[in] is_direct: direct connection or background auto connection(by now, background auto connection is not supported).
* @param[in] is_direct: direct connection or background auto connection
*
* @return
* - ESP_OK: success

View File

@@ -188,7 +188,7 @@ typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
*
* @param[in] len : size(in bytes) in buf
*
* @return length of data successfully read
* @param[out] length of data successfully read
*/
typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);

View File

@@ -273,7 +273,7 @@ typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t l
*
* @param[in] len : size(in bytes) in buf
*
* @return length of data successfully read
* @param[out] length of data successfully read
*
*/
typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len);

View File

@@ -26,12 +26,11 @@ typedef enum {
ESP_SPP_SUCCESS = 0, /*!< Successful operation. */
ESP_SPP_FAILURE, /*!< Generic failure. */
ESP_SPP_BUSY, /*!< Temporarily can not handle this request. */
ESP_SPP_NO_DATA, /*!< No data */
ESP_SPP_NO_DATA, /*!< no data. */
ESP_SPP_NO_RESOURCE, /*!< No more resource */
ESP_SPP_NEED_INIT, /*!< SPP module shall init first */
ESP_SPP_NEED_DEINIT, /*!< SPP module shall deinit first */
ESP_SPP_NO_CONNECTION, /*!< Connection may have been closed */
ESP_SPP_NO_SERVER, /*!< No SPP server */
ESP_SPP_NO_CONNECTION, /*!< connection may have been closed */
} esp_spp_status_t;
/* Security Setting Mask
@@ -102,10 +101,9 @@ typedef union {
* @brief SPP_DISCOVERY_COMP_EVT
*/
struct spp_discovery_comp_evt_param {
esp_spp_status_t status; /*!< status */
uint8_t scn_num; /*!< The num of scn_num */
uint8_t scn[ESP_SPP_MAX_SCN]; /*!< channel # */
const char *service_name[ESP_SPP_MAX_SCN]; /*!< service_name */
esp_spp_status_t status; /*!< status */
uint8_t scn_num; /*!< The num of scn_num */
uint8_t scn[ESP_SPP_MAX_SCN]; /*!< channel # */
} disc_comp; /*!< SPP callback param of SPP_DISCOVERY_COMP_EVT */
/**
@@ -145,7 +143,6 @@ typedef union {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint8_t sec_id; /*!< security ID used by this server */
uint8_t scn; /*!< Server channel number */
bool use_co; /*!< TRUE to use co_rfc_data */
} start; /*!< SPP callback param of ESP_SPP_START_EVT */
@@ -154,7 +151,6 @@ typedef union {
*/
struct spp_srv_stop_evt_param {
esp_spp_status_t status; /*!< status */
uint8_t scn; /*!< Server channel number */
} srv_stop; /*!< SPP callback param of ESP_SPP_SRV_STOP_EVT */
/**
@@ -308,7 +304,7 @@ esp_err_t esp_spp_disconnect(uint32_t handle);
esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t local_scn, const char *name);
/**
* @brief This function stops all SPP servers.
* @brief This function stops a SPP server.
* The operation will close all active SPP connection first, then the callback function will be called
* with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
* When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT.
@@ -318,24 +314,8 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_stop_srv(void);
/**
* @brief This function stops a specific SPP server.
* The operation will close all active SPP connection first on the specific SPP server, then the callback function will be called
* with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
* When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT.
* This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
*
* @param[in] scn: Server channel number.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_stop_srv_scn(uint8_t scn);
/**
* @brief This function is used to write data, only for ESP_SPP_MODE_CB.
* When this function need to be called repeatedly, it is strongly recommended to call this function again after

View File

@@ -973,11 +973,10 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
p_clcb->p_srcb->srvc_hdl_chg = FALSE;
p_clcb->p_srcb->update_count = 0;
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
if (p_clcb->transport == BTA_TRANSPORT_LE) {
L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
}
#endif
/* set all srcb related clcb into discovery ST */
bta_gattc_set_discover_st(p_clcb->p_srcb);
@@ -1684,7 +1683,8 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
tBTA_GATTC_DATA *p_buf;
if (reason != 0) {
APPL_TRACE_WARNING("gattc_conn_cb: if=%d st=%d id=%d rsn=0x%x", gattc_if, connected, conn_id, reason);
APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
__FUNCTION__, gattc_if, connected, conn_id, reason);
}
bt_bdaddr_t bdaddr;
@@ -1702,7 +1702,7 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
p_buf->int_conn.conn_params.latency = p_lcb->current_used_conn_latency;
p_buf->int_conn.conn_params.timeout = p_lcb->current_used_conn_timeout;
} else {
APPL_TRACE_WARNING("gattc_conn_cb: conn params not found");
APPL_TRACE_WARNING("%s not found connection parameters of the device ", __func__);
}
}
p_buf->int_conn.hdr.layer_specific = conn_id;

View File

@@ -616,11 +616,9 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
//server discover end, update connection parameters
#if BLE_INCLUDED == TRUE
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
if (p_clcb->transport == BTA_TRANSPORT_LE) {
L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
}
#endif
//discover service complete, trigger callback
tBTA_GATTC cb_data;
cb_data.dis_cmpl.status = p_clcb->status;

View File

@@ -172,10 +172,9 @@ typedef struct {
/* data associated with BTA_JV_DISCOVERY_COMP_EVT_ */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT8 scn_num; /* num of channel */
UINT8 scn[BTA_JV_MAX_SCN]; /* channel # */
const char *service_name[BTA_JV_MAX_SCN]; /* service_name */
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT8 scn_num; /* num of channel */
UINT8 scn[BTA_JV_MAX_SCN]; /* channel # */
} tBTA_JV_DISCOVERY_COMP;
/* data associated with BTA_JV_CREATE_RECORD_EVT */
@@ -306,7 +305,6 @@ typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT8 sec_id; /* security ID used by this server */
UINT8 scn; /* Server channe number */
BOOLEAN use_co; /* TRUE to use co_rfc_data */
} tBTA_JV_RFCOMM_START;
@@ -378,9 +376,8 @@ typedef struct {
/* data associated with BTA_JV_FREE_SCN_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Status of the operation */
tBTA_JV_SERVER_STATUS server_status; /* Server status */
UINT8 scn; /* Server channe number */
tBTA_JV_STATUS status; /* Status of the operation */
tBTA_JV_SERVER_STATUS server_status;
} tBTA_JV_FREE_SCN;

View File

@@ -856,7 +856,6 @@ void bta_jv_free_scn(tBTA_JV_MSG *p_data)
tBTA_JV_FREE_SCN evt_data = {
.status = BTA_JV_SUCCESS,
.server_status = BTA_JV_SERVER_STATUS_MAX,
.scn = scn
};
tBTA_JV_FREE_SCN_USER_DATA *user_data = NULL;
@@ -950,7 +949,6 @@ static void bta_jv_start_discovery_cback(UINT16 result, void *user_data)
status = BTA_JV_FAILURE;
if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
tSDP_DISC_REC *p_sdp_rec = NULL;
tSDP_DISC_ATTR *p_attr = NULL;
tSDP_PROTOCOL_ELEM pe;
logu("bta_jv_cb.uuid", bta_jv_cb.uuid.uu.uuid128);
tBT_UUID su = shorten_sdp_uuid(&bta_jv_cb.uuid);
@@ -959,13 +957,7 @@ static void bta_jv_start_discovery_cback(UINT16 result, void *user_data)
p_sdp_rec = SDP_FindServiceUUIDInDb(p_bta_jv_cfg->p_sdp_db, &su, p_sdp_rec);
APPL_TRACE_DEBUG("p_sdp_rec:%p", p_sdp_rec);
if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)){
dcomp.scn[dcomp.scn_num] = (UINT8) pe.params[0];
if ((p_attr = SDP_FindAttributeInRec(p_sdp_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
dcomp.service_name[dcomp.scn_num] = (char *)p_attr->attr_value.v.array;
} else {
dcomp.service_name[dcomp.scn_num] = NULL;
}
dcomp.scn_num++;
dcomp.scn[dcomp.scn_num++] = (UINT8) pe.params[0];
status = BTA_JV_SUCCESS;
}
} while (p_sdp_rec);
@@ -2162,7 +2154,6 @@ void bta_jv_rfcomm_start_server(tBTA_JV_MSG *p_data)
evt_data.status = BTA_JV_SUCCESS;
evt_data.handle = p_pcb->handle;
evt_data.sec_id = sec_id;
evt_data.scn = rs->local_scn;
evt_data.use_co = TRUE;
PORT_ClearKeepHandleFlag(handle);

View File

@@ -53,11 +53,7 @@
/* Max HF Clients Supported From App */
static UINT16 btc_max_hf_clients = 1;
/* HF Param Definition */
#if HFP_DYNAMIC_MEMORY == FALSE
static hf_local_param_t hf_local_param[BTC_HF_NUM_CB];
#else
static hf_local_param_t *hf_local_param;
#endif
#if (BTM_WBS_INCLUDED == TRUE)
#ifndef BTC_HF_FEATURES
@@ -300,15 +296,7 @@ bt_status_t btc_hf_execute_service(BOOLEAN b_enable)
************************************************************************************/
bt_status_t btc_hf_init(bt_bdaddr_t *bd_addr)
{
int idx = 0;
UNUSED(bd_addr);
#if HFP_DYNAMIC_MEMORY == TRUE
if ((hf_local_param = (hf_local_param_t *)osi_malloc(sizeof(hf_local_param_t) * BTC_HF_NUM_CB)) == NULL) {
return BT_STATUS_FAIL;
}
#endif
int idx = btc_hf_idx_by_bdaddr(bd_addr);
BTC_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btc_max_hf_clients);
/* Invoke the enable service API to the core to set the appropriate service_id
* Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone)
@@ -334,18 +322,10 @@ bt_status_t btc_hf_init(bt_bdaddr_t *bd_addr)
void btc_hf_deinit(bt_bdaddr_t *bd_addr)
{
UNUSED(bd_addr);
int idx = btc_hf_idx_by_bdaddr(bd_addr);
BTC_TRACE_EVENT("%s", __FUNCTION__);
btc_dm_disable_service(BTA_HFP_SERVICE_ID);
#if HFP_DYNAMIC_MEMORY == TRUE
if (hf_local_param) {
osi_free(hf_local_param);
hf_local_param = NULL;
}
#else
hf_local_param[0].btc_hf_cb.initialized = false;
#endif
hf_local_param[idx].btc_hf_cb.initialized = false;
}
static bt_status_t connect_init(bt_bdaddr_t *bd_addr, uint16_t uuid)
@@ -937,10 +917,6 @@ void btc_hf_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
case BTC_HF_COPS_RESPONSE_EVT:
{
if (src->cops_rep.name == NULL) {
break;
}
dst->cops_rep.name = (char *)osi_malloc(strlen(src->cops_rep.name)+1);
if(dst->cops_rep.name) {
memcpy(dst->cops_rep.name, src->cops_rep.name, strlen(src->cops_rep.name)+1);
@@ -954,10 +930,6 @@ void btc_hf_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
case BTC_HF_CLCC_RESPONSE_EVT:
{
if (src->clcc_rep.number == NULL) {
break;
}
dst->clcc_rep.number = (char *)osi_malloc(strlen(src->clcc_rep.number)+1);
if(dst->clcc_rep.number) {
memcpy(dst->clcc_rep.number, src->clcc_rep.number, strlen(src->clcc_rep.number)+1);
@@ -971,10 +943,6 @@ void btc_hf_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
case BTC_HF_CNUM_RESPONSE_EVT:
{
if (src->cnum_rep.number == NULL) {
break;
}
dst->cnum_rep.number = (char *)osi_malloc(strlen(src->cnum_rep.number)+1);
if(dst->cnum_rep.number) {
memcpy(dst->cnum_rep.number, src->cnum_rep.number, strlen(src->cnum_rep.number)+1);
@@ -991,10 +959,6 @@ void btc_hf_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
case BTC_HF_OUT_CALL_EVT:
case BTC_HF_END_CALL_EVT:
{
if (src->phone.number == NULL) {
break;
}
dst->phone.number = (char *)osi_malloc(strlen(src->phone.number)+1);
if(dst->phone.number) {
memcpy(dst->phone.number, src->phone.number, strlen(src->phone.number)+1);

View File

@@ -206,6 +206,11 @@ typedef union
/* APP ID definition*/
#define BTC_HF_ID_1 0
#if HFP_DYNAMIC_MEMORY == TRUE
extern hf_local_param_t *hf_local_param_ptr;
#define hf_local_param (*hf_local_param_ptr)
#endif
/* BTC-AG control block to map bdaddr to BTA handle */
typedef struct
{

View File

@@ -28,8 +28,6 @@
#define ESP_SPP_RINGBUF_SIZE 1000
#define BTC_SPP_INVALID_SCN 0x00
typedef enum {
BTC_SPP_ACT_INIT = 0,
BTC_SPP_ACT_UNINIT,
@@ -76,10 +74,6 @@ typedef union {
UINT8 max_session;
char name[ESP_SPP_SERVER_NAME_MAX + 1];
} start_srv;
//BTC_SPP_ACT_STOP_SRV
struct stop_srv_arg {
UINT8 scn;
} stop_srv;
//BTC_SPP_ACT_WRITE
struct write_arg {
UINT32 handle;

View File

@@ -265,10 +265,6 @@ static void btc_create_server_fail_cb(void)
{
esp_spp_cb_param_t param;
param.start.status = ESP_SPP_FAILURE;
param.start.handle = 0;
param.start.sec_id = 0;
param.start.scn = BTC_SPP_INVALID_SCN;
param.start.use_co = FALSE;
btc_spp_cb_to_app(ESP_SPP_START_EVT, &param);
}
@@ -535,7 +531,6 @@ static void btc_spp_uninit(void)
esp_spp_cb_param_t param;
BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
param.srv_stop.status = ESP_SPP_NO_RESOURCE;
param.srv_stop.scn = spp_local_param.spp_slots[i]->scn;
btc_spp_cb_to_app(ESP_SPP_SRV_STOP_EVT, &param);
}
BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM,
@@ -677,117 +672,61 @@ static void btc_spp_start_srv(btc_spp_args_t *arg)
if (ret != ESP_SPP_SUCCESS) {
esp_spp_cb_param_t param;
param.start.status = ret;
param.start.handle = 0;
param.start.sec_id = 0;
param.start.scn = BTC_SPP_INVALID_SCN;
param.start.use_co = FALSE;
btc_spp_cb_to_app(ESP_SPP_START_EVT, &param);
}
}
static void btc_spp_stop_srv(btc_spp_args_t *arg)
static void btc_spp_stop_srv(void)
{
esp_spp_status_t ret = ESP_SPP_SUCCESS;
bool is_remove_all = false;
uint8_t i, j, srv_cnt = 0;
uint8_t *srv_scn_arr = osi_malloc(MAX_RFC_PORTS);
if (arg->stop_srv.scn == BTC_SPP_INVALID_SCN) {
is_remove_all = true;
}
do {
if (!is_spp_init()) {
BTC_TRACE_ERROR("%s SPP have not been init\n", __func__);
ret = ESP_SPP_NEED_INIT;
break;
}
if (srv_scn_arr == NULL) {
BTC_TRACE_ERROR("%s malloc srv_scn_arr failed\n", __func__);
ret = ESP_SPP_NO_RESOURCE;
break;
}
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
// [1] find all server
for (i = 1; i <= MAX_RFC_PORTS; i++) {
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected &&
spp_local_param.spp_slots[i]->sdp_handle > 0) {
if (is_remove_all) {
srv_scn_arr[srv_cnt++] = spp_local_param.spp_slots[i]->scn;
} else if (spp_local_param.spp_slots[i]->scn == arg->stop_srv.scn) {
srv_scn_arr[srv_cnt++] = spp_local_param.spp_slots[i]->scn;
break;
}
// first, remove all connection
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected) {
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb,
(void *)spp_local_param.spp_slots[i]->id);
}
}
if (srv_cnt == 0) {
if (is_remove_all) {
BTC_TRACE_ERROR("%s can not find any server!\n", __func__);
} else {
BTC_TRACE_ERROR("%s can not find server:%d!\n", __func__, arg->stop_srv.scn);
}
ret = ESP_SPP_NO_SERVER;
break;
}
// [2] remove all local related connection
for (j = 0; j < srv_cnt; j++) {
for (i = 1; i <= MAX_RFC_PORTS; i++) {
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected &&
spp_local_param.spp_slots[i]->sdp_handle > 0 &&
spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) {
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb,
(void *)spp_local_param.spp_slots[i]->id);
// second, remove all server
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected) {
if (spp_local_param.spp_slots[i]->sdp_handle > 0) {
BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle);
}
}
}
// [3] remove all server
for (j = 0; j < srv_cnt; j++) {
for (i = 1; i <= MAX_RFC_PORTS; i++) {
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected &&
spp_local_param.spp_slots[i]->sdp_handle > 0 &&
spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) {
if (spp_local_param.spp_slots[i]->sdp_handle > 0) {
BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle);
}
if (spp_local_param.spp_slots[i]->rfc_handle > 0) {
BTA_JvRfcommStopServer(spp_local_param.spp_slots[i]->rfc_handle,
(void *)spp_local_param.spp_slots[i]->id);
}
tBTA_JV_FREE_SCN_USER_DATA *user_data = osi_malloc(sizeof(tBTA_JV_FREE_SCN_USER_DATA));
if (user_data) {
user_data->server_status = BTA_JV_SERVER_RUNNING;
user_data->slot_id = spp_local_param.spp_slots[i]->id;
} else {
esp_spp_cb_param_t param;
BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
param.srv_stop.status = ESP_SPP_NO_RESOURCE;
param.srv_stop.scn = spp_local_param.spp_slots[i]->scn;
btc_spp_cb_to_app(ESP_SPP_SRV_STOP_EVT, &param);
}
BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
if (spp_local_param.spp_slots[i]->rfc_handle > 0) {
BTA_JvRfcommStopServer(spp_local_param.spp_slots[i]->rfc_handle,
(void *)spp_local_param.spp_slots[i]->id);
}
tBTA_JV_FREE_SCN_USER_DATA *user_data = osi_malloc(sizeof(tBTA_JV_FREE_SCN_USER_DATA));
if (user_data) {
user_data->server_status = BTA_JV_SERVER_RUNNING;
user_data->slot_id = spp_local_param.spp_slots[i]->id;
} else {
esp_spp_cb_param_t param;
BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
param.srv_stop.status = ESP_SPP_NO_RESOURCE;
btc_spp_cb_to_app(ESP_SPP_SRV_STOP_EVT, &param);
}
BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
}
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
} while (0);
} while(0);
if (ret != ESP_SPP_SUCCESS) {
esp_spp_cb_param_t param;
param.srv_stop.status = ret;
param.srv_stop.scn = BTC_SPP_INVALID_SCN;
btc_spp_cb_to_app(ESP_SPP_SRV_STOP_EVT, &param);
}
if (srv_scn_arr) {
osi_free(srv_scn_arr);
srv_scn_arr = NULL;
}
}
static void btc_spp_write(btc_spp_args_t *arg)
@@ -910,7 +849,7 @@ void btc_spp_call_handler(btc_msg_t *msg)
btc_spp_start_srv(arg);
break;
case BTC_SPP_ACT_STOP_SRV:
btc_spp_stop_srv(arg);
btc_spp_stop_srv();
break;
case BTC_SPP_ACT_WRITE:
btc_spp_write(arg);
@@ -937,8 +876,6 @@ void btc_spp_cb_handler(btc_msg_t *msg)
param.disc_comp.status = p_data->disc_comp.status;
param.disc_comp.scn_num = p_data->disc_comp.scn_num;
memcpy(param.disc_comp.scn, p_data->disc_comp.scn, p_data->disc_comp.scn_num);
memcpy(param.disc_comp.service_name, p_data->disc_comp.service_name,
p_data->disc_comp.scn_num * sizeof(const char *));
btc_spp_cb_to_app(ESP_SPP_DISCOVERY_COMP_EVT, &param);
break;
case BTA_JV_RFCOMM_CL_INIT_EVT:
@@ -972,7 +909,6 @@ void btc_spp_cb_handler(btc_msg_t *msg)
param.start.status = p_data->rfc_start.status;
param.start.handle = p_data->rfc_start.handle;
param.start.sec_id = p_data->rfc_start.sec_id;
param.start.scn = p_data->rfc_start.scn;
param.start.use_co = p_data->rfc_start.use_co;
btc_spp_cb_to_app(ESP_SPP_START_EVT, &param);
break;
@@ -1194,7 +1130,6 @@ void btc_spp_cb_handler(btc_msg_t *msg)
case BTA_JV_FREE_SCN_EVT:
if (p_data->free_scn.server_status == BTA_JV_SERVER_RUNNING) {
param.srv_stop.status = p_data->free_scn.status;
param.srv_stop.scn = p_data->free_scn.scn;
btc_spp_cb_to_app(ESP_SPP_SRV_STOP_EVT, &param);
}
break;

View File

@@ -134,13 +134,6 @@
#define UC_BT_GATTC_CACHE_NVS_FLASH_ENABLED FALSE
#endif
#ifdef CONFIG_BT_GATTC_CONNECT_RETRY_COUNT
#define UC_BT_GATTC_CONNECT_RETRY_COUNT CONFIG_BT_GATTC_CONNECT_RETRY_COUNT
#else
#define UC_BT_GATTC_CONNECT_RETRY_COUNT 0
#endif
//SMP
#ifdef CONFIG_BT_SMP_ENABLE
#define UC_BT_SMP_ENABLE CONFIG_BT_SMP_ENABLE
@@ -210,12 +203,6 @@
#define UC_BT_ACL_CONNECTIONS 5
#endif
#ifdef CONFIG_BT_MULTI_CONNECTION_ENBALE
#define UC_BT_MULTI_CONNECTION_ENBALE CONFIG_BT_MULTI_CONNECTION_ENBALE
#else
#define UC_BT_MULTI_CONNECTION_ENBALE FALSE
#endif
//BT_BLE_ESTAB_LINK_CONN_TOUT
#ifdef CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT
#define UC_BT_BLE_ESTAB_LINK_CONN_TOUT CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT
@@ -237,14 +224,6 @@
#define UC_CONFIG_BT_GATTS_PPCP_CHAR_GAP FALSE
#endif
#ifdef CONFIG_BT_GATT_MAX_SR_PROFILES
#define UC_CONFIG_BT_GATT_MAX_SR_PROFILES CONFIG_BT_GATT_MAX_SR_PROFILES
#else
#define UC_CONFIG_BT_GATT_MAX_SR_PROFILES 8
#endif
#ifdef CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE
#define UC_BT_GATTS_SEND_SERVICE_CHANGE_MODE CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE
#else

View File

@@ -202,18 +202,6 @@
#define GATTC_CACHE_NVS FALSE
#endif /* UC_BT_GATTC_ENABLE && UC_BT_GATTC_CACHE_NVS_FLASH_ENABLED */
#if (UC_BT_GATTC_ENABLE && UC_BT_GATTC_CONNECT_RETRY_COUNT)
#define GATTC_CONNECT_RETRY_COUNT UC_BT_GATTC_CONNECT_RETRY_COUNT
#else
#define GATTC_CONNECT_RETRY_COUNT 0
#endif /* UC_BT_GATTC_ENABLE && UC_BT_GATTC_CONNECT_RETRY_COUNT */
#if (GATTC_CONNECT_RETRY_COUNT > 0)
#define GATTC_CONNECT_RETRY_EN TRUE
#else
#define GATTC_CONNECT_RETRY_EN FALSE
#endif
#if (UC_BT_SMP_ENABLE)
#define SMP_INCLUDED TRUE
#if (BLE_INCLUDED == TRUE)
@@ -249,16 +237,6 @@
#define GATT_MAX_PHY_CHANNEL UC_BT_ACL_CONNECTIONS
#endif /* UC_BT_ACL_CONNECTIONS */
#ifdef UC_BT_MULTI_CONNECTION_ENBALE
#define BT_MULTI_CONNECTION_ENBALE UC_BT_MULTI_CONNECTION_ENBALE
#endif
#if(BT_MULTI_CONNECTION_ENBALE && (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3))
#define BLE_CE_LEN_MIN 5
#else
#define BLE_CE_LEN_MIN 0
#endif
#ifdef UC_BT_BLE_ESTAB_LINK_CONN_TOUT
#define BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT UC_BT_BLE_ESTAB_LINK_CONN_TOUT
#endif
@@ -1246,7 +1224,7 @@
#endif
#ifndef GATT_MAX_SR_PROFILES
#define GATT_MAX_SR_PROFILES UC_CONFIG_BT_GATT_MAX_SR_PROFILES
#define GATT_MAX_SR_PROFILES 8 /* max is 32 */
#endif
#ifndef GATT_MAX_APPS

View File

@@ -93,10 +93,6 @@
#include "bta_hf_client_int.h"
#endif
#if BTA_AG_INCLUDED == TRUE
#include "bta_ag_int.h"
#endif
#if BTA_SDP_INCLUDED == TRUE
#include "bta_sdp_int.h"
#endif
@@ -220,12 +216,6 @@ void BTE_DeinitStack(void)
osi_free(bta_hf_client_cb_ptr);
bta_hf_client_cb_ptr = NULL;
}
#endif
#if (defined BTA_AG_INCLUDED && BTA_AG_INCLUDED == TRUE)
if (bta_ag_cb_ptr){
osi_free(bta_ag_cb_ptr);
bta_ag_cb_ptr = NULL;
}
#endif
if (bta_dm_conn_srvcs_ptr){
osi_free(bta_dm_conn_srvcs_ptr);
@@ -384,12 +374,6 @@ bt_status_t BTE_InitStack(void)
}
memset((void *)bta_hf_client_cb_ptr, 0, sizeof(tBTA_HF_CLIENT_CB));
#endif
#if (defined BTA_AG_INCLUDED && BTA_AG_INCLUDED == TRUE)
if ((bta_ag_cb_ptr = (tBTA_AG_CB *)osi_malloc(sizeof(tBTA_AG_CB))) == NULL) {
goto error_exit;
}
memset((void *)bta_ag_cb_ptr, 0, sizeof(tBTA_AG_CB));
#endif
#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE)
if ((bta_jv_cb_ptr = (tBTA_JV_CB *)osi_malloc(sizeof(tBTA_JV_CB))) == NULL) {
goto error_exit;

View File

@@ -2076,30 +2076,6 @@ void btm_ble_create_ll_conn_complete (UINT8 status)
btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status);
}
}
/*****************************************************************************
** Function btm_ble_create_conn_cancel_complete
**
** Description LE connection cancel complete.
**
******************************************************************************/
void btm_ble_create_conn_cancel_complete (UINT8 *p)
{
UINT8 status;
STREAM_TO_UINT8 (status, p);
switch (status) {
case HCI_SUCCESS:
if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) {
btm_ble_set_conn_st (BLE_CONN_IDLE);
}
break;
default:
break;
}
}
/*****************************************************************************
** Function btm_proc_smp_cback
**

View File

@@ -23,26 +23,9 @@ tBTM_BLE_EXTENDED_CB extend_adv_cb;
tBTM_BLE_5_HCI_CBACK ble_5_hci_cb;
#define INVALID_VALUE 0XFF
extern BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda);
extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda);
extern void BTM_BleSetStaticAddr(BD_ADDR rand_addr);
extern uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS *params);
static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, UINT8 *data);
typedef struct {
uint16_t ter_con_handle;
bool invalid;
UINT8 instance;
int duration;
int max_events;
uint8_t retry_count;
} tBTM_EXT_ADV_RECORD;
tBTM_EXT_ADV_RECORD adv_record[MAX_BLE_ADV_INSTANCE] = {0};
extern void btm_ble_inter_set(bool extble_inter);
static char *btm_ble_hci_status_to_str(tHCI_STATUS status)
{
switch(status) {
@@ -193,16 +176,6 @@ static char *btm_ble_hci_status_to_str(tHCI_STATUS status)
return NULL;
}
void btm_ble_extendadvcb_init(void)
{
memset(&extend_adv_cb, 0, sizeof(tBTM_BLE_EXTENDED_CB));
}
void btm_ble_advrecod_init(void)
{
memset(&adv_record[0], 0, sizeof(tBTM_EXT_ADV_RECORD)*MAX_BLE_ADV_INSTANCE);
}
void BTM_BleGapRegisterCallback(tBTM_BLE_5_HCI_CBACK cb)
{
if (cb) {
@@ -212,15 +185,6 @@ void BTM_BleGapRegisterCallback(tBTM_BLE_5_HCI_CBACK cb)
}
}
void BTM_ExtBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_5_GAP_CB_PARAMS *params)
{
if(params && params->status == BTM_SUCCESS) {
btm_ble_inter_set(true);
}
if (ble_5_hci_cb) {
ble_5_hci_cb(event, params);
}
}
tBTM_STATUS BTM_BleReadPhy(BD_ADDR bd_addr, UINT8 *tx_phy, UINT8 *rx_phy)
{
@@ -257,9 +221,9 @@ tBTM_STATUS BTM_BleSetPreferDefaultPhy(UINT8 tx_phy_mask, UINT8 rx_phy_mask)
}
cb_params.set_perf_def_phy.status = err;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -283,7 +247,9 @@ tBTM_STATUS BTM_BleSetPreferPhy(BD_ADDR bd_addr, UINT8 all_phys, UINT8 tx_phy_ma
if (!btsnd_hcic_ble_set_phy(p_lcb->handle, all_phys, tx_phy_mask, rx_phy_mask, phy_options)) {
cb_params.status = BTM_ILLEGAL_VALUE;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
}
}
@@ -319,12 +285,6 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr)
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
} else {
// set random address success, update address infor
if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) {
BTM_BleSetStaticAddr(rand_addr);
BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr);
}
}
} else {
BTM_TRACE_ERROR("%s invalid random address", __func__);
@@ -335,7 +295,9 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr)
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, &cb_params);
}
return status;
@@ -345,8 +307,6 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
bool use_rpa_addr = false;
BD_ADDR rand_addr;
if (instance >= MAX_BLE_ADV_INSTANCE) {
status = BTM_ILLEGAL_VALUE;
@@ -375,41 +335,27 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR
} else {
extend_adv_cb.inst[instance].legacy_pdu = false;
}
// if own_addr_type == BLE_ADDR_PUBLIC_ID or BLE_ADDR_RANDOM_ID,
if((params->own_addr_type == BLE_ADDR_PUBLIC_ID || params->own_addr_type == BLE_ADDR_RANDOM_ID) && BTM_GetLocalResolvablePrivateAddr(rand_addr)) {
params->own_addr_type = BLE_ADDR_RANDOM;
use_rpa_addr = true;
} else if(params->own_addr_type == BLE_ADDR_PUBLIC_ID){
params->own_addr_type = BLE_ADDR_PUBLIC;
} else if (params->own_addr_type == BLE_ADDR_RANDOM_ID) {
params->own_addr_type = BLE_ADDR_RANDOM;
}
if ((err = btsnd_hcic_ble_set_ext_adv_params(instance, params->type, params->interval_min, params->interval_max,
params->channel_map, params->own_addr_type, params->peer_addr_type,
params->peer_addr, params->filter_policy, params->tx_power,
params->primary_phy, params->max_skip,
params->secondary_phy, params->sid, params->scan_req_notif)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
goto end;
goto end;
}
extend_adv_cb.inst[instance].configured = true;
end:
if(use_rpa_addr) {
// update RPA address
if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err);
status = BTM_ILLEGAL_VALUE;
} else {
// set addr success, update address infor
BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr);
}
}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -444,12 +390,14 @@ tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance,
}
if (!is_scan_rsp) {
if ((err = btsnd_hcic_ble_set_ext_adv_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetAdvData: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, line %d, fail to send the hci command, the error code = %s",
__func__, __LINE__, btm_ble_hci_status_to_str(err));
status = BTM_ILLEGAL_VALUE;
}
} else {
if ((err = btsnd_hcic_ble_set_ext_adv_scan_rsp_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetScanRspData: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, line %d, fail to send the hci command, the error code = %s(0x%x)",
__func__, __LINE__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
}
@@ -460,7 +408,10 @@ tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance,
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(is_scan_rsp ? BTM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(is_scan_rsp ? BTM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -501,7 +452,8 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_
if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, instance,
duration, max_events)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
@@ -512,8 +464,9 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_
// enable = false, num == 0 or ext_adv = NULL
if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, NULL, NULL, NULL)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err);
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
goto end;
}
@@ -527,72 +480,17 @@ end:
for (int i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
extend_adv_cb.inst[i].configured = false;
}
// disable all ext adv
if(num == 0) {
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++)
{
adv_record[i].invalid = false;
adv_record[i].instance = INVALID_VALUE;
adv_record[i].duration = INVALID_VALUE;
adv_record[i].max_events = INVALID_VALUE;
adv_record[i].retry_count = 0;
}
} else {
for (uint8_t i = 0; i < num; i++)
{
uint8_t index = ext_adv[i].instance;
adv_record[index].invalid = false;
adv_record[index].instance = INVALID_VALUE;
adv_record[index].duration = INVALID_VALUE;
adv_record[index].max_events = INVALID_VALUE;
adv_record[index].retry_count = 0;
}
}
}
// start extend adv success, save the adv information
if(enable && status == BTM_SUCCESS) {
for (uint8_t i = 0; i < num; i++)
{
uint8_t index = ext_adv[i].instance;
adv_record[index].invalid = true;
adv_record[index].instance = ext_adv[i].instance;
adv_record[index].duration = ext_adv[i].duration;
adv_record[index].max_events = ext_adv[i].max_events;
adv_record[index].retry_count = 0;
}
}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params);
}
return status;
}
tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t con_handle)
{
tBTM_BLE_EXT_ADV ext_adv;
uint8_t index = INVALID_VALUE;
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++)
{
if(adv_record[i].ter_con_handle == con_handle) {
index = i;
break;
}
}
if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid) || (adv_record[index].retry_count > GATTC_CONNECT_RETRY_COUNT)) {
return BTM_WRONG_MODE;
}
adv_record[index].retry_count ++;
BTM_TRACE_DEBUG("remote device did not reveive aux connect response, retatrt the extend adv to reconnect, adv handle %d con_handle %d\n", index, con_handle);
ext_adv.instance = adv_record[index].instance;
ext_adv.duration = adv_record[index].duration;
ext_adv.max_events = adv_record[index].max_events;
return BTM_BleStartExtAdv(true, 1, &ext_adv);
}
tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance)
{
tBTM_STATUS status = BTM_SUCCESS;
@@ -606,21 +504,18 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance)
}
if ((err = btsnd_hcic_ble_remove_adv_set(instance)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EAS Rm: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
} else {
extend_adv_cb.inst[instance].configured = false;
extend_adv_cb.inst[instance].legacy_pdu = false;
extend_adv_cb.inst[instance].directed = false;
extend_adv_cb.inst[instance].scannable = false;
extend_adv_cb.inst[instance].connetable = false;
}
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -632,21 +527,16 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void)
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_clear_adv_set()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EAS Clr: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
} else {
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
extend_adv_cb.inst[i].configured = false;
extend_adv_cb.inst[i].legacy_pdu = false;
extend_adv_cb.inst[i].directed = false;
extend_adv_cb.inst[i].scannable = false;
extend_adv_cb.inst[i].connetable = false;
}
}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -669,14 +559,15 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa
extend_adv_cb.inst[instance].connetable ||
extend_adv_cb.inst[instance].legacy_pdu) {
BTM_TRACE_ERROR("%s, instance = %d, Before set the periodic adv parameters, please configure the the \
extend adv to nonscannable and nonconnectable first, and it shouldn't include the legacy bit.", __func__, instance);
extend adv to nonscannable and nonconnectable fisrt, and it shouldn't include the legacy bit.", __func__, instance);
status = BTM_ILLEGAL_VALUE;
goto end;
}
if ((err= btsnd_hcic_ble_set_periodic_adv_params(instance, params->interval_min,
params->interval_max, params->properties)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SetParams: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
@@ -684,7 +575,9 @@ end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -726,7 +619,8 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data
}
if ((err = btsnd_hcic_ble_set_periodic_adv_data(instance, operation, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SetData: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
rem_len -= send_data_len;
@@ -735,7 +629,9 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -747,13 +643,14 @@ tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, BOOLEAN enable)
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (instance >= MAX_BLE_ADV_INSTANCE) {
BTM_TRACE_ERROR("%s, invalid instance %d", __func__, instance);
BTM_TRACE_ERROR("%s, invalid insatnce %d", __func__, instance);
status = BTM_ILLEGAL_VALUE;
goto end;
}
if ((err = btsnd_hcic_ble_periodic_adv_enable(enable, instance)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA En=%d: cmd err=0x%x", enable, err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
@@ -761,7 +658,9 @@ end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(enable ? BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT, &cb_params);
}
return status;
@@ -789,16 +688,17 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params)
if (!btsnd_hcic_ble_periodic_adv_create_sync(params->filter_policy, params->sid, params->addr_type,
params->addr, params->sync_timeout, 0)) {
BTM_TRACE_ERROR("LE PA CreateSync cmd failed");
BTM_TRACE_ERROR("%s, send cmd failed", __func__);
status = BTM_ILLEGAL_VALUE;
}
end:
if(status != BTM_SUCCESS) {
if((status != BTM_SUCCESS) && ble_5_hci_cb) {
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params);
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params);
}
return status;
}
void btm_set_phy_callback(UINT8 status)
@@ -806,7 +706,9 @@ void btm_set_phy_callback(UINT8 status)
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
}
}
void btm_create_sync_callback(UINT8 status)
@@ -814,7 +716,9 @@ void btm_create_sync_callback(UINT8 status)
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params);
}
}
void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_phy, uint8_t rx_phy)
@@ -833,7 +737,9 @@ void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_
cb_params.read_phy.tx_phy = tx_phy;
cb_params.read_phy.rx_phy = rx_phy;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT, &cb_params);
}
}
tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void)
@@ -843,13 +749,16 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void)
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_periodic_adv_create_sync_cancel()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -861,13 +770,16 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncTerm(UINT16 sync_handle)
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (( err = btsnd_hcic_ble_periodic_adv_term_sync(sync_handle)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SyncTerm: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -885,13 +797,16 @@ tBTM_STATUS BTM_BlePeriodicAdvAddDevToList(tBLE_ADDR_TYPE addr_type, BD_ADDR add
}
if ((err = btsnd_hcic_ble_add_dev_to_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA AddDevToList: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -909,14 +824,17 @@ tBTM_STATUS BTM_BlePeriodicAdvRemoveDevFromList(tBLE_ADDR_TYPE addr_type, BD_ADD
}
if ((err = btsnd_hcic_ble_rm_dev_from_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA RmDevFromList: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -927,12 +845,15 @@ tBTM_STATUS BTM_BlePeriodicAdvClearDev(void)
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_clear_periodic_adv_list()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA ClrDev: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -969,17 +890,12 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params)
phy_count++;
}
if (BTM_BleUpdateOwnType(&params->own_addr_type, NULL) != 0 ) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("LE UpdateOwnType err");
goto end;
}
extend_adv_cb.scan_duplicate = params->scan_duplicate;
if ((err = btsnd_hcic_ble_set_ext_scan_params(params->own_addr_type, params->filter_policy, phy_mask, phy_count,
hci_params)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE ES SetParams: cmd err=0x%x", err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
@@ -987,7 +903,9 @@ end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT, &cb_params);
}
return cb_params.status;
}
@@ -1005,7 +923,8 @@ tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period)
}
if ((err = btsnd_hcic_ble_ext_scan_enable(enable, extend_adv_cb.scan_duplicate, duration, period)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE ES En=%d: cmd err=0x%x", enable, err);
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_ILLEGAL_VALUE;
}
@@ -1013,7 +932,9 @@ end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(enable ? BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT, &cb_params);
}
return status;
}
@@ -1137,15 +1058,20 @@ void btm_ble_update_phy_evt(tBTM_BLE_UPDATE_PHY *params)
memcpy(cb_params.phy_update.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PHY_UPDATE_COMPLETE_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PHY_UPDATE_COMPLETE_EVT, &cb_params);
}
return;
}
void btm_ble_scan_timeout_evt(void)
{
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT, NULL);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT, NULL);
}
return;
}
void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
@@ -1157,18 +1083,12 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
return;
}
// adv terminated due to connection, save the adv handle and connection handle
if(params->completed_event == 0x00) {
adv_record[params->adv_handle].ter_con_handle = params->conn_handle;
} else {
adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE;
adv_record[params->adv_handle].invalid = false;
}
memcpy(&cb_params.adv_term, params, sizeof(tBTM_BLE_ADV_TERMINAT));
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_ADV_TERMINATED_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_ADV_TERMINATED_EVT, &cb_params);
}
return;
}
@@ -1185,7 +1105,9 @@ void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params)
memcpy(&cb_params.ext_adv_report, params, sizeof(tBTM_BLE_EXT_ADV_REPORT));
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_REPORT_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_EXT_ADV_REPORT_EVT, &cb_params);
}
return;
@@ -1203,7 +1125,9 @@ void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params)
memcpy(&cb_params.scan_req, params, sizeof(tBTM_BLE_SCAN_REQ_RECEIVED));
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SCAN_REQ_RECEIVED_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_SCAN_REQ_RECEIVED_EVT, &cb_params);
}
return;
}
@@ -1220,7 +1144,9 @@ void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params)
memcpy(&cb_params.channel_sel, params, sizeof(tBTM_BLE_CHANNEL_SEL_ALG));
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT, &cb_params);
}
return;
}
@@ -1237,7 +1163,9 @@ void btm_ble_periodic_adv_report_evt(tBTM_PERIOD_ADV_REPORT *params)
memcpy(&cb_params.period_adv_report, params, sizeof(tBTM_PERIOD_ADV_REPORT));
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT, &cb_params);
}
return;
@@ -1255,7 +1183,9 @@ void btm_ble_periodic_adv_sync_lost_evt(tBTM_BLE_PERIOD_ADV_SYNC_LOST *params)
memcpy(&cb_params.sync_lost, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_LOST));
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT, &cb_params);
}
return;
@@ -1273,7 +1203,9 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par
memcpy(&cb_params.sync_estab, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB));
// If the user has register the callback function, should callback it to the application.
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT, &cb_params);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT, &cb_params);
}
return;

View File

@@ -414,13 +414,12 @@ void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK *p_c
/* start to resolve random address */
/* check for next security record */
for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
p_dev_rec = list_node(p_node);
p_dev_rec = list_node(p_node);
p_mgnt_cb->p_dev_rec = p_dev_rec;
if (btm_ble_match_random_bda(p_dev_rec)) {
break;
}
p_mgnt_cb->p_dev_rec = NULL;
}
break;
}
}
btm_ble_resolve_address_cmpl();
} else {
(*p_cback)(NULL, p);

View File

@@ -82,25 +82,12 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
tBLE_ADDR_TYPE *p_own_addr_type);
static void btm_ble_stop_observe(void);
static void btm_ble_stop_discover(void);
uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
#define BTM_BLE_INQ_RESULT 0x01
#define BTM_BLE_OBS_RESULT 0x02
#define BTM_BLE_SEL_CONN_RESULT 0x04
#define BTM_BLE_DISCO_RESULT 0x08
static bool is_ble50_inter = false;
void btm_ble_inter_set(bool extble_inter)
{
is_ble50_inter = extble_inter;
}
bool btm_ble_inter_get(void)
{
return is_ble50_inter;
}
/* LE states combo bit to check */
const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = {
{/* single state support */
@@ -921,140 +908,6 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK
#endif
}
/*******************************************************************************
**
** Function BTMGetLocalResolvablePrivateAddr
**
** Description This function is called to get local RPA address
**
** Parameters bda: address pointer.
**
**
*******************************************************************************/
BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda)
{
tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
BTM_TRACE_DEBUG ("get owm resolvable random address");
if (bda) {
/* if privacy disabled, return false */
if ((p_cb->exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) == BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) {
memcpy(bda, p_cb->resolvale_addr, BD_ADDR_LEN);
BTM_TRACE_DEBUG("own resolvable random address: 0x%02x:%02x:%02x:%02x:%02x:%02x",
p_cb->resolvale_addr[0], p_cb->resolvale_addr[1],
p_cb->resolvale_addr[2], p_cb->resolvale_addr[3],
p_cb->resolvale_addr[4], p_cb->resolvale_addr[5]);
return TRUE;
}
return FALSE;
}
return FALSE;
}
/*******************************************************************************
**
** Function BTM_UpdateAddrInfor
**
** Description This function is called to update address information
**
** Parameters addr_type: address type
** bda: address pointer.
**
**
*******************************************************************************/
void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda)
{
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = addr_type;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, bda, BD_ADDR_LEN);
}
/*******************************************************************************
**
** Function BTM_BleSetStaticAddr
**
** Description This function is called to save random address
**
** Parameters rand_addr: address pointer.
**
**
*******************************************************************************/
void BTM_BleSetStaticAddr(BD_ADDR rand_addr)
{
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, rand_addr, BD_ADDR_LEN);
btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit |= BTM_BLE_GAP_ADDR_BIT_RANDOM;
}
uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb)
{
if(*own_bda_type == BLE_ADDR_RANDOM) {
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) == BTM_BLE_GAP_ADDR_BIT_RANDOM) {
//close privacy
#if BLE_PRIVACY_SPT == TRUE
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
BTM_BleConfigPrivacy(FALSE, NULL);
}
#endif
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, BD_ADDR_LEN);
// set address to controller
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr);
} else if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) == BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) {
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr);
}else {
BTM_TRACE_ERROR ("No random address yet, please set random address and try\n");
if(cb) {
(* cb)(HCI_ERR_ESP_VENDOR_FAIL);
}
return BTM_ILLEGAL_VALUE;
}
} else if(*own_bda_type == BLE_ADDR_PUBLIC_ID || *own_bda_type == BLE_ADDR_RANDOM_ID) {
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) == BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) {
*own_bda_type = BLE_ADDR_RANDOM;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr);
} else {
#if BLE_PRIVACY_SPT == TRUE
if(btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
BTM_TRACE_ERROR ("Error state\n");
if(cb) {
(* cb)(HCI_ERR_ESP_VENDOR_FAIL);
}
return BTM_ILLEGAL_VALUE;
}
#endif
if(*own_bda_type == BLE_ADDR_PUBLIC_ID) {
*own_bda_type = BLE_ADDR_PUBLIC;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
} else { //own_bda_type == BLE_ADDR_RANDOM_ID
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) == BTM_BLE_GAP_ADDR_BIT_RANDOM) {
*own_bda_type = BLE_ADDR_RANDOM;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr);
} else {
BTM_TRACE_ERROR ("No RPA and no random address yet, please set RPA or random address and try\n");
if(cb) {
(* cb)(HCI_ERR_ESP_VENDOR_FAIL);
}
return BTM_ILLEGAL_VALUE;
}
}
}
} else {
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
}
return BTM_SUCCESS;
}
/*******************************************************************************
**
** Function BTM_BleConfigLocalIcon
@@ -1492,9 +1345,69 @@ tBTM_STATUS BTM_BleSetAdvParamsAll(UINT16 adv_int_min, UINT16 adv_int_max, UINT8
if (!controller_get_interface()->supports_ble()) {
return BTM_ILLEGAL_VALUE;
}
if (BTM_BleUpdateOwnType(&own_bda_type, adv_cb) != 0) {
return BTM_ILLEGAL_VALUE;
if(own_bda_type == BLE_ADDR_RANDOM) {
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) == BTM_BLE_GAP_ADDR_BIT_RANDOM) {
//close privacy
#if BLE_PRIVACY_SPT == TRUE
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
BTM_BleConfigPrivacy(FALSE, NULL);
}
#endif
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, BD_ADDR_LEN);
// set address to controller
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr);
} else if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) == BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) {
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr);
}else {
BTM_TRACE_ERROR ("No random address yet, please set random address and try\n");
if(adv_cb) {
(* adv_cb)(HCI_ERR_ESP_VENDOR_FAIL);
}
return BTM_ILLEGAL_VALUE;
}
} else if(own_bda_type == BLE_ADDR_PUBLIC_ID || own_bda_type == BLE_ADDR_RANDOM_ID) {
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) == BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) {
own_bda_type = BLE_ADDR_RANDOM;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr);
} else {
#if BLE_PRIVACY_SPT == TRUE
if(btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
BTM_TRACE_ERROR ("Error state\n");
if(adv_cb) {
(* adv_cb)(HCI_ERR_ESP_VENDOR_FAIL);
}
return BTM_ILLEGAL_VALUE;
}
#endif
if(own_bda_type == BLE_ADDR_PUBLIC_ID) {
own_bda_type = BLE_ADDR_PUBLIC;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
} else { //own_bda_type == BLE_ADDR_RANDOM_ID
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) == BTM_BLE_GAP_ADDR_BIT_RANDOM) {
own_bda_type = BLE_ADDR_RANDOM;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr);
} else {
BTM_TRACE_ERROR ("No RPA and no random address yet, please set RPA or random address and try\n");
if(adv_cb) {
(* adv_cb)(HCI_ERR_ESP_VENDOR_FAIL);
}
return BTM_ILLEGAL_VALUE;
}
}
}
} else {
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
}
if (!BTM_BLE_ISVALID_PARAM(adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) ||
!BTM_BLE_ISVALID_PARAM(adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX)) {
BTM_TRACE_ERROR ("adv_int_min or adv_int_max is invalid\n");
@@ -1666,9 +1579,61 @@ tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval,
if (!controller_get_interface()->supports_ble()) {
return BTM_ILLEGAL_VALUE;
}
if (BTM_BleUpdateOwnType(&addr_type_own, NULL) != 0) {
return BTM_ILLEGAL_VALUE;
if(addr_type_own == BLE_ADDR_RANDOM) {
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) == BTM_BLE_GAP_ADDR_BIT_RANDOM) {
//close privacy
#if BLE_PRIVACY_SPT == TRUE
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
BTM_BleConfigPrivacy(FALSE, NULL);
}
#endif
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, BD_ADDR_LEN);
// set address to controller
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr);
} else if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) == BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) {
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr);
}else {
BTM_TRACE_ERROR ("No random address yet, please set random address and try\n");
return BTM_ILLEGAL_VALUE;
}
} else if(addr_type_own == BLE_ADDR_PUBLIC_ID || addr_type_own == BLE_ADDR_RANDOM_ID) {
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) == BTM_BLE_GAP_ADDR_BIT_RESOLVABLE) {
addr_type_own = BLE_ADDR_RANDOM;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr);
} else {
#if BLE_PRIVACY_SPT == TRUE
if(btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
BTM_TRACE_ERROR ("Error state\n");
return BTM_ILLEGAL_VALUE;
}
#endif
if(addr_type_own == BLE_ADDR_PUBLIC_ID) {
addr_type_own = BLE_ADDR_PUBLIC;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
} else {
//own_bda_type == BLE_ADDR_RANDOM_ID
if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) == BTM_BLE_GAP_ADDR_BIT_RANDOM) {
addr_type_own = BLE_ADDR_RANDOM;
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, BD_ADDR_LEN);
btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr);
} else {
BTM_TRACE_ERROR ("No RPA and no random address yet, please set RPA or random address and try\n");
return BTM_ILLEGAL_VALUE;
}
}
}
} else {
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
}
/* If not supporting extended scan support, use the older range for checking */
if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) {
max_scan_interval = BTM_BLE_SCAN_INT_MAX;

View File

@@ -37,12 +37,6 @@ tBTM_CB btm_cb;
tBTM_CB *btm_cb_ptr;
#endif
#if (BLE_50_FEATURE_SUPPORT == TRUE)
extern void btm_ble_extendadvcb_init(void);
extern void btm_ble_advrecod_init(void);
#endif
/*******************************************************************************
**
** Function btm_init
@@ -86,11 +80,6 @@ void btm_init (void)
btm_ble_sem_init();
#endif
btm_sec_dev_init();
#if (BLE_50_FEATURE_SUPPORT == TRUE)
btm_ble_extendadvcb_init();
btm_ble_advrecod_init();
#endif
}

View File

@@ -4589,6 +4589,26 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
#endif ///BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE
BTM_TRACE_EVENT("%s before update sec_flags=0x%x\n", __func__, p_dev_rec->sec_flags);
/* If we are in the process of bonding we need to tell client that auth failed */
if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
&& (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)) {
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
if (btm_cb.api.p_auth_complete_callback) {
/* If the disconnection reason is REPEATED_ATTEMPTS,
send this error message to complete callback function
to display the error message of Repeated attempts.
All others, send HCI_ERR_AUTH_FAILURE. */
if (reason == HCI_ERR_REPEATED_ATTEMPTS) {
result = HCI_ERR_REPEATED_ATTEMPTS;
} else if (old_pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) {
result = HCI_ERR_HOST_REJECT_SECURITY;
}
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, result);
}
}
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, p_dev_rec->bd_addr, HCI_SUCCESS);
/* see sec_flags processing in btm_acl_removed */
@@ -4625,26 +4645,6 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
}
BTM_TRACE_EVENT("%s after update sec_flags=0x%x\n", __func__, p_dev_rec->sec_flags);
/* If we are in the process of bonding we need to tell client that auth failed */
if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
&& (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)) {
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
if (btm_cb.api.p_auth_complete_callback) {
/* If the disconnection reason is REPEATED_ATTEMPTS,
send this error message to complete callback function
to display the error message of Repeated attempts.
All others, send HCI_ERR_AUTH_FAILURE. */
if (reason == HCI_ERR_REPEATED_ATTEMPTS) {
result = HCI_ERR_REPEATED_ATTEMPTS;
} else if (old_pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) {
result = HCI_ERR_HOST_REJECT_SECURITY;
}
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, result);
}
}
}
/*******************************************************************************

View File

@@ -413,7 +413,6 @@ tBTM_STATUS btm_ble_start_adv(void);
tBTM_STATUS btm_ble_stop_adv(void);
tBTM_STATUS btm_ble_start_scan(void);
void btm_ble_create_ll_conn_complete (UINT8 status);
void btm_ble_create_conn_cancel_complete (UINT8 *p);
/* LE security function from btm_sec.c */
#if SMP_INCLUDED == TRUE

View File

@@ -707,10 +707,6 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p)
handle = HCID_GET_HANDLE (handle);
if (reason != HCI_ERR_PEER_USER && reason != HCI_ERR_CONN_CAUSE_LOCAL_HOST) {
HCI_TRACE_WARNING("DiscCmpl evt: hdl=%d, rsn=0x%x", handle, reason);
}
#if BTM_SCO_INCLUDED == TRUE
/* If L2CAP doesn't know about it, send it to SCO */
if (!l2c_link_hci_disc_comp (handle, reason)) {
@@ -1071,9 +1067,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
case HCI_BLE_TEST_END:
btm_ble_test_command_complete(p);
break;
case HCI_BLE_CREATE_CONN_CANCEL:
btm_ble_create_conn_cancel_complete(p);
break;
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
case HCI_BLE_ADD_DEV_RESOLVING_LIST:
@@ -1133,7 +1126,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
uint8_t status;
STREAM_TO_UINT8 (status, p);
if(status != HCI_SUCCESS) {
HCI_TRACE_ERROR("CC evt: op=0x%x, status=0x%x", opcode, status);
HCI_TRACE_ERROR("%s opcode 0x%x status 0x%x", __func__, opcode, status);
}
break;
}
@@ -1266,7 +1259,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
{
uint8_t btm_status = BTM_SUCCESS;
if(status != HCI_SUCCESS) {
HCI_TRACE_ERROR("CS evt: LE PA CreateSync status=0x%x", status);
HCI_TRACE_ERROR("%s, Create sync error, the error code = 0x%x", __func__, status);
btm_status = BTM_ILLEGAL_VALUE;
}
btm_create_sync_callback(btm_status);
@@ -1276,7 +1269,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
{
uint8_t btm_status = BTM_SUCCESS;
if(status != HCI_SUCCESS) {
HCI_TRACE_ERROR("CS evt: LE SetPhy status=0x%x", status);
HCI_TRACE_ERROR("%s, Set phy error, the error code = 0x%x", __func__, status);
btm_status = BTM_ILLEGAL_VALUE;
}
btm_set_phy_callback(btm_status);
@@ -2071,8 +2064,6 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
UINT8 num_reports = {0};
//UINT8 legacy_event_type = 0;
UINT16 evt_type = 0;
uint8_t addr_type;
BD_ADDR bda;
if (!p) {
HCI_TRACE_ERROR("%s, Invalid params.", __func__);
@@ -2104,16 +2095,8 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
}
}
STREAM_TO_UINT8(addr_type, p);
STREAM_TO_BDADDR(bda, p);
// If it is an anonymous adv, skip address resolution
if(addr_type != 0xFF) {
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
btm_identity_addr_to_random_pseudo(bda, &addr_type, FALSE);
#endif
}
ext_adv_report.addr_type = addr_type;
memcpy(ext_adv_report.addr, bda, 6);
STREAM_TO_UINT8(ext_adv_report.addr_type, p);
STREAM_TO_BDADDR(ext_adv_report.addr, p);
STREAM_TO_UINT8(ext_adv_report.primary_phy, p);
STREAM_TO_UINT8(ext_adv_report.secondry_phy, p);
STREAM_TO_UINT8(ext_adv_report.sid, p);

View File

@@ -1568,8 +1568,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
UINT16_TO_STREAM(pp, params->conn_interval_max);
UINT16_TO_STREAM(pp, params->conn_latency);
UINT16_TO_STREAM(pp, params->sup_timeout);
UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
UINT16_TO_STREAM(pp, params->min_ce_len);
UINT16_TO_STREAM(pp, params->max_ce_len);
}
if (p_conn->init_phy_mask & 0x02) {
@@ -1580,8 +1580,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
UINT16_TO_STREAM(pp, params->conn_interval_max);
UINT16_TO_STREAM(pp, params->conn_latency);
UINT16_TO_STREAM(pp, params->sup_timeout);
UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
UINT16_TO_STREAM(pp, params->min_ce_len);
UINT16_TO_STREAM(pp, params->max_ce_len);
}
if (p_conn->init_phy_mask & 0x04) {
@@ -1592,8 +1592,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
UINT16_TO_STREAM(pp, params->conn_interval_max);
UINT16_TO_STREAM(pp, params->conn_latency);
UINT16_TO_STREAM(pp, params->sup_timeout);
UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
UINT16_TO_STREAM(pp, params->min_ce_len);
UINT16_TO_STREAM(pp, params->max_ce_len);
}
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);

View File

@@ -168,11 +168,7 @@ typedef UINT8 tBTM_BLE_SFP;
/* default connection interval max */
#ifndef BTM_BLE_CONN_INT_MAX_DEF
#if CONFIG_IDF_TARGET_ESP32
#define BTM_BLE_CONN_INT_MAX_DEF 12 /* recommended max: 15 ms = 12 * 1.25 */
#else
#define BTM_BLE_CONN_INT_MAX_DEF (((MAX_ACL_CONNECTIONS + 1) * 4) > 12 ? ((MAX_ACL_CONNECTIONS + 1) * 4) : 12) /* recommended max: BTM_BLE_CONN_INT_MAX_DEF * 1.25 ms*/
#endif
#endif
/* default slave latency */
@@ -704,6 +700,8 @@ typedef void (tBTM_BLE_PF_PARAM_CBACK) (tBTM_BLE_PF_ACTION action_type,
#define MAX_BLE_ADV_INSTANCE 10
typedef struct {
UINT8 inst_id;
BOOLEAN in_use;
UINT8 adv_evt;
BOOLEAN configured;
BOOLEAN legacy_pdu;
@@ -716,6 +714,7 @@ typedef struct {
typedef struct {
tBTM_BLE_EXTENDED_INST inst[MAX_BLE_ADV_INSTANCE]; /* dynamic array to store adv instance */
UINT8 scan_duplicate;
tBTM_BLE_MULTI_ADV_OPQ op_q;
} tBTM_BLE_EXTENDED_CB;
#define BTM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE (1 << 0)

View File

@@ -455,9 +455,6 @@ typedef struct t_l2c_linkcb {
/* connection parameters update order:
waiting_update_conn_xx -> updating_conn_xx -> current_used_conn_xx
*/
/* create connection retry count*/
UINT8 retry_create_con;
UINT32 start_time_s;
#endif
#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
@@ -600,7 +597,6 @@ extern BOOLEAN l2cu_start_post_bond_timer (UINT16 handle);
extern void l2cu_release_lcb (tL2C_LCB *p_lcb);
extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport);
extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle);
extern uint8_t l2cu_plcb_active_count(void);
extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding);
extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb);

View File

@@ -1833,7 +1833,7 @@ UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
}
// If already congested, do not accept any more packets
if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent && fixed_cid != L2CAP_SMP_CID) {
if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
L2CAP_TRACE_DEBUG ("L2CAP - CID: 0x%04x cannot send, already congested\
xmit_hold_q.count: %u buff_quota: %u", fixed_cid,
fixed_queue_length(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q),

View File

@@ -51,7 +51,6 @@ const tHCI_ExtConnParams ext_conn_params = {
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb);
extern int64_t esp_system_get_time(void);
/*******************************************************************************
**
@@ -205,10 +204,6 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
if (p_lcb->current_used_conn_interval <= BTM_BLE_CONN_INT_MAX_DEF && (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0){
return (FALSE);
}
bool is_disable = (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE);
if(l2cu_plcb_active_count() >1 && !(enable && is_disable)) {
return FALSE;
}
if (enable) {
p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE;
@@ -368,7 +363,7 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
p_dev_rec->conn_params.max_conn_int,
p_dev_rec->conn_params.slave_latency,
p_dev_rec->conn_params.supervision_tout,
BLE_CE_LEN_MIN, BLE_CE_LEN_MIN);
0, 0);
}
/* Tell BTM Acl management about the link */
@@ -529,7 +524,7 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb)
#endif
) {
btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, min_conn_int, max_conn_int,
slave_latency, supervision_tout, BLE_CE_LEN_MIN, BLE_CE_LEN_MIN);
slave_latency, supervision_tout, 0, 0);
} else {
l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout);
}
@@ -557,7 +552,7 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb)
#endif
) {
btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->waiting_update_conn_min_interval,
p_lcb->waiting_update_conn_max_interval, p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout, BLE_CE_LEN_MIN, BLE_CE_LEN_MIN);
p_lcb->waiting_update_conn_max_interval, p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout, 0, 0);
} else {
l2cu_send_peer_ble_par_req (p_lcb, p_lcb->waiting_update_conn_min_interval, p_lcb->waiting_update_conn_max_interval,
p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout);
@@ -596,7 +591,7 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in
/* See if we have a link control block for the remote device */
p_lcb = l2cu_find_lcb_by_handle(handle);
if (!p_lcb) {
L2CAP_TRACE_WARNING("le con upd: inv hdl=%d", handle);
L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Invalid handle: %d", handle);
return;
}
if (status == HCI_SUCCESS){
@@ -604,7 +599,7 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in
p_lcb->current_used_conn_latency = conn_latency;
p_lcb->current_used_conn_timeout = conn_timeout;
}else{
L2CAP_TRACE_WARNING("le con upd: err_stat=0x%x", status);
L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Error status: %d", status);
}
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
@@ -622,7 +617,7 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in
btu_stop_timer (&p_lcb->timer_entry);
L2CAP_TRACE_DEBUG("le con upd: conn_update_mask=%d", p_lcb->conn_update_mask);
L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt: conn_update_mask=%d", p_lcb->conn_update_mask);
}
/*******************************************************************************
@@ -806,6 +801,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
#if ( (defined BLE_PRIVACY_SPT) && (BLE_PRIVACY_SPT == TRUE))
own_addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type;
#if (!CONTROLLER_RPA_LIST_ENABLE)
if(dev_rec_exist) {
// if the current address information is valid, get the real address information
@@ -829,7 +825,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
#endif // (!CONTROLLER_RPA_LIST_ENABLE)
#if (CONTROLLER_RPA_LIST_ENABLE)
#if CONTROLLER_RPA_LIST_ENABLE
if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) {
if (btm_cb.ble_ctr_cb.privacy_mode >= BTM_PRIVACY_1_2) {
@@ -843,6 +839,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
}
#endif // CONTROLLER_RPA_LIST_ENABLE
#endif // (defined BLE_PRIVACY_SPT) && (BLE_PRIVACY_SPT == TRUE)
if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) {
@@ -850,18 +847,6 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation");
return FALSE;
}
uint32_t link_timeout = L2CAP_BLE_LINK_CONNECT_TOUT;
if(GATTC_CONNECT_RETRY_COUNT) {
if(!p_lcb->retry_create_con) {
p_lcb->start_time_s = (esp_system_get_time()/1000);
}
uint32_t current_time = (esp_system_get_time()/1000);
link_timeout = (L2CAP_BLE_LINK_CONNECT_TOUT*1000 - (current_time - p_lcb->start_time_s))/1000;
if(link_timeout == 0 || link_timeout > L2CAP_BLE_LINK_CONNECT_TOUT) {
link_timeout = L2CAP_BLE_LINK_CONNECT_TOUT;
}
}
if (!p_lcb->is_aux) {
if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */
@@ -878,8 +863,8 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */
(UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */
BLE_CE_LEN_MIN, /* UINT16 min_len */
BLE_CE_LEN_MIN)) { /* UINT16 max_len */
0, /* UINT16 min_len */
0)) { /* UINT16 max_len */
l2cu_release_lcb (p_lcb);
L2CAP_TRACE_ERROR("initate direct connection fail, no resources");
return (FALSE);
@@ -887,28 +872,13 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
p_lcb->link_state = LST_CONNECTING;
l2cb.is_ble_connecting = TRUE;
memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, link_timeout);
btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
btm_ble_set_conn_st (BLE_DIR_CONN);
return (TRUE);
}
} else {
#if (BLE_50_FEATURE_SUPPORT == TRUE)
/*
* 0x00 Public Device Address
* 0x01 Random Device Address
* 0x02 Public Identity Address (corresponds to Resolved Private Address)
* 0x03 Random (static) Identity Address (corresponds to Resolved Private Address)
* 0xFF No address provided (anonymous advertisement)
*/
if ((peer_addr_type & BLE_ADDR_RANDOM) == BLE_ADDR_RANDOM) {
peer_addr_type = BLE_ADDR_RANDOM;
} else {
peer_addr_type = BLE_ADDR_PUBLIC;
}
tHCI_CreatExtConn aux_conn = {0};
aux_conn.filter_policy = FALSE;
aux_conn.own_addr_type = own_addr_type;
@@ -929,7 +899,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
p_lcb->link_state = LST_CONNECTING;
l2cb.is_ble_connecting = TRUE;
memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, link_timeout);
btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
btm_ble_set_conn_st (BLE_DIR_CONN);
if(!btsnd_hcic_ble_create_ext_conn(&aux_conn)) {
l2cu_release_lcb (p_lcb);
@@ -1134,12 +1104,12 @@ void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 i
/* if update is enabled, always accept connection parameter update */
if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) {
p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, BLE_CE_LEN_MIN, BLE_CE_LEN_MIN);
btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
}else {
/* always accept connection parameters request which is sent by itself */
if (int_max == BTM_BLE_CONN_INT_MIN) {
p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, BLE_CE_LEN_MIN, BLE_CE_LEN_MIN);
btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
}else {
L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled");
p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;

View File

@@ -42,11 +42,6 @@
static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
extern tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t handle);
#endif// #if (BLE_50_FEATURE_SUPPORT == TRUE)
extern bool btm_ble_inter_get(void);
/*******************************************************************************
**
** Function l2c_link_hci_conn_req
@@ -338,6 +333,7 @@ void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data
}
}
/*******************************************************************************
**
** Function l2c_link_hci_disc_comp
@@ -460,38 +456,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
}
p_lcb->p_pending_ccb = NULL;
#if (BLE_INCLUDED == TRUE && GATTC_CONNECT_RETRY_EN == TRUE)
if(reason == HCI_ERR_CONN_FAILED_ESTABLISHMENT && p_lcb->transport == BT_TRANSPORT_LE) {
if(p_lcb->link_role == HCI_ROLE_MASTER && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) {
L2CAP_TRACE_DEBUG("master retry connect, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason);
p_lcb->retry_create_con ++;
// create connection retry
if (l2cu_create_conn(p_lcb, BT_TRANSPORT_LE)) {
btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
lcb_is_free = FALSE; /* still using this lcb */
}
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
if(btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) {
p_lcb->retry_create_con ++;
L2CAP_TRACE_DEBUG("slave restart extend adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason);
BTM_BleStartExtAdvRestart(handle);
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_42_FEATURE_SUPPORT == TRUE)
if(!btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) {
p_lcb->retry_create_con ++;
L2CAP_TRACE_DEBUG("slave resatrt adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason);
btm_ble_start_adv();
}
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
}
#endif // #if (BLE_INCLUDED == TRUE)
/* Release the LCB */
if (lcb_is_free) {
l2cu_release_lcb (p_lcb);

View File

@@ -158,10 +158,6 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
p_lcb->in_use = FALSE;
p_lcb->is_bonding = FALSE;
#if (BLE_INCLUDED == TRUE)
p_lcb->retry_create_con = 0;
p_lcb->start_time_s = 0;
#endif // #if (BLE_INCLUDED == TRUE)
/* Stop and release timers */
btu_free_timer (&p_lcb->timer_entry);
@@ -339,26 +335,6 @@ tL2C_LCB *l2cu_find_free_lcb (void)
return (NULL);
}
uint8_t l2cu_plcb_active_count(void)
{
list_node_t *p_node = NULL;
tL2C_LCB *p_lcb = NULL;
uint8_t active_count = 0;
for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
p_lcb = list_node(p_node);
if (p_lcb && p_lcb->in_use) {
active_count ++;
}
}
if (active_count >= MAX_L2CAP_CHANNELS) {
L2CAP_TRACE_ERROR("error active count");
active_count = 0;
}
L2CAP_TRACE_DEBUG("plcb active count %d", active_count);
return active_count;
}
/*******************************************************************************
**
** Function l2cu_get_conn_role
@@ -1480,11 +1456,9 @@ void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
** Returns pointer to CCB, or NULL if none
**
*******************************************************************************/
bool l2cu_find_ccb_in_list(void *p_ccb_node, void *p_local_cid);
tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
{
tL2C_CCB *p_ccb = NULL;
uint16_t tmp_cid = L2CAP_BASE_APPL_CID;
L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x", cid);
p_ccb = l2cu_find_free_ccb ();
@@ -1507,13 +1481,7 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
p_ccb->in_use = TRUE;
/* Get a CID for the connection */
for (tmp_cid = L2CAP_BASE_APPL_CID; tmp_cid < MAX_L2CAP_CHANNELS + L2CAP_BASE_APPL_CID; tmp_cid++) {
if (list_foreach(l2cb.p_ccb_pool, l2cu_find_ccb_in_list, &tmp_cid) == NULL) {
break;
}
}
assert(tmp_cid != MAX_L2CAP_CHANNELS + L2CAP_BASE_APPL_CID);
p_ccb->local_cid = tmp_cid;
p_ccb->local_cid = L2CAP_BASE_APPL_CID + (list_length(l2cb.p_ccb_pool) - 1);
p_ccb->p_lcb = p_lcb;
p_ccb->p_rcb = NULL;
p_ccb->should_free_rcb = false;

View File

@@ -1540,11 +1540,9 @@ void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
*******************************************************************************/
void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
if(p_cb->role == BTM_ROLE_MASTER) {
L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
}
#endif
#if (SMP_SLAVE_CON_PARAMS_UPD_ENABLE == TRUE)
else {
tBTM_SEC_DEV_REC *p_rec = btm_find_dev (p_cb->pairing_bda);
@@ -1556,9 +1554,7 @@ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
some peripherals are not able to revert to fast connection parameters
during the start of service discovery. Connection paramter updates
get enabled again once service discovery completes. */
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
#endif
}
#endif
}

View File

@@ -1021,9 +1021,7 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
//clear flag
p_rec->ble.skip_update_conn_param = false;
} else {
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, TRUE);
#endif
}
}

View File

@@ -72,15 +72,11 @@ config BT_NIMBLE_LOG_LEVEL
config BT_NIMBLE_MAX_CONNECTIONS
int "Maximum number of concurrent connections"
range 1 8 if (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
range 1 9 if IDF_TARGET_ESP32
default 3
range 1 9
default BTDM_CTRL_BLE_MAX_CONN
depends on BT_NIMBLE_ENABLED
help
Defines maximum number of concurrent BLE connections. For ESP32, user
is expected to configure BTDM_CTRL_BLE_MAX_CONN from controller menu
along with this option. Similarly for ESP32-C3 or ESP32-S3, user is expected to
configure BT_CTRL_BLE_MAX_ACT from controller menu.
Defines maximum number of concurrent BLE connections
config BT_NIMBLE_MAX_BONDS
int "Maximum number of bonds to save across reboots"
@@ -435,22 +431,6 @@ config BT_NIMBLE_HOST_BASED_PRIVACY
Use this option to do host based Random Private Address resolution.
If this option is disabled then controller based privacy is used.
config BT_NIMBLE_ENABLE_CONN_REATTEMPT
bool "Enable connection reattempts on connection establishment error"
default y if (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
default n if IDF_TARGET_ESP32
help
Enable to make the NimBLE host to reattempt GAP connection on connection
establishment failure.
config BT_NIMBLE_MAX_CONN_REATTEMPT
int "Maximum number connection reattempts"
range 1 7
default 3
depends on BT_NIMBLE_ENABLED && BT_NIMBLE_ENABLE_CONN_REATTEMPT
help
Defines maximum number of connection reattempts.
config BT_NIMBLE_EXT_ADV
bool "Enable extended advertising."
default n

View File

@@ -252,7 +252,6 @@ static struct os_mbuf *ble_hci_trans_acl_buf_alloc(void)
static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
{
struct os_mbuf *m;
int rc;
int sr;
if (len < BLE_HCI_DATA_HDR_SZ || len > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) {
return;
@@ -261,11 +260,9 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
m = ble_hci_trans_acl_buf_alloc();
if (!m) {
ESP_LOGE(TAG, "%s failed to allocate ACL buffers; increase ACL_BUF_COUNT", __func__);
return;
}
if ((rc = os_mbuf_append(m, data, len)) != 0) {
ESP_LOGE(TAG, "%s failed to os_mbuf_append; rc = %d", __func__, rc);
if (os_mbuf_append(m, data, len)) {
os_mbuf_free_chain(m);
return;
}

View File

@@ -488,7 +488,6 @@ esp_err_t esp_bt_sleep_disable(void);
* Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached
* the amount of device in the filter can be configured in menuconfig.
*
* @note This function name is incorrectly spelled, it will be fixed in release 5.x version.
*
* @return
* - ESP_OK : success

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
#define ESP_BT_CTRL_CONFIG_MAGIC_VAL 0x5A5AA5A5
#define ESP_BT_CTRL_CONFIG_VERSION 0x02103310
#define ESP_BT_CTRL_CONFIG_VERSION 0x02101290
#define ESP_BT_HCI_TL_MAGIC_VALUE 0xfadebead
#define ESP_BT_HCI_TL_VERSION 0x00010000
@@ -96,7 +96,6 @@ enum {
#ifdef CONFIG_BT_ENABLED
#define BT_CTRL_BLE_MAX_ACT_LIMIT 10 //Maximum BLE activity limitation
#define SLAVE_CE_LEN_MIN_DEFAULT 5
#ifdef CONFIG_BT_CTRL_SCAN_DUPL_TYPE
#define SCAN_DUPLICATE_TYPE_VALUE CONFIG_BT_CTRL_SCAN_DUPL_TYPE
@@ -134,8 +133,6 @@ enum {
#define CFG_NASK CFG_MASK_BIT_SCAN_DUPLICATE_OPTION
#define BLE_HW_TARGET_CODE_ESP32C3_CHIP_ECO0 (0x01010000)
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL, \
.version = ESP_BT_CTRL_CONFIG_VERSION, \
@@ -161,8 +158,6 @@ enum {
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
.coex_phy_coded_tx_rx_time_limit = CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF, \
.hw_target_code = BLE_HW_TARGET_CODE_ESP32C3_CHIP_ECO0, \
.slave_ce_len_min = SLAVE_CE_LEN_MIN_DEFAULT, \
};
#else
@@ -226,8 +221,6 @@ typedef struct {
uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
uint8_t coex_phy_coded_tx_rx_time_limit; /*!< limit on max tx/rx time in case of connection using CODED-PHY with Wi-Fi coexistence */
uint32_t hw_target_code; /*!< hardware target */
uint8_t slave_ce_len_min;
} esp_bt_controller_config_t;
/**
@@ -270,23 +263,22 @@ typedef enum {
* @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm).
*/
typedef enum {
ESP_PWR_LVL_N27 = 0, /*!< Corresponding to -27dbm */
ESP_PWR_LVL_N24 = 1, /*!< Corresponding to -24dbm */
ESP_PWR_LVL_N21 = 2, /*!< Corresponding to -21dbm */
ESP_PWR_LVL_N18 = 3, /*!< Corresponding to -18dbm */
ESP_PWR_LVL_N15 = 4, /*!< Corresponding to -15dbm */
ESP_PWR_LVL_N12 = 5, /*!< Corresponding to -12dbm */
ESP_PWR_LVL_N9 = 6, /*!< Corresponding to -9dbm */
ESP_PWR_LVL_N6 = 7, /*!< Corresponding to -6dbm */
ESP_PWR_LVL_N3 = 8, /*!< Corresponding to -3dbm */
ESP_PWR_LVL_N0 = 9, /*!< Corresponding to 0dbm */
ESP_PWR_LVL_P3 = 10, /*!< Corresponding to +3dbm */
ESP_PWR_LVL_P6 = 11, /*!< Corresponding to +6dbm */
ESP_PWR_LVL_P9 = 12, /*!< Corresponding to +9dbm */
ESP_PWR_LVL_P12 = 13, /*!< Corresponding to +12dbm */
ESP_PWR_LVL_P15 = 14, /*!< Corresponding to +15dbm */
ESP_PWR_LVL_P18 = 15, /*!< Corresponding to +18dbm */
ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */
ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12dbm */
ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9dbm */
ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6dbm */
ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3dbm */
ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0dbm */
ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3dbm */
ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6dbm */
ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9dbm */
ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14dbm will actually result to -12dbm */
ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11dbm will actually result to -9dbm */
ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8dbm will actually result to -6dbm */
ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5dbm will actually result to -3dbm */
ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2dbm will actually result to 0dbm */
ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1dbm will actually result to +3dbm */
ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4dbm will actually result to +6dbm */
ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7dbm will actually result to +9dbm */
} esp_power_level_t;
/**

View File

@@ -76,8 +76,7 @@ idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${includes}
PRIV_INCLUDE_DIRS "include/driver"
PRIV_REQUIRES efuse esp_pm esp_timer esp_ipc
REQUIRES esp_ringbuf freertos soc hal esp_hw_support
LDFRAGMENTS linker.lf)
REQUIRES esp_ringbuf freertos soc hal esp_hw_support)
# (REQUIRES cannot hide soc headers, since many arguments in the driver headers are chip-dependent)
# uses C11 atomic feature

View File

@@ -87,48 +87,6 @@ menu "Driver configurations"
- Alert logging (i.e., setting of the TWAI_ALERT_AND_LOG flag)
will have no effect.
config TWAI_ERRATA_FIX_BUS_OFF_REC
bool "Add SW workaround for REC change during bus-off"
depends on IDF_TARGET_ESP32
default n
help
When the bus-off condition is reached, the REC should be reset to 0 and frozen (via LOM) by the
driver's ISR. However on the ESP32, there is an edge case where the REC will increase before the
driver's ISR can respond in time (e.g., due to the rapid occurrence of bus errors), thus causing the
REC to be non-zero after bus-off. A non-zero REC can prevent bus-off recovery as the bus-off recovery
condition is that both TEC and REC become 0. Enabling this option will add a workaround in the driver
to forcibly reset REC to zero on reaching bus-off.
config TWAI_ERRATA_FIX_TX_INTR_LOST
bool "Add SW workaround for TX interrupt lost errata"
depends on IDF_TARGET_ESP32
default n
help
On the ESP32, when a transmit interrupt occurs, and interrupt register is read on the same APB clock
cycle, the transmit interrupt could be lost. Enabling this option will add a workaround that checks the
transmit buffer status bit to recover any lost transmit interrupt.
config TWAI_ERRATA_FIX_RX_FRAME_INVALID
bool "Add SW workaround for invalid RX frame errata"
depends on IDF_TARGET_ESP32
default n
help
On the ESP32, when receiving a data or remote frame, if a bus error occurs in the data or CRC field,
the data of the next received frame could be invalid. Enabling this option will add a workaround that
will reset the peripheral on detection of this errata condition. Note that if a frame is transmitted on
the bus whilst the reset is ongoing, the message will not be receive by the peripheral sent on the bus
during the reset, the message will be lost.
config TWAI_ERRATA_FIX_RX_FIFO_CORRUPT
bool "Add SW workaround for RX FIFO corruption errata"
depends on IDF_TARGET_ESP32
default n
help
On the ESP32, when the RX FIFO overruns and the RX message counter maxes out at 64 messages, the entire
RX FIFO is no longer recoverable. Enabling this option will add a workaround that resets the peripheral
on detection of this errata condition. Note that if a frame is being sent on the bus during the reset
bus during the reset, the message will be lost.
endmenu # TWAI Configuration
menu "UART configuration"

View File

@@ -160,12 +160,17 @@ static void adc_power_on_internal(void)
void adc_power_acquire(void)
{
bool powered_on = false;
ADC_POWER_ENTER();
s_adc_power_on_cnt++;
if (s_adc_power_on_cnt == 1) {
adc_power_on_internal();
powered_on = true;
}
ADC_POWER_EXIT();
if (powered_on) {
ESP_LOGV(ADC_TAG, "%s: ADC powered on", __func__);
}
}
void adc_power_on(void)
@@ -177,15 +182,12 @@ void adc_power_on(void)
static void adc_power_off_internal(void)
{
#if CONFIG_IDF_TARGET_ESP32
adc_hal_set_power_manage(ADC_POWER_SW_OFF);
#else
adc_hal_set_power_manage(ADC_POWER_BY_FSM);
#endif
}
void adc_power_release(void)
{
bool powered_off = false;
ADC_POWER_ENTER();
s_adc_power_on_cnt--;
/* Sanity check */
@@ -195,8 +197,12 @@ void adc_power_release(void)
abort();
} else if (s_adc_power_on_cnt == 0) {
adc_power_off_internal();
powered_off = true;
}
ADC_POWER_EXIT();
if (powered_off) {
ESP_LOGV(ADC_TAG, "%s: ADC powered off", __func__);
}
}
void adc_power_off(void)
@@ -206,33 +212,6 @@ void adc_power_off(void)
ADC_POWER_EXIT();
}
esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num)
{
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
int io = ADC_GET_IO_NUM(ADC_NUM_1, channel);
if (io < 0) {
return ESP_ERR_INVALID_ARG;
} else {
*gpio_num = (gpio_num_t)io;
}
return ESP_OK;
}
esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num)
{
ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
int io = ADC_GET_IO_NUM(ADC_NUM_2, channel);
if (io < 0) {
return ESP_ERR_INVALID_ARG;
} else {
*gpio_num = (gpio_num_t)io;
}
return ESP_OK;
}
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
esp_err_t adc_set_clk_div(uint8_t clk_div)
@@ -344,6 +323,20 @@ esp_err_t adc_rtc_reset(void)
/*-------------------------------------------------------------------------------------
* ADC1
*------------------------------------------------------------------------------------*/
esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num)
{
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
int io = ADC_GET_IO_NUM(ADC_NUM_1, channel);
if (io < 0) {
return ESP_ERR_INVALID_ARG;
} else {
*gpio_num = (gpio_num_t)io;
}
return ESP_OK;
}
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
{
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
@@ -473,6 +466,20 @@ void adc1_ulp_enable(void)
/*---------------------------------------------------------------
ADC2
---------------------------------------------------------------*/
esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num)
{
ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
int io = ADC_GET_IO_NUM(ADC_NUM_2, channel);
if (io < 0) {
return ESP_ERR_INVALID_ARG;
} else {
*gpio_num = (gpio_num_t)io;
}
return ESP_OK;
}
/** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock.*/
esp_err_t adc2_wifi_acquire(void)
{
@@ -555,7 +562,6 @@ static inline void adc2_dac_disable( adc2_channel_t channel)
*/
esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out)
{
esp_err_t ret = ESP_OK;
int adc_value = 0;
ADC_CHECK(raw_out != NULL, "ADC out value err", ESP_ERR_INVALID_ARG);
@@ -595,8 +601,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
#endif //CONFIG_PM_ENABLE
#endif //CONFIG_IDF_TARGET_ESP32
ret = adc_hal_convert(ADC_NUM_2, channel, &adc_value);
if (ret != ESP_OK) {
if (adc_hal_convert(ADC_NUM_2, channel, &adc_value)) {
adc_value = -1;
}
@@ -613,8 +618,13 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
adc_power_release();
SARADC2_RELEASE();
if (adc_value < 0) {
ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." );
return ESP_ERR_INVALID_STATE;
}
*raw_out = adc_value;
return ret;
return ESP_OK;
}
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)

View File

@@ -25,7 +25,6 @@
#include "soc/io_mux_reg.h"
#include "hal/cpu_hal.h"
#include "hal/cpu_ll.h"
#include "hal/gpio_hal.h"
#include "driver/periph_ctrl.h"
#include "esp_rom_gpio.h"
#include "freertos/FreeRTOS.h"
@@ -268,13 +267,13 @@ esp_err_t dedic_gpio_new_bundle(const dedic_gpio_bundle_config_t *config, dedic_
// route dedicated GPIO channel signals to GPIO matrix
if (config->flags.in_en) {
for (size_t i = 0; i < config->array_size; i++) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->gpio_array[i]], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->gpio_array[i]], PIN_FUNC_GPIO);
esp_rom_gpio_connect_in_signal(config->gpio_array[i], dedic_gpio_periph_signals.cores[core_id].in_sig_per_channel[in_offset + i], config->flags.in_invert);
}
}
if (config->flags.out_en) {
for (size_t i = 0; i < config->array_size; i++) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->gpio_array[i]], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->gpio_array[i]], PIN_FUNC_GPIO);
esp_rom_gpio_connect_out_signal(config->gpio_array[i], dedic_gpio_periph_signals.cores[core_id].out_sig_per_channel[out_offset + i], config->flags.out_invert, false);
}
}

View File

@@ -135,7 +135,6 @@ esp_err_t adc_digi_init(void)
esp_err_t adc_digi_deinit(void)
{
adc_power_release();
ADC_ENTER_CRITICAL();
adc_hal_digi_deinit();
ADC_EXIT_CRITICAL();
@@ -144,8 +143,6 @@ esp_err_t adc_digi_deinit(void)
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
{
/* If enable digital controller, adc xpd should always on. */
adc_power_acquire();
ADC_ENTER_CRITICAL();
adc_hal_digi_controller_config(config);
ADC_EXIT_CRITICAL();

View File

@@ -19,7 +19,6 @@
#include "sdkconfig.h"
#include "esp_intr_alloc.h"
#include "esp_log.h"
#include "esp_pm.h"
#include "sys/lock.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
@@ -33,7 +32,6 @@
#include "hal/adc_hal.h"
#include "hal/dma_types.h"
#include "esp32c3/esp_efuse_rtc_calib.h"
#include "esp_private/gdma.h"
#define ADC_CHECK_RET(fun_ret) ({ \
if (fun_ret != ESP_OK) { \
@@ -59,34 +57,37 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi
#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
/*---------------------------------------------------------------
Digital Controller Context
---------------------------------------------------------------*/
/**
* 1. sar_adc1_lock: this mutex lock is to protect the SARADC1 module.
* 2. sar_adc2_lock: this mutex lock is to protect the SARADC2 module. On C3, it is controlled by the digital controller
* and PWDET controller.
* 3. adc_reg_lock: this spin lock is to protect the shared registers used by ADC1 / ADC2 single read mode.
* 1. adc_digi_mutex: this mutex lock is used for ADC digital controller. On ESP32-C3, the ADC single read APIs (unit1 & unit2)
* and ADC DMA continuous read APIs share the ``apb_saradc_struct.h`` regs.
*
* 2. sar_adc_mutex: this mutex lock is used for SARADC2 module. On ESP32C-C3, the ADC single read APIs (unit2), ADC DMA
* continuous read APIs and WIFI share the SARADC2 analog IP.
*
* Sequence:
* Acquire: 1. sar_adc_mutex; 2. adc_digi_mutex;
* Release: 1. adc_digi_mutex; 2. sar_adc_mutex;
*/
static _lock_t sar_adc1_lock;
#define SAR_ADC1_LOCK_ACQUIRE() _lock_acquire(&sar_adc1_lock)
#define SAR_ADC1_LOCK_RELEASE() _lock_release(&sar_adc1_lock)
static _lock_t sar_adc2_lock;
#define SAR_ADC2_LOCK_ACQUIRE() _lock_acquire(&sar_adc2_lock)
#define SAR_ADC2_LOCK_RELEASE() _lock_release(&sar_adc2_lock)
portMUX_TYPE adc_reg_lock = portMUX_INITIALIZER_UNLOCKED;
#define ADC_REG_LOCK_ENTER() portENTER_CRITICAL(&adc_reg_lock)
#define ADC_REG_LOCK_EXIT() portEXIT_CRITICAL(&adc_reg_lock)
static _lock_t adc_digi_mutex;
#define ADC_DIGI_LOCK_ACQUIRE() _lock_acquire(&adc_digi_mutex)
#define ADC_DIGI_LOCK_RELEASE() _lock_release(&adc_digi_mutex)
static _lock_t sar_adc2_mutex;
#define SAC_ADC2_LOCK_ACQUIRE() _lock_acquire(&sar_adc2_mutex)
#define SAC_ADC2_LOCK_RELEASE() _lock_release(&sar_adc2_mutex)
#define INTERNAL_BUF_NUM 5
#define IN_SUC_EOF_BIT GDMA_LL_EVENT_RX_SUC_EOF
/*---------------------------------------------------------------
Digital Controller Context
---------------------------------------------------------------*/
typedef struct adc_digi_context_t {
intr_handle_t dma_intr_hdl; //MD interrupt handle
uint32_t bytes_between_intr; //bytes between in suc eof intr
uint8_t *rx_dma_buf; //dma buffer
adc_hal_context_t hal; //hal context
gdma_channel_handle_t rx_dma_channel; //dma rx channel handle
adc_dma_hal_context_t hal_dma; //dma context (hal)
adc_dma_hal_config_t hal_dma_config; //dma config (hal)
RingbufHandle_t ringbuf_hdl; //RX ringbuffer handler
intptr_t rx_eof_desc_addr; //eof descriptor address of RX channel
bool ringbuf_overflow_flag; //1: ringbuffer overflow
bool driver_start_flag; //1: driver is started; 0: driver is stoped
bool use_adc1; //1: ADC unit1 will be used; 0: ADC unit1 won't be used.
@@ -94,7 +95,6 @@ typedef struct adc_digi_context_t {
adc_atten_t adc1_atten; //Attenuation for ADC1. On this chip each ADC can only support one attenuation.
adc_atten_t adc2_atten; //Attenuation for ADC2. On this chip each ADC can only support one attenuation.
adc_digi_config_t digi_controller_config; //Digital Controller Configuration
esp_pm_lock_handle_t pm_lock; //For power management
} adc_digi_context_t;
static adc_digi_context_t *s_adc_digi_ctx = NULL;
@@ -104,7 +104,7 @@ static uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t cha
/*---------------------------------------------------------------
ADC Continuous Read Mode (via DMA)
---------------------------------------------------------------*/
static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data);
static void adc_dma_intr(void* arg);
static int8_t adc_digi_get_io_num(uint8_t adc_unit, uint8_t adc_channel)
{
@@ -149,6 +149,11 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config)
goto cleanup;
}
ret = esp_intr_alloc(SOC_GDMA_ADC_INTR_SOURCE, 0, adc_dma_intr, (void *)s_adc_digi_ctx, &s_adc_digi_ctx->dma_intr_hdl);
if (ret != ESP_OK) {
goto cleanup;
}
//ringbuffer
s_adc_digi_ctx->ringbuf_hdl = xRingbufferCreate(init_config->max_store_buf_size, RINGBUF_TYPE_BYTEBUF);
if (!s_adc_digi_ctx->ringbuf_hdl) {
@@ -156,19 +161,22 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config)
goto cleanup;
}
//malloc internal buffer used by DMA
s_adc_digi_ctx->rx_dma_buf = heap_caps_calloc(1, init_config->conv_num_each_intr * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL);
//malloc internal buffer
s_adc_digi_ctx->bytes_between_intr = init_config->conv_num_each_intr;
s_adc_digi_ctx->rx_dma_buf = heap_caps_calloc(1, s_adc_digi_ctx->bytes_between_intr * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL);
if (!s_adc_digi_ctx->rx_dma_buf) {
ret = ESP_ERR_NO_MEM;
goto cleanup;
}
//malloc dma descriptor
s_adc_digi_ctx->hal.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * INTERNAL_BUF_NUM, MALLOC_CAP_DMA);
if (!s_adc_digi_ctx->hal.rx_desc) {
s_adc_digi_ctx->hal_dma_config.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * INTERNAL_BUF_NUM, MALLOC_CAP_DMA);
if (!s_adc_digi_ctx->hal_dma_config.rx_desc) {
ret = ESP_ERR_NO_MEM;
goto cleanup;
}
s_adc_digi_ctx->hal_dma_config.desc_max_num = INTERNAL_BUF_NUM;
s_adc_digi_ctx->hal_dma_config.dma_chan = init_config->dma_chan;
//malloc pattern table
s_adc_digi_ctx->digi_controller_config.adc_pattern = calloc(1, SOC_ADC_PATT_LEN_MAX * sizeof(adc_digi_pattern_table_t));
@@ -177,14 +185,6 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config)
goto cleanup;
}
#if CONFIG_PM_ENABLE
ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_ctx->pm_lock);
if (ret != ESP_OK) {
goto cleanup;
}
#endif //CONFIG_PM_ENABLE
//init gpio pins
if (init_config->adc1_chan_mask) {
ret = adc_digi_gpio_init(ADC_NUM_1, init_config->adc1_chan_mask);
if (ret != ESP_OK) {
@@ -198,39 +198,8 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config)
}
}
//alloc rx gdma channel
gdma_channel_alloc_config_t rx_alloc_config = {
.direction = GDMA_CHANNEL_DIRECTION_RX,
};
ret = gdma_new_channel(&rx_alloc_config, &s_adc_digi_ctx->rx_dma_channel);
if (ret != ESP_OK) {
goto cleanup;
}
gdma_connect(s_adc_digi_ctx->rx_dma_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_ADC, 0));
gdma_strategy_config_t strategy_config = {
.auto_update_desc = true,
.owner_check = true
};
gdma_apply_strategy(s_adc_digi_ctx->rx_dma_channel, &strategy_config);
gdma_rx_event_callbacks_t cbs = {
.on_recv_eof = adc_dma_in_suc_eof_callback
};
gdma_register_rx_event_callbacks(s_adc_digi_ctx->rx_dma_channel, &cbs, s_adc_digi_ctx);
int dma_chan;
gdma_get_channel_id(s_adc_digi_ctx->rx_dma_channel, &dma_chan);
adc_hal_config_t config = {
.desc_max_num = INTERNAL_BUF_NUM,
.dma_chan = dma_chan,
.eof_num = init_config->conv_num_each_intr / ADC_HAL_DATA_LEN_PER_CONV
};
adc_hal_context_config(&s_adc_digi_ctx->hal, &config);
//enable SARADC module clock
periph_module_enable(PERIPH_SARADC_MODULE);
periph_module_enable(PERIPH_GDMA_MODULE);
adc_hal_calibration_init(ADC_NUM_1);
adc_hal_calibration_init(ADC_NUM_2);
@@ -243,42 +212,46 @@ cleanup:
}
static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx);
static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
{
assert(event_data);
adc_digi_context_t *adc_digi_ctx = (adc_digi_context_t *)user_data;
adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr;
return adc_dma_intr(adc_digi_ctx);
}
static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx)
static IRAM_ATTR void adc_dma_intr(void *arg)
{
portBASE_TYPE taskAwoken = 0;
BaseType_t ret;
adc_hal_dma_desc_status_t status = false;
dma_descriptor_t *current_desc = NULL;
while (1) {
status = adc_hal_get_reading_result(&adc_digi_ctx->hal, adc_digi_ctx->rx_eof_desc_addr, &current_desc);
if (status != ADC_HAL_DMA_DESC_VALID) {
break;
}
//clear the in suc eof interrupt
adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT);
ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, current_desc->buffer, current_desc->dw0.length, &taskAwoken);
while (s_adc_digi_ctx->hal_dma_config.cur_desc_ptr->dw0.owner == 0) {
dma_descriptor_t *current_desc = s_adc_digi_ctx->hal_dma_config.cur_desc_ptr;
ret = xRingbufferSendFromISR(s_adc_digi_ctx->ringbuf_hdl, current_desc->buffer, current_desc->dw0.length, &taskAwoken);
if (ret == pdFALSE) {
//ringbuffer overflow
adc_digi_ctx->ringbuf_overflow_flag = 1;
s_adc_digi_ctx->ringbuf_overflow_flag = 1;
}
s_adc_digi_ctx->hal_dma_config.desc_cnt += 1;
//cycle the dma descriptor and buffers
s_adc_digi_ctx->hal_dma_config.cur_desc_ptr = s_adc_digi_ctx->hal_dma_config.cur_desc_ptr->next;
if (!s_adc_digi_ctx->hal_dma_config.cur_desc_ptr) {
break;
}
}
if (status == ADC_HAL_DMA_DESC_NULL) {
if (!s_adc_digi_ctx->hal_dma_config.cur_desc_ptr) {
assert(s_adc_digi_ctx->hal_dma_config.desc_cnt == s_adc_digi_ctx->hal_dma_config.desc_max_num);
//reset the current descriptor status
s_adc_digi_ctx->hal_dma_config.cur_desc_ptr = s_adc_digi_ctx->hal_dma_config.rx_desc;
s_adc_digi_ctx->hal_dma_config.desc_cnt = 0;
//start next turns of dma operation
adc_hal_digi_rxdma_start(&adc_digi_ctx->hal, adc_digi_ctx->rx_dma_buf);
adc_hal_digi_dma_multi_descriptor(&s_adc_digi_ctx->hal_dma_config, s_adc_digi_ctx->rx_dma_buf, s_adc_digi_ctx->bytes_between_intr, s_adc_digi_ctx->hal_dma_config.desc_max_num);
adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
}
return (taskAwoken == pdTRUE);
if(taskAwoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
esp_err_t adc_digi_start(void)
@@ -287,21 +260,15 @@ esp_err_t adc_digi_start(void)
ESP_LOGE(ADC_TAG, "The driver is already started");
return ESP_ERR_INVALID_STATE;
}
adc_power_acquire();
//reset flags
s_adc_digi_ctx->ringbuf_overflow_flag = 0;
s_adc_digi_ctx->driver_start_flag = 1;
if (s_adc_digi_ctx->use_adc1) {
SAR_ADC1_LOCK_ACQUIRE();
}
if (s_adc_digi_ctx->use_adc2) {
SAR_ADC2_LOCK_ACQUIRE();
}
#if CONFIG_PM_ENABLE
// Lock APB frequency while ADC driver is in use
esp_pm_lock_acquire(s_adc_digi_ctx->pm_lock);
#endif
//When using SARADC2 module, this task needs to be protected from WIFI
if (s_adc_digi_ctx->use_adc2) {
SAC_ADC2_LOCK_ACQUIRE();
}
ADC_DIGI_LOCK_ACQUIRE();
adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
if (s_adc_digi_ctx->use_adc1) {
@@ -314,16 +281,26 @@ esp_err_t adc_digi_start(void)
}
adc_hal_init();
adc_hal_arbiter_config(&config);
adc_hal_digi_init(&s_adc_digi_ctx->hal);
adc_hal_digi_init(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
adc_hal_digi_controller_config(&s_adc_digi_ctx->digi_controller_config);
//reset ADC and DMA
adc_hal_fifo_reset(&s_adc_digi_ctx->hal);
//start DMA
adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal, s_adc_digi_ctx->rx_dma_buf);
//create dma descriptors
adc_hal_digi_dma_multi_descriptor(&s_adc_digi_ctx->hal_dma_config, s_adc_digi_ctx->rx_dma_buf, s_adc_digi_ctx->bytes_between_intr, s_adc_digi_ctx->hal_dma_config.desc_max_num);
adc_hal_digi_set_eof_num(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, (s_adc_digi_ctx->bytes_between_intr)/4);
//set the current descriptor pointer
s_adc_digi_ctx->hal_dma_config.cur_desc_ptr = s_adc_digi_ctx->hal_dma_config.rx_desc;
s_adc_digi_ctx->hal_dma_config.desc_cnt = 0;
//enable in suc eof intr
adc_hal_digi_ena_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT);
//start ADC
adc_hal_digi_start(&s_adc_digi_ctx->hal);
adc_hal_digi_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
//start DMA
adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
return ESP_OK;
}
@@ -337,27 +314,20 @@ esp_err_t adc_digi_stop(void)
s_adc_digi_ctx->driver_start_flag = 0;
//disable the in suc eof intrrupt
adc_hal_digi_dis_intr(&s_adc_digi_ctx->hal, IN_SUC_EOF_BIT);
adc_hal_digi_dis_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT);
//clear the in suc eof interrupt
adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal, IN_SUC_EOF_BIT);
//stop ADC
adc_hal_digi_stop(&s_adc_digi_ctx->hal);
adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT);
//stop DMA
adc_hal_digi_rxdma_stop(&s_adc_digi_ctx->hal);
adc_hal_digi_rxdma_stop(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
//stop ADC
adc_hal_digi_stop(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
adc_hal_digi_deinit();
#if CONFIG_PM_ENABLE
if (s_adc_digi_ctx->pm_lock) {
esp_pm_lock_release(s_adc_digi_ctx->pm_lock);
}
#endif //CONFIG_PM_ENABLE
if (s_adc_digi_ctx->use_adc1) {
SAR_ADC1_LOCK_RELEASE();
}
ADC_DIGI_LOCK_RELEASE();
//When using SARADC2 module, this task needs to be protected from WIFI
if (s_adc_digi_ctx->use_adc2) {
SAR_ADC2_LOCK_RELEASE();
SAC_ADC2_LOCK_RELEASE();
}
adc_power_release();
return ESP_OK;
}
@@ -405,27 +375,23 @@ esp_err_t adc_digi_deinitialize(void)
return ESP_ERR_INVALID_STATE;
}
if (s_adc_digi_ctx->ringbuf_hdl) {
if (s_adc_digi_ctx->dma_intr_hdl) {
esp_intr_free(s_adc_digi_ctx->dma_intr_hdl);
}
if(s_adc_digi_ctx->ringbuf_hdl) {
vRingbufferDelete(s_adc_digi_ctx->ringbuf_hdl);
s_adc_digi_ctx->ringbuf_hdl = NULL;
}
#if CONFIG_PM_ENABLE
if (s_adc_digi_ctx->pm_lock) {
esp_pm_lock_delete(s_adc_digi_ctx->pm_lock);
}
#endif //CONFIG_PM_ENABLE
free(s_adc_digi_ctx->rx_dma_buf);
free(s_adc_digi_ctx->hal.rx_desc);
free(s_adc_digi_ctx->hal_dma_config.rx_desc);
free(s_adc_digi_ctx->digi_controller_config.adc_pattern);
gdma_disconnect(s_adc_digi_ctx->rx_dma_channel);
gdma_del_channel(s_adc_digi_ctx->rx_dma_channel);
free(s_adc_digi_ctx);
s_adc_digi_ctx = NULL;
periph_module_disable(PERIPH_SARADC_MODULE);
periph_module_disable(PERIPH_GDMA_MODULE);
return ESP_OK;
}
@@ -436,38 +402,6 @@ esp_err_t adc_digi_deinitialize(void)
static adc_atten_t s_atten1_single[ADC1_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC1, used by single read API
static adc_atten_t s_atten2_single[ADC2_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC2, used by single read API
esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
{
esp_err_t ret;
uint32_t channel = ADC2_CHANNEL_MAX;
if (adc_unit == ADC_UNIT_2) {
for (int i = 0; i < ADC2_CHANNEL_MAX; i++) {
if (gpio == ADC_GET_IO_NUM(ADC_NUM_2, i)) {
channel = i;
break;
}
}
if (channel == ADC2_CHANNEL_MAX) {
return ESP_ERR_INVALID_ARG;
}
}
adc_power_acquire();
if (adc_unit & ADC_UNIT_1) {
ADC_ENTER_CRITICAL();
adc_hal_vref_output(ADC_NUM_1, channel, true);
ADC_EXIT_CRITICAL()
} else if (adc_unit & ADC_UNIT_2) {
ADC_ENTER_CRITICAL();
adc_hal_vref_output(ADC_NUM_2, channel, true);
ADC_EXIT_CRITICAL()
}
ret = adc_digi_gpio_init(ADC_NUM_2, BIT(channel));
return ret;
}
esp_err_t adc1_config_width(adc_bits_width_t width_bit)
{
//On ESP32C3, the data width is always 12-bits.
@@ -495,26 +429,41 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
int adc1_get_raw(adc1_channel_t channel)
{
int raw_out = 0;
adc_digi_config_t dig_cfg = {
.conv_limit_en = 0,
.conv_limit_num = 250,
.sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH,
};
ADC_DIGI_LOCK_ACQUIRE();
periph_module_enable(PERIPH_SARADC_MODULE);
adc_power_acquire();
SAR_ADC1_LOCK_ACQUIRE();
adc_atten_t atten = s_atten1_single[channel];
uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, channel, atten);
adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
ADC_REG_LOCK_ENTER();
adc_hal_set_atten(ADC_NUM_2, channel, atten);
adc_hal_convert(ADC_NUM_1, channel, &raw_out);
ADC_REG_LOCK_EXIT();
adc_hal_digi_controller_config(&dig_cfg);
SAR_ADC1_LOCK_RELEASE();
adc_hal_intr_clear(ADC_EVENT_ADC1_DONE);
adc_power_release();
adc_hal_adc1_onetime_sample_enable(true);
adc_hal_onetime_channel(ADC_NUM_1, channel);
adc_hal_set_onetime_atten(atten);
//Trigger single read.
adc_hal_onetime_start(&dig_cfg);
while (!adc_hal_intr_get_raw(ADC_EVENT_ADC1_DONE));
adc_hal_single_read(ADC_NUM_1, &raw_out);
adc_hal_intr_clear(ADC_EVENT_ADC1_DONE);
adc_hal_adc1_onetime_sample_enable(false);
adc_hal_digi_deinit();
periph_module_disable(PERIPH_SARADC_MODULE);
ADC_DIGI_LOCK_RELEASE();
return raw_out;
}
@@ -540,26 +489,42 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
}
esp_err_t ret = ESP_OK;
adc_digi_config_t dig_cfg = {
.conv_limit_en = 0,
.conv_limit_num = 250,
.sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH,
};
SAC_ADC2_LOCK_ACQUIRE();
ADC_DIGI_LOCK_ACQUIRE();
periph_module_enable(PERIPH_SARADC_MODULE);
adc_power_acquire();
SAR_ADC2_LOCK_ACQUIRE();
adc_atten_t atten = s_atten2_single[channel];
uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, channel, atten);
adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
ADC_REG_LOCK_ENTER();
adc_hal_set_atten(ADC_NUM_2, channel, atten);
ret = adc_hal_convert(ADC_NUM_2, channel, raw_out);
ADC_REG_LOCK_EXIT();
adc_hal_digi_controller_config(&dig_cfg);
SAR_ADC2_LOCK_RELEASE();
adc_hal_intr_clear(ADC_EVENT_ADC2_DONE);
adc_power_release();
adc_hal_adc2_onetime_sample_enable(true);
adc_hal_onetime_channel(ADC_NUM_2, channel);
adc_hal_set_onetime_atten(atten);
//Trigger single read.
adc_hal_onetime_start(&dig_cfg);
while (!adc_hal_intr_get_raw(ADC_EVENT_ADC2_DONE));
ret = adc_hal_single_read(ADC_NUM_2, raw_out);
adc_hal_intr_clear(ADC_EVENT_ADC2_DONE);
adc_hal_adc2_onetime_sample_enable(false);
adc_hal_digi_deinit();
periph_module_disable(PERIPH_SARADC_MODULE);
ADC_DIGI_LOCK_RELEASE();
SAC_ADC2_LOCK_RELEASE();
return ret;
}
@@ -586,7 +551,7 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
s_adc_digi_ctx->use_adc1 = 0;
s_adc_digi_ctx->use_adc2 = 0;
for (int i = 0; i < config->adc_pattern_len; i++) {
const adc_digi_pattern_table_t *pat = &config->adc_pattern[i];
const adc_digi_pattern_table_t* pat = &config->adc_pattern[i];
if (pat->unit == ADC_NUM_1) {
s_adc_digi_ctx->use_adc1 = 1;
@@ -610,6 +575,86 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
return ESP_OK;
}
esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config)
{
if (adc_unit & ADC_UNIT_1) {
return ESP_ERR_NOT_SUPPORTED;
}
ADC_ENTER_CRITICAL();
adc_hal_arbiter_config(config);
ADC_EXIT_CRITICAL();
return ESP_OK;
}
/**
* @brief Set ADC module controller.
* There are five SAR ADC controllers:
* Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes;
* Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep;
* the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2.
*
* @note Only ADC2 support arbiter to switch controllers automatically. Access to the ADC is based on the priority of the controller.
* @note For ADC1, Controller access is mutually exclusive.
*
* @param adc_unit ADC unit.
* @param ctrl ADC controller, Refer to `adc_controller_t`.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl)
{
adc_arbiter_t config = {0};
adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT();
if (adc_unit & ADC_UNIT_1) {
adc_hal_set_controller(ADC_NUM_1, ctrl);
}
if (adc_unit & ADC_UNIT_2) {
adc_hal_set_controller(ADC_NUM_2, ctrl);
switch (ctrl) {
case ADC2_CTRL_FORCE_PWDET:
config.pwdet_pri = 2;
config.mode = ADC_ARB_MODE_SHIELD;
adc_hal_arbiter_config(&config);
adc_hal_set_controller(ADC_NUM_2, ADC2_CTRL_PWDET);
break;
case ADC2_CTRL_FORCE_RTC:
config.rtc_pri = 2;
config.mode = ADC_ARB_MODE_SHIELD;
adc_hal_arbiter_config(&config);
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);
break;
case ADC2_CTRL_FORCE_DIG:
config.dig_pri = 2;
config.mode = ADC_ARB_MODE_SHIELD;
adc_hal_arbiter_config(&config);
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
break;
default:
adc_hal_arbiter_config(&cfg);
break;
}
}
return ESP_OK;
}
/**
* @brief Reset FSM of adc digital controller.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_reset(void)
{
ADC_ENTER_CRITICAL();
adc_hal_digi_reset();
adc_hal_digi_clear_pattern_table(ADC_NUM_1);
adc_hal_digi_clear_pattern_table(ADC_NUM_2);
ADC_EXIT_CRITICAL();
return ESP_OK;
}
/*************************************/
/* Digital controller filter setting */
/*************************************/
@@ -667,6 +712,90 @@ esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable)
return ESP_OK;
}
/**************************************/
/* Digital controller intr setting */
/**************************************/
esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
{
ADC_ENTER_CRITICAL();
if (adc_unit & ADC_UNIT_1) {
adc_hal_digi_intr_enable(ADC_NUM_1, intr_mask);
}
if (adc_unit & ADC_UNIT_2) {
adc_hal_digi_intr_enable(ADC_NUM_2, intr_mask);
}
ADC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
{
ADC_ENTER_CRITICAL();
if (adc_unit & ADC_UNIT_1) {
adc_hal_digi_intr_disable(ADC_NUM_1, intr_mask);
}
if (adc_unit & ADC_UNIT_2) {
adc_hal_digi_intr_disable(ADC_NUM_2, intr_mask);
}
ADC_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
{
ADC_ENTER_CRITICAL();
if (adc_unit & ADC_UNIT_1) {
adc_hal_digi_intr_clear(ADC_NUM_1, intr_mask);
}
if (adc_unit & ADC_UNIT_2) {
adc_hal_digi_intr_clear(ADC_NUM_2, intr_mask);
}
ADC_EXIT_CRITICAL();
return ESP_OK;
}
uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit)
{
uint32_t ret = 0;
ADC_ENTER_CRITICAL();
if (adc_unit & ADC_UNIT_1) {
ret = adc_hal_digi_get_intr_status(ADC_NUM_1);
}
if (adc_unit & ADC_UNIT_2) {
ret = adc_hal_digi_get_intr_status(ADC_NUM_2);
}
ADC_EXIT_CRITICAL();
return ret;
}
static bool s_isr_registered = 0;
static intr_handle_t s_adc_isr_handle = NULL;
esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags)
{
ADC_CHECK((fn != NULL), "Parameter error", ESP_ERR_INVALID_ARG);
ADC_CHECK(s_isr_registered == 0, "ADC ISR have installed, can not install again", ESP_FAIL);
esp_err_t ret = esp_intr_alloc(ETS_APB_ADC_INTR_SOURCE, intr_alloc_flags, fn, arg, &s_adc_isr_handle);
if (ret == ESP_OK) {
s_isr_registered = 1;
}
return ret;
}
esp_err_t adc_digi_isr_deregister(void)
{
esp_err_t ret = ESP_FAIL;
if (s_isr_registered) {
ret = esp_intr_free(s_adc_isr_handle);
if (ret == ESP_OK) {
s_isr_registered = 0;
}
}
return ret;
}
/*---------------------------------------------------------------
RTC controller setting
---------------------------------------------------------------*/

View File

@@ -22,6 +22,25 @@ extern "C" {
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* @brief Config ADC module arbiter.
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
* the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data.
*
* @note Only ADC2 support arbiter.
* @note Default priority: Wi-Fi > RTC > Digital;
* @note In normal use, there is no need to call this interface to config arbiter.
*
* @param adc_unit ADC unit.
* @param config Refer to `adc_arbiter_t`.
*
* @return
* - ESP_OK Success
* - ESP_ERR_NOT_SUPPORTED ADC unit not support arbiter.
*/
esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config);
/*************************************/
/* Digital controller filter setting */
/*************************************/
@@ -95,6 +114,78 @@ esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monit
*/
esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable);
/**************************************/
/* Digital controller intr setting */
/**************************************/
/**
* @brief Enable interrupt of adc digital controller by bitmask.
*
* @param adc_unit ADC unit.
* @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask);
/**
* @brief Disable interrupt of adc digital controller by bitmask.
*
* @param adc_unit ADC unit.
* @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask);
/**
* @brief Clear interrupt of adc digital controller by bitmask.
*
* @param adc_unit ADC unit.
* @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask);
/**
* @brief Get interrupt status mask of adc digital controller.
*
* @param adc_unit ADC unit.
* @return
* - intr Interrupt bitmask, See ``adc_digi_intr_t``.
*/
uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit);
/**
* @brief Register ADC interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
*
* @param fn Interrupt handler function.
* @param arg Parameter for handler function
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
*
* @return
* - ESP_OK Success
* - ESP_ERR_NOT_FOUND Can not find the interrupt that matches the flags.
* - ESP_ERR_INVALID_ARG Function pointer error.
*/
esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags);
/**
* @brief Deregister ADC interrupt handler, the handler is an ISR.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG hander error.
* - ESP_FAIL ISR not be registered.
*/
esp_err_t adc_digi_isr_deregister(void);
#ifdef __cplusplus
}
#endif

View File

@@ -15,7 +15,6 @@
#include <esp_types.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.h"
@@ -27,7 +26,6 @@
#include "driver/temp_sensor.h"
#include "regi2c_ctrl.h"
#include "esp32c3/rom/ets_sys.h"
#include "esp32c3/esp_efuse_rtc_calib.h"
static const char *TAG = "tsens";
@@ -60,8 +58,6 @@ static const tsens_dac_offset_t dac_offset[TSENS_DAC_MAX] = {
{TSENS_DAC_L4, 2, 10, -40, 20, 3},
};
static float s_deltaT = NAN; // unused number
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
{
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_TSENS_CLK_EN);
@@ -116,28 +112,6 @@ esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
return ESP_OK;
}
static void read_delta_t_from_efuse(void)
{
uint32_t version = esp_efuse_rtc_calib_get_ver();
if (version == 1) {
// fetch calibration value for temp sensor from eFuse
s_deltaT = esp_efuse_rtc_calib_get_cal_temp(version);
} else {
// no value to fetch, use 0.
s_deltaT = 0;
}
ESP_LOGD(TAG, "s_deltaT = %f", s_deltaT);
}
static float parse_temp_sensor_raw_value(uint32_t tsens_raw, const int dac_offset)
{
if (isnan(s_deltaT)) { //suggests that the value is not initialized
read_delta_t_from_efuse();
}
float result = (TSENS_ADC_FACTOR * (float)tsens_raw - TSENS_DAC_FACTOR * dac_offset - TSENS_SYS_OFFSET) - s_deltaT / 10.0;
return result;
}
esp_err_t temp_sensor_read_celsius(float *celsius)
{
TSENS_CHECK(celsius != NULL, ESP_ERR_INVALID_ARG);
@@ -149,7 +123,7 @@ esp_err_t temp_sensor_read_celsius(float *celsius)
printf("tsens_out %d\r\n", tsens_out);
TSENS_CHECK(ret == ESP_OK, ret);
const tsens_dac_offset_t *dac = &dac_offset[tsens.dac_offset];
*celsius = parse_temp_sensor_raw_value(tsens_out, dac->offset);
*celsius = (TSENS_ADC_FACTOR * (float)tsens_out - TSENS_DAC_FACTOR * dac->offset - TSENS_SYS_OFFSET);
if (*celsius < dac->range_min || *celsius > dac->range_max) {
ESP_LOGW(TAG, "Exceeding the temperature range!");
ret = ESP_ERR_INVALID_STATE;

View File

@@ -89,7 +89,6 @@ esp_err_t adc_digi_deinit(void)
s_adc_digi_arbiter_lock = NULL;
}
#endif
adc_power_release();
ADC_ENTER_CRITICAL();
adc_hal_digi_deinit();
ADC_EXIT_CRITICAL();
@@ -125,8 +124,6 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
}
}
/* If enable digtal controller, adc xpd should always on. */
adc_power_acquire();
ADC_ENTER_CRITICAL();
adc_hal_digi_controller_config(config);
ADC_EXIT_CRITICAL();

View File

@@ -13,12 +13,12 @@
#pragma once
#include "driver/touch_sensor_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "driver/touch_sensor_common.h"
/**
* @brief Set touch sensor FSM start
* @note Start FSM after the touch sensor FSM mode is set.
@@ -579,22 +579,6 @@ esp_err_t touch_pad_sleep_channel_reset_benchmark(void);
*/
esp_err_t touch_pad_sleep_channel_read_proximity_cnt(touch_pad_t pad_num, uint32_t *proximity_cnt);
/**
* @brief Change the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption.
* If this function is not called, the working frequency of touch in the deep sleep state is the same as that in the wake-up state.
*
* @param sleep_cycle The touch sensor will sleep after each measurement.
* sleep_cycle decide the interval between each measurement.
* t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency).
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
* @param meas_times The times of charge and discharge in each measure process of touch channels.
* The timer frequency is 8Mhz. Range: 0 ~ 0xffff.
* Recommended typical value: Modify this value to make the measurement time around 1ms.
* @return
* - ESP_OK Success
*/
esp_err_t touch_pad_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times);
#ifdef __cplusplus
}
#endif

View File

@@ -14,7 +14,6 @@
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "esp_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
@@ -62,7 +61,7 @@ static const tsens_dac_offset_t dac_offset[TSENS_DAC_MAX] = {
static SemaphoreHandle_t rtc_tsens_mux = NULL;
static float s_deltaT = NAN; // Unused number
static float deltaT = 1000; // greater than range
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
{
@@ -143,20 +142,20 @@ static void read_delta_t_from_efuse(void)
uint32_t version = esp_efuse_rtc_table_read_calib_version();
if (version == 1 || version == 2) {
// fetch calibration value for temp sensor from eFuse
s_deltaT = esp_efuse_rtc_table_get_parsed_efuse_value(RTCCALIB_IDX_TMPSENSOR, false) / 10.0;
deltaT = esp_efuse_rtc_table_get_parsed_efuse_value(RTCCALIB_IDX_TMPSENSOR, false) / 10.0;
} else {
// no value to fetch, use 0.
s_deltaT = 0;
deltaT = 0;
}
ESP_LOGD(TAG, "s_deltaT = %f\n", s_deltaT);
ESP_LOGD(TAG, "deltaT = %f\n", deltaT);
}
static float parse_temp_sensor_raw_value(uint32_t tsens_raw, const int dac_offset)
static float parse_temp_sensor_raw_value(uint32_t tsens_raw, const tsens_dac_offset_t *dac)
{
if (isnan(s_deltaT)) { //suggests that the value is not initialized
if (deltaT > 512) { //suggests that the value is not initialized
read_delta_t_from_efuse();
}
float result = (TSENS_ADC_FACTOR * (float)tsens_raw - TSENS_DAC_FACTOR * dac_offset - TSENS_SYS_OFFSET) - s_deltaT;
float result = (TSENS_ADC_FACTOR * (float)tsens_raw - TSENS_DAC_FACTOR * dac->offset - TSENS_SYS_OFFSET) - deltaT;
return result;
}
@@ -170,7 +169,7 @@ esp_err_t temp_sensor_read_celsius(float *celsius)
ret = temp_sensor_read_raw(&tsens_out);
TSENS_CHECK(ret == ESP_OK, ret);
const tsens_dac_offset_t *dac = &dac_offset[tsens.dac_offset];
*celsius = parse_temp_sensor_raw_value(tsens_out, dac->offset);
*celsius = parse_temp_sensor_raw_value(tsens_out, dac);
if (*celsius < dac->range_min || *celsius > dac->range_max) {
ESP_LOGW(TAG, "Exceeding the temperature range!");
ret = ESP_ERR_INVALID_STATE;

View File

@@ -629,9 +629,3 @@ esp_err_t touch_pad_sleep_channel_read_proximity_cnt(touch_pad_t pad_num, uint32
touch_hal_sleep_read_proximity_cnt(approach_cnt);
return ESP_OK;
}
esp_err_t touch_pad_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times)
{
touch_hal_sleep_channel_set_work_time(sleep_cycle, meas_times);
return ESP_OK;
}

View File

@@ -577,22 +577,6 @@ esp_err_t touch_pad_sleep_channel_reset_benchmark(void);
*/
esp_err_t touch_pad_sleep_channel_read_proximity_cnt(touch_pad_t pad_num, uint32_t *proximity_cnt);
/**
* @brief Change the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption.
* If this function is not called, the working frequency of touch in the deep sleep state is the same as that in the wake-up state.
*
* @param sleep_cycle The touch sensor will sleep after each measurement.
* sleep_cycle decide the interval between each measurement.
* t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency).
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
* @param meas_times The times of charge and discharge in each measure process of touch channels.
* The timer frequency is 8Mhz. Range: 0 ~ 0xffff.
* Recommended typical value: Modify this value to make the measurement time around 1ms.
* @return
* - ESP_OK Success
*/
esp_err_t touch_pad_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times);
#ifdef __cplusplus
}
#endif

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