mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
Merge branch 'master' into feature/github-7365-second
This commit is contained in:
commit
ea7122e3fb
4
.flake8
4
.flake8
@ -164,3 +164,7 @@ exclude =
|
||||
components/wifi_provisioning/python/wifi_constants_pb2.py,
|
||||
components/esp_local_ctrl/python/esp_local_ctrl_pb2.py,
|
||||
examples/provisioning/legacy/custom_config/components/custom_provisioning/python/custom_config_pb2.py,
|
||||
|
||||
per-file-ignores =
|
||||
# Sphinx conf.py files use star imports to setup config variables
|
||||
docs/conf_common.py: F405
|
||||
|
2
.github/workflows/python_lint.yml
vendored
2
.github/workflows/python_lint.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [2.7, 3.5, 3.6, 3.7, 3.8]
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -88,3 +88,6 @@ build
|
||||
|
||||
# lock files for examples and components
|
||||
dependencies.lock
|
||||
|
||||
# managed_components for examples
|
||||
managed_components
|
||||
|
@ -48,10 +48,11 @@ variables:
|
||||
|
||||
# Docker images
|
||||
BOT_DOCKER_IMAGE_TAG: ":latest"
|
||||
ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env:v4.4-1-v2"
|
||||
ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env:v4.4-1-v4"
|
||||
ESP_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-env:v4.4-1"
|
||||
AFL_FUZZER_TEST_IMAGE: "$CI_DOCKER_REGISTRY/afl-fuzzer-test:v4.4-1-1"
|
||||
CLANG_STATIC_ANALYSIS_IMAGE: "${CI_DOCKER_REGISTRY}/clang-static-analysis:v4.4-1-1"
|
||||
CLANG_STATIC_ANALYSIS_IMAGE: "${CI_DOCKER_REGISTRY}/clang-static-analysis:v4.4-1-2"
|
||||
SONARQUBE_SCANNER_IMAGE: "${CI_DOCKER_REGISTRY}/sonarqube-scanner:3"
|
||||
|
||||
# target test config file, used by assign test job
|
||||
CI_TARGET_TEST_CONFIG_FILE: "$CI_PROJECT_DIR/.gitlab/ci/target-test.yml"
|
||||
|
@ -57,6 +57,7 @@
|
||||
/export.* @esp-idf-codeowners/tools
|
||||
/install.* @esp-idf-codeowners/tools
|
||||
/sdkconfig.rename @esp-idf-codeowners/build-config
|
||||
/sonar-project.properties @esp-idf-codeowners/ci
|
||||
|
||||
# sort-order-reset
|
||||
|
||||
@ -66,6 +67,7 @@
|
||||
/components/bootloader*/ @esp-idf-codeowners/system @esp-idf-codeowners/security
|
||||
/components/bt/ @esp-idf-codeowners/bluetooth
|
||||
/components/cbor/ @esp-idf-codeowners/app-utilities
|
||||
/components/cmock/ @esp-idf-codeowners/system
|
||||
/components/coap/ @esp-idf-codeowners/app-utilities
|
||||
/components/console/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
||||
/components/cxx/ @esp-idf-codeowners/system
|
||||
@ -159,6 +161,7 @@
|
||||
/examples/ethernet/ @esp-idf-codeowners/network
|
||||
/examples/get-started/ @esp-idf-codeowners/system
|
||||
/examples/mesh/ @esp-idf-codeowners/wifi
|
||||
/examples/network/ @esp-idf-codeowners/network @esp-idf-codeowners/wifi
|
||||
/examples/openthread/ @esp-idf-codeowners/ieee802154
|
||||
/examples/peripherals/ @esp-idf-codeowners/peripherals
|
||||
/examples/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
@ -183,6 +186,7 @@
|
||||
/tools/kconfig*/ @esp-idf-codeowners/build-config
|
||||
/tools/ldgen/ @esp-idf-codeowners/build-config
|
||||
/tools/mass_mfg/ @esp-idf-codeowners/app-utilities
|
||||
/tools/mocks/ @esp-idf-codeowners/system
|
||||
|
||||
## Note: owners here should be the same as the owners for the same example subdir, above
|
||||
/tools/test_apps/build_system/ @esp-idf-codeowners/build-config
|
||||
|
@ -221,6 +221,14 @@ build_examples_cmake_esp32s2:
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
build_examples_cmake_esp32s3:
|
||||
extends:
|
||||
- .build_examples_cmake_template
|
||||
- .rules:build:example_test-esp32s3
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
|
||||
build_examples_cmake_esp32c3:
|
||||
extends:
|
||||
- .build_examples_cmake_template
|
||||
@ -344,6 +352,7 @@ build_docker:
|
||||
- .before_script_minimal
|
||||
- .rules:build:docker
|
||||
stage: host_test
|
||||
needs: []
|
||||
image: espressif/docker-builder:1
|
||||
tags:
|
||||
- build_docker_amd64_brno
|
||||
@ -366,6 +375,7 @@ build_docker:
|
||||
- .before_script_minimal
|
||||
- .rules:build:windows
|
||||
stage: host_test
|
||||
needs: []
|
||||
image: $CI_DOCKER_REGISTRY/esp32-toolchain-win-cross
|
||||
tags:
|
||||
- build
|
||||
|
@ -39,7 +39,6 @@
|
||||
check_readme_links:
|
||||
extends:
|
||||
- .pre_check_job_template
|
||||
- .doc-rules:build:docs
|
||||
tags: ["build", "amd64", "internet"]
|
||||
allow_failure: true
|
||||
script:
|
||||
@ -62,12 +61,12 @@ check_docs_lang_sync:
|
||||
dependencies: []
|
||||
script:
|
||||
- cd docs
|
||||
- python -m pip install -r requirements.txt
|
||||
- python ./build_docs.py -bs $DOC_BUILDERS -l $DOCLANG -t $DOCTGT build
|
||||
- pip install -r requirements.txt
|
||||
- build-docs -t $DOCTGT -bs $DOC_BUILDERS -l $DOCLANG build
|
||||
parallel:
|
||||
matrix:
|
||||
- DOCLANG: ["en", "zh_CN"]
|
||||
DOCTGT: ["esp32", "esp32s2", "esp32c3"]
|
||||
DOCTGT: ["esp32", "esp32s2", "esp32s3", "esp32c3"]
|
||||
|
||||
check_docs_gh_links:
|
||||
image: $ESP_IDF_DOC_ENV_IMAGE
|
||||
@ -78,8 +77,8 @@ check_docs_gh_links:
|
||||
- .doc-rules:build:docs
|
||||
script:
|
||||
- cd docs
|
||||
- python -m pip install -r requirements.txt
|
||||
- python ./build_docs.py gh-linkcheck
|
||||
- pip install -r requirements.txt
|
||||
- build-docs gh-linkcheck
|
||||
|
||||
# stage: build_doc
|
||||
# Add this stage to let the build_docs job run in parallel with build
|
||||
@ -129,13 +128,6 @@ build_docs_html_fast:
|
||||
variables:
|
||||
DOC_BUILDERS: "html"
|
||||
DOCS_FAST_BUILD: "yes"
|
||||
# matrix is redefined to include esp32s3 here
|
||||
# that we can build for S3 MRs during bringup phase without
|
||||
# anything being built and published from master branch
|
||||
parallel:
|
||||
matrix:
|
||||
- DOCLANG: ["en", "zh_CN"]
|
||||
DOCTGT: ["esp32", "esp32s2", "esp32s3", "esp32c3"]
|
||||
|
||||
build_docs_pdf:
|
||||
extends:
|
||||
@ -168,7 +160,8 @@ build_docs_pdf:
|
||||
script:
|
||||
- add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
|
||||
- export GIT_VER=$(git describe --always)
|
||||
- python ${IDF_PATH}/tools/ci/deploy_docs.py
|
||||
- pip install -r docs/requirements.txt
|
||||
- deploy-docs
|
||||
|
||||
# stage: test_deploy
|
||||
deploy_docs_preview:
|
||||
@ -227,6 +220,6 @@ check_doc_links:
|
||||
allow_failure: true
|
||||
script:
|
||||
- cd docs
|
||||
- python -m pip install -r requirements.txt
|
||||
- pip install -r requirements.txt
|
||||
# At the moment this check will always fail due to multiple known limitations, ignore result
|
||||
- python ./build_docs.py -l $DOCLANG -t $DOCTGT linkcheck || { echo "THERE ARE ISSUES DUE TO KNOWN LIMITATIONS, PLEASE FIX THEM. Nowadays we're ignored them to pass pipeline."; true; }
|
||||
- build-docs -t $DOCTGT -l $DOCLANG linkcheck || { echo "THERE ARE ISSUES DUE TO KNOWN LIMITATIONS, PLEASE FIX THEM. Nowadays we're ignored them to pass pipeline."; true; }
|
||||
|
@ -220,11 +220,6 @@ test_efuse_table_on_host_esp32s2:
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
test_efuse_table_on_host_esp32s2:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
test_efuse_table_on_host_esp32s3:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
variables:
|
||||
@ -250,10 +245,11 @@ test_espcoredump:
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
IDF_COREDUMP_ELF_REPO: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/idf/idf-coredump-elf.git"
|
||||
IDF_COREDUMP_ELF_TAG: idf-20210910-00
|
||||
# install CMake version specified in tools.json
|
||||
SETUP_TOOLS_LIST: "all"
|
||||
script:
|
||||
- retry_failed git clone ${IDF_COREDUMP_ELF_REPO} -b master
|
||||
- retry_failed git clone ${IDF_COREDUMP_ELF_REPO} -b $IDF_COREDUMP_ELF_TAG
|
||||
- cd ${IDF_PATH}/components/espcoredump/test/
|
||||
- ./test_espcoredump.sh ${CI_PROJECT_DIR}/idf-coredump-elf
|
||||
|
||||
@ -295,22 +291,6 @@ test_mkuf2:
|
||||
- cd ${IDF_PATH}/tools/test_mkuf2
|
||||
- ./test_mkuf2.py
|
||||
|
||||
test_docs:
|
||||
extends: .host_test_template
|
||||
image: $ESP_IDF_DOC_ENV_IMAGE
|
||||
variables:
|
||||
PYTHON_VER: 3.6.13
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- docs/test/_build/*/*/*/html/*
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd ${IDF_PATH}/docs/test
|
||||
- python -m pip install -r ${IDF_PATH}/docs/requirements.txt
|
||||
- ./test_docs.py
|
||||
- ./test_sphinx_idf_extensions.py
|
||||
|
||||
test_autocomplete:
|
||||
extends: .host_test_template
|
||||
image: $CI_DOCKER_REGISTRY/linux-shells:1
|
||||
@ -340,7 +320,7 @@ test_nvs_page:
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/nvs_flash/host_test/nvs_page_test
|
||||
- idf.py build
|
||||
- build/host_nvs_page_test.elf
|
||||
- build/test_nvs_page_host.elf
|
||||
|
||||
test_log:
|
||||
extends: .host_test_template
|
||||
@ -349,9 +329,44 @@ test_log:
|
||||
- idf.py build
|
||||
- build/test_log_host.elf
|
||||
|
||||
test_esp_event:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/esp_event/host_test/esp_event_unit_test
|
||||
- idf.py build
|
||||
- build/test_esp_event_host.elf
|
||||
|
||||
test_esp_timer_cxx:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer
|
||||
- idf.py build
|
||||
- build/test_esp_timer_cxx_host.elf
|
||||
|
||||
test_eh_frame_parser:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/esp_system/test_eh_frame_parser
|
||||
- make
|
||||
- ./eh_frame_test
|
||||
|
||||
test_rom_on_linux_works:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/esp_rom/host_test/rom_test
|
||||
- idf.py build
|
||||
- build/test_rom_host.elf
|
||||
|
||||
test_cxx_gpio:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/gpio
|
||||
- idf.py build
|
||||
- build/test_gpio_cxx_host.elf
|
||||
|
||||
test_linux_example:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/build_system/cmake/linux_host_app
|
||||
- idf.py build
|
||||
- build/linux_host_app.elf
|
||||
|
@ -113,6 +113,15 @@ check_public_headers:
|
||||
script:
|
||||
- python tools/ci/check_public_headers.py --jobs 4 --prefix xtensa-esp32-elf-
|
||||
|
||||
check_soc_struct_headers:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
script:
|
||||
- find ${IDF_PATH}/components/soc/*/include/soc/ -name "*_struct.h" -print0 | xargs -0 -n1 ./tools/ci/check_soc_struct_headers.py
|
||||
|
||||
check_esp_err_to_name:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
|
@ -3,7 +3,10 @@
|
||||
############
|
||||
.patterns-c-files: &patterns-c-files
|
||||
- ".gitlab/ci/static-code-analysis.yml"
|
||||
|
||||
- "tools/ci/static-analysis-rules.yml"
|
||||
- "tools/ci/clang_tidy_dirs.txt"
|
||||
|
||||
- "**/*.{c,C}"
|
||||
- "**/*.{h,H}"
|
||||
- "components/**/Kconfig"
|
||||
@ -37,6 +40,7 @@
|
||||
|
||||
.patterns-build_components: &patterns-build_components
|
||||
- "components/**/*"
|
||||
- "examples/cxx/experimental/experimental_cpp_component/*"
|
||||
|
||||
.patterns-build_system: &patterns-build_system
|
||||
- "tools/cmake/**/*"
|
||||
|
@ -5,17 +5,46 @@ clang_tidy_check:
|
||||
- .rules:patterns:clang_tidy
|
||||
image: ${CLANG_STATIC_ANALYSIS_IMAGE}
|
||||
artifacts:
|
||||
reports:
|
||||
junit: $IDF_PATH/output.xml
|
||||
paths:
|
||||
- $OUTPUT_DIR
|
||||
when: always
|
||||
expire_in: 1 day
|
||||
variables:
|
||||
CLANG_TIDY_RUNNER_PROJ: 2107 # idf/clang-tidy-runner
|
||||
CLANG_TIDY_DIRS_TXT: ${CI_PROJECT_DIR}/tools/ci/clang_tidy_dirs.txt
|
||||
RULES_FILE: ${CI_PROJECT_DIR}/tools/ci/static-analysis-rules.yml
|
||||
OUTPUT_DIR: ${CI_PROJECT_DIR}/clang_tidy_reports
|
||||
script:
|
||||
- python -m pip install -U pip
|
||||
- internal_pip_install $CLANG_TIDY_RUNNER_PROJ pyclang
|
||||
- export PATH=$PATH:$(python -c "import sys; print(sys.executable.rsplit('/', 1)[0])")
|
||||
- dirs=$(cat ${CLANG_TIDY_DIRS_TXT} | while read line; do echo ${CI_PROJECT_DIR}/${line}; done | xargs)
|
||||
- run_cmd idf_clang ${dirs}
|
||||
--output-path ${OUTPUT_DIR}
|
||||
--limit-file ${RULES_FILE}
|
||||
--xtensa-include-dir
|
||||
--run-clang-tidy-py ${RUN_CLANG_TIDY_PY}
|
||||
|
||||
check_pylint:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:patterns:python-files
|
||||
- .before_script_minimal
|
||||
image: $SONARQUBE_SCANNER_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $IDF_PATH/examples/get-started/hello_world/tidybuild/report/*
|
||||
expire_in: 1 day
|
||||
- pylint-report.txt
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- retry_failed git clone $IDF_ANALYSIS_UTILS static_analysis_utils && cd static_analysis_utils
|
||||
# Setup parameters of triggered/regular job
|
||||
- export TARGET_BRANCH=${BOT_CUSTOMIZED_REVISION-}
|
||||
- ./analyze.sh $IDF_PATH/examples/get-started/hello_world/ $IDF_PATH/tools/ci/static-analysis-rules.yml $IDF_PATH/output.xml
|
||||
- export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
|
||||
- |
|
||||
if [ -n "$CI_MERGE_REQUEST_IID" ]; then
|
||||
export files=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py files ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} | grep ".py");
|
||||
else
|
||||
export files=$(find . -iname "*.py" -print);
|
||||
fi
|
||||
- pylint --rcfile=.pylintrc $files -r n --output-format=parseable > pylint-report.txt || exit 0
|
||||
|
||||
# build stage
|
||||
# Sonarqube related jobs put here for this reason:
|
||||
@ -33,26 +62,31 @@ clang_tidy_check:
|
||||
.sonar_scan_template:
|
||||
stage: build
|
||||
image:
|
||||
name: $CI_DOCKER_REGISTRY/sonarqube-scanner:2
|
||||
name: $SONARQUBE_SCANNER_IMAGE
|
||||
before_script:
|
||||
- source tools/ci/utils.sh
|
||||
- export PYTHONPATH="$CI_PROJECT_DIR/tools:$CI_PROJECT_DIR/tools/ci/python_packages:$PYTHONPATH"
|
||||
- fetch_submodules
|
||||
# Exclude the submodules, all paths ends with /**
|
||||
- export SUBMODULES=$(get_all_submodules)
|
||||
- submodules=$(get_all_submodules)
|
||||
# get all exclude paths specified in tools/ci/sonar_exclude_list.txt | ignore lines start with # | xargs | replace all <space> to <comma>
|
||||
- export CUSTOM_EXCLUDES=$(cat $CI_PROJECT_DIR/tools/ci/sonar_exclude_list.txt | grep -v '^#' | xargs | sed -e 's/ /,/g')
|
||||
- custom_excludes=$(cat $CI_PROJECT_DIR/tools/ci/sonar_exclude_list.txt | grep -v '^#' | xargs | sed -e 's/ /,/g')
|
||||
# Exclude the report dir as well
|
||||
- export EXCLUSIONS="$CUSTOM_EXCLUDES,$SUBMODULES,$REPORT_DIR/**,docs/_static/**,**/*.png,**/*.jpg"
|
||||
- python $NORMALIZE_CLANGTIDY_PY $CI_PROJECT_DIR/$REPORT_DIR/warnings.txt $CI_PROJECT_DIR/$REPORT_DIR/clang_tidy_report.txt $CI_PROJECT_DIR
|
||||
- export EXCLUSIONS="$custom_excludes,$submodules"
|
||||
- export SONAR_SCANNER_OPTS="-Xmx2048m"
|
||||
|
||||
variables:
|
||||
GIT_DEPTH: 0
|
||||
NORMALIZE_CLANGTIDY_PY: $CI_PROJECT_DIR/tools/ci/normalize_clangtidy_path.py
|
||||
REPORT_DIR: examples/get-started/hello_world/tidybuild/report
|
||||
REPORT_PATTERN: clang_tidy_reports/*.txt
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORT_PATTERN
|
||||
tags:
|
||||
- host_test
|
||||
dependencies: # Here is not a hard dependency relationship, could be skipped when only python files changed. so we do not use "needs" here.
|
||||
- clang_tidy_check
|
||||
- check_pylint
|
||||
|
||||
code_quality_check:
|
||||
extends:
|
||||
@ -67,23 +101,16 @@ code_quality_check:
|
||||
- test -n "$CI_MERGE_REQUEST_COMMITS" || exit 0
|
||||
- sonar-scanner
|
||||
-Dsonar.analysis.mode=preview
|
||||
-Dsonar.branch.name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_DIR/clang_tidy_report.txt
|
||||
-Dsonar.cxx.includeDirectories=components,/usr/include
|
||||
-Dsonar.branch.name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
|
||||
-Dsonar.exclusions=$EXCLUSIONS
|
||||
-Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID
|
||||
-Dsonar.gitlab.commit_sha=$CI_MERGE_REQUEST_COMMITS
|
||||
-Dsonar.gitlab.failure_notification_mode=exit-code
|
||||
-Dsonar.gitlab.merge_request_discussion=true
|
||||
-Dsonar.gitlab.project_id=$CI_PROJECT_ID
|
||||
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.gitlab.ref_name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
-Dsonar.host.url=$SONAR_HOST_URL
|
||||
-Dsonar.login=$SONAR_LOGIN
|
||||
-Dsonar.projectBaseDir=$CI_PROJECT_DIR
|
||||
-Dsonar.projectKey=esp-idf
|
||||
-Dsonar.python.pylint_config=.pylintrc
|
||||
-Dsonar.sourceEncoding=UTF-8
|
||||
-Dsonar.sources=$CI_PROJECT_DIR
|
||||
-Dsonar.python.pylint.reportPath=pylint-report.txt
|
||||
|
||||
code_quality_report:
|
||||
extends:
|
||||
@ -94,41 +121,10 @@ code_quality_report:
|
||||
script:
|
||||
- sonar-scanner
|
||||
-Dsonar.branch.name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_DIR/clang_tidy_report.txt
|
||||
-Dsonar.cxx.includeDirectories=components,/usr/include
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
|
||||
-Dsonar.exclusions=$EXCLUSIONS
|
||||
-Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA
|
||||
-Dsonar.gitlab.failure_notification_mode=exit-code
|
||||
-Dsonar.gitlab.project_id=$CI_PROJECT_ID
|
||||
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.host.url=$SONAR_HOST_URL
|
||||
-Dsonar.login=$SONAR_LOGIN
|
||||
-Dsonar.projectBaseDir=$CI_PROJECT_DIR
|
||||
-Dsonar.projectKey=esp-idf
|
||||
-Dsonar.python.pylint_config=.pylintrc
|
||||
-Dsonar.sourceEncoding=UTF-8
|
||||
-Dsonar.sources=$CI_PROJECT_DIR
|
||||
|
||||
# deploy stage
|
||||
clang_tidy_deploy:
|
||||
extends:
|
||||
- .deploy_job_template
|
||||
- .rules:patterns:clang_tidy
|
||||
needs:
|
||||
- clang_tidy_check
|
||||
tags:
|
||||
- deploy
|
||||
- shiny
|
||||
script:
|
||||
- add_doc_server_ssh_keys $DOCS_DEPLOY_KEY $DOCS_SERVER $DOCS_SERVER_USER
|
||||
- export GIT_VER=$(git describe --always)
|
||||
- cd $IDF_PATH/examples/get-started/hello_world/tidybuild
|
||||
- mv report $GIT_VER
|
||||
- tar czvf $GIT_VER.tar.gz $GIT_VER
|
||||
- export STATIC_REPORT_PATH="web/static_analysis/esp-idf/"
|
||||
- ssh $DOCS_SERVER -x "mkdir -p $STATIC_REPORT_PATH/clang-tidy"
|
||||
- scp $GIT_VER.tar.gz $DOCS_SERVER:$STATIC_REPORT_PATH/clang-tidy
|
||||
- ssh $DOCS_SERVER -x "cd $STATIC_REPORT_PATH/clang-tidy && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest"
|
||||
# add link to view the report
|
||||
- echo "[static analysis][clang tidy] $CI_DOCKER_REGISTRY/static_analysis/esp-idf/clang-tidy/${GIT_VER}/index.html"
|
||||
- test ! -e ${GIT_VER}/FAILED_RULES || { echo 'Failed static analysis rules!'; cat ${GIT_VER}/FAILED_RULES; exit 1; }
|
||||
-Dsonar.python.pylint.reportPath=pylint-report.txt
|
||||
|
@ -46,7 +46,7 @@
|
||||
extends:
|
||||
- .example_test_template
|
||||
- .rules:test:example_test-esp32
|
||||
variables:
|
||||
variables:
|
||||
SUBMODULES_TO_FETCH: "all"
|
||||
|
||||
test_weekend_mqtt:
|
||||
@ -60,7 +60,7 @@ test_weekend_mqtt:
|
||||
- export MQTT_PUBLISH_TEST=1
|
||||
- export TEST_PATH=$CI_PROJECT_DIR/tools/test_apps/protocols/mqtt/publish_connect_test
|
||||
- cd $IDF_PATH/tools/ci/python_packages/tiny_test_fw/bin
|
||||
- run_cmd python Runner.py $TEST_PATH -c $TEST_PATH/publish_connect_mqtt_.yml -e $TEST_PATH/env.yml
|
||||
- run_cmd python Runner.py $TEST_PATH -c $TEST_PATH/publish_connect_mqtt_.yml
|
||||
|
||||
.example_test_esp32_template:
|
||||
extends:
|
||||
@ -97,7 +97,7 @@ example_test_001B_V3:
|
||||
|
||||
example_test_001C:
|
||||
extends: .example_test_esp32_template
|
||||
parallel: 3
|
||||
parallel: 4
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_GENERIC
|
||||
@ -129,7 +129,7 @@ example_test_002:
|
||||
- ESP32
|
||||
- Example_ShieldBox_Basic
|
||||
|
||||
example_test_enternet:
|
||||
example_test_ethernet:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
@ -270,20 +270,17 @@ example_test_ESP32_SDSPI:
|
||||
- ESP32
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
# uncomment when ESP32S2 & ESP32C3 runners with external SD connected over SPI are available
|
||||
# ensure the runners have required tags created
|
||||
#
|
||||
#example_test_ESP32S2_SDSPI:
|
||||
# extends: .example_test_esp32s2_template
|
||||
# tags:
|
||||
# - ESP32S2
|
||||
# - UT_T1_SPIMODE
|
||||
#
|
||||
#example_test_ESP32C3_SDSPI:
|
||||
# extends: .example_test_esp32c3_template
|
||||
# tags:
|
||||
# - ESP32C3
|
||||
# - UT_T1_SPIMODE
|
||||
example_test_ESP32S2_SDSPI:
|
||||
extends: .example_test_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
example_test_ESP32C3_SDSPI:
|
||||
extends: .example_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
.test_app_template:
|
||||
extends: .target_test_job_template
|
||||
@ -447,7 +444,7 @@ UT_001:
|
||||
|
||||
UT_002:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 16
|
||||
parallel: 14
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
@ -482,7 +479,7 @@ UT_006:
|
||||
|
||||
UT_007:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 2
|
||||
parallel: 4
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
@ -508,19 +505,6 @@ UT_014:
|
||||
- UT_T2_RS485
|
||||
- psram
|
||||
|
||||
UT_015:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_RMT
|
||||
|
||||
UT_016:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_RMT
|
||||
- psram
|
||||
|
||||
UT_017:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
@ -544,7 +528,6 @@ UT_020:
|
||||
|
||||
UT_021:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- psram
|
||||
@ -579,7 +562,7 @@ UT_033:
|
||||
|
||||
UT_034:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 3
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
@ -607,7 +590,7 @@ UT_036:
|
||||
|
||||
UT_038:
|
||||
extends: .unit_test_esp32s2_template
|
||||
parallel: 3
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
@ -647,7 +630,7 @@ UT_046:
|
||||
|
||||
UT_047:
|
||||
extends: .unit_test_esp32s2_template
|
||||
parallel: 3
|
||||
parallel: 5
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_1
|
||||
@ -658,9 +641,15 @@ UT_S2_SPI_DUAL:
|
||||
- ESP32S2_IDF
|
||||
- Example_SPI_Multi_device
|
||||
|
||||
UT_S2_SDSPI:
|
||||
extends: .unit_test_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
UT_C3:
|
||||
extends: .unit_test_esp32c3_template
|
||||
parallel: 33
|
||||
parallel: 32
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_1
|
||||
@ -674,7 +663,6 @@ UT_C3_FLASH:
|
||||
|
||||
UT_C3_SPI_DUAL:
|
||||
extends: .unit_test_esp32c3_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- Example_SPI_Multi_device
|
||||
@ -697,9 +685,15 @@ UT_C3_FLASH_SUSPEND:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_Flash_Suspend
|
||||
|
||||
UT_C3_SDSPI:
|
||||
extends: .unit_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
UT_S3:
|
||||
extends: .unit_test_esp32s3_template
|
||||
parallel: 27
|
||||
parallel: 29
|
||||
tags:
|
||||
- ESP32S3_IDF
|
||||
- UT_T1_1
|
||||
@ -717,6 +711,18 @@ UT_S3_FLASH:
|
||||
- ESP32S3_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
|
||||
component_ut_test_ip101:
|
||||
extends: .component_ut_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- COMPONENT_UT_IP101
|
||||
|
||||
component_ut_test_lan8720:
|
||||
extends: .component_ut_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- COMPONENT_UT_LAN8720
|
||||
|
||||
.integration_test_template:
|
||||
extends:
|
||||
- .target_test_job_template
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
# note: whitespace exclusions use multiline regex, see https://pre-commit.com/#regular-expressions
|
||||
@ -26,12 +26,12 @@ repos:
|
||||
args: ['-f=lf']
|
||||
- id: double-quote-string-fixer
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.8.4
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
args: ['--config=.flake8', '--tee', '--benchmark']
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.6.4
|
||||
rev: 5.9.3
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
@ -92,11 +92,24 @@ repos:
|
||||
- id: mypy-check
|
||||
name: Check type annotations in python files
|
||||
entry: tools/ci/check_type_comments.py
|
||||
additional_dependencies: ['mypy==0.800', 'mypy-extensions==0.4.3']
|
||||
additional_dependencies:
|
||||
- 'mypy==0.800'
|
||||
- 'mypy-extensions==0.4.3'
|
||||
language: python
|
||||
types: [python]
|
||||
- id: check-copyright
|
||||
name: Check copyright notices
|
||||
entry: tools/ci/check_copyright.py --verbose --replace
|
||||
additional_dependencies:
|
||||
- 'comment_parser == 1.2.3'
|
||||
- 'thefuzz == 0.19.0'
|
||||
- 'thefuzz[speedup] == 0.19.0; sys_platform != "win32"'
|
||||
# don't depend on python-Levenshtein on Windows, as it requires Microsoft C++ Build Tools to install
|
||||
language: python
|
||||
files: \.(py|c|h|cpp|hpp|ld)$
|
||||
require_serial: true
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: file-contents-sorter
|
||||
files: '(tools\/ci\/executable-list\.txt|tools\/ci\/mypy_ignore_list\.txt)'
|
||||
files: 'tools\/ci\/(executable-list\.txt|mypy_ignore_list\.txt|check_copyright_ignore\.txt)'
|
||||
|
@ -20,7 +20,9 @@ if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_SIZE)
|
||||
list(APPEND compile_options "-Os")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_DEFAULT)
|
||||
list(APPEND compile_options "-Og")
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_NONE)
|
||||
@ -33,7 +35,9 @@ else() # BOOTLOADER_BUILD
|
||||
|
||||
if(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE)
|
||||
list(APPEND compile_options "-Os")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG)
|
||||
list(APPEND compile_options "-Og")
|
||||
elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE)
|
||||
@ -74,6 +78,48 @@ if(CONFIG_COMPILER_DISABLE_GCC8_WARNINGS)
|
||||
"-Wno-int-in-bool-context")
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND c_compile_options "-Wno-old-style-declaration")
|
||||
endif()
|
||||
|
||||
# Clang finds some warnings in IDF code which GCC doesn't.
|
||||
# All these warnings should be fixed before Clang is presented
|
||||
# as a toolchain choice for users.
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# Clang checks Doxygen comments for being in sync with function prototype.
|
||||
# There are some inconsistencies, especially in ROM headers.
|
||||
list(APPEND compile_options "-Wno-documentation")
|
||||
# GCC allows repeated typedefs when the source and target types are the same.
|
||||
# Clang doesn't allow this. This occurs in many components due to forward
|
||||
# declarations.
|
||||
list(APPEND compile_options "-Wno-typedef-redefinition")
|
||||
# This issue is seemingly related to newlib's char type functions.
|
||||
# Fix is not clear yet.
|
||||
list(APPEND compile_options "-Wno-char-subscripts")
|
||||
# Clang seems to notice format string issues which GCC doesn't.
|
||||
list(APPEND compile_options "-Wno-format-security")
|
||||
# Logic bug in essl component
|
||||
list(APPEND compile_options "-Wno-tautological-overlap-compare")
|
||||
# Some pointer checks in mDNS component check addresses which can't be NULL
|
||||
list(APPEND compile_options "-Wno-tautological-pointer-compare")
|
||||
# Similar to the above, in tcp_transport
|
||||
list(APPEND compile_options "-Wno-pointer-bool-conversion")
|
||||
# mbedTLS md5.c triggers this warning in md5_test_buf (false positive)
|
||||
list(APPEND compile_options "-Wno-string-concatenation")
|
||||
# multiple cases of implict convertions between unrelated enum types
|
||||
list(APPEND compile_options "-Wno-enum-conversion")
|
||||
# When IRAM_ATTR is specified both in function declaration and definition,
|
||||
# it produces different section names, since section names include __COUNTER__.
|
||||
# Occurs in multiple places.
|
||||
list(APPEND compile_options "-Wno-section")
|
||||
# Multiple cases of attributes unknown to clang, for example
|
||||
# __attribute__((optimize("-O3")))
|
||||
list(APPEND compile_options "-Wno-unknown-attributes")
|
||||
# Clang also produces many -Wunused-function warnings which GCC doesn't.
|
||||
# However these aren't treated as errors.
|
||||
endif()
|
||||
# More warnings may exist in unit tests and example projects.
|
||||
|
||||
if(CONFIG_COMPILER_WARN_WRITE_STRINGS)
|
||||
list(APPEND compile_options "-Wwrite-strings")
|
||||
endif()
|
||||
@ -118,7 +164,15 @@ list(APPEND link_options "-fno-lto")
|
||||
# Placing jump tables in flash would cause issues with code that required
|
||||
# to be placed in IRAM
|
||||
list(APPEND compile_options "-fno-jump-tables")
|
||||
list(APPEND compile_options "-fno-tree-switch-conversion")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
# This flag is GCC-specific.
|
||||
# Not clear yet if some other flag should be used for Clang.
|
||||
list(APPEND compile_options "-fno-tree-switch-conversion")
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "LLVM")
|
||||
list(APPEND compile_options "-fno-use-cxa-atexit")
|
||||
endif()
|
||||
|
||||
idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND)
|
||||
idf_build_set_property(C_COMPILE_OPTIONS "${c_compile_options}" APPEND)
|
||||
|
@ -56,7 +56,6 @@ Related Documents
|
||||
style-guide
|
||||
install-pre-commit-hook
|
||||
documenting-code
|
||||
add-ons-reference
|
||||
creating-examples
|
||||
../api-reference/template
|
||||
contributor-agreement
|
||||
|
1
Kconfig
1
Kconfig
@ -11,7 +11,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
config IDF_ENV_FPGA
|
||||
# This option is for internal use only
|
||||
bool
|
||||
default "y" if IDF_TARGET="esp32h2" # ESP32H2-TODO: IDF-3378
|
||||
option env="IDF_ENV_FPGA"
|
||||
|
||||
config IDF_TARGET_ARCH_RISCV
|
||||
|
24
README.md
24
README.md
@ -2,7 +2,24 @@
|
||||
|
||||
* [中文版](./README_CN.md)
|
||||
|
||||
ESP-IDF is the development framework for Espressif SoCs (released after 2016<sup>[1](#fn1)</sup>) provided for Windows, Linux and macOS.
|
||||
ESP-IDF is the development framework for Espressif SoCs supported on Windows, Linux and macOS.
|
||||
|
||||
# ESP-IDF Release and SoC Compatibility
|
||||
|
||||
The following table shows ESP-IDF support of Espressif SoCs where ![alt text][preview] and ![alt text][supported] denote preview status and support, respectively. In preview status the build is not yet enabled and some crucial parts could be missing (like documentation, datasheet). Please use an ESP-IDF release where the desired SoC is already supported.
|
||||
|
||||
|Chip | v3.3 | v4.0 | v4.1 | v4.2 | v4.3 | v4.4 | |
|
||||
|:----------- |:---------------------: | :---------------------:| :---------------------:| :---------------------:| :---------------------:| :---------------------:|:---------------------------------------------------------- |
|
||||
|ESP32 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S2 | | | | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-C3 | | | | | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S3 | | | | | ![alt text][preview] | ![alt text][supported] | [Announcement](https://www.espressif.com/en/news/ESP32_S3) |
|
||||
|ESP32-H2 | | | | | | ![alt text][preview] | [Announcement](https://www.espressif.com/en/news/ESP32_H2) |
|
||||
|
||||
[supported]: https://img.shields.io/badge/-supported-green "supported"
|
||||
[preview]: https://img.shields.io/badge/-preview-orange "preview"
|
||||
|
||||
Espressif SoCs released before 2016 (ESP8266 and ESP8285) are supported by [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK) instead.
|
||||
|
||||
# Developing With ESP-IDF
|
||||
|
||||
@ -99,8 +116,3 @@ This can be combined with other targets, ie `idf.py -p PORT erase_flash flash` w
|
||||
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
|
||||
|
||||
* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html).
|
||||
|
||||
|
||||
________
|
||||
|
||||
<a name="fn1">1</a>: ESP8266 and ESP8285 are not supported in ESP-IDF. See [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK) instead.
|
26
README_CN.md
26
README_CN.md
@ -2,13 +2,30 @@
|
||||
|
||||
* [English Version](./README.md)
|
||||
|
||||
ESP-IDF 是由乐鑫官方针对乐鑫各系列芯片产品(发布于 2016 年后<sup>[1](#fn1)</sup>)推出的开发框架,支持 Windows、Linux 和 macOS 操作系统。
|
||||
ESP-IDF 是乐鑫官方推出的物联网开发框架,支持 Windows、Linux 和 macOS 操作系统。
|
||||
|
||||
# ESP-IDF 与乐鑫芯片
|
||||
|
||||
下表总结了乐鑫芯片在 ESP-IDF 各版本中的支持状态,其中 ![alt text][supported] 代表已支持,![alt text][preview] 代表目前处于预览支持状态。在预览支持阶段,因为新芯片尚未完全添加到构建系统目录,所以一些重要的内容(如文档和技术规格书等)可能会缺失。请确保使用与芯片相匹配的 ESP-IDF 版本。
|
||||
|
||||
| 芯片 | v3.3 | v4.0 | v4.1 | v4.2 | v4.3 | v4.4 | |
|
||||
|:----------- |:---------------------: | :---------------------:| :---------------------:| :---------------------:| :---------------------:| :---------------------:|:---------------------------------------------------------- |
|
||||
|ESP32 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S2 | | | | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-C3 | | | | | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S3 | | | | | ![alt text][preview] | ![alt text][supported] | [芯片发布公告](https://www.espressif.com/en/news/ESP32_S3) |
|
||||
|ESP32-H2 | | | | | | ![alt text][preview] | [芯片发布公告](https://www.espressif.com/en/news/ESP32_H2) |
|
||||
|
||||
[supported]: https://img.shields.io/badge/-%E6%94%AF%E6%8C%81-green "supported"
|
||||
[preview]: https://img.shields.io/badge/-%E9%A2%84%E8%A7%88-orange "preview"
|
||||
|
||||
对于 2016 年之前发布的乐鑫芯片(包括 ESP8266 和 ESP8285),请参考 [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK)。
|
||||
|
||||
# 使用 ESP-IDF 进行开发
|
||||
|
||||
## 搭建 ESP-IDF 开发环境
|
||||
|
||||
关于不同芯片如何搭建 ESP-IDF 的开发环境,请参考 https://idf.espressif.com/。
|
||||
关于不同芯片如何搭建 ESP-IDF 的开发环境,请参考 https://idf.espressif.com/ 。
|
||||
|
||||
**注意:** 不同系列芯片和不同 ESP-IDF 版本都有其对应的文档。请参阅[版本](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/versions.html)部分,获得关于如何查找文档以及如何检出 ESP-IDF 的特定发行版的详细信息。
|
||||
|
||||
@ -99,8 +116,3 @@ ESP-IDF 中的子模块采用相对路径([详见 .gitmodules 文件](.gitmodu
|
||||
* 如果你在使用中发现了错误或者需要新的功能,请先[查看 GitHub Issues](https://github.com/espressif/esp-idf/issues),确保该问题没有重复提交。
|
||||
|
||||
* 如果你有兴趣为 ESP-IDF 作贡献,请先阅读[贡献指南](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html)。
|
||||
|
||||
|
||||
__________
|
||||
|
||||
<a name="fn1">1</a>: ESP-IDF 不支持 ESP8266 和 ESP8285。如有需要,请参考 [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK)。
|
||||
|
160
components/README.md
Normal file
160
components/README.md
Normal file
@ -0,0 +1,160 @@
|
||||
# Core Components
|
||||
|
||||
## Overview
|
||||
|
||||
This document contains details about what the core components are, what they contain, and how they are organized.
|
||||
|
||||
## Organization
|
||||
|
||||
The core components are organized into two groups.
|
||||
|
||||
The first group (referred to as `G0` from now on) contains `hal`, `xtensa` and `riscv` (referred to as `arch` components from now on), `esp_rom`, `esp_common`, and `soc`. This
|
||||
group contain information about and low-level access to underlying hardware; or in the case of `esp_common`, hardware-agnostic code and utilities.
|
||||
These components can depend on each other, but as much as possible have no dependencies outside the group. The reason for this is that, due to the
|
||||
nature of what these components contain, the likelihood is high that a lot of other components will require these. Ideally, then, the dependency
|
||||
relationship only goes one way. This makes it easier for these components, as a group, to be usable in another project. One can conceivably implement
|
||||
a competing SDK to ESP-IDF on top of these components.
|
||||
|
||||
The second group (referred to as `G1` from now on) sits at a higher level than the first group. This group contains the components `esp_hw_support`, `esp_system`, `newlib`, `spi_flash`,
|
||||
`freertos`, `log`, and `heap`. Like the first group, circular dependencies within the group are allowed; and being at a higher level, dependency on the first group
|
||||
is allowed. These components represent software mechanisms essential to building other components.
|
||||
|
||||
## Descriptions
|
||||
|
||||
The following is a short description of the components mentioned above.
|
||||
|
||||
### `G0` Components
|
||||
|
||||
#### `hal`
|
||||
|
||||
Contains the hardware abstraction layer and low-level operation implementations for the various peripherals. The low-level functions assign meaningful names to register-level manipulations; the hardware abstraction provide operations one level above this, grouping these low-level functions
|
||||
into routines that achieve a meaningful action or state of the peripheral.
|
||||
|
||||
Example:
|
||||
|
||||
- `spi_flash_ll_set_address` is a low-level function part of the hardware abstraction `spi_flash_hal_read_block`
|
||||
|
||||
#### `arch`
|
||||
|
||||
Contains low-level architecture operations and definitions, including those for customizations (can be thought of on the same level as the low-level functions of `hal`).
|
||||
This can also contain files provided by the architecture vendor.
|
||||
|
||||
Example:
|
||||
|
||||
- `xt_set_exception_handler`
|
||||
- `riscv_global_interrupts_enable`
|
||||
- `ERI_PERFMON_MAX`
|
||||
|
||||
#### `esp_common`
|
||||
|
||||
Contains hardware-agnostic definitions, constants, macros, utilities, 'pure' and/or algorithmic functions that is useable by all other components (that is, barring there being a more appropriate component to put them in).
|
||||
|
||||
Example:
|
||||
|
||||
- `BIT(nr)` and other bit manipulation utilities in the future
|
||||
- `IDF_DEPRECATED(REASON)`
|
||||
- `ESP_IDF_VERSION_MAJOR`
|
||||
|
||||
#### `soc`
|
||||
|
||||
Contains description of the underlying hardware: register structure, addresses, pins, capabilities, etc.
|
||||
|
||||
Example:
|
||||
|
||||
- `DR_REG_DPORT_BASE`
|
||||
- `SOC_MCPWM_SUPPORTED`
|
||||
- `uart_dev_s`
|
||||
|
||||
#### `esp_rom`
|
||||
|
||||
Contains headers, linker scripts, abstraction layer, patches, and other related files to ROM functions.
|
||||
|
||||
Example:
|
||||
|
||||
- `esp32.rom.eco3.ld`
|
||||
- `rom/aes.h`
|
||||
|
||||
### `G1` Components
|
||||
|
||||
#### `spi_flash`
|
||||
|
||||
SPI flash device access implementation.
|
||||
|
||||
#### `freertos`
|
||||
|
||||
FreeRTOS port to targets supported by ESP-IDF.
|
||||
|
||||
#### `log`
|
||||
|
||||
Logging library.
|
||||
|
||||
#### `heap`
|
||||
|
||||
Heap implementation.
|
||||
|
||||
#### `newlib`
|
||||
|
||||
Some functions n the standard library are implemented here, especially those needing other `G1` components.
|
||||
|
||||
Example:
|
||||
|
||||
- `malloc` is implemented in terms of the component `heap`'s functions
|
||||
- `gettimeofday` is implemented in terms of system time in `esp_system`
|
||||
|
||||
#### `esp_system`
|
||||
|
||||
Contains implementation of system services and controls system behavior. The implementations
|
||||
here may take hardware resources and/or decide on a hardware state needed for support of a system service/feature/mechanism.
|
||||
Currently, this encompasses the following, but not limited to:
|
||||
|
||||
- Startup and initialization
|
||||
- Panic and debug
|
||||
- Reset and reset reason
|
||||
- Task and interrupt watchdogs
|
||||
|
||||
#### `esp_hw_support`
|
||||
|
||||
Contains implementations that provide hardware operations, arbitration, or resource sharing, especially those that
|
||||
is used in the system. Unlike `esp_system`, implementations here do not decide on a hardware state or takes hardware resource, acting
|
||||
merely as facilitator to hardware access. Currently, this encompasses the following, but not limited to:
|
||||
|
||||
- Interrupt allocation
|
||||
- Sleep functions
|
||||
- Memory functions (external SPIRAM, async memory, etc.)
|
||||
- Clock and clock control
|
||||
- Random generation
|
||||
- CPU utilities
|
||||
- MAC settings
|
||||
|
||||
### `esp_hw_support` vs `esp_system`
|
||||
|
||||
This section details list some implementations and the reason for placing it in either `esp_hw_support` or `esp_system`.
|
||||
|
||||
#### `task_wdt.c` (`esp_system`) vs `intr_alloc.c` (`esp_hw_support`)
|
||||
|
||||
The task watchdog fits the definition of taking and configuring hardware resources (wdt, interrupt) for implementation of a system service/mechanism.
|
||||
|
||||
This is in contrast with interrupt allocation that merely facilitates access to the underlying hardware for other implementations -
|
||||
drivers, user code, and even the task watchdog mentioned previously!
|
||||
|
||||
#### `crosscore_int.c` (`esp_system`)
|
||||
|
||||
The current implementation of crosscore interrupts is tightly coupled with a number of interrupt reasons
|
||||
associated with system services/mechanisms: REASON_YIELD (scheduler), REASON_FREQ_SWITCH (power management)
|
||||
REASON_PRINT_BACKTRACE (panic and debug).
|
||||
|
||||
However, if an implementation exists that makes it possible to register an arbitrary interrupt reason - a
|
||||
lower level inter-processor call if you will, then this implementation is a good candidate for `esp_hw_support`.
|
||||
The current implementation in `esp_system` can then just register the interrupt reasons mentioned above.
|
||||
|
||||
#### `esp_mac.h`, `esp_chip_info.h`, `esp_random.h` (`esp_hw_support`)
|
||||
|
||||
The functions in these headers used to be in `esp_system.h`, but have been split-off.
|
||||
However, to maintain backward compatibility, `esp_system.h` includes these headers.
|
||||
|
||||
The remaining functions in `esp_system.h` are those that deal with system behavior, such
|
||||
as `esp_register_shutdown_handler`, or are proxy for other system components's APIs such as
|
||||
`esp_get_free_heap_size`.
|
||||
|
||||
The functions split-off from `esp_system.h` are much more hardware manipulation oriented such as:
|
||||
`esp_read_mac`, `esp_random` and `esp_chip_info`.
|
@ -47,7 +47,7 @@ endif()
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
PRIV_REQUIRES soc
|
||||
PRIV_REQUIRES soc esp_ipc
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
# disable --coverage for this component, as it is used as transport
|
||||
|
@ -14,7 +14,9 @@
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/timer_periph.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_freertos_hooks.h"
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/libc_stubs.h"
|
||||
@ -28,128 +30,113 @@
|
||||
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_gcov_rtio";
|
||||
static volatile bool s_create_gcov_task = false;
|
||||
static volatile bool s_gcov_task_running = false;
|
||||
|
||||
extern void __gcov_dump(void);
|
||||
extern void __gcov_reset(void);
|
||||
|
||||
static struct syscall_stub_table s_gcov_stub_table;
|
||||
|
||||
|
||||
static int gcov_stub_lock_try_acquire_recursive(_lock_t *lock)
|
||||
void gcov_dump_task(void *pvParameter)
|
||||
{
|
||||
if (*lock && uxSemaphoreGetCount((xSemaphoreHandle)(*lock)) == 0) {
|
||||
// we can do nothing here, gcov dump is initiated with some resource locked
|
||||
// which is also used by gcov functions
|
||||
ESP_EARLY_LOGE(TAG, "Lock 0x%x is busy during GCOV dump! System state can be inconsistent after dump!", lock);
|
||||
}
|
||||
return pdTRUE;
|
||||
}
|
||||
int dump_result = 0;
|
||||
bool *running = (bool *)pvParameter;
|
||||
|
||||
static void gcov_stub_lock_acquire_recursive(_lock_t *lock)
|
||||
{
|
||||
gcov_stub_lock_try_acquire_recursive(lock);
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use in %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
static void gcov_stub_lock_release_recursive(_lock_t *lock)
|
||||
{
|
||||
}
|
||||
|
||||
static int esp_dbg_stub_gcov_dump_do(void)
|
||||
{
|
||||
int ret = ESP_OK;
|
||||
FILE* old_stderr = stderr;
|
||||
FILE* old_stdout = stdout;
|
||||
static struct syscall_stub_table *old_tables[portNUM_PROCESSORS];
|
||||
|
||||
old_tables[0] = syscall_table_ptr_pro;
|
||||
#if portNUM_PROCESSORS > 1
|
||||
old_tables[1] = syscall_table_ptr_app;
|
||||
#endif
|
||||
ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE);
|
||||
void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE);
|
||||
if (down_buf == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "Could not allocate memory for the buffer");
|
||||
return ESP_ERR_NO_MEM;
|
||||
dump_result = ESP_ERR_NO_MEM;
|
||||
goto gcov_exit;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Config apptrace down buf");
|
||||
esp_apptrace_down_buffer_config(down_buf, ESP_GCOV_DOWN_BUF_SIZE);
|
||||
/* we are directing the std outputs to the fake ones in order to reduce stack usage */
|
||||
FILE *old_stderr = stderr;
|
||||
FILE *old_stdout = stdout;
|
||||
stderr = (FILE *) &__sf_fake_stderr;
|
||||
stdout = (FILE *) &__sf_fake_stdout;
|
||||
ESP_EARLY_LOGV(TAG, "Dump data...");
|
||||
// incase of dual-core chip APP and PRO CPUs share the same table, so it is safe to save only PRO's table
|
||||
memcpy(&s_gcov_stub_table, syscall_table_ptr_pro, sizeof(s_gcov_stub_table));
|
||||
s_gcov_stub_table._lock_acquire_recursive = &gcov_stub_lock_acquire_recursive;
|
||||
s_gcov_stub_table._lock_release_recursive = &gcov_stub_lock_release_recursive;
|
||||
s_gcov_stub_table._lock_try_acquire_recursive = &gcov_stub_lock_try_acquire_recursive,
|
||||
syscall_table_ptr_pro = &s_gcov_stub_table;
|
||||
#if portNUM_PROCESSORS > 1
|
||||
syscall_table_ptr_app = &s_gcov_stub_table;
|
||||
#endif
|
||||
stderr = (FILE*) &__sf_fake_stderr;
|
||||
stdout = (FILE*) &__sf_fake_stdout;
|
||||
__gcov_dump();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
__gcov_reset();
|
||||
stdout = old_stdout;
|
||||
stderr = old_stderr;
|
||||
syscall_table_ptr_pro = old_tables[0];
|
||||
#if portNUM_PROCESSORS > 1
|
||||
syscall_table_ptr_app = old_tables[1];
|
||||
#endif
|
||||
ESP_EARLY_LOGV(TAG, "Free apptrace down buf");
|
||||
free(down_buf);
|
||||
stderr = old_stderr;
|
||||
stdout = old_stdout;
|
||||
ESP_EARLY_LOGV(TAG, "Finish file transfer session");
|
||||
ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
dump_result = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (dump_result != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", dump_result);
|
||||
}
|
||||
|
||||
gcov_exit:
|
||||
ESP_EARLY_LOGV(TAG, "dump_result %d", dump_result);
|
||||
if (running) {
|
||||
*running = false;
|
||||
}
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use out %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void gcov_create_task(void *arg)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", 2048, (void *)&s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
}
|
||||
|
||||
void gcov_create_task_tick_hook(void)
|
||||
{
|
||||
extern esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
if (s_create_gcov_task) {
|
||||
if (esp_ipc_start_gcov_from_isr(xPortGetCoreID(), &gcov_create_task, NULL) == ESP_OK) {
|
||||
s_create_gcov_task = false;
|
||||
}
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "exit %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Triggers gcov info dump.
|
||||
* @brief Triggers gcov info dump task
|
||||
* This function is to be called by OpenOCD, not by normal user code.
|
||||
* TODO: what about interrupted flash access (when cache disabled)???
|
||||
* TODO: what about interrupted flash access (when cache disabled)
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
static int esp_dbg_stub_gcov_entry(void)
|
||||
{
|
||||
return esp_dbg_stub_gcov_dump_do();
|
||||
/* we are in isr context here */
|
||||
s_create_gcov_task = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
|
||||
{
|
||||
uint32_t capabilities = 0;
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
|
||||
return 0;
|
||||
if (esp_dbg_stub_entry_get(ESP_DBG_STUB_ENTRY_CAPABILITIES, &capabilities) == ESP_OK) {
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK);
|
||||
}
|
||||
esp_register_freertos_tick_hook(gcov_create_task_tick_hook);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_gcov_dump(void)
|
||||
{
|
||||
// disable IRQs on this CPU, other CPU is halted by OpenOCD
|
||||
unsigned irq_state = portENTER_CRITICAL_NESTED();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
int other_core = cpu_hal_get_core_id() ? 0 : 1;
|
||||
esp_cpu_stall(other_core);
|
||||
#endif
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
|
||||
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) {
|
||||
wdt_hal_context_t twdt = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
|
||||
wdt_hal_context_t iwdt = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
|
||||
//Feed the Task Watchdog (TG0) to prevent it from timing out
|
||||
wdt_hal_write_protect_disable(&twdt);
|
||||
wdt_hal_feed(&twdt);
|
||||
wdt_hal_write_protect_enable(&twdt);
|
||||
//Likewise, feed the Interrupt Watchdog (TG1) to prevent a reboot
|
||||
wdt_hal_write_protect_disable(&iwdt);
|
||||
wdt_hal_feed(&iwdt);
|
||||
wdt_hal_write_protect_enable(&iwdt);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
esp_dbg_stub_gcov_dump_do();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
esp_cpu_unstall(other_core);
|
||||
#endif
|
||||
portEXIT_CRITICAL_NESTED(irq_state);
|
||||
/* We are not in isr context here. Waiting for the completion is safe */
|
||||
s_gcov_task_running = true;
|
||||
s_create_gcov_task = true;
|
||||
while (s_gcov_task_running) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
void *gcov_rtio_fopen(const char *path, const char *mode)
|
||||
@ -168,7 +155,7 @@ int gcov_rtio_fclose(void *stream)
|
||||
|
||||
size_t gcov_rtio_fread(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s read %u", __FUNCTION__, size*nmemb);
|
||||
ESP_EARLY_LOGV(TAG, "%s read %u", __FUNCTION__, size * nmemb);
|
||||
size_t sz = esp_apptrace_fread(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s actually read %u", __FUNCTION__, sz);
|
||||
return sz;
|
||||
|
@ -151,16 +151,17 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
// The lowest RAM address used for IDs (pointers)
|
||||
#define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
#ifdef CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
|
||||
#if CONFIG_FREERTOS_CORETIMER_0
|
||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
#if CONFIG_FREERTOS_CORETIMER_1
|
||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
|
||||
#elif CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE)
|
||||
#endif // CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
|
||||
|
||||
// SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
|
||||
// disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
|
||||
|
@ -209,7 +209,7 @@ Notes:
|
||||
#define apiID_VEVENTGROUPDELETE (72u)
|
||||
#define apiID_UXEVENTGROUPGETNUMBER (73u)
|
||||
|
||||
#define traceTASK_NOTIFY_TAKE() SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_ULTASKNOTIFYTAKE, xClearCountOnExit, xTicksToWait)
|
||||
#define traceTASK_NOTIFY_TAKE( uxIndexToWait ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_ULTASKNOTIFYTAKE, xClearCountOnExit, xTicksToWait)
|
||||
#define traceTASK_DELAY() SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKDELAY, xTicksToDelay)
|
||||
#define traceTASK_DELAY_UNTIL() SEGGER_SYSVIEW_RecordVoid(apiFastID_OFFSET + apiID_VTASKDELAYUNTIL)
|
||||
#define traceTASK_DELETE( pxTCB ) if (pxTCB != NULL) { \
|
||||
@ -217,16 +217,16 @@ Notes:
|
||||
SEGGER_SYSVIEW_ShrinkId((U32)pxTCB)); \
|
||||
SYSVIEW_DeleteTask((U32)pxTCB); \
|
||||
}
|
||||
#define traceTASK_NOTIFY_GIVE_FROM_ISR() SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VTASKNOTIFYGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VTASKNOTIFYGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_PRIORITY_INHERIT( pxTCB, uxPriority ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKPRIORITYINHERIT, (U32)pxMutexHolder)
|
||||
#define traceTASK_RESUME( pxTCB ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKRESUME, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
|
||||
#define traceINCREASE_TICK_COUNT( xTicksToJump ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKSTEPTICK, xTicksToJump)
|
||||
#define traceTASK_SUSPEND( pxTCB ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKSUSPEND, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
|
||||
#define traceTASK_PRIORITY_DISINHERIT( pxTCB, uxBasePriority ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_XTASKPRIORITYDISINHERIT, (U32)pxMutexHolder)
|
||||
#define traceTASK_RESUME_FROM_ISR( pxTCB ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_XTASKRESUMEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
|
||||
#define traceTASK_NOTIFY() SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFY, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue)
|
||||
#define traceTASK_NOTIFY_FROM_ISR() SYSVIEW_RecordU32x5(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFYFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue, (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_NOTIFY_WAIT() SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKNOTIFYWAIT, ulBitsToClearOnEntry, ulBitsToClearOnExit, (U32)pulNotificationValue, xTicksToWait)
|
||||
#define traceTASK_NOTIFY( uxIndexToNotify ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFY, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue)
|
||||
#define traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify ) SYSVIEW_RecordU32x5(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFYFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue, (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_NOTIFY_WAIT( uxIndexToWait ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKNOTIFYWAIT, ulBitsToClearOnEntry, ulBitsToClearOnExit, (U32)pulNotificationValue, xTicksToWait)
|
||||
|
||||
#define traceQUEUE_CREATE( pxNewQueue ) SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUEGENERICCREATE, uxQueueLength, uxItemSize, ucQueueType)
|
||||
#define traceQUEUE_DELETE( pxQueue ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VQUEUEDELETE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue))
|
||||
|
@ -46,6 +46,7 @@ if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
add_custom_target(blank_ota_data ALL DEPENDS ${blank_otadata_file})
|
||||
add_dependencies(flash blank_ota_data)
|
||||
add_dependencies(encrypted-flash blank_ota_data)
|
||||
|
||||
set(otatool_py ${python} ${COMPONENT_DIR}/otatool.py)
|
||||
|
||||
|
@ -386,6 +386,15 @@ menu "Bootloader config"
|
||||
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
|
||||
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.
|
||||
|
||||
config BOOTLOADER_FLASH_XMC_SUPPORT
|
||||
bool "Enable the support for flash chips of XMC (READ HELP FIRST)"
|
||||
default y
|
||||
help
|
||||
Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow.
|
||||
XMC chips will be forbidden to be used, when this option is disabled.
|
||||
|
||||
DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||
|
||||
endmenu # Bootloader
|
||||
|
||||
|
||||
@ -415,12 +424,12 @@ menu "Security features"
|
||||
config SECURE_BOOT_SUPPORTS_RSA
|
||||
bool
|
||||
default y
|
||||
depends on ESP32_REV_MIN_3 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
|
||||
depends on ESP32_REV_MIN_3 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
|
||||
|
||||
config SECURE_TARGET_HAS_SECURE_ROM_DL_MODE
|
||||
bool
|
||||
default y
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
|
||||
|
||||
|
||||
config SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
@ -492,7 +501,8 @@ 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_ESP32 || IDF_TARGET_ESP32S2 || ESP32C3_REV_MIN_3 || IDF_TARGET_ESP32S3
|
||||
select ESPTOOLPY_NO_STUB if !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2
|
||||
help
|
||||
Build a bootloader which enables Secure Boot on first boot.
|
||||
|
||||
@ -755,9 +765,17 @@ menu "Security features"
|
||||
efuse when Secure Boot is enabled. This prevents any more efuses from being read protected.
|
||||
|
||||
If this option is set, it will remain possible to write the EFUSE_RD_DIS efuse field after Secure
|
||||
Boot is enabled. This may allow an attacker to read-protect the BLK2 efuse holding the public
|
||||
key digest, causing an immediate denial of service and possibly allowing an additional fault
|
||||
injection attack to bypass the signature protection.
|
||||
Boot is enabled. This may allow an attacker to read-protect the BLK2 efuse (for ESP32) and
|
||||
BLOCK4-BLOCK10 (i.e. BLOCK_KEY0-BLOCK_KEY5)(for other chips) holding the public key digest, causing an
|
||||
immediate denial of service and possibly allowing an additional fault injection attack to
|
||||
bypass the signature protection.
|
||||
|
||||
NOTE: Once a BLOCK is read-protected, the application will read all zeros from that block
|
||||
|
||||
NOTE: If "UART ROM download mode (Permanently disabled (recommended))" or
|
||||
"UART ROM download mode (Permanently switch to Secure mode (recommended))" is set,
|
||||
then it is __NOT__ possible to read/write efuses using espefuse.py utility.
|
||||
However, efuse can be read/written from the application
|
||||
|
||||
config SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS
|
||||
bool "Leave unused digest slots available (not revoke)"
|
||||
@ -875,6 +893,8 @@ menu "Security features"
|
||||
It is also possible to enable secure download mode at runtime by calling
|
||||
esp_efuse_enable_rom_secure_download_mode()
|
||||
|
||||
Note: Secure Download mode is not available for ESP32 (includes revisions till ECO3).
|
||||
|
||||
config SECURE_INSECURE_ALLOW_DL_MODE
|
||||
bool "UART ROM download mode (Enabled (not recommended))"
|
||||
help
|
||||
|
@ -49,6 +49,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
|
||||
|
@ -36,6 +36,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
|
||||
|
@ -36,6 +36,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
|
||||
|
@ -36,6 +36,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
|
||||
|
@ -37,6 +37,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
|
||||
|
@ -26,6 +26,7 @@ if(BOOTLOADER_BUILD)
|
||||
"src/bootloader_console_loader.c"
|
||||
"src/bootloader_panic.c"
|
||||
"src/${IDF_TARGET}/bootloader_sha.c"
|
||||
"src/${IDF_TARGET}/bootloader_soc.c"
|
||||
"src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c"
|
||||
)
|
||||
list(APPEND priv_requires hal)
|
||||
|
@ -119,6 +119,15 @@ bool bootloader_common_label_search(const char *list, char *label);
|
||||
*/
|
||||
void bootloader_configure_spi_pins(int drv);
|
||||
|
||||
/**
|
||||
* @brief Get flash CS IO
|
||||
*
|
||||
* Can be determined by eFuse values, or the default value
|
||||
*
|
||||
* @return Flash CS IO
|
||||
*/
|
||||
uint8_t bootloader_flash_get_cs_io(void);
|
||||
|
||||
/**
|
||||
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
|
||||
*
|
||||
|
@ -14,6 +14,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Read flash ID by sending RDID command (0x9F)
|
||||
* @return flash raw ID
|
||||
* mfg_id = (ID >> 16) & 0xFF;
|
||||
flash_id = ID & 0xffff;
|
||||
*/
|
||||
uint32_t bootloader_read_flash_id(void);
|
||||
|
||||
#if SOC_CACHE_SUPPORT_WRAP
|
||||
/**
|
||||
* @brief Set the burst mode setting command for specified wrap mode.
|
||||
@ -32,6 +40,13 @@ esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode);
|
||||
*/
|
||||
esp_err_t bootloader_flash_unlock(void);
|
||||
|
||||
/**
|
||||
* @brief Startup flow recommended by XMC. Call at startup before any erase/write operation.
|
||||
*
|
||||
* @return ESP_OK When startup successfully, otherwise ESP_FAIL (indiciating you should reboot before erase/write).
|
||||
*/
|
||||
esp_err_t bootloader_flash_xmc_startup(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -29,6 +29,7 @@
|
||||
#define CMD_RDSR 0x05
|
||||
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
|
||||
#define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */
|
||||
#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */
|
||||
#define CMD_WRAP 0x77 /* Set burst with wrap command */
|
||||
#define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */
|
||||
|
||||
@ -156,6 +157,15 @@ static inline uint32_t bootloader_cache_pages_to_map(uint32_t size, uint32_t vad
|
||||
*/
|
||||
uint32_t bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len);
|
||||
|
||||
/**
|
||||
* @brief Read the SFDP of the flash
|
||||
*
|
||||
* @param sfdp_addr Address of the parameter to read
|
||||
* @param miso_byte_num Bytes to read
|
||||
* @return The read SFDP, little endian, 4 bytes at most
|
||||
*/
|
||||
uint32_t bootloader_flash_read_sfdp(uint32_t sfdp_addr, unsigned int miso_byte_num);
|
||||
|
||||
/**
|
||||
* @brief Enable the flash write protect (WEL bit).
|
||||
*/
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @brief Configure analog super WDT reset
|
||||
*
|
||||
* @param enable Boolean to enable or disable super WDT reset
|
||||
*/
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Configure analog brownout reset
|
||||
*
|
||||
* @param enable Boolean to enable or disable brownout reset
|
||||
*/
|
||||
void bootloader_ana_bod_reset_config(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Configure analog clock glitch reset
|
||||
*
|
||||
* @param enable Boolean to enable or disable clock glitch reset
|
||||
*/
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable);
|
@ -23,6 +23,7 @@
|
||||
#include "esp_rom_crc.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_common.h"
|
||||
@ -191,8 +192,19 @@ void bootloader_common_vddsdio_configure(void)
|
||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||
}
|
||||
|
||||
|
||||
RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
|
||||
{
|
||||
return (RESET_REASON)esp_rom_get_reset_reason(cpu_no);
|
||||
}
|
||||
|
||||
uint8_t bootloader_flash_get_cs_io(void)
|
||||
{
|
||||
uint8_t cs_io;
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
|
||||
cs_io = SPI_CS0_GPIO_NUM;
|
||||
} else {
|
||||
cs_io = (spiconfig >> 18) & 0x3f;
|
||||
}
|
||||
return cs_io;
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ void bootloader_console_init(void)
|
||||
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);
|
||||
// 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;
|
||||
const uint32_t tx_idx = UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX);
|
||||
const uint32_t rx_idx = UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX);
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
|
||||
esp_rom_gpio_pad_pullup_only(uart_rx_gpio);
|
||||
esp_rom_gpio_connect_out_signal(uart_tx_gpio, tx_idx, 0, 0);
|
||||
|
@ -7,14 +7,14 @@
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_clock.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
|
||||
uint8_t bootloader_common_get_chip_revision(void)
|
||||
{
|
||||
uint8_t eco_bit0, eco_bit1, eco_bit2;
|
||||
eco_bit0 = (REG_READ(EFUSE_BLK0_RDATA3_REG) & 0xF000) >> 15;
|
||||
eco_bit1 = (REG_READ(EFUSE_BLK0_RDATA5_REG) & 0x100000) >> 20;
|
||||
eco_bit2 = (REG_READ(APB_CTRL_DATE_REG) & 0x80000000) >> 31;
|
||||
eco_bit2 = (REG_READ(SYSCON_DATE_REG) & 0x80000000) >> 31;
|
||||
uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0;
|
||||
uint8_t chip_ver = 0;
|
||||
switch (combine_value) {
|
||||
@ -28,7 +28,7 @@ uint8_t bootloader_common_get_chip_revision(void)
|
||||
chip_ver = 2;
|
||||
break;
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
case 4: /* Empty efuses, but APB_CTRL_DATE_REG bit is set */
|
||||
case 4: /* Empty efuses, but SYSCON_DATE_REG bit is set */
|
||||
chip_ver = 3;
|
||||
break;
|
||||
#endif
|
||||
|
@ -19,5 +19,5 @@ uint8_t bootloader_common_get_chip_revision(void)
|
||||
uint32_t bootloader_common_get_chip_ver_pkg(void)
|
||||
{
|
||||
// should return the same value as esp_efuse_get_pkg_ver()
|
||||
return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION);
|
||||
return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_4_REG, EFUSE_PKG_VERSION);
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
return spi_flash_erase_range(start_addr, size);
|
||||
}
|
||||
|
||||
#else
|
||||
#else //BOOTLOADER_BUILD
|
||||
/* Bootloader version, uses ROM functions only */
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/spi_flash.h"
|
||||
@ -481,7 +481,8 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
return spi_to_esp_err(rc);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
|
||||
FORCE_INLINE_ATTR bool is_issi_chip(const esp_rom_spiflash_chip_t* chip)
|
||||
{
|
||||
@ -563,29 +564,49 @@ esp_err_t IRAM_ATTR __attribute__((weak)) bootloader_flash_unlock(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
#ifndef g_rom_spiflash_dummy_len_plus // ESP32-C3 uses a macro to access ROM data here
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
#endif
|
||||
uint32_t IRAM_ATTR bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
|
||||
IRAM_ATTR static uint32_t bootloader_flash_execute_command_common(
|
||||
uint8_t command,
|
||||
uint32_t addr_len, uint32_t address,
|
||||
uint8_t dummy_len,
|
||||
uint8_t mosi_len, uint32_t mosi_data,
|
||||
uint8_t miso_len)
|
||||
{
|
||||
assert(mosi_len <= 32);
|
||||
assert(miso_len <= 32);
|
||||
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
|
||||
uint32_t old_user_reg = SPIFLASH.user.val;
|
||||
uint32_t old_user1_reg = SPIFLASH.user1.val;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SPIFLASH.ctrl.val = SPI_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
|
||||
#else
|
||||
SPIFLASH.ctrl.val = SPI_MEM_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
|
||||
#endif
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user.usr_addr = 0;
|
||||
//command phase
|
||||
SPIFLASH.user.usr_command = 1;
|
||||
SPIFLASH.user2.usr_command_bitlen = 7;
|
||||
|
||||
SPIFLASH.user2.usr_command_value = command;
|
||||
SPIFLASH.user.usr_miso = miso_len > 0;
|
||||
//addr phase
|
||||
SPIFLASH.user.usr_addr = addr_len > 0;
|
||||
SPIFLASH.user1.usr_addr_bitlen = addr_len - 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
|
||||
SPIFLASH.addr = (addr_len > 0)? (address << (32-addr_len)) : 0;
|
||||
#else
|
||||
SPIFLASH.miso_dlen.usr_miso_bit_len = miso_len ? (miso_len - 1) : 0;
|
||||
SPIFLASH.addr = address;
|
||||
#endif
|
||||
//dummy phase
|
||||
if (miso_len > 0) {
|
||||
uint32_t total_dummy = dummy_len + g_rom_spiflash_dummy_len_plus[1];
|
||||
SPIFLASH.user.usr_dummy = total_dummy > 0;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = total_dummy - 1;
|
||||
} else {
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = 0;
|
||||
}
|
||||
//output data
|
||||
SPIFLASH.user.usr_mosi = mosi_len > 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
|
||||
@ -593,24 +614,52 @@ uint32_t IRAM_ATTR bootloader_execute_flash_command(uint8_t command, uint32_t mo
|
||||
SPIFLASH.mosi_dlen.usr_mosi_bit_len = mosi_len ? (mosi_len - 1) : 0;
|
||||
#endif
|
||||
SPIFLASH.data_buf[0] = mosi_data;
|
||||
|
||||
if (g_rom_spiflash_dummy_len_plus[1]) {
|
||||
/* When flash pins are mapped via GPIO matrix, need a dummy cycle before reading via MISO */
|
||||
if (miso_len > 0) {
|
||||
SPIFLASH.user.usr_dummy = 1;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = g_rom_spiflash_dummy_len_plus[1] - 1;
|
||||
} else {
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = 0;
|
||||
}
|
||||
}
|
||||
//input data
|
||||
SPIFLASH.user.usr_miso = miso_len > 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
|
||||
#else
|
||||
SPIFLASH.miso_dlen.usr_miso_bit_len = miso_len ? (miso_len - 1) : 0;
|
||||
#endif
|
||||
|
||||
SPIFLASH.cmd.usr = 1;
|
||||
while (SPIFLASH.cmd.usr != 0) {
|
||||
}
|
||||
|
||||
SPIFLASH.ctrl.val = old_ctrl_reg;
|
||||
return SPIFLASH.data_buf[0];
|
||||
SPIFLASH.user.val = old_user_reg;
|
||||
SPIFLASH.user1.val = old_user1_reg;
|
||||
|
||||
uint32_t ret = SPIFLASH.data_buf[0];
|
||||
if (miso_len < 32) {
|
||||
//set unused bits to 0
|
||||
ret &= ~(UINT32_MAX << miso_len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
|
||||
{
|
||||
const uint8_t addr_len = 0;
|
||||
const uint8_t address = 0;
|
||||
const uint8_t dummy_len = 0;
|
||||
|
||||
return bootloader_flash_execute_command_common(command, addr_len, address,
|
||||
dummy_len, mosi_len, mosi_data, miso_len);
|
||||
}
|
||||
|
||||
// cmd(0x5A) + 24bit address + 8 cycles dummy
|
||||
uint32_t IRAM_ATTR bootloader_flash_read_sfdp(uint32_t sfdp_addr, unsigned int miso_byte_num)
|
||||
{
|
||||
assert(miso_byte_num <= 4);
|
||||
const uint8_t command = CMD_RDSFDP;
|
||||
const uint8_t addr_len = 24;
|
||||
const uint8_t dummy_len = 8;
|
||||
const uint8_t mosi_len = 0;
|
||||
const uint32_t mosi_data = 0;
|
||||
const uint8_t miso_len = miso_byte_num * 8;
|
||||
|
||||
return bootloader_flash_execute_command_common(command, addr_len, sfdp_addr,
|
||||
dummy_len, mosi_len, mosi_data, miso_len);
|
||||
}
|
||||
|
||||
void bootloader_enable_wp(void)
|
||||
@ -618,6 +667,13 @@ void bootloader_enable_wp(void)
|
||||
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR bootloader_read_flash_id(void)
|
||||
{
|
||||
uint32_t id = bootloader_execute_flash_command(CMD_RDID, 0, 0, 24);
|
||||
id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00);
|
||||
return id;
|
||||
}
|
||||
|
||||
#if SOC_CACHE_SUPPORT_WRAP
|
||||
esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode)
|
||||
{
|
||||
@ -649,3 +705,104 @@ esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode)
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif //SOC_CACHE_SUPPORT_WRAP
|
||||
|
||||
/*******************************************************************************
|
||||
* XMC startup flow
|
||||
******************************************************************************/
|
||||
|
||||
#define XMC_SUPPORT CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT
|
||||
#define XMC_VENDOR_ID 0x20
|
||||
|
||||
#if BOOTLOADER_BUILD
|
||||
#define BOOTLOADER_FLASH_LOG(level, ...) ESP_LOG##level(TAG, ##__VA_ARGS__)
|
||||
#else
|
||||
static DRAM_ATTR char bootloader_flash_tag[] = "bootloader_flash";
|
||||
#define BOOTLOADER_FLASH_LOG(level, ...) ESP_DRAM_LOG##level(bootloader_flash_tag, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if XMC_SUPPORT
|
||||
//strictly check the model
|
||||
static IRAM_ATTR bool is_xmc_chip_strict(uint32_t rdid)
|
||||
{
|
||||
uint32_t vendor_id = BYTESHIFT(rdid, 2);
|
||||
uint32_t mfid = BYTESHIFT(rdid, 1);
|
||||
uint32_t cpid = BYTESHIFT(rdid, 0);
|
||||
|
||||
if (vendor_id != XMC_VENDOR_ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool matched = false;
|
||||
if (mfid == 0x40) {
|
||||
if (cpid >= 0x13 && cpid <= 0x20) {
|
||||
matched = true;
|
||||
}
|
||||
} else if (mfid == 0x41) {
|
||||
if (cpid >= 0x17 && cpid <= 0x20) {
|
||||
matched = true;
|
||||
}
|
||||
} else if (mfid == 0x50) {
|
||||
if (cpid >= 0x15 && cpid <= 0x16) {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void)
|
||||
{
|
||||
// If the RDID value is a valid XMC one, may skip the flow
|
||||
const bool fast_check = true;
|
||||
if (fast_check && is_xmc_chip_strict(g_rom_flashchip.device_id)) {
|
||||
BOOTLOADER_FLASH_LOG(D, "XMC chip detected by RDID (%08X), skip.", g_rom_flashchip.device_id);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Check the Manufacturer ID in SFDP registers (JEDEC standard). If not XMC chip, no need to run the flow
|
||||
const int sfdp_mfid_addr = 0x10;
|
||||
uint8_t mf_id = (bootloader_flash_read_sfdp(sfdp_mfid_addr, 1) & 0xff);
|
||||
if (mf_id != XMC_VENDOR_ID) {
|
||||
BOOTLOADER_FLASH_LOG(D, "non-XMC chip detected by SFDP Read (%02X), skip.", mf_id);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
BOOTLOADER_FLASH_LOG(I, "XM25QHxxC startup flow");
|
||||
// Enter DPD
|
||||
bootloader_execute_flash_command(0xB9, 0, 0, 0);
|
||||
// Enter UDPD
|
||||
bootloader_execute_flash_command(0x79, 0, 0, 0);
|
||||
// Exit UDPD
|
||||
bootloader_execute_flash_command(0xFF, 0, 0, 0);
|
||||
// Delay tXUDPD
|
||||
esp_rom_delay_us(2000);
|
||||
// Release Power-down
|
||||
bootloader_execute_flash_command(0xAB, 0, 0, 0);
|
||||
esp_rom_delay_us(20);
|
||||
// Read flash ID and check again
|
||||
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||
if (!is_xmc_chip_strict(g_rom_flashchip.device_id)) {
|
||||
BOOTLOADER_FLASH_LOG(E, "XMC flash startup fail");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
//only compare the vendor id
|
||||
static IRAM_ATTR bool is_xmc_chip(uint32_t rdid)
|
||||
{
|
||||
uint32_t vendor_id = (rdid >> 16) & 0xFF;
|
||||
return (vendor_id == XMC_VENDOR_ID);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void)
|
||||
{
|
||||
if (is_xmc_chip(g_rom_flashchip.device_id)) {
|
||||
BOOTLOADER_FLASH_LOG(E, "XMC chip detected (%08X) while support disabled.", g_rom_flashchip.device_id);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif //XMC_SUPPORT
|
||||
|
@ -33,18 +33,18 @@ void bootloader_flash_update_id()
|
||||
|
||||
void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||
{
|
||||
// SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for FLASH/PSRAM, so we only need to set SPI0 related registers here
|
||||
//SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for FLASH, so we only need to set SPI0 related registers here
|
||||
#if CONFIG_ESPTOOLPY_OCT_FLASH
|
||||
SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_CS_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, FLASH_CS_SETUP_TIME, SPI_MEM_CS_SETUP_TIME_S);
|
||||
|
||||
SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_SETUP_TIME_V, FLASH_CS_SETUP_TIME, SPI_MEM_SPI_SMEM_CS_SETUP_TIME_S);
|
||||
|
||||
// cs high time
|
||||
//CS high time
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_DELAY_V, FLASH_CS_HOLD_DELAY, SPI_MEM_CS_HOLD_DELAY_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V, FLASH_CS_HOLD_DELAY, SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S);
|
||||
#else
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S);
|
||||
SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)
|
||||
|
@ -76,6 +76,7 @@
|
||||
#include "bootloader_utility.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
static const char *TAG = "boot";
|
||||
@ -636,6 +637,12 @@ static void load_image(const esp_image_metadata_t *image_data)
|
||||
ESP_LOGI(TAG, "Disabling RNG early entropy source...");
|
||||
bootloader_random_disable();
|
||||
|
||||
/* Disable glitch reset after all the security checks are completed.
|
||||
* Glitch detection can be falsely triggered by EMI interference (high RF TX power, etc)
|
||||
* and to avoid such false alarms, disable it.
|
||||
*/
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
|
||||
// copy loaded segments to RAM, set up caches for mapped segments, and start application
|
||||
unpack_load_app(image_data);
|
||||
}
|
||||
|
@ -387,6 +387,11 @@ esp_err_t bootloader_init(void)
|
||||
bootloader_print_banner();
|
||||
// update flash ID
|
||||
bootloader_flash_update_id();
|
||||
// Check and run XMC startup flow
|
||||
if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
|
||||
goto err;
|
||||
}
|
||||
// read bootloader header
|
||||
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
|
||||
goto err;
|
||||
|
21
components/bootloader_support/src/esp32/bootloader_soc.c
Normal file
21
components/bootloader_support/src/esp32/bootloader_soc.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
@ -36,6 +36,7 @@
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
static const char *TAG = "boot.esp32c3";
|
||||
@ -263,7 +264,7 @@ static inline void bootloader_hardware_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bootloader_glitch_reset_disable(void)
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
/*
|
||||
For origin chip & ECO1: only support swt reset;
|
||||
@ -271,10 +272,27 @@ static inline void bootloader_glitch_reset_disable(void)
|
||||
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);
|
||||
switch (chip_version) {
|
||||
case 0:
|
||||
case 1:
|
||||
//Enable WDT reset. Disable BOR and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(false);
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
break;
|
||||
case 2:
|
||||
//Enable WDT and BOR reset. Disable GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
//Enable WDT, BOR, and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,7 +301,7 @@ esp_err_t bootloader_init(void)
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
bootloader_hardware_init();
|
||||
bootloader_glitch_reset_disable();
|
||||
bootloader_ana_reset_config();
|
||||
bootloader_super_wdt_auto_feed();
|
||||
// protect memory region
|
||||
bootloader_init_mem();
|
||||
@ -309,6 +327,11 @@ esp_err_t bootloader_init(void)
|
||||
bootloader_print_banner();
|
||||
// update flash ID
|
||||
bootloader_flash_update_id();
|
||||
// Check and run XMC startup flow
|
||||
if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
|
||||
goto err;
|
||||
}
|
||||
// read bootloader header
|
||||
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
|
||||
goto err;
|
||||
|
41
components/bootloader_support/src/esp32c3/bootloader_soc.c
Normal file
41
components/bootloader_support/src/esp32c3/bootloader_soc.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOR_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_GLITCH_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
}
|
||||
}
|
@ -40,5 +40,11 @@ esp_err_t esp_flash_encryption_enable_secure_features(void)
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
|
||||
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
|
||||
// otherwise the Flash Encryption key cannot be read protected
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -40,5 +40,20 @@ esp_err_t esp_secure_boot_enable_secure_features(void)
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
bool rd_dis_now = true;
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
/* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
|
||||
when Flash Encryption is being enabled */
|
||||
rd_dis_now = esp_flash_encryption_enabled();
|
||||
#endif
|
||||
if (rd_dis_now) {
|
||||
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_soc.h"
|
||||
|
||||
static const char *TAG = "boot.esp32h2";
|
||||
|
||||
@ -254,27 +255,15 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline void bootloader_glitch_reset_disable(void)
|
||||
static inline void bootloader_ana_reset_config(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);
|
||||
}
|
||||
//Enable WDT, BOR, and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(true);
|
||||
}
|
||||
|
||||
esp_err_t bootloader_init(void)
|
||||
@ -282,7 +271,7 @@ esp_err_t bootloader_init(void)
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
bootloader_hardware_init();
|
||||
bootloader_glitch_reset_disable();
|
||||
bootloader_ana_reset_config();
|
||||
bootloader_super_wdt_auto_feed();
|
||||
// protect memory region
|
||||
bootloader_init_mem();
|
||||
@ -301,6 +290,11 @@ esp_err_t bootloader_init(void)
|
||||
bootloader_print_banner();
|
||||
// update flash ID
|
||||
bootloader_flash_update_id();
|
||||
// Check and run XMC startup flow
|
||||
if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
|
||||
goto err;
|
||||
}
|
||||
// read bootloader header
|
||||
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
|
||||
goto err;
|
||||
|
41
components/bootloader_support/src/esp32h2/bootloader_soc.c
Normal file
41
components/bootloader_support/src/esp32h2/bootloader_soc.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOR_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_GLITCH_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
}
|
||||
}
|
@ -307,6 +307,11 @@ esp_err_t bootloader_init(void)
|
||||
bootloader_print_banner();
|
||||
// update flash ID
|
||||
bootloader_flash_update_id();
|
||||
// Check and run XMC startup flow
|
||||
if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
|
||||
goto err;
|
||||
}
|
||||
// read bootloader header
|
||||
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
|
||||
goto err;
|
||||
|
21
components/bootloader_support/src/esp32s2/bootloader_soc.c
Normal file
21
components/bootloader_support/src/esp32s2/bootloader_soc.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
@ -41,5 +41,11 @@ esp_err_t esp_flash_encryption_enable_secure_features(void)
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_BOOT_REMAP);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
|
||||
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
|
||||
// otherwise the Flash Encryption key cannot be read protected
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -40,5 +40,20 @@ esp_err_t esp_secure_boot_enable_secure_features(void)
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
bool rd_dis_now = true;
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
/* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
|
||||
when Flash Encryption is being enabled */
|
||||
rd_dis_now = esp_flash_encryption_enabled();
|
||||
#endif
|
||||
if (rd_dis_now) {
|
||||
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "bootloader_mem.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
|
||||
@ -139,7 +140,7 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
|
||||
str = "20MHz";
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Speed : %s", str);
|
||||
ESP_LOGI(TAG, "Boot SPI Speed : %s", str);
|
||||
|
||||
/* SPI mode could have been set to QIO during boot already,
|
||||
so test the SPI registers not the flash header */
|
||||
@ -296,9 +297,18 @@ static void bootloader_super_wdt_auto_feed(void)
|
||||
REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
|
||||
}
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
//Enable WDT, BOR, and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(true);
|
||||
}
|
||||
|
||||
esp_err_t bootloader_init(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
bootloader_ana_reset_config();
|
||||
bootloader_super_wdt_auto_feed();
|
||||
// protect memory region
|
||||
bootloader_init_mem();
|
||||
@ -328,6 +338,11 @@ esp_err_t bootloader_init(void)
|
||||
bootloader_print_banner();
|
||||
// update flash ID
|
||||
bootloader_flash_update_id();
|
||||
// Check and run XMC startup flow
|
||||
if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
|
||||
goto err;
|
||||
}
|
||||
// read bootloader header
|
||||
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
|
||||
goto err;
|
||||
|
41
components/bootloader_support/src/esp32s3/bootloader_soc.c
Normal file
41
components/bootloader_support/src/esp32s3/bootloader_soc.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOR_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_GLITCH_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
}
|
||||
}
|
@ -41,5 +41,11 @@ esp_err_t esp_flash_encryption_enable_secure_features(void)
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
|
||||
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
|
||||
// otherwise the Flash Encryption key cannot be read protected
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ esp_err_t esp_secure_boot_enable_secure_features(void)
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable hardware & software JTAG...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_HARD_DIS_JTAG);
|
||||
esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
|
||||
#else
|
||||
@ -39,5 +40,20 @@ esp_err_t esp_secure_boot_enable_secure_features(void)
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
bool rd_dis_now = true;
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
/* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
|
||||
when Flash Encryption is being enabled */
|
||||
rd_dis_now = esp_flash_encryption_enabled();
|
||||
#endif
|
||||
if (rd_dis_now) {
|
||||
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -105,14 +105,6 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
The command passed here is always the on-the-wire command given to the SPI flash unit.
|
||||
*/
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
uint32_t bootloader_read_flash_id(void)
|
||||
{
|
||||
uint32_t id = bootloader_execute_flash_command(CMD_RDID, 0, 0, 24);
|
||||
id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00);
|
||||
return id;
|
||||
}
|
||||
|
||||
void bootloader_enable_qio_mode(void)
|
||||
{
|
||||
uint32_t raw_flash_id;
|
||||
|
@ -1,6 +1,8 @@
|
||||
if(CONFIG_BT_ENABLED)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
set(srcs "controller/esp32/bt.c")
|
||||
set(srcs "controller/esp32/bt.c"
|
||||
"controller/esp32/hli_api.c"
|
||||
"controller/esp32/hli_vectors.S")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
set(srcs "controller/esp32c3/bt.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
@ -55,6 +57,7 @@ if(CONFIG_BT_ENABLED)
|
||||
host/bluedroid/bta/gatt/include
|
||||
host/bluedroid/bta/hf_ag/include
|
||||
host/bluedroid/bta/hf_client/include
|
||||
host/bluedroid/bta/hd/include
|
||||
host/bluedroid/bta/hh/include
|
||||
host/bluedroid/bta/jv/include
|
||||
host/bluedroid/bta/sdp/include
|
||||
@ -66,12 +69,12 @@ if(CONFIG_BT_ENABLED)
|
||||
host/bluedroid/external/sbc/plc/include
|
||||
host/bluedroid/btc/profile/esp/include
|
||||
host/bluedroid/btc/profile/std/a2dp/include
|
||||
host/bluedroid/btc/profile/std/hid/include
|
||||
host/bluedroid/btc/profile/std/include
|
||||
host/bluedroid/btc/include
|
||||
host/bluedroid/stack/btm/include
|
||||
host/bluedroid/stack/gap/include
|
||||
host/bluedroid/stack/gatt/include
|
||||
host/bluedroid/stack/hid/include
|
||||
host/bluedroid/stack/l2cap/include
|
||||
host/bluedroid/stack/sdp/include
|
||||
host/bluedroid/stack/smp/include
|
||||
@ -94,6 +97,8 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/api/esp_gatt_common_api.c"
|
||||
"host/bluedroid/api/esp_gattc_api.c"
|
||||
"host/bluedroid/api/esp_gatts_api.c"
|
||||
"host/bluedroid/api/esp_hidd_api.c"
|
||||
"host/bluedroid/api/esp_hidh_api.c"
|
||||
"host/bluedroid/api/esp_hf_ag_api.c"
|
||||
"host/bluedroid/api/esp_hf_client_api.c"
|
||||
"host/bluedroid/api/esp_spp_api.c"
|
||||
@ -128,6 +133,9 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/bta/gatt/bta_gatts_co.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_main.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_utils.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_api.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_act.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_main.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_act.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_api.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_cfg.c"
|
||||
@ -184,8 +192,9 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c"
|
||||
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
||||
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
||||
"host/bluedroid/btc/profile/std/hid/hidh_api.c"
|
||||
"host/bluedroid/btc/profile/std/hid/hidh_conn.c"
|
||||
"host/bluedroid/btc/profile/std/hid/btc_hd.c"
|
||||
"host/bluedroid/btc/profile/std/hid/btc_hh.c"
|
||||
"host/bluedroid/btc/profile/std/hid/bta_hh_co.c"
|
||||
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||
"host/bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
||||
"host/bluedroid/btc/profile/std/gap/bta_gap_bt_co.c"
|
||||
@ -251,6 +260,10 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/stack/avrc/avrc_pars_tg.c"
|
||||
"host/bluedroid/stack/avrc/avrc_sdp.c"
|
||||
"host/bluedroid/stack/avrc/avrc_utils.c"
|
||||
"host/bluedroid/stack/hid/hidd_api.c"
|
||||
"host/bluedroid/stack/hid/hidd_conn.c"
|
||||
"host/bluedroid/stack/hid/hidh_api.c"
|
||||
"host/bluedroid/stack/hid/hidh_conn.c"
|
||||
"host/bluedroid/stack/btm/btm_acl.c"
|
||||
"host/bluedroid/stack/btm/btm_ble.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_addr.c"
|
||||
@ -597,6 +610,8 @@ if(CONFIG_BT_ENABLED)
|
||||
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} PUBLIC btdm_app)
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u ld_include_hli_vectors_bt")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE
|
||||
"-L${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32c3")
|
||||
|
@ -7,42 +7,16 @@ menu "Bluetooth"
|
||||
help
|
||||
Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
|
||||
|
||||
config BT_CTRL_ESP32
|
||||
bool
|
||||
depends on BT_ENABLED && IDF_TARGET_ESP32
|
||||
default y
|
||||
|
||||
config BT_CTRL_ESP32C3
|
||||
bool
|
||||
depends on BT_ENABLED && IDF_TARGET_ESP32C3
|
||||
default y
|
||||
config BT_CTRL_ESP32S3
|
||||
bool
|
||||
depends on BT_ENABLED && IDF_TARGET_ESP32S3
|
||||
default y
|
||||
|
||||
config BT_SOC_SUPPORT_5_0
|
||||
bool
|
||||
depends on BT_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
|
||||
default y if BT_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
|
||||
default n
|
||||
|
||||
menu "Bluetooth controller(ESP32 Dual Mode Bluetooth)"
|
||||
visible if BT_CTRL_ESP32
|
||||
menu "Bluetooth controller"
|
||||
depends on BT_ENABLED
|
||||
|
||||
source "$IDF_PATH/components/bt/controller/esp32/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
menu "Bluetooth controller(ESP32C3 Bluetooth Low Energy)"
|
||||
visible if BT_CTRL_ESP32C3
|
||||
|
||||
source "$IDF_PATH/components/bt/controller/esp32c3/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
menu "Bluetooth controller(ESP32S3 Bluetooth Low Energy)"
|
||||
visible if BT_CTRL_ESP32S3
|
||||
|
||||
source "$IDF_PATH/components/bt/controller/esp32s3/Kconfig.in"
|
||||
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
choice BT_HOST
|
||||
@ -73,12 +47,12 @@ menu "Bluetooth"
|
||||
endchoice
|
||||
|
||||
menu "Bluedroid Options"
|
||||
visible if BT_BLUEDROID_ENABLED
|
||||
depends on BT_BLUEDROID_ENABLED
|
||||
|
||||
source "$IDF_PATH/components/bt/host/bluedroid/Kconfig.in"
|
||||
endmenu
|
||||
menu "NimBLE Options"
|
||||
visible if BT_NIMBLE_ENABLED
|
||||
depends on BT_NIMBLE_ENABLED
|
||||
|
||||
source "$IDF_PATH/components/bt/host/nimble/Kconfig.in"
|
||||
endmenu
|
||||
|
@ -53,6 +53,12 @@
|
||||
#if BTC_HF_CLIENT_INCLUDED
|
||||
#include "btc_hf_client.h"
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#if BTC_HD_INCLUDED == TRUE
|
||||
#include "btc_hd.h"
|
||||
#endif /* BTC_HD_INCLUDED */
|
||||
#if BTC_HH_INCLUDED == TRUE
|
||||
#include "btc_hh.h"
|
||||
#endif /* BTC_HH_INCLUDED */
|
||||
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||
#endif
|
||||
|
||||
@ -120,6 +126,12 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
#if BTC_HF_CLIENT_INCLUDED
|
||||
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#if BTC_HD_INCLUDED
|
||||
[BTC_PID_HD] = {btc_hd_call_handler, btc_hd_cb_handler },
|
||||
#endif
|
||||
#if BTC_HH_INCLUDED
|
||||
[BTC_PID_HH] = {btc_hh_call_handler, btc_hh_cb_handler },
|
||||
#endif
|
||||
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH
|
||||
|
@ -65,6 +65,8 @@ typedef enum {
|
||||
BTC_PID_AVRC_CT,
|
||||
BTC_PID_AVRC_TG,
|
||||
BTC_PID_SPP,
|
||||
BTC_PID_HD,
|
||||
BTC_PID_HH,
|
||||
#if (BTC_HF_INCLUDED == TRUE)
|
||||
BTC_PID_HF,
|
||||
#endif /* BTC_HF_INCLUDED */
|
||||
@ -99,6 +101,10 @@ typedef struct {
|
||||
|
||||
typedef void (* btc_arg_deep_copy_t)(btc_msg_t *msg, void *dst, void *src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* transfer an message to another module in the different task.
|
||||
* @param msg message
|
||||
@ -124,4 +130,8 @@ void btc_deinit(void);
|
||||
bool btc_check_queue_is_congest(void);
|
||||
int get_btc_work_queue_size(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BTC_TASK_H__ */
|
||||
|
@ -318,3 +318,14 @@ uint32_t osi_time_get_os_boottime_ms(void)
|
||||
{
|
||||
return (uint32_t)(esp_timer_get_time() / 1000);
|
||||
}
|
||||
|
||||
bool osi_alarm_is_active(osi_alarm_t *alarm)
|
||||
{
|
||||
assert(alarm != NULL);
|
||||
|
||||
if (alarm->alarm_hdl != NULL) {
|
||||
return esp_timer_is_active(alarm->alarm_hdl);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -77,4 +77,8 @@ period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm);
|
||||
|
||||
uint32_t osi_time_get_os_boottime_ms(void);
|
||||
|
||||
// This function returns whether the given |alarm| is active or not.
|
||||
// Return true if active, false otherwise.
|
||||
bool osi_alarm_is_active(osi_alarm_t *alarm);
|
||||
|
||||
#endif /*_ALARM_H_*/
|
||||
|
@ -10,6 +10,7 @@ COMPONENT_ADD_INCLUDEDIRS := include
|
||||
LIBS := btdm_app
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/controller/lib_esp32/esp32 \
|
||||
-u ld_include_hli_vectors_bt \
|
||||
$(addprefix -l,$(LIBS))
|
||||
|
||||
# re-link program if BT binary libs change
|
||||
@ -46,6 +47,7 @@ COMPONENT_PRIV_INCLUDEDIRS += host/bluedroid/bta/include \
|
||||
host/bluedroid/bta/hf_client/include \
|
||||
host/bluedroid/bta/dm/include \
|
||||
host/bluedroid/bta/gatt/include \
|
||||
host/bluedroid/bta/hd/include \
|
||||
host/bluedroid/bta/hh/include \
|
||||
host/bluedroid/bta/jv/include \
|
||||
host/bluedroid/bta/sdp/include \
|
||||
@ -70,6 +72,7 @@ COMPONENT_PRIV_INCLUDEDIRS += host/bluedroid/bta/include \
|
||||
host/bluedroid/stack/gap/include \
|
||||
host/bluedroid/stack/gatt/include \
|
||||
host/bluedroid/stack/hcic/include \
|
||||
host/bluedroid/stack/hid/include \
|
||||
host/bluedroid/stack/l2cap/include \
|
||||
host/bluedroid/stack/sdp/include \
|
||||
host/bluedroid/stack/smp/include \
|
||||
@ -86,6 +89,7 @@ COMPONENT_ADD_INCLUDEDIRS += host/bluedroid/api/include/api \
|
||||
|
||||
COMPONENT_SRCDIRS += host/bluedroid/bta/dm \
|
||||
host/bluedroid/bta/gatt \
|
||||
host/bluedroid/bta/hd \
|
||||
host/bluedroid/bta/hh \
|
||||
host/bluedroid/bta/sdp \
|
||||
host/bluedroid/bta/av \
|
||||
@ -118,6 +122,7 @@ COMPONENT_SRCDIRS += host/bluedroid/bta/dm \
|
||||
host/bluedroid/stack/gap \
|
||||
host/bluedroid/stack/gatt \
|
||||
host/bluedroid/stack/hcic \
|
||||
host/bluedroid/stack/hid \
|
||||
host/bluedroid/stack/include \
|
||||
host/bluedroid/stack/l2cap \
|
||||
host/bluedroid/stack/sdp \
|
||||
|
@ -1,6 +1,5 @@
|
||||
choice BTDM_CTRL_MODE
|
||||
prompt "Bluetooth controller mode (BR/EDR/BLE/DUALMODE)"
|
||||
depends on BT_CTRL_ESP32
|
||||
help
|
||||
Specify the bluetooth controller mode (BR/EDR, BLE or dual mode).
|
||||
|
||||
@ -152,7 +151,7 @@ config BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF
|
||||
|
||||
choice BTDM_CTRL_PINNED_TO_CORE_CHOICE
|
||||
prompt "The cpu core which bluetooth controller run"
|
||||
depends on BT_CTRL_ESP32 && !FREERTOS_UNICORE
|
||||
depends on !FREERTOS_UNICORE
|
||||
help
|
||||
Specify the cpu core to run bluetooth controller.
|
||||
Can not specify no-affinity.
|
||||
@ -172,7 +171,6 @@ config BTDM_CTRL_PINNED_TO_CORE
|
||||
|
||||
choice BTDM_CTRL_HCI_MODE_CHOICE
|
||||
prompt "HCI mode"
|
||||
depends on BT_CTRL_ESP32
|
||||
help
|
||||
Speicify HCI mode as VHCI or UART(H4)
|
||||
|
||||
@ -210,11 +208,8 @@ menu "HCI UART(H4) Options"
|
||||
endmenu
|
||||
|
||||
menu "MODEM SLEEP Options"
|
||||
visible if BT_CTRL_ESP32
|
||||
|
||||
config BTDM_CTRL_MODEM_SLEEP
|
||||
bool "Bluetooth modem sleep"
|
||||
depends on BT_CTRL_ESP32
|
||||
default y
|
||||
help
|
||||
Enable/disable bluetooth controller low power mode.
|
||||
@ -415,3 +410,16 @@ config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
|
||||
config BTDM_RESERVE_DRAM
|
||||
hex
|
||||
default 0xdb5c if BT_ENABLED
|
||||
default 0
|
||||
|
||||
config BTDM_CTRL_HLI
|
||||
bool "High level interrupt"
|
||||
depends on BT_ENABLED
|
||||
default y
|
||||
help
|
||||
Using Level 4 interrupt for Bluetooth.
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "esp_coexist_internal.h"
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
@ -47,6 +48,7 @@
|
||||
#endif
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
#include "hli_api.h"
|
||||
|
||||
#if CONFIG_BT_ENABLED
|
||||
|
||||
@ -54,6 +56,7 @@
|
||||
************************************************************************
|
||||
*/
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
#define BTDM_LOG_TAG "BTDM_INIT"
|
||||
|
||||
#define BTDM_INIT_PERIOD (5000) /* ms */
|
||||
@ -92,12 +95,12 @@ do{\
|
||||
} while(0)
|
||||
|
||||
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
|
||||
#define OSI_VERSION 0x00010002
|
||||
#define OSI_VERSION 0x00010003
|
||||
#define OSI_MAGIC_VALUE 0xFADEBEAD
|
||||
|
||||
/* SPIRAM Configuration */
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
#define BTDM_MAX_QUEUE_NUM (5)
|
||||
#define BTDM_MAX_QUEUE_NUM (6)
|
||||
#endif
|
||||
|
||||
/* Types definition
|
||||
@ -184,6 +187,10 @@ struct osi_funcs_t {
|
||||
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);
|
||||
xt_handler (*_set_isr_l3)(int n, xt_handler f, void *arg);
|
||||
void (*_interrupt_l3_disable)(void);
|
||||
void (*_interrupt_l3_restore)(void);
|
||||
void *(* _customer_queue_create)(uint32_t queue_len, uint32_t item_size);
|
||||
uint32_t _magic;
|
||||
};
|
||||
|
||||
@ -268,8 +275,13 @@ extern uint32_t _btdm_data_end;
|
||||
static bool btdm_queue_generic_register(const btdm_queue_item_t *queue);
|
||||
static bool btdm_queue_generic_deregister(btdm_queue_item_t *queue);
|
||||
#endif /* CONFIG_SPIRAM_USE_MALLOC */
|
||||
static void IRAM_ATTR interrupt_disable(void);
|
||||
static void IRAM_ATTR interrupt_restore(void);
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
static xt_handler set_isr_hlevel_wrapper(int n, xt_handler f, void *arg);
|
||||
static void IRAM_ATTR interrupt_hlevel_disable(void);
|
||||
static void IRAM_ATTR interrupt_hlevel_restore(void);
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
static void IRAM_ATTR task_yield(void);
|
||||
static void IRAM_ATTR task_yield_from_isr(void);
|
||||
static void *semphr_create_wrapper(uint32_t max, uint32_t init);
|
||||
static void semphr_delete_wrapper(void *semphr);
|
||||
@ -281,12 +293,21 @@ static void *mutex_create_wrapper(void);
|
||||
static void mutex_delete_wrapper(void *mutex);
|
||||
static int32_t mutex_lock_wrapper(void *mutex);
|
||||
static int32_t mutex_unlock_wrapper(void *mutex);
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
static void *queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size);
|
||||
static void queue_delete_hlevel_wrapper(void *queue);
|
||||
static int32_t IRAM_ATTR queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms);
|
||||
static int32_t IRAM_ATTR queue_send_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw);
|
||||
static int32_t IRAM_ATTR queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms);
|
||||
static int32_t IRAM_ATTR queue_recv_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw);
|
||||
#else
|
||||
static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size);
|
||||
static void queue_delete_wrapper(void *queue);
|
||||
static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms);
|
||||
static int32_t IRAM_ATTR queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms);
|
||||
static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw);
|
||||
static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms);
|
||||
static int32_t IRAM_ATTR queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms);
|
||||
static int32_t IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw);
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
static int32_t task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id);
|
||||
static void task_delete_wrapper(void *task_handle);
|
||||
static bool IRAM_ATTR is_in_isr_wrapper(void);
|
||||
@ -317,17 +338,30 @@ 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);
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size);
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
static void IRAM_ATTR interrupt_l3_disable(void);
|
||||
static void IRAM_ATTR interrupt_l3_restore(void);
|
||||
|
||||
/* Local variable definition
|
||||
***************************************************************************
|
||||
*/
|
||||
/* OSI funcs */
|
||||
static const struct osi_funcs_t osi_funcs_ro = {
|
||||
._version = OSI_VERSION,
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
._set_isr = set_isr_hlevel_wrapper,
|
||||
._ints_on = xt_ints_on,
|
||||
._interrupt_disable = interrupt_hlevel_disable,
|
||||
._interrupt_restore = interrupt_hlevel_restore,
|
||||
#else
|
||||
._set_isr = xt_set_interrupt_handler,
|
||||
._ints_on = xt_ints_on,
|
||||
._interrupt_disable = interrupt_disable,
|
||||
._interrupt_restore = interrupt_restore,
|
||||
._task_yield = vPortYield,
|
||||
._interrupt_disable = interrupt_l3_disable,
|
||||
._interrupt_restore = interrupt_l3_restore,
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
._task_yield = task_yield,
|
||||
._task_yield_from_isr = task_yield_from_isr,
|
||||
._semphr_create = semphr_create_wrapper,
|
||||
._semphr_delete = semphr_delete_wrapper,
|
||||
@ -339,12 +373,21 @@ static const struct osi_funcs_t osi_funcs_ro = {
|
||||
._mutex_delete = mutex_delete_wrapper,
|
||||
._mutex_lock = mutex_lock_wrapper,
|
||||
._mutex_unlock = mutex_unlock_wrapper,
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
._queue_create = queue_create_hlevel_wrapper,
|
||||
._queue_delete = queue_delete_hlevel_wrapper,
|
||||
._queue_send = queue_send_hlevel_wrapper,
|
||||
._queue_send_from_isr = queue_send_from_isr_hlevel_wrapper,
|
||||
._queue_recv = queue_recv_hlevel_wrapper,
|
||||
._queue_recv_from_isr = queue_recv_from_isr_hlevel_wrapper,
|
||||
#else
|
||||
._queue_create = queue_create_wrapper,
|
||||
._queue_delete = queue_delete_wrapper,
|
||||
._queue_send = queue_send_wrapper,
|
||||
._queue_send_from_isr = queue_send_from_isr_wrapper,
|
||||
._queue_recv = queue_recv_wrapper,
|
||||
._queue_recv_from_isr = queue_recv_from_isr_wrapper,
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
._task_create = task_create_wrapper,
|
||||
._task_delete = task_delete_wrapper,
|
||||
._is_in_isr = is_in_isr_wrapper,
|
||||
@ -378,6 +421,14 @@ static const struct osi_funcs_t osi_funcs_ro = {
|
||||
._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,
|
||||
._set_isr_l3 = xt_set_interrupt_handler,
|
||||
._interrupt_l3_disable = interrupt_l3_disable,
|
||||
._interrupt_l3_restore = interrupt_l3_restore,
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
._customer_queue_create = customer_queue_create_hlevel_wrapper,
|
||||
#else
|
||||
._customer_queue_create = NULL,
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
._magic = OSI_MAGIC_VALUE,
|
||||
};
|
||||
|
||||
@ -494,7 +545,48 @@ static bool btdm_queue_generic_deregister(btdm_queue_item_t *queue)
|
||||
|
||||
#endif /* CONFIG_SPIRAM_USE_MALLOC */
|
||||
|
||||
static void IRAM_ATTR interrupt_disable(void)
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
struct interrupt_hlevel_cb{
|
||||
uint32_t status;
|
||||
uint8_t nested;
|
||||
};
|
||||
|
||||
static DRAM_ATTR struct interrupt_hlevel_cb hli_cb = {
|
||||
.status = 0,
|
||||
.nested = 0,
|
||||
};
|
||||
|
||||
static xt_handler set_isr_hlevel_wrapper(int mask, xt_handler f, void *arg)
|
||||
{
|
||||
esp_err_t err = hli_intr_register((intr_handler_t) f, arg, DPORT_PRO_INTR_STATUS_0_REG, mask);
|
||||
if (err == ESP_OK) {
|
||||
return f;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR interrupt_hlevel_disable(void)
|
||||
{
|
||||
assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
|
||||
assert(hli_cb.nested != ~0);
|
||||
uint32_t status = hli_intr_disable();
|
||||
if (hli_cb.nested++ == 0) {
|
||||
hli_cb.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR interrupt_hlevel_restore(void)
|
||||
{
|
||||
assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
|
||||
assert(hli_cb.nested > 0);
|
||||
if (--hli_cb.nested == 0) {
|
||||
hli_intr_restore(hli_cb.status);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
static void IRAM_ATTR interrupt_l3_disable(void)
|
||||
{
|
||||
if (xPortInIsrContext()) {
|
||||
portENTER_CRITICAL_ISR(&global_int_mux);
|
||||
@ -503,7 +595,7 @@ static void IRAM_ATTR interrupt_disable(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR interrupt_restore(void)
|
||||
static void IRAM_ATTR interrupt_l3_restore(void)
|
||||
{
|
||||
if (xPortInIsrContext()) {
|
||||
portEXIT_CRITICAL_ISR(&global_int_mux);
|
||||
@ -512,6 +604,12 @@ static void IRAM_ATTR interrupt_restore(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR task_yield(void)
|
||||
{
|
||||
vPortYield();
|
||||
}
|
||||
|
||||
|
||||
static void IRAM_ATTR task_yield_from_isr(void)
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
@ -519,18 +617,19 @@ static void IRAM_ATTR task_yield_from_isr(void)
|
||||
|
||||
static void *semphr_create_wrapper(uint32_t max, uint32_t init)
|
||||
{
|
||||
void *handle = NULL;
|
||||
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
return (void *)xSemaphoreCreateCounting(max, init);
|
||||
handle = (void *)xSemaphoreCreateCounting(max, init);
|
||||
#else
|
||||
StaticQueue_t *queue_buffer = NULL;
|
||||
QueueHandle_t handle = NULL;
|
||||
|
||||
queue_buffer = heap_caps_malloc(sizeof(StaticQueue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!queue_buffer) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
handle = xSemaphoreCreateCountingStatic(max, init, queue_buffer);
|
||||
handle = (void *)xSemaphoreCreateCountingStatic(max, init, queue_buffer);
|
||||
if (!handle) {
|
||||
goto error;
|
||||
}
|
||||
@ -544,8 +643,19 @@ static void *semphr_create_wrapper(uint32_t max, uint32_t init)
|
||||
if (!btdm_queue_generic_register(&item)) {
|
||||
goto error;
|
||||
}
|
||||
return handle;
|
||||
#endif
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
SemaphoreHandle_t downstream_semaphore = handle;
|
||||
assert(downstream_semaphore);
|
||||
hli_queue_handle_t s_semaphore = hli_semaphore_create(max, downstream_semaphore);
|
||||
assert(downstream_semaphore);
|
||||
return s_semaphore;
|
||||
#else
|
||||
return handle;
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
error:
|
||||
if (handle) {
|
||||
vSemaphoreDelete(handle);
|
||||
@ -560,11 +670,22 @@ static void *semphr_create_wrapper(uint32_t max, uint32_t init)
|
||||
|
||||
static void semphr_delete_wrapper(void *semphr)
|
||||
{
|
||||
void *handle = NULL;
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
if (((hli_queue_handle_t)semphr)->downstream != NULL) {
|
||||
handle = ((hli_queue_handle_t)semphr)->downstream;
|
||||
}
|
||||
|
||||
hli_queue_delete(semphr);
|
||||
#else
|
||||
handle = semphr;
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
vSemaphoreDelete(semphr);
|
||||
vSemaphoreDelete(handle);
|
||||
#else
|
||||
btdm_queue_item_t item = {
|
||||
.handle = semphr,
|
||||
.handle = handle,
|
||||
.storage = NULL,
|
||||
.buffer = NULL,
|
||||
};
|
||||
@ -573,33 +694,55 @@ static void semphr_delete_wrapper(void *semphr)
|
||||
vSemaphoreDelete(item.handle);
|
||||
free(item.buffer);
|
||||
}
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
|
||||
{
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
return (int32_t)xSemaphoreTakeFromISR(((hli_queue_handle_t)semphr)->downstream, hptw);
|
||||
#else
|
||||
return (int32_t)xSemaphoreTakeFromISR(semphr, hptw);
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
|
||||
{
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
UNUSED(hptw);
|
||||
assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
|
||||
return hli_semaphore_give(semphr);
|
||||
#else
|
||||
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
}
|
||||
|
||||
static int32_t semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
|
||||
{
|
||||
bool ret;
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
||||
return (int32_t)xSemaphoreTake(semphr, portMAX_DELAY);
|
||||
ret = xSemaphoreTake(((hli_queue_handle_t)semphr)->downstream, portMAX_DELAY);
|
||||
} else {
|
||||
return (int32_t)xSemaphoreTake(semphr, block_time_ms / portTICK_PERIOD_MS);
|
||||
ret = xSemaphoreTake(((hli_queue_handle_t)semphr)->downstream, block_time_ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
#else
|
||||
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
||||
ret = xSemaphoreTake(semphr, portMAX_DELAY);
|
||||
} else {
|
||||
ret = xSemaphoreTake(semphr, block_time_ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
return (int32_t)ret;
|
||||
}
|
||||
|
||||
static int32_t semphr_give_wrapper(void *semphr)
|
||||
{
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
return (int32_t)xSemaphoreGive(((hli_queue_handle_t)semphr)->downstream);
|
||||
#else
|
||||
return (int32_t)xSemaphoreGive(semphr);
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
}
|
||||
|
||||
static void *mutex_create_wrapper(void)
|
||||
@ -745,6 +888,79 @@ static void queue_delete_wrapper(void *queue)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
static void *queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size)
|
||||
{
|
||||
QueueHandle_t downstream_queue = queue_create_wrapper(queue_len, item_size);
|
||||
assert(downstream_queue);
|
||||
hli_queue_handle_t queue = hli_queue_create(queue_len, item_size, downstream_queue);
|
||||
assert(queue);
|
||||
return queue;
|
||||
}
|
||||
|
||||
static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size)
|
||||
{
|
||||
QueueHandle_t downstream_queue = queue_create_wrapper(queue_len, item_size);
|
||||
assert(downstream_queue);
|
||||
hli_queue_handle_t queue = hli_customer_queue_create(queue_len, item_size, downstream_queue);
|
||||
assert(queue);
|
||||
return queue;
|
||||
}
|
||||
|
||||
static void queue_delete_hlevel_wrapper(void *queue)
|
||||
{
|
||||
if (((hli_queue_handle_t)queue)->downstream != NULL) {
|
||||
queue_delete_wrapper(((hli_queue_handle_t)queue)->downstream);
|
||||
}
|
||||
hli_queue_delete(queue);
|
||||
}
|
||||
|
||||
static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms)
|
||||
{
|
||||
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
||||
return (int32_t)xQueueSend(((hli_queue_handle_t)queue)->downstream, item, portMAX_DELAY);
|
||||
} else {
|
||||
return (int32_t)xQueueSend(((hli_queue_handle_t)queue)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue send from isr
|
||||
* @param queue The queue which will send to
|
||||
* @param item The message which will be send
|
||||
* @param hptw need do task yield or not
|
||||
* @return send success or not
|
||||
* There is an issue here: When the queue is full, it may reture true but it send fail to the queue, sometimes.
|
||||
* But in Bluetooth controller's isr, We don't care about the return value.
|
||||
* It only required tp send success when the queue is empty all the time.
|
||||
* So, this function meets the requirement.
|
||||
*/
|
||||
static int32_t IRAM_ATTR queue_send_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw)
|
||||
{
|
||||
UNUSED(hptw);
|
||||
assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
|
||||
return hli_queue_put(queue, item);
|
||||
}
|
||||
|
||||
static int32_t queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms)
|
||||
{
|
||||
bool ret;
|
||||
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
||||
ret = xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, portMAX_DELAY);
|
||||
} else {
|
||||
ret = xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
return (int32_t)ret;
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR queue_recv_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw)
|
||||
{
|
||||
return (int32_t)xQueueReceiveFromISR(((hli_queue_handle_t)queue)->downstream, item, hptw);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms)
|
||||
{
|
||||
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
||||
@ -760,18 +976,23 @@ static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, vo
|
||||
}
|
||||
|
||||
static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms)
|
||||
{
|
||||
{
|
||||
bool ret;
|
||||
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
||||
return (int32_t)xQueueReceive(queue, item, portMAX_DELAY);
|
||||
ret = xQueueReceive(queue, item, portMAX_DELAY);
|
||||
} else {
|
||||
return (int32_t)xQueueReceive(queue, item, block_time_ms / portTICK_PERIOD_MS);
|
||||
ret = xQueueReceive(queue, item, block_time_ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
return (int32_t)ret;
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw)
|
||||
{
|
||||
return (int32_t)xQueueReceiveFromISR(queue, item, hptw);
|
||||
}
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
|
||||
static int32_t task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id)
|
||||
{
|
||||
@ -1317,11 +1538,35 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
static void hli_queue_setup_cb(void* arg)
|
||||
{
|
||||
hli_queue_setup();
|
||||
}
|
||||
|
||||
static void hli_queue_setup_pinned_to_core(int core_id)
|
||||
{
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
hli_queue_setup_cb(NULL);
|
||||
#else /* CONFIG_FREERTOS_UNICORE */
|
||||
if (xPortGetCoreID() == core_id) {
|
||||
hli_queue_setup_cb(NULL);
|
||||
} else {
|
||||
esp_ipc_call(core_id, hli_queue_setup_cb, NULL);
|
||||
}
|
||||
#endif /* !CONFIG_FREERTOS_UNICORE */
|
||||
}
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t btdm_cfg_mask = 0;
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
hli_queue_setup_pinned_to_core(CONFIG_BTDM_CTRL_PINNED_TO_CORE);
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
//if all the bt available memory was already released, cannot initialize bluetooth controller
|
||||
if (btdm_dram_available_region[0].mode == ESP_BT_MODE_IDLE) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
@ -1394,7 +1639,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
#if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_32K_XTAL) {
|
||||
btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // set default value
|
||||
btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32kHz XTAL
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
s_btdm_allow_light_sleep = true;
|
||||
#endif
|
||||
@ -1736,4 +1981,15 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function re-write controller's function,
|
||||
* As coredump can not show paramerters in function which is in a .a file.
|
||||
*
|
||||
* After coredump fixing this issue, just delete this function.
|
||||
*/
|
||||
void IRAM_ATTR r_assert(const char *condition, int param0, int param1, const char *file, int line)
|
||||
{
|
||||
__asm__ __volatile__("ill\n");
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
306
components/bt/controller/esp32/hli_api.c
Normal file
306
components/bt/controller/esp32/hli_api.c
Normal file
@ -0,0 +1,306 @@
|
||||
// Copyright 2015-2021 Espressif Systems (Shanghai) CO 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 "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "xtensa/core-macros.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "hli_api.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
#define HLI_MAX_HANDLERS 4
|
||||
|
||||
typedef struct {
|
||||
intr_handler_t handler;
|
||||
void* arg;
|
||||
uint32_t intr_reg;
|
||||
uint32_t intr_mask;
|
||||
} hli_handler_info_t;
|
||||
|
||||
typedef struct {
|
||||
#define CUSTOMER_TYPE_REQUEST (0)
|
||||
#define CUSTOMER_TYPE_RELEASE (1)
|
||||
struct {
|
||||
uint32_t cb_type;
|
||||
union {
|
||||
int (* request)(uint32_t, uint32_t, uint32_t);
|
||||
int (* release)(uint32_t);
|
||||
} cb;
|
||||
} customer_cb;
|
||||
uint32_t arg0, arg1, arg2;
|
||||
} customer_swisr_t;
|
||||
|
||||
static void IRAM_ATTR customer_swisr_handle(customer_swisr_t *cus_swisr)
|
||||
{
|
||||
if (cus_swisr->customer_cb.cb_type == CUSTOMER_TYPE_REQUEST) {
|
||||
if (cus_swisr->customer_cb.cb.request != NULL) {
|
||||
cus_swisr->customer_cb.cb.request(cus_swisr->arg0, cus_swisr->arg1, cus_swisr->arg2);
|
||||
}
|
||||
} else if(cus_swisr->customer_cb.cb_type == CUSTOMER_TYPE_RELEASE) {
|
||||
if (cus_swisr->customer_cb.cb.release != NULL) {
|
||||
cus_swisr->customer_cb.cb.release(cus_swisr->arg0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DRAM_ATTR hli_handler_info_t s_hli_handlers[HLI_MAX_HANDLERS];
|
||||
|
||||
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask)
|
||||
{
|
||||
for (hli_handler_info_t* hip = s_hli_handlers;
|
||||
hip < s_hli_handlers + HLI_MAX_HANDLERS;
|
||||
++hip) {
|
||||
if (hip->handler == NULL) {
|
||||
hip->arg = arg;
|
||||
hip->intr_reg = intr_reg;
|
||||
hip->intr_mask = intr_mask;
|
||||
hip->handler = handler; /* set last, indicates the entry as valid */
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
void IRAM_ATTR hli_c_handler(void)
|
||||
{
|
||||
bool handled = false;
|
||||
/* Iterate over registered interrupt handlers,
|
||||
* and check if the expected mask is present in the interrupt status register.
|
||||
*/
|
||||
for (hli_handler_info_t* hip = s_hli_handlers;
|
||||
hip < s_hli_handlers + HLI_MAX_HANDLERS;
|
||||
++hip) {
|
||||
if (hip->handler == NULL) {
|
||||
continue;
|
||||
}
|
||||
uint32_t reg = hip->intr_reg;
|
||||
uint32_t val;
|
||||
if (reg == 0) { /* special case for CPU internal interrupts */
|
||||
val = XTHAL_GET_INTERRUPT();
|
||||
} else {
|
||||
/* "reg" might not be in DPORT, but this will work in any case */
|
||||
val = DPORT_REG_READ(reg);
|
||||
}
|
||||
if ((val & hip->intr_mask) != 0) {
|
||||
handled = true;
|
||||
(*hip->handler)(hip->arg);
|
||||
}
|
||||
}
|
||||
if (!handled) {
|
||||
/* no handler found, it is OK in this case. */
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR hli_intr_disable(void)
|
||||
{
|
||||
/* disable level 4 and below */
|
||||
return XTOS_SET_INTLEVEL(XCHAL_DEBUGLEVEL - 2);
|
||||
}
|
||||
|
||||
void IRAM_ATTR hli_intr_restore(uint32_t state)
|
||||
{
|
||||
XTOS_RESTORE_JUST_INTLEVEL(state);
|
||||
}
|
||||
|
||||
#define HLI_META_QUEUE_SIZE 16
|
||||
#define HLI_QUEUE_MAX_ELEM_SIZE 32
|
||||
#define HLI_QUEUE_SW_INT_NUM 29
|
||||
|
||||
#define HLI_QUEUE_FLAG_SEMAPHORE BIT(0)
|
||||
#define HLI_QUEUE_FLAG_CUSTOMER BIT(1)
|
||||
|
||||
static DRAM_ATTR struct hli_queue_t *s_meta_queue_ptr = NULL;
|
||||
static intr_handle_t ret_handle;
|
||||
|
||||
static inline char* IRAM_ATTR wrap_ptr(hli_queue_handle_t queue, char *ptr)
|
||||
{
|
||||
return (ptr == queue->bufend) ? queue->buf : ptr;
|
||||
}
|
||||
|
||||
static inline bool IRAM_ATTR queue_empty(hli_queue_handle_t queue)
|
||||
{
|
||||
return queue->begin == queue->end;
|
||||
}
|
||||
|
||||
static inline bool IRAM_ATTR queue_full(hli_queue_handle_t queue)
|
||||
{
|
||||
return wrap_ptr(queue, queue->end + queue->elem_size) == queue->begin;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR queue_isr_handler(void* arg)
|
||||
{
|
||||
int do_yield = pdFALSE;
|
||||
XTHAL_SET_INTCLEAR(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
hli_queue_handle_t queue;
|
||||
|
||||
while (hli_queue_get(s_meta_queue_ptr, &queue)) {
|
||||
static DRAM_ATTR char scratch[HLI_QUEUE_MAX_ELEM_SIZE];
|
||||
while (hli_queue_get(queue, scratch)) {
|
||||
int res = pdPASS;
|
||||
if ((queue->flags & HLI_QUEUE_FLAG_CUSTOMER) != 0) {
|
||||
customer_swisr_handle((customer_swisr_t *)scratch);
|
||||
} else if ((queue->flags & HLI_QUEUE_FLAG_SEMAPHORE) != 0) {
|
||||
res = xSemaphoreGiveFromISR((SemaphoreHandle_t) queue->downstream, &do_yield);
|
||||
} else {
|
||||
res = xQueueSendFromISR(queue->downstream, scratch, &do_yield);
|
||||
}
|
||||
if (res == pdFAIL) {
|
||||
/* Failed to send to downstream queue, it is OK in this case. */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (do_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify the level 3 handler that an element is added to the given hli queue.
|
||||
* Do this by placing the queue handle onto s_meta_queue, and raising a SW interrupt.
|
||||
*
|
||||
* This function must be called with HL interrupts disabled!
|
||||
*/
|
||||
static void IRAM_ATTR queue_signal(hli_queue_handle_t queue)
|
||||
{
|
||||
/* See if the queue is already in s_meta_queue, before adding */
|
||||
bool found = false;
|
||||
const hli_queue_handle_t *end = (hli_queue_handle_t*) s_meta_queue_ptr->end;
|
||||
hli_queue_handle_t *item = (hli_queue_handle_t*) s_meta_queue_ptr->begin;
|
||||
for (;item != end; item = (hli_queue_handle_t*) wrap_ptr(s_meta_queue_ptr, (char*) (item + 1))) {
|
||||
if (*item == queue) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
bool res = hli_queue_put(s_meta_queue_ptr, &queue);
|
||||
if (!res) {
|
||||
esp_rom_printf(DRAM_STR("Fatal error in queue_signal: s_meta_queue full\n"));
|
||||
abort();
|
||||
}
|
||||
XTHAL_SET_INTSET(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
}
|
||||
}
|
||||
|
||||
static void queue_init(hli_queue_handle_t queue, size_t buf_size, size_t elem_size, QueueHandle_t downstream)
|
||||
{
|
||||
queue->elem_size = elem_size;
|
||||
queue->begin = queue->buf;
|
||||
queue->end = queue->buf;
|
||||
queue->bufend = queue->buf + buf_size;
|
||||
queue->downstream = downstream;
|
||||
queue->flags = 0;
|
||||
}
|
||||
|
||||
void hli_queue_setup(void)
|
||||
{
|
||||
if (s_meta_queue_ptr == NULL) {
|
||||
s_meta_queue_ptr = hli_queue_create(HLI_META_QUEUE_SIZE, sizeof(void*), NULL);
|
||||
ESP_ERROR_CHECK(esp_intr_alloc(ETS_INTERNAL_SW1_INTR_SOURCE, ESP_INTR_FLAG_IRAM, queue_isr_handler, NULL, &ret_handle));
|
||||
xt_ints_on(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
}
|
||||
}
|
||||
|
||||
void hli_queue_shutdown(void)
|
||||
{
|
||||
if (s_meta_queue_ptr != NULL) {
|
||||
hli_queue_delete(s_meta_queue_ptr);
|
||||
s_meta_queue_ptr = NULL;
|
||||
esp_intr_free(ret_handle);
|
||||
xt_ints_off(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
}
|
||||
}
|
||||
|
||||
hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream)
|
||||
{
|
||||
const size_t buf_elem = nelem + 1;
|
||||
if (elem_size > HLI_QUEUE_MAX_ELEM_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
size_t buf_size = buf_elem * elem_size;
|
||||
hli_queue_handle_t res = (hli_queue_handle_t) heap_caps_malloc(sizeof(struct hli_queue_t) + buf_size,
|
||||
MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
queue_init(res, buf_size, elem_size, downstream);
|
||||
return res;
|
||||
}
|
||||
|
||||
hli_queue_handle_t hli_customer_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream)
|
||||
{
|
||||
hli_queue_handle_t res = hli_queue_create(nelem, elem_size, (QueueHandle_t) downstream);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
res->flags |= HLI_QUEUE_FLAG_CUSTOMER;
|
||||
return res;
|
||||
}
|
||||
|
||||
hli_queue_handle_t hli_semaphore_create(size_t max_count, SemaphoreHandle_t downstream)
|
||||
{
|
||||
const size_t elem_size = 1;
|
||||
hli_queue_handle_t res = hli_queue_create(max_count, elem_size, (QueueHandle_t) downstream);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
res->flags |= HLI_QUEUE_FLAG_SEMAPHORE;
|
||||
return res;
|
||||
}
|
||||
|
||||
void hli_queue_delete(hli_queue_handle_t queue)
|
||||
{
|
||||
free(queue);
|
||||
}
|
||||
|
||||
bool IRAM_ATTR hli_queue_get(hli_queue_handle_t queue, void* out)
|
||||
{
|
||||
uint32_t int_state = hli_intr_disable();
|
||||
bool res = false;
|
||||
if (!queue_empty(queue)) {
|
||||
memcpy(out, queue->begin, queue->elem_size);
|
||||
queue->begin = wrap_ptr(queue, queue->begin + queue->elem_size);
|
||||
res = true;
|
||||
}
|
||||
hli_intr_restore(int_state);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IRAM_ATTR hli_queue_put(hli_queue_handle_t queue, const void* data)
|
||||
{
|
||||
uint32_t int_state = hli_intr_disable();
|
||||
bool res = false;
|
||||
bool was_empty = queue_empty(queue);
|
||||
if (!queue_full(queue)) {
|
||||
memcpy(queue->end, data, queue->elem_size);
|
||||
queue->end = wrap_ptr(queue, queue->end + queue->elem_size);
|
||||
if (was_empty && queue != s_meta_queue_ptr) {
|
||||
queue_signal(queue);
|
||||
}
|
||||
res = true;
|
||||
}
|
||||
hli_intr_restore(int_state);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IRAM_ATTR hli_semaphore_give(hli_queue_handle_t queue)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
return hli_queue_put(queue, &data);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
176
components/bt/controller/esp32/hli_api.h
Normal file
176
components/bt/controller/esp32/hli_api.h
Normal file
@ -0,0 +1,176 @@
|
||||
// Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
|
||||
/*** Queues ***/
|
||||
|
||||
struct hli_queue_t
|
||||
{
|
||||
size_t elem_size;
|
||||
char* begin;
|
||||
char* end;
|
||||
const char* bufend;
|
||||
QueueHandle_t downstream;
|
||||
int flags;
|
||||
char buf[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Register a high level interrupt function
|
||||
*
|
||||
* @param handler interrupt handler function
|
||||
* @param arg argument to pass to the interrupt handler
|
||||
* @param intr_reg address of the peripheral register containing the interrupt status,
|
||||
* or value 0 to get the status from CPU INTERRUPT register
|
||||
* @param intr_mask mask of the interrupt, in the interrupt status register
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if too many handlers are registered
|
||||
*/
|
||||
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask);
|
||||
|
||||
/**
|
||||
* @brief Mask all interrupts (including high level ones) on the current CPU
|
||||
*
|
||||
* @return uint32_t interrupt status, pass it to hli_intr_restore
|
||||
*/
|
||||
uint32_t hli_intr_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Re-enable interrupts
|
||||
*
|
||||
* @param state value returned by hli_intr_disable
|
||||
*/
|
||||
void hli_intr_restore(uint32_t state);
|
||||
|
||||
/**
|
||||
* @brief Type of a hli queue
|
||||
*/
|
||||
typedef struct hli_queue_t* hli_queue_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize hli_queue module. Must be called once before using hli queue APIs.
|
||||
*/
|
||||
void hli_queue_setup(void);
|
||||
|
||||
/**
|
||||
* @brief Shutdown hli_queue module.
|
||||
*/
|
||||
void hli_queue_shutdown(void);
|
||||
|
||||
/**
|
||||
* @brief Create a hli queue, wrapping a FreeRTOS queue
|
||||
*
|
||||
* This queue can be used from high level interrupts,
|
||||
* but **ONLY ON THE CPU WHERE hli_queue_setup WAS CALLED**. Values sent to this
|
||||
* queue are automatically forwarded to "downstream" FreeRTOS queue using a level 3
|
||||
* software interrupt.
|
||||
*
|
||||
* @param nelem number of elements in the queue
|
||||
* @param elem_size size of one element; must match element size of a downstream queue
|
||||
* @param downstream FreeRTOS queue to send the values to
|
||||
* @return hli_queue_handle_t handle of the created queue, or NULL on failure
|
||||
*/
|
||||
hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream);
|
||||
|
||||
/**
|
||||
* @brief Create a customer hli queue, wrapping a FreeRTOS queue
|
||||
*
|
||||
* This queue can be used from high level interrupts,
|
||||
* but **ONLY ON THE CPU WHERE hli_queue_setup WAS CALLED**. Values sent to this
|
||||
* queue are automatically forwarded to "downstream" FreeRTOS queue using a level 3
|
||||
* software interrupt.
|
||||
*
|
||||
* @param nelem number of elements in the queue
|
||||
* @param elem_size size of one element; must match element size of a downstream queue
|
||||
* @param downstream FreeRTOS queue to send the values to
|
||||
* @return hli_queue_handle_t handle of the created queue, or NULL on failure
|
||||
*/
|
||||
hli_queue_handle_t hli_customer_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream);
|
||||
|
||||
/**
|
||||
* @brief Create a hli queue, wrapping a FreeRTOS semaphore
|
||||
*
|
||||
* See notes on hli_queue_create.
|
||||
*
|
||||
* @param max_count maximum semaphore count
|
||||
* @param downstream FreeRTOS semaphore to forward the calls to
|
||||
* @return hli_queue_handle_t handle of the created queue, or NULL on failure
|
||||
*/
|
||||
hli_queue_handle_t hli_semaphore_create(size_t max_count, SemaphoreHandle_t downstream);
|
||||
|
||||
/**
|
||||
* @brief Delete a hli queue
|
||||
*
|
||||
* Make sure noone is using the queue before deleting it.
|
||||
*
|
||||
* @param queue handle returned by hli_queue_create or hli_semaphore_create
|
||||
*/
|
||||
void hli_queue_delete(hli_queue_handle_t queue);
|
||||
|
||||
/**
|
||||
* @brief Get one element from a hli queue
|
||||
*
|
||||
* Usually not used, values get sent to a downstream FreeRTOS queue automatically.
|
||||
* However if downstream queue is NULL, this API can be used to get values from a hli queue.
|
||||
*
|
||||
* @param queue handle of a queue
|
||||
* @param out pointer where to store the element
|
||||
* @return true if the element was successfully read from the queue
|
||||
*/
|
||||
bool hli_queue_get(hli_queue_handle_t queue, void* out);
|
||||
|
||||
/**
|
||||
* @brief Put one element into a hli queue
|
||||
*
|
||||
* This puts copies an element into the queue and raises a software interrupt (level 3).
|
||||
* In the interrupt, the value is copied to a FreeRTOS "downstream" queue.
|
||||
*
|
||||
* Note that if the value does not fit into a downstream queue, no error is returned,
|
||||
* and the value is lost.
|
||||
*
|
||||
* @param queue handle of a queue
|
||||
* @param data pointer to the element to be sent
|
||||
* @return true if data was placed into the hli queue successfully
|
||||
*/
|
||||
bool hli_queue_put(hli_queue_handle_t queue, const void* data);
|
||||
|
||||
/**
|
||||
* @brief "Give" a semaphore wrapped by a hli queue
|
||||
*
|
||||
* @param queue handle returned by hli_semaphore_create
|
||||
* @return true if the event was sent to a hli queue successfully
|
||||
*/
|
||||
bool hli_semaphore_give(hli_queue_handle_t queue);
|
||||
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
275
components/bt/controller/esp32/hli_vectors.S
Normal file
275
components/bt/controller/esp32/hli_vectors.S
Normal file
@ -0,0 +1,275 @@
|
||||
// Copyright 2015-2021 Espressif Systems (Shanghai) CO 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 <xtensa/coreasm.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
#include "freertos/xtensa_context.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
|
||||
/* Interrupt stack size, for C code.
|
||||
* TODO: reduce and make configurable.
|
||||
*/
|
||||
#define L4_INTR_STACK_SIZE 4096
|
||||
|
||||
/* Save area for the CPU state:
|
||||
* - 64 words for the general purpose registers
|
||||
* - 7 words for some of the special registers:
|
||||
* - WINDOWBASE, WINDOWSTART — only WINDOWSTART is truly needed
|
||||
* - SAR, LBEG, LEND, LCOUNT — since the C code might use these
|
||||
* - EPC1 — since the C code might cause window overflow exceptions
|
||||
* This is not laid out as standard exception frame structure
|
||||
* for simplicity of the save/restore code.
|
||||
*/
|
||||
#define REG_FILE_SIZE (64 * 4)
|
||||
#define SPECREG_OFFSET REG_FILE_SIZE
|
||||
#define SPECREG_SIZE (7 * 4)
|
||||
#define REG_SAVE_AREA_SIZE (SPECREG_OFFSET + SPECREG_SIZE)
|
||||
|
||||
.data
|
||||
_l4_intr_stack:
|
||||
.space L4_INTR_STACK_SIZE
|
||||
_l4_save_ctx:
|
||||
.space REG_SAVE_AREA_SIZE
|
||||
|
||||
.section .iram1,"ax"
|
||||
.global xt_highint4
|
||||
.type xt_highint4,@function
|
||||
.align 4
|
||||
|
||||
xt_highint4:
|
||||
|
||||
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
|
||||
/*
|
||||
Here, Timer2 is used to count a little time(50us).
|
||||
The subsequent dram0 write operation is blocked due to live lock, which will
|
||||
cause timer2 to timeout and trigger a level 5 interrupt.
|
||||
*/
|
||||
rsr.ccount a0
|
||||
addmi a0, a0, (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ*50)
|
||||
wsr a0, CCOMPARE2
|
||||
|
||||
/* Enable Timer 2 interrupt */
|
||||
rsr a0, INTENABLE
|
||||
extui a0, a0, 16, 1
|
||||
bnez a0, 1f
|
||||
movi a0, 0
|
||||
xsr a0, INTENABLE /* disable all interrupts */
|
||||
/* And a0 with (1 << 16) for Timer 2 interrupt mask */
|
||||
addmi a0, a0, (1<<14)
|
||||
addmi a0, a0, (1<<14)
|
||||
addmi a0, a0, (1<<14)
|
||||
addmi a0, a0, (1<<14)
|
||||
wsr a0, INTENABLE /* Enable Timer 2 */
|
||||
1:
|
||||
#endif
|
||||
|
||||
movi a0, _l4_save_ctx
|
||||
/* save 4 lower registers */
|
||||
s32i a1, a0, 4
|
||||
s32i a2, a0, 8
|
||||
s32i a3, a0, 12
|
||||
rsr a2, EXCSAVE_4 /* holds the value of a0 */
|
||||
s32i a2, a0, 0
|
||||
|
||||
/* Save special registers */
|
||||
addi a0, a0, SPECREG_OFFSET
|
||||
rsr a2, WINDOWBASE
|
||||
s32i a2, a0, 0
|
||||
rsr a2, WINDOWSTART
|
||||
s32i a2, a0, 4
|
||||
rsr a2, SAR
|
||||
s32i a2, a0, 8
|
||||
rsr a2, LBEG
|
||||
s32i a2, a0, 12
|
||||
rsr a2, LEND
|
||||
s32i a2, a0, 16
|
||||
rsr a2, LCOUNT
|
||||
s32i a2, a0, 20
|
||||
rsr a2, EPC1
|
||||
s32i a2, a0, 24
|
||||
|
||||
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
|
||||
movi a0, 0
|
||||
xsr a0, INTENABLE /* disable all interrupts */
|
||||
movi a2, ~(1<<16)
|
||||
and a0, a2, a0
|
||||
wsr a0, INTENABLE
|
||||
#endif
|
||||
|
||||
/* disable exception mode, window overflow */
|
||||
movi a0, PS_INTLEVEL(5) | PS_EXCM
|
||||
wsr a0, PS
|
||||
rsync
|
||||
|
||||
/* Save the remaining physical registers.
|
||||
* 4 registers are already saved, which leaves 60 registers to save.
|
||||
* (FIXME: consider the case when the CPU is configured with physical 32 registers)
|
||||
* These 60 registers are saved in 5 iterations, 12 registers at a time.
|
||||
*/
|
||||
movi a1, 5
|
||||
movi a3, _l4_save_ctx + 4 * 4
|
||||
|
||||
/* This is repeated 5 times, each time the window is shifted by 12 registers.
|
||||
* We come here with a1 = downcounter, a3 = save pointer, a2 and a0 unused.
|
||||
*/
|
||||
1:
|
||||
s32i a4, a3, 0
|
||||
s32i a5, a3, 4
|
||||
s32i a6, a3, 8
|
||||
s32i a7, a3, 12
|
||||
s32i a8, a3, 16
|
||||
s32i a9, a3, 20
|
||||
s32i a10, a3, 24
|
||||
s32i a11, a3, 28
|
||||
s32i a12, a3, 32
|
||||
s32i a13, a3, 36
|
||||
s32i a14, a3, 40
|
||||
s32i a15, a3, 44
|
||||
|
||||
/* We are about to rotate the window, so that a12-a15 will become the new a0-a3.
|
||||
* Copy a0-a3 to a12-15 to still have access to these values.
|
||||
* At the same time we can decrement the counter and adjust the save area pointer
|
||||
*/
|
||||
|
||||
/* a0 is constant (_l4_save_ctx), no need to copy */
|
||||
addi a13, a1, -1 /* copy and decrement the downcounter */
|
||||
/* a2 is scratch so no need to copy */
|
||||
addi a15, a3, 48 /* copy and adjust the save area pointer */
|
||||
beqz a13, 2f /* have saved all registers ? */
|
||||
rotw 3 /* rotate the window and go back */
|
||||
j 1b
|
||||
|
||||
/* the loop is complete */
|
||||
2:
|
||||
rotw 4 /* this brings us back to the original window */
|
||||
/* a0 still points to _l4_save_ctx */
|
||||
|
||||
/* Can clear WINDOWSTART now, all registers are saved */
|
||||
rsr a2, WINDOWBASE
|
||||
/* WINDOWSTART = (1 << WINDOWBASE) */
|
||||
movi a3, 1
|
||||
ssl a2
|
||||
sll a3, a3
|
||||
wsr a3, WINDOWSTART
|
||||
|
||||
_highint4_stack_switch:
|
||||
movi a0, 0
|
||||
movi sp, _l4_intr_stack + L4_INTR_STACK_SIZE - 16
|
||||
s32e a0, sp, -12 /* For GDB: set null SP */
|
||||
s32e a0, sp, -16 /* For GDB: set null PC */
|
||||
movi a0, _highint4_stack_switch /* For GDB: cosmetics, for the frame where stack switch happened */
|
||||
|
||||
/* Set up PS for C, disable all interrupts except NMI and debug, and clear EXCM. */
|
||||
movi a6, PS_INTLEVEL(4) | PS_UM | PS_WOE
|
||||
wsr a6, PS
|
||||
rsync
|
||||
|
||||
/* Call C handler */
|
||||
mov a6, sp
|
||||
call4 hli_c_handler
|
||||
|
||||
l32e sp, sp, -12 /* switch back to the original stack */
|
||||
|
||||
/* Done with C handler; re-enable exception mode, disabling window overflow */
|
||||
movi a2, PS_INTLEVEL(5) | PS_EXCM /* TOCHECK */
|
||||
wsr a2, PS
|
||||
rsync
|
||||
|
||||
/* Restore the special registers.
|
||||
* WINDOWSTART will be restored near the end.
|
||||
*/
|
||||
movi a0, _l4_save_ctx + SPECREG_OFFSET
|
||||
l32i a2, a0, 8
|
||||
wsr a2, SAR
|
||||
l32i a2, a0, 12
|
||||
wsr a2, LBEG
|
||||
l32i a2, a0, 16
|
||||
wsr a2, LEND
|
||||
l32i a2, a0, 20
|
||||
wsr a2, LCOUNT
|
||||
l32i a2, a0, 24
|
||||
wsr a2, EPC1
|
||||
|
||||
/* Restoring the physical registers.
|
||||
* This is the reverse to the saving process above.
|
||||
*/
|
||||
|
||||
/* Rotate back to the final window, then start loading 12 registers at a time,
|
||||
* in 5 iterations.
|
||||
* Again, a1 is the downcounter and a3 is the save area pointer.
|
||||
* After each rotation, a1 and a3 are copied from a13 and a15.
|
||||
* To simplify the loop, we put the initial values into a13 and a15.
|
||||
*/
|
||||
rotw -4
|
||||
movi a15, _l4_save_ctx + 64 * 4 /* point to the end of the save area */
|
||||
movi a13, 5
|
||||
|
||||
1:
|
||||
/* Copy a1 and a3 from their previous location,
|
||||
* at the same time decrementing and adjusting the save area pointer.
|
||||
*/
|
||||
addi a1, a13, -1
|
||||
addi a3, a15, -48
|
||||
|
||||
/* Load 12 registers */
|
||||
l32i a4, a3, 0
|
||||
l32i a5, a3, 4
|
||||
l32i a6, a3, 8
|
||||
l32i a7, a3, 12
|
||||
l32i a8, a3, 16
|
||||
l32i a9, a3, 20
|
||||
l32i a10, a3, 24
|
||||
l32i a11, a3, 28 /* ensure PS and EPC written */
|
||||
l32i a12, a3, 32
|
||||
l32i a13, a3, 36
|
||||
l32i a14, a3, 40
|
||||
l32i a15, a3, 44
|
||||
|
||||
/* Done with the loop? */
|
||||
beqz a1, 2f
|
||||
/* If no, rotate the window and repeat */
|
||||
rotw -3
|
||||
j 1b
|
||||
|
||||
2:
|
||||
/* Done with the loop. Only 4 registers (a0-a3 in the original window) remain
|
||||
* to be restored. Also need to restore WINDOWSTART, since all the general
|
||||
* registers are now in place.
|
||||
*/
|
||||
movi a0, _l4_save_ctx
|
||||
|
||||
l32i a2, a0, SPECREG_OFFSET + 4
|
||||
wsr a2, WINDOWSTART
|
||||
|
||||
l32i a1, a0, 4
|
||||
l32i a2, a0, 8
|
||||
l32i a3, a0, 12
|
||||
rsr a0, EXCSAVE_4 /* holds the value of a0 before the interrupt handler */
|
||||
|
||||
/* Return from the interrupt, restoring PS from EPS_4 */
|
||||
rfi 4
|
||||
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
/* The linker has no reason to link in this file; all symbols it exports are already defined
|
||||
(weakly!) in the default int handler. Define a symbol here so we can use it to have the
|
||||
linker inspect this anyway. */
|
||||
|
||||
.global ld_include_hli_vectors_bt
|
||||
ld_include_hli_vectors_bt:
|
@ -359,7 +359,8 @@ menu "MODEM SLEEP Options"
|
||||
bool "Internal 150kHz RC oscillator"
|
||||
depends on ESP32C3_RTC_CLK_SRC_INT_RC
|
||||
help
|
||||
Internal 150kHz RC oscillator.
|
||||
Internal 150kHz RC oscillator. The accuracy of this clock is a lot larger than 500ppm which is required
|
||||
in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.
|
||||
|
||||
|
||||
endchoice
|
||||
|
@ -992,7 +992,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
|
||||
// configure and initialize resources
|
||||
s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0;
|
||||
s_lp_cntl.no_light_sleep = 0;
|
||||
s_lp_cntl.no_light_sleep = 1;
|
||||
|
||||
if (s_lp_cntl.enable) {
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
@ -1029,31 +1029,29 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
|
||||
|
||||
// // set default bluetooth sleep clock source
|
||||
// s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL;
|
||||
// set default bluetooth sleep clock source
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
#if CONFIG_BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_32K_XTAL) {
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // set default value
|
||||
// #ifdef CONFIG_PM_ENABLE
|
||||
// s_btdm_allow_light_sleep = true;
|
||||
// #endif
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32 kHz XTAL
|
||||
s_lp_cntl.no_light_sleep = 0;
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
||||
"light sleep mode will not be able to apply when bluetooth is enabled");
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
}
|
||||
#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW)
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_RTC) {
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // set default value
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator
|
||||
ESP_LOGW(BTDM_LOG_TAG, "Internal 150kHz RC osciallator. The accuracy of this clock is a lot larger than 500ppm which is "
|
||||
"required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.");
|
||||
} else {
|
||||
ESP_LOGW(BTDM_LOG_TAG, "Internal 150kHz RC oscillator not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
||||
"light sleep mode will not be able to apply when bluetooth is enabled");
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC oscillator not detected.");
|
||||
assert(0);
|
||||
}
|
||||
#else
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
s_lp_cntl.no_light_sleep = 1;
|
||||
#endif
|
||||
|
||||
bool select_src_ret __attribute__((unused));
|
||||
|
@ -373,10 +373,11 @@ menu "MODEM SLEEP Options"
|
||||
modem sleep to be used with both DFS and light sleep.
|
||||
|
||||
config BT_CTRL_LPCLK_SEL_RTC_SLOW
|
||||
bool "Internal 90kHz RC oscillator"
|
||||
bool "Internal 150kHz RC oscillator"
|
||||
depends on ESP32S3_RTC_CLK_SRC_INT_RC
|
||||
help
|
||||
Internal 90kHz RC oscillator.
|
||||
Internal 150kHz RC oscillator. The accuracy of this clock is a lot larger than 500ppm which is required
|
||||
in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.
|
||||
|
||||
|
||||
endchoice
|
||||
|
@ -972,7 +972,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
|
||||
// configure and initialize resources
|
||||
s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0;
|
||||
s_lp_cntl.no_light_sleep = 0;
|
||||
s_lp_cntl.no_light_sleep = 1;
|
||||
|
||||
if (s_lp_cntl.enable) {
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
@ -1009,31 +1009,29 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
|
||||
|
||||
// // set default bluetooth sleep clock source
|
||||
// s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL;
|
||||
// set default bluetooth sleep clock source
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
#if CONFIG_BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_32K_XTAL) {
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // set default value
|
||||
// #ifdef CONFIG_PM_ENABLE
|
||||
// s_btdm_allow_light_sleep = true;
|
||||
// #endif
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32 kHz XTAL
|
||||
s_lp_cntl.no_light_sleep = 0;
|
||||
} else {
|
||||
ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
||||
"light sleep mode will not be able to apply when bluetooth is enabled");
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
}
|
||||
#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW)
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_RTC) {
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // set default value
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator
|
||||
ESP_LOGW(BTDM_LOG_TAG, "Internal 150kHz RC osciallator. The accuracy of this clock is a lot larger than 500ppm which is "
|
||||
"required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.");
|
||||
} else {
|
||||
ESP_LOGW(BT_LOG_TAG, "Internal 90kHz RC oscillator not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
||||
"light sleep mode will not be able to apply when bluetooth is enabled");
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC oscillator not detected.");
|
||||
assert(0);
|
||||
}
|
||||
#else
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
||||
s_lp_cntl.no_light_sleep = 1;
|
||||
#endif
|
||||
|
||||
bool select_src_ret __attribute__((unused));
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b97b2abd1a98ab887fb4cdc0553fabcba95aedaf
|
||||
Subproject commit fe0a3d00f11dbf9d219f2a291e3cab7419e5cac1
|
@ -1 +1 @@
|
||||
Subproject commit b223604efd557d0a5314afb3b751229df424d244
|
||||
Subproject commit 32f15e826a102d2d64e612620468122ea2234a2e
|
@ -9,10 +9,10 @@ if BLE_MESH
|
||||
config BLE_MESH_USE_DUPLICATE_SCAN
|
||||
bool "Support Duplicate Scan in BLE Mesh"
|
||||
depends on BT_BLUEDROID_ENABLED
|
||||
select BTDM_BLE_SCAN_DUPL if BT_CTRL_ESP32
|
||||
select BTDM_BLE_MESH_SCAN_DUPL_EN if BT_CTRL_ESP32
|
||||
select BT_CTRL_BLE_SCAN_DUPL if BT_CTRL_ESP32C3
|
||||
select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if BT_CTRL_ESP32C3
|
||||
select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32
|
||||
select BTDM_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32
|
||||
select BT_CTRL_BLE_SCAN_DUPL if IDF_TARGET_ESP32C3
|
||||
select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32C3
|
||||
default y
|
||||
help
|
||||
Enable this option to allow using specific duplicate scan filter
|
||||
|
@ -69,6 +69,12 @@ esp_err_t esp_ble_mesh_node_prov_disable(esp_ble_mesh_prov_bearer_t bearers);
|
||||
/**
|
||||
* @brief Unprovisioned device set own oob public key & private key pair.
|
||||
*
|
||||
* @note In order to avoid suffering brute-forcing attack (CVE-2020-26559).
|
||||
* The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
|
||||
* use an out-of-band mechanism to exchange the public keys.
|
||||
* So as an unprovisioned device, it should use this function to input
|
||||
* the Public Key exchanged through the out-of-band mechanism.
|
||||
*
|
||||
* @param[in] pub_key_x: Unprovisioned device's Public Key X
|
||||
* @param[in] pub_key_y: Unprovisioned device's Public Key Y
|
||||
* @param[in] private_key: Unprovisioned device's Private Key
|
||||
@ -121,6 +127,10 @@ esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name);
|
||||
/**
|
||||
* @brief Provisioner inputs unprovisioned device's oob public key.
|
||||
*
|
||||
* @note In order to avoid suffering brute-forcing attack (CVE-2020-26559).
|
||||
* The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
|
||||
* use an out-of-band mechanism to exchange the public keys.
|
||||
*
|
||||
* @param[in] link_idx: The provisioning link index
|
||||
* @param[in] pub_key_x: Unprovisioned device's Public Key X
|
||||
* @param[in] pub_key_y: Unprovisioned device's Public Key Y
|
||||
@ -329,6 +339,14 @@ esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_inf
|
||||
* A large entropy helps ensure that a brute-force of the AuthValue, even a static
|
||||
* AuthValue, cannot normally be completed in a reasonable time (CVE-2020-26557).
|
||||
*
|
||||
* AuthValues selected using a cryptographically secure random or pseudorandom number
|
||||
* generator and having the maximum permitted entropy (128-bits) will be most difficult
|
||||
* to brute-force. AuthValues with reduced entropy or generated in a predictable manner
|
||||
* will not grant the same level of protection against this vulnerability. Selecting a
|
||||
* new AuthValue with each provisioning attempt can also make it more difficult to launch
|
||||
* a brute-force attack by requiring the attacker to restart the search with each
|
||||
* provisioning attempt (CVE-2020-26556).
|
||||
*
|
||||
* @param[in] value: Pointer to the static oob value.
|
||||
* @param[in] length: Length of the static oob value.
|
||||
*
|
||||
|
@ -573,8 +573,10 @@ typedef struct {
|
||||
esp_ble_mesh_prov_oob_info_t oob_info;
|
||||
|
||||
/* NOTE: In order to avoid suffering brute-forcing attack (CVE-2020-26559).
|
||||
* The Bluetooth SIG recommends that potentially vulnerable mesh node
|
||||
* The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
|
||||
* support an out-of-band mechanism to exchange the public keys.
|
||||
* So as an unprovisioned device, it should enable this flag to support
|
||||
* using an out-of-band mechanism to exchange Public Key.
|
||||
*/
|
||||
/** Flag indicates whether unprovisioned devices support OOB public key */
|
||||
bool oob_pub_key;
|
||||
@ -629,7 +631,7 @@ typedef struct {
|
||||
/** Provisioning Algorithm for the Provisioner */
|
||||
uint8_t prov_algorithm;
|
||||
|
||||
/* NOTE: In order to avoid suffering brute-forcing attack(CVE-2020-26559).
|
||||
/* NOTE: In order to avoid suffering brute-forcing attack (CVE-2020-26559).
|
||||
* The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
|
||||
* use an out-of-band mechanism to exchange the public keys.
|
||||
*/
|
||||
@ -643,6 +645,14 @@ typedef struct {
|
||||
* selected AuthValue using all of the available bits, where permitted by the
|
||||
* implementation. A large entropy helps ensure that a brute-force of the AuthValue,
|
||||
* even a static AuthValue, cannot normally be completed in a reasonable time (CVE-2020-26557).
|
||||
*
|
||||
* AuthValues selected using a cryptographically secure random or pseudorandom number
|
||||
* generator and having the maximum permitted entropy (128-bits) will be most difficult
|
||||
* to brute-force. AuthValues with reduced entropy or generated in a predictable manner
|
||||
* will not grant the same level of protection against this vulnerability. Selecting a
|
||||
* new AuthValue with each provisioning attempt can also make it more difficult to launch
|
||||
* a brute-force attack by requiring the attacker to restart the search with each
|
||||
* provisioning attempt (CVE-2020-26556).
|
||||
*/
|
||||
/** Provisioner static oob value */
|
||||
uint8_t *prov_static_oob_val;
|
||||
|
@ -1930,6 +1930,19 @@ static int prov_auth(const uint8_t idx, uint8_t method, uint8_t action, uint8_t
|
||||
/* Provisioner ouput number/string and wait for device's Provisioning Input Complete PDU */
|
||||
link[idx].expect = PROV_INPUT_COMPLETE;
|
||||
|
||||
/* NOTE: The Bluetooth SIG recommends that mesh implementations enforce a randomly
|
||||
* selected AuthValue using all of the available bits, where permitted by the
|
||||
* implementation. A large entropy helps ensure that a brute-force of the AuthValue,
|
||||
* even a static AuthValue, cannot normally be completed in a reasonable time (CVE-2020-26557).
|
||||
*
|
||||
* AuthValues selected using a cryptographically secure random or pseudorandom number
|
||||
* generator and having the maximum permitted entropy (128-bits) will be most difficult
|
||||
* to brute-force. AuthValues with reduced entropy or generated in a predictable manner
|
||||
* will not grant the same level of protection against this vulnerability. Selecting a
|
||||
* new AuthValue with each provisioning attempt can also make it more difficult to launch
|
||||
* a brute-force attack by requiring the attacker to restart the search with each
|
||||
* provisioning attempt (CVE-2020-26556).
|
||||
*/
|
||||
if (input == BLE_MESH_ENTER_STRING) {
|
||||
unsigned char str[9] = {'\0'};
|
||||
uint8_t j = 0U;
|
||||
@ -2312,12 +2325,11 @@ static void prov_confirm(const uint8_t idx, const uint8_t *data)
|
||||
|
||||
BT_DBG("Remote Confirm: %s", bt_hex(data, 16));
|
||||
|
||||
/* NOTE: The Bluetooth SIG recommends that potentially vulnerable mesh
|
||||
* provisioners restrict the authentication procedure and not accept
|
||||
* provisioning random and provisioning confirmation numbers from a remote
|
||||
* peer that are the same as those selected by the local device (CVE-2020-26556
|
||||
* & CVE-2020-26560).
|
||||
* */
|
||||
/* NOTE: The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
|
||||
* restrict the authentication procedure and not accept provisioning random and
|
||||
* provisioning confirmation numbers from a remote peer that are the same as those
|
||||
* selected by the local device (CVE-2020-26560).
|
||||
*/
|
||||
if (!memcmp(data, link[idx].local_conf, 16)) {
|
||||
BT_ERR("Confirmation value is identical to ours, rejecting.");
|
||||
close_link(idx, CLOSE_REASON_FAILED);
|
||||
@ -2534,12 +2546,11 @@ static void prov_random(const uint8_t idx, const uint8_t *data)
|
||||
|
||||
BT_DBG("Remote Random: %s", bt_hex(data, 16));
|
||||
|
||||
/* NOTE: The Bluetooth SIG recommends that potentially vulnerable mesh
|
||||
* provisioners restrict the authentication procedure and not accept
|
||||
* provisioning random and provisioning confirmation numbers from a remote
|
||||
* peer that are the same as those selected by the local device (CVE-2020-26556
|
||||
* & CVE-2020-26560).
|
||||
* */
|
||||
/* NOTE: The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
|
||||
* restrict the authentication procedure and not accept provisioning random and
|
||||
* provisioning confirmation numbers from a remote peer that are the same as those
|
||||
* selected by the local device (CVE-2020-26560).
|
||||
*/
|
||||
if (!memcmp(data, link[idx].rand, 16)) {
|
||||
BT_ERR("Random value is identical to ours, rejecting.");
|
||||
goto fail;
|
||||
|
@ -42,7 +42,7 @@ config BT_BLUEDROID_MEM_DEBUG
|
||||
|
||||
config BT_CLASSIC_ENABLED
|
||||
bool "Classic Bluetooth"
|
||||
depends on BT_BLUEDROID_ENABLED && BT_CTRL_ESP32
|
||||
depends on BT_BLUEDROID_ENABLED && IDF_TARGET_ESP32
|
||||
default n
|
||||
help
|
||||
For now this option needs "SMP_ENABLE" to be set to yes
|
||||
@ -99,13 +99,27 @@ config BT_HFP_WBS_ENABLE
|
||||
This enables Wide Band Speech. Should disable it when SCO data path is PCM.
|
||||
Otherwise there will be no data transmited via GPIOs.
|
||||
|
||||
config BT_HID_HOST_ENABLED
|
||||
bool "Classic BT HID Host"
|
||||
config BT_HID_ENABLED
|
||||
bool "Classic BT HID"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
default n
|
||||
help
|
||||
This enables the BT HID Host
|
||||
|
||||
choice BT_HID_ROLE
|
||||
prompt "Profile Role configuration"
|
||||
depends on BT_HID_ENABLED
|
||||
config BT_HID_HOST_ENABLED
|
||||
bool "Classic BT HID Host"
|
||||
help
|
||||
This enables the BT HID Host
|
||||
|
||||
config BT_HID_DEVICE_ENABLED
|
||||
bool "Classic BT HID Device"
|
||||
help
|
||||
This enables the BT HID Device
|
||||
endchoice
|
||||
|
||||
config BT_SSP_ENABLED
|
||||
bool "Secure Simple Pairing"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
@ -1056,8 +1070,3 @@ config BT_BLE_42_FEATURES_SUPPORTED
|
||||
default n
|
||||
help
|
||||
This enables BLE 4.2 features.
|
||||
|
||||
config BT_RESERVE_DRAM
|
||||
hex
|
||||
default 0xdb5c if BT_ENABLED
|
||||
default 0
|
||||
|
176
components/bt/host/bluedroid/api/esp_hidd_api.c
Normal file
176
components/bt/host/bluedroid/api/esp_hidd_api.c
Normal file
@ -0,0 +1,176 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// 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 "esp_err.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_hd.h"
|
||||
#include "esp_hidd_api.h"
|
||||
|
||||
#if (defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE)
|
||||
|
||||
esp_err_t esp_bt_hid_device_register_callback(esp_hd_cb_t *callback)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_HD, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_init(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_INIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_deinit(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_DEINIT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t* app_param, esp_hidd_qos_param_t* in_qos, esp_hidd_qos_param_t* out_qos)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
args.register_app.app_param = app_param;
|
||||
args.register_app.in_qos = in_qos;
|
||||
args.register_app.out_qos = out_qos;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_REGISTER_APP_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_unregister_app(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_UNREGISTER_APP_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
memcpy(args.connect.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_CONNECT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_disconnect(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_DISCONNECT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t* data)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_SEND_REPORT_EVT;
|
||||
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
args.send_report.type = type;
|
||||
args.send_report.id = id;
|
||||
args.send_report.len = len;
|
||||
args.send_report.data = data;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), btc_hd_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_REPORT_ERROR_EVT;
|
||||
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
args.error = error;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_virtual_cable_unplug(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_UNPLUG_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE */
|
254
components/bt/host/bluedroid/api/esp_hidh_api.c
Normal file
254
components/bt/host/bluedroid/api/esp_hidh_api.c
Normal file
@ -0,0 +1,254 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// 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 "btc/btc_manage.h"
|
||||
#include "btc_hh.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_hidh_api.h"
|
||||
#include <string.h>
|
||||
|
||||
#if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
|
||||
|
||||
esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t *callback)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_HH, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_init(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_INIT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_deinit(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_DEINIT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_CONNECT_EVT;
|
||||
|
||||
memcpy(arg.connect.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_DISCONNECT_EVT;
|
||||
|
||||
memcpy(arg.disconnect.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_UNPLUG_EVT;
|
||||
|
||||
memcpy(arg.unplug.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_INFO_EVT;
|
||||
|
||||
memcpy(arg.set_info.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_info.hid_info = hid_info;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), btc_hh_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_GET_PROTO_EVT;
|
||||
|
||||
memcpy(arg.get_protocol.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_PROTO_EVT;
|
||||
|
||||
memcpy(arg.set_protocol.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_protocol.protocol_mode = protocol_mode;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_GET_IDLE_EVT;
|
||||
|
||||
memcpy(arg.get_idle.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_IDLE_EVT;
|
||||
|
||||
memcpy(arg.set_idle.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_idle.idle_time = idle_time;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t report_id,
|
||||
int buffer_size)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_GET_REPORT_EVT;
|
||||
|
||||
memcpy(arg.get_report.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.get_report.report_type = report_type;
|
||||
arg.get_report.report_id = report_id;
|
||||
arg.get_report.buffer_size = buffer_size;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t *report,
|
||||
size_t len)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_REPORT_EVT;
|
||||
|
||||
memcpy(arg.set_report.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_report.report_type = report_type;
|
||||
arg.set_report.len = len;
|
||||
arg.set_report.report = report;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), btc_hh_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SEND_DATA_EVT;
|
||||
|
||||
memcpy(arg.send_data.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.send_data.len = len;
|
||||
arg.send_data.data = data;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), btc_hh_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE */
|
@ -467,7 +467,7 @@ typedef struct
|
||||
{
|
||||
uint16_t rx_len; /*!< pkt rx data length value */
|
||||
uint16_t tx_len; /*!< pkt tx data length value */
|
||||
}esp_ble_pkt_data_length_params_t;
|
||||
} esp_ble_pkt_data_length_params_t;
|
||||
|
||||
/**
|
||||
* @brief BLE encryption keys
|
||||
@ -648,7 +648,7 @@ typedef enum {
|
||||
typedef enum{
|
||||
ESP_BLE_WHITELIST_REMOVE = 0X00, /*!< remove mac from whitelist */
|
||||
ESP_BLE_WHITELIST_ADD = 0X01, /*!< add address to whitelist */
|
||||
}esp_ble_wl_opration_t;
|
||||
} esp_ble_wl_opration_t;
|
||||
#if (BLE_42_FEATURE_SUPPORT == TRUE)
|
||||
typedef enum {
|
||||
ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD = 0, /*!< Add device info into duplicate scan exceptional list */
|
||||
@ -998,7 +998,7 @@ typedef union {
|
||||
uint16_t conn_int; /*!< Current connection interval */
|
||||
uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
|
||||
Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec */
|
||||
}update_conn_params; /*!< Event parameter of ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */
|
||||
} update_conn_params; /*!< Event parameter of ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT
|
||||
*/
|
||||
@ -1018,13 +1018,13 @@ typedef union {
|
||||
struct ble_remove_bond_dev_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */
|
||||
esp_bd_addr_t bd_addr; /*!< The device address which has been remove from the bond list */
|
||||
}remove_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */
|
||||
} remove_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_clear_bond_dev_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the clear bond device operation success status */
|
||||
}clear_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT */
|
||||
} clear_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT
|
||||
*/
|
||||
@ -1032,7 +1032,7 @@ typedef union {
|
||||
esp_bt_status_t status; /*!< Indicate the get bond device operation success status */
|
||||
uint8_t dev_num; /*!< Indicate the get number device in the bond list */
|
||||
esp_ble_bond_dev_t *bond_dev; /*!< the pointer to the bond device Structure */
|
||||
}get_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT */
|
||||
} get_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT
|
||||
*/
|
||||
|
@ -380,7 +380,7 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
|
||||
/**
|
||||
* @brief Find all the service with the given service uuid in the gattc cache, if the svc_uuid is NULL, find all the service.
|
||||
* Note: It just get service from local cache, won't get from remote devices. If want to get it from remote device, need
|
||||
* to used the esp_ble_gattc_search_service.
|
||||
* to used the esp_ble_gattc_cache_refresh, then call esp_ble_gattc_get_service again.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID which identify the server.
|
||||
|
379
components/bt/host/bluedroid/api/include/api/esp_hidd_api.h
Normal file
379
components/bt/host/bluedroid/api/include/api/esp_hidd_api.h
Normal file
@ -0,0 +1,379 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __ESP_HIDD_API_H__
|
||||
#define __ESP_HIDD_API_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* sub_class of hid device */
|
||||
#define ESP_HID_CLASS_UNKNOWN (0x00<<2)
|
||||
#define ESP_HID_CLASS_JOS (0x01<<2) /* joy stick */
|
||||
#define ESP_HID_CLASS_GPD (0x02<<2) /* game pad */
|
||||
#define ESP_HID_CLASS_RMC (0x03<<2) /* remote control */
|
||||
#define ESP_HID_CLASS_SED (0x04<<2) /* sensing device */
|
||||
#define ESP_HID_CLASS_DGT (0x05<<2) /* Digitizer tablet */
|
||||
#define ESP_HID_CLASS_CDR (0x06<<2) /* card reader */
|
||||
#define ESP_HID_CLASS_KBD (0x10<<2) /* keyboard */
|
||||
#define ESP_HID_CLASS_MIC (0x20<<2) /* pointing device */
|
||||
#define ESP_HID_CLASS_COM (0x30<<2) /* Combo keyboard/pointing */
|
||||
|
||||
/**
|
||||
* @brief HIDD handshake error
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_SUCCESS = 0,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_NOT_READY = 1,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID = 2,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ = 3,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM = 4,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN = 14,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_FATAL = 15
|
||||
} esp_hidd_handshake_error_t;
|
||||
|
||||
/**
|
||||
* @brief HIDD report types
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_REPORT_TYPE_OTHER = 0,
|
||||
ESP_HIDD_REPORT_TYPE_INPUT,
|
||||
ESP_HIDD_REPORT_TYPE_OUTPUT,
|
||||
ESP_HIDD_REPORT_TYPE_FEATURE,
|
||||
// special value for reports to be sent on INTR(INPUT is assumed)
|
||||
ESP_HIDD_REPORT_TYPE_INTRDATA
|
||||
} esp_hidd_report_type_t;
|
||||
|
||||
/**
|
||||
* @brief HIDD connection state
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_CONN_STATE_CONNECTED,
|
||||
ESP_HIDD_CONN_STATE_CONNECTING,
|
||||
ESP_HIDD_CONN_STATE_DISCONNECTED,
|
||||
ESP_HIDD_CONN_STATE_DISCONNECTING,
|
||||
ESP_HIDD_CONN_STATE_UNKNOWN
|
||||
} esp_hidd_connection_state_t;
|
||||
|
||||
/**
|
||||
* @brief HID device protocol modes
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_REPORT_MODE = 0x00,
|
||||
ESP_HIDD_BOOT_MODE = 0x01,
|
||||
ESP_HIDD_UNSUPPORTED_MODE = 0xff
|
||||
} esp_hidd_protocol_mode_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief HIDD characteristics for SDP report
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *description;
|
||||
const char *provider;
|
||||
uint8_t subclass;
|
||||
uint8_t *desc_list;
|
||||
int desc_list_len;
|
||||
} esp_hidd_app_param_t;
|
||||
|
||||
/**
|
||||
* @brief HIDD Quality of Service parameters
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t service_type;
|
||||
uint32_t token_rate;
|
||||
uint32_t token_bucket_size;
|
||||
uint32_t peak_bandwidth;
|
||||
uint32_t access_latency;
|
||||
uint32_t delay_variation;
|
||||
} esp_hidd_qos_param_t;
|
||||
|
||||
/**
|
||||
* @brief HID device callback function events
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_INIT_EVT = 0, /*!< When HID device is inited, the event comes */
|
||||
ESP_HIDD_DEINIT_EVT, /*!< When HID device is deinited, the event comes */
|
||||
ESP_HIDD_REGISTER_APP_EVT, /*!< When HID device application registered, the event comes */
|
||||
ESP_HIDD_UNREGISTER_APP_EVT, /*!< When HID device application unregistered, the event comes */
|
||||
ESP_HIDD_OPEN_EVT, /*!< When HID device connection to host opened, the event comes */
|
||||
ESP_HIDD_CLOSE_EVT, /*!< When HID device connection to host closed, the event comes */
|
||||
ESP_HIDD_SEND_REPORT_EVT, /*!< When HID device send report to lower layer, the event comes */
|
||||
ESP_HIDD_REPORT_ERR_EVT, /*!< When HID device report handshanke error to lower layer, the event comes */
|
||||
ESP_HIDD_GET_REPORT_EVT, /*!< When HID device receives GET_REPORT request from host, the event comes */
|
||||
ESP_HIDD_SET_REPORT_EVT, /*!< When HID device receives SET_REPORT request from host, the event comes */
|
||||
ESP_HIDD_SET_PROTOCOL_EVT, /*!< When HID device receives SET_PROTOCOL request from host, the event comes */
|
||||
ESP_HIDD_INTR_DATA_EVT, /*!< When HID device receives DATA from host on intr, the event comes */
|
||||
ESP_HIDD_VC_UNPLUG_EVT, /*!< When HID device initiates Virtual Cable Unplug, the event comes */
|
||||
ESP_HIDD_API_ERR_EVT /*!< When HID device has API error, the event comes */
|
||||
} esp_hidd_cb_event_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_HIDD_SUCCESS,
|
||||
ESP_HIDD_ERROR, /*!< general ESP HD error */
|
||||
ESP_HIDD_NO_RES, /*!< out of system resources */
|
||||
ESP_HIDD_BUSY, /*!< Temporarily can not handle this request. */
|
||||
ESP_HIDD_NO_DATA, /*!< No data. */
|
||||
ESP_HIDD_NEED_INIT, /*!< HIDD module shall init first */
|
||||
ESP_HIDD_NEED_DEINIT, /*!< HIDD module shall deinit first */
|
||||
ESP_HIDD_NEED_REG, /*!< HIDD module shall register first */
|
||||
ESP_HIDD_NEED_DEREG, /*!< HIDD module shall deregister first */
|
||||
ESP_HIDD_NO_CONNECTION, /*!< connection may have been closed */
|
||||
} esp_hidd_status_t;
|
||||
|
||||
/**
|
||||
* @brief HID device callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_HIDD_INIT_EVT
|
||||
*/
|
||||
struct hidd_init_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
} init; /*!< HIDD callback param of ESP_HIDD_INIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_DEINIT_EVT
|
||||
*/
|
||||
struct hidd_deinit_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
} deinit; /*!< HIDD callback param of ESP_HIDD_DEINIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_REGISTER_APP_EVT
|
||||
*/
|
||||
struct hidd_register_app_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
bool in_use; /*!< indicate whether use virtual cable plug host address */
|
||||
esp_bd_addr_t bd_addr; /*!< host address */
|
||||
} register_app; /*!< HIDD callback param of ESP_HIDD_REGISTER_APP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_UNREGISTER_APP_EVT
|
||||
*/
|
||||
struct hidd_unregister_app_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
} unregister_app; /*!< HIDD callback param of ESP_HIDD_UNREGISTER_APP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_OPEN_EVT
|
||||
*/
|
||||
struct hidd_open_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
esp_hidd_connection_state_t conn_status; /*!< connection status */
|
||||
esp_bd_addr_t bd_addr; /*!< host address */
|
||||
} open; /*!< HIDD callback param of ESP_HIDD_OPEN_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_CLOSE_EVT
|
||||
*/
|
||||
struct hidd_close_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
esp_hidd_connection_state_t conn_status; /*!< connection status */
|
||||
} close; /*!< HIDD callback param of ESP_HIDD_CLOSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_SEND_REPORT_EVT
|
||||
*/
|
||||
struct hidd_send_report_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
esp_hidd_report_type_t report_type; /*!< report type */
|
||||
uint8_t report_id; /*!< report id */
|
||||
} send_report; /*!< HIDD callback param of ESP_HIDD_SEND_REPORT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_REPORT_ERR_EVT
|
||||
*/
|
||||
struct hidd_report_err_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
} report_err; /*!< HIDD callback param of ESP_HIDD_REPORT_ERR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_GET_REPORT_EVT
|
||||
*/
|
||||
struct hidd_get_report_evt_param {
|
||||
esp_hidd_report_type_t report_type; /*!< report type */
|
||||
uint8_t report_id; /*!< report id */
|
||||
uint16_t buffer_size; /*!< buffer size */
|
||||
} get_report; /*!< HIDD callback param of ESP_HIDD_GET_REPORT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_SET_REPORT_EVT
|
||||
*/
|
||||
struct hidd_set_report_evt_param {
|
||||
esp_hidd_report_type_t report_type; /*!< report type */
|
||||
uint8_t report_id; /*!< report id */
|
||||
uint16_t len; /*!< set_report data length */
|
||||
uint8_t *data; /*!< set_report data pointer */
|
||||
} set_report; /*!< HIDD callback param of ESP_HIDD_SET_REPORT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_SET_PROTOCOL_EVT
|
||||
*/
|
||||
struct hidd_set_protocol_evt_param {
|
||||
esp_hidd_protocol_mode_t protocol_mode; /*!< protocol mode */
|
||||
} set_protocol; /*!< HIDD callback param of ESP_HIDD_SET_PROTOCOL_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_INTR_DATA_EVT
|
||||
*/
|
||||
struct hidd_intr_data_evt_param {
|
||||
uint8_t report_id; /*!< interrupt channel report id */
|
||||
uint16_t len; /*!< interrupt channel report data length */
|
||||
uint8_t *data; /*!< interrupt channel report data pointer */
|
||||
} intr_data; /*!< HIDD callback param of ESP_HIDD_INTR_DATA_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_VC_UNPLUG_EVT
|
||||
*/
|
||||
struct hidd_vc_unplug_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
esp_hidd_connection_state_t conn_status; /*!< connection status */
|
||||
} vc_unplug; /*!< HIDD callback param of ESP_HIDD_VC_UNPLUG_EVT */
|
||||
} esp_hidd_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief HID device callback function type.
|
||||
* @param event: Event type
|
||||
* @param param: Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (esp_hd_cb_t)(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to init callbacks with HID device module.
|
||||
*
|
||||
* @param[in] callback: pointer to the init callback function.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_register_callback(esp_hd_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief This function initializes HIDD. This function should be called after esp_bluedroid_enable and
|
||||
* esp_blueroid_init success, and should be called after esp_bt_hid_device_register_callback.
|
||||
* When the operation is complete the callback function will be called with ESP_HIDD_INIT_EVT.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_init(void);
|
||||
|
||||
/**
|
||||
* @brief This function de-initializes HIDD interface. This function should be called after esp_bluedroid_enable() and
|
||||
* esp_blueroid_init() success, and should be called after esp_bt_hid_device_init(). When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_DEINIT_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Registers HIDD parameters with SDP and sets l2cap Quality of Service. This function should be called after
|
||||
* esp_bluedroid_enable and esp_blueroid_init success, and must be done after esp_bt_hid_device_init. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_REGISTER_APP_EVT.
|
||||
*
|
||||
* @param[in] app_param: HIDD parameters
|
||||
* @param[in] in_qos: incoming QoS parameters
|
||||
* @param[in] out_qos: outgoing QoS parameters
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t *app_param, esp_hidd_qos_param_t *in_qos,
|
||||
esp_hidd_qos_param_t *out_qos);
|
||||
|
||||
/**
|
||||
* @brief Removes HIDD parameters from SDP and resets l2cap Quality of Service. This function should be called after esp_bluedroid_enable and
|
||||
* esp_blueroid_init success, and should be called after esp_bt_hid_device_init. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_UNREGISTER_APP_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_unregister_app(void);
|
||||
|
||||
/**
|
||||
* @brief This function connects HIDD interface to connected bluetooth device, if not done already. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_OPEN_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote host bluetooth device address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief This function disconnects HIDD interface. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_CLOSE_EVT.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_disconnect(void);
|
||||
|
||||
/**
|
||||
* @brief Send HIDD report. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_SEND_REPORT_EVT.
|
||||
*
|
||||
* @param[in] type: type of report
|
||||
* @param[in] id: report id as defined by descriptor
|
||||
* @param[in] len: length of report
|
||||
* @param[in] data: report data
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Sends HIDD handshake with error info for invalid set_report. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_REPORT_ERR_EVT.
|
||||
*
|
||||
* @param[in] error: type of error
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error);
|
||||
|
||||
/**
|
||||
* @brief Unplug virtual cable of HIDD. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_VC_UNPLUG_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_virtual_cable_unplug(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
465
components/bt/host/bluedroid/api/include/api/esp_hidh_api.h
Normal file
465
components/bt/host/bluedroid/api/include/api/esp_hidh_api.h
Normal file
@ -0,0 +1,465 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __ESP_HIDH_API_H__
|
||||
#define __ESP_HIDH_API_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BTHH_MAX_DSC_LEN 884
|
||||
|
||||
/**
|
||||
* @brief HID host connection state
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_CONN_STATE_CONNECTED = 0, /*!< connected state */
|
||||
ESP_HIDH_CONN_STATE_CONNECTING, /*!< connecting state */
|
||||
ESP_HIDH_CONN_STATE_DISCONNECTED, /*!< disconnected state */
|
||||
ESP_HIDH_CONN_STATE_DISCONNECTING, /*!< disconnecting state */
|
||||
ESP_HIDH_CONN_STATE_UNKNOWN /*!< unknown state(initial state) */
|
||||
} esp_hidh_connection_state_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_HIDH_OK,
|
||||
ESP_HIDH_HS_HID_NOT_READY, /*!< handshake error : device not ready */
|
||||
ESP_HIDH_HS_INVALID_RPT_ID, /*!< handshake error : invalid report ID */
|
||||
ESP_HIDH_HS_TRANS_NOT_SPT, /*!< handshake error : transaction not spt */
|
||||
ESP_HIDH_HS_INVALID_PARAM, /*!< handshake error : invalid paremter */
|
||||
ESP_HIDH_HS_ERROR, /*!< handshake error : unspecified HS error */
|
||||
ESP_HIDH_ERR, /*!< general ESP HH error */
|
||||
ESP_HIDH_ERR_SDP, /*!< SDP error */
|
||||
ESP_HIDH_ERR_PROTO, /*!< SET_Protocol error,
|
||||
only used in ESP_HIDH_OPEN_EVT callback */
|
||||
|
||||
ESP_HIDH_ERR_DB_FULL, /*!< device database full error, used in
|
||||
ESP_HIDH_OPEN_EVT/ESP_HIDH_ADD_DEV_EVT */
|
||||
ESP_HIDH_ERR_TOD_UNSPT, /*!< type of device not supported */
|
||||
ESP_HIDH_ERR_NO_RES, /*!< out of system resources */
|
||||
ESP_HIDH_ERR_AUTH_FAILED, /*!< authentication fail */
|
||||
ESP_HIDH_ERR_HDL, /*!< connection handle error */
|
||||
ESP_HIDH_ERR_SEC, /*!< encryption error */
|
||||
// self_defined
|
||||
ESP_HIDH_BUSY, /*!< Temporarily can not handle this request. */
|
||||
ESP_HIDH_NO_DATA, /*!< No data. */
|
||||
ESP_HIDH_NEED_INIT, /*!< HIDH module shall init first */
|
||||
ESP_HIDH_NEED_DEINIT, /*!< HIDH module shall deinit first */
|
||||
ESP_HIDH_NO_CONNECTION, /*!< connection may have been closed */
|
||||
} esp_hidh_status_t;
|
||||
|
||||
/**
|
||||
* @brief HID host protocol modes
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_BOOT_MODE = 0x00, /*!< boot protocol mode */
|
||||
ESP_HIDH_REPORT_MODE = 0x01, /*!< report protocol mode */
|
||||
ESP_HIDH_UNSUPPORTED_MODE = 0xff /*!< unsupported protocol mode */
|
||||
} esp_hidh_protocol_mode_t;
|
||||
|
||||
/**
|
||||
* @brief HID host report types
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_REPORT_TYPE_OTHER = 0, /*!< unsupported report type */
|
||||
ESP_HIDH_REPORT_TYPE_INPUT, /*!< input report type */
|
||||
ESP_HIDH_REPORT_TYPE_OUTPUT, /*!< output report type */
|
||||
ESP_HIDH_REPORT_TYPE_FEATURE, /*!< feature report type */
|
||||
} esp_hidh_report_type_t;
|
||||
|
||||
/**
|
||||
* @brief HID host callback function events
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_INIT_EVT = 0, /*!< When HID host is inited, the event comes */
|
||||
ESP_HIDH_DEINIT_EVT, /*!< When HID host is deinited, the event comes */
|
||||
ESP_HIDH_OPEN_EVT, /*!< When HID host connection opened, the event comes */
|
||||
ESP_HIDH_CLOSE_EVT, /*!< When HID host connection closed, the event comes */
|
||||
ESP_HIDH_GET_RPT_EVT, /*!< When Get_Report command is called, the event comes */
|
||||
ESP_HIDH_SET_RPT_EVT, /*!< When Set_Report command is called, the event comes */
|
||||
ESP_HIDH_GET_PROTO_EVT, /*!< When Get_Protocol command is called, the event comes */
|
||||
ESP_HIDH_SET_PROTO_EVT, /*!< When Set_Protocol command is called, the event comes */
|
||||
ESP_HIDH_GET_IDLE_EVT, /*!< When Get_Idle command is called, the event comes */
|
||||
ESP_HIDH_SET_IDLE_EVT, /*!< When Set_Idle command is called, the event comes */
|
||||
ESP_HIDH_GET_DSCP_EVT, /*!< When HIDH is inited, the event comes */
|
||||
ESP_HIDH_ADD_DEV_EVT, /*!< When a device is added, the event comes */
|
||||
ESP_HIDH_RMV_DEV_EVT, /*!< When a device is removed, the event comes */
|
||||
ESP_HIDH_VC_UNPLUG_EVT, /*!< When virtually unplugged, the event comes */
|
||||
ESP_HIDH_DATA_EVT, /*!< When send data on interrupt channel, the event comes */
|
||||
ESP_HIDH_DATA_IND_EVT, /*!< When receive data on interrupt channel, the event comes */
|
||||
ESP_HIDH_SET_INFO_EVT /*!< When set the HID device descriptor, the event comes */
|
||||
} esp_hidh_cb_event_t;
|
||||
|
||||
typedef struct {
|
||||
int attr_mask;
|
||||
uint8_t sub_class;
|
||||
uint8_t app_id;
|
||||
int vendor_id;
|
||||
int product_id;
|
||||
int version;
|
||||
uint8_t ctry_code;
|
||||
int dl_len;
|
||||
uint8_t dsc_list[BTHH_MAX_DSC_LEN];
|
||||
} esp_hidh_hid_info_t;
|
||||
|
||||
/**
|
||||
* @brief HID host callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_HIDH_INIT_EVT
|
||||
*/
|
||||
struct hidh_init_evt_param {
|
||||
esp_hidh_status_t status; /*!< status */
|
||||
} init; /*!< HIDH callback param of ESP_HIDH_INIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_DEINIT_EVT
|
||||
*/
|
||||
struct hidh_uninit_evt_param {
|
||||
esp_hidh_status_t status; /*!< status */
|
||||
} deinit; /*!< HIDH callback param of ESP_HIDH_DEINIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_OPEN_EVT
|
||||
*/
|
||||
struct hidh_open_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
esp_hidh_connection_state_t conn_status; /*!< connection status */
|
||||
bool is_orig; /*!< indicate if host intiate the connection */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} open; /*!< HIDH callback param of ESP_HIDH_OPEN_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_CLOSE_EVT
|
||||
*/
|
||||
struct hidh_close_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
esp_hidh_connection_state_t conn_status; /*!< connection status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} close; /*!< HIDH callback param of ESP_HIDH_CLOSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_VC_UNPLUG_EVT
|
||||
*/
|
||||
struct hidh_unplug_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
esp_hidh_connection_state_t conn_status; /*!< connection status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} unplug; /*!< HIDH callback param of ESP_HIDH_VC_UNPLUG_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_PROTO_EVT
|
||||
*/
|
||||
struct hidh_get_proto_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode */
|
||||
} get_proto; /*!< HIDH callback param of ESP_HIDH_GET_PROTO_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_PROTO_EVT
|
||||
*/
|
||||
struct hidh_set_proto_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} set_proto; /*!< HIDH callback param of ESP_HIDH_SET_PROTO_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_RPT_EVT
|
||||
*/
|
||||
struct hidh_get_rpt_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
uint16_t len; /*!< data length */
|
||||
uint8_t *data; /*!< data pointer */
|
||||
} get_rpt; /*!< HIDH callback param of ESP_HIDH_GET_RPT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_RPT_EVT
|
||||
*/
|
||||
struct hidh_set_rpt_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} set_rpt; /*!< HIDH callback param of ESP_HIDH_SET_RPT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_DATA_EVT
|
||||
*/
|
||||
struct hidh_send_data_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
} send_data; /*!< HIDH callback param of ESP_HIDH_DATA_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_IDLE_EVT
|
||||
*/
|
||||
struct hidh_get_idle_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
uint8_t idle_rate; /*!< idle rate */
|
||||
} get_idle; /*!< HIDH callback param of ESP_HIDH_GET_IDLE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_IDLE_EVT
|
||||
*/
|
||||
struct hidh_set_idle_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} set_idle; /*!< HIDH callback param of ESP_HIDH_SET_IDLE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_DATA_IND_EVT
|
||||
*/
|
||||
struct hidh_data_ind_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode */
|
||||
uint16_t len; /*!< data length */
|
||||
uint8_t *data; /*!< data pointer */
|
||||
} data_ind; /*!< HIDH callback param of ESP_HIDH_DATA_IND_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_ADD_DEV_EVT
|
||||
*/
|
||||
struct hidh_add_dev_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} add_dev; /*!< HIDH callback param of ESP_HIDH_ADD_DEV_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_RMV_DEV_EVT
|
||||
*/
|
||||
struct hidh_rmv_dev_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} rmv_dev; /*!< HIDH callback param of ESP_HIDH_RMV_DEV_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_DSCP_EVT
|
||||
*/
|
||||
struct hidh_get_dscp_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
bool added; /*!< Indicate if added */
|
||||
uint16_t vendor_id; /*!< Vendor ID */
|
||||
uint16_t product_id; /*!< Product ID */
|
||||
uint16_t version; /*!< Version */
|
||||
uint16_t ssr_max_latency; /*!< SSR max latency */
|
||||
uint16_t ssr_min_tout; /*!< SSR min timeout */
|
||||
uint8_t ctry_code; /*!< Country Code */
|
||||
uint16_t dl_len; /*!< Device descriptor length */
|
||||
uint8_t *dsc_list; /*!< Device descriptor pointer */
|
||||
} dscp; /*!< HIDH callback param of ESP_HIDH_GET_DSCP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_INFO_EVT
|
||||
*/
|
||||
struct hidh_set_info_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} set_info; /*!< HIDH callback param of ESP_HIDH_SET_INFO_EVT */
|
||||
} esp_hidh_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief HID host callback function type
|
||||
* @param event: Event type
|
||||
* @param param: Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (esp_hh_cb_t)(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to init callbacks with HID host module.
|
||||
*
|
||||
* @param[in] callback: pointer to the init callback function.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief This function initializes HID host. This function should be called after esp_bluedroid_enable() and
|
||||
* esp_blueroid_init() success, and should be called after esp_bt_hid_host_register_callback().
|
||||
* When the operation is complete the callback function will be called with ESP_HIDH_INIT_EVT.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_init(void);
|
||||
|
||||
/**
|
||||
* @brief Closes the interface. This function should be called after esp_bluedroid_enable() and
|
||||
* esp_blueroid_init() success, and should be called after esp_bt_hid_host_init().
|
||||
* When the operation is complete the callback function will be called with ESP_HIDH_DEINIT_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Connect to hid device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_OPEN_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Disconnect from hid device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_CLOSE_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Virtual UnPlug (VUP) the specified HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_VC_UNPLUG_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Set the HID device descriptor for the specified HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_INFO_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] hid_info: HID device descriptor structure.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info);
|
||||
|
||||
/**
|
||||
* @brief Get the HID proto mode. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_GET_PROTO_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Set the HID proto mode. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_PROTO_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] protocol_mode: Protocol mode type.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode);
|
||||
|
||||
/**
|
||||
* @brief Get the HID Idle Time. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_GET_IDLE_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Set the HID Idle Time. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_IDLE_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] idle_time: Idle time rate
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time);
|
||||
|
||||
/**
|
||||
* @brief Send a GET_REPORT to HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_GET_RPT_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] report_type: Report type
|
||||
* @param[in] report_id: Report id
|
||||
* @param[in] buffer_size: Buffer size
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t report_id,
|
||||
int buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Send a SET_REPORT to HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_RPT_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] report_type: Report type
|
||||
* @param[in] report: Report data pointer
|
||||
* @param[in] len: Report data length
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t *report,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* @brief Send data to HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_DATA_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] data: Data pointer
|
||||
* @param[in] len: Data length
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -126,7 +126,7 @@ static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
|
||||
#endif
|
||||
#endif
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
|
||||
static BOOLEAN bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
|
||||
@ -3069,7 +3069,9 @@ static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev
|
||||
bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
|
||||
}
|
||||
|
||||
bta_dm_remove_sec_dev_entry(bd_addr);
|
||||
if (bta_dm_remove_sec_dev_entry(bd_addr)) {
|
||||
return BTM_SEC_DEV_REC_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
return BTM_SUCCESS;
|
||||
@ -3740,12 +3742,13 @@ static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
|
||||
** remtoe device does not exist, else schedule for dev entry removal upon
|
||||
ACL close
|
||||
**
|
||||
** Returns void
|
||||
** Returns TRUE if device entry is removed from Security device DB, FALSE otherwise
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
static BOOLEAN bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
{
|
||||
BOOLEAN is_device_deleted = FALSE;
|
||||
UINT16 index = 0;
|
||||
if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
|
||||
BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
|
||||
@ -3763,7 +3766,7 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
|
||||
}
|
||||
} else {
|
||||
BTM_SecDeleteDevice (remote_bd_addr, bta_dm_cb.device_list.peer_device[index].transport);
|
||||
is_device_deleted = BTM_SecDeleteDevice (remote_bd_addr, bta_dm_cb.device_list.peer_device[index].transport);
|
||||
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
|
||||
/* need to remove all pending background connection */
|
||||
BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
|
||||
@ -3771,6 +3774,7 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
BTA_GATTC_Refresh(remote_bd_addr, false);
|
||||
#endif
|
||||
}
|
||||
return is_device_deleted;
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
||||
@ -3835,7 +3839,10 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
|
||||
} else {
|
||||
bta_dm_cb.switch_delay_timer[i].p_cback =
|
||||
(TIMER_CBACK *)&bta_dm_delay_role_switch_cback;
|
||||
bta_sys_start_timer(&bta_dm_cb.switch_delay_timer[i], 0, 500);
|
||||
/* Start the timer if not active */
|
||||
if (!bta_sys_timer_is_active(&bta_dm_cb.switch_delay_timer[i])) {
|
||||
bta_sys_start_timer(&bta_dm_cb.switch_delay_timer[i], 0, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4495,6 +4502,22 @@ void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
||||
#if (BTA_HD_INCLUDED == TRUE)
|
||||
BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s: count(%d)", __func__, bta_dm_conn_srvcs.count);
|
||||
for (uint8_t j = 0; j < bta_dm_conn_srvcs.count; j++) {
|
||||
// Check if profiles other than hid are connected
|
||||
if ((bta_dm_conn_srvcs.conn_srvc[j].id != BTA_ID_HD) &&
|
||||
!bdcmp(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr)) {
|
||||
APPL_TRACE_DEBUG("%s: Another profile (id=%d) is connected", __func__, bta_dm_conn_srvcs.conn_srvc[j].id);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED == TRUE */
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -4975,9 +4998,6 @@ void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
|
||||
p_data->ble_update_conn_params.latency,
|
||||
p_data->ble_update_conn_params.timeout)) {
|
||||
APPL_TRACE_ERROR("Update connection parameters failed!");
|
||||
} else {
|
||||
BTM_BleConfigConnParams(p_data->ble_update_conn_params.min_int, p_data->ble_update_conn_params.max_int,
|
||||
p_data->ble_update_conn_params.latency, p_data->ble_update_conn_params.timeout);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
|
@ -117,11 +117,11 @@ tBTA_DM_CFG *const p_bta_dm_cfg = (tBTA_DM_CFG *) &bta_dm_cfg;
|
||||
tBTA_DM_RM *const p_bta_dm_rm_cfg = (tBTA_DM_RM *) &bta_dm_rm_cfg;
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
# define BTA_DM_NUM_PM_ENTRY 10 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 10 /* number of entries in bta_dm_pm_spec */
|
||||
#else
|
||||
# define BTA_DM_NUM_PM_ENTRY 8 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 8 /* number of entries in bta_dm_pm_spec */
|
||||
#else
|
||||
# define BTA_DM_NUM_PM_ENTRY 6 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 6 /* number of entries in bta_dm_pm_spec */
|
||||
#endif
|
||||
|
||||
#if (BTA_DM_PM_INCLUDED == TRUE)
|
||||
@ -133,10 +133,12 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG bta_dm_pm_cfg[BTA_DM_NUM_PM_ENTRY + 1]
|
||||
{BTA_ID_JV, BTA_APP_ID_1, 2}, /* app BTA_JV_PM_ID_1, reuse ftc spec table */
|
||||
{BTA_ID_JV, BTA_ALL_APP_ID, 3}, /* reuse fts spec table */
|
||||
{BTA_ID_HS, BTA_ALL_APP_ID, 4}, /* HS spec table */
|
||||
{BTA_ID_AVK, BTA_ALL_APP_ID, 5} /* avk spec table */
|
||||
{BTA_ID_AVK, BTA_ALL_APP_ID, 5}, /* avk spec table */
|
||||
{BTA_ID_HD, BTA_ALL_APP_ID, 6}, /* hd spec table */
|
||||
{BTA_ID_HH, BTA_ALL_APP_ID, 7} /* hh spec table */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
, {BTA_ID_GATTC, BTA_ALL_APP_ID, 6} /* gattc spec table */
|
||||
, {BTA_ID_GATTS, BTA_ALL_APP_ID, 7} /* gatts spec table */
|
||||
, {BTA_ID_GATTC, BTA_ALL_APP_ID, 8} /* gattc spec table */
|
||||
, {BTA_ID_GATTS, BTA_ALL_APP_ID, 9} /* gatts spec table */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -254,10 +256,48 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HD : 6 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR3), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HH : 7 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR1), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close, used for HH suspend */
|
||||
{{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* GATTC : 6 */
|
||||
/* GATTC : 8 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
@ -278,7 +318,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
{{BTA_DM_PM_RETRY, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
/* GATTS : 7 */
|
||||
/* GATTS : 9 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
@ -372,7 +412,7 @@ tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] = {
|
||||
seting default max latency and min remote timeout as 0,
|
||||
and always read individual device preference from HH module */
|
||||
{1200, 2, 2}, /* BTA_DM_PM_SSR2 - others (as long as sniff is allowed)*/
|
||||
{360, 160, 2} /* BTA_DM_PM_SSR3 - HD */
|
||||
{360, 160, 1600} /* BTA_DM_PM_SSR3 - HD */
|
||||
};
|
||||
|
||||
tBTA_DM_SSR_SPEC *const p_bta_dm_ssr_spec = (tBTA_DM_SSR_SPEC *) &bta_dm_ssr_spec;
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
|
||||
#include "bta/bta_gatt_api.h"
|
||||
#endif
|
||||
@ -1596,6 +1597,11 @@ extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_confirm(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_key_req(tBTA_DM_MSG *p_data);
|
||||
|
||||
#if (BTA_HD_INCLUDED == TRUE)
|
||||
extern BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr);
|
||||
#endif /* BTA_HD_INCLUDED */
|
||||
|
||||
#if (BTM_OOB_INCLUDED == TRUE)
|
||||
extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_oob_reply(tBTA_DM_MSG *p_data);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "gatt_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/mutex.h"
|
||||
#include "bta_hh_int.h"
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
#include "bta_hh_int.h"
|
||||
@ -304,7 +305,10 @@ void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg)
|
||||
bta_gattc_deregister_cmpl(p_clreg);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
|
||||
APPL_TRACE_ERROR("Deregister Failed unknown client cif");
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
bta_hh_cleanup_disable(BTA_HH_OK);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
|
774
components/bt/host/bluedroid/bta/hd/bta_hd_act.c
Normal file
774
components/bt/host/bluedroid/bta/hd/bta_hd_act.c
Normal file
@ -0,0 +1,774 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID device action functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
|
||||
|
||||
#include "bta/bta_sys.h"
|
||||
#include "bta_hd_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/osi.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include <string.h>
|
||||
|
||||
static void bta_hd_cback(BD_ADDR bd_addr, uint8_t event, uint32_t data, BT_HDR *pdata);
|
||||
|
||||
static bool check_descriptor(uint8_t *data, uint16_t length, bool *has_report_id)
|
||||
{
|
||||
uint8_t *ptr = data;
|
||||
*has_report_id = FALSE;
|
||||
while (ptr < data + length) {
|
||||
uint8_t item = *ptr++;
|
||||
switch (item) {
|
||||
case 0xfe: // long item indicator
|
||||
if (ptr < data + length) {
|
||||
ptr += ((*ptr) + 2);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 0x85: // Report ID
|
||||
*has_report_id = TRUE;
|
||||
default:
|
||||
ptr += (item & 0x03);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (ptr == data + length);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_api_enable
|
||||
*
|
||||
* Description Enables HID device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_api_enable(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_STATUS status = BTA_HD_ERROR;
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevInit();
|
||||
|
||||
memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
|
||||
|
||||
HID_DevSetSecurityLevel(BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
|
||||
/* store parameters */
|
||||
bta_hd_cb.p_cback = p_data->api_enable.p_cback;
|
||||
|
||||
ret = HID_DevRegister(bta_hd_cback);
|
||||
if (ret == HID_SUCCESS) {
|
||||
status = BTA_HD_OK;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s: Failed to register HID device (%d)", __func__, ret);
|
||||
}
|
||||
|
||||
/* signal BTA call back event */
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_ENABLE_EVT, (tBTA_HD *)&status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_api_disable
|
||||
*
|
||||
* Description Disables HID device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_api_disable(void)
|
||||
{
|
||||
tBTA_HD_STATUS status = BTA_HD_ERROR;
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
/* service is not enabled */
|
||||
if (bta_hd_cb.p_cback == NULL)
|
||||
return;
|
||||
|
||||
/* Remove service record */
|
||||
if (bta_hd_cb.sdp_handle != 0) {
|
||||
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
|
||||
bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
|
||||
}
|
||||
|
||||
/* Deregister with lower layer */
|
||||
ret = HID_DevDeregister();
|
||||
if (ret == HID_SUCCESS) {
|
||||
status = BTA_HD_OK;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s: Failed to deregister HID device (%d)", __func__, ret);
|
||||
}
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_DISABLE_EVT, (tBTA_HD *)&status);
|
||||
|
||||
memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_register_act
|
||||
*
|
||||
* Description Registers SDP record
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_register_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD ret;
|
||||
tBTA_HD_REGISTER_APP *p_app_data = (tBTA_HD_REGISTER_APP *)p_data;
|
||||
bool use_report_id = FALSE;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
ret.reg_status.in_use = FALSE;
|
||||
|
||||
/* Check if len doesn't exceed BTA_HD_APP_DESCRIPTOR_LEN and descriptor
|
||||
* itself is well-formed. Also check if descriptor has Report Id item so we
|
||||
* know if report will have prefix or not. */
|
||||
if (p_app_data->d_len > BTA_HD_APP_DESCRIPTOR_LEN ||
|
||||
!check_descriptor(p_app_data->d_data, p_app_data->d_len, &use_report_id)) {
|
||||
APPL_TRACE_ERROR("%s: Descriptor is too long or malformed", __func__);
|
||||
ret.reg_status.status = BTA_HD_ERROR;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret.reg_status.status = BTA_HD_OK;
|
||||
|
||||
/* Remove old record if for some reason it's already registered */
|
||||
if (bta_hd_cb.sdp_handle != 0) {
|
||||
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
|
||||
}
|
||||
|
||||
bta_hd_cb.use_report_id = use_report_id;
|
||||
bta_hd_cb.sdp_handle = SDP_CreateRecord();
|
||||
HID_DevAddRecord(bta_hd_cb.sdp_handle, p_app_data->name, p_app_data->description, p_app_data->provider,
|
||||
p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
|
||||
bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
|
||||
|
||||
HID_DevSetIncomingQos(p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
|
||||
p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
|
||||
p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);
|
||||
|
||||
HID_DevSetOutgoingQos(p_app_data->out_qos.service_type, p_app_data->out_qos.token_rate,
|
||||
p_app_data->out_qos.token_bucket_size, p_app_data->out_qos.peak_bandwidth,
|
||||
p_app_data->out_qos.access_latency, p_app_data->out_qos.delay_variation);
|
||||
|
||||
// application is registered so we can accept incoming connections
|
||||
HID_DevSetIncomingPolicy(TRUE);
|
||||
|
||||
if (HID_DevGetDevice(&ret.reg_status.bda) == HID_SUCCESS) {
|
||||
ret.reg_status.in_use = TRUE;
|
||||
}
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_unregister_act
|
||||
*
|
||||
* Description Unregisters SDP record
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_unregister_act(UNUSED_ATTR tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_STATUS status = BTA_HD_OK;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
// application is no longer registered so we do not want incoming connections
|
||||
HID_DevSetIncomingPolicy(FALSE);
|
||||
|
||||
if (bta_hd_cb.sdp_handle != 0) {
|
||||
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
|
||||
}
|
||||
|
||||
bta_hd_cb.sdp_handle = 0;
|
||||
bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_UNREGISTER_APP_EVT, (tBTA_HD *)&status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_unregister2_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_unregister2_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
// close first
|
||||
bta_hd_close_act(p_data);
|
||||
|
||||
// then unregister
|
||||
bta_hd_unregister_act(p_data);
|
||||
|
||||
if (bta_hd_cb.disable_w4_close) {
|
||||
bta_hd_api_disable();
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_connect_act
|
||||
*
|
||||
* Description Connect to device (must be virtually plugged)
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_connect_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS ret;
|
||||
tBTA_HD_DEVICE_CTRL *p_ctrl = (tBTA_HD_DEVICE_CTRL *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
do {
|
||||
ret = HID_DevPlugDevice(p_ctrl->addr);
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevPlugDevice returned %d", __func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = HID_DevConnect();
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevConnect returned %d", __func__, ret);
|
||||
return;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_ctrl->addr);
|
||||
cback_data.conn.status = (ret == HID_SUCCESS ? BTA_HD_OK : BTA_HD_ERROR);
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_CONNECTING;
|
||||
bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_disconnect_act
|
||||
*
|
||||
* Description Disconnect from device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_disconnect_act(UNUSED_ATTR tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS ret;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
ret = HID_DevDisconnect();
|
||||
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevDisconnect returned %d", __func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HID_DevGetDevice(&cback_data.conn.bda) == HID_SUCCESS) {
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTING;
|
||||
bta_hd_cb.p_cback(BTA_HD_CLOSE_EVT, &cback_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_add_device_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_add_device_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_ctrl = (tBTA_HD_DEVICE_CTRL *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevPlugDevice(p_ctrl->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_remove_device_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_remove_device_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_ctrl = (tBTA_HD_DEVICE_CTRL *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevUnplugDevice(p_ctrl->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_send_report_act
|
||||
*
|
||||
* Description Sends report
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_send_report_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_SEND_REPORT *p_report = (tBTA_HD_SEND_REPORT *)p_data;
|
||||
uint8_t channel;
|
||||
uint8_t report_id;
|
||||
tBTA_HD cback_data;
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_VERBOSE("%s", __func__);
|
||||
|
||||
channel = p_report->use_intr ? HID_CHANNEL_INTR : HID_CHANNEL_CTRL;
|
||||
report_id = (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) ? p_report->id : 0x00;
|
||||
|
||||
ret = HID_DevSendReport(channel, p_report->type, report_id, p_report->len, p_report->data);
|
||||
|
||||
/* trigger PM */
|
||||
bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
|
||||
cback_data.send_report.status = (ret == HID_SUCCESS ? BTA_HD_OK : BTA_HD_ERROR);
|
||||
cback_data.send_report.reason = ret;
|
||||
cback_data.send_report.report_id = report_id;
|
||||
cback_data.send_report.report_type = p_report->type;
|
||||
bta_hd_cb.p_cback(BTA_HD_SEND_REPORT_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_report_error_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_report_error_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_REPORT_ERR *p_report = (tBTA_HD_REPORT_ERR *)p_data;
|
||||
tHID_STATUS ret;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s: error = %d", __func__, p_report->error);
|
||||
|
||||
ret = HID_DevReportError(p_report->error);
|
||||
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevReportError returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
cback_data.report_err.status = (ret == HID_SUCCESS ? BTA_HD_OK : BTA_HD_ERROR);
|
||||
cback_data.report_err.reason = ret;
|
||||
bta_hd_cb.p_cback(BTA_HD_REPORT_ERR_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_vc_unplug_act
|
||||
*
|
||||
* Description Sends Virtual Cable Unplug
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_vc_unplug_act(UNUSED_ATTR tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_hd_cb.vc_unplug = TRUE;
|
||||
ret = HID_DevVirtualCableUnplug();
|
||||
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevVirtualCableUnplug returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
/* trigger PM */
|
||||
bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_open_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_open_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevPlugDevice(p_cback->addr);
|
||||
bta_sys_conn_open(BTA_ID_HD, 1, p_cback->addr);
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_cback->addr);
|
||||
bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_CONNECTED;
|
||||
bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_close_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_close_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
tBTA_HD_EVT cback_event = BTA_HD_CLOSE_EVT;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
|
||||
|
||||
if (bta_hd_cb.vc_unplug) {
|
||||
bta_hd_cb.vc_unplug = FALSE;
|
||||
HID_DevUnplugDevice(p_cback->addr);
|
||||
cback_event = BTA_HD_VC_UNPLUG_EVT;
|
||||
}
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_cback->addr);
|
||||
memset(bta_hd_cb.bd_addr, 0, sizeof(BD_ADDR));
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
|
||||
bta_hd_cb.p_cback(cback_event, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_intr_data_act
|
||||
*
|
||||
* Description Handles incoming DATA request on intr
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_intr_data_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
BT_HDR *p_msg = p_cback->p_data;
|
||||
uint16_t len = p_msg->len;
|
||||
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
|
||||
tBTA_HD_INTR_DATA ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
|
||||
ret.report_id = *p_buf;
|
||||
len--;
|
||||
p_buf++;
|
||||
} else {
|
||||
ret.report_id = 0;
|
||||
}
|
||||
|
||||
ret.len = len;
|
||||
ret.p_data = p_buf;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_INTR_DATA_EVT, (tBTA_HD *)&ret);
|
||||
if (p_msg) {
|
||||
osi_free(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_get_report_act
|
||||
*
|
||||
* Description Handles incoming GET_REPORT request
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_get_report_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
bool rep_size_follows = p_cback->data;
|
||||
BT_HDR *p_msg = p_cback->p_data;
|
||||
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
|
||||
tBTA_HD_GET_REPORT ret = {0, 0, 0};
|
||||
uint16_t remaining_len = p_msg->len;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if (remaining_len < 1) {
|
||||
APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
|
||||
return;
|
||||
}
|
||||
|
||||
ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
|
||||
p_buf++;
|
||||
remaining_len--;
|
||||
|
||||
if (bta_hd_cb.use_report_id) {
|
||||
if (remaining_len < 1) {
|
||||
APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
|
||||
return;
|
||||
}
|
||||
ret.report_id = *p_buf;
|
||||
p_buf++;
|
||||
remaining_len--;
|
||||
}
|
||||
|
||||
if (rep_size_follows) {
|
||||
if (remaining_len < 2) {
|
||||
APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
|
||||
return;
|
||||
}
|
||||
ret.buffer_size = *p_buf | (*(p_buf + 1) << 8);
|
||||
}
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_GET_REPORT_EVT, (tBTA_HD *)&ret);
|
||||
if (p_msg) {
|
||||
osi_free(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_set_report_act
|
||||
*
|
||||
* Description Handles incoming SET_REPORT request
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
BT_HDR *p_msg = p_cback->p_data;
|
||||
uint16_t len = p_msg->len;
|
||||
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
|
||||
tBTA_HD_SET_REPORT ret = {0, 0, 0, NULL};
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
|
||||
p_buf++;
|
||||
len--;
|
||||
|
||||
if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
|
||||
ret.report_id = *p_buf;
|
||||
len--;
|
||||
p_buf++;
|
||||
} else {
|
||||
ret.report_id = 0;
|
||||
}
|
||||
|
||||
ret.len = len;
|
||||
ret.p_data = p_buf;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_SET_REPORT_EVT, (tBTA_HD *)&ret);
|
||||
if (p_msg) {
|
||||
osi_free(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_set_protocol_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_hd_cb.boot_mode = (p_cback->data == HID_PAR_PROTOCOL_BOOT_MODE);
|
||||
cback_data.set_protocol = p_cback->data;
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_SET_PROTOCOL_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_vc_unplug_done_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
|
||||
|
||||
HID_DevUnplugDevice(p_cback->addr);
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_cback->addr);
|
||||
bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_VC_UNPLUG_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_suspend_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_exit_suspend_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_busy(BTA_ID_HD, 1, p_cback->addr);
|
||||
bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_cback
|
||||
*
|
||||
* Description BTA HD callback function
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void bta_hd_cback(BD_ADDR bd_addr, uint8_t event, uint32_t data, BT_HDR *pdata)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_buf = NULL;
|
||||
uint16_t sm_event = BTA_HD_INVALID_EVT;
|
||||
|
||||
APPL_TRACE_API("%s: event=%d", __func__, event);
|
||||
|
||||
switch (event) {
|
||||
case HID_DHOST_EVT_OPEN:
|
||||
sm_event = BTA_HD_INT_OPEN_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_CLOSE:
|
||||
sm_event = BTA_HD_INT_CLOSE_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_GET_REPORT:
|
||||
sm_event = BTA_HD_INT_GET_REPORT_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_SET_REPORT:
|
||||
sm_event = BTA_HD_INT_SET_REPORT_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_SET_PROTOCOL:
|
||||
sm_event = BTA_HD_INT_SET_PROTOCOL_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_INTR_DATA:
|
||||
sm_event = BTA_HD_INT_INTR_DATA_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_VC_UNPLUG:
|
||||
sm_event = BTA_HD_INT_VC_UNPLUG_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_SUSPEND:
|
||||
sm_event = BTA_HD_INT_SUSPEND_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_EXIT_SUSPEND:
|
||||
sm_event = BTA_HD_INT_EXIT_SUSPEND_EVT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sm_event != BTA_HD_INVALID_EVT &&
|
||||
(p_buf = (tBTA_HD_CBACK_DATA *)osi_malloc(sizeof(tBTA_HD_CBACK_DATA) + sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->hdr.event = sm_event;
|
||||
bdcpy(p_buf->addr, bd_addr);
|
||||
p_buf->data = data;
|
||||
p_buf->p_data = pdata;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED */
|
287
components/bt/host/bluedroid/bta/hd/bta_hd_api.c
Normal file
287
components/bt/host/bluedroid/bta/hd/bta_hd_api.c
Normal file
@ -0,0 +1,287 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID DEVICE API in the subsystem of BTA.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
|
||||
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "bta_hd_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Constants
|
||||
****************************************************************************/
|
||||
static const tBTA_SYS_REG bta_hd_reg = {bta_hd_hdl_event, BTA_HdDisable};
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdEnable
|
||||
*
|
||||
* Description Enables HID device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void BTA_HdEnable(tBTA_HD_CBACK *p_cback)
|
||||
{
|
||||
tBTA_HD_API_ENABLE *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
bta_sys_register(BTA_ID_HD, &bta_hd_reg);
|
||||
p_buf = (tBTA_HD_API_ENABLE *)osi_malloc((uint16_t)sizeof(tBTA_HD_API_ENABLE));
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HD_API_ENABLE));
|
||||
p_buf->hdr.event = BTA_HD_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdDisable
|
||||
*
|
||||
* Description Disables HID device.
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void BTA_HdDisable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
bta_sys_deregister(BTA_ID_HD);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdRegisterApp
|
||||
*
|
||||
* Description This function is called when application should be
|
||||
*registered
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdRegisterApp(tBTA_HD_APP_INFO *p_app_info, tBTA_HD_QOS_INFO *p_in_qos, tBTA_HD_QOS_INFO *p_out_qos)
|
||||
{
|
||||
tBTA_HD_REGISTER_APP *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_REGISTER_APP *)osi_malloc(sizeof(tBTA_HD_REGISTER_APP))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_REGISTER_APP_EVT;
|
||||
if (p_app_info->p_name) {
|
||||
strncpy(p_buf->name, p_app_info->p_name, BTA_HD_APP_NAME_LEN);
|
||||
p_buf->name[BTA_HD_APP_NAME_LEN] = '\0';
|
||||
} else {
|
||||
p_buf->name[0] = '\0';
|
||||
}
|
||||
if (p_app_info->p_description) {
|
||||
strncpy(p_buf->description, p_app_info->p_description, BTA_HD_APP_DESCRIPTION_LEN);
|
||||
p_buf->description[BTA_HD_APP_DESCRIPTION_LEN] = '\0';
|
||||
} else {
|
||||
p_buf->description[0] = '\0';
|
||||
}
|
||||
if (p_app_info->p_provider) {
|
||||
strncpy(p_buf->provider, p_app_info->p_provider, BTA_HD_APP_PROVIDER_LEN);
|
||||
p_buf->provider[BTA_HD_APP_PROVIDER_LEN] = '\0';
|
||||
} else {
|
||||
p_buf->provider[0] = '\0';
|
||||
}
|
||||
p_buf->subclass = p_app_info->subclass;
|
||||
p_buf->d_len = p_app_info->descriptor.dl_len;
|
||||
memcpy(p_buf->d_data, p_app_info->descriptor.dsc_list, p_app_info->descriptor.dl_len);
|
||||
// copy qos data as-is
|
||||
memcpy(&p_buf->in_qos, p_in_qos, sizeof(tBTA_HD_QOS_INFO));
|
||||
memcpy(&p_buf->out_qos, p_out_qos, sizeof(tBTA_HD_QOS_INFO));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdUnregisterApp
|
||||
*
|
||||
* Description This function is called when application should be
|
||||
*unregistered
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdUnregisterApp(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_UNREGISTER_APP_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdSendReport
|
||||
*
|
||||
* Description This function is called when report is to be sent
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdSendReport(tBTA_HD_REPORT *p_report)
|
||||
{
|
||||
tBTA_HD_SEND_REPORT *p_buf;
|
||||
APPL_TRACE_VERBOSE("%s", __func__);
|
||||
if (p_report->len > BTA_HD_REPORT_LEN) {
|
||||
APPL_TRACE_WARNING("%s, report len (%d) > MTU len (%d), can't send report."
|
||||
" Increase value of HID_DEV_MTU_SIZE to send larger reports",
|
||||
__func__, p_report->len, BTA_HD_REPORT_LEN);
|
||||
return;
|
||||
}
|
||||
if ((p_buf = (tBTA_HD_SEND_REPORT *)osi_malloc(sizeof(tBTA_HD_SEND_REPORT))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_SEND_REPORT_EVT;
|
||||
p_buf->use_intr = p_report->use_intr;
|
||||
p_buf->type = p_report->type;
|
||||
p_buf->id = p_report->id;
|
||||
p_buf->len = p_report->len;
|
||||
memcpy(p_buf->data, p_report->p_data, p_report->len);
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdVirtualCableUnplug
|
||||
*
|
||||
* Description This function is called when VCU shall be sent
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdVirtualCableUnplug(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_VC_UNPLUG_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdConnect
|
||||
*
|
||||
* Description This function is called when connection to host shall be
|
||||
* made
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdConnect(BD_ADDR addr)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
if ((p_buf = (tBTA_HD_DEVICE_CTRL *)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_CONNECT_EVT;
|
||||
memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdDisconnect
|
||||
*
|
||||
* Description This function is called when host shall be disconnected
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdDisconnect(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_DISCONNECT_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdAddDevice
|
||||
*
|
||||
* Description This function is called when a device is virtually cabled
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdAddDevice(BD_ADDR addr)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_DEVICE_CTRL *)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_ADD_DEVICE_EVT;
|
||||
memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdRemoveDevice
|
||||
*
|
||||
* Description This function is called when a device is virtually uncabled
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdRemoveDevice(BD_ADDR addr)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_DEVICE_CTRL *)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_REMOVE_DEVICE_EVT;
|
||||
memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdReportError
|
||||
*
|
||||
* Description This function is called when reporting error for set report
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdReportError(uint8_t error)
|
||||
{
|
||||
tBTA_HD_REPORT_ERR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_REPORT_ERR *)osi_malloc(sizeof(tBTA_HD_REPORT_ERR))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_REPORT_ERROR_EVT;
|
||||
p_buf->error = error;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED */
|
320
components/bt/host/bluedroid/bta/hd/bta_hd_main.c
Normal file
320
components/bt/host/bluedroid/bta/hd/bta_hd_main.c
Normal file
@ -0,0 +1,320 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID host main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
|
||||
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "bta_hd_int.h"
|
||||
#include <string.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Constants and types
|
||||
****************************************************************************/
|
||||
/* state machine states */
|
||||
enum {
|
||||
BTA_HD_INIT_ST,
|
||||
BTA_HD_IDLE_ST, /* not connected, waiting for connection */
|
||||
BTA_HD_CONN_ST, /* host connected */
|
||||
BTA_HD_TRANSIENT_TO_INIT_ST, /* transient state: going back from CONN to INIT */
|
||||
};
|
||||
typedef uint8_t tBTA_HD_STATE;
|
||||
|
||||
/* state machine actions */
|
||||
enum {
|
||||
BTA_HD_REGISTER_ACT,
|
||||
BTA_HD_UNREGISTER_ACT,
|
||||
BTA_HD_UNREGISTER2_ACT,
|
||||
BTA_HD_CONNECT_ACT,
|
||||
BTA_HD_DISCONNECT_ACT,
|
||||
BTA_HD_ADD_DEVICE_ACT,
|
||||
BTA_HD_REMOVE_DEVICE_ACT,
|
||||
BTA_HD_SEND_REPORT_ACT,
|
||||
BTA_HD_REPORT_ERROR_ACT,
|
||||
BTA_HD_VC_UNPLUG_ACT,
|
||||
BTA_HD_OPEN_ACT,
|
||||
BTA_HD_CLOSE_ACT,
|
||||
BTA_HD_INTR_DATA_ACT,
|
||||
BTA_HD_GET_REPORT_ACT,
|
||||
BTA_HD_SET_REPORT_ACT,
|
||||
BTA_HD_SET_PROTOCOL_ACT,
|
||||
BTA_HD_VC_UNPLUG_DONE_ACT,
|
||||
BTA_HD_SUSPEND_ACT,
|
||||
BTA_HD_EXIT_SUSPEND_ACT,
|
||||
BTA_HD_NUM_ACTIONS
|
||||
};
|
||||
|
||||
#define BTA_HD_IGNORE BTA_HD_NUM_ACTIONS
|
||||
|
||||
typedef void (*tBTA_HD_ACTION)(tBTA_HD_DATA *p_data);
|
||||
/* action functions */
|
||||
const tBTA_HD_ACTION bta_hd_action[] = {
|
||||
bta_hd_register_act, bta_hd_unregister_act, bta_hd_unregister2_act, bta_hd_connect_act,
|
||||
bta_hd_disconnect_act, bta_hd_add_device_act, bta_hd_remove_device_act, bta_hd_send_report_act,
|
||||
bta_hd_report_error_act, bta_hd_vc_unplug_act, bta_hd_open_act, bta_hd_close_act,
|
||||
bta_hd_intr_data_act, bta_hd_get_report_act, bta_hd_set_report_act, bta_hd_set_protocol_act,
|
||||
bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act,
|
||||
};
|
||||
|
||||
/* state table information */
|
||||
#define BTA_HD_ACTION 0 /* position of action */
|
||||
#define BTA_HD_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_HD_NUM_COLS 2 /* number of columns */
|
||||
|
||||
const uint8_t bta_hd_st_init[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state
|
||||
*/
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_REGISTER_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
};
|
||||
|
||||
const uint8_t bta_hd_st_idle[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state
|
||||
*/
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_UNREGISTER_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_CONNECT_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_OPEN_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
};
|
||||
|
||||
const uint8_t bta_hd_st_conn[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_REPORT_ERROR_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_CLOSE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_INTR_DATA_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_GET_REPORT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_SET_REPORT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_SET_PROTOCOL_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_DONE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_SUSPEND_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_EXIT_SUSPEND_ACT, BTA_HD_CONN_ST},
|
||||
};
|
||||
|
||||
const uint8_t bta_hd_st_transient_to_init[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_UNREGISTER2_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_UNREGISTER2_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
};
|
||||
|
||||
/* type for state table */
|
||||
typedef const uint8_t (*tBTA_HD_ST_TBL)[BTA_HD_NUM_COLS];
|
||||
/* state table */
|
||||
const tBTA_HD_ST_TBL bta_hd_st_tbl[] = {bta_hd_st_init, bta_hd_st_idle, bta_hd_st_conn, bta_hd_st_transient_to_init};
|
||||
|
||||
/*****************************************************************************
|
||||
* Global data
|
||||
****************************************************************************/
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_HD_CB bta_hd_cb;
|
||||
#else
|
||||
tBTA_HD_CB *bta_hd_cb_ptr;
|
||||
#endif
|
||||
|
||||
static const char *bta_hd_evt_code(tBTA_HD_INT_EVT evt_code);
|
||||
static const char *bta_hd_state_code(tBTA_HD_STATE state_code);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_sm_execute
|
||||
*
|
||||
* Description State machine event handling function for HID Device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_sm_execute(uint16_t event, tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_ST_TBL state_table;
|
||||
tBTA_HD_STATE prev_state;
|
||||
uint8_t action;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_EVENT("%s: state=%s (%d) event=%s (%d)", __func__, bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state,
|
||||
bta_hd_evt_code(event), event);
|
||||
|
||||
prev_state = bta_hd_cb.state;
|
||||
memset(&cback_data, 0, sizeof(tBTA_HD));
|
||||
state_table = bta_hd_st_tbl[bta_hd_cb.state];
|
||||
event &= 0xff;
|
||||
|
||||
if ((action = state_table[event][BTA_HD_ACTION]) < BTA_HD_IGNORE) {
|
||||
(*bta_hd_action[action])(p_data);
|
||||
}
|
||||
|
||||
bta_hd_cb.state = state_table[event][BTA_HD_NEXT_STATE];
|
||||
|
||||
if (bta_hd_cb.state != prev_state) {
|
||||
APPL_TRACE_EVENT("%s: [new] state=%s (%d)", __func__, bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_hdl_event
|
||||
*
|
||||
* Description HID device main event handling function.
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
bool bta_hd_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
APPL_TRACE_API("%s: p_msg->event=%d", __func__, p_msg->event);
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTA_HD_API_ENABLE_EVT:
|
||||
bta_hd_api_enable((tBTA_HD_DATA *)p_msg);
|
||||
break;
|
||||
case BTA_HD_API_DISABLE_EVT:
|
||||
if (bta_hd_cb.state == BTA_HD_CONN_ST) {
|
||||
APPL_TRACE_WARNING("%s: host connected, disconnect before disabling", __func__);
|
||||
// unregister (and disconnect)
|
||||
bta_hd_cb.disable_w4_close = TRUE;
|
||||
bta_hd_sm_execute(BTA_HD_API_UNREGISTER_APP_EVT, (tBTA_HD_DATA *)p_msg);
|
||||
} else {
|
||||
bta_hd_api_disable();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bta_hd_sm_execute(p_msg->event, (tBTA_HD_DATA *)p_msg);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static const char *bta_hd_evt_code(tBTA_HD_INT_EVT evt_code)
|
||||
{
|
||||
switch (evt_code) {
|
||||
case BTA_HD_API_REGISTER_APP_EVT:
|
||||
return "BTA_HD_API_REGISTER_APP_EVT";
|
||||
case BTA_HD_API_UNREGISTER_APP_EVT:
|
||||
return "BTA_HD_API_UNREGISTER_APP_EVT";
|
||||
case BTA_HD_API_CONNECT_EVT:
|
||||
return "BTA_HD_API_CONNECT_EVT";
|
||||
case BTA_HD_API_DISCONNECT_EVT:
|
||||
return "BTA_HD_API_DISCONNECT_EVT";
|
||||
case BTA_HD_API_ADD_DEVICE_EVT:
|
||||
return "BTA_HD_API_ADD_DEVICE_EVT";
|
||||
case BTA_HD_API_REMOVE_DEVICE_EVT:
|
||||
return "BTA_HD_API_REMOVE_DEVICE_EVT";
|
||||
case BTA_HD_API_SEND_REPORT_EVT:
|
||||
return "BTA_HD_API_SEND_REPORT_EVT";
|
||||
case BTA_HD_API_REPORT_ERROR_EVT:
|
||||
return "BTA_HD_API_REPORT_ERROR_EVT";
|
||||
case BTA_HD_API_VC_UNPLUG_EVT:
|
||||
return "BTA_HD_API_VC_UNPLUG_EVT";
|
||||
case BTA_HD_INT_OPEN_EVT:
|
||||
return "BTA_HD_INT_OPEN_EVT";
|
||||
case BTA_HD_INT_CLOSE_EVT:
|
||||
return "BTA_HD_INT_CLOSE_EVT";
|
||||
case BTA_HD_INT_INTR_DATA_EVT:
|
||||
return "BTA_HD_INT_INTR_DATA_EVT";
|
||||
case BTA_HD_INT_GET_REPORT_EVT:
|
||||
return "BTA_HD_INT_GET_REPORT_EVT";
|
||||
case BTA_HD_INT_SET_REPORT_EVT:
|
||||
return "BTA_HD_INT_SET_REPORT_EVT";
|
||||
case BTA_HD_INT_SET_PROTOCOL_EVT:
|
||||
return "BTA_HD_INT_SET_PROTOCOL_EVT";
|
||||
case BTA_HD_INT_VC_UNPLUG_EVT:
|
||||
return "BTA_HD_INT_VC_UNPLUG_EVT";
|
||||
case BTA_HD_INT_SUSPEND_EVT:
|
||||
return "BTA_HD_INT_SUSPEND_EVT";
|
||||
case BTA_HD_INT_EXIT_SUSPEND_EVT:
|
||||
return "BTA_HD_INT_EXIT_SUSPEND_EVT";
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *bta_hd_state_code(tBTA_HD_STATE state_code)
|
||||
{
|
||||
switch (state_code) {
|
||||
case BTA_HD_INIT_ST:
|
||||
return "BTA_HD_INIT_ST";
|
||||
case BTA_HD_IDLE_ST:
|
||||
return "BTA_HD_IDLE_ST";
|
||||
case BTA_HD_CONN_ST:
|
||||
return "BTA_HD_CONN_ST";
|
||||
case BTA_HD_TRANSIENT_TO_INIT_ST:
|
||||
return "BTA_HD_TRANSIENT_TO_INIT_ST";
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED */
|
168
components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h
Normal file
168
components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h
Normal file
@ -0,0 +1,168 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains BTA HID Device internal definitions
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_HD_INT_H
|
||||
#define BTA_HD_INT_H
|
||||
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#include "stack/hiddefs.h"
|
||||
|
||||
enum {
|
||||
BTA_HD_API_REGISTER_APP_EVT = BTA_SYS_EVT_START(BTA_ID_HD),
|
||||
BTA_HD_API_UNREGISTER_APP_EVT,
|
||||
BTA_HD_API_CONNECT_EVT,
|
||||
BTA_HD_API_DISCONNECT_EVT,
|
||||
BTA_HD_API_ADD_DEVICE_EVT,
|
||||
BTA_HD_API_REMOVE_DEVICE_EVT,
|
||||
BTA_HD_API_SEND_REPORT_EVT,
|
||||
BTA_HD_API_REPORT_ERROR_EVT,
|
||||
BTA_HD_API_VC_UNPLUG_EVT,
|
||||
BTA_HD_INT_OPEN_EVT,
|
||||
BTA_HD_INT_CLOSE_EVT,
|
||||
BTA_HD_INT_INTR_DATA_EVT,
|
||||
BTA_HD_INT_GET_REPORT_EVT,
|
||||
BTA_HD_INT_SET_REPORT_EVT,
|
||||
BTA_HD_INT_SET_PROTOCOL_EVT,
|
||||
BTA_HD_INT_VC_UNPLUG_EVT,
|
||||
BTA_HD_INT_SUSPEND_EVT,
|
||||
BTA_HD_INT_EXIT_SUSPEND_EVT,
|
||||
/* handled outside state machine */
|
||||
BTA_HD_API_ENABLE_EVT,
|
||||
BTA_HD_API_DISABLE_EVT
|
||||
};
|
||||
typedef uint16_t tBTA_HD_INT_EVT;
|
||||
#define BTA_HD_INVALID_EVT (BTA_HD_API_DISABLE_EVT + 1)
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_HD_CBACK *p_cback;
|
||||
} tBTA_HD_API_ENABLE;
|
||||
#define BTA_HD_APP_NAME_LEN 50
|
||||
#define BTA_HD_APP_DESCRIPTION_LEN 50
|
||||
#define BTA_HD_APP_PROVIDER_LEN 50
|
||||
#define BTA_HD_APP_DESCRIPTOR_LEN 2048
|
||||
#define BTA_HD_STATE_DISABLED 0x00
|
||||
#define BTA_HD_STATE_ENABLED 0x01
|
||||
#define BTA_HD_STATE_IDLE 0x02
|
||||
#define BTA_HD_STATE_CONNECTED 0x03
|
||||
#define BTA_HD_STATE_DISABLING 0x04
|
||||
#define BTA_HD_STATE_REMOVING 0x05
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
char name[BTA_HD_APP_NAME_LEN + 1];
|
||||
char description[BTA_HD_APP_DESCRIPTION_LEN + 1];
|
||||
char provider[BTA_HD_APP_PROVIDER_LEN + 1];
|
||||
uint8_t subclass;
|
||||
uint16_t d_len;
|
||||
uint8_t d_data[BTA_HD_APP_DESCRIPTOR_LEN];
|
||||
tBTA_HD_QOS_INFO in_qos;
|
||||
tBTA_HD_QOS_INFO out_qos;
|
||||
} tBTA_HD_REGISTER_APP;
|
||||
|
||||
#define BTA_HD_REPORT_LEN HID_DEV_MTU_SIZE
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
bool use_intr;
|
||||
uint8_t type;
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
uint8_t data[BTA_HD_REPORT_LEN];
|
||||
} tBTA_HD_SEND_REPORT;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR addr;
|
||||
} tBTA_HD_DEVICE_CTRL;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
uint8_t error;
|
||||
} tBTA_HD_REPORT_ERR;
|
||||
|
||||
/* union of all event data types */
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_HD_API_ENABLE api_enable;
|
||||
tBTA_HD_REGISTER_APP register_app;
|
||||
tBTA_HD_SEND_REPORT send_report;
|
||||
tBTA_HD_DEVICE_CTRL device_ctrl;
|
||||
tBTA_HD_REPORT_ERR report_err;
|
||||
} tBTA_HD_DATA;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR addr;
|
||||
uint32_t data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HD_CBACK_DATA;
|
||||
|
||||
/******************************************************************************
|
||||
* Main Control Block
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
tBTA_HD_CBACK *p_cback;
|
||||
uint32_t sdp_handle;
|
||||
uint8_t trace_level;
|
||||
uint8_t state;
|
||||
BD_ADDR bd_addr;
|
||||
bool use_report_id;
|
||||
bool boot_mode;
|
||||
bool vc_unplug;
|
||||
bool disable_w4_close;
|
||||
} tBTA_HD_CB;
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_HD_CB bta_hd_cb;
|
||||
#else
|
||||
extern tBTA_HD_CB *bta_hd_cb_ptr;
|
||||
#define bta_hd_cb (*bta_hd_cb_ptr)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************/
|
||||
extern bool bta_hd_hdl_event(BT_HDR *p_msg);
|
||||
extern void bta_hd_api_enable(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_api_disable(void);
|
||||
extern void bta_hd_register_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_unregister_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_unregister2_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_connect_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_disconnect_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_add_device_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_remove_device_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_send_report_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_report_error_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_vc_unplug_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_open_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_close_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_intr_data_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_get_report_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data);
|
||||
|
||||
#endif
|
@ -214,7 +214,7 @@ const UINT8 bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
|
||||
/* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
|
||||
/* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
|
||||
/* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
|
||||
/* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
|
||||
/* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
|
||||
/* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||
/* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
|
||||
|
@ -323,6 +323,7 @@ void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
|
||||
p_cb->sec_mask = p_data->api_conn.sec_mask;
|
||||
p_cb->mode = p_data->api_conn.mode;
|
||||
p_cb->new_mode = p_data->api_conn.mode;
|
||||
bta_hh_cb.p_cur = p_cb;
|
||||
|
||||
#if (BTA_HH_LE_INCLUDED == TRUE)
|
||||
@ -451,6 +452,8 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
HID_HostRemoveDev( p_cb->incoming_hid_handle);
|
||||
}
|
||||
conn_dat.status = status;
|
||||
/* check if host initiate the connection*/
|
||||
conn_dat.is_orig = !p_cb->incoming_conn;
|
||||
(* bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn_dat);
|
||||
|
||||
/* move state machine W4_CONN ->IDLE */
|
||||
@ -521,6 +524,8 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
|
||||
memset((void *)&conn, 0, sizeof (tBTA_HH_CONN));
|
||||
conn.handle = dev_handle;
|
||||
/* check if host initiate the connection*/
|
||||
conn.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn.bda, p_cb->addr);
|
||||
|
||||
/* increase connection number */
|
||||
@ -587,6 +592,7 @@ void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
APPL_TRACE_EVENT ("bta_hh_open_act: Device[%d] connected", dev_handle);
|
||||
#endif
|
||||
|
||||
p_cb->incoming_conn = TRUE;
|
||||
/* SDP has been done */
|
||||
if (p_cb->app_id != 0) {
|
||||
bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data);
|
||||
@ -594,7 +600,6 @@ void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
/* app_id == 0 indicates an incoming conenction request arrives without SDP
|
||||
performed, do it first */
|
||||
{
|
||||
p_cb->incoming_conn = TRUE;
|
||||
/* store the handle here in case sdp fails - need to disconnect */
|
||||
p_cb->incoming_hid_handle = dev_handle;
|
||||
|
||||
@ -676,6 +681,11 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
case BTA_HH_SET_IDLE_EVT :
|
||||
cback_data.handle = p_cb->hid_handle;
|
||||
cback_data.status = bta_hh_get_trans_status(p_data->hid_cback.data);
|
||||
if (cback_data.status == BTA_HH_OK) {
|
||||
p_cb->mode = p_cb->new_mode;
|
||||
} else {
|
||||
p_cb->new_mode = p_cb->mode;
|
||||
}
|
||||
(* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&cback_data);
|
||||
p_cb->w4_evt = 0;
|
||||
break;
|
||||
@ -684,6 +694,8 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
case BTA_HH_OPEN_EVT:
|
||||
conn.status = p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK;
|
||||
conn.handle = p_cb->hid_handle;
|
||||
/* check if host initiate the connection*/
|
||||
conn.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn.bda, p_cb->addr);
|
||||
(* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&conn);
|
||||
#if BTA_HH_DEBUG
|
||||
@ -787,6 +799,8 @@ void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
conn_dat.handle = p_cb->hid_handle;
|
||||
conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ?
|
||||
BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
|
||||
/* check if host initiate the connection*/
|
||||
conn_dat.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn_dat.bda, p_cb->addr);
|
||||
HID_HostCloseDev(p_cb->hid_handle);
|
||||
|
||||
@ -836,6 +850,8 @@ void bta_hh_close_act (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
/* Failure in opening connection */
|
||||
conn_dat.handle = p_cb->hid_handle;
|
||||
conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
|
||||
/* check if host initiate the connection*/
|
||||
conn_dat.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn_dat.bda, p_cb->addr);
|
||||
HID_HostCloseDev(p_cb->hid_handle);
|
||||
|
||||
@ -1019,7 +1035,9 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
*******************************************************************************/
|
||||
void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS status;
|
||||
tBTA_HH_CBDATA cbdata = {BTA_HH_OK, 0};
|
||||
tBTA_HH_API_SENDDATA send_data = {BTA_HH_OK, 0, 0};
|
||||
UINT16 event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
|
||||
BTA_HH_FST_TRANS_CB_EVT;
|
||||
|
||||
@ -1031,25 +1049,33 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
{
|
||||
|
||||
cbdata.handle = p_cb->hid_handle;
|
||||
send_data.handle = p_cb->hid_handle;
|
||||
|
||||
/* match up BTE/BTA report/boot mode def */
|
||||
if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL) {
|
||||
p_cb->new_mode = p_data->api_sndcmd.param;
|
||||
p_data->api_sndcmd.param = ( p_data->api_sndcmd.param == BTA_HH_PROTO_RPT_MODE) ? \
|
||||
HID_PAR_PROTOCOL_REPORT : HID_PAR_PROTOCOL_BOOT_MODE;
|
||||
}
|
||||
|
||||
if (HID_HostWriteDev (p_cb->hid_handle,
|
||||
p_data->api_sndcmd.t_type,
|
||||
p_data->api_sndcmd.param,
|
||||
p_data->api_sndcmd.data,
|
||||
p_data->api_sndcmd.rpt_id,
|
||||
p_data->api_sndcmd.p_data) != HID_SUCCESS) {
|
||||
APPL_TRACE_ERROR("HID_HostWriteDev Error ");
|
||||
status = HID_HostWriteDev(p_cb->hid_handle, p_data->api_sndcmd.t_type, p_data->api_sndcmd.param,
|
||||
p_data->api_sndcmd.data, p_data->api_sndcmd.rpt_id, p_data->api_sndcmd.p_data);
|
||||
if (status != HID_SUCCESS) {
|
||||
APPL_TRACE_ERROR("HID_HostWriteDev status:%d", status);
|
||||
cbdata.status = BTA_HH_ERR;
|
||||
send_data.status = BTA_HH_ERR;
|
||||
|
||||
if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL &&
|
||||
p_data->api_sndcmd.t_type != HID_TRANS_DATA) {
|
||||
(* bta_hh_cb.p_cback)(event, (tBTA_HH *)&cbdata);
|
||||
if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
|
||||
switch (p_data->api_sndcmd.t_type) {
|
||||
case HID_TRANS_DATA:
|
||||
event = BTA_HH_DATA_EVT;
|
||||
send_data.reason = status;
|
||||
(*bta_hh_cb.p_cback)(event, (tBTA_HH *)&send_data);
|
||||
break;
|
||||
default:
|
||||
(*bta_hh_cb.p_cback)(event, (tBTA_HH *)&cbdata);
|
||||
break;
|
||||
}
|
||||
} else if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
|
||||
(* bta_hh_cb.p_cback)(BTA_HH_VC_UNPLUG_EVT, (tBTA_HH *)&cbdata);
|
||||
}
|
||||
@ -1070,6 +1096,7 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
p_cb->w4_evt = event;
|
||||
break;
|
||||
case HID_TRANS_DATA: /* output report */
|
||||
(*bta_hh_cb.p_cback)(BTA_HH_DATA_EVT, (tBTA_HH *)&send_data);
|
||||
/* fall through */
|
||||
case HID_TRANS_CONTROL:
|
||||
/* no handshake event will be generated */
|
||||
@ -1098,7 +1125,6 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user