Merge branch 'master' into feature/cmake

This commit is contained in:
Angus Gratton 2018-08-16 15:01:43 +10:00 committed by Angus Gratton
commit ff2404a272
1085 changed files with 86220 additions and 78268 deletions

5
.gitignore vendored
View File

@ -43,6 +43,11 @@ tools/unit-test-app/build
tools/unit-test-app/builds tools/unit-test-app/builds
tools/unit-test-app/output tools/unit-test-app/output
# IDF monitor test
tools/test_idf_monitor/outputs
TEST_LOGS
# AWS IoT Examples require device-specific certs/keys # AWS IoT Examples require device-specific certs/keys
examples/protocols/aws_iot/*/main/certs/*.pem.* examples/protocols/aws_iot/*/main/certs/*.pem.*

View File

@ -1,9 +1,9 @@
stages: stages:
- build - build
- assign_test - assign_test
- host_test
- unit_test - unit_test
- test - integration_test
- test_report
- deploy - deploy
variables: variables:
@ -31,11 +31,25 @@ variables:
APPLY_BOT_FILTER_SCRIPT: "$CI_PROJECT_DIR/tools/ci/apply_bot_filter.py" APPLY_BOT_FILTER_SCRIPT: "$CI_PROJECT_DIR/tools/ci/apply_bot_filter.py"
CHECKOUT_REF_SCRIPT: "$CI_PROJECT_DIR/tools/ci/checkout_project_ref.py" CHECKOUT_REF_SCRIPT: "$CI_PROJECT_DIR/tools/ci/checkout_project_ref.py"
# When 'fetch' strategy is used, Gitlab removes untracked files before checking out
# new revision. However if the new revision doesn't include some of the submodules
# which were present in the old revision, such submodule directories would not be
# removed by the checkout. This extra step ensures that these stale submodules
# are removed.
.git_clean_stale_submodules: &git_clean_stale_submodules >
find . -name '.git' -not -path './.git' -printf '%P\n'
| sed 's|/.git||'
| xargs -I {} sh -c '
grep -q {} .gitmodules
|| (echo "Removing {}, has .git directory but not in .gitmodules file"
&& rm -rf {});'
# before each job, we need to check if this job is filtered by bot stage/job filter # before each job, we need to check if this job is filtered by bot stage/job filter
.apply_bot_filter: &apply_bot_filter .apply_bot_filter: &apply_bot_filter
python $APPLY_BOT_FILTER_SCRIPT || exit 0 python $APPLY_BOT_FILTER_SCRIPT || exit 0
before_script: before_script:
- *git_clean_stale_submodules
# apply bot filter in before script # apply bot filter in before script
- *apply_bot_filter - *apply_bot_filter
# add gitlab ssh key # add gitlab ssh key
@ -56,6 +70,7 @@ before_script:
.do_nothing_before: .do_nothing_before:
before_script: &do_nothing_before before_script: &do_nothing_before
- *git_clean_stale_submodules
# apply bot filter in before script # apply bot filter in before script
- *apply_bot_filter - *apply_bot_filter
- echo "Not setting up GitLab key, not fetching submodules" - echo "Not setting up GitLab key, not fetching submodules"
@ -63,6 +78,7 @@ before_script:
.add_gitlab_key_before: .add_gitlab_key_before:
before_script: &add_gitlab_key_before before_script: &add_gitlab_key_before
- *git_clean_stale_submodules
# apply bot filter in before script # apply bot filter in before script
- *apply_bot_filter - *apply_bot_filter
- echo "Not fetching submodules" - echo "Not fetching submodules"
@ -135,6 +151,8 @@ build_ssc_01:
build_ssc_02: build_ssc_02:
<<: *build_ssc_template <<: *build_ssc_template
# If you want to add new build ssc jobs, please add it into dependencies of `assign_test` and `.test_template`
build_esp_idf_tests: build_esp_idf_tests:
<<: *build_template <<: *build_template
artifacts: artifacts:
@ -142,14 +160,14 @@ build_esp_idf_tests:
- tools/unit-test-app/output - tools/unit-test-app/output
- components/idf_test/unit_test/TestCaseAll.yml - components/idf_test/unit_test/TestCaseAll.yml
- components/idf_test/unit_test/CIConfigs/*.yml - components/idf_test/unit_test/CIConfigs/*.yml
expire_in: 6 mos expire_in: 1 mos
script: script:
- cd tools/unit-test-app - cd tools/unit-test-app
- make help # make sure kconfig tools are built in single process - MAKEFLAGS= make help # make sure kconfig tools are built in single process
- make ut-clean-all-configs - make ut-clean-all-configs
- export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations" - export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations"
- export EXTRA_CXXFLAGS=${EXTRA_CFLAGS} - export EXTRA_CXXFLAGS=${EXTRA_CFLAGS}
- make ut-build-all-configs TESTS_ALL=1 - make ut-build-all-configs
- python tools/UnitTestParser.py - python tools/UnitTestParser.py
.build_examples_template: &build_examples_template .build_examples_template: &build_examples_template
@ -208,6 +226,7 @@ build_examples_06:
build_examples_07: build_examples_07:
<<: *build_examples_template <<: *build_examples_template
# If you want to add new build example jobs, please add it into dependencies of `.example_test_template`
build_docs: build_docs:
stage: build stage: build
@ -246,22 +265,21 @@ verify_cmake_style:
script: script:
tools/cmake/run_cmake_lint.sh tools/cmake/run_cmake_lint.sh
test_nvs_on_host: .host_test_template: &host_test_template
stage: test stage: host_test
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags: tags:
- host_test - host_test
dependencies: [] dependencies: []
test_nvs_on_host:
<<: *host_test_template
script: script:
- cd components/nvs_flash/test_nvs_host - cd components/nvs_flash/test_nvs_host
- make test - make test
test_nvs_coverage: test_nvs_coverage:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
dependencies: []
artifacts: artifacts:
paths: paths:
- components/nvs_flash/test_nvs_host/coverage_report - components/nvs_flash/test_nvs_host/coverage_report
@ -275,52 +293,73 @@ test_nvs_coverage:
- make coverage_report - make coverage_report
test_partition_table_on_host: test_partition_table_on_host:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags: tags:
- build - build
dependencies: []
script: script:
- cd components/partition_table/test_gen_esp32part_host - cd components/partition_table/test_gen_esp32part_host
- ./gen_esp32part_tests.py - ./gen_esp32part_tests.py
test_wl_on_host: test_wl_on_host:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
artifacts: artifacts:
paths: paths:
- components/wear_levelling/test_wl_host/coverage_report.zip - components/wear_levelling/test_wl_host/coverage_report.zip
dependencies: []
script: script:
- cd components/wear_levelling/test_wl_host - cd components/wear_levelling/test_wl_host
- make test - make test
test_multi_heap_on_host: test_fatfs_on_host:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG script:
- cd components/fatfs/test_fatfs_host/
- make test
test_mdns_fuzzer_on_host:
stage: host_test
image: $CI_DOCKER_REGISTRY/afl-fuzzer-test
tags: tags:
- host_test - host_test
dependencies: []
artifacts:
when: always
paths:
- components/mdns/test_afl_fuzz_host/out/crashes
expire_in: 1 mos
only:
# can only be triggered
- triggers
variables:
BOT_NEEDS_TRIGGER_BY_NAME: 1
script:
- export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 && export AFL_SKIP_CPUFREQ=1
- cd components/mdns/test_afl_fuzz_host/
# run AFL fuzzer for one hour
- ( make fuzz || pkill sleep ) &
- ( sleep 3600 || mkdir -p out/crashes/env_failed ) && pkill afl-fuz
# check no crashes found
- "[ -z `ls out/crashes/` ] || exit 1"
test_spiffs_on_host:
<<: *host_test_template
script:
- cd components/spiffs/test_spiffs_host/
- make test
test_multi_heap_on_host:
<<: *host_test_template
script: script:
- cd components/heap/test_multi_heap_host - cd components/heap/test_multi_heap_host
- ./test_all_configs.sh - ./test_all_configs.sh
test_confserver: test_confserver:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
script: script:
- cd tools/kconfig_new/test - cd tools/kconfig_new/test
- ./test_confserver.py - ./test_confserver.py
test_build_system: test_build_system:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
dependencies: []
script: script:
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh - ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- rm -rf test_build_system - rm -rf test_build_system
@ -329,11 +368,7 @@ test_build_system:
- ${IDF_PATH}/tools/ci/test_build_system.sh - ${IDF_PATH}/tools/ci/test_build_system.sh
test_build_system_cmake: test_build_system_cmake:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
dependencies: []
script: script:
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh - ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- rm -rf test_build_system - rm -rf test_build_system
@ -341,73 +376,25 @@ test_build_system_cmake:
- cd test_build_system - cd test_build_system
- ${IDF_PATH}/tools/ci/test_build_system_cmake.sh - ${IDF_PATH}/tools/ci/test_build_system_cmake.sh
test_report: test_idf_monitor:
stage: test_report <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- report
only:
- master
- triggers
- schedules
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
variables:
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report"
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/tools/ModuleDefinition.yml"
#dependencies:
#We need all UT* and IT* artifacts except for only a few other
artifacts: artifacts:
when: always when: on_failure
paths: paths:
- $REPORT_PATH - tools/test_idf_monitor/outputs/*
- $LOG_PATH expire_in: 1 week
expire_in: 12 mos
script: script:
# calc log path - cd ${IDF_PATH}/tools/test_idf_monitor
- VER_NUM=`git rev-list HEAD | wc -l | awk '{print $1}'` - ./run_test_idf_monitor.py
- SHA_ID=`echo $CI_COMMIT_SHA | cut -c 1-7`
- REVISION="${VER_NUM}_${SHA_ID}"
# replace / to _ in branch name
- ESCAPED_BRANCH_NAME=`echo $CI_COMMIT_REF_NAME | sed 's/\//___/g'`
# result path and artifacts path
- RESULT_PATH="$CI_PROJECT_NAME/$ESCAPED_BRANCH_NAME/$REVISION"
- ARTIFACTS_PATH="$GITLAB_HTTP_SERVER/idf/esp-idf/builds/$CI_JOB_ID/artifacts/browse/$CI_COMMIT_SHA"
# clone test bench
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
- cd auto_test_script
- python $CHECKOUT_REF_SCRIPT auto_test_script
# generate report
- TEST_RESULT=Pass
- python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || TEST_RESULT=Fail
# commit to CI-test-result project
- git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git
- rm -rf "CI-test-result/RawData/$RESULT_PATH"
- cp -R $CI_PROJECT_NAME CI-test-result/RawData
- cd CI-test-result
# config git user
- git config --global user.email "ci-test-result@espressif.com"
- git config --global user.name "ci-test-result"
# commit test result
- git add .
- git commit . -m "update test result for $CI_PROJECT_NAME/$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA, pipeline ID $CI_PIPELINE_ID" || exit 0
- git push origin master
- test "${TEST_RESULT}" = "Pass" || exit 1
test_esp_err_to_name_on_host: test_esp_err_to_name_on_host:
stage: test <<: *host_test_template
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- build
dependencies: []
script: script:
- cd tools/ - cd tools/
- ./gen_esp_err_to_name.py - ./gen_esp_err_to_name.py
- git diff --exit-code -- ../components/esp32/esp_err_to_name.c || (echo 'Differences found. Please run gen_esp_err_to_name.py and commit the changes.'; exit 1) - git diff --exit-code -- ../components/esp32/esp_err_to_name.c || (echo 'Differences found. Please run gen_esp_err_to_name.py and commit the changes.'; exit 1)
push_master_to_github: push_to_github:
stage: deploy stage: deploy
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags: tags:
@ -416,11 +403,8 @@ push_master_to_github:
- master - master
- /^release\/v/ - /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/ - /^v\d+\.\d+(\.\d+)?($|-)/
- feature/cmake
when: on_success when: on_success
dependencies: [] dependencies: []
variables:
GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master refs/remotes/origin/feature/cmake
before_script: *do_nothing_before before_script: *do_nothing_before
script: script:
- mkdir -p ~/.ssh - mkdir -p ~/.ssh
@ -431,15 +415,12 @@ push_master_to_github:
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- git remote remove github &>/dev/null || true - git remote remove github &>/dev/null || true
- git remote add github git@github.com:espressif/esp-idf.git - git remote add github git@github.com:espressif/esp-idf.git
# What the next line of script does: goes through the list of refs for all branches we push to github, # Need separate push commands for tag builds and for branch builds
# generates a snippet of shell which is evaluated. The snippet checks CI_COMMIT_SHA against the SHA - "[ -n \"${CI_COMMIT_TAG}\" ] && git push github ${CI_COMMIT_TAG}"
# (aka objectname) at tip of each branch, and if any SHAs match then it checks out the local branch - "[ -z \"${CI_COMMIT_TAG}\" ] && git push github ${CI_COMMIT_SHA}:refs/heads/${CI_COMMIT_REF_NAME}"
# and then pushes that ref to a corresponding github branch
- eval $(git for-each-ref --shell bash --format 'if [ $CI_COMMIT_SHA == %(objectname) ]; then git checkout -B %(refname:strip=3); git push --follow-tags github %(refname:strip=3); fi;' $GITHUB_PUSH_REFS)
deploy_docs: deploy_docs:
stage: assign_test stage: host_test
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags: tags:
- deploy - deploy
@ -474,7 +455,7 @@ deploy_docs:
- echo "[document preview][zh_CN] $CI_DOCKER_REGISTRY/docs/esp-idf/zh_CN/${GIT_VER}/index.html" - echo "[document preview][zh_CN] $CI_DOCKER_REGISTRY/docs/esp-idf/zh_CN/${GIT_VER}/index.html"
check_doc_links: check_doc_links:
stage: test stage: host_test
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags: tags:
- check_doc_links - check_doc_links
@ -493,6 +474,20 @@ check_doc_links:
- cd docs - cd docs
- make linkcheck - make linkcheck
check_line_endings:
stage: deploy
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- build
except:
- master
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
dependencies: []
before_script: *do_nothing_before
script:
- tools/ci/check-line-endings.sh ${IDF_PATH}
check_commit_msg: check_commit_msg:
stage: deploy stage: deploy
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
@ -544,7 +539,7 @@ check_submodule_sync:
assign_test: assign_test:
tags: tags:
- assign_test - assign_test
image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG image: $CI_DOCKER_REGISTRY/ubuntu-test-env
stage: assign_test stage: assign_test
# gitlab ci do not support match job with RegEx or wildcard now in dependencies. # gitlab ci do not support match job with RegEx or wildcard now in dependencies.
# we have a lot build example jobs. now we don't use dependencies, just download all artificats of build stage. # we have a lot build example jobs. now we don't use dependencies, just download all artificats of build stage.
@ -576,7 +571,7 @@ assign_test:
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/integration_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/SSC/ssc_bin - python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/integration_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/SSC/ssc_bin
.example_test_template: &example_test_template .example_test_template: &example_test_template
stage: test stage: integration_test
when: on_success when: on_success
only: only:
- master - master
@ -584,14 +579,21 @@ assign_test:
- /^v\d+\.\d+(\.\d+)?($|-)/ - /^v\d+\.\d+(\.\d+)?($|-)/
- triggers - triggers
- schedules - schedules
# gitlab ci do not support match job with RegEx or wildcard now in dependencies. dependencies:
# we have a lot build example jobs and the binaries them exceed the limitation of artifacts. - assign_test
# we can't artifact them in one job. For example test jobs, download all artifacts from previous stages. - build_examples_00
- build_examples_01
- build_examples_02
- build_examples_03
- build_examples_04
- build_examples_05
- build_examples_06
- build_examples_07
artifacts: artifacts:
when: always when: always
paths: paths:
- $LOG_PATH - $LOG_PATH
expire_in: 6 mos expire_in: 1 mos
variables: variables:
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw" TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
TEST_CASE_PATH: "$CI_PROJECT_DIR/examples" TEST_CASE_PATH: "$CI_PROJECT_DIR/examples"
@ -623,7 +625,7 @@ assign_test:
ENV_FILE: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/EnvConfig.yml" ENV_FILE: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/EnvConfig.yml"
.test_template: &test_template .test_template: &test_template
stage: test stage: integration_test
when: on_success when: on_success
only: only:
- master - master
@ -631,7 +633,6 @@ assign_test:
- /^v\d+\.\d+(\.\d+)?($|-)/ - /^v\d+\.\d+(\.\d+)?($|-)/
- triggers - triggers
- schedules - schedules
allow_failure: true
dependencies: dependencies:
- assign_test - assign_test
- build_ssc_00 - build_ssc_00
@ -641,7 +642,7 @@ assign_test:
when: always when: always
paths: paths:
- $LOG_PATH - $LOG_PATH
expire_in: 6 mos expire_in: 1 mos
variables: variables:
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF" LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA" LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
@ -670,7 +671,7 @@ nvs_compatible_test:
paths: paths:
- $LOG_PATH - $LOG_PATH
- nvs_wifi.bin - nvs_wifi.bin
expire_in: 6 mos expire_in: 1 mos
tags: tags:
- ESP32_IDF - ESP32_IDF
- NVS_Compatible - NVS_Compatible
@ -700,6 +701,18 @@ example_test_002_01:
- ESP32 - ESP32
- Example_ShieldBox - Example_ShieldBox
example_test_003_01:
<<: *example_test_template
tags:
- ESP32
- Example_SDIO
example_test_004_01:
<<: *example_test_template
tags:
- ESP32
- Example_CAN
UT_001_01: UT_001_01:
<<: *unit_test_template <<: *unit_test_template
tags: tags:
@ -844,6 +857,66 @@ UT_001_24:
- ESP32_IDF - ESP32_IDF
- UT_T1_1 - UT_T1_1
UT_001_25:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_26:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_27:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_28:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_29:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_30:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_31:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_32:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_33:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_001_34:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
UT_002_01: UT_002_01:
<<: *unit_test_template <<: *unit_test_template
tags: tags:
@ -936,6 +1009,27 @@ UT_004_08:
- UT_T1_1 - UT_T1_1
- psram - psram
UT_004_09:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
- psram
UT_004_10:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
- psram
UT_004_11:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
- psram
UT_005_01: UT_005_01:
<<: *unit_test_template <<: *unit_test_template
tags: tags:
@ -950,6 +1044,112 @@ UT_005_02:
- UT_T1_SPIMODE - UT_T1_SPIMODE
- psram - psram
UT_006_01:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_GPIO
UT_006_02:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_GPIO
UT_006_03:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_GPIO
UT_006_04:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_GPIO
- psram
UT_007_01:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_PCNT
UT_007_02:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_PCNT
UT_007_03:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_PCNT
UT_007_04:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_PCNT
- psram
UT_008_01:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_LEDC
UT_008_02:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_LEDC
UT_008_03:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_LEDC
UT_008_04:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_LEDC
- psram
UT_010_01:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_RMT
UT_010_02:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_RMT
UT_010_03:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_RMT
UT_010_04:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_RMT
- psram
UT_601_01:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
IT_001_01: IT_001_01:
<<: *test_template <<: *test_template
tags: tags:
@ -1118,6 +1318,12 @@ IT_010_01:
- ESP32_IDF - ESP32_IDF
- SSC_T5_1 - SSC_T5_1
IT_011_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T50_1
IT_501_01: IT_501_01:
<<: *test_template <<: *test_template
tags: tags:

8
.gitmodules vendored
View File

@ -41,3 +41,11 @@
[submodule "components/mbedtls/mbedtls"] [submodule "components/mbedtls/mbedtls"]
path = components/mbedtls/mbedtls path = components/mbedtls/mbedtls
url = https://github.com/espressif/mbedtls.git url = https://github.com/espressif/mbedtls.git
[submodule "components/asio/asio"]
path = components/asio/asio
url = https://github.com/espressif/asio.git
[submodule "components/expat/expat"]
path = components/expat/expat
url = https://github.com/libexpat/libexpat.git

View File

@ -25,6 +25,8 @@ Before sending us a Pull Request, please consider this list of points:
* Are comments and documentation written in clear English, with no spelling or grammar errors? * Are comments and documentation written in clear English, with no spelling or grammar errors?
* Example contributions are also welcome. Please check the :doc:`creating-examples` guide for these.
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_? * If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback. * If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
@ -51,5 +53,6 @@ Related Documents
style-guide style-guide
documenting-code documenting-code
creating-examples
../api-reference/template ../api-reference/template
contributor-agreement contributor-agreement

132
Kconfig
View File

@ -42,137 +42,7 @@ endmenu # SDK tool configuration
source "$COMPONENT_KCONFIGS_PROJBUILD" source "$COMPONENT_KCONFIGS_PROJBUILD"
menu "Compiler options" source "$IDF_PATH/Kconfig.compiler"
choice OPTIMIZATION_COMPILER
prompt "Optimization Level"
default OPTIMIZATION_LEVEL_DEBUG
help
This option sets compiler optimization level (gcc -O argument).
- for "Release" setting, -Os flag is added to CFLAGS.
- for "Debug" setting, -Og flag is added to CFLAGS.
"Release" with -Os produces smaller & faster compiled code but it
may be harder to correlated code addresses to source files when debugging.
To add custom optimization settings, set CFLAGS and/or CPPFLAGS
in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
custom optimization levels may be unsupported.
config OPTIMIZATION_LEVEL_DEBUG
bool "Debug (-Og)"
config OPTIMIZATION_LEVEL_RELEASE
bool "Release (-Os)"
endchoice
choice OPTIMIZATION_ASSERTION_LEVEL
prompt "Assertion level"
default OPTIMIZATION_ASSERTIONS_ENABLED
help
Assertions can be:
- Enabled. Failure will print verbose assertion details. This is the default.
- Set to "silent" to save code size (failed assertions will abort() but user
needs to use the aborting address to find the line number with the failed assertion.)
- Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
to CPPFLAGS in this case.
config OPTIMIZATION_ASSERTIONS_ENABLED
prompt "Enabled"
bool
help
Enable assertions. Assertion content and line number will be printed on failure.
config OPTIMIZATION_ASSERTIONS_SILENT
prompt "Silent (saves code size)"
bool
help
Enable silent assertions. Failed assertions will abort(), user needs to
use the aborting address to find the line number with the failed assertion.
config OPTIMIZATION_ASSERTIONS_DISABLED
prompt "Disabled (sets -DNDEBUG)"
bool
help
If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
endchoice # assertions
menuconfig CXX_EXCEPTIONS
bool "Enable C++ exceptions"
default n
help
Enabling this option compiles all IDF C++ files with exception support enabled.
Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code which throws
an exception will abort instead.
Enabling this option currently adds an additional ~500 bytes of heap overhead
when an exception is thrown in user code for the first time.
config CXX_EXCEPTIONS_EMG_POOL_SIZE
int "Emergency Pool Size"
default 0
depends on CXX_EXCEPTIONS
help
Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
memory for thrown exceptions when there is not enough memory on the heap.
choice STACK_CHECK_MODE
prompt "Stack smashing protection mode"
default STACK_CHECK_NONE
help
Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
The guards are initialized when a function is entered and then checked when the function exits.
If a guard check fails, program is halted. Protection has the following modes:
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call
alloca, and functions with buffers larger than 8 bytes are protected.
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but
includes additional functions to be protected -- those that have
local array definitions, or have references to local frame addresses.
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are
protected.
Modes have the following impact on code performance and coverage:
- performance: NORMAL > STRONG > OVERALL
- coverage: NORMAL < STRONG < OVERALL
config STACK_CHECK_NONE
bool "None"
config STACK_CHECK_NORM
bool "Normal"
config STACK_CHECK_STRONG
bool "Strong"
config STACK_CHECK_ALL
bool "Overall"
endchoice
config STACK_CHECK
bool
default !STACK_CHECK_NONE
help
Stack smashing protection.
config WARN_WRITE_STRINGS
bool "Enable -Wwrite-strings warning flag"
default "n"
help
Adds -Wwrite-strings flag for the C/C++ compilers.
For C, this gives string constants the type "const char[]" so that
copying the address of one into a non-"const" "char *" pointer
produces a warning. This warning helps to find at compile time code
that tries to write into a string constant.
For C++, this warns about the deprecated conversion from string
literals to "char *".
endmenu # Compiler Options
menu "Component config" menu "Component config"
source "$COMPONENT_KCONFIGS" source "$COMPONENT_KCONFIGS"

135
Kconfig.compiler Normal file
View File

@ -0,0 +1,135 @@
menu "Compiler options"
choice OPTIMIZATION_COMPILER
prompt "Optimization Level"
default OPTIMIZATION_LEVEL_DEBUG
help
This option sets compiler optimization level (gcc -O argument).
- for "Release" setting, -Os flag is added to CFLAGS.
- for "Debug" setting, -Og flag is added to CFLAGS.
"Release" with -Os produces smaller & faster compiled code but it
may be harder to correlated code addresses to source files when debugging.
To add custom optimization settings, set CFLAGS and/or CPPFLAGS
in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
custom optimization levels may be unsupported.
config OPTIMIZATION_LEVEL_DEBUG
bool "Debug (-Og)"
config OPTIMIZATION_LEVEL_RELEASE
bool "Release (-Os)"
endchoice
choice OPTIMIZATION_ASSERTION_LEVEL
prompt "Assertion level"
default OPTIMIZATION_ASSERTIONS_ENABLED
help
Assertions can be:
- Enabled. Failure will print verbose assertion details. This is the default.
- Set to "silent" to save code size (failed assertions will abort() but user
needs to use the aborting address to find the line number with the failed assertion.)
- Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
to CPPFLAGS in this case.
config OPTIMIZATION_ASSERTIONS_ENABLED
prompt "Enabled"
bool
help
Enable assertions. Assertion content and line number will be printed on failure.
config OPTIMIZATION_ASSERTIONS_SILENT
prompt "Silent (saves code size)"
bool
help
Enable silent assertions. Failed assertions will abort(), user needs to
use the aborting address to find the line number with the failed assertion.
config OPTIMIZATION_ASSERTIONS_DISABLED
prompt "Disabled (sets -DNDEBUG)"
bool
help
If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
endchoice # assertions
menuconfig CXX_EXCEPTIONS
bool "Enable C++ exceptions"
default n
help
Enabling this option compiles all IDF C++ files with exception support enabled.
Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code which throws
an exception will abort instead.
Enabling this option currently adds an additional ~500 bytes of heap overhead
when an exception is thrown in user code for the first time.
config CXX_EXCEPTIONS_EMG_POOL_SIZE
int "Emergency Pool Size"
default 0
depends on CXX_EXCEPTIONS
help
Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
memory for thrown exceptions when there is not enough memory on the heap.
choice STACK_CHECK_MODE
prompt "Stack smashing protection mode"
default STACK_CHECK_NONE
help
Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
The guards are initialized when a function is entered and then checked when the function exits.
If a guard check fails, program is halted. Protection has the following modes:
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca,
and functions with buffers larger than 8 bytes are protected.
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes
additional functions to be protected -- those that have local array definitions,
or have references to local frame addresses.
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
Modes have the following impact on code performance and coverage:
- performance: NORMAL > STRONG > OVERALL
- coverage: NORMAL < STRONG < OVERALL
config STACK_CHECK_NONE
bool "None"
config STACK_CHECK_NORM
bool "Normal"
config STACK_CHECK_STRONG
bool "Strong"
config STACK_CHECK_ALL
bool "Overall"
endchoice
config STACK_CHECK
bool
default !STACK_CHECK_NONE
help
Stack smashing protection.
config WARN_WRITE_STRINGS
bool "Enable -Wwrite-strings warning flag"
default "n"
help
Adds -Wwrite-strings flag for the C/C++ compilers.
For C, this gives string constants the type ``const char[]`` so that
copying the address of one into a non-const ``char *`` pointer
produces a warning. This warning helps to find at compile time code
that tries to write into a string constant.
For C++, this warns about the deprecated conversion from string
literals to ``char *``.
endmenu # Compiler Options

View File

@ -1,28 +1,33 @@
# Espressif IoT Development Framework # Espressif IoT Development Framework
[![alt text](https://readthedocs.org/projects/docs/badge/?version=latest "Documentation Status")](https://esp-idf.readthedocs.io/en/latest/?badge=latest) [![alt text](https://readthedocs.org/projects/docs/badge/?version=latest "Documentation Status")](https://docs.espressif.com/projects/esp-idf/en/latest/?badge=latest)
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip. ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip.
# Developing With the ESP-IDF # Developing With ESP-IDF
## Setting Up ESP-IDF ## Setting Up ESP-IDF
See setup guides for detailed instructions to set up the ESP-IDF: See setup guides for detailed instructions to set up the ESP-IDF:
* [Windows Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/windows-setup.html) * [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
* [Mac OS Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/macos-setup.html) * [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
* [Linux Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/linux-setup.html)
## Finding a Project ## Finding a Project
As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, ESP-IDF comes with some example projects in the [examples](examples) directory. As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in Getting Started, ESP-IDF comes with some example projects in the [examples](examples) directory.
Once you've found the project you want to work with, change to its directory and you can configure and build it. Once you've found the project you want to work with, change to its directory and you can configure and build it.
To start your own project based on an example, copy the example project directory outside of the ESP-IDF directory.
# Quick Reference
See the Getting Started guide links above for a detailed setup guide. This is a quick reference for common commands when working with ESP-IDF projects:
## Configuring the Project ## Configuring the Project
`idf.py menuconfig` `make menuconfig`
* Opens a text-based configuration menu for the project. * Opens a text-based configuration menu for the project.
* Use up & down arrow keys to navigate the menu. * Use up & down arrow keys to navigate the menu.
@ -36,41 +41,54 @@ Once done configuring, press Escape multiple times to exit and say "Yes" to save
## Compiling the Project ## Compiling the Project
`idf.py build` `make -j4 all`
... will compile app, bootloader and generate a partition table based on the config. ... will compile app, bootloader and generate a partition table based on the config.
NOTE: The `-j4` option causes `make` to run 4 parallel jobs. This is much faster than the default single job. The recommended number to pass to this option is `-j(number of CPUs + 1)`.
## Flashing the Project ## Flashing the Project
When the build finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this automatically by running: When the build finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this automatically by running:
`idf.py flash` `make -j4 flash`
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `idf.py menuconfig`. This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
You don't need to run `idf.py build` before running `idf.py flash`, `idf.py flash` will automatically rebuild anything which needs it. You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
## Viewing Serial Output ## Viewing Serial Output
The `idf.py monitor` target uses the [idf_monitor tool](https://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html). The `make monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
Exit the monitor by typing Ctrl-]. Exit the monitor by typing Ctrl-].
To flash and monitor output in one pass, you can run: To build, flash and monitor output in one pass, you can run:
`idf.py flash monitor` `make -j4 flash monitor`
## Compiling & Flashing Just the App ## Compiling & Flashing Only the App
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table: After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
* `idf.py app` - build just the app. * `make app` - build just the app.
* `idf.py app-flash` - flash just the app. * `make app-flash` - flash just the app.
`idf.py app-flash` will automatically rebuild the app if it needs it. `make app-flash` will automatically rebuild the app if any source files have changed.
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.) (In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
## Parallel Builds
ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to the number of CPU cores in your system, plus one.)
Multiple make functions can be combined into one. For example: to build the app & bootloader using 5 jobs in parallel, then flash everything, and then display serial output from the ESP32 run:
```
make -j5 flash monitor
```
## The Partition Table ## The Partition Table
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader. Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
@ -79,29 +97,29 @@ A single ESP32's flash can contain multiple apps, as well as many different kind
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded. Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
The simplest way to use the partition table is to `idf.py menuconfig` and choose one of the simple predefined partition tables: The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
* "Single factory app, no OTA" * "Single factory app, no OTA"
* "Factory app, two OTA definitions" * "Factory app, two OTA definitions"
In both cases the factory app is flashed at offset 0x10000. If you `idf.py partition_table` then it will print a summary of the partition table. In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
For more details about partition tables and how to create custom variations, view the [`docs/en/api-guides/partition-tables.rst`](docs/en/api-guides/partition-tables.rst) file. For more details about partition tables and how to create custom variations, view the [`docs/en/api-guides/partition-tables.rst`](docs/en/api-guides/partition-tables.rst) file.
## Erasing Flash ## Erasing Flash
The `idf.py flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `idf.py erase_flash`. The `make flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `make erase_flash`.
This can be combined with other targets, ie `idf.py erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table. This can be combined with other targets, ie `make erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
# Resources # Resources
* Documentation for the latest version: https://esp-idf.readthedocs.io/. This documentation is built from the [docs directory](docs) of this repository. * Documentation for the latest version: https://docs.espressif.com/projects/esp-idf/. This documentation is built from the [docs directory](docs) of this repository.
* The [esp32.com forum](https://esp32.com/) is a place to ask questions and find community resources. * The [esp32.com forum](https://esp32.com/) is a place to ask questions and find community resources.
* [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. * [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://esp-idf.readthedocs.io/en/latest/contribute/index.html). * 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).

View File

@ -56,6 +56,7 @@ config ESP32_APPTRACE_PENDING_DATA_SIZE_MAX
events will be discarded when main HW buffer is full. events will be discarded when main HW buffer is full.
menu "FreeRTOS SystemView Tracing" menu "FreeRTOS SystemView Tracing"
depends on ESP32_APPTRACE_ENABLE
config SYSVIEW_ENABLE config SYSVIEW_ENABLE
bool "SystemView Tracing Enable" bool "SystemView Tracing Enable"
depends on ESP32_APPTRACE_ENABLE depends on ESP32_APPTRACE_ENABLE

View File

@ -279,6 +279,8 @@ static void esp_apptrace_fseek_args_prepare(uint8_t *buf, void *priv)
esp_apptrace_fseek_args_t *args = priv; esp_apptrace_fseek_args_t *args = priv;
memcpy(buf, &args->file, sizeof(args->file)); memcpy(buf, &args->file, sizeof(args->file));
memcpy(buf + sizeof(args->file), &args->offset, sizeof(args->offset));
memcpy(buf + sizeof(args->file) + sizeof(args->offset), &args->whence, sizeof(args->whence));
} }
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence) int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence)

View File

@ -1,102 +1,102 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
---------------------------------------------------------------------- ----------------------------------------------------------------------
File : Global.h File : Global.h
Purpose : Global types Purpose : Global types
In case your application already has a Global.h, you should In case your application already has a Global.h, you should
merge the files. In order to use Segger code, the types merge the files. In order to use Segger code, the types
U8, U16, U32, I8, I16, I32 need to be defined in Global.h; U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
additional definitions do not hurt. additional definitions do not hurt.
---------------------------END-OF-HEADER------------------------------ ---------------------------END-OF-HEADER------------------------------
*/ */
#ifndef GLOBAL_H // Guard against multiple inclusion #ifndef GLOBAL_H // Guard against multiple inclusion
#define GLOBAL_H #define GLOBAL_H
#define U8 unsigned char #define U8 unsigned char
#define U16 unsigned short #define U16 unsigned short
#define U32 unsigned long #define U32 unsigned long
#define I8 signed char #define I8 signed char
#define I16 signed short #define I16 signed short
#define I32 signed long #define I32 signed long
#ifdef _WIN32 #ifdef _WIN32
// //
// Microsoft VC6 compiler related // Microsoft VC6 compiler related
// //
#define U64 unsigned __int64 #define U64 unsigned __int64
#define U128 unsigned __int128 #define U128 unsigned __int128
#define I64 __int64 #define I64 __int64
#define I128 __int128 #define I128 __int128
#if _MSC_VER <= 1200 #if _MSC_VER <= 1200
#define U64_C(x) x##UI64 #define U64_C(x) x##UI64
#else #else
#define U64_C(x) x##ULL #define U64_C(x) x##ULL
#endif #endif
#else #else
// //
// C99 compliant compiler // C99 compliant compiler
// //
#define U64 unsigned long long #define U64 unsigned long long
#define I64 signed long long #define I64 signed long long
#define U64_C(x) x##ULL #define U64_C(x) x##ULL
#endif #endif
#endif // Avoid multiple inclusion #endif // Avoid multiple inclusion
/*************************** End of file ****************************/ /*************************** End of file ****************************/

View File

@ -1,298 +1,298 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
---------------------------END-OF-HEADER------------------------------ ---------------------------END-OF-HEADER------------------------------
File : SEGGER_RTT_Conf.h File : SEGGER_RTT_Conf.h
Purpose : Implementation of SEGGER real-time transfer (RTT) which Purpose : Implementation of SEGGER real-time transfer (RTT) which
allows real-time communication on targets which support allows real-time communication on targets which support
debugger memory accesses while the CPU is running. debugger memory accesses while the CPU is running.
Revision: $Rev: 5626 $ Revision: $Rev: 5626 $
*/ */
#ifndef SEGGER_RTT_CONF_H #ifndef SEGGER_RTT_CONF_H
#define SEGGER_RTT_CONF_H #define SEGGER_RTT_CONF_H
#ifdef __IAR_SYSTEMS_ICC__ #ifdef __IAR_SYSTEMS_ICC__
#include <intrinsics.h> #include <intrinsics.h>
#endif #endif
/********************************************************************* /*********************************************************************
* *
* Defines, configurable * Defines, configurable
* *
********************************************************************** **********************************************************************
*/ */
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3) #define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3) #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) #define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) #define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
// //
// Target is not allowed to perform other RTT operations while string still has not been stored completely. // Target is not allowed to perform other RTT operations while string still has not been stored completely.
// Otherwise we would probably end up with a mixed string in the buffer. // Otherwise we would probably end up with a mixed string in the buffer.
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. // If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
// //
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. // SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. // Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. // When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
// (Higher priority = lower priority number) // (Higher priority = lower priority number)
// Default value for embOS: 128u // Default value for embOS: 128u
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) // Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC // In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
// or define SEGGER_RTT_LOCK() to completely disable interrupts. // or define SEGGER_RTT_LOCK() to completely disable interrupts.
// //
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
/********************************************************************* /*********************************************************************
* *
* RTT lock configuration for SEGGER Embedded Studio, * RTT lock configuration for SEGGER Embedded Studio,
* Rowley CrossStudio and GCC * Rowley CrossStudio and GCC
*/ */
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) #if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
#ifdef __ARM_ARCH_6M__ #ifdef __ARM_ARCH_6M__
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
__asm volatile ("mrs %0, primask \n\t" \ __asm volatile ("mrs %0, primask \n\t" \
"mov r1, $1 \n\t" \ "mov r1, $1 \n\t" \
"msr primask, r1 \n\t" \ "msr primask, r1 \n\t" \
: "=r" (LockState) \ : "=r" (LockState) \
: \ : \
: "r1" \ : "r1" \
); );
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
: \ : \
: "r" (LockState) \ : "r" (LockState) \
: \ : \
); \ ); \
} }
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif #endif
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
__asm volatile ("mrs %0, basepri \n\t" \ __asm volatile ("mrs %0, basepri \n\t" \
"mov r1, %1 \n\t" \ "mov r1, %1 \n\t" \
"msr basepri, r1 \n\t" \ "msr basepri, r1 \n\t" \
: "=r" (LockState) \ : "=r" (LockState) \
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
: "r1" \ : "r1" \
); );
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
: \ : \
: "r" (LockState) \ : "r" (LockState) \
: \ : \
); \ ); \
} }
#elif defined(__ARM_ARCH_7A__) #elif defined(__ARM_ARCH_7A__)
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
__asm volatile ("mrs r1, CPSR \n\t" \ __asm volatile ("mrs r1, CPSR \n\t" \
"mov %0, r1 \n\t" \ "mov %0, r1 \n\t" \
"orr r1, r1, #0xC0 \n\t" \ "orr r1, r1, #0xC0 \n\t" \
"msr CPSR_c, r1 \n\t" \ "msr CPSR_c, r1 \n\t" \
: "=r" (LockState) \ : "=r" (LockState) \
: \ : \
: "r1" \ : "r1" \
); );
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
"mrs r1, CPSR \n\t" \ "mrs r1, CPSR \n\t" \
"bic r1, r1, #0xC0 \n\t" \ "bic r1, r1, #0xC0 \n\t" \
"and r0, r0, #0xC0 \n\t" \ "and r0, r0, #0xC0 \n\t" \
"orr r1, r1, r0 \n\t" \ "orr r1, r1, r0 \n\t" \
"msr CPSR_c, r1 \n\t" \ "msr CPSR_c, r1 \n\t" \
: \ : \
: "r" (LockState) \ : "r" (LockState) \
: "r0", "r1" \ : "r0", "r1" \
); \ ); \
} }
#else #else
#define SEGGER_RTT_LOCK() #define SEGGER_RTT_LOCK()
#define SEGGER_RTT_UNLOCK() #define SEGGER_RTT_UNLOCK()
#endif #endif
#endif #endif
/********************************************************************* /*********************************************************************
* *
* RTT lock configuration for IAR EWARM * RTT lock configuration for IAR EWARM
*/ */
#ifdef __ICCARM__ #ifdef __ICCARM__
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
LockState = __get_PRIMASK(); \ LockState = __get_PRIMASK(); \
__set_PRIMASK(1); __set_PRIMASK(1);
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
} }
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif #endif
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
LockState = __get_BASEPRI(); \ LockState = __get_BASEPRI(); \
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
} }
#endif #endif
#endif #endif
/********************************************************************* /*********************************************************************
* *
* RTT lock configuration for IAR RX * RTT lock configuration for IAR RX
*/ */
#ifdef __ICCRX__ #ifdef __ICCRX__
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned long LockState; \ unsigned long LockState; \
LockState = __get_interrupt_state(); \ LockState = __get_interrupt_state(); \
__disable_interrupt(); __disable_interrupt();
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
} }
#endif #endif
/********************************************************************* /*********************************************************************
* *
* RTT lock configuration for KEIL ARM * RTT lock configuration for KEIL ARM
*/ */
#ifdef __CC_ARM #ifdef __CC_ARM
#if (defined __TARGET_ARCH_6S_M) #if (defined __TARGET_ARCH_6S_M)
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
register unsigned char PRIMASK __asm( "primask"); \ register unsigned char PRIMASK __asm( "primask"); \
LockState = PRIMASK; \ LockState = PRIMASK; \
PRIMASK = 1u; \ PRIMASK = 1u; \
__schedule_barrier(); __schedule_barrier();
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
__schedule_barrier(); \ __schedule_barrier(); \
} }
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif #endif
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
register unsigned char BASEPRI __asm( "basepri"); \ register unsigned char BASEPRI __asm( "basepri"); \
LockState = BASEPRI; \ LockState = BASEPRI; \
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
__schedule_barrier(); __schedule_barrier();
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
__schedule_barrier(); \ __schedule_barrier(); \
} }
#endif #endif
#endif #endif
/********************************************************************* /*********************************************************************
* *
* RTT lock configuration for TI ARM * RTT lock configuration for TI ARM
*/ */
#ifdef __TI_ARM__ #ifdef __TI_ARM__
#if defined (__TI_ARM_V6M0__) #if defined (__TI_ARM_V6M0__)
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
LockState = __get_PRIMASK(); \ LockState = __get_PRIMASK(); \
__set_PRIMASK(1); __set_PRIMASK(1);
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
} }
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif #endif
#define SEGGER_RTT_LOCK() { \ #define SEGGER_RTT_LOCK() { \
unsigned int LockState; \ unsigned int LockState; \
LockState = OS_GetBASEPRI(); \ LockState = OS_GetBASEPRI(); \
OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
#define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \ #define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \
} }
#endif #endif
#endif #endif
/********************************************************************* /*********************************************************************
* *
* RTT lock configuration fallback * RTT lock configuration fallback
*/ */
#ifndef SEGGER_RTT_LOCK #ifndef SEGGER_RTT_LOCK
void SEGGER_SYSVIEW_X_RTT_Lock(); void SEGGER_SYSVIEW_X_RTT_Lock();
#define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts) #define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
#endif #endif
#ifndef SEGGER_RTT_UNLOCK #ifndef SEGGER_RTT_UNLOCK
void SEGGER_SYSVIEW_X_RTT_Unlock(); void SEGGER_SYSVIEW_X_RTT_Unlock();
#define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) #define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
#endif #endif
#endif #endif
/*************************** End of file ****************************/ /*************************** End of file ****************************/

View File

@ -1,176 +1,176 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
-------------------------- END-OF-HEADER ----------------------------- -------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Conf.h File : SEGGER_SYSVIEW_Conf.h
Purpose : SEGGER SystemView configuration. Purpose : SEGGER SystemView configuration.
Revision: $Rev: 5927 $ Revision: $Rev: 5927 $
*/ */
#ifndef SEGGER_SYSVIEW_CONF_H #ifndef SEGGER_SYSVIEW_CONF_H
#define SEGGER_SYSVIEW_CONF_H #define SEGGER_SYSVIEW_CONF_H
/********************************************************************* /*********************************************************************
* *
* Defines, fixed * Defines, fixed
* *
********************************************************************** **********************************************************************
*/ */
// //
// Constants for known core configuration // Constants for known core configuration
// //
#define SEGGER_SYSVIEW_CORE_OTHER 0 #define SEGGER_SYSVIEW_CORE_OTHER 0
#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1 #define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7 #define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX #define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) #if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
#ifdef __ARM_ARCH_6M__ #ifdef __ARM_ARCH_6M__
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif #endif
#elif defined(__ICCARM__) #elif defined(__ICCARM__)
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__))) #elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif #endif
#elif defined(__CC_ARM) #elif defined(__CC_ARM)
#if (defined(__TARGET_ARCH_6S_M)) #if (defined(__TARGET_ARCH_6S_M))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif #endif
#elif defined(__TI_ARM__) #elif defined(__TI_ARM__)
#ifdef __TI_ARM_V6M0__ #ifdef __TI_ARM_V6M0__
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
#elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__)) #elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
#endif #endif
#elif defined(__ICCRX__) #elif defined(__ICCRX__)
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
#elif defined(__RX) #elif defined(__RX)
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
#endif #endif
#ifndef SEGGER_SYSVIEW_CORE #ifndef SEGGER_SYSVIEW_CORE
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
#endif #endif
/********************************************************************* /*********************************************************************
* *
* Defines, configurable * Defines, configurable
* *
********************************************************************** **********************************************************************
*/ */
/********************************************************************* /*********************************************************************
* *
* SystemView buffer configuration * SystemView buffer configuration
*/ */
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer. #define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer.
#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection #define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack #define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode #define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode
/********************************************************************* /*********************************************************************
* *
* SystemView timestamp configuration * SystemView timestamp configuration
*/ */
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3 #if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter. #define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
#else #else
#define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function #define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp() #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
#endif #endif
/********************************************************************* /*********************************************************************
* *
* SystemView Id configuration * SystemView Id configuration
*/ */
//TODO: optimise it //TODO: optimise it
#define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM) #define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned) #define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
/********************************************************************* /*********************************************************************
* *
* SystemView interrupt configuration * SystemView interrupt configuration
*/ */
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3 #if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector) #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0 #elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
#if defined(__ICCARM__) #if defined(__ICCARM__)
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead. #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
#else #else
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector) #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
#endif #endif
#else #else
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function. #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
#endif #endif
void SEGGER_SYSVIEW_X_SysView_Lock(); void SEGGER_SYSVIEW_X_SysView_Lock();
void SEGGER_SYSVIEW_X_SysView_Unlock(); void SEGGER_SYSVIEW_X_SysView_Unlock();
#define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock() #define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock()
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock() #define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock()
#endif // SEGGER_SYSVIEW_CONF_H #endif // SEGGER_SYSVIEW_CONF_H
/*************************** End of file ****************************/ /*************************** End of file ****************************/

View File

@ -1,155 +1,155 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
---------------------------------------------------------------------- ----------------------------------------------------------------------
File : SEGGER.h File : SEGGER.h
Purpose : Global types etc & general purpose utility functions Purpose : Global types etc & general purpose utility functions
---------------------------END-OF-HEADER------------------------------ ---------------------------END-OF-HEADER------------------------------
*/ */
#ifndef SEGGER_H // Guard against multiple inclusion #ifndef SEGGER_H // Guard against multiple inclusion
#define SEGGER_H #define SEGGER_H
#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32 #include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { /* Make sure we have C-declarations in C++ programs */ extern "C" { /* Make sure we have C-declarations in C++ programs */
#endif #endif
/********************************************************************* /*********************************************************************
* *
* Keywords/specifiers * Keywords/specifiers
* *
********************************************************************** **********************************************************************
*/ */
#ifndef INLINE #ifndef INLINE
#ifdef _WIN32 #ifdef _WIN32
// //
// Microsoft VC6 and newer. // Microsoft VC6 and newer.
// Force inlining without cost checking. // Force inlining without cost checking.
// //
#define INLINE __forceinline #define INLINE __forceinline
#else #else
#if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__)) #if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__))
// //
// Other known compilers. // Other known compilers.
// //
#define INLINE inline #define INLINE inline
#else #else
// //
// Unknown compilers. // Unknown compilers.
// //
#define INLINE #define INLINE
#endif #endif
#endif #endif
#endif #endif
/********************************************************************* /*********************************************************************
* *
* Function-like macros * Function-like macros
* *
********************************************************************** **********************************************************************
*/ */
#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0])) #define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b)) #define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b)) #define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
/********************************************************************* /*********************************************************************
* *
* Types * Types
* *
********************************************************************** **********************************************************************
*/ */
typedef struct { typedef struct {
char *pBuffer; char *pBuffer;
int BufferSize; int BufferSize;
int Cnt; int Cnt;
} SEGGER_BUFFER_DESC; } SEGGER_BUFFER_DESC;
typedef struct { typedef struct {
int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size. int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed. void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory. void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory.
void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory. void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory.
} SEGGER_CACHE_CONFIG; } SEGGER_CACHE_CONFIG;
/********************************************************************* /*********************************************************************
* *
* Utility functions * Utility functions
* *
********************************************************************** **********************************************************************
*/ */
void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes); void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes);
void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes); void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes);
void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes); void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes);
void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c); void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c);
void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits); void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits);
void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits); void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits);
int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...); int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...);
#if defined(__cplusplus) #if defined(__cplusplus)
} /* Make sure we have C-declarations in C++ programs */ } /* Make sure we have C-declarations in C++ programs */
#endif #endif
#endif // Avoid multiple inclusion #endif // Avoid multiple inclusion
/*************************** End of file ****************************/ /*************************** End of file ****************************/

File diff suppressed because it is too large Load Diff

View File

@ -1,334 +1,334 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
-------------------------- END-OF-HEADER ----------------------------- -------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW.h File : SEGGER_SYSVIEW.h
Purpose : System visualization API. Purpose : System visualization API.
Revision: $Rev: 5626 $ Revision: $Rev: 5626 $
*/ */
#ifndef SEGGER_SYSVIEW_H #ifndef SEGGER_SYSVIEW_H
#define SEGGER_SYSVIEW_H #define SEGGER_SYSVIEW_H
/********************************************************************* /*********************************************************************
* *
* #include Section * #include Section
* *
********************************************************************** **********************************************************************
*/ */
#include "SEGGER.h" #include "SEGGER.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/********************************************************************* /*********************************************************************
* *
* Defines, fixed * Defines, fixed
* *
********************************************************************** **********************************************************************
*/ */
#define SEGGER_SYSVIEW_VERSION 21000 #define SEGGER_SYSVIEW_VERSION 21000
#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp. #define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet. #define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
#define SEGGER_SYSVIEW_LOG (0u) #define SEGGER_SYSVIEW_LOG (0u)
#define SEGGER_SYSVIEW_WARNING (1u) #define SEGGER_SYSVIEW_WARNING (1u)
#define SEGGER_SYSVIEW_ERROR (2u) #define SEGGER_SYSVIEW_ERROR (2u)
#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6) #define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4 #define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
// //
// SystemView events. First 32 IDs from 0 .. 31 are reserved for these // SystemView events. First 32 IDs from 0 .. 31 are reserved for these
// //
#define SYSVIEW_EVTID_NOP 0 // Dummy packet. #define SYSVIEW_EVTID_NOP 0 // Dummy packet.
#define SYSVIEW_EVTID_OVERFLOW 1 #define SYSVIEW_EVTID_OVERFLOW 1
#define SYSVIEW_EVTID_ISR_ENTER 2 #define SYSVIEW_EVTID_ISR_ENTER 2
#define SYSVIEW_EVTID_ISR_EXIT 3 #define SYSVIEW_EVTID_ISR_EXIT 3
#define SYSVIEW_EVTID_TASK_START_EXEC 4 #define SYSVIEW_EVTID_TASK_START_EXEC 4
#define SYSVIEW_EVTID_TASK_STOP_EXEC 5 #define SYSVIEW_EVTID_TASK_STOP_EXEC 5
#define SYSVIEW_EVTID_TASK_START_READY 6 #define SYSVIEW_EVTID_TASK_START_READY 6
#define SYSVIEW_EVTID_TASK_STOP_READY 7 #define SYSVIEW_EVTID_TASK_STOP_READY 7
#define SYSVIEW_EVTID_TASK_CREATE 8 #define SYSVIEW_EVTID_TASK_CREATE 8
#define SYSVIEW_EVTID_TASK_INFO 9 #define SYSVIEW_EVTID_TASK_INFO 9
#define SYSVIEW_EVTID_TRACE_START 10 #define SYSVIEW_EVTID_TRACE_START 10
#define SYSVIEW_EVTID_TRACE_STOP 11 #define SYSVIEW_EVTID_TRACE_STOP 11
#define SYSVIEW_EVTID_SYSTIME_CYCLES 12 #define SYSVIEW_EVTID_SYSTIME_CYCLES 12
#define SYSVIEW_EVTID_SYSTIME_US 13 #define SYSVIEW_EVTID_SYSTIME_US 13
#define SYSVIEW_EVTID_SYSDESC 14 #define SYSVIEW_EVTID_SYSDESC 14
#define SYSVIEW_EVTID_USER_START 15 #define SYSVIEW_EVTID_USER_START 15
#define SYSVIEW_EVTID_USER_STOP 16 #define SYSVIEW_EVTID_USER_STOP 16
#define SYSVIEW_EVTID_IDLE 17 #define SYSVIEW_EVTID_IDLE 17
#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18 #define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
#define SYSVIEW_EVTID_TIMER_ENTER 19 #define SYSVIEW_EVTID_TIMER_ENTER 19
#define SYSVIEW_EVTID_TIMER_EXIT 20 #define SYSVIEW_EVTID_TIMER_EXIT 20
#define SYSVIEW_EVTID_STACK_INFO 21 #define SYSVIEW_EVTID_STACK_INFO 21
#define SYSVIEW_EVTID_MODULEDESC 22 #define SYSVIEW_EVTID_MODULEDESC 22
#define SYSVIEW_EVTID_INIT 24 #define SYSVIEW_EVTID_INIT 24
#define SYSVIEW_EVTID_NAME_RESOURCE 25 #define SYSVIEW_EVTID_NAME_RESOURCE 25
#define SYSVIEW_EVTID_PRINT_FORMATTED 26 #define SYSVIEW_EVTID_PRINT_FORMATTED 26
#define SYSVIEW_EVTID_NUMMODULES 27 #define SYSVIEW_EVTID_NUMMODULES 27
#define SYSVIEW_EVTID_END_CALL 28 #define SYSVIEW_EVTID_END_CALL 28
#define SYSVIEW_EVTID_TASK_TERMINATE 29 #define SYSVIEW_EVTID_TASK_TERMINATE 29
#define SYSVIEW_EVTID_EX 31 #define SYSVIEW_EVTID_EX 31
// //
// Event masks to disable/enable events // Event masks to disable/enable events
// //
#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP) #define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW) #define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER) #define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT) #define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC) #define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC) #define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY) #define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY) #define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE) #define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO) #define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START) #define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP) #define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES) #define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US) #define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC) #define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START) #define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP) #define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE) #define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER) #define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER) #define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT) #define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO) #define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC) #define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT) #define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE) #define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED) #define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES) #define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL) #define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE) #define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX) #define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \ #define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
| SYSVIEW_EVTMASK_ISR_EXIT \ | SYSVIEW_EVTMASK_ISR_EXIT \
| SYSVIEW_EVTMASK_ISR_TO_SCHEDULER) | SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \ #define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
| SYSVIEW_EVTMASK_TASK_STOP_EXEC \ | SYSVIEW_EVTMASK_TASK_STOP_EXEC \
| SYSVIEW_EVTMASK_TASK_START_READY \ | SYSVIEW_EVTMASK_TASK_START_READY \
| SYSVIEW_EVTMASK_TASK_STOP_READY \ | SYSVIEW_EVTMASK_TASK_STOP_READY \
| SYSVIEW_EVTMASK_TASK_CREATE \ | SYSVIEW_EVTMASK_TASK_CREATE \
| SYSVIEW_EVTMASK_TASK_INFO \ | SYSVIEW_EVTMASK_TASK_INFO \
| SYSVIEW_EVTMASK_STACK_INFO \ | SYSVIEW_EVTMASK_STACK_INFO \
| SYSVIEW_EVTMASK_TASK_TERMINATE) | SYSVIEW_EVTMASK_TASK_TERMINATE)
/********************************************************************* /*********************************************************************
* *
* Structures * Structures
* *
********************************************************************** **********************************************************************
*/ */
typedef struct { typedef struct {
U32 TaskID; U32 TaskID;
const char* sName; const char* sName;
U32 Prio; U32 Prio;
U32 StackBase; U32 StackBase;
U32 StackSize; U32 StackSize;
} SEGGER_SYSVIEW_TASKINFO; } SEGGER_SYSVIEW_TASKINFO;
typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE; typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
struct SEGGER_SYSVIEW_MODULE_STRUCT { struct SEGGER_SYSVIEW_MODULE_STRUCT {
const char* sModule; const char* sModule;
U32 NumEvents; U32 NumEvents;
U32 EventOffset; U32 EventOffset;
void (*pfSendModuleDesc)(void); void (*pfSendModuleDesc)(void);
SEGGER_SYSVIEW_MODULE* pNext; SEGGER_SYSVIEW_MODULE* pNext;
}; };
typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void); typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
/********************************************************************* /*********************************************************************
* *
* API functions * API functions
* *
********************************************************************** **********************************************************************
*/ */
typedef struct { typedef struct {
U64 (*pfGetTime) (void); U64 (*pfGetTime) (void);
void (*pfSendTaskList) (void); void (*pfSendTaskList) (void);
} SEGGER_SYSVIEW_OS_API; } SEGGER_SYSVIEW_OS_API;
/********************************************************************* /*********************************************************************
* *
* Control and initialization functions * Control and initialization functions
*/ */
void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc); void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress); void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
void SEGGER_SYSVIEW_Start (void); void SEGGER_SYSVIEW_Start (void);
void SEGGER_SYSVIEW_Stop (void); void SEGGER_SYSVIEW_Stop (void);
void SEGGER_SYSVIEW_GetSysDesc (void); void SEGGER_SYSVIEW_GetSysDesc (void);
void SEGGER_SYSVIEW_SendTaskList (void); void SEGGER_SYSVIEW_SendTaskList (void);
void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo); void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc); void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
/********************************************************************* /*********************************************************************
* *
* Event recording functions * Event recording functions
*/ */
void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId); void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0); void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1); void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2); void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3); void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4); void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5); void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6); void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7); void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8); void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9); void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString); void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
void SEGGER_SYSVIEW_RecordSystime (void); void SEGGER_SYSVIEW_RecordSystime (void);
void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId); void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
void SEGGER_SYSVIEW_RecordExitISR (void); void SEGGER_SYSVIEW_RecordExitISR (void);
void SEGGER_SYSVIEW_RecordExitISRToScheduler (void); void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId); void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
void SEGGER_SYSVIEW_RecordExitTimer (void); void SEGGER_SYSVIEW_RecordExitTimer (void);
void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID); void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0); void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
void SEGGER_SYSVIEW_OnIdle (void); void SEGGER_SYSVIEW_OnIdle (void);
void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId); void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId); void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId); void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskStopExec (void); void SEGGER_SYSVIEW_OnTaskStopExec (void);
void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId); void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause); void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile) void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile)
void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event
void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName); void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId); int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
/********************************************************************* /*********************************************************************
* *
* Event parameter encoding functions * Event parameter encoding functions
*/ */
U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value); U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len); U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen); U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id); U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
U32 SEGGER_SYSVIEW_ShrinkId (U32 Id); U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
/********************************************************************* /*********************************************************************
* *
* Middleware module registration * Middleware module registration
*/ */
void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule); void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription); void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
void SEGGER_SYSVIEW_SendModule (U8 ModuleId); void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
void SEGGER_SYSVIEW_SendModuleDescription (void); void SEGGER_SYSVIEW_SendModuleDescription (void);
void SEGGER_SYSVIEW_SendNumModules (void); void SEGGER_SYSVIEW_SendNumModules (void);
/********************************************************************* /*********************************************************************
* *
* printf-Style functions * printf-Style functions
*/ */
#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list #ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...); void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...); void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
void SEGGER_SYSVIEW_PrintfHost (const char* s, ...); void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...); void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
void SEGGER_SYSVIEW_WarnfHost (const char* s, ...); void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...); void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...); void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...); void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
#endif #endif
void SEGGER_SYSVIEW_Print (const char* s); void SEGGER_SYSVIEW_Print (const char* s);
void SEGGER_SYSVIEW_Warn (const char* s); void SEGGER_SYSVIEW_Warn (const char* s);
void SEGGER_SYSVIEW_Error (const char* s); void SEGGER_SYSVIEW_Error (const char* s);
/********************************************************************* /*********************************************************************
* *
* Run-time configuration functions * Run-time configuration functions
*/ */
void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask); void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask); void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
/********************************************************************* /*********************************************************************
* *
* Application-provided functions * Application-provided functions
*/ */
void SEGGER_SYSVIEW_Conf (void); void SEGGER_SYSVIEW_Conf (void);
U32 SEGGER_SYSVIEW_X_GetTimestamp (void); U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
U32 SEGGER_SYSVIEW_X_GetInterruptId (void); U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif
/*************************** End of file ****************************/ /*************************** End of file ****************************/

View File

@ -1,178 +1,178 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
-------------------------- END-OF-HEADER ----------------------------- -------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_ConfDefaults.h File : SEGGER_SYSVIEW_ConfDefaults.h
Purpose : Defines defaults for configurable defines used in Purpose : Defines defaults for configurable defines used in
SEGGER SystemView. SEGGER SystemView.
Revision: $Rev: 3734 $ Revision: $Rev: 3734 $
*/ */
#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H #ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
#define SEGGER_SYSVIEW_CONFDEFAULTS_H #define SEGGER_SYSVIEW_CONFDEFAULTS_H
/********************************************************************* /*********************************************************************
* *
* #include Section * #include Section
* *
********************************************************************** **********************************************************************
*/ */
#include "SEGGER_SYSVIEW_Conf.h" #include "SEGGER_SYSVIEW_Conf.h"
#include "SEGGER_RTT_Conf.h" #include "SEGGER_RTT_Conf.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/********************************************************************* /*********************************************************************
* *
* Configuration defaults * Configuration defaults
* *
********************************************************************** **********************************************************************
*/ */
// Number of bytes that SystemView uses for a buffer. // Number of bytes that SystemView uses for a buffer.
#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE #ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 #define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
#endif #endif
// The RTT channel that SystemView will use. // The RTT channel that SystemView will use.
#ifndef SEGGER_SYSVIEW_RTT_CHANNEL #ifndef SEGGER_SYSVIEW_RTT_CHANNEL
#define SEGGER_SYSVIEW_RTT_CHANNEL 0 #define SEGGER_SYSVIEW_RTT_CHANNEL 0
#endif #endif
// Sanity check of RTT channel // Sanity check of RTT channel
#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2) #if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!" #error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS) #elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!" #error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
#endif #endif
// Place the SystemView buffer into its own/the RTT section // Place the SystemView buffer into its own/the RTT section
#if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION) #if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION)
#define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION #define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION
#endif #endif
// Retrieve a system timestamp. This gets the Cortex-M cycle counter. // Retrieve a system timestamp. This gets the Cortex-M cycle counter.
#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP #ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
#error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!" #error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!"
#endif #endif
// Define number of valid bits low-order delivered by clock source. // Define number of valid bits low-order delivered by clock source.
#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS #ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
#endif #endif
// Lowest Id reported by the Application. // Lowest Id reported by the Application.
#ifndef SEGGER_SYSVIEW_ID_BASE #ifndef SEGGER_SYSVIEW_ID_BASE
#define SEGGER_SYSVIEW_ID_BASE 0 #define SEGGER_SYSVIEW_ID_BASE 0
#endif #endif
// Number of bits to shift Ids to save bandwidth // Number of bits to shift Ids to save bandwidth
#ifndef SEGGER_SYSVIEW_ID_SHIFT #ifndef SEGGER_SYSVIEW_ID_SHIFT
#define SEGGER_SYSVIEW_ID_SHIFT 0 #define SEGGER_SYSVIEW_ID_SHIFT 0
#endif #endif
#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID #ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
#error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!" #error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!"
#endif #endif
#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS #ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
#define SEGGER_SYSVIEW_MAX_ARGUMENTS 16 #define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
#endif #endif
#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN #ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
#define SEGGER_SYSVIEW_MAX_STRING_LEN 128 #define SEGGER_SYSVIEW_MAX_STRING_LEN 128
#endif #endif
// Use a static buffer instead of a buffer on the stack for packets // Use a static buffer instead of a buffer on the stack for packets
#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER #ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 #define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
#endif #endif
// Maximum packet size used by SystemView for the static buffer // Maximum packet size used by SystemView for the static buffer
#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE #ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
#define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32 #define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32
#endif #endif
// Use post-mortem analysis instead of real-time analysis // Use post-mortem analysis instead of real-time analysis
#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE #ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 #define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
#endif #endif
// Configure how frequently syncronization is sent // Configure how frequently syncronization is sent
#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT #ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
#define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8 #define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
#endif #endif
// Lock SystemView (nestable) // Lock SystemView (nestable)
#ifndef SEGGER_SYSVIEW_LOCK #ifndef SEGGER_SYSVIEW_LOCK
#define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK() #define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
#endif #endif
// Unlock SystemView (nestable) // Unlock SystemView (nestable)
#ifndef SEGGER_SYSVIEW_UNLOCK #ifndef SEGGER_SYSVIEW_UNLOCK
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK() #define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif
/*************************** End of file ****************************/ /*************************** End of file ****************************/

View File

@ -1,110 +1,110 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
-------------------------- END-OF-HEADER ----------------------------- -------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Int.h File : SEGGER_SYSVIEW_Int.h
Purpose : SEGGER SystemView internal header. Purpose : SEGGER SystemView internal header.
Revision: $Rev: 5626 $ Revision: $Rev: 5626 $
*/ */
#ifndef SEGGER_SYSVIEW_INT_H #ifndef SEGGER_SYSVIEW_INT_H
#define SEGGER_SYSVIEW_INT_H #define SEGGER_SYSVIEW_INT_H
/********************************************************************* /*********************************************************************
* *
* #include Section * #include Section
* *
********************************************************************** **********************************************************************
*/ */
#include "SEGGER_SYSVIEW.h" #include "SEGGER_SYSVIEW.h"
#include "SEGGER_SYSVIEW_Conf.h" #include "SEGGER_SYSVIEW_Conf.h"
#include "SEGGER_SYSVIEW_ConfDefaults.h" #include "SEGGER_SYSVIEW_ConfDefaults.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/********************************************************************* /*********************************************************************
* *
* Private data types * Private data types
* *
********************************************************************** **********************************************************************
*/ */
// //
// Commands that Host can send to target // Commands that Host can send to target
// //
typedef enum { typedef enum {
SEGGER_SYSVIEW_COMMAND_ID_START = 1, SEGGER_SYSVIEW_COMMAND_ID_START = 1,
SEGGER_SYSVIEW_COMMAND_ID_STOP, SEGGER_SYSVIEW_COMMAND_ID_STOP,
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME, SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST, SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC, SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES, SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC, SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
// Extended commands: Commands >= 128 have a second parameter // Extended commands: Commands >= 128 have a second parameter
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128 SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
} SEGGER_SYSVIEW_COMMAND_ID; } SEGGER_SYSVIEW_COMMAND_ID;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif
/*************************** End of file ****************************/ /*************************** End of file ****************************/

View File

@ -1,290 +1,290 @@
/********************************************************************* /*********************************************************************
* SEGGER Microcontroller GmbH & Co. KG * * SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts * * The Embedded Experts *
********************************************************************** **********************************************************************
* * * *
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG * * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
* * * *
* www.segger.com Support: support@segger.com * * www.segger.com Support: support@segger.com *
* * * *
********************************************************************** **********************************************************************
* * * *
* SEGGER SystemView * Real-time application analysis * * SEGGER SystemView * Real-time application analysis *
* * * *
********************************************************************** **********************************************************************
* * * *
* All rights reserved. * * All rights reserved. *
* * * *
* SEGGER strongly recommends to not make any changes * * SEGGER strongly recommends to not make any changes *
* to or modify the source code of this software in order to stay * * to or modify the source code of this software in order to stay *
* compatible with the RTT protocol and J-Link. * * compatible with the RTT protocol and J-Link. *
* * * *
* Redistribution and use in source and binary forms, with or * * Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following * * without modification, are permitted provided that the following *
* conditions are met: * * conditions are met: *
* * * *
* o Redistributions of source code must retain the above copyright * * o Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * * notice, this list of conditions and the following disclaimer. *
* * * *
* o Redistributions in binary form must reproduce the above * * o Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the following * * copyright notice, this list of conditions and the following *
* disclaimer in the documentation and/or other materials provided * * disclaimer in the documentation and/or other materials provided *
* with the distribution. * * with the distribution. *
* * * *
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
* nor the names of its contributors may be used to endorse or * * nor the names of its contributors may be used to endorse or *
* promote products derived from this software without specific * * promote products derived from this software without specific *
* prior written permission. * * prior written permission. *
* * * *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. * * DAMAGE. *
* * * *
********************************************************************** **********************************************************************
* * * *
* SystemView version: V2.42 * * SystemView version: V2.42 *
* * * *
********************************************************************** **********************************************************************
-------------------------- END-OF-HEADER ----------------------------- -------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_FreeRTOS.c File : SEGGER_SYSVIEW_FreeRTOS.c
Purpose : Interface between FreeRTOS and SystemView. Purpose : Interface between FreeRTOS and SystemView.
Revision: $Rev: 3734 $ Revision: $Rev: 3734 $
*/ */
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "SEGGER_SYSVIEW.h" #include "SEGGER_SYSVIEW.h"
#include "SEGGER_SYSVIEW_FreeRTOS.h" #include "SEGGER_SYSVIEW_FreeRTOS.h"
#include "string.h" // Required for memset #include "string.h" // Required for memset
typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS; typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
struct SYSVIEW_FREERTOS_TASK_STATUS { struct SYSVIEW_FREERTOS_TASK_STATUS {
U32 xHandle; U32 xHandle;
const char* pcTaskName; const char* pcTaskName;
unsigned uxCurrentPriority; unsigned uxCurrentPriority;
U32 pxStack; U32 pxStack;
unsigned uStackHighWaterMark; unsigned uStackHighWaterMark;
}; };
static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS]; static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
/********************************************************************* /*********************************************************************
* *
* _cbSendTaskList() * _cbSendTaskList()
* *
* Function description * Function description
* This function is part of the link between FreeRTOS and SYSVIEW. * This function is part of the link between FreeRTOS and SYSVIEW.
* Called from SystemView when asked by the host, it uses SYSVIEW * Called from SystemView when asked by the host, it uses SYSVIEW
* functions to send the entire task list to the host. * functions to send the entire task list to the host.
*/ */
static void _cbSendTaskList(void) { static void _cbSendTaskList(void) {
unsigned n; unsigned n;
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) { for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
if (_aTasks[n].xHandle) { if (_aTasks[n].xHandle) {
#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark #if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
_aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle); _aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
#endif #endif
SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark); SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
} }
} }
} }
/********************************************************************* /*********************************************************************
* *
* _cbGetTime() * _cbGetTime()
* *
* Function description * Function description
* This function is part of the link between FreeRTOS and SYSVIEW. * This function is part of the link between FreeRTOS and SYSVIEW.
* Called from SystemView when asked by the host, returns the * Called from SystemView when asked by the host, returns the
* current system time in micro seconds. * current system time in micro seconds.
*/ */
static U64 _cbGetTime(void) { static U64 _cbGetTime(void) {
U64 Time; U64 Time;
Time = xTaskGetTickCountFromISR(); Time = xTaskGetTickCountFromISR();
Time *= portTICK_PERIOD_MS; Time *= portTICK_PERIOD_MS;
Time *= 1000; Time *= 1000;
return Time; return Time;
} }
/********************************************************************* /*********************************************************************
* *
* Global functions * Global functions
* *
********************************************************************** **********************************************************************
*/ */
/********************************************************************* /*********************************************************************
* *
* SYSVIEW_AddTask() * SYSVIEW_AddTask()
* *
* Function description * Function description
* Add a task to the internal list and record its information. * Add a task to the internal list and record its information.
*/ */
void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) { void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
unsigned n; unsigned n;
if (memcmp(pcTaskName, "IDLE", 5) == 0) { if (memcmp(pcTaskName, "IDLE", 5) == 0) {
return; return;
} }
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) { for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
if (_aTasks[n].xHandle == 0) { if (_aTasks[n].xHandle == 0) {
break; break;
} }
} }
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) { if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached."); SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
return; return;
} }
_aTasks[n].xHandle = xHandle; _aTasks[n].xHandle = xHandle;
_aTasks[n].pcTaskName = pcTaskName; _aTasks[n].pcTaskName = pcTaskName;
_aTasks[n].uxCurrentPriority = uxCurrentPriority; _aTasks[n].uxCurrentPriority = uxCurrentPriority;
_aTasks[n].pxStack = pxStack; _aTasks[n].pxStack = pxStack;
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark; _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark); SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
} }
/********************************************************************* /*********************************************************************
* *
* SYSVIEW_UpdateTask() * SYSVIEW_UpdateTask()
* *
* Function description * Function description
* Update a task in the internal list and record its information. * Update a task in the internal list and record its information.
*/ */
void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) { void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
unsigned n; unsigned n;
if (memcmp(pcTaskName, "IDLE", 5) == 0) { if (memcmp(pcTaskName, "IDLE", 5) == 0) {
return; return;
} }
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) { for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
if (_aTasks[n].xHandle == xHandle) { if (_aTasks[n].xHandle == xHandle) {
break; break;
} }
} }
if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) { if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
_aTasks[n].pcTaskName = pcTaskName; _aTasks[n].pcTaskName = pcTaskName;
_aTasks[n].uxCurrentPriority = uxCurrentPriority; _aTasks[n].uxCurrentPriority = uxCurrentPriority;
_aTasks[n].pxStack = pxStack; _aTasks[n].pxStack = pxStack;
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark; _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark); SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
} else { } else {
SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark); SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
} }
} }
/********************************************************************* /*********************************************************************
* *
* SYSVIEW_DeleteTask() * SYSVIEW_DeleteTask()
* *
* Function description * Function description
* Delete a task from the internal list. * Delete a task from the internal list.
*/ */
void SYSVIEW_DeleteTask(U32 xHandle) { void SYSVIEW_DeleteTask(U32 xHandle) {
unsigned n; unsigned n;
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) { for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
if (_aTasks[n].xHandle == xHandle) { if (_aTasks[n].xHandle == xHandle) {
break; break;
} }
} }
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) { if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task."); SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
return; return;
} }
_aTasks[n].xHandle = 0; _aTasks[n].xHandle = 0;
} }
/********************************************************************* /*********************************************************************
* *
* SYSVIEW_SendTaskInfo() * SYSVIEW_SendTaskInfo()
* *
* Function description * Function description
* Record task information. * Record task information.
*/ */
void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) { void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
SEGGER_SYSVIEW_TASKINFO TaskInfo; SEGGER_SYSVIEW_TASKINFO TaskInfo;
memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
TaskInfo.TaskID = TaskID; TaskInfo.TaskID = TaskID;
TaskInfo.sName = sName; TaskInfo.sName = sName;
TaskInfo.Prio = Prio; TaskInfo.Prio = Prio;
TaskInfo.StackBase = StackBase; TaskInfo.StackBase = StackBase;
TaskInfo.StackSize = StackSize; TaskInfo.StackSize = StackSize;
SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo); SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
} }
/********************************************************************* /*********************************************************************
* *
* SYSVIEW_RecordU32x4() * SYSVIEW_RecordU32x4()
* *
* Function description * Function description
* Record an event with 4 parameters * Record an event with 4 parameters
*/ */
void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) { void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32]; U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
U8* pPayload; U8* pPayload;
// //
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
// //
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
} }
/********************************************************************* /*********************************************************************
* *
* SYSVIEW_RecordU32x5() * SYSVIEW_RecordU32x5()
* *
* Function description * Function description
* Record an event with 5 parameters * Record an event with 5 parameters
*/ */
void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) { void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32]; U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
U8* pPayload; U8* pPayload;
// //
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
// //
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
} }
/********************************************************************* /*********************************************************************
* *
* Public API structures * Public API structures
* *
********************************************************************** **********************************************************************
*/ */
// Callbacks provided to SYSTEMVIEW by FreeRTOS // Callbacks provided to SYSTEMVIEW by FreeRTOS
const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = { const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
_cbGetTime, _cbGetTime,
_cbSendTaskList, _cbSendTaskList,
}; };
/*************************** End of file ****************************/ /*************************** End of file ****************************/

View File

@ -20,7 +20,6 @@
#include "rom/ets_sys.h" #include "rom/ets_sys.h"
#include "esp_app_trace.h" #include "esp_app_trace.h"
#define LOG_LOCAL_LEVEL ESP_LOG_ERROR
#include "esp_log.h" #include "esp_log.h"
const static char *TAG = "segger_rtt"; const static char *TAG = "segger_rtt";
@ -125,7 +124,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
uint8_t event_id = *pbuf; uint8_t event_id = *pbuf;
if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) { if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
ESP_LOGE(TAG, "Too large event %d bytes!", NumBytes); ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
return 0; return 0;
} }
if (xPortGetCoreID()) { // dual core specific code if (xPortGetCoreID()) { // dual core specific code

View File

@ -0,0 +1,27 @@
#
# Generate partition binary
#
.PHONY: erase_ota blank_ota_data
GEN_EMPTY_PART := $(PYTHON) $(COMPONENT_PATH)/gen_empty_partition.py
BLANK_OTA_DATA_FILE = $(BUILD_DIR_BASE)/ota_data_initial.bin
# If there is no otadata partition, both OTA_DATA_OFFSET and BLANK_OTA_DATA_FILE
# expand to empty values.
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
$(BLANK_OTA_DATA_FILE): partition_table_get_info
$(GEN_EMPTY_PART) --size $(OTA_DATA_SIZE) $(BLANK_OTA_DATA_FILE)
$(eval BLANK_OTA_DATA_FILE = $(shell if [ $(OTA_DATA_SIZE) != 0 ]; then echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
blank_ota_data: $(BLANK_OTA_DATA_FILE)
erase_ota: partition_table_get_info
@echo $(if $(OTA_DATA_OFFSET), "Erase ota_data [addr=$(OTA_DATA_OFFSET) size=$(OTA_DATA_SIZE)] ...", $(error "ERROR: Partition table does not have ota_data partition."))
$(ESPTOOLPY_SERIAL) erase_region $(OTA_DATA_OFFSET) $(OTA_DATA_SIZE)
all: blank_ota_data
flash: blank_ota_data
clean:
rm -f $(BLANK_OTA_DATA_FILE)

View File

@ -236,19 +236,11 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
.size = it->part->size, .size = it->part->size,
}; };
if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) { if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
ret = ESP_ERR_OTA_VALIDATE_FAILED; ret = ESP_ERR_OTA_VALIDATE_FAILED;
goto cleanup; goto cleanup;
} }
#ifdef CONFIG_SECURE_BOOT_ENABLED
ret = esp_secure_boot_verify_signature(it->part->address, data.image_len);
if (ret != ESP_OK) {
ret = ESP_ERR_OTA_VALIDATE_FAILED;
goto cleanup;
}
#endif
cleanup: cleanup:
LIST_REMOVE(it, entries); LIST_REMOVE(it, entries);
free(it); free(it);
@ -381,7 +373,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
.offset = partition->address, .offset = partition->address,
.size = partition->size, .size = partition->size,
}; };
if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) { if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
return ESP_ERR_OTA_VALIDATE_FAILED; return ESP_ERR_OTA_VALIDATE_FAILED;
} }

View File

@ -0,0 +1,83 @@
#!/usr/bin/env python
#
# generates an empty binary file
#
# This tool generates an empty binary file of the required size.
#
# Copyright 2018 Espressif Systems (Shanghai) PTE LTD
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http:#www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function, division
import argparse
import os
import re
import struct
import sys
import hashlib
import binascii
__version__ = '1.0'
quiet = False
def status(msg):
""" Print status message to stderr """
if not quiet:
critical(msg)
def critical(msg):
""" Print critical message to stderr """
if not quiet:
sys.stderr.write(msg)
sys.stderr.write('\n')
def generate_blanked_file(size, output_path):
output = ""
for i in range(size):
output += b"\xFF"
try:
stdout_binary = sys.stdout.buffer # Python 3
except AttributeError:
stdout_binary = sys.stdout
with stdout_binary if output_path == '-' else open(output_path, 'wb') as f:
f.write(output)
def main():
global quiet
parser = argparse.ArgumentParser(description='Generates an empty binary file of the required size.')
parser.add_argument('--quiet', '-q', help="Don't print status messages to stderr", action='store_true')
parser.add_argument('--size', help='Size of generated the file', type=str, required=True)
parser.add_argument('output', help='Path for binary file.', nargs='?', default='-')
args = parser.parse_args()
quiet = args.quiet
size = int(args.size, 0)
if size > 0 :
generate_blanked_file(size, args.output)
return 0
class InputError(RuntimeError):
def __init__(self, e):
super(InputError, self).__init__(e)
if __name__ == '__main__':
try:
r = main()
sys.exit(r)
except InputError as e:
print(e, file=sys.stderr)
sys.exit(2)

View File

@ -132,7 +132,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
* If the OTA data partition is not present or not valid then the result is the first app partition found in the * If the OTA data partition is not present or not valid then the result is the first app partition found in the
* partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition. * partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition.
* *
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_load(ESP_IMAGE_VERIFY, ...) to verify if the * Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the
* returned partition contains a bootable image. * returned partition contains a bootable image.
* *
* @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application. * @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application.

View File

@ -0,0 +1,8 @@
set(COMPONENT_ADD_INCLUDEDIRS asio/asio/include port/include)
set(COMPONENT_SRCDIRS asio/asio/src)
set(COMPONENT_SRCEXCLUDE asio/asio/src/asio_ssl.cpp)
set(COMPONENT_REQUIRES lwip)
register_component()

1
components/asio/asio Submodule

@ -0,0 +1 @@
Subproject commit 55efc179b76139c8f9b44bf22a4aba4803f7a7bd

View File

@ -0,0 +1,6 @@
COMPONENT_ADD_INCLUDEDIRS := asio/asio/include port/include
COMPONENT_PRIV_INCLUDEDIRS := private_include
COMPONENT_SRCDIRS := asio/asio/src
COMPONENT_OBJEXCLUDE := asio/asio/src/asio_ssl.o
COMPONENT_SUBMODULES += asio

View File

@ -0,0 +1,45 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_ASIO_CONFIG_H_
#define _ESP_ASIO_CONFIG_H_
//
// Enabling exceptions only when they are enabled in menuconfig
//
# include <sdkconfig.h>
# ifndef CONFIG_CXX_EXCEPTIONS
# define ASIO_NO_EXCEPTIONS
# endif // CONFIG_CXX_EXCEPTIONS
//
// LWIP compatifility inet and address macros/functions
//
# define LWIP_COMPAT_SOCKET_INET 1
# define LWIP_COMPAT_SOCKET_ADDR 1
//
// Specific ASIO feature flags
//
# define ASIO_DISABLE_SERIAL_PORT
# define ASIO_SEPARATE_COMPILATION
# define ASIO_STANDALONE
# define ASIO_NO_TYPEID
# define ASIO_DISABLE_SIGNAL
# define ASIO_HAS_PTHREADS
# define ASIO_DISABLE_EPOLL
# define ASIO_DISABLE_EVENTFD
# define ASIO_DISABLE_SIGNAL
# define ASIO_DISABLE_SIGACTION
#endif // _ESP_ASIO_CONFIG_H_

View File

@ -0,0 +1,39 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_EXCEPTION_H_
#define _ESP_EXCEPTION_H_
//
// This exception stub is enabled only if exceptions are disabled in menuconfig
//
#if !defined(CONFIG_CXX_EXCEPTIONS) && defined (ASIO_NO_EXCEPTIONS)
#include "esp_log.h"
//
// asio exception stub
//
namespace asio {
namespace detail {
template <typename Exception>
void throw_exception(const Exception& e)
{
ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
abort();
}
}}
#endif // CONFIG_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS)
#endif // _ESP_EXCEPTION_H_

@ -1 +1 @@
Subproject commit 8bf852db77c360eebfa4b800754fdb90e29ea43e Subproject commit 299183238ffe7a3e6a5ca0af9db19c10eaca62cf

View File

@ -142,7 +142,7 @@ config SECURE_BOOT_ENABLED
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default. When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling. Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
choice SECURE_BOOTLOADER_MODE choice SECURE_BOOTLOADER_MODE
bool "Secure bootloader mode" bool "Secure bootloader mode"
@ -206,7 +206,7 @@ config SECURE_BOOT_VERIFICATION_KEY
PEM formatted private key using the espsecure.py PEM formatted private key using the espsecure.py
extract_public_key command. extract_public_key command.
Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling. Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
config SECURE_BOOT_INSECURE config SECURE_BOOT_INSECURE
bool "Allow potentially insecure options" bool "Allow potentially insecure options"
@ -217,7 +217,7 @@ config SECURE_BOOT_INSECURE
Only enable these options if you are very sure. Only enable these options if you are very sure.
Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling. Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
config FLASH_ENCRYPTION_ENABLED config FLASH_ENCRYPTION_ENABLED
bool "Enable flash encryption on boot (READ DOCS FIRST)" bool "Enable flash encryption on boot (READ DOCS FIRST)"
@ -228,7 +228,7 @@ config FLASH_ENCRYPTION_ENABLED
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
system is complicated and not always possible. system is complicated and not always possible.
Read https://esp-idf.readthedocs.io/en/latest/security/flash-encryption.html before enabling. Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html before enabling.
config FLASH_ENCRYPTION_INSECURE config FLASH_ENCRYPTION_INSECURE
bool "Allow potentially insecure options" bool "Allow potentially insecure options"
@ -275,6 +275,13 @@ config SECURE_BOOT_ALLOW_JTAG
Only set this option in testing environments. Only set this option in testing environments.
config SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
bool "Allow app partition length not 64KB aligned"
depends on SECURE_BOOT_INSECURE
help
If not set (default), app partition size must be a multiple of 64KB. App images are padded to 64KB length, and the bootloader checks any trailing bytes after the signature (before the next 64KB boundary) have not been written. This is because flash cache maps entire 64KB pages into the address space. This prevents an attacker from appending unverified data after the app image in the flash, causing it to be mapped into the address space.
Setting this option allows the app partition length to be unaligned, and disables padding of the app image to this length. It is generally not recommended to set this option, unless you have a legacy partitioning scheme which doesn't support 64KB aligned partition lengths.
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
bool "Leave UART bootloader encryption enabled" bool "Leave UART bootloader encryption enabled"

View File

@ -32,7 +32,8 @@ BOOTLOADER_MAKE= +\
V=$(V) \ V=$(V) \
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
TEST_COMPONENTS= \ TEST_COMPONENTS= \
TESTS_ALL= TESTS_ALL= \
EXCLUDE_COMPONENTS=
.PHONY: bootloader-clean bootloader-flash bootloader-list-components bootloader $(BOOTLOADER_BIN) .PHONY: bootloader-clean bootloader-flash bootloader-list-components bootloader $(BOOTLOADER_BIN)
@ -106,7 +107,7 @@ bootloader: $(BOOTLOADER_DIGEST_BIN)
$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY) $(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY)
@echo "DIGEST $(notdir $@)" @echo "DIGEST $(notdir $@)"
$(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $< $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $<
else # CONFIG_SECURE_BOOT_ENABLED && !CONFIG_SECURE_BOOTLOADER_REFLASHABLE && !CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH else # CONFIG_SECURE_BOOT_ENABLED && !CONFIG_SECURE_BOOTLOADER_REFLASHABLE && !CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
bootloader: bootloader:
@ -115,7 +116,7 @@ bootloader:
endif endif
ifndef CONFIG_SECURE_BOOT_ENABLED ifndef CONFIG_SECURE_BOOT_ENABLED
# don't build bootloader by default is secure boot is enabled # don't build bootloader by default if secure boot is enabled
all_binaries: $(BOOTLOADER_BIN) all_binaries: $(BOOTLOADER_BIN)
endif endif

View File

@ -10,7 +10,7 @@ if(NOT IDF_PATH)
"in by the parent build process.") "in by the parent build process.")
endif() endif()
set(COMPONENTS bootloader esptool_py esp32 soc bootloader_support log spi_flash micro-ecc soc) set(COMPONENTS bootloader esptool_py esp32 partition_table soc bootloader_support log spi_flash micro-ecc soc)
set(BOOTLOADER_BUILD 1) set(BOOTLOADER_BUILD 1)
add_definitions(-DBOOTLOADER_BUILD=1) add_definitions(-DBOOTLOADER_BUILD=1)

View File

@ -27,51 +27,42 @@
static const char* TAG = "boot"; static const char* TAG = "boot";
static esp_err_t select_image (esp_image_metadata_t *image_data); static int select_partition_number (bootloader_state_t *bs);
static int selected_boot_partition(const bootloader_state_t *bs); static int selected_boot_partition(const bootloader_state_t *bs);
/* /*
* We arrive here after the ROM bootloader finished loading this second stage bootloader from flash. * We arrive here after the ROM bootloader finished loading this second stage bootloader from flash.
* The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset. * The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset.
* We do have a stack, so we can do the initialization in C. * We do have a stack, so we can do the initialization in C.
*/ */
void call_start_cpu0() void __attribute__((noreturn)) call_start_cpu0()
{ {
// 1. Hardware initialization // 1. Hardware initialization
if(bootloader_init() != ESP_OK){ if (bootloader_init() != ESP_OK) {
return; bootloader_reset();
} }
// 2. Select image to boot // 2. Select the number of boot partition
esp_image_metadata_t image_data;
if(select_image(&image_data) != ESP_OK){
return;
}
// 3. Loading the selected image
bootloader_utility_load_image(&image_data);
}
// Selects image to boot
static esp_err_t select_image (esp_image_metadata_t *image_data)
{
// 1. Load partition table
bootloader_state_t bs = { 0 }; bootloader_state_t bs = { 0 };
if (!bootloader_utility_load_partition_table(&bs)) { int boot_index = select_partition_number(&bs);
ESP_LOGE(TAG, "load partition table error!"); if (boot_index == INVALID_INDEX) {
return ESP_FAIL; bootloader_reset();
}
// 2. Select boot partition
int boot_index = selected_boot_partition(&bs);
if(boot_index == INVALID_INDEX) {
return ESP_FAIL; // Unrecoverable failure (not due to corrupt ota data or bad partition contents)
} }
// 3. Load the app image for booting // 3. Load the app image for booting
if (!bootloader_utility_load_boot_image(&bs, boot_index, image_data)) { bootloader_utility_load_boot_image(&bs, boot_index);
return ESP_FAIL; }
// Select the number of boot partition
static int select_partition_number (bootloader_state_t *bs)
{
// 1. Load partition table
if (!bootloader_utility_load_partition_table(bs)) {
ESP_LOGE(TAG, "load partition table error!");
return INVALID_INDEX;
} }
return ESP_OK;
// 2. Select the number of boot partition
return selected_boot_partition(bs);
} }
/* /*

View File

@ -8,12 +8,19 @@ Linker file used to link the bootloader.
The main purpose is to make sure the bootloader can load into main memory The main purpose is to make sure the bootloader can load into main memory
without overwriting itself. without overwriting itself.
*/ */
MEMORY MEMORY
{ {
/* I/O */ /* I/O */
dport0_seg (RW) : org = 0x3FF00000, len = 0x10 dport0_seg (RW) : org = 0x3FF00000, len = 0x10
/* IRAM POOL1, used for APP CPU cache. We can abuse it in bootloader because APP CPU is still held in reset, the main app enables APP CPU cache */ /* IRAM POOL1, used for APP CPU cache. Bootloader runs from here during the final stage of loading the app because APP CPU is still held in reset, the main app enables APP CPU cache */
iram_seg (RWX) : org = 0x40078000, len = 0x8000 iram_loader_seg (RWX) : org = 0x40078000, len = 0x8000 /* 32KB, APP CPU cache */
/* 63kB, IRAM. We skip the first 1k to prevent the entry point being
placed into the same range as exception vectors in the app.
This leads to idf_monitor decoding ROM bootloader "entry 0x40080xxx"
message as one of the exception vectors, which looks scary to users.
*/
iram_seg (RWX) : org = 0x40080400, len = 0xfc00
/* 64k at the end of DRAM, after ROM bootloader stack */ /* 64k at the end of DRAM, after ROM bootloader stack */
dram_seg (RW) : org = 0x3FFF0000, len = 0x10000 dram_seg (RW) : org = 0x3FFF0000, len = 0x10000
} }
@ -24,7 +31,36 @@ ENTRY(call_start_cpu0);
SECTIONS SECTIONS
{ {
.iram1.text :
.iram_loader.text :
{
. = ALIGN (16);
_stext = .;
_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*liblog.a:(.literal .text .literal.* .text.*)
*libgcc.a:(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:efuse.*(.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.*)
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_loader_seg
.iram.text :
{ {
. = ALIGN (16); . = ALIGN (16);
*(.entry.text) *(.entry.text)
@ -88,13 +124,13 @@ SECTIONS
. = (. + 3) & ~ 3; . = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */ /* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.); __init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*))) KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors)) KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.); __init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*))) KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors)) KEEP (*(.dtors))
/* C++ exception handlers table: */ /* C++ exception handlers table: */
@ -121,7 +157,7 @@ SECTIONS
_stext = .; _stext = .;
_text_start = ABSOLUTE(.); _text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ *(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal) *(.fini.literal)
*(.fini) *(.fini)
*(.gnu.version) *(.gnu.version)

View File

@ -1,12 +1,12 @@
set(COMPONENT_SRCDIRS "src") set(COMPONENT_SRCDIRS "src")
if(${BOOTLOADER_BUILD}) if(${BOOTLOADER_BUILD})
set(COMPONENT_ADD_INCLUDEDIRS "include include_priv") set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader")
set(COMPONENT_REQUIRES) set(COMPONENT_REQUIRES)
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc) set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc)
else() else()
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_PRIV_INCLUDEDIRS "include_priv") set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader")
set(COMPONENT_REQUIRES) set(COMPONENT_REQUIRES)
set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls micro-ecc) set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls micro-ecc)
endif() endif()

View File

@ -1,10 +1,10 @@
COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_PRIV_INCLUDEDIRS := include_priv
ifdef IS_BOOTLOADER_BUILD ifdef IS_BOOTLOADER_BUILD
# share "private" headers with the bootloader component # share "include_bootloader" headers with bootloader main component
# eventual goal: all functionality that needs this lives in bootloader_support COMPONENT_ADD_INCLUDEDIRS += include_bootloader
COMPONENT_ADD_INCLUDEDIRS += include_priv else
COMPONENT_PRIV_INCLUDEDIRS := include_bootloader
endif endif
COMPONENT_SRCDIRS := src COMPONENT_SRCDIRS := src

View File

@ -68,3 +68,26 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
* @return Returns true if the list contains the label, false otherwise. * @return Returns true if the list contains the label, false otherwise.
*/ */
bool bootloader_common_label_search(const char *list, char *label); bool bootloader_common_label_search(const char *list, char *label);
/**
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
*
* This function can be used to return the SHA-256 digest of application, bootloader and data partitions.
* For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content.
* The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID.
* For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image.
* For other partition types, the result is the SHA-256 of the entire partition.
*
* @param[in] address Address of partition.
* @param[in] size Size of partition.
* @param[in] type Type of partition. For applications the type is 0, otherwise type is data.
* @param[out] out_sha_256 Returned SHA-256 digest for a given partition.
*
* @return
* - ESP_OK: In case of successful operation.
* - ESP_ERR_INVALID_ARG: The size was 0 or the sha_256 was NULL.
* - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation.
* - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image.
* - ESP_FAIL: An allocation error occurred.
*/
esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);

View File

@ -17,17 +17,17 @@
#include "esp_err.h" #include "esp_err.h"
#include "esp_flash_data_types.h" #include "esp_flash_data_types.h"
#include <stdbool.h> #include <stdbool.h>
#include "sdkconfig.h"
/* Pre-partition table fixed flash offsets */ /* Pre-partition table fixed flash offsets */
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0 #define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
#define ESP_BOOTLOADER_OFFSET 0x1000 /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */ #define ESP_BOOTLOADER_OFFSET 0x1000 /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
#define ESP_BOOTLOADER_SIZE (ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET) #define ESP_PARTITION_TABLE_OFFSET CONFIG_PARTITION_TABLE_OFFSET /* Offset of partition table. Backwards-compatible name.*/
#define ESP_PARTITION_TABLE_OFFSET 0x8000 /* Offset of partition table. Has matching value in partition_table Kconfig.projbuild file. */
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */ #define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */ #define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
/* @brief Verify the partition table (does not include verifying secure boot cryptographic signature) /* @brief Verify the partition table
* *
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.) * @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
* @param log_errors Log errors if the partition table is invalid. * @param log_errors Log errors if the partition table is invalid.
@ -35,6 +35,13 @@
* *
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid. * @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
*/ */
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions); esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
/* This function is included for compatibility with the ESP-IDF v3.x API */
inline static __attribute__((deprecated)) esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
{
return esp_partition_table_verify(partition_table, log_errors, num_partitions);
}
#endif #endif

View File

@ -36,7 +36,7 @@ typedef enum {
} esp_image_spi_mode_t; } esp_image_spi_mode_t;
/* SPI flash clock frequency */ /* SPI flash clock frequency */
enum { typedef enum {
ESP_IMAGE_SPI_SPEED_40M, ESP_IMAGE_SPI_SPEED_40M,
ESP_IMAGE_SPI_SPEED_26M, ESP_IMAGE_SPI_SPEED_26M,
ESP_IMAGE_SPI_SPEED_20M, ESP_IMAGE_SPI_SPEED_20M,
@ -96,11 +96,12 @@ typedef struct {
esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */ esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */ uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
uint32_t image_len; /* Length of image on flash, in bytes */ uint32_t image_len; /* Length of image on flash, in bytes */
uint8_t image_digest[32]; /* appended SHA-256 digest */
} esp_image_metadata_t; } esp_image_metadata_t;
/* Mode selection for esp_image_load() */ /* Mode selection for esp_image_load() */
typedef enum { typedef enum {
ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errorsors. */ ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errors. */
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, load metadata. Don't print errors. */ ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, load metadata. Don't print errors. */
#ifdef BOOTLOADER_BUILD #ifdef BOOTLOADER_BUILD
ESP_IMAGE_LOAD, /* Verify image contents, load to memory. Print errors. */ ESP_IMAGE_LOAD, /* Verify image contents, load to memory. Print errors. */
@ -110,6 +111,11 @@ typedef enum {
/** /**
* @brief Verify and (optionally, in bootloader mode) load an app image. * @brief Verify and (optionally, in bootloader mode) load an app image.
* *
* This name is deprecated and is included for compatibility with the ESP-IDF v3.x API.
* It will be removed in V4.0 version.
* Function has been renamed to esp_image_verify().
* Use function esp_image_verify() to verify a image. And use function bootloader_load_image() to load image from a bootloader space.
*
* If encryption is enabled, data will be transparently decrypted. * If encryption is enabled, data will be transparently decrypted.
* *
* @param mode Mode of operation (verify, silent verify, or load). * @param mode Mode of operation (verify, silent verify, or load).
@ -130,7 +136,60 @@ typedef enum {
* - ESP_ERR_IMAGE_INVALID if the image appears invalid. * - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid. * - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/ */
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data); esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((deprecated));
/**
* @brief Verify an app image.
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param mode Mode of operation (verify, silent verify, or load).
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Verify and load an app image (available only in space of bootloader).
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/** /**
* @brief Verify the bootloader image. * @brief Verify the bootloader image.

View File

@ -22,6 +22,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "esp_err.h"
typedef void *bootloader_sha256_handle_t; typedef void *bootloader_sha256_handle_t;
@ -30,3 +31,26 @@ bootloader_sha256_handle_t bootloader_sha256_start();
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len); void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len);
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest); void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest);
/**
* @brief Converts an array to a printable string.
*
* This function is useful for printing SHA-256 digest.
* \code{c}
* // Example of using. image_hash will be printed
* #define HASH_LEN 32 // SHA-256 digest length
* ...
* char hash_print[HASH_LEN * 2 + 1];
* hash_print[HASH_LEN * 2] = 0;
* bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
* ESP_LOGI(TAG, %s", hash_print);
* \endcode
* @param[out] out_str Output string
* @param[in] in_array_hex Pointer to input array
* @param[in] len Length of input array
*
* @return ESP_OK: Successful
* ESP_ERR_INVALID_ARG: Error in the passed arguments
*/
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len);

View File

@ -40,25 +40,25 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs);
int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs); int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs);
/** /**
* @brief Load the app image for booting. * @brief Load the selected partition and start application.
* *
* Start from partition 'start_index', if not bootable then work backwards to FACTORY_INDEX * Start from partition 'start_index', if not bootable then work backwards to FACTORY_INDEX
* (ie try any OTA slots in descending order and then the factory partition). * (ie try any OTA slots in descending order and then the factory partition).
* If still nothing, start from 'start_index + 1' and work up to highest numbered OTA partition. * If still nothing, start from 'start_index + 1' and work up to highest numbered OTA partition.
* If still nothing, try TEST_APP_INDEX. * If still nothing, try TEST_APP_INDEX.
* Everything this function calls must be located in the iram_loader_seg segment.
* *
* @param[in] bs Bootloader state structure. * @param[in] bs Bootloader state structure.
* @param[in] start_index The index from which the search for images begins. * @param[in] start_index The index from which the search for images begins.
* @param[out] result The image found.
* @return Returns true on success, false if there's no bootable app in the partition table.
*/ */
bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index, esp_image_metadata_t *result); __attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
/** /**
* @brief Loading the selected image. * @brief Software reset the ESP32
* *
* Copy loaded segments to RAM, set up caches for mapped segments, and start application. * Bootloader code should call this in the case that it cannot proceed.
* *
* @param[in] data Structure to hold on-flash image metadata. * It is not recommended to call this function from an app (if called, the app will abort).
*/ */
void bootloader_utility_load_image(const esp_image_metadata_t* image_data); __attribute__((noreturn)) void bootloader_reset(void);

View File

@ -26,6 +26,11 @@
#include "esp_flash_partitions.h" #include "esp_flash_partitions.h"
#include "bootloader_flash.h" #include "bootloader_flash.h"
#include "bootloader_common.h" #include "bootloader_common.h"
#include "soc/gpio_periph.h"
#include "esp_image_format.h"
#include "bootloader_sha.h"
#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
static const char* TAG = "boot_comm"; static const char* TAG = "boot_comm";
@ -42,6 +47,9 @@ bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s)
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec) esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec)
{ {
gpio_pad_select_gpio(num_pin); gpio_pad_select_gpio(num_pin);
if (GPIO_PIN_MUX_REG[num_pin]) {
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[num_pin]);
}
gpio_pad_pullup(num_pin); gpio_pad_pullup(num_pin);
uint32_t tm_start = esp_log_early_timestamp(); uint32_t tm_start = esp_log_early_timestamp();
if (GPIO_INPUT_GET(num_pin) == 1) { if (GPIO_INPUT_GET(num_pin) == 1) {
@ -96,26 +104,14 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
int num_partitions; int num_partitions;
bool ret = true; bool ret = true;
#ifdef CONFIG_SECURE_BOOT_ENABLED partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
if (esp_secure_boot_enabled()) {
ESP_LOGI(TAG, "Verifying partition table signature...");
err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify partition table signature.");
return false;
}
ESP_LOGD(TAG, "Partition table signature verified");
}
#endif
partitions = bootloader_mmap(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
if (!partitions) { if (!partitions) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN); ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
return false; return false;
} }
ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_ADDR, (intptr_t)partitions); ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions);
err = esp_partition_table_basic_verify(partitions, true, &num_partitions); err = esp_partition_table_verify(partitions, true, &num_partitions);
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify partition table"); ESP_LOGE(TAG, "Failed to verify partition table");
ret = false; ret = false;
@ -130,7 +126,7 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
fl_ota_data_erase = true; fl_ota_data_erase = true;
} }
// partition->label is not null-terminated string. // partition->label is not null-terminated string.
strncpy(label, (char *)&partition->label, sizeof(partition->label)); strncpy(label, (char *)&partition->label, sizeof(label) - 1);
if (fl_ota_data_erase == true || (bootloader_common_label_search(list_erase, label) == true)) { if (fl_ota_data_erase == true || (bootloader_common_label_search(list_erase, label) == true)) {
err = esp_rom_spiflash_erase_area(partition->pos.offset, partition->pos.size); err = esp_rom_spiflash_erase_area(partition->pos.offset, partition->pos.size);
if (err != ESP_OK) { if (err != ESP_OK) {
@ -153,3 +149,46 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
return ret; return ret;
} }
esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t size, int type, uint8_t *out_sha_256)
{
if (out_sha_256 == NULL || size == 0) {
return ESP_ERR_INVALID_ARG;
}
if (type == PART_TYPE_APP) {
const esp_partition_pos_t partition_pos = {
.offset = address,
.size = size,
};
esp_image_metadata_t data;
// Function esp_image_verify() verifies and fills the structure data.
// here important to get: image_digest, image_len, hash_appended.
if (esp_image_verify(ESP_IMAGE_VERIFY_SILENT, &partition_pos, &data) != ESP_OK) {
return ESP_ERR_IMAGE_INVALID;
}
if (data.image.hash_appended) {
memcpy(out_sha_256, data.image_digest, ESP_PARTITION_HASH_LEN);
return ESP_OK;
}
// If image doesn't have a appended hash then hash calculates for entire image.
size = data.image_len;
}
// If image is type by data then hash is calculated for entire image.
const void *partition_bin = bootloader_mmap(address, size);
if (partition_bin == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", address, size);
return ESP_FAIL;
}
bootloader_sha256_handle_t sha_handle = bootloader_sha256_start();
if (sha_handle == NULL) {
bootloader_munmap(partition_bin);
return ESP_ERR_NO_MEM;
}
bootloader_sha256_data(sha_handle, partition_bin, size);
bootloader_sha256_finish(sha_handle, out_sha_256);
bootloader_munmap(partition_bin);
return ESP_OK;
}

View File

@ -39,6 +39,7 @@
#include "soc/timer_group_reg.h" #include "soc/timer_group_reg.h"
#include "soc/gpio_reg.h" #include "soc/gpio_reg.h"
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "soc/rtc_wdt.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_image_format.h" #include "esp_image_format.h"
@ -143,7 +144,7 @@ static esp_err_t bootloader_main()
ets_set_appcpu_boot_addr(0); ets_set_appcpu_boot_addr(0);
/* disable watch dog here */ /* disable watch dog here */
REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN ); rtc_wdt_disable();
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN ); REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH #ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH

View File

@ -28,7 +28,10 @@ bootloader_sha256_handle_t bootloader_sha256_start()
return NULL; return NULL;
} }
mbedtls_sha256_init(ctx); mbedtls_sha256_init(ctx);
assert(mbedtls_sha256_starts_ret(ctx, false) == 0); int ret = mbedtls_sha256_starts_ret(ctx, false);
if (ret != 0) {
return NULL;
}
return ctx; return ctx;
} }
@ -36,7 +39,8 @@ void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data,
{ {
assert(handle != NULL); assert(handle != NULL);
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle; mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
assert(mbedtls_sha256_update_ret(ctx, data, data_len) == 0); int ret = mbedtls_sha256_update_ret(ctx, data, data_len);
assert(ret == 0);
} }
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest) void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest)
@ -44,7 +48,8 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
assert(handle != NULL); assert(handle != NULL);
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle; mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
if (digest != NULL) { if (digest != NULL) {
assert(mbedtls_sha256_finish_ret(ctx, digest) == 0); int ret = mbedtls_sha256_finish_ret(ctx, digest);
assert(ret == 0);
} }
mbedtls_sha256_free(ctx); mbedtls_sha256_free(ctx);
free(handle); free(handle);
@ -164,3 +169,21 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
} }
#endif #endif
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len)
{
if (out_str == NULL || in_array_hex == NULL || len == 0) {
return ESP_ERR_INVALID_ARG;
}
for (int i = 0; i < len; i++) {
for (int shift = 0; shift < 2; shift++) {
uint8_t nibble = (in_array_hex[i] >> (shift ? 0 : 4)) & 0x0F;
if (nibble < 10) {
out_str[i*2+shift] = '0' + nibble;
} else {
out_str[i*2+shift] = 'a' + nibble - 10;
}
}
}
return ESP_OK;
}

View File

@ -49,12 +49,15 @@
#include "bootloader_random.h" #include "bootloader_random.h"
#include "bootloader_config.h" #include "bootloader_config.h"
#include "bootloader_common.h" #include "bootloader_common.h"
#include "bootloader_utility.h"
#include "bootloader_sha.h"
static const char* TAG = "boot"; static const char* TAG = "boot";
/* Reduce literal size for some generic string literals */ /* Reduce literal size for some generic string literals */
#define MAP_ERR_MSG "Image contains multiple %s segments. Only the last one will be mapped." #define MAP_ERR_MSG "Image contains multiple %s segments. Only the last one will be mapped."
static void load_image(const esp_image_metadata_t* image_data);
static void unpack_load_app(const esp_image_metadata_t *data); static void unpack_load_app(const esp_image_metadata_t *data);
static void set_cache_and_start_app(uint32_t drom_addr, static void set_cache_and_start_app(uint32_t drom_addr,
uint32_t drom_load_addr, uint32_t drom_load_addr,
@ -71,26 +74,14 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
esp_err_t err; esp_err_t err;
int num_partitions; int num_partitions;
#ifdef CONFIG_SECURE_BOOT_ENABLED partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
if(esp_secure_boot_enabled()) {
ESP_LOGI(TAG, "Verifying partition table signature...");
err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify partition table signature.");
return false;
}
ESP_LOGD(TAG, "Partition table signature verified");
}
#endif
partitions = bootloader_mmap(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
if (!partitions) { if (!partitions) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN); ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
return false; return false;
} }
ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_ADDR, (intptr_t)partitions); ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions);
err = esp_partition_table_basic_verify(partitions, true, &num_partitions); err = esp_partition_table_verify(partitions, true, &num_partitions);
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify partition table"); ESP_LOGE(TAG, "Failed to verify partition table");
return false; return false;
@ -221,8 +212,8 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
bootloader_munmap(ota_select_map); bootloader_munmap(ota_select_map);
ESP_LOGD(TAG, "OTA sequence values A 0x%08x B 0x%08x", sa.ota_seq, sb.ota_seq); ESP_LOGD(TAG, "OTA sequence values A 0x%08x B 0x%08x", sa.ota_seq, sb.ota_seq);
if(sa.ota_seq == UINT32_MAX && sb.ota_seq == UINT32_MAX) { if ((sa.ota_seq == UINT32_MAX && sb.ota_seq == UINT32_MAX) || (bs->app_count == 0)) {
ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF)"); ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF) or partition table does not have bootable ota_apps (app_count=%d)", bs->app_count);
if (bs->factory.offset != 0) { if (bs->factory.offset != 0) {
ESP_LOGI(TAG, "Defaulting to factory image"); ESP_LOGI(TAG, "Defaulting to factory image");
return FACTORY_INDEX; return FACTORY_INDEX;
@ -275,7 +266,7 @@ static bool try_load_partition(const esp_partition_pos_t *partition, esp_image_m
return false; return false;
} }
#ifdef BOOTLOADER_BUILD #ifdef BOOTLOADER_BUILD
if (esp_image_load(ESP_IMAGE_LOAD, partition, data) == ESP_OK) { if (bootloader_load_image(partition, data) == ESP_OK) {
ESP_LOGI(TAG, "Loaded app from partition at offset 0x%x", ESP_LOGI(TAG, "Loaded app from partition at offset 0x%x",
partition->offset); partition->offset);
return true; return true;
@ -287,18 +278,21 @@ static bool try_load_partition(const esp_partition_pos_t *partition, esp_image_m
#define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x" #define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x"
bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index, esp_image_metadata_t *result) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index)
{ {
int index = start_index; int index = start_index;
esp_partition_pos_t part; esp_partition_pos_t part;
esp_image_metadata_t image_data;
if(start_index == TEST_APP_INDEX) { if(start_index == TEST_APP_INDEX) {
if (try_load_partition(&bs->test, result)) { if (try_load_partition(&bs->test, &image_data)) {
return true; load_image(&image_data);
} else { } else {
ESP_LOGE(TAG, "No bootable test partition in the partition table"); ESP_LOGE(TAG, "No bootable test partition in the partition table");
return false; bootloader_reset();
} }
} }
/* work backwards from start_index, down to the factory app */ /* work backwards from start_index, down to the factory app */
for(index = start_index; index >= FACTORY_INDEX; index--) { for(index = start_index; index >= FACTORY_INDEX; index--) {
part = index_to_partition(bs, index); part = index_to_partition(bs, index);
@ -306,8 +300,8 @@ bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
continue; continue;
} }
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size); ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
if (try_load_partition(&part, result)) { if (try_load_partition(&part, &image_data)) {
return true; load_image(&image_data);
} }
log_invalid_app_partition(index); log_invalid_app_partition(index);
} }
@ -319,23 +313,24 @@ bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
continue; continue;
} }
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size); ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
if (try_load_partition(&part, result)) { if (try_load_partition(&part, &image_data)) {
return true; load_image(&image_data);
} }
log_invalid_app_partition(index); log_invalid_app_partition(index);
} }
if (try_load_partition(&bs->test, result)) { if (try_load_partition(&bs->test, &image_data)) {
ESP_LOGW(TAG, "Falling back to test app as only bootable partition"); ESP_LOGW(TAG, "Falling back to test app as only bootable partition");
return true; load_image(&image_data);
} }
ESP_LOGE(TAG, "No bootable app partitions in the partition table"); ESP_LOGE(TAG, "No bootable app partitions in the partition table");
bzero(result, sizeof(esp_image_metadata_t)); bzero(&image_data, sizeof(esp_image_metadata_t));
return false; bootloader_reset();
} }
void bootloader_utility_load_image(const esp_image_metadata_t* image_data) // Copy loaded segments to RAM, set up caches for mapped segments, and start application.
static void load_image(const esp_image_metadata_t* image_data)
{ {
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED) #if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
esp_err_t err; esp_err_t err;
@ -368,8 +363,7 @@ void bootloader_utility_load_image(const esp_image_metadata_t* image_data)
so issue a system reset to ensure flash encryption so issue a system reset to ensure flash encryption
cache resets properly */ cache resets properly */
ESP_LOGI(TAG, "Resetting with flash encryption enabled..."); ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST); bootloader_reset();
return;
} }
#endif #endif
@ -463,10 +457,24 @@ static void set_cache_and_start_app(
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) // Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
ESP_LOGD(TAG, "start: 0x%08x", entry_addr); ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
typedef void (*entry_t)(void); typedef void (*entry_t)(void) __attribute__((noreturn));
entry_t entry = ((entry_t) entry_addr); entry_t entry = ((entry_t) entry_addr);
// TODO: we have used quite a bit of stack at this point. // TODO: we have used quite a bit of stack at this point.
// use "movsp" instruction to reset stack back to where ROM stack starts. // use "movsp" instruction to reset stack back to where ROM stack starts.
(*entry)(); (*entry)();
} }
void bootloader_reset(void)
{
#ifdef BOOTLOADER_BUILD
uart_tx_flush(0); /* Ensure any buffered log output is displayed */
uart_tx_flush(1);
ets_delay_us(1000); /* Allow last byte to leave FIFO */
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
while (1) { } /* This line will never be reached, used to keep gcc happy */
#else
abort(); /* This function should really not be called from application code */
#endif
}

View File

@ -75,7 +75,7 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t
static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data); static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data); static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{ {
#ifdef BOOTLOADER_BUILD #ifdef BOOTLOADER_BUILD
bool do_load = (mode == ESP_IMAGE_LOAD); bool do_load = (mode == ESP_IMAGE_LOAD);
@ -128,7 +128,7 @@ esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *
err = verify_image_header(data->start_addr, &data->image, silent); err = verify_image_header(data->start_addr, &data->image, silent);
if (err != ESP_OK) { if (err != ESP_OK) {
goto err; goto err;
} }
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) { if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
@ -189,6 +189,17 @@ goto err;
bootloader_sha256_finish(sha_handle, NULL); bootloader_sha256_finish(sha_handle, NULL);
} }
} }
if (data->image.hash_appended) {
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
if (hash == NULL) {
err = ESP_FAIL;
goto err;
}
memcpy(data->image_digest, hash, HASH_LEN);
bootloader_munmap(hash);
}
sha_handle = NULL; sha_handle = NULL;
if (err != ESP_OK) { if (err != ESP_OK) {
goto err; goto err;
@ -224,6 +235,22 @@ goto err;
return err; return err;
} }
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
return image_load(ESP_IMAGE_LOAD, part, data);
#else
return ESP_FAIL;
#endif
}
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
return image_load(mode, part, data);
}
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((alias("esp_image_verify")));
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent) static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
{ {
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
@ -446,7 +473,7 @@ esp_err_t esp_image_verify_bootloader(uint32_t *length)
.offset = ESP_BOOTLOADER_OFFSET, .offset = ESP_BOOTLOADER_OFFSET,
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET, .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
}; };
esp_err_t err = esp_image_load(ESP_IMAGE_VERIFY, esp_err_t err = esp_image_verify(ESP_IMAGE_VERIFY,
&bootloader_part, &bootloader_part,
&data); &data);
if (length != NULL) { if (length != NULL) {
@ -556,18 +583,9 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
static void debug_log_hash(const uint8_t *image_hash, const char *label) static void debug_log_hash(const uint8_t *image_hash, const char *label)
{ {
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG #if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
char hash_print[sizeof(image_hash)*2 + 1]; char hash_print[HASH_LEN * 2 + 1];
hash_print[sizeof(image_hash)*2] = 0; hash_print[HASH_LEN * 2] = 0;
for (int i = 0; i < sizeof(image_hash); i++) { bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
for (int shift = 0; shift < 2; shift++) { ESP_LOGD(TAG, "%s: %s", label, hash_print);
uint8_t nibble = (image_hash[i] >> (shift ? 0 : 4)) & 0x0F;
if (nibble < 10) {
hash_print[i*2+shift] = '0' + nibble;
} else {
hash_print[i*2+shift] = 'a' + nibble - 10;
}
}
}
ESP_LOGD(TAG, "%s: %s", label, hash_print);
#endif #endif
} }

View File

@ -254,7 +254,7 @@ static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partitio
ESP_LOGE(TAG, "Failed to read partition table data"); ESP_LOGE(TAG, "Failed to read partition table data");
return err; return err;
} }
if (esp_partition_table_basic_verify(partition_table, false, num_partitions) == ESP_OK) { if (esp_partition_table_verify(partition_table, false, num_partitions) == ESP_OK) {
ESP_LOGD(TAG, "partition table is plaintext. Encrypting..."); ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET, esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
FLASH_SECTOR_SIZE); FLASH_SECTOR_SIZE);
@ -281,7 +281,7 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit
if (partition->type == PART_TYPE_APP) { if (partition->type == PART_TYPE_APP) {
/* check if the partition holds a valid unencrypted app */ /* check if the partition holds a valid unencrypted app */
esp_image_metadata_t data_ignored; esp_image_metadata_t data_ignored;
err = esp_image_load(ESP_IMAGE_VERIFY, err = esp_image_verify(ESP_IMAGE_VERIFY,
&partition->pos, &partition->pos,
&data_ignored); &data_ignored);
should_encrypt = (err == ESP_OK); should_encrypt = (err == ESP_OK);

View File

@ -20,7 +20,7 @@
static const char *TAG = "flash_parts"; static const char *TAG = "flash_parts";
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions) esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
{ {
int md5_found = 0; int md5_found = 0;
int num_parts; int num_parts;

View File

@ -35,6 +35,7 @@
#define CMD_WRDI 0x04 #define CMD_WRDI 0x04
#define CMD_RDSR 0x05 #define CMD_RDSR 0x05
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */ #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 */
static const char *TAG = "qio_mode"; static const char *TAG = "qio_mode";
@ -65,6 +66,11 @@ static void write_status_8b_wrsr2(unsigned new_status);
/* Write 16 bit status using WRSR */ /* Write 16 bit status using WRSR */
static void write_status_16b_wrsr(unsigned new_status); static void write_status_16b_wrsr(unsigned new_status);
/* Read 8 bit status of XM25QU64A */
static unsigned read_status_8b_xmc25qu64a();
/* Write 8 bit status of XM25QU64A */
static void write_status_8b_xmc25qu64a(unsigned new_status);
#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */ #define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */
#ifndef CONFIG_BOOTLOADER_SPI_WP_PIN // Set in menuconfig if SPI flasher config is set to a quad mode #ifndef CONFIG_BOOTLOADER_SPI_WP_PIN // Set in menuconfig if SPI flasher config is set to a quad mode
@ -84,11 +90,12 @@ static void write_status_16b_wrsr(unsigned new_status);
Searching of this table stops when the first match is found. Searching of this table stops when the first match is found.
*/ */
const static qio_info_t chip_data[] = { const static qio_info_t chip_data[] = {
/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */ /* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */
{ "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, { "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 },
{ "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */ { "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */
{ "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 }, { "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
{ "GD", 0xC8, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 }, { "GD", 0xC8, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
{ "XM25QU64A", 0x20, 0x3817, 0xFFFF, read_status_8b_xmc25qu64a, write_status_8b_xmc25qu64a, 6 },
/* Final entry is default entry, if no other IDs have matched. /* Final entry is default entry, if no other IDs have matched.
@ -96,7 +103,7 @@ const static qio_info_t chip_data[] = {
GigaDevice (mfg ID 0xC8, flash IDs including 4016), GigaDevice (mfg ID 0xC8, flash IDs including 4016),
FM25Q32 (QOUT mode only, mfg ID 0xA1, flash IDs including 4016) FM25Q32 (QOUT mode only, mfg ID 0xA1, flash IDs including 4016)
*/ */
{ NULL, 0xFF, 0xFFFF, 0xFFFF, read_status_8b_rdsr2, write_status_8b_wrsr2, 1 }, { NULL, 0xFF, 0xFFFF, 0xFFFF, read_status_8b_rdsr2, write_status_8b_wrsr2, 1 },
}; };
#define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t)) #define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t))
@ -246,6 +253,24 @@ static void write_status_16b_wrsr(unsigned new_status)
execute_flash_command(CMD_WRSR, new_status, 16, 0); execute_flash_command(CMD_WRSR, new_status, 16, 0);
} }
static unsigned read_status_8b_xmc25qu64a()
{
execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
uint32_t read_status = execute_flash_command(CMD_RDSR, 0, 0, 8);
execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
return read_status;
}
static void write_status_8b_xmc25qu64a(unsigned new_status)
{
execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
execute_flash_command(CMD_WRSR, new_status, 8, 0);
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
}
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len) static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
{ {
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val; uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;

View File

@ -84,10 +84,13 @@ esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block
return ESP_FAIL; return ESP_FAIL;
} }
ESP_LOGD(TAG, "Verifying secure boot signature");
is_valid = uECC_verify(signature_verification_key_start, is_valid = uECC_verify(signature_verification_key_start,
image_digest, image_digest,
DIGEST_LEN, DIGEST_LEN,
sig_block->signature, sig_block->signature,
uECC_secp256r1()); uECC_secp256r1());
ESP_LOGD(TAG, "Verification result %d", is_valid);
return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID; return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID;
} }

View File

@ -25,7 +25,7 @@ TEST_CASE("Verify bootloader image in flash", "[bootloader_support]")
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET, .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
}; };
esp_image_metadata_t data = { 0 }; esp_image_metadata_t data = { 0 };
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &fake_bootloader_partition, &data)); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_verify(ESP_IMAGE_VERIFY, &fake_bootloader_partition, &data));
TEST_ASSERT_NOT_EQUAL(0, data.image_len); TEST_ASSERT_NOT_EQUAL(0, data.image_len);
uint32_t bootloader_length = 0; uint32_t bootloader_length = 0;
@ -43,7 +43,7 @@ TEST_CASE("Verify unit test app image", "[bootloader_support]")
.size = running->size, .size = running->size,
}; };
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &running_pos, &data)); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_verify(ESP_IMAGE_VERIFY, &running_pos, &data));
TEST_ASSERT_NOT_EQUAL(0, data.image_len); TEST_ASSERT_NOT_EQUAL(0, data.image_len);
TEST_ASSERT_TRUE(data.image_len <= running->size); TEST_ASSERT_TRUE(data.image_len <= running->size);
} }

View File

@ -70,7 +70,7 @@ menu "MODEM SLEEP Options"
config BTDM_CONTROLLER_MODEM_SLEEP config BTDM_CONTROLLER_MODEM_SLEEP
bool "Bluetooth modem sleep" bool "Bluetooth modem sleep"
depends on BT_ENABLED depends on BT_ENABLED
default y default n
help help
Enable/disable bluetooth controller low power mode. Enable/disable bluetooth controller low power mode.
Note that currently there is problem in the combination use of bluetooth modem sleep and Dynamic Frequency Scaling(DFS). So do not enable DFS if bluetooth modem sleep is in use. Note that currently there is problem in the combination use of bluetooth modem sleep and Dynamic Frequency Scaling(DFS). So do not enable DFS if bluetooth modem sleep is in use.
@ -155,6 +155,11 @@ config CLASSIC_BT_ENABLED
help help
For now this option needs "SMP_ENABLE" to be set to yes For now this option needs "SMP_ENABLE" to be set to yes
config BT_SSP_ENABLE
bool "Enable Secure Simple Pairing"
depends on CLASSIC_BT_ENABLED
default CLASSIC_BT_ENABLED
config A2DP_ENABLE config A2DP_ENABLE
bool "A2DP" bool "A2DP"
depends on CLASSIC_BT_ENABLED depends on CLASSIC_BT_ENABLED
@ -220,6 +225,13 @@ config GATTC_ENABLE
help help
This option can be close when the app work only on gatt server mode This option can be close when the app work only on gatt server mode
config GATTC_CACHE_NVS_FLASH
bool "Save gattc cache data to nvs flash"
depends on GATTC_ENABLE
default n
help
This select can save gattc cache data to nvs flash
config BLE_SMP_ENABLE config BLE_SMP_ENABLE
bool "Include BLE security module(SMP)" bool "Include BLE security module(SMP)"
depends on BLUEDROID_ENABLED depends on BLUEDROID_ENABLED
@ -997,6 +1009,15 @@ config BT_BLE_DYNAMIC_ENV_MEMORY
help help
This select can make the allocation of memory will become more flexible This select can make the allocation of memory will become more flexible
config BLE_HOST_QUEUE_CONGESTION_CHECK
bool "BLE queue congestion check"
depends on BLUEDROID_ENABLED
default n
help
When scanning and scan duplicate is not enabled, if there are a lot of adv packets around or application layer
handling adv packets is slow, it will cause the controller memory to run out. if enabled, adv packets will be
lost when host queue is congested.
config BLE_SCAN_DUPLICATE config BLE_SCAN_DUPLICATE
bool "BLE Scan Duplicate Options" bool "BLE Scan Duplicate Options"
depends on BLUEDROID_ENABLED depends on BLUEDROID_ENABLED
@ -1007,8 +1028,8 @@ config BLE_SCAN_DUPLICATE
config DUPLICATE_SCAN_CACHE_SIZE config DUPLICATE_SCAN_CACHE_SIZE
int "Maximum number of devices in scan duplicate filter" int "Maximum number of devices in scan duplicate filter"
depends on BLE_SCAN_DUPLICATE depends on BLE_SCAN_DUPLICATE
range 10 200 range 10 1000
default 20 default 50
help help
Maximum number of devices which can be recorded in scan duplicate filter. Maximum number of devices which can be recorded in scan duplicate filter.
When the maximum amount of device in the filter is reached, the cache will be refreshed. When the maximum amount of device in the filter is reached, the cache will be refreshed.
@ -1023,8 +1044,8 @@ config BLE_MESH_SCAN_DUPLICATE_EN
config MESH_DUPLICATE_SCAN_CACHE_SIZE config MESH_DUPLICATE_SCAN_CACHE_SIZE
int "Maximum number of Mesh adv packets in scan duplicate filter" int "Maximum number of Mesh adv packets in scan duplicate filter"
depends on BLE_MESH_SCAN_DUPLICATE_EN depends on BLE_MESH_SCAN_DUPLICATE_EN
range 10 200 range 10 1000
default 50 default 100
help help
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh. Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
When the maximum amount of device in the filter is reached, the cache will be refreshed. When the maximum amount of device in the filter is reached, the cache will be refreshed.

View File

@ -240,4 +240,65 @@ esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list)
return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
} }
#if (BT_SSP_INCLUDED == TRUE)
esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
void *value, uint8_t len)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_SET_SECURITY_PARAM;
arg.set_security_param.param_type = param_type;
arg.set_security_param.len = len;
arg.set_security_param.value = value;
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_PASSKEY_REPLY;
arg.passkey_reply.accept = accept;
arg.passkey_reply.passkey = passkey;
memcpy(arg.passkey_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_CONFIRM_REPLY;
arg.confirm_reply.accept = accept;
memcpy(arg.confirm_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /*(BT_SSP_INCLUDED == TRUE)*/
#endif /* #if BTC_GAP_BT_INCLUDED == TRUE */ #endif /* #if BTC_GAP_BT_INCLUDED == TRUE */

View File

@ -164,6 +164,7 @@ esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((start_handle == 0) && (end_handle == 0)) { if ((start_handle == 0) && (end_handle == 0)) {
*count = 0;
return ESP_GATT_INVALID_HANDLE; return ESP_GATT_INVALID_HANDLE;
} }
@ -206,6 +207,7 @@ esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) { if (start_handle == 0 && end_handle == 0) {
*count = 0;
return ESP_GATT_INVALID_HANDLE; return ESP_GATT_INVALID_HANDLE;
} }
@ -247,6 +249,7 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (char_handle == 0) { if (char_handle == 0) {
*count = 0;
return ESP_GATT_INVALID_HANDLE; return ESP_GATT_INVALID_HANDLE;
} }
@ -269,6 +272,7 @@ esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) { if (start_handle == 0 && end_handle == 0) {
*count = 0;
return ESP_GATT_INVALID_HANDLE; return ESP_GATT_INVALID_HANDLE;
} }
@ -291,6 +295,7 @@ esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((start_handle == 0 && end_handle == 0) && (type != ESP_GATT_DB_DESCRIPTOR)) { if ((start_handle == 0 && end_handle == 0) && (type != ESP_GATT_DB_DESCRIPTOR)) {
*count = 0;
return ESP_GATT_INVALID_HANDLE; return ESP_GATT_INVALID_HANDLE;
} }
@ -308,6 +313,7 @@ esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) { if (start_handle == 0 && end_handle == 0) {
*count = 0;
return ESP_GATT_INVALID_HANDLE; return ESP_GATT_INVALID_HANDLE;
} }

View File

@ -261,7 +261,7 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) { if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
LOG_ERROR("%s, the l2cap chanel is congest.", __func__); LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
return ESP_FAIL; return ESP_FAIL;
} }

View File

@ -102,6 +102,19 @@ typedef enum {
ESP_BT_COD_SRVC_INFORMATION = 0x400, /*!< Information, e.g., WEB-server, WAP-server */ ESP_BT_COD_SRVC_INFORMATION = 0x400, /*!< Information, e.g., WEB-server, WAP-server */
} esp_bt_cod_srvc_t; } esp_bt_cod_srvc_t;
typedef enum {
ESP_BT_SP_IOCAP_MODE = 0, /*!< Set IO mode */
//ESP_BT_SP_OOB_DATA, //TODO /*!< Set OOB data */
} esp_bt_sp_param_t;
/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */
#define ESP_BT_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */
#define ESP_BT_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
#define ESP_BT_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in stack/btm_api.h */
#define ESP_BT_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */
typedef uint8_t esp_bt_io_cap_t; /*!< combination of the io capability */
/// Bits of major service class field /// Bits of major service class field
#define ESP_BT_COD_SRVC_BIT_MASK (0xffe000) /*!< Major service bit mask */ #define ESP_BT_COD_SRVC_BIT_MASK (0xffe000) /*!< Major service bit mask */
#define ESP_BT_COD_SRVC_BIT_OFFSET (13) /*!< Major service bit offset */ #define ESP_BT_COD_SRVC_BIT_OFFSET (13) /*!< Major service bit offset */
@ -149,6 +162,9 @@ typedef enum {
ESP_BT_GAP_RMT_SRVCS_EVT, /*!< get remote services event */ ESP_BT_GAP_RMT_SRVCS_EVT, /*!< get remote services event */
ESP_BT_GAP_RMT_SRVC_REC_EVT, /*!< get remote service record event */ ESP_BT_GAP_RMT_SRVC_REC_EVT, /*!< get remote service record event */
ESP_BT_GAP_AUTH_CMPL_EVT, /*!< AUTH complete event */ ESP_BT_GAP_AUTH_CMPL_EVT, /*!< AUTH complete event */
ESP_BT_GAP_CFM_REQ_EVT, /*!< Simple Pairing User Confirmation request. */
ESP_BT_GAP_KEY_NOTIF_EVT, /*!< Simple Pairing Passkey Notification */
ESP_BT_GAP_KEY_REQ_EVT, /*!< Simple Pairing Passkey request */
ESP_BT_GAP_READ_RSSI_DELTA_EVT, /*!< read rssi event */ ESP_BT_GAP_READ_RSSI_DELTA_EVT, /*!< read rssi event */
ESP_BT_GAP_EVT_MAX, ESP_BT_GAP_EVT_MAX,
} esp_bt_gap_cb_event_t; } esp_bt_gap_cb_event_t;
@ -216,6 +232,29 @@ typedef union {
esp_bt_status_t stat; /*!< authentication complete status */ esp_bt_status_t stat; /*!< authentication complete status */
uint8_t device_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< device name */ uint8_t device_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< device name */
} auth_cmpl; /*!< authentication complete parameter struct */ } auth_cmpl; /*!< authentication complete parameter struct */
/**
* @brief ESP_BT_GAP_CFM_REQ_EVT
*/
struct cfm_req_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
uint32_t num_val; /*!< the numeric value for comparison. */
} cfm_req; /*!< confirm request parameter struct */
/**
* @brief ESP_BT_GAP_KEY_NOTIF_EVT
*/
struct key_notif_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
uint32_t passkey; /*!< the numeric value for passkey entry. */
} key_notif; /*!< passkey notif parameter struct */
/**
* @brief ESP_BT_GAP_KEY_REQ_EVT
*/
struct key_req_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
} key_req; /*!< passkey request parameter struct */
} esp_bt_gap_cb_param_t; } esp_bt_gap_cb_param_t;
/** /**
@ -447,6 +486,53 @@ int esp_bt_gap_get_bond_device_num(void);
*/ */
esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list); esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list);
#if (BT_SSP_INCLUDED == TRUE)
/**
* @brief Set a GAP security parameter value. Overrides the default value.
*
* @param[in] param_type : the type of the param which is to be set
* @param[in] value : the param value
* @param[in] len : the length of the param value
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*
*/
esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
void *value, uint8_t len);
/**
* @brief Reply the key value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer
* @param[in] accept : passkey entry sucessful or declined.
* @param[in] passkey : passkey value, must be a 6 digit number,
* can be lead by 0.
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*
*/
esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey);
/**
* @brief Reply the confirm value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer device
* @param[in] accept : numbers to compare are the same or different.
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*
*/
esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
#endif /*(BT_SSP_INCLUDED == TRUE)*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -422,7 +422,7 @@ typedef struct {
* @brief service element * @brief service element
*/ */
typedef struct { typedef struct {
bool is_primary; /*!< The service flag, ture if the service is primary service, else is secondly service */ bool is_primary; /*!< The service flag, true if the service is primary service, else is secondly service */
uint16_t start_handle; /*!< The start handle of the service */ uint16_t start_handle; /*!< The start handle of the service */
uint16_t end_handle; /*!< The end handle of the service */ uint16_t end_handle; /*!< The end handle of the service */
esp_bt_uuid_t uuid; /*!< The uuid of the service */ esp_bt_uuid_t uuid; /*!< The uuid of the service */

View File

@ -350,7 +350,8 @@ esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db
uint8_t max_nb_attr, uint8_t max_nb_attr,
uint8_t srvc_inst_id); uint8_t srvc_inst_id);
/** /**
* @brief This function is called to add an included service. After included * @brief This function is called to add an included service. This function have to be called between
* 'esp_ble_gatts_create_service' and 'esp_ble_gatts_add_char'. After included
* service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT * service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
* is reported the included service ID. * is reported the included service ID.
* *

View File

@ -815,7 +815,7 @@ void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS; p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
if (p_data->role_res.hci_status != HCI_SUCCESS) { if (p_data->role_res.hci_status != HCI_SUCCESS) {
p_scb->role &= ~BTA_AV_ROLE_START_INT; p_scb->role &= ~BTA_AV_ROLE_START_INT;
bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr); bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
/* start failed because of role switch. */ /* start failed because of role switch. */
start.chnl = p_scb->chnl; start.chnl = p_scb->chnl;
start.status = BTA_AV_FAIL_ROLE; start.status = BTA_AV_FAIL_ROLE;
@ -956,7 +956,7 @@ void bta_av_do_disc_a2d (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_scb->sec_mask = p_data->api_open.sec_mask; p_scb->sec_mask = p_data->api_open.sec_mask;
p_scb->use_rc = p_data->api_open.use_rc; p_scb->use_rc = p_data->api_open.use_rc;
bta_sys_app_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr); bta_sys_app_open(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
/* allocate discovery database */ /* allocate discovery database */
if (p_scb->p_disc_db == NULL) { if (p_scb->p_disc_db == NULL) {
@ -1330,7 +1330,7 @@ void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_MEDIUM); L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_MEDIUM);
L2CA_SetChnlFlushability (p_scb->l2c_cid, TRUE); L2CA_SetChnlFlushability (p_scb->l2c_cid, TRUE);
bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr); bta_sys_conn_open(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
memset(&p_scb->q_info, 0, sizeof(tBTA_AV_Q_INFO)); memset(&p_scb->q_info, 0, sizeof(tBTA_AV_Q_INFO));
p_scb->l2c_bufs = 0; p_scb->l2c_bufs = 0;
@ -1933,8 +1933,7 @@ void bta_av_do_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
if ((p_scb->started == FALSE) && ((p_scb->role & BTA_AV_ROLE_START_INT) == 0)) { if ((p_scb->started == FALSE) && ((p_scb->role & BTA_AV_ROLE_START_INT) == 0)) {
p_scb->role |= BTA_AV_ROLE_START_INT; p_scb->role |= BTA_AV_ROLE_START_INT;
bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr); bta_sys_busy(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
AVDT_StartReq(&p_scb->avdt_handle, 1); AVDT_StartReq(&p_scb->avdt_handle, 1);
} else if (p_scb->started) { } else if (p_scb->started) {
p_scb->role |= BTA_AV_ROLE_START_INT; p_scb->role |= BTA_AV_ROLE_START_INT;
@ -1969,7 +1968,7 @@ void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %p", APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %p",
bta_av_cb.audio_open_cnt, p_data); bta_av_cb.audio_open_cnt, p_data);
bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr); bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1) { if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1) {
policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
} }
@ -2239,7 +2238,7 @@ void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE)) { if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE)) {
p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS; p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
if (p_data->hdr.offset == BTA_AV_RS_FAIL) { if (p_data->hdr.offset == BTA_AV_RS_FAIL) {
bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr); bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
start.chnl = p_scb->chnl; start.chnl = p_scb->chnl;
start.status = BTA_AV_FAIL_ROLE; start.status = BTA_AV_FAIL_ROLE;
start.hndl = p_scb->hndl; start.hndl = p_scb->hndl;
@ -2275,9 +2274,9 @@ void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
} }
/* tell role manager to check M/S role */ /* tell role manager to check M/S role */
bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr); bta_sys_conn_open(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr); bta_sys_busy(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
if (p_scb->media_type == AVDT_MEDIA_AUDIO) { if (p_scb->media_type == AVDT_MEDIA_AUDIO) {
/* in normal logic, conns should be bta_av_cb.audio_count - 1, /* in normal logic, conns should be bta_av_cb.audio_count - 1,
@ -2364,7 +2363,7 @@ void bta_av_start_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
UNUSED(p_data); UNUSED(p_data);
if (p_scb->started == FALSE && p_scb->co_started == FALSE) { if (p_scb->started == FALSE && p_scb->co_started == FALSE) {
bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr); bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
notify_start_failed(p_scb); notify_start_failed(p_scb);
} }
@ -2413,7 +2412,8 @@ void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
event = BTA_AV_OPEN_EVT; event = BTA_AV_OPEN_EVT;
p_scb->open_status = BTA_AV_SUCCESS; p_scb->open_status = BTA_AV_SUCCESS;
bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr); bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
bta_av_cleanup(p_scb, p_data); bta_av_cleanup(p_scb, p_data);
(*bta_av_cb.p_cback)(event, &data); (*bta_av_cb.p_cback)(event, &data);
} else { } else {
@ -2432,7 +2432,8 @@ void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
data.close.disc_rsn = p_scb->disc_rsn; data.close.disc_rsn = p_scb->disc_rsn;
event = BTA_AV_CLOSE_EVT; event = BTA_AV_CLOSE_EVT;
bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr); bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
bta_av_cleanup(p_scb, p_data); bta_av_cleanup(p_scb, p_data);
(*bta_av_cb.p_cback)(event, &data); (*bta_av_cb.p_cback)(event, &data);
} }
@ -2506,7 +2507,7 @@ void bta_av_suspend_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_scb->cong = FALSE; p_scb->cong = FALSE;
} }
bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr); bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1) { if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1) {
policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
} }

View File

@ -153,6 +153,7 @@ enum {
#define BTA_AV_MULTI_AV_SUPPORTED 0x01 #define BTA_AV_MULTI_AV_SUPPORTED 0x01
#define BTA_AV_MULTI_AV_IN_USE 0x02 #define BTA_AV_MULTI_AV_IN_USE 0x02
#define TSEP_TO_SYS_ID(x) ((x) == AVDT_TSEP_SRC ? BTA_ID_AV : BTA_ID_AVK)
/***************************************************************************** /*****************************************************************************
** Data types ** Data types

View File

@ -72,9 +72,9 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
/* Extended Inquiry Response */ /* Extended Inquiry Response */
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE) #if (BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data); static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data);
#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */ #endif /* (BT_SSP_INCLUDED == TRUE) */
static void bta_dm_set_eir (char *local_name); static void bta_dm_set_eir (char *local_name);
#if (SDP_INCLUDED == TRUE) #if (SDP_INCLUDED == TRUE)
@ -218,7 +218,7 @@ const tBTM_APPL_INFO bta_security = {
&bta_dm_new_link_key_cback, &bta_dm_new_link_key_cback,
&bta_dm_authentication_complete_cback, &bta_dm_authentication_complete_cback,
&bta_dm_bond_cancel_complete_cback, &bta_dm_bond_cancel_complete_cback,
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) #if (BT_SSP_INCLUDED == TRUE)
&bta_dm_sp_cback, &bta_dm_sp_cback,
#else #else
NULL, NULL,
@ -374,6 +374,12 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH ); bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
/* notify BTA DM is now unactive */ /* notify BTA DM is now unactive */
bta_dm_cb.is_bta_dm_active = FALSE; bta_dm_cb.is_bta_dm_active = FALSE;
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
#if (GATTC_INCLUDED == TRUE && GATTC_CACHE_NVS == TRUE)
/* clear the gattc cache address list */
bta_gattc_co_cache_addr_deinit();
#endif
#endif
} else if ( status == BTA_SYS_HW_ON_EVT ) { } else if ( status == BTA_SYS_HW_ON_EVT ) {
/* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error. /* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error.
* We need to revisit when this platform has more than one BLuetooth H/W chip */ * We need to revisit when this platform has more than one BLuetooth H/W chip */
@ -403,7 +409,7 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
BTM_SetDeviceClass (dev_class); BTM_SetDeviceClass (dev_class);
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
#if (GATTC_INCLUDED == TRUE) #if (GATTC_INCLUDED == TRUE && GATTC_CACHE_NVS == TRUE)
// load the gattc cache address list // load the gattc cache address list
bta_gattc_co_cache_addr_init(); bta_gattc_co_cache_addr_init();
#endif /* #if (GATTC_INCLUDED = TRUE) */ #endif /* #if (GATTC_INCLUDED = TRUE) */
@ -596,16 +602,16 @@ void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data)
if (p_data->read_tx_power.read_tx_power_cb != NULL) { if (p_data->read_tx_power.read_tx_power_cb != NULL) {
BTM_BleReadAdvTxPower(p_data->read_tx_power.read_tx_power_cb); BTM_BleReadAdvTxPower(p_data->read_tx_power.read_tx_power_cb);
} else { } else {
APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__); APPL_TRACE_ERROR("%s(), the callback function can't be NULL.", __func__);
} }
} }
void bta_dm_ble_read_rssi(tBTA_DM_MSG *p_data) void bta_dm_ble_read_rssi(tBTA_DM_MSG *p_data)
{ {
if (p_data->rssi.read_rssi_cb != NULL) { if (p_data->rssi.read_rssi_cb != NULL) {
BTM_ReadRSSI(p_data->rssi.remote_addr, p_data->rssi.read_rssi_cb); BTM_ReadRSSI(p_data->rssi.remote_addr, p_data->rssi.transport, p_data->rssi.read_rssi_cb);
} else { } else {
APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__); APPL_TRACE_ERROR("%s(), the callback function can't be NULL.", __func__);
} }
} }
@ -692,25 +698,29 @@ void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
** Description Removes device, Disconnects ACL link if required. ** Description Removes device, Disconnects ACL link if required.
**** ****
*******************************************************************************/ *******************************************************************************/
void bta_dm_process_remove_device(BD_ADDR bd_addr) static void bta_dm_process_remove_device(BD_ADDR bd_addr, tBT_TRANSPORT transport)
{ {
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection before unpair */ /* need to remove all pending background connection before unpair */
BTA_GATTC_CancelOpen(0, bd_addr, FALSE); BTA_GATTC_CancelOpen(0, bd_addr, FALSE);
#endif #endif
BTM_SecDeleteDevice(bd_addr); BTM_SecDeleteDevice(bd_addr, transport);
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* remove all cached GATT information */ /* remove all cached GATT information */
BTA_GATTC_Refresh(bd_addr); BTA_GATTC_Refresh(bd_addr, false);
#endif #endif
if (bta_dm_cb.p_sec_cback) { if (bta_dm_cb.p_sec_cback) {
tBTA_DM_SEC sec_event; tBTA_DM_SEC sec_event;
bdcpy(sec_event.link_down.bd_addr, bd_addr); bdcpy(sec_event.link_down.bd_addr, bd_addr);
sec_event.link_down.status = HCI_SUCCESS; sec_event.link_down.status = HCI_SUCCESS;
bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event); if (transport == BT_TRANSPORT_LE){
bta_dm_cb.p_sec_cback(BTA_DM_BLE_DEV_UNPAIRED_EVT, &sec_event);
} else {
bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
}
} }
} }
@ -728,32 +738,22 @@ void bta_dm_remove_device(tBTA_DM_MSG *p_data)
return; return;
} }
BD_ADDR other_address;
bdcpy(other_address, p_dev->bd_addr);
/* If ACL exists for the device in the remove_bond message*/ /* If ACL exists for the device in the remove_bond message*/
BOOLEAN continue_delete_dev = FALSE; BOOLEAN continue_delete_dev = FALSE;
UINT8 other_transport = BT_TRANSPORT_INVALID; UINT8 transport = p_dev->transport;
if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) || if (BTM_IsAclConnectionUp(p_dev->bd_addr, transport)) {
BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR)) {
APPL_TRACE_DEBUG("%s: ACL Up count %d", __func__, bta_dm_cb.device_list.count); APPL_TRACE_DEBUG("%s: ACL Up count %d", __func__, bta_dm_cb.device_list.count);
continue_delete_dev = FALSE; continue_delete_dev = FALSE;
/* Take the link down first, and mark the device for removal when disconnected */ /* Take the link down first, and mark the device for removal when disconnected */
for (int i = 0; i < bta_dm_cb.device_list.count; i++) { for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr)) { if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr)
&& bta_dm_cb.device_list.peer_device[i].transport == transport) {
bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING; bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
btm_remove_acl( p_dev->bd_addr, bta_dm_cb.device_list.peer_device[i].transport); btm_remove_acl( p_dev->bd_addr, bta_dm_cb.device_list.peer_device[i].transport);
APPL_TRACE_DEBUG("%s:transport = %d", __func__, APPL_TRACE_DEBUG("%s:transport = %d", __func__,
bta_dm_cb.device_list.peer_device[i].transport); bta_dm_cb.device_list.peer_device[i].transport);
/* save the other transport to check if device is connected on other_transport */
if (bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_LE) {
other_transport = BT_TRANSPORT_BR_EDR;
} else {
other_transport = BT_TRANSPORT_LE;
}
break; break;
} }
} }
@ -761,35 +761,9 @@ void bta_dm_remove_device(tBTA_DM_MSG *p_data)
continue_delete_dev = TRUE; continue_delete_dev = TRUE;
} }
// If it is DUMO device and device is paired as different address, unpair that device
// if different address
BOOLEAN continue_delete_other_dev = FALSE;
if ((other_transport && (BTM_ReadConnectedTransportAddress(other_address, other_transport))) ||
(!other_transport && (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) ||
BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE)))) {
continue_delete_other_dev = FALSE;
/* Take the link down first, and mark the device for removal when disconnected */
for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, other_address)) {
bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
btm_remove_acl(other_address, bta_dm_cb.device_list.peer_device[i].transport);
break;
}
}
} else {
APPL_TRACE_DEBUG("%s: continue to delete the other dev ", __func__);
continue_delete_other_dev = TRUE;
}
/* Delete the device mentioned in the msg */ /* Delete the device mentioned in the msg */
if (continue_delete_dev) { if (continue_delete_dev) {
bta_dm_process_remove_device(p_dev->bd_addr); bta_dm_process_remove_device(p_dev->bd_addr, transport);
}
/* Delete the other paired device too */
BD_ADDR dummy_bda = {0};
if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0)) {
bta_dm_process_remove_device(other_address);
} }
} }
@ -880,14 +854,14 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data)
} }
/* if to remove the device from security database ? do it now */ /* if to remove the device from security database ? do it now */
else if (p_remove_acl->remove_dev) { else if (p_remove_acl->remove_dev) {
if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr)) { if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr, p_remove_acl->transport)) {
APPL_TRACE_ERROR("delete device from security database failed."); APPL_TRACE_ERROR("delete device from security database failed.");
} }
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection if any */ /* need to remove all pending background connection if any */
BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE); BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE);
/* remove all cached GATT information */ /* remove all cached GATT information */
BTA_GATTC_Refresh(p_remove_acl->bd_addr); BTA_GATTC_Refresh(p_remove_acl->bd_addr, false);
#endif #endif
} }
/* otherwise, no action needed */ /* otherwise, no action needed */
@ -1121,6 +1095,28 @@ void bta_dm_confirm(tBTA_DM_MSG *p_data)
} }
#endif ///SMP_INCLUDED == TRUE #endif ///SMP_INCLUDED == TRUE
/*******************************************************************************
**
** Function bta_dm_key_req
**
** Description Send the user passkey request reply in response to a
** request from BTM
**
** Returns void
**
*******************************************************************************/
#if (SMP_INCLUDED == TRUE && BT_SSP_INCLUDED)
void bta_dm_key_req(tBTA_DM_MSG *p_data)
{
tBTM_STATUS res = BTM_NOT_AUTHORIZED;
if (p_data->key_req.accept == TRUE) {
res = BTM_SUCCESS;
}
BTM_PasskeyReqReply(res, p_data->key_req.bd_addr, p_data->key_req.passkey);
}
#endif ///SMP_INCLUDED == TRUE && BT_SSP_INCLUDED
/******************************************************************************* /*******************************************************************************
** **
** Function bta_dm_loc_oob ** Function bta_dm_loc_oob
@ -2841,7 +2837,7 @@ static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev
return BTM_SUCCESS; return BTM_SUCCESS;
} }
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) #if (BT_SSP_INCLUDED == TRUE)
/******************************************************************************* /*******************************************************************************
** **
** Function bta_dm_sp_cback ** Function bta_dm_sp_cback
@ -2865,7 +2861,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
/* TODO_SP */ /* TODO_SP */
switch (event) { switch (event) {
case BTM_SP_IO_REQ_EVT: case BTM_SP_IO_REQ_EVT:
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) #if (BT_SSP_INCLUDED == TRUE)
/* translate auth_req */ /* translate auth_req */
bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap, bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
&p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig); &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
@ -2877,7 +2873,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data); APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
break; break;
case BTM_SP_IO_RSP_EVT: case BTM_SP_IO_RSP_EVT:
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) #if (BT_SSP_INCLUDED == TRUE)
bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap, bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
p_data->io_rsp.oob_data, p_data->io_rsp.auth_req ); p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
#endif #endif
@ -2892,10 +2888,10 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps; sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
/* continue to next case */ /* continue to next case */
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) #if (BT_SSP_INCLUDED == TRUE)
/* Passkey entry mode, mobile device with output capability is very /* Passkey entry mode, mobile device with output capability is very
unlikely to receive key request, so skip this event */ unlikely to receive key request, so skip this event */
/*case BTM_SP_KEY_REQ_EVT: */ case BTM_SP_KEY_REQ_EVT:
case BTM_SP_KEY_NOTIF_EVT: case BTM_SP_KEY_NOTIF_EVT:
#endif #endif
if (BTM_SP_CFM_REQ_EVT == event) { if (BTM_SP_CFM_REQ_EVT == event) {
@ -2943,6 +2939,27 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
} }
} }
if (BTM_SP_KEY_REQ_EVT == event) {
pin_evt = BTA_DM_SP_KEY_REQ_EVT;
/* If the device name is not known, save bdaddr and devclass
and initiate a name request with values from key_notif */
if (p_data->key_notif.bd_name[0] == 0) {
bta_dm_cb.pin_evt = pin_evt;
bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
return BTM_CMD_STARTED;
}
APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
} else {
bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
(char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
}
}
bta_dm_cb.p_sec_cback(pin_evt, &sec_event); bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
break; break;
@ -2996,7 +3013,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
APPL_TRACE_EVENT("dm status: %d", status); APPL_TRACE_EVENT("dm status: %d", status);
return status; return status;
} }
#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */ #endif /* (BT_SSP_INCLUDED == TRUE) */
#endif ///SMP_INCLUDED == TRUE #endif ///SMP_INCLUDED == TRUE
@ -3283,7 +3300,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
} }
if ( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) { if ( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) {
if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) { if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bta_dm_cb.device_list.peer_device[i].transport)) {
issue_unpair_cb = TRUE; issue_unpair_cb = TRUE;
} }
@ -3331,12 +3348,12 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
} }
} }
if (conn.link_down.is_removed) { if (conn.link_down.is_removed) {
BTM_SecDeleteDevice(p_bda); BTM_SecDeleteDevice(p_bda, p_data->acl_change.transport);
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection */ /* need to remove all pending background connection */
BTA_GATTC_CancelOpen(0, p_bda, FALSE); BTA_GATTC_CancelOpen(0, p_bda, FALSE);
/* remove all cached GATT information */ /* remove all cached GATT information */
BTA_GATTC_Refresh(p_bda); BTA_GATTC_Refresh(p_bda, false);
#endif #endif
} }
@ -3345,7 +3362,11 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
if ( bta_dm_cb.p_sec_cback ) { if ( bta_dm_cb.p_sec_cback ) {
bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn); bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
if ( issue_unpair_cb ) { if ( issue_unpair_cb ) {
bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn); if (p_data->acl_change.transport == BT_TRANSPORT_LE) {
bta_dm_cb.p_sec_cback(BTA_DM_BLE_DEV_UNPAIRED_EVT, &conn);
} else {
bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
}
} }
} }
} }
@ -3505,12 +3526,12 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__); APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
} }
} else { } else {
BTM_SecDeleteDevice (remote_bd_addr); BTM_SecDeleteDevice (remote_bd_addr, bta_dm_cb.device_list.peer_device[index].transport);
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection */ /* need to remove all pending background connection */
BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE); BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
/* remove all cached GATT information */ /* remove all cached GATT information */
BTA_GATTC_Refresh(remote_bd_addr); BTA_GATTC_Refresh(remote_bd_addr, false);
#endif #endif
} }
} }
@ -4257,7 +4278,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
switch (event) { switch (event) {
case BTM_LE_IO_REQ_EVT: case BTM_LE_IO_REQ_EVT:
// #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) // #if (BT_SSP_INCLUDED == TRUE)
bta_dm_co_ble_io_req(bda, bta_dm_co_ble_io_req(bda,
&p_data->io_req.io_cap, &p_data->io_req.io_cap,
@ -4659,7 +4680,7 @@ void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data)
void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data) void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
{ {
if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) { if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) {
APPL_TRACE_ERROR("Invalid BTA event,cann't stop the BLE adverting\n"); APPL_TRACE_ERROR("Invalid BTA event,can't stop the BLE adverting\n");
} }
btm_ble_stop_adv(); btm_ble_stop_adv();

View File

@ -206,12 +206,13 @@ void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb)
} }
} }
void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_CMPL_CB *cmpl_cb) void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb)
{ {
tBTA_DM_API_READ_RSSI *p_msg; tBTA_DM_API_READ_RSSI *p_msg;
if ((p_msg = (tBTA_DM_API_READ_RSSI *)osi_malloc(sizeof(tBTA_DM_API_READ_RSSI))) != NULL) { if ((p_msg = (tBTA_DM_API_READ_RSSI *)osi_malloc(sizeof(tBTA_DM_API_READ_RSSI))) != NULL) {
p_msg->hdr.event = BTA_DM_API_BLE_READ_RSSI_EVT; p_msg->hdr.event = BTA_DM_API_BLE_READ_RSSI_EVT;
memcpy(p_msg->remote_addr, remote_addr, sizeof(BD_ADDR)); memcpy(p_msg->remote_addr, remote_addr, sizeof(BD_ADDR));
p_msg->transport = transport;
p_msg->read_rssi_cb = cmpl_cb; p_msg->read_rssi_cb = cmpl_cb;
bta_sys_sendmsg(p_msg); bta_sys_sendmsg(p_msg);
} }
@ -510,6 +511,29 @@ void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept)
} }
} }
/*******************************************************************************
**
** Function BTA_DmPasskeyReqReply
**
** Description This function is called to provide the passkey for
** Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT
**
** Returns void
**
*******************************************************************************/
#if (BT_SSP_INCLUDED == TRUE)
void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey)
{
tBTA_DM_API_KEY_REQ *p_msg;
if ((p_msg = (tBTA_DM_API_KEY_REQ *) osi_malloc(sizeof(tBTA_DM_API_KEY_REQ))) != NULL) {
p_msg->hdr.event = BTA_DM_API_KEY_REQ_EVT;
bdcpy(p_msg->bd_addr, bd_addr);
p_msg->accept = accept;
p_msg->passkey = passkey;
bta_sys_sendmsg(p_msg);
}
}
#endif ///BT_SSP_INCLUDED == TRUE
/******************************************************************************* /*******************************************************************************
** **
** Function BTA_DmAddDevice ** Function BTA_DmAddDevice
@ -569,7 +593,7 @@ void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, LINK_KEY link_key,
** Returns void ** Returns void
** **
*******************************************************************************/ *******************************************************************************/
tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr) tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr, tBT_TRANSPORT transport)
{ {
tBTA_DM_API_REMOVE_DEVICE *p_msg; tBTA_DM_API_REMOVE_DEVICE *p_msg;
@ -578,6 +602,7 @@ tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr)
p_msg->hdr.event = BTA_DM_API_REMOVE_DEVICE_EVT; p_msg->hdr.event = BTA_DM_API_REMOVE_DEVICE_EVT;
bdcpy(p_msg->bd_addr, bd_addr); bdcpy(p_msg->bd_addr, bd_addr);
p_msg->transport = transport;
bta_sys_sendmsg(p_msg); bta_sys_sendmsg(p_msg);
} else { } else {
return BTA_FAILURE; return BTA_FAILURE;

View File

@ -44,6 +44,16 @@ tBTE_APPL_CFG bte_appl_cfg = {
}; };
#endif #endif
#if (defined CLASSIC_BT_INCLUDED && CLASSIC_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE)
#include "common/bte_appl.h"
#include "btm_int.h"
tBTE_BT_APPL_CFG bte_bt_appl_cfg = {
0, //Todo, Authentication requirements
BTM_LOCAL_IO_CAPS,
NULL, //Todo, OOB data
};
#endif
/******************************************************************************* /*******************************************************************************
** **
** Function bta_dm_co_get_compress_memory ** Function bta_dm_co_get_compress_memory
@ -65,6 +75,34 @@ BOOLEAN bta_dm_co_get_compress_memory(tBTA_SYS_ID id, UINT8 **memory_p, UINT32 *
return TRUE; return TRUE;
} }
/*******************************************************************************
**
** Function bta_dm_co_bt_set_io_cap
**
** Description This function is used to set IO capabilities
**
** Parameters bt_io_cap - IO capabilities
**
** @return - ESP_BT_STATUS_SUCCESS : success
** - other : failed
**
*******************************************************************************/
esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap)
{
esp_err_t ret = ESP_BT_STATUS_SUCCESS;
#if (BT_SSP_INCLUDED == TRUE)
if(bt_io_cap < BTM_IO_CAP_MAX ) {
bte_bt_appl_cfg.bt_io_cap = bt_io_cap;
btm_cb.devcb.loc_io_caps = bt_io_cap;
ret = ESP_BT_STATUS_SUCCESS;
} else {
ret = ESP_BT_STATUS_FAIL;
APPL_TRACE_ERROR("%s error:Invalid io cap value.",__func__);
}
#endif ///BT_SSP_INCLUDED == TRUE
return ret;
}
/******************************************************************************* /*******************************************************************************
** **
** Function bta_dm_co_io_req ** Function bta_dm_co_io_req

View File

@ -74,12 +74,15 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
/* simple pairing events */ /* simple pairing events */
#if (SMP_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE)
bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */ bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */
#if (BT_SSP_INCLUDED == TRUE)
bta_dm_key_req, /* 19 BTA_DM_API_KEY_REQ_EVT */
#endif ///BT_SSP_INCLUDED == TRUE
bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */ bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */
#endif ///SMP_INCLUDED == TRUE #endif ///SMP_INCLUDED == TRUE
#if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE) #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
bta_dm_loc_oob, /* 20 BTA_DM_API_LOC_OOB_EVT */ bta_dm_loc_oob, /* 21 BTA_DM_API_LOC_OOB_EVT */
bta_dm_ci_io_req_act, /* 21 BTA_DM_CI_IO_REQ_EVT */ bta_dm_ci_io_req_act, /* 22 BTA_DM_CI_IO_REQ_EVT */
bta_dm_ci_rmt_oob_act, /* 22 BTA_DM_CI_RMT_OOB_EVT */ bta_dm_ci_rmt_oob_act, /* 23 BTA_DM_CI_RMT_OOB_EVT */
#endif /* BTM_OOB_INCLUDED */ #endif /* BTM_OOB_INCLUDED */
@ -119,7 +122,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
data to HCI */ data to HCI */
bta_dm_ble_set_adv_config_raw, /* BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT */ bta_dm_ble_set_adv_config_raw, /* BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT */
bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */ bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
/* New function to allow set raw scan /* New function to allow set raw scan
response data to HCI */ response data to HCI */
bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */ bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */
bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */ bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */

View File

@ -71,7 +71,9 @@ enum {
#if (SMP_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE)
/* simple pairing events */ /* simple pairing events */
BTA_DM_API_CONFIRM_EVT, BTA_DM_API_CONFIRM_EVT,
#if (BT_SSP_INCLUDED == TRUE)
BTA_DM_API_KEY_REQ_EVT,
#endif ///BT_SSP_INCLUDED == TRUE
BTA_DM_API_SET_ENCRYPTION_EVT, BTA_DM_API_SET_ENCRYPTION_EVT,
#endif ///SMP_INCLUDED == TRUE #endif ///SMP_INCLUDED == TRUE
#if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE) #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
@ -196,6 +198,7 @@ typedef struct {
typedef struct { typedef struct {
BT_HDR hdr; BT_HDR hdr;
BD_ADDR remote_addr; BD_ADDR remote_addr;
tBTA_TRANSPORT transport;
tBTA_CMPL_CB *read_rssi_cb; tBTA_CMPL_CB *read_rssi_cb;
}tBTA_DM_API_READ_RSSI; }tBTA_DM_API_READ_RSSI;
@ -291,6 +294,14 @@ typedef struct {
BOOLEAN accept; BOOLEAN accept;
} tBTA_DM_API_CONFIRM; } tBTA_DM_API_CONFIRM;
/* data type for BTA_DM_API_KEY_REQ_EVT */
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
BOOLEAN accept;
UINT32 passkey;
} tBTA_DM_API_KEY_REQ;
/* data type for BTA_DM_CI_IO_REQ_EVT */ /* data type for BTA_DM_CI_IO_REQ_EVT */
typedef struct { typedef struct {
BT_HDR hdr; BT_HDR hdr;
@ -391,6 +402,7 @@ typedef struct {
typedef struct { typedef struct {
BT_HDR hdr; BT_HDR hdr;
BD_ADDR bd_addr; BD_ADDR bd_addr;
UINT8 transport;
} tBTA_DM_API_REMOVE_DEVICE; } tBTA_DM_API_REMOVE_DEVICE;
/* data type for BTA_DM_API_EXECUTE_CBACK_EVT */ /* data type for BTA_DM_API_EXECUTE_CBACK_EVT */
@ -746,6 +758,7 @@ typedef union {
tBTA_DM_API_LOC_OOB loc_oob; tBTA_DM_API_LOC_OOB loc_oob;
tBTA_DM_API_CONFIRM confirm; tBTA_DM_API_CONFIRM confirm;
tBTA_DM_API_KEY_REQ key_req;
tBTA_DM_CI_IO_REQ ci_io_req; tBTA_DM_CI_IO_REQ ci_io_req;
tBTA_DM_CI_RMT_OOB ci_rmt_oob; tBTA_DM_CI_RMT_OOB ci_rmt_oob;
@ -1223,6 +1236,7 @@ extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
#endif #endif
extern void bta_dm_set_encryption(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_confirm(tBTA_DM_MSG *p_data);
extern void bta_dm_key_req(tBTA_DM_MSG *p_data);
#if (BTM_OOB_INCLUDED == TRUE) #if (BTM_OOB_INCLUDED == TRUE)
extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data); extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data);
extern void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data); extern void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data);

View File

@ -65,6 +65,7 @@ static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb);
static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda); static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested); static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
static tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda); static tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda);
static tGATT_CBACK bta_gattc_cl_cback = { static tGATT_CBACK bta_gattc_cl_cback = {
@ -72,7 +73,7 @@ static tGATT_CBACK bta_gattc_cl_cback = {
bta_gattc_cmpl_cback, bta_gattc_cmpl_cback,
bta_gattc_disc_res_cback, bta_gattc_disc_res_cback,
bta_gattc_disc_cmpl_cback, bta_gattc_disc_cmpl_cback,
NULL, bta_gattc_req_cback,
bta_gattc_enc_cmpl_cback, bta_gattc_enc_cmpl_cback,
bta_gattc_cong_cback bta_gattc_cong_cback
}; };
@ -666,11 +667,16 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
if (p_clcb->p_srcb->p_srvc_cache == NULL || if (p_clcb->p_srcb->p_srvc_cache == NULL ||
p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) { p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) { if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
#if (GATTC_CACHE_NVS == TRUE)
p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD; p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
if (bta_gattc_cache_load(p_clcb)) { if (bta_gattc_cache_load(p_clcb)) {
p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
} else { /* cache is building */ //register service change
bta_gattc_register_service_change_notify(p_clcb->bta_conn_id, p_clcb->bda);
} else
#endif
{ /* cache is building */
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
/* cache load failure, start discovery */ /* cache load failure, start discovery */
bta_gattc_start_discover(p_clcb, NULL); bta_gattc_start_discover(p_clcb, NULL);
@ -1016,9 +1022,10 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
list_free(p_clcb->p_srcb->p_srvc_cache); list_free(p_clcb->p_srcb->p_srvc_cache);
p_clcb->p_srcb->p_srvc_cache = NULL; p_clcb->p_srcb->p_srvc_cache = NULL;
} }
#if(GATTC_CACHE_NVS == TRUE)
/* used to reset cache in application */ /* used to reset cache in application */
bta_gattc_cache_reset(p_clcb->p_srcb->server_bda); bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
#endif
} }
if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) { if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
/* release pending attribute list buffer */ /* release pending attribute list buffer */
@ -1291,6 +1298,7 @@ void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
cb_data.write.conn_id = p_clcb->bta_conn_id; cb_data.write.conn_id = p_clcb->bta_conn_id;
if (p_conn && p_conn->svc_change_descr_handle == cb_data.write.handle) { if (p_conn && p_conn->svc_change_descr_handle == cb_data.write.handle) {
if(cb_data.write.status != BTA_GATT_OK) { if(cb_data.write.status != BTA_GATT_OK) {
p_conn->write_remote_svc_change_ccc_done = FALSE;
APPL_TRACE_ERROR("service change write ccc failed"); APPL_TRACE_ERROR("service change write ccc failed");
} }
return; return;
@ -1716,7 +1724,6 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
} }
if (found) { if (found) {
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
return; return;
} }
} }
@ -1726,8 +1733,6 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
p_srvc_cb->p_srvc_cache = NULL; p_srvc_cb->p_srvc_cache = NULL;
} }
} }
/* used to reset cache in application */
bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
} }
void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
@ -1873,6 +1878,10 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
/* if connection available, refresh cache by doing discovery now */ /* if connection available, refresh cache by doing discovery now */
if (p_clcb != NULL) { if (p_clcb != NULL) {
tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_clcb->bda);
if(p_conn) {
p_conn->write_remote_svc_change_ccc_done = FALSE;
}
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
} }
} }
@ -2085,6 +2094,27 @@ static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
} }
} }
/*******************************************************************************
**
** Function bta_gattc_req_cback
**
** Description GATT request command callback for BTA GATT client.
**
** Returns void
**
********************************************************************************/
static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
{
/* GATTC doesn't need to process the GATT request commands.
* Add this callback here to avoid the warning "Call back not found for application"
* printed in the function gatt_sr_send_req_callback
* */
UNUSED (conn_id);
UNUSED (trans_id) ;
UNUSED (type);
UNUSED (p_data);
}
#if BLE_INCLUDED == TRUE #if BLE_INCLUDED == TRUE
/******************************************************************************* /*******************************************************************************
** **
@ -2257,6 +2287,10 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}}; tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}}; tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}};
tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}}; tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find_alloc(remote_bda);
if(p_conn && p_conn->write_remote_svc_change_ccc_done) {
return SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
}
p_srcb = bta_gattc_find_srcb(remote_bda); p_srcb = bta_gattc_find_srcb(remote_bda);
if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) { if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
@ -2321,9 +2355,9 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
} }
if (gatt_ccc_found == TRUE){ if (gatt_ccc_found == TRUE){
tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find_alloc(remote_bda);
if (p_conn) { if (p_conn) {
p_conn->svc_change_descr_handle = p_desc->handle; p_conn->svc_change_descr_handle = p_desc->handle;
p_conn->write_remote_svc_change_ccc_done = TRUE;
} }
result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS; result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
uint16_t indicate_value = GATT_CLT_CONFIG_INDICATION; uint16_t indicate_value = GATT_CLT_CONFIG_INDICATION;

View File

@ -912,12 +912,20 @@ tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if,
** Description Refresh the server cache of the remote device ** Description Refresh the server cache of the remote device
** **
** Parameters remote_bda: remote device BD address. ** Parameters remote_bda: remote device BD address.
** erase_flash: delete cache from nvs flash
** **
** Returns void ** Returns void
** **
*******************************************************************************/ *******************************************************************************/
void BTA_GATTC_Refresh(BD_ADDR remote_bda) void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash)
{ {
#if(GATTC_CACHE_NVS == TRUE)
if(erase_flash) {
/* used to reset cache in application */
bta_gattc_cache_reset(remote_bda);
}
#endif
tBTA_GATTC_API_OPEN *p_buf; tBTA_GATTC_API_OPEN *p_buf;
if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) { if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) {

View File

@ -346,6 +346,7 @@ static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
tBT_UUID *p_uuid, tBT_UUID *p_uuid,
UINT8 property, UINT8 property,
UINT16 incl_srvc_s_handle, UINT16 incl_srvc_s_handle,
UINT16 incl_srvc_e_handle,
tBTA_GATTC_ATTR_TYPE type) tBTA_GATTC_ATTR_TYPE type)
{ {
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
@ -370,18 +371,13 @@ static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
isvc->handle = handle; isvc->handle = handle;
memcpy(&isvc->uuid, p_uuid, sizeof(tBT_UUID)); memcpy(&isvc->uuid, p_uuid, sizeof(tBT_UUID));
isvc->incl_srvc_s_handle = incl_srvc_s_handle; isvc->incl_srvc_s_handle = incl_srvc_s_handle;
isvc->incl_srvc_e_handle = incl_srvc_e_handle;
isvc->owning_service = service; isvc->owning_service = service;
isvc->included_service = bta_gattc_find_matching_service( isvc->included_service = bta_gattc_find_matching_service(
p_srvc_cb->p_srvc_cache, incl_srvc_s_handle); p_srvc_cb->p_srvc_cache, incl_srvc_s_handle);
if (!isvc->included_service) { if (!isvc->included_service) {
// if it is a secondary service, wait to update later // if can't find included service, wait to update later
if(property == 0){ p_srvc_cb->update_incl_srvc = true;
p_srvc_cb->update_sec_sev = true;
} else {
APPL_TRACE_ERROR("%s: Illegal action to add non-existing included service!", __func__);
osi_free(isvc);
return GATT_WRONG_STATE;
}
} }
list_append(service->included_svc, isvc); list_append(service->included_svc, isvc);
@ -604,10 +600,10 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
return; return;
} }
} }
//update include service when have secondary service // if update_incl_srvc is true, update include service
if(p_srvc_cb->update_sec_sev) { if(p_srvc_cb->update_incl_srvc) {
bta_gattc_update_include_service(p_srvc_cb->p_srvc_cache); bta_gattc_update_include_service(p_srvc_cb->p_srvc_cache);
p_srvc_cb->update_sec_sev = false; p_srvc_cb->update_incl_srvc = false;
} }
/* no service found at all, the end of server discovery*/ /* no service found at all, the end of server discovery*/
APPL_TRACE_DEBUG("%s no more services found", __func__); APPL_TRACE_DEBUG("%s no more services found", __func__);
@ -622,10 +618,11 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
} }
#endif #endif
#if(GATTC_CACHE_NVS == TRUE)
/* save cache to NV */ /* save cache to NV */
p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE; p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE;
bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id); bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id);
#endif
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
} }
/******************************************************************************* /*******************************************************************************
@ -995,6 +992,7 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
&p_data->value.incl_service.service_type, &p_data->value.incl_service.service_type,
pri_srvc, pri_srvc,
p_data->value.incl_service.s_handle, p_data->value.incl_service.s_handle,
p_data->value.incl_service.e_handle,
BTA_GATTC_ATTR_TYPE_INCL_SRVC); BTA_GATTC_ATTR_TYPE_INCL_SRVC);
break; break;
@ -1008,10 +1006,14 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
break; break;
case GATT_DISC_CHAR_DSCPT: case GATT_DISC_CHAR_DSCPT:
bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0, bta_gattc_add_attr_to_cache(p_srvc_cb,
0 /* incl_srvc_handle */, p_data->handle,
&p_data->type,
0,
0 /* incl_srvc_s_handle */,
0 /* incl_srvc_e_handle */,
BTA_GATTC_ATTR_TYPE_CHAR_DESCR); BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
break; break;
} }
} }
} }
@ -1352,7 +1354,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
BTGATT_DB_INCLUDED_SERVICE, BTGATT_DB_INCLUDED_SERVICE,
p_isvc->handle, p_isvc->handle,
p_isvc->incl_srvc_s_handle /* s_handle */, p_isvc->incl_srvc_s_handle /* s_handle */,
0 /* e_handle */, p_isvc->incl_srvc_e_handle /* e_handle */,
p_isvc->handle, p_isvc->handle,
p_isvc->uuid, p_isvc->uuid,
0 /* property */); 0 /* property */);
@ -1650,7 +1652,8 @@ void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 en
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
if (p_clcb == NULL) { if (p_clcb == NULL) {
return NULL; *count = 0;
return;
} }
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb; tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
@ -1919,12 +1922,21 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
break; break;
case BTA_GATTC_ATTR_TYPE_CHAR_DESCR: case BTA_GATTC_ATTR_TYPE_CHAR_DESCR:
bta_gattc_add_attr_to_cache(p_srvc_cb,
p_attr->s_handle,
&p_attr->uuid,
p_attr->prop,
p_attr->incl_srvc_s_handle,
p_attr->incl_srvc_e_handle,
p_attr->attr_type);
break;
case BTA_GATTC_ATTR_TYPE_INCL_SRVC: case BTA_GATTC_ATTR_TYPE_INCL_SRVC:
bta_gattc_add_attr_to_cache(p_srvc_cb, bta_gattc_add_attr_to_cache(p_srvc_cb,
p_attr->s_handle, p_attr->s_handle,
&p_attr->uuid, &p_attr->uuid,
p_attr->prop, p_attr->prop,
p_attr->incl_srvc_handle, p_attr->incl_srvc_s_handle,
p_attr->incl_srvc_e_handle,
p_attr->attr_type); p_attr->attr_type);
break; break;
} }
@ -1943,8 +1955,8 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
** **
*******************************************************************************/ *******************************************************************************/
void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle, void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle,
UINT16 e_handle, tBT_UUID uuid, UINT8 prop, UINT16 incl_srvc_handle, UINT16 e_handle, tBT_UUID uuid, UINT8 prop, UINT16 incl_srvc_s_handle,
BOOLEAN is_primary) UINT16 incl_srvc_e_handle, BOOLEAN is_primary)
{ {
p_attr->s_handle = s_handle; p_attr->s_handle = s_handle;
p_attr->e_handle = e_handle; p_attr->e_handle = e_handle;
@ -1952,7 +1964,8 @@ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_han
p_attr->is_primary = is_primary; p_attr->is_primary = is_primary;
p_attr->id = 0; p_attr->id = 0;
p_attr->prop = prop; p_attr->prop = prop;
p_attr->incl_srvc_handle = incl_srvc_handle; p_attr->incl_srvc_s_handle = incl_srvc_s_handle;
p_attr->incl_srvc_e_handle = incl_srvc_e_handle;
memcpy(&p_attr->uuid, &uuid, sizeof(tBT_UUID)); memcpy(&p_attr->uuid, &uuid, sizeof(tBT_UUID));
} }
@ -1992,7 +2005,8 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
p_cur_srvc->e_handle, p_cur_srvc->e_handle,
p_cur_srvc->uuid, p_cur_srvc->uuid,
0 /* properties */, 0 /* properties */,
0 /* incl_srvc_handle */, 0 /* incl_srvc_s_handle */,
0 /* incl_srvc_e_handle */,
p_cur_srvc->is_primary); p_cur_srvc->is_primary);
} }
@ -2013,7 +2027,8 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
0, 0,
p_char->uuid, p_char->uuid,
p_char->properties, p_char->properties,
0 /* incl_srvc_handle */, 0 /* incl_srvc_s_handle */,
0 /* incl_srvc_e_handle */,
FALSE); FALSE);
if (!p_char->descriptors || list_is_empty(p_char->descriptors)) if (!p_char->descriptors || list_is_empty(p_char->descriptors))
@ -2029,7 +2044,8 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
0, 0,
p_desc->uuid, p_desc->uuid,
0 /* properties */, 0 /* properties */,
0 /* incl_srvc_handle */, 0 /* incl_srvc_s_handle */,
0 /* incl_srvc_e_handle */,
FALSE); FALSE);
} }
} }
@ -2048,6 +2064,7 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
p_isvc->uuid, p_isvc->uuid,
0 /* properties */, 0 /* properties */,
p_isvc->included_service->s_handle, p_isvc->included_service->s_handle,
p_isvc->included_service->e_handle,
FALSE); FALSE);
} }
} }

View File

@ -75,7 +75,7 @@ static void cacheReset(BD_ADDR bda)
#else #else
static const char *cache_key = "gattc_cahe_key"; static const char *cache_key = "gattc_cache_key";
static const char *cache_addr = "cache_addr_tab"; static const char *cache_addr = "cache_addr_tab";
nvs_handle nvs_fp; nvs_handle nvs_fp;
@ -144,7 +144,7 @@ static void cacheReset(BD_ADDR bda)
char fname[255] = {0}; char fname[255] = {0};
getFilename(fname, bda); getFilename(fname, bda);
UINT8 index = 0; UINT8 index = 0;
//cache_env.cache_addr //cache_env.cache_addr
if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) { if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) {
//clear the association address pending in the source address. //clear the association address pending in the source address.
bta_gattc_co_cache_clear_assoc_addr(bda); bta_gattc_co_cache_clear_assoc_addr(bda);
@ -152,7 +152,22 @@ static void cacheReset(BD_ADDR bda)
nvs_erase_all(cache_env.cache_addr[index].cache_fp); nvs_erase_all(cache_env.cache_addr[index].cache_fp);
nvs_close(cache_env.cache_addr[index].cache_fp); nvs_close(cache_env.cache_addr[index].cache_fp);
cache_env.cache_addr[index].is_open = FALSE; cache_env.cache_addr[index].is_open = FALSE;
} else {
cacheOpen(bda, false, &index);
if (cache_env.cache_addr[index].is_open) {
nvs_erase_all(cache_env.cache_addr[index].cache_fp);
nvs_close(cache_env.cache_addr[index].cache_fp);
cache_env.cache_addr[index].is_open = FALSE;
} else {
APPL_TRACE_ERROR("%s cacheOpen failed", __func__);
return;
}
} }
if(cache_env.num_addr == 0) {
APPL_TRACE_ERROR("%s cache addr list error", __func__);
return;
}
UINT8 num = cache_env.num_addr; UINT8 num = cache_env.num_addr;
//delete the server_bda in the addr_info list. //delete the server_bda in the addr_info list.
for(UINT8 i = index; i < (num - 1); i++) { for(UINT8 i = index; i < (num - 1); i++) {
@ -160,6 +175,40 @@ static void cacheReset(BD_ADDR bda)
} }
//reduced the number address counter also //reduced the number address counter also
cache_env.num_addr--; cache_env.num_addr--;
//update addr list to nvs flash
if(cache_env.num_addr > 0) {
//update
UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
if(!p_buf) {
APPL_TRACE_ERROR("%s malloc error", __func__);
return;
}
UINT16 length = cache_env.num_addr*(sizeof(BD_ADDR) + sizeof(hash_key_t));
for (UINT8 i = 0; i < cache_env.num_addr; i++) {
//copy the address to the buffer.
memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), cache_env.cache_addr[i].addr, sizeof(BD_ADDR));
//copy the hash key to the buffer.
memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR),
cache_env.cache_addr[i].hash_key, sizeof(hash_key_t));
}
if (cache_env.is_open) {
if (nvs_set_blob(cache_env.addr_fp, cache_key, p_buf, length) != ESP_OK) {
APPL_TRACE_WARNING("%s, nvs set blob failed", __func__);
}
}
osi_free(p_buf);
} else {
//erase
if (cache_env.is_open) {
nvs_erase_all(cache_env.addr_fp);
nvs_close(cache_env.addr_fp);
cache_env.is_open = FALSE;
} else {
APPL_TRACE_WARNING("cache_env status is error");
}
}
} }
} }
@ -325,10 +374,11 @@ void bta_gattc_co_cache_addr_init(void)
esp_err_t err_code; esp_err_t err_code;
UINT8 num_addr; UINT8 num_addr;
UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF); UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
size_t length = 0; size_t length = MAX_ADDR_LIST_CACHE_BUF;
if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) { if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) {
cache_env.addr_fp = fp; cache_env.addr_fp = fp;
cache_env.is_open = TRUE;
// Read previously saved blob if available // Read previously saved blob if available
if ((err_code = nvs_get_blob(fp, cache_key, p_buf, &length)) != ESP_OK) { if ((err_code = nvs_get_blob(fp, cache_key, p_buf, &length)) != ESP_OK) {
if(err_code != ESP_ERR_NVS_NOT_FOUND) { if(err_code != ESP_ERR_NVS_NOT_FOUND) {
@ -361,6 +411,26 @@ void bta_gattc_co_cache_addr_init(void)
return; return;
} }
void bta_gattc_co_cache_addr_deinit(void)
{
if(!cache_env.is_open) {
return;
}
nvs_close(cache_env.addr_fp);
cache_env.is_open = false;
for(UINT8 i = 0; i< cache_env.num_addr; i++) {
cache_addr_info_t *addr_info = &cache_env.cache_addr[i];
if(addr_info) {
nvs_close(addr_info->cache_fp);
addr_info->is_open = false;
if(addr_info->assoc_addr) {
list_free(addr_info->assoc_addr);
}
}
}
}
BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda) BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda)
{ {
UINT8 addr_index = 0; UINT8 addr_index = 0;

View File

@ -125,7 +125,7 @@ void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RANGE *p_h
** **
** Returns TRUE - if the request is processed successfully and ** Returns TRUE - if the request is processed successfully and
** the response is returned in p_rsp. ** the response is returned in p_rsp.
** FASLE - if the request can not be processed ** FALSE - if the request can not be processed
** **
*******************************************************************************/ *******************************************************************************/
BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd, BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd,

View File

@ -300,7 +300,7 @@ typedef struct {
UINT16 attr_index; /* cahce NV saving/loading attribute index */ UINT16 attr_index; /* cahce NV saving/loading attribute index */
UINT16 mtu; UINT16 mtu;
bool update_sec_sev; bool update_incl_srvc;
} tBTA_GATTC_SERV; } tBTA_GATTC_SERV;
#ifndef BTA_GATTC_NOTIF_REG_MAX #ifndef BTA_GATTC_NOTIF_REG_MAX
@ -365,7 +365,8 @@ typedef struct {
typedef struct { typedef struct {
BOOLEAN in_use; BOOLEAN in_use;
BD_ADDR remote_bda; BD_ADDR remote_bda;
UINT16 svc_change_descr_handle; UINT16 svc_change_descr_handle;
BOOLEAN write_remote_svc_change_ccc_done;
} tBTA_GATTC_CONN; } tBTA_GATTC_CONN;
enum { enum {

View File

@ -46,7 +46,7 @@ static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = {
BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
.retrans_effort = BTM_ESCO_RETRANS_POWER, .retrans_effort = BTM_ESCO_RETRANS_OFF,
}, },
/* ESCO CVSD */ /* ESCO CVSD */
{ {

View File

@ -631,10 +631,13 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK;
#define BTA_DM_SP_RMT_OOB_EXT_EVT 23 /* Simple Pairing Remote OOB Extended Data request. */ #define BTA_DM_SP_RMT_OOB_EXT_EVT 23 /* Simple Pairing Remote OOB Extended Data request. */
#define BTA_DM_BLE_AUTH_CMPL_EVT 24 /* BLE Auth complete */ #define BTA_DM_BLE_AUTH_CMPL_EVT 24 /* BLE Auth complete */
// btla-specific -- // btla-specific --
#define BTA_DM_DEV_UNPAIRED_EVT 25 #define BTA_DM_DEV_UNPAIRED_EVT 25 /* BT unpair event */
#define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */ #define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */
#define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */ #define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */
#define BTA_DM_ENER_INFO_READ 28 /* Energy info read */ #define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
#define BTA_DM_BLE_DEV_UNPAIRED_EVT 29 /* BLE unpair event */
#define BTA_DM_SP_KEY_REQ_EVT 30 /* Simple Pairing Passkey request */
typedef UINT8 tBTA_DM_SEC_EVT; typedef UINT8 tBTA_DM_SEC_EVT;
/* Structure associated with BTA_DM_ENABLE_EVT */ /* Structure associated with BTA_DM_ENABLE_EVT */
@ -867,6 +870,13 @@ typedef struct {
tBTA_AUTH_REQ rmt_io_caps; /* IO Capabilities of remote device */ tBTA_AUTH_REQ rmt_io_caps; /* IO Capabilities of remote device */
} tBTA_DM_SP_CFM_REQ; } tBTA_DM_SP_CFM_REQ;
/* Structure associated with tBTA_DM_SP_KEY_REQ */
typedef struct {
BD_ADDR bd_addr; /* peer address */
DEV_CLASS dev_class; /* peer CoD */
BD_NAME bd_name; /* peer device name */
} tBTA_DM_SP_KEY_REQ;
enum { enum {
BTA_SP_KEY_STARTED, /* passkey entry started */ BTA_SP_KEY_STARTED, /* passkey entry started */
BTA_SP_KEY_ENTERED, /* passkey digit entered */ BTA_SP_KEY_ENTERED, /* passkey digit entered */
@ -906,23 +916,24 @@ typedef struct {
/* Union of all security callback structures */ /* Union of all security callback structures */
typedef union { typedef union {
tBTA_DM_ENABLE enable; /* BTA enabled */ tBTA_DM_ENABLE enable; /* BTA enabled */
tBTA_DM_PIN_REQ pin_req; /* PIN request. */ tBTA_DM_PIN_REQ pin_req; /* PIN request. */
tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication. */ tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication. */
tBTA_DM_AUTHORIZE authorize; /* Authorization request. */ tBTA_DM_AUTHORIZE authorize; /* Authorization request. */
tBTA_DM_LINK_UP link_up; /* ACL connection down event */ tBTA_DM_LINK_UP link_up; /* ACL connection down event */
tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */ tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */
tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */ tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */
tBTA_DM_SP_CFM_REQ cfm_req; /* user confirm request */ tBTA_DM_SP_CFM_REQ cfm_req; /* user confirm request */
tBTA_DM_SP_KEY_NOTIF key_notif; /* passkey notification */ tBTA_DM_SP_KEY_REQ key_req; /* user passkey request */
tBTA_DM_SP_RMT_OOB rmt_oob; /* remote oob */ tBTA_DM_SP_KEY_NOTIF key_notif; /* passkey notification */
tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */ tBTA_DM_SP_RMT_OOB rmt_oob; /* remote oob */
tBTA_DM_SP_KEY_PRESS key_press; /* key press notification event */ tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */
tBTA_DM_ROLE_CHG role_chg; /* role change event */ tBTA_DM_SP_KEY_PRESS key_press; /* key press notification event */
tBTA_DM_BLE_SEC_REQ ble_req; /* BLE SMP related request */ tBTA_DM_ROLE_CHG role_chg; /* role change event */
tBTA_DM_BLE_KEY ble_key; /* BLE SMP keys used when pairing */ tBTA_DM_BLE_SEC_REQ ble_req; /* BLE SMP related request */
tBTA_BLE_LOCAL_ID_KEYS ble_id_keys; /* IR event */ tBTA_DM_BLE_KEY ble_key; /* BLE SMP keys used when pairing */
BT_OCTET16 ble_er; /* ER event data */ tBTA_BLE_LOCAL_ID_KEYS ble_id_keys; /* IR event */
BT_OCTET16 ble_er; /* ER event data */
} tBTA_DM_SEC; } tBTA_DM_SEC;
/* Security callback */ /* Security callback */
@ -1428,7 +1439,7 @@ extern void BTA_DmUpdateWhiteList(BOOLEAN add_remove, BD_ADDR remote_addr, tBTA
extern void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb); extern void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb);
extern void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_CMPL_CB *cmpl_cb); extern void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb);
/******************************************************************************* /*******************************************************************************
** **
@ -1601,6 +1612,18 @@ extern void BTA_DmLocalOob(void);
*******************************************************************************/ *******************************************************************************/
extern void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept); extern void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept);
/*******************************************************************************
**
** Function BTA_DmPasskeyReqReply
**
** Description This function is called to provide the passkey for
** Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT
**
** Returns void
**
*******************************************************************************/
extern void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey);
/******************************************************************************* /*******************************************************************************
** **
** Function BTA_DmAddDevice ** Function BTA_DmAddDevice
@ -1632,7 +1655,7 @@ extern void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class,
** BTA_FAIL if operation failed. ** BTA_FAIL if operation failed.
** **
*******************************************************************************/ *******************************************************************************/
extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr); extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr, tBT_TRANSPORT transport);
/******************************************************************************* /*******************************************************************************
** **

View File

@ -30,6 +30,20 @@
** Function Declarations ** Function Declarations
*****************************************************************************/ *****************************************************************************/
/*******************************************************************************
**
** Function bta_dm_co_bt_set_io_cap
**
** Description This function is used to set IO capabilities
**
** Parameters bt_io_cap - IO capabilities
**
** @return - ESP_BT_STATUS_SUCCESS : success
** - other : failed
**
*******************************************************************************/
extern esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap);
/******************************************************************************* /*******************************************************************************
** **
** Function bta_dm_co_io_req ** Function bta_dm_co_io_req

View File

@ -282,7 +282,8 @@ typedef struct {
UINT8 id; UINT8 id;
UINT8 prop; /* used when attribute type is characteristic */ UINT8 prop; /* used when attribute type is characteristic */
BOOLEAN is_primary; /* used when attribute type is service */ BOOLEAN is_primary; /* used when attribute type is service */
UINT16 incl_srvc_handle; /* used when attribute type is included service */ UINT16 incl_srvc_s_handle; /* used when attribute type is included service */
UINT16 incl_srvc_e_handle; /* used when attribute type is included service */
}tBTA_GATTC_NV_ATTR; }tBTA_GATTC_NV_ATTR;
/* callback data structure */ /* callback data structure */
@ -691,6 +692,7 @@ typedef struct
tBT_UUID uuid; tBT_UUID uuid;
UINT16 handle; UINT16 handle;
UINT16 incl_srvc_s_handle; UINT16 incl_srvc_s_handle;
UINT16 incl_srvc_e_handle;
tBTA_GATTC_SERVICE *owning_service; /* owning service*/ tBTA_GATTC_SERVICE *owning_service; /* owning service*/
tBTA_GATTC_SERVICE *included_service; tBTA_GATTC_SERVICE *included_service;
} __attribute__((packed)) tBTA_GATTC_INCLUDED_SVC; } __attribute__((packed)) tBTA_GATTC_INCLUDED_SVC;
@ -1096,11 +1098,12 @@ extern void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_mult
** Description Refresh the server cache of the remote device ** Description Refresh the server cache of the remote device
** **
** Parameters remote_bda: remote device BD address. ** Parameters remote_bda: remote device BD address.
** erase_flash: delete cache from nvs flash
** **
** Returns void ** Returns void
** **
*******************************************************************************/ *******************************************************************************/
extern void BTA_GATTC_Refresh(BD_ADDR remote_bda); extern void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash);
extern void BTA_GATTC_CacheAssoc(tBTA_GATTC_IF client_if, BD_ADDR src_addr, BD_ADDR assoc_addr, BOOLEAN is_assoc); extern void BTA_GATTC_CacheAssoc(tBTA_GATTC_IF client_if, BD_ADDR src_addr, BD_ADDR assoc_addr, BOOLEAN is_assoc);

View File

@ -113,6 +113,8 @@ extern size_t bta_gattc_get_cache_attr_length(UINT8 index);
extern void bta_gattc_co_cache_addr_init(void); extern void bta_gattc_co_cache_addr_init(void);
extern void bta_gattc_co_cache_addr_deinit(void);
extern BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda); extern BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda);
extern uint8_t bta_gattc_co_find_addr_in_cache(BD_ADDR bda); extern uint8_t bta_gattc_co_find_addr_in_cache(BD_ADDR bda);

View File

@ -55,7 +55,7 @@ extern void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RAN
** **
** Returns TRUE - if the request is processed successfully and ** Returns TRUE - if the request is processed successfully and
** the response is returned in p_rsp. ** the response is returned in p_rsp.
** FASLE - if the request can not be processed ** FALSE - if the request can not be processed
** **
*******************************************************************************/ *******************************************************************************/
extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd, extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd,

View File

@ -22,7 +22,6 @@
* *
******************************************************************************/ ******************************************************************************/
#include <arpa/inet.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
@ -959,6 +958,14 @@ static bool create_base_record(const uint32_t sdp_handle, const char *name, cons
return FALSE; return FALSE;
} }
stage = "profile_descriptor_list";
if (!SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_SERIAL_PORT, SPP_VERSION)){
APPL_TRACE_ERROR("create_base_record: failed to create base service "
"record, stage: %s, scn: %d, name: %s, with_obex: %d",
stage, channel, name, with_obex);
return FALSE;
}
// Add the name to the SDP record. // Add the name to the SDP record.
if (name[0] != '\0') { if (name[0] != '\0') {
stage = "service_name"; stage = "service_name";

View File

@ -37,6 +37,8 @@
** Constants ** Constants
*****************************************************************************/ *****************************************************************************/
#define SPP_VERSION 0x0102
enum { enum {
/* these events are handled by the state machine */ /* these events are handled by the state machine */
BTA_JV_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_JV), BTA_JV_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_JV),

View File

@ -182,6 +182,10 @@ static void btc_dm_remove_ble_bonding_keys(void)
static void btc_dm_save_ble_bonding_keys(void) static void btc_dm_save_ble_bonding_keys(void)
{ {
if(!(pairing_cb.ble.is_penc_key_rcvd || pairing_cb.ble.is_pid_key_rcvd || pairing_cb.ble.is_pcsrk_key_rcvd ||
pairing_cb.ble.is_lenc_key_rcvd || pairing_cb.ble.is_lcsrk_key_rcvd || pairing_cb.ble.is_lidk_key_rcvd)) {
return ;
}
bt_bdaddr_t bd_addr; bt_bdaddr_t bd_addr;
bdcpy(bd_addr.address, pairing_cb.bd_addr); bdcpy(bd_addr.address, pairing_cb.bd_addr);
@ -344,7 +348,7 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
case HCI_ERR_INSUFFCIENT_SECURITY: case HCI_ERR_INSUFFCIENT_SECURITY:
case HCI_ERR_PEER_USER: case HCI_ERR_PEER_USER:
case HCI_ERR_UNSPECIFIED: case HCI_ERR_UNSPECIFIED:
BTC_TRACE_DEBUG(" %s() Authentication fail reason %d", BTC_TRACE_ERROR(" %s() Authentication fail reason %d",
__FUNCTION__, p_auth_cmpl->fail_reason); __FUNCTION__, p_auth_cmpl->fail_reason);
/* if autopair attempts are more than 1, or not attempted */ /* if autopair attempts are more than 1, or not attempted */
status = BT_STATUS_AUTH_FAILURE; status = BT_STATUS_AUTH_FAILURE;
@ -353,7 +357,7 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
status = BT_STATUS_FAIL; status = BT_STATUS_FAIL;
} }
} }
#if (BTC_GAP_BT_INCLUDED == TRUE) #if (BTC_GAP_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE)
esp_bt_gap_cb_param_t param; esp_bt_gap_cb_param_t param;
bt_status_t ret; bt_status_t ret;
btc_msg_t msg; btc_msg_t msg;
@ -368,13 +372,80 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
sizeof(esp_bt_gap_cb_param_t), NULL); sizeof(esp_bt_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) { if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_DEBUG("%s btc_transfer_context failed\n", __func__); BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
} }
#endif /* BTC_GAP_BT_INCLUDED == TRUE */ #endif /// BTC_GAP_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE
(void) status; (void) status;
} }
#if (BT_SSP_INCLUDED == TRUE)
static void btc_dm_sp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_cfm_req)
{
if (p_cfm_req->just_works) {
// just work, not show to users.
BTA_DmConfirm(p_cfm_req->bd_addr, true);
return;
}
esp_bt_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_CFM_REQ_EVT;
param.cfm_req.num_val = p_cfm_req->num_val;
memcpy(param.cfm_req.bda, p_cfm_req->bd_addr, ESP_BD_ADDR_LEN);
ret = btc_transfer_context(&msg, &param,
sizeof(esp_bt_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_dm_sp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF *p_key_notif)
{
esp_bt_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_KEY_NOTIF_EVT;
param.key_notif.passkey = p_key_notif->passkey;
memcpy(param.key_notif.bda, p_key_notif->bd_addr, ESP_BD_ADDR_LEN);
ret = btc_transfer_context(&msg, &param,
sizeof(esp_bt_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_dm_sp_key_req_evt(tBTA_DM_SP_KEY_REQ *p_key_req)
{
esp_bt_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_KEY_REQ_EVT;
memcpy(param.key_req.bda, p_key_req->bd_addr, ESP_BD_ADDR_LEN);
ret = btc_transfer_context(&msg, &param,
sizeof(esp_bt_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
#endif ///BT_SSP_INCLUDED == TRUE
tBTA_SERVICE_MASK btc_get_enabled_services_mask(void) tBTA_SERVICE_MASK btc_get_enabled_services_mask(void)
{ {
return btc_enabled_services; return btc_enabled_services;
@ -484,21 +555,52 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
break; break;
} }
case BTA_DM_PIN_REQ_EVT: case BTA_DM_PIN_REQ_EVT:
BTC_TRACE_DEBUG("BTA_DM_PIN_REQ_EVT");
break; break;
case BTA_DM_AUTH_CMPL_EVT: case BTA_DM_AUTH_CMPL_EVT:
btc_dm_auth_cmpl_evt(&p_data->auth_cmpl); btc_dm_auth_cmpl_evt(&p_data->auth_cmpl);
break; break;
case BTA_DM_BOND_CANCEL_CMPL_EVT: case BTA_DM_BOND_CANCEL_CMPL_EVT:
case BTA_DM_SP_CFM_REQ_EVT: BTC_TRACE_DEBUG("BTA_DM_BOND_CANCEL_CMPL_EVT");
case BTA_DM_SP_KEY_NOTIF_EVT:
break; break;
#if (BT_SSP_INCLUDED == TRUE)
case BTA_DM_SP_CFM_REQ_EVT:
btc_dm_sp_cfm_req_evt(&p_data->cfm_req);
break;
case BTA_DM_SP_KEY_NOTIF_EVT:
btc_dm_sp_key_notif_evt(&p_data->key_notif);
break;
case BTA_DM_SP_KEY_REQ_EVT:
btc_dm_sp_key_req_evt(&p_data->key_req);
break;
case BTA_DM_SP_RMT_OOB_EVT:
BTC_TRACE_DEBUG("BTA_DM_SP_RMT_OOB_EVT");
break;
case BTA_DM_SP_KEYPRESS_EVT:
BTC_TRACE_DEBUG("BTA_DM_SP_KEYPRESS_EVT");
break;
#endif ///BT_SSP_INCLUDED == TRUE
case BTA_DM_DEV_UNPAIRED_EVT: { case BTA_DM_DEV_UNPAIRED_EVT: {
#if (SMP_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE)
bt_bdaddr_t bd_addr; bt_bdaddr_t bd_addr;
rsp_app = true;
BTC_TRACE_DEBUG("BTA_DM_DEV_UNPAIRED_EVT"); BTC_TRACE_DEBUG("BTA_DM_DEV_UNPAIRED_EVT");
memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR)); memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR));
btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN); btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
if (p_data->link_down.status == HCI_SUCCESS) {
//remove the bonded key in the config and nvs flash.
btc_storage_remove_bonded_device(&bd_addr);
}
#endif /* #if (SMP_INCLUDED == TRUE) */
break;
}
case BTA_DM_BLE_DEV_UNPAIRED_EVT: {
#if (SMP_INCLUDED == TRUE)
bt_bdaddr_t bd_addr;
rsp_app = true;
BTC_TRACE_DEBUG("BTA_DM_BLE_DEV_UNPAIRED_EVT");
memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR));
btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
param.remove_bond_dev_cmpl.status = ESP_BT_STATUS_FAIL; param.remove_bond_dev_cmpl.status = ESP_BT_STATUS_FAIL;
if (p_data->link_down.status == HCI_SUCCESS) { if (p_data->link_down.status == HCI_SUCCESS) {
@ -675,8 +777,6 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
case BTA_DM_AUTHORIZE_EVT: case BTA_DM_AUTHORIZE_EVT:
case BTA_DM_SIG_STRENGTH_EVT: case BTA_DM_SIG_STRENGTH_EVT:
case BTA_DM_SP_RMT_OOB_EVT:
case BTA_DM_SP_KEYPRESS_EVT:
case BTA_DM_ROLE_CHG_EVT: case BTA_DM_ROLE_CHG_EVT:
BTC_TRACE_DEBUG( "btc_dm_sec_cback : unhandled event (%d)\n", msg->act ); BTC_TRACE_DEBUG( "btc_dm_sec_cback : unhandled event (%d)\n", msg->act );
break; break;

View File

@ -170,6 +170,9 @@ int btc_init(void)
return BT_STATUS_NOMEM; return BT_STATUS_NOMEM;
} }
btc_gap_callback_init(); btc_gap_callback_init();
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_init();
#endif
/* TODO: initial the profile_tab */ /* TODO: initial the profile_tab */
return BT_STATUS_SUCCESS; return BT_STATUS_SUCCESS;
} }
@ -178,7 +181,18 @@ void btc_deinit(void)
{ {
vTaskDelete(xBtcTaskHandle); vTaskDelete(xBtcTaskHandle);
vQueueDelete(xBtcQueue); vQueueDelete(xBtcQueue);
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_deinit();
#endif
xBtcTaskHandle = NULL; xBtcTaskHandle = NULL;
xBtcQueue = 0; xBtcQueue = 0;
} }
bool btc_check_queue_is_congest(void)
{
UBaseType_t wait_size = uxQueueMessagesWaiting(xBtcQueue);
if(wait_size >= QUEUE_CONGEST_SIZE) {
return true;
}
return false;
}

View File

@ -28,6 +28,11 @@ typedef struct btc_msg {
void *arg; //param for btc function or function param void *arg; //param for btc function or function param
} btc_msg_t; } btc_msg_t;
typedef struct btc_adv_packet {
uint8_t addr[6];
uint8_t addr_type;
} btc_adv_packet_t;
typedef enum { typedef enum {
BTC_SIG_API_CALL = 0, // APP TO STACK BTC_SIG_API_CALL = 0, // APP TO STACK
BTC_SIG_API_CB, // STACK TO APP BTC_SIG_API_CB, // STACK TO APP
@ -72,5 +77,6 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg
int btc_init(void); int btc_init(void);
void btc_deinit(void); void btc_deinit(void);
bool btc_check_queue_is_congest(void);
#endif /* __BTC_TASK_H__ */ #endif /* __BTC_TASK_H__ */

View File

@ -87,8 +87,8 @@ enum {
but due to link flow control or thread preemption in lower but due to link flow control or thread preemption in lower
layers we might need to temporarily buffer up data */ layers we might need to temporarily buffer up data */
/* 5 frames is equivalent to 6.89*5*2.9 ~= 100 ms @ 44.1 khz, 20 ms mediatick */ /* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (5) #define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18)
typedef struct { typedef struct {
UINT16 num_frames_to_be_processed; UINT16 num_frames_to_be_processed;
@ -763,7 +763,7 @@ static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context)
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON; btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON;
btc_aa_snk_cb.RxSbcQ = fixed_queue_new(SIZE_MAX); btc_aa_snk_cb.RxSbcQ = fixed_queue_new(QUEUE_SIZE_MAX);
btc_a2dp_control_init(); btc_a2dp_control_init();
} }

View File

@ -1616,7 +1616,7 @@ static void btc_a2dp_source_thread_init(UNUSED_ATTR void *context)
btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_ON; btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_ON;
btc_aa_src_cb.TxAaQ = fixed_queue_new(SIZE_MAX); btc_aa_src_cb.TxAaQ = fixed_queue_new(QUEUE_SIZE_MAX);
btc_a2dp_control_init(); btc_a2dp_control_init();
} }

View File

@ -28,9 +28,23 @@
#include "btc/btc_ble_storage.h" #include "btc/btc_ble_storage.h"
#include "btc/btc_dm.h" #include "btc/btc_dm.h"
#include "btc/btc_util.h" #include "btc/btc_util.h"
#include "osi/mutex.h"
static tBTA_BLE_ADV_DATA gl_bta_adv_data; static tBTA_BLE_ADV_DATA gl_bta_adv_data;
static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data; static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
#if SCAN_QUEUE_CONGEST_CHECK
static list_t *adv_filter_list;
static osi_mutex_t adv_list_lock;
bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type);
uint32_t btc_get_adv_list_length(void);
void btc_adv_list_refresh(void);
void btc_adv_list_lock(void);
void btc_adv_list_unlock(void);
static uint16_t btc_adv_list_count = 0;
#define BTC_ADV_LIST_MAX_LENGTH 50
#define BTC_ADV_LIST_MAX_COUNT 200
#endif
static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{ {
@ -510,6 +524,19 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data
param.scan_rst.search_evt = event; param.scan_rst.search_evt = event;
switch (event) { switch (event) {
case BTA_DM_INQ_RES_EVT: { case BTA_DM_INQ_RES_EVT: {
#if SCAN_QUEUE_CONGEST_CHECK
if(btc_check_queue_is_congest()) {
BTC_TRACE_DEBUG("BtcQueue is congested");
if(btc_get_adv_list_length() > BTC_ADV_LIST_MAX_LENGTH || btc_adv_list_count > BTC_ADV_LIST_MAX_COUNT) {
btc_adv_list_refresh();
btc_adv_list_count = 0;
}
if(btc_check_adv_list(p_data->inq_res.bd_addr, p_data->inq_res.ble_addr_type)) {
return;
}
}
btc_adv_list_count ++;
#endif
bdcpy(param.scan_rst.bda, p_data->inq_res.bd_addr); bdcpy(param.scan_rst.bda, p_data->inq_res.bd_addr);
param.scan_rst.dev_type = p_data->inq_res.device_type; param.scan_rst.dev_type = p_data->inq_res.device_type;
param.scan_rst.rssi = p_data->inq_res.rssi; param.scan_rst.rssi = p_data->inq_res.rssi;
@ -585,6 +612,9 @@ static void btc_stop_scan_callback(tBTA_STATUS status)
if (ret != BT_STATUS_SUCCESS) { if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
} }
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_refresh();
#endif
} }
void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params) void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params)
@ -725,6 +755,9 @@ static void btc_ble_start_scanning(uint32_t duration,
tBTA_START_STOP_SCAN_CMPL_CBACK *start_scan_cb) tBTA_START_STOP_SCAN_CMPL_CBACK *start_scan_cb)
{ {
if ((results_cb != NULL) && (start_scan_cb != NULL)) { if ((results_cb != NULL) && (start_scan_cb != NULL)) {
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_refresh();
#endif
//Start scan the device //Start scan the device
BTA_DmBleScan(true, duration, results_cb, start_scan_cb); BTA_DmBleScan(true, duration, results_cb, start_scan_cb);
} else { } else {
@ -1018,7 +1051,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
BTA_DmUpdateWhiteList(arg->update_white_list.add_remove, arg->update_white_list.remote_bda, btc_add_whitelist_complete_callback); BTA_DmUpdateWhiteList(arg->update_white_list.add_remove, arg->update_white_list.remote_bda, btc_add_whitelist_complete_callback);
break; break;
case BTC_GAP_BLE_ACT_READ_RSSI: case BTC_GAP_BLE_ACT_READ_RSSI:
BTA_DmBleReadRSSI(arg->read_rssi.remote_addr, btc_read_ble_rssi_cmpl_callback); BTA_DmBleReadRSSI(arg->read_rssi.remote_addr, BTA_TRANSPORT_LE, btc_read_ble_rssi_cmpl_callback);
break; break;
case BTC_GAP_BLE_ACT_SET_CONN_PARAMS: case BTC_GAP_BLE_ACT_SET_CONN_PARAMS:
BTA_DmSetBlePrefConnParams(arg->set_conn_params.bd_addr, arg->set_conn_params.min_conn_int, BTA_DmSetBlePrefConnParams(arg->set_conn_params.bd_addr, arg->set_conn_params.min_conn_int,
@ -1108,7 +1141,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: { case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: {
BD_ADDR bd_addr; BD_ADDR bd_addr;
memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR)); memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR));
BTA_DmRemoveDevice(bd_addr); BTA_DmRemoveDevice(bd_addr, BT_TRANSPORT_LE);
break; break;
} }
#endif ///SMP_INCLUDED == TRUE #endif ///SMP_INCLUDED == TRUE
@ -1134,3 +1167,99 @@ void btc_gap_ble_deinit(void)
btc_cleanup_adv_data(&gl_bta_adv_data); btc_cleanup_adv_data(&gl_bta_adv_data);
btc_cleanup_adv_data(&gl_bta_scan_rsp_data); btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
} }
#if SCAN_QUEUE_CONGEST_CHECK
void btc_adv_list_free(void *data)
{
osi_free(data);
}
void btc_adv_list_init(void)
{
osi_mutex_new(&adv_list_lock);
adv_filter_list = list_new(btc_adv_list_free);
}
void btc_adv_list_deinit(void)
{
osi_mutex_free(&adv_list_lock);
if(adv_filter_list) {
list_free(adv_filter_list);
adv_filter_list = NULL;
}
}
void btc_adv_list_add_packet(void * data)
{
if(!data) {
BTC_TRACE_ERROR("%s data is NULL", __func__);
return;
}
btc_adv_list_lock();
list_prepend(adv_filter_list, data);
btc_adv_list_unlock();
}
uint32_t btc_get_adv_list_length(void)
{
if(!adv_filter_list) {
BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
return 0;
}
btc_adv_list_lock();
size_t length = list_length(adv_filter_list);
btc_adv_list_unlock();
return length;
}
void btc_adv_list_refresh(void)
{
if(!adv_filter_list) {
BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
return ;
}
btc_adv_list_lock();
list_clear(adv_filter_list);
btc_adv_list_unlock();
}
bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type)
{
bool found = false;
if(!adv_filter_list || !addr) {
BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
return found;
}
btc_adv_list_lock();
for (const list_node_t *node = list_begin(adv_filter_list); node != list_end(adv_filter_list); node = list_next(node)) {
btc_adv_packet_t *packet = (btc_adv_packet_t *)list_node(node);
if(!bdcmp(addr, packet->addr) && packet->addr_type == addr_type) {
found = true;
break;
}
}
btc_adv_list_unlock();
if(!found) {
btc_adv_packet_t *adv_packet = osi_malloc(sizeof(btc_adv_packet_t));
if(adv_packet) {
adv_packet->addr_type = addr_type;
bdcpy(adv_packet->addr, addr);
btc_adv_list_add_packet(adv_packet);
} else {
BTC_TRACE_ERROR("%s adv_packet malloc failed", __func__);
}
}
return found;
}
void btc_adv_list_lock(void)
{
osi_mutex_lock(&adv_list_lock, OSI_MUTEX_MAX_TIMEOUT);
}
void btc_adv_list_unlock(void)
{
osi_mutex_unlock(&adv_list_lock);
}
#endif

View File

@ -23,6 +23,7 @@
#include "btc/btc_manage.h" #include "btc/btc_manage.h"
#include "btc/btc_util.h" #include "btc/btc_util.h"
#include "osi/allocator.h" #include "osi/allocator.h"
#include "bta/bta_dm_co.h"
#if (BTC_GAP_BT_INCLUDED == TRUE) #if (BTC_GAP_BT_INCLUDED == TRUE)
@ -151,7 +152,7 @@ static void search_devices_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
switch (p_dest_data->event) { switch (p_dest_data->event) {
case BTA_DM_INQ_RES_EVT: { case BTA_DM_INQ_RES_EVT: {
if (p_src_data->p_data->inq_res.p_eir) { if (p_src_data->p_data->inq_res.p_eir) {
p_dest_data->p_data->inq_res.p_eir = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH)); p_dest_data->p_data->inq_res.p_eir = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->inq_res.p_eir, p_src_data->p_data->inq_res.p_eir, HCI_EXT_INQ_RESPONSE_LEN); memcpy(p_dest_data->p_data->inq_res.p_eir, p_src_data->p_data->inq_res.p_eir, HCI_EXT_INQ_RESPONSE_LEN);
} }
} }
@ -159,7 +160,7 @@ static void search_devices_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
case BTA_DM_DISC_RES_EVT: { case BTA_DM_DISC_RES_EVT: {
if (p_src_data->p_data->disc_res.raw_data_size && p_src_data->p_data->disc_res.p_raw_data) { if (p_src_data->p_data->disc_res.raw_data_size && p_src_data->p_data->disc_res.p_raw_data) {
p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH)); p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_raw_data, memcpy(p_dest_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.p_raw_data, p_src_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.raw_data_size); p_src_data->p_data->disc_res.raw_data_size);
@ -194,7 +195,7 @@ static void search_service_record_copy_cb(btc_msg_t *msg, void *p_dest, void *p_
switch (p_dest_data->event) { switch (p_dest_data->event) {
case BTA_DM_DISC_RES_EVT: { case BTA_DM_DISC_RES_EVT: {
if (p_src_data->p_data->disc_res.p_raw_data && p_src_data->p_data->disc_res.raw_data_size > 0) { if (p_src_data->p_data->disc_res.p_raw_data && p_src_data->p_data->disc_res.raw_data_size > 0) {
p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH)); p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_raw_data, memcpy(p_dest_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.p_raw_data, p_src_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.raw_data_size); p_src_data->p_data->disc_res.raw_data_size);
@ -478,7 +479,7 @@ static void btc_gap_bt_search_services(char *p_param)
param.rmt_srvcs.stat = ESP_BT_STATUS_FAIL; param.rmt_srvcs.stat = ESP_BT_STATUS_FAIL;
if (p_data->p_data->disc_res.result == BTA_SUCCESS) { if (p_data->p_data->disc_res.result == BTA_SUCCESS) {
uuid_list = malloc(sizeof(esp_bt_uuid_t) * p_data->p_data->disc_res.num_uuids); uuid_list = osi_malloc(sizeof(esp_bt_uuid_t) * p_data->p_data->disc_res.num_uuids);
if (uuid_list) { if (uuid_list) {
param.rmt_srvcs.stat = ESP_BT_STATUS_SUCCESS; param.rmt_srvcs.stat = ESP_BT_STATUS_SUCCESS;
param.rmt_srvcs.num_uuids = p_data->p_data->disc_res.num_uuids; param.rmt_srvcs.num_uuids = p_data->p_data->disc_res.num_uuids;
@ -566,7 +567,7 @@ static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
case BTA_DM_DISC_RES_EVT: { case BTA_DM_DISC_RES_EVT: {
if (p_src_data->p_data->disc_res.result == BTA_SUCCESS) { if (p_src_data->p_data->disc_res.result == BTA_SUCCESS) {
if (p_src_data->p_data->disc_res.num_uuids > 0) { if (p_src_data->p_data->disc_res.num_uuids > 0) {
p_dest_data->p_data->disc_res.p_uuid_list = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH)); p_dest_data->p_data->disc_res.p_uuid_list = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_uuid_list, p_src_data->p_data->disc_res.p_uuid_list, memcpy(p_dest_data->p_data->disc_res.p_uuid_list, p_src_data->p_data->disc_res.p_uuid_list,
p_src_data->p_data->disc_res.num_uuids * MAX_UUID_SIZE); p_src_data->p_data->disc_res.num_uuids * MAX_UUID_SIZE);
osi_free(p_src_data->p_data->disc_res.p_uuid_list); osi_free(p_src_data->p_data->disc_res.p_uuid_list);
@ -632,20 +633,116 @@ static void btc_gap_bt_read_rssi_delta_cmpl_callback(void *p_data)
static void btc_gap_bt_read_rssi_delta(btc_gap_bt_args_t *arg) static void btc_gap_bt_read_rssi_delta(btc_gap_bt_args_t *arg)
{ {
BTA_DmBleReadRSSI(arg->read_rssi_delta.bda.address, btc_gap_bt_read_rssi_delta_cmpl_callback); BTA_DmBleReadRSSI(arg->read_rssi_delta.bda.address, BTA_TRANSPORT_BR_EDR, btc_gap_bt_read_rssi_delta_cmpl_callback);
} }
esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg) static esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
{ {
BD_ADDR bd_addr; BD_ADDR bd_addr;
memcpy(bd_addr, arg->rm_bond_device.bda.address, sizeof(BD_ADDR)); memcpy(bd_addr, arg->rm_bond_device.bda.address, sizeof(BD_ADDR));
if(BTA_DmRemoveDevice(bd_addr) == BTA_SUCCESS){ if(BTA_DmRemoveDevice(bd_addr, BT_TRANSPORT_BR_EDR) == BTA_SUCCESS){
btc_storage_remove_bonded_device(&(arg->rm_bond_device.bda));
return ESP_BT_STATUS_SUCCESS; return ESP_BT_STATUS_SUCCESS;
} }
return ESP_BT_STATUS_FAIL; return ESP_BT_STATUS_FAIL;
} }
#if (BT_SSP_INCLUDED == TRUE)
static esp_err_t btc_gap_bt_set_security_param(btc_gap_bt_args_t *arg)
{
esp_err_t ret;
switch(arg->set_security_param.param_type) {
case ESP_BT_SP_IOCAP_MODE:{
uint8_t iocap = 0;
uint8_t *p = arg->set_security_param.value;
STREAM_TO_UINT8(iocap, p);
ret = bta_dm_co_bt_set_io_cap(iocap);
break;
}
default:
ret = ESP_BT_STATUS_FAIL;
break;
}
return ret;
}
static void btc_gap_bt_ssp_passkey_reply(btc_gap_bt_args_t *arg)
{
BTA_DmPasskeyReqReply(arg->passkey_reply.accept, arg->passkey_reply.bda.address, arg->passkey_reply.passkey);
}
static void btc_gap_bt_ssp_confirm(btc_gap_bt_args_t *arg)
{
BTA_DmConfirm(arg->confirm_reply.bda.address, arg->confirm_reply.accept);
}
#endif ///BT_SSP_INCLUDED == TRUE
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
case BTC_GAP_BT_ACT_SET_SCAN_MODE:
case BTC_GAP_BT_ACT_START_DISCOVERY:
case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
case BTC_GAP_BT_ACT_SET_COD:
case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
break;
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_ACT_PASSKEY_REPLY:
case BTC_GAP_BT_ACT_CONFIRM_REPLY:
break;
case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
btc_gap_bt_args_t *src = (btc_gap_bt_args_t *)p_src;
btc_gap_bt_args_t *dst = (btc_gap_bt_args_t *) p_dest;
uint8_t length = 0;
if (src->set_security_param.value) {
length = dst->set_security_param.len;
dst->set_security_param.value = osi_malloc(length);
if (dst->set_security_param.value != NULL) {
memcpy(dst->set_security_param.value, src->set_security_param.value, length);
} else {
BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
}
}
break;
}
#endif ///BT_SSP_INCLUDED == TRUE
default:
BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
break;
}
}
void btc_gap_bt_arg_deep_free(btc_msg_t *msg)
{
btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
switch (msg->act) {
case BTC_GAP_BT_ACT_SET_SCAN_MODE:
case BTC_GAP_BT_ACT_START_DISCOVERY:
case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
case BTC_GAP_BT_ACT_SET_COD:
case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
break;
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_ACT_PASSKEY_REPLY:
case BTC_GAP_BT_ACT_CONFIRM_REPLY:
break;
case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:
osi_free(arg->set_security_param.value);
break;
#endif ///BT_SSP_INCLUDED == TRUE
default:
BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
break;
}
}
void btc_gap_bt_call_handler(btc_msg_t *msg) void btc_gap_bt_call_handler(btc_msg_t *msg)
{ {
btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg; btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
@ -683,10 +780,25 @@ void btc_gap_bt_call_handler(btc_msg_t *msg)
btc_gap_bt_remove_bond_device(msg->arg); btc_gap_bt_remove_bond_device(msg->arg);
break; break;
} }
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
btc_gap_bt_set_security_param(arg);
break;
}
case BTC_GAP_BT_ACT_PASSKEY_REPLY:{
btc_gap_bt_ssp_passkey_reply(arg);
break;
}
case BTC_GAP_BT_ACT_CONFIRM_REPLY:{
btc_gap_bt_ssp_confirm(arg);
break;
}
#endif ///BT_SSP_INCLUDED == TRUE
default: default:
break; break;
} }
btc_gap_bt_arg_deep_free(msg);
return; return;
} }
@ -715,7 +827,12 @@ void btc_gap_bt_cb_deep_free(btc_msg_t *msg)
osi_free(((tBTA_DM_SEARCH_PARAM *) (msg->arg)) ->p_data); osi_free(((tBTA_DM_SEARCH_PARAM *) (msg->arg)) ->p_data);
break; break;
case BTC_GAP_BT_READ_RSSI_DELTA_EVT: case BTC_GAP_BT_READ_RSSI_DELTA_EVT:
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_AUTH_CMPL_EVT: case BTC_GAP_BT_AUTH_CMPL_EVT:
case BTC_GAP_BT_CFM_REQ_EVT:
case BTC_GAP_BT_KEY_NOTIF_EVT:
case BTC_GAP_BT_KEY_REQ_EVT:
#endif ///BT_SSP_INCLUDED == TRUE
break; break;
default: default:
BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act); BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
@ -742,10 +859,24 @@ void btc_gap_bt_cb_handler(btc_msg_t *msg)
btc_gap_bt_cb_to_app(ESP_BT_GAP_READ_RSSI_DELTA_EVT, (esp_bt_gap_cb_param_t *)msg->arg); btc_gap_bt_cb_to_app(ESP_BT_GAP_READ_RSSI_DELTA_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break; break;
} }
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_AUTH_CMPL_EVT:{ case BTC_GAP_BT_AUTH_CMPL_EVT:{
btc_gap_bt_cb_to_app(ESP_BT_GAP_AUTH_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg); btc_gap_bt_cb_to_app(ESP_BT_GAP_AUTH_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break; break;
} }
case BTC_GAP_BT_CFM_REQ_EVT:{
btc_gap_bt_cb_to_app(ESP_BT_GAP_CFM_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break;
}
case BTC_GAP_BT_KEY_NOTIF_EVT:{
btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_NOTIF_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break;
}
case BTC_GAP_BT_KEY_REQ_EVT:{
btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break;
}
#endif ///BT_SSP_INCLUDED == TRUE
default: default:
BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act); BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
break; break;

View File

@ -331,6 +331,7 @@ esp_gatt_status_t btc_ble_gattc_get_service(uint16_t conn_id, esp_bt_uuid_t *svc
if (bta_uuid) { if (bta_uuid) {
osi_free(bta_uuid); osi_free(bta_uuid);
} }
*count = 0;
return status; return status;
} else { } else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)svc_num, ESP_GATT_DB_PRIMARY_SERVICE, offset, (void *)result, db); btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)svc_num, ESP_GATT_DB_PRIMARY_SERVICE, offset, (void *)result, db);
@ -362,6 +363,7 @@ esp_gatt_status_t btc_ble_gattc_get_all_char(uint16_t conn_id,
if (db) { if (db) {
osi_free(db); osi_free(db);
} }
*count = 0;
return status; return status;
} else { } else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, offset, (void *)result, db); btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, offset, (void *)result, db);
@ -389,6 +391,7 @@ esp_gatt_status_t btc_ble_gattc_get_all_descr(uint16_t conn_id,
if (db) { if (db) {
osi_free(db); osi_free(db);
} }
*count = 0;
return status; return status;
} else { } else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, offset, (void *)result, db); btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, offset, (void *)result, db);
@ -420,6 +423,7 @@ esp_gatt_status_t btc_ble_gattc_get_char_by_uuid(uint16_t conn_id,
if (db) { if (db) {
osi_free(db); osi_free(db);
} }
*count = 0;
return status; return status;
} else { } else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, 0, (void *)result, db); btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, 0, (void *)result, db);
@ -456,6 +460,7 @@ esp_gatt_status_t btc_ble_gattc_get_descr_by_uuid(uint16_t conn_id,
if (db) { if (db) {
osi_free(db); osi_free(db);
} }
*count = 0;
return status; return status;
} else { } else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db); btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db);
@ -487,6 +492,7 @@ esp_gatt_status_t btc_ble_gattc_get_descr_by_char_handle(uint16_t conn_id,
if (db) { if (db) {
osi_free(db); osi_free(db);
} }
*count = 0;
return status; return status;
} else { } else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db); btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db);
@ -524,6 +530,7 @@ esp_gatt_status_t btc_ble_gattc_get_include_service(uint16_t conn_id,
if (db) { if (db) {
osi_free(db); osi_free(db);
} }
*count = 0;
return status; return status;
}else { }else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)incl_num, ESP_GATT_DB_INCLUDED_SERVICE, 0, (void *)result, db); btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)incl_num, ESP_GATT_DB_INCLUDED_SERVICE, 0, (void *)result, db);
@ -566,6 +573,7 @@ esp_gatt_status_t btc_ble_gattc_get_db(uint16_t conn_id, uint16_t start_handle,
if (get_db) { if (get_db) {
osi_free(get_db); osi_free(get_db);
} }
*count = 0;
return ESP_GATT_NOT_FOUND; return ESP_GATT_NOT_FOUND;
} }
@ -579,7 +587,7 @@ esp_gatt_status_t btc_ble_gattc_get_db(uint16_t conn_id, uint16_t start_handle,
btc128_to_bta_uuid(&bta_uuid, get_db[i].uuid.uu); btc128_to_bta_uuid(&bta_uuid, get_db[i].uuid.uu);
bta_to_btc_uuid(&db[i].uuid, &bta_uuid); bta_to_btc_uuid(&db[i].uuid, &bta_uuid);
} }
*count = num; *count = db_size;
//don't forget to free the db buffer after used. //don't forget to free the db buffer after used.
if (get_db) { if (get_db) {
osi_free(get_db); osi_free(get_db);
@ -738,7 +746,7 @@ void btc_gattc_call_handler(btc_msg_t *msg)
btc_gattc_unreg_for_notify(arg); btc_gattc_unreg_for_notify(arg);
break; break;
case BTC_GATTC_ACT_CACHE_REFRESH: case BTC_GATTC_ACT_CACHE_REFRESH:
BTA_GATTC_Refresh(arg->cache_refresh.remote_bda); BTA_GATTC_Refresh(arg->cache_refresh.remote_bda, true);
break; break;
case BTC_GATTC_ACT_CACHE_ASSOC: case BTC_GATTC_ACT_CACHE_ASSOC:
BTA_GATTC_CacheAssoc(arg->cache_assoc.gattc_if, BTA_GATTC_CacheAssoc(arg->cache_assoc.gattc_if,

View File

@ -506,6 +506,8 @@ static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_sr
if (p_dest_data->req_data.p_data != NULL) { if (p_dest_data->req_data.p_data != NULL) {
memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data, memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data,
sizeof(tBTA_GATTS_REQ_DATA)); sizeof(tBTA_GATTS_REQ_DATA));
} else {
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
} }
break; break;
@ -759,6 +761,9 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
param.write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id); param.write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
param.write.trans_id = p_data->req_data.trans_id; param.write.trans_id = p_data->req_data.trans_id;
memcpy(param.write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN); memcpy(param.write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN);
if (p_data->req_data.p_data == NULL) {
break;
}
param.write.handle = p_data->req_data.p_data->write_req.handle; param.write.handle = p_data->req_data.p_data->write_req.handle;
param.write.offset = p_data->req_data.p_data->write_req.offset; param.write.offset = p_data->req_data.p_data->write_req.offset;
param.write.need_rsp = p_data->req_data.p_data->write_req.need_rsp; param.write.need_rsp = p_data->req_data.p_data->write_req.need_rsp;
@ -775,6 +780,9 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
param.exec_write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id); param.exec_write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
param.exec_write.trans_id = p_data->req_data.trans_id; param.exec_write.trans_id = p_data->req_data.trans_id;
memcpy(param.exec_write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN); memcpy(param.exec_write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN);
if (p_data->req_data.p_data == NULL) {
break;
}
param.exec_write.exec_write_flag = p_data->req_data.p_data->exec_write; param.exec_write.exec_write_flag = p_data->req_data.p_data->exec_write;
btc_gatts_cb_to_app(ESP_GATTS_EXEC_WRITE_EVT, gatts_if, &param); btc_gatts_cb_to_app(ESP_GATTS_EXEC_WRITE_EVT, gatts_if, &param);

View File

@ -1,638 +0,0 @@
#include <string.h>
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "hid_le_prf.h"
#include "prf_defs.h"
#if (HIDD_LE_PROFILE_CFG)
hidd_le_env_t hidd_le_env;
#define HI_UINT16(a) (((a) >> 8) & 0xFF)
#define LO_UINT16(a) ((a) & 0xFF)
// HID Information characteristic value
static const uint8_t hidInfo[HID_INFORMATION_LEN] = {
LO_UINT16(0x0111), HI_UINT16(0x0111), // bcdHID (USB HID version)
0x00, // bCountryCode
HID_KBD_FLAGS // Flags
};
// HID Report Map characteristic value
// Keyboard report descriptor (using format for Boot interface descriptor)
static const uint8_t hidReportMap[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report Id (1)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Buttons)
0x19, 0x01, // Usage Minimum (01) - Button 1
0x29, 0x03, // Usage Maximum (03) - Button 3
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x03, // Report Count (3)
0x81, 0x02, // Input (Data, Variable, Absolute) - Button states
0x75, 0x05, // Report Size (5)
0x95, 0x01, // Report Count (1)
0x81, 0x01, // Input (Constant) - Padding or Reserved bits
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x38, // Usage (Wheel)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x03, // Report Count (3)
0x81, 0x06, // Input (Data, Variable, Relative) - X & Y coordinate
0xC0, // End Collection
0xC0, // End Collection
0x05, 0x01, // Usage Pg (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection: (Application)
0x85, 0x02, // Report Id (2)
//
0x05, 0x07, // Usage Pg (Key Codes)
0x19, 0xE0, // Usage Min (224)
0x29, 0xE7, // Usage Max (231)
0x15, 0x00, // Log Min (0)
0x25, 0x01, // Log Max (1)
//
// Modifier byte
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input: (Data, Variable, Absolute)
//
// Reserved byte
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x01, // Input: (Constant)
//
// LED report
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Pg (LEDs)
0x19, 0x01, // Usage Min (1)
0x29, 0x05, // Usage Max (5)
0x91, 0x02, // Output: (Data, Variable, Absolute)
//
// LED report padding
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x01, // Output: (Constant)
//
// Key arrays (6 bytes)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Log Min (0)
0x25, 0x65, // Log Max (101)
0x05, 0x07, // Usage Pg (Key Codes)
0x19, 0x00, // Usage Min (0)
0x29, 0x65, // Usage Max (101)
0x81, 0x00, // Input: (Data, Array)
//
0xC0, // End Collection
//
0x05, 0x0C, // Usage Pg (Consumer Devices)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x03, // Report Id (3)
0x09, 0x02, // Usage (Numeric Key Pad)
0xA1, 0x02, // Collection (Logical)
0x05, 0x09, // Usage Pg (Button)
0x19, 0x01, // Usage Min (Button 1)
0x29, 0x0A, // Usage Max (Button 10)
0x15, 0x01, // Logical Min (1)
0x25, 0x0A, // Logical Max (10)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x00, // Input (Data, Ary, Abs)
0xC0, // End Collection
0x05, 0x0C, // Usage Pg (Consumer Devices)
0x09, 0x86, // Usage (Channel)
0x15, 0xFF, // Logical Min (-1)
0x25, 0x01, // Logical Max (1)
0x75, 0x02, // Report Size (2)
0x95, 0x01, // Report Count (1)
0x81, 0x46, // Input (Data, Var, Rel, Null)
0x09, 0xE9, // Usage (Volume Up)
0x09, 0xEA, // Usage (Volume Down)
0x15, 0x00, // Logical Min (0)
0x75, 0x01, // Report Size (1)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data, Var, Abs)
0x09, 0xE2, // Usage (Mute)
0x09, 0x30, // Usage (Power)
0x09, 0x83, // Usage (Recall Last)
0x09, 0x81, // Usage (Assign Selection)
0x09, 0xB0, // Usage (Play)
0x09, 0xB1, // Usage (Pause)
0x09, 0xB2, // Usage (Record)
0x09, 0xB3, // Usage (Fast Forward)
0x09, 0xB4, // Usage (Rewind)
0x09, 0xB5, // Usage (Scan Next)
0x09, 0xB6, // Usage (Scan Prev)
0x09, 0xB7, // Usage (Stop)
0x15, 0x01, // Logical Min (1)
0x25, 0x0C, // Logical Max (12)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x00, // Input (Data, Ary, Abs)
0x09, 0x80, // Usage (Selection)
0xA1, 0x02, // Collection (Logical)
0x05, 0x09, // Usage Pg (Button)
0x19, 0x01, // Usage Min (Button 1)
0x29, 0x03, // Usage Max (Button 3)
0x15, 0x01, // Logical Min (1)
0x25, 0x03, // Logical Max (3)
0x75, 0x02, // Report Size (2)
0x81, 0x00, // Input (Data, Ary, Abs)
0xC0, // End Collection
0x81, 0x03, // Input (Const, Var, Abs)
0xC0 // End Collection
};
// HID report map length
uint8_t hidReportMapLen = sizeof(hidReportMap);
uint8_t hidProtocolMode = HID_PROTOCOL_MODE_REPORT;
// HID report mapping table
static hidRptMap_t hidRptMap[HID_NUM_REPORTS];
esp_bt_uuid_t char_info_uuid = {LEN_UUID_16, {CHAR_HID_INFO_UUID}};
esp_bt_uuid_t char_ctnl_pt_uuid = {LEN_UUID_16, {CHAR_HID_CTNL_PT_UUID}};
esp_bt_uuid_t char_report_map_uuid = {LEN_UUID_16, {CHAR_REPORT_MAP_UUID}};
esp_bt_uuid_t char_report_uuid = {LEN_UUID_16, {CHAR_REPORT_UUID}};
esp_bt_uuid_t char_proto_mode_uuid = {LEN_UUID_16, {CHAR_PROTOCOL_MODE_UUID}};
esp_bt_uuid_t char_kb_in_report_uuid = {LEN_UUID_16, {CHAR_BOOT_KB_IN_REPORT_UUID}};
esp_bt_uuid_t char_kb_out_report_uuid = {LEN_UUID_16, {CHAR_BOOT_KB_OUT_REPORT_UUID}};
esp_bt_uuid_t char_mouse_in_report_uuid = {LEN_UUID_16, {CHAR_BOOT_MOUSE_IN_REPORT_UUID}};
/// Full HID device Database Description - Used to add attributes into the database
const char_desc_t hids_char_db[HIDD_LE_CHAR_MAX] = {
// HID Information Characteristic Value
[HIDD_LE_INFO_CHAR] = {
&char_info_uuid,
GATT_PERM_READ,
GATT_CHAR_PROP_BIT_READ
},
// HID Control Point Characteristic Value
[HIDD_LE_CTNL_PT_CHAR] = {
&char_ctnl_pt_uuid,
GATT_PERM_WRITE,
GATT_CHAR_PROP_BIT_WRITE_NR
},
// Report Map Characteristic Value
[HIDD_LE_REPORT_MAP_CHAR] = {
&char_report_map_uuid,
GATT_PERM_READ,
GATT_CHAR_PROP_BIT_READ
},
// Report Characteristic Value
[HIDD_LE_REPORT_CHAR] = {
&char_report_uuid,
(GATT_PERM_READ | GATT_PERM_WRITE),
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE | GATT_CHAR_PROP_BIT_WRITE_NR)
},
// Protocol Mode Characteristic Declaration
[HIDD_LE_PROTO_MODE_CHAR] = {
&char_proto_mode_uuid,
GATT_PERM_READ,
GATT_CHAR_PROP_BIT_READ,
},
// Boot Keyboard Input Report Characteristic Value
[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = {
&char_kb_in_report_uuid,
GATT_PERM_READ,
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY),
},
// Boot Keyboard Output Report Characteristic Value
[HIDD_LE_BOOT_KB_OUT_REPORT_CHAR] = {
&char_kb_out_report_uuid,
GATT_PERM_READ,
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE | GATT_CHAR_PROP_BIT_WRITE_NR)
},
// Boot Mouse Input Report Characteristic Value
[HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR] = {
&char_mouse_in_report_uuid,
GATT_PERM_READ,
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY),
},
};
static void hidd_add_characterisitc(const char_desc_t *char_desc);
/*****************************************************************************
** Constants
*****************************************************************************/
static void hidd_le_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data);
/*******************************************************************************
**
** Function hidd_add_characterisitc
**
** Description the callback function after the hid device profile has been register to the BTA manager module
**
** Returns NULL
**
*******************************************************************************/
static void hidd_add_characterisitc(const char_desc_t *char_desc)
{
uint16_t service_id;
if (char_desc == NULL) {
BTC_TRACE_ERROR("Invalid hid characteristic\n");
return;
}
//check the hid device serivce has been register to the data base or not
if (!hidd_le_env.enabled) {
BTC_TRACE_ERROR("The hid device didn't register yet\n");
return;
}
//get the service id from the env whitch has been register
service_id = hidd_le_env.hidd_clcb.cur_srvc_id;
if (char_desc->char_uuid != 0x00) {
// start added the charact to the data base
esp_ble_gatts_add_char (service_id,
char_desc->char_uuid,
char_desc->perm,
char_desc->prop);
}
}
/*******************************************************************************
**
** Function hidd_le_profile_cb
**
** Description the callback function after the hid device profile has been register to the BTA manager module
**
** Returns NULL
**
*******************************************************************************/
static void hidd_le_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
{
esp_gatts_rsp_t rsp;
esp_bt_uuid_t uuid = {LEN_UUID_16, {ATT_SVC_HID}};
static uint8_t hid_char_idx;
hidd_clcb_t *p_clcb = NULL;
uint8_t app_id = 0xff;
switch (event) {
case ESP_GATTS_REG_EVT:
//check the register of the hid device profile has been succeess or not
if (p_data->reg_oper.status != ESP_GATT_OK) {
BTC_TRACE_ERROR("hidd profile register failed\n");
}
hidd_le_env.hidd_inst.app_id = app_id;
//save the gatt interface in the hid device ENV
hidd_le_env.gatt_if = p_data->reg_oper.server_if;
//set the env flag to enable
hidd_le_env.enabled = true;
//create the hid device service to the service data base.
if (p_data->reg_oper.uuid.uu.uuid16 == ATT_SVC_HID) {
hidd_le_create_service(true);
}
break;
case ESP_GATTS_CREATE_EVT:
if (p_data->create.uuid.uu.uuid16 == ATT_SVC_HID) {
///store the service id to the env
hidd_le_env.hidd_clcb.cur_srvc_id = p_data->create.service_id;
//start the button service after created
esp_ble_gatts_start_srvc(p_data->create.service_id);
hid_char_idx = HIDD_LE_INFO_CHAR;
//added the info character to the data base.
hidd_add_characterisitc(&hids_char_db[hid_char_idx]);
hid_char_idx++;
}
break;
case ESP_GATTS_ADD_INCL_SRVC_EVT:
break;
case ESP_GATTS_ADD_CHAR_EVT:
//save the charateristic handle to the env
hidd_le_env.hidd_inst.att_tbl[hid_char_idx - 1] = p_data->add_result.attr_id;
BTC_TRACE_ERROR("hanlder = %x, p_data->add_result.char_uuid.uu.uuid16 = %x\n", p_data->add_result.attr_id,
p_data->add_result.char_uuid.uu.uuid16);
BTC_TRACE_ERROR("hid_char_idx=%x\n", hid_char_idx);
if (hid_char_idx <= HIDD_LE_CHAR_MAX) { //added the characteristic until the index overflow
if ((p_data->add_result.char_uuid.uu.uuid16 == CHAR_BOOT_KB_IN_REPORT_UUID) ||
(p_data->add_result.char_uuid.uu.uuid16 == CHAR_BOOT_MOUSE_IN_REPORT_UUID)) {
// add the gattc config descriptor to the notify charateristic
//tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE);
uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
BTC_TRACE_ERROR("p_data->add_result.char_uuid.uu.uuid16 = %x\n",
p_data->add_result.char_uuid.uu.uuid16);
esp_ble_gatts_add_char_descr (hidd_le_env.hidd_clcb.cur_srvc_id,
GATT_PERM_WRITE,
&uuid);
break;
}
hidd_add_characterisitc(&hids_char_db[hid_char_idx]);
}
hid_char_idx++;
break;
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
if (p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) {
uuid.uu.uuid16 = GATT_UUID_RPT_REF_DESCR;
BTA_GATTS_AddCharDescriptor (hidd_le_env.hidd_clcb.cur_srvc_id,
GATT_PERM_READ,
&uuid);
BTC_TRACE_ERROR("p_data->add_result.char_uuid.uu.uuid16 = %x\n",
p_data->add_result.char_uuid.uu.uuid16);
}
if (p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_RPT_REF_DESCR) {
if (hid_char_idx < HIDD_LE_CHAR_MAX) {
hidd_add_characterisitc(&hids_char_db[hid_char_idx]);
hid_char_idx++;
}
}
break;
case ESP_GATTS_READ_EVT: {
BTC_TRACE_ERROR("Hidd profile BTA_GATTS_READ_EVT\n");
UINT32 trans_id = p_data->req_data.trans_id;
UINT16 conn_id = p_data->req_data.conn_id;
UINT16 handle = p_data->req_data.p_data->read_req.handle;
bool is_long = p_data->req_data.p_data->read_req.is_long;
BTC_TRACE_ERROR("read request:event=0x%x,handle=0x%x,trans_id=0x%x,conn_id=0x%x\n",
event, handle, trans_id, conn_id);
hidd_read_attr_value(p_data->req_data.p_data, trans_id);
}
break;
case ESP_GATTS_WRITE_EVT:
esp_ble_gatts_send_rsp (p_data->req_data.conn_id, p_data->req_data.trans_id,
p_data->req_data.status, NULL);
break;
case ESP_GATTS_CONNECT_EVT:
p_clcb = &hidd_le_env.hidd_clcb;
if (!p_clcb->in_use) {
p_clcb->in_use = TRUE;
p_clcb->conn_id = p_data->conn.conn_id;;
BTC_TRACE_ERROR("hidd->conn_id = %x\n", p_data->conn.conn_id);
p_clcb->connected = TRUE;
memcpy(p_clcb->remote_bda, p_data->conn.remote_bda, BD_ADDR_LEN);
}
break;
case ESP_GATTS_DISCONNECT_EVT:
p_clcb = &hidd_le_env.hidd_clcb;
//set the connection flag to true
p_clcb->connected = false;
p_clcb->in_use = TRUE;
memset(p_clcb->remote_bda, 0, BD_ADDR_LEN);
break;
case ESP_GATTS_START_EVT:
break;
case ESP_GATTS_CONGEST_EVT:
if (hidd_le_env.hidd_clcb.connected && (hidd_le_env.hidd_clcb.conn_id == p_data->conn.conn_id)) {
//set the connection channal congested flag to true
hidd_le_env.hidd_clcb.congest = p_data->congest.congested;
}
break;
default:
break;
}
}
/*******************************************************************************
**
** Function hidd_le_create_service
**
** Description Create a Service for the hid device profile
**
** Parameters is_primary: this service is the primary service or not,true is the primary service
** false is not the primary service
** p_service_uuid: service UUID.
**
** Returns NULL
**
*******************************************************************************/
void hidd_le_create_service(BOOLEAN is_primary)
{
esp_gatts_if_t server_if ;
esp_bt_uuid_t uuid = {LEN_UUID_16, {ATT_SVC_HID}};
//the number of the hid device attributes in the hid service.
UINT16 num_handle = HIDD_LE_IDX_NB;
UINT8 inst = 0x00;
server_if = hidd_le_env.gatt_if;
hidd_le_env.inst_id = inst;
//start create the hid device service
esp_ble_gatts_create_srvc (server_if, &uuid, inst, num_handle, is_primary);
}
/*****************************************************************************
** Function hidd_read_attr_value
**
** Description it will be called when client sends a read request
******************************************************************************/
void hidd_read_attr_value(tGATTS_DATA *p_data, uint32_t trans_id)
{
hidd_inst_t *p_inst = &hidd_le_env.hidd_inst;
uint8_t i;
uint8_t status = ESP_GATT_OK;
uint8_t app_id = hidd_le_env.hidd_inst.app_id;
esp_gatt_status_t st = ESP_GATT_NOT_FOUND;
uint16_t handle = p_data->read_req.handle;
uint16_t conn_id = hidd_le_env.hidd_clcb.conn_id;
if (handle == p_inst->att_tbl[HIDD_LE_INFO_CHAR]) {
//read hid device info evt
p_inst->pending_evt = HIDD_LE_READ_INFO_EVT;
} else if (handle == p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR]) {
//read hid device contol point evt
p_inst->pending_evt = HIDD_LE_READ_CTNL_PT_EVT;
} else if (handle == p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR]) {
//read hid device report map value evt
p_inst->pending_evt = HIDD_LE_READ_REPORT_MAP_EVT;
} else if (handle == p_inst->att_tbl[HIDD_LE_REPORT_CHAR]) {
//read hid device report evt
p_inst->pending_evt = HIDD_LE_READ_REPORT_EVT;
} else if (handle == p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR]) {
//read hid device mode evt
p_inst->pending_evt = HIDD_LE_READ_PROTO_MODE_EVT;
} else if (handle == p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]) {
//read hid boot keyboard in report evt
p_inst->pending_evt = HIDD_LE_BOOT_KB_IN_REPORT_EVT;
} else if (handle == p_inst->att_tbl[HIDD_LE_BOOT_KB_OUT_REPORT_CHAR]) {
//read hid boot keyboard out report evt
p_inst->pending_evt = HIDD_LE_BOOT_KB_OUT_REPORT_EVT;
} else if (handle == p_inst->att_tbl[HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR]) {
//read hid device boot mouse in report evt
p_inst->pending_evt = HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT;
}
//start build the rsp message
hidd_rsp(trans_id, conn_id, app_id, status, p_inst->pending_evt, p_data);
}
/*******************************************************************************
**
** Function hidd_rsp
**
** Description Respond to a hid device service request
**
*******************************************************************************/
void hidd_rsp (uint32_t trans_id, uint16_t conn_id, uint8_t app_id,
esp_gatt_status_t status, uint8_t event, tGATTS_DATA *p_rsp)
{
hidd_inst_t *p_inst = &hidd_le_env.hidd_inst;
tGATTS_RSP rsp;
uint8_t *pp;
BTC_TRACE_ERROR("conn_id = %x, trans_id = %x, event = %x\n",
conn_id, trans_id, event);
if (p_inst->app_id == app_id) {
return ;
}
memset(&rsp, 0, sizeof(tGATTS_RSP));
if (p_inst->pending_evt == event) {
switch (event) {
case HIDD_LE_READ_INFO_EVT:
BTC_TRACE_ERROR(" p_inst->att_tbl[HIDD_LE_INFO_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_INFO_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_INFO_CHAR];
rsp.attr_value.len = HID_INFORMATION_LEN;
//copy the infomation value to the att value to sent to the peer device
memcpy(rsp.attr_value.value, hidInfo, HID_INFORMATION_LEN);
//start send the rsp to the peer device
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
case HIDD_LE_READ_CTNL_PT_EVT:
BTC_TRACE_ERROR(" p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR];
rsp.attr_value.len = 0;
//start send the rsp to the peer device
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
case HIDD_LE_READ_REPORT_MAP_EVT:
BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR];
rsp.attr_value.len = hidReportMapLen;
//copy the infomation value to the att value to sent to the peer device
memcpy(rsp.attr_value.value, hidReportMap, hidReportMapLen);
//start send the rsp to the peer device
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
case HIDD_LE_READ_REPORT_EVT:
BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
rsp.attr_value.len = 0;
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
case HIDD_LE_READ_PROTO_MODE_EVT:
BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR];
rsp.attr_value.len = 1;
pp = rsp.attr_value.value;
//copy the infomation value to the att value to sent to the peer device
memcpy(rsp.attr_value.value, &hidProtocolMode, rsp.attr_value.len);
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
case HIDD_LE_BOOT_KB_IN_REPORT_EVT:
BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
rsp.attr_value.len = 0;
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
case HIDD_LE_BOOT_KB_OUT_REPORT_EVT:
BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
rsp.attr_value.len = 0;
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
case HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT:
BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
rsp.attr_value.len = 0;
esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
break;
default:
break;
}
// p_inst->pending_clcb_idx = 0;
p_inst->pending_evt = 0;
p_inst->pending_hal = 0;
}
return;
}
/*******************************************************************************
**
** Function hidd_le_init
**
** Description Initializa the GATT Service for button profiles.
** Returns NULL
*******************************************************************************/
esp_gatt_status_t hidd_le_init (void)
{
tBT_UUID app_uuid = {LEN_UUID_16, {ATT_SVC_HID}};
if (hidd_le_env.enabled) {
BTC_TRACE_ERROR("hid device svc already initaliezd\n");
return ESP_GATT_ERROR;
} else {
memset(&hidd_le_env, 0, sizeof(hidd_le_env_t));
}
/*
register the hid deivce profile to the BTA_GATTS module*/
esp_ble_gatts_app_register(&app_uuid, hidd_le_profile_cb);
hidd_le_env.enabled = TRUE;
return ESP_GATT_OK;
}
#endif ///HIDD_LE_PROFILE_CFG

View File

@ -166,5 +166,7 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_callback_init(void); void btc_gap_callback_init(void);
void btc_gap_ble_deinit(void); void btc_gap_ble_deinit(void);
void btc_adv_list_init(void);
void btc_adv_list_deinit(void);
#endif /* __BTC_GAP_BLE_H__ */ #endif /* __BTC_GAP_BLE_H__ */

View File

@ -26,8 +26,11 @@ typedef enum {
BTC_GAP_BT_SEARCH_DEVICES_EVT = 0, BTC_GAP_BT_SEARCH_DEVICES_EVT = 0,
BTC_GAP_BT_SEARCH_SERVICES_EVT, BTC_GAP_BT_SEARCH_SERVICES_EVT,
BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT, BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT,
BTC_GAP_BT_READ_RSSI_DELTA_EVT,
BTC_GAP_BT_AUTH_CMPL_EVT, BTC_GAP_BT_AUTH_CMPL_EVT,
BTC_GAP_BT_CFM_REQ_EVT,
BTC_GAP_BT_KEY_NOTIF_EVT,
BTC_GAP_BT_KEY_REQ_EVT,
BTC_GAP_BT_READ_RSSI_DELTA_EVT,
}btc_gap_bt_evt_t; }btc_gap_bt_evt_t;
typedef enum { typedef enum {
@ -39,6 +42,9 @@ typedef enum {
BTC_GAP_BT_ACT_SET_COD, BTC_GAP_BT_ACT_SET_COD,
BTC_GAP_BT_ACT_READ_RSSI_DELTA, BTC_GAP_BT_ACT_READ_RSSI_DELTA,
BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE, BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE,
BTC_GAP_BT_ACT_SET_SECURITY_PARAM,
BTC_GAP_BT_ACT_PASSKEY_REPLY,
BTC_GAP_BT_ACT_CONFIRM_REPLY,
} btc_gap_bt_act_t; } btc_gap_bt_act_t;
/* btc_bt_gap_args_t */ /* btc_bt_gap_args_t */
@ -79,11 +85,31 @@ typedef union {
struct rm_bond_device_args { struct rm_bond_device_args {
bt_bdaddr_t bda; bt_bdaddr_t bda;
} rm_bond_device; } rm_bond_device;
// BTC_GAP_BT_ACT_SET_SECURITY_PARAM
struct set_sec_param_args {
esp_bt_sp_param_t param_type;
uint8_t len;
uint8_t *value;
} set_security_param;
// BTC_GAP_BT_ACT_PASSKEY_REPLY
struct passkey_reply_args {
bt_bdaddr_t bda;
bool accept;
uint32_t passkey;
} passkey_reply;
// BTC_GAP_BT_ACT_CONFIRM_REPLY
struct confirm_reply_args {
bt_bdaddr_t bda;
bool accept;
} confirm_reply;
} btc_gap_bt_args_t; } btc_gap_bt_args_t;
void btc_gap_bt_call_handler(btc_msg_t *msg); void btc_gap_bt_call_handler(btc_msg_t *msg);
void btc_gap_bt_cb_handler(btc_msg_t *msg); void btc_gap_bt_cb_handler(btc_msg_t *msg);
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_bt_busy_level_updated(uint8_t bl_flags); void btc_gap_bt_busy_level_updated(uint8_t bl_flags);
esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod); esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod);

View File

@ -1,265 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "prf_defs.h"
#if (HIDD_LE_PROFILE_CFG)
#include "bta_gatts_int.h"
#include "stack/bt_types.h"
#include "bta/bta_api.h"
#include "stack/gatt_api.h"
#include "bt_app_api.h"
/// Maximal number of HIDS that can be added in the DB
#ifndef USE_ONE_HIDS_INSTANCE
#define HIDD_LE_NB_HIDS_INST_MAX (2)
#else
#define HIDD_LE_NB_HIDS_INST_MAX (1)
#endif
// Number of HID reports defined in the service
#define HID_NUM_REPORTS 9
#define ATT_SVC_HID 0x1812
/// Maximal number of Report Char. that can be added in the DB for one HIDS - Up to 11
#define HIDD_LE_NB_REPORT_INST_MAX (5)
/// Maximal length of Report Char. Value
#define HIDD_LE_REPORT_MAX_LEN (45)
/// Maximal length of Report Map Char. Value
#define HIDD_LE_REPORT_MAP_MAX_LEN (512)
/// Length of Boot Report Char. Value Maximal Length
#define HIDD_LE_BOOT_REPORT_MAX_LEN (8)
/// Boot KB Input Report Notification Configuration Bit Mask
#define HIDD_LE_BOOT_KB_IN_NTF_CFG_MASK (0x40)
/// Boot KB Input Report Notification Configuration Bit Mask
#define HIDD_LE_BOOT_MOUSE_IN_NTF_CFG_MASK (0x80)
/// Boot Report Notification Configuration Bit Mask
#define HIDD_LE_REPORT_NTF_CFG_MASK (0x20)
/* HID information flags */
#define HID_FLAGS_REMOTE_WAKE 0x01 // RemoteWake
#define HID_FLAGS_NORMALLY_CONNECTABLE 0x02 // NormallyConnectable
/* Control point commands */
#define HID_CMD_SUSPEND 0x00 // Suspend
#define HID_CMD_EXIT_SUSPEND 0x01 // Exit Suspend
/* HID protocol mode values */
#define HID_PROTOCOL_MODE_BOOT 0x00 // Boot Protocol Mode
#define HID_PROTOCOL_MODE_REPORT 0x01 // Report Protocol Mode
/* Attribute value lengths */
#define HID_PROTOCOL_MODE_LEN 1 // HID Protocol Mode
#define HID_INFORMATION_LEN 4 // HID Information
#define HID_REPORT_REF_LEN 2 // HID Report Reference Descriptor
#define HID_EXT_REPORT_REF_LEN 2 // External Report Reference Descriptor
// HID feature flags
#define HID_KBD_FLAGS HID_FLAGS_REMOTE_WAKE
/// HID Service Attributes Indexes
enum {
HIDD_LE_IDX_SVC,
// Included Service
HIDD_LE_IDX_INCL_SVC,
// HID Information
HIDD_LE_IDX_HID_INFO_CHAR,
HIDD_LE_IDX_HID_INFO_VAL,
// HID Control Point
HIDD_LE_IDX_HID_CTNL_PT_CHAR,
HIDD_LE_IDX_HID_CTNL_PT_VAL,
// Report Map
HIDD_LE_IDX_REPORT_MAP_CHAR,
HIDD_LE_IDX_REPORT_MAP_VAL,
HIDD_LE_IDX_REPORT_MAP_EXT_REP_REF,
// Protocol Mode
HIDD_LE_IDX_PROTO_MODE_CHAR,
HIDD_LE_IDX_PROTO_MODE_VAL,
// Boot Keyboard Input Report
HIDD_LE_IDX_BOOT_KB_IN_REPORT_CHAR,
HIDD_LE_IDX_BOOT_KB_IN_REPORT_VAL,
HIDD_LE_IDX_BOOT_KB_IN_REPORT_NTF_CFG,
// Boot Keyboard Output Report
HIDD_LE_IDX_BOOT_KB_OUT_REPORT_CHAR,
HIDD_LE_IDX_BOOT_KB_OUT_REPORT_VAL,
// Boot Mouse Input Report
HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_CHAR,
HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_VAL,
HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG,
// Report
HIDD_LE_IDX_REPORT_CHAR,
HIDD_LE_IDX_REPORT_VAL,
HIDD_LE_IDX_REPORT_REP_REF,
HIDD_LE_IDX_REPORT_NTF_CFG,
HIDD_LE_IDX_NB,
};
/// Attribute Table Indexes
enum {
HIDD_LE_INFO_CHAR,
HIDD_LE_CTNL_PT_CHAR,
HIDD_LE_REPORT_MAP_CHAR,
HIDD_LE_REPORT_CHAR,
HIDD_LE_PROTO_MODE_CHAR,
HIDD_LE_BOOT_KB_IN_REPORT_CHAR,
HIDD_LE_BOOT_KB_OUT_REPORT_CHAR,
HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR,
HIDD_LE_CHAR_MAX //= HIDD_LE_REPORT_CHAR + HIDD_LE_NB_REPORT_INST_MAX,
};
///att read event table Indexs
enum {
HIDD_LE_READ_INFO_EVT,
HIDD_LE_READ_CTNL_PT_EVT,
HIDD_LE_READ_REPORT_MAP_EVT,
HIDD_LE_READ_REPORT_EVT,
HIDD_LE_READ_PROTO_MODE_EVT,
HIDD_LE_BOOT_KB_IN_REPORT_EVT,
HIDD_LE_BOOT_KB_OUT_REPORT_EVT,
HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT,
HID_LE_EVT_MAX
};
/// Client Characteristic Configuration Codes
enum {
HIDD_LE_DESC_MASK = 0x10,
HIDD_LE_BOOT_KB_IN_REPORT_CFG = HIDD_LE_BOOT_KB_IN_REPORT_CHAR | HIDD_LE_DESC_MASK,
HIDD_LE_BOOT_MOUSE_IN_REPORT_CFG = HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR | HIDD_LE_DESC_MASK,
HIDD_LE_REPORT_CFG = HIDD_LE_REPORT_CHAR | HIDD_LE_DESC_MASK,
};
/// Features Flag Values
enum {
HIDD_LE_CFG_KEYBOARD = 0x01,
HIDD_LE_CFG_MOUSE = 0x02,
HIDD_LE_CFG_PROTO_MODE = 0x04,
HIDD_LE_CFG_MAP_EXT_REF = 0x08,
HIDD_LE_CFG_BOOT_KB_WR = 0x10,
HIDD_LE_CFG_BOOT_MOUSE_WR = 0x20,
};
/// Report Char. Configuration Flag Values
enum {
HIDD_LE_CFG_REPORT_IN = 0x01,
HIDD_LE_CFG_REPORT_OUT = 0x02,
//HOGPD_CFG_REPORT_FEAT can be used as a mask to check Report type
HIDD_LE_CFG_REPORT_FEAT = 0x03,
HIDD_LE_CFG_REPORT_WR = 0x10,
};
/// Pointer to the connection clean-up function
#define HIDD_LE_CLEANUP_FNCT (NULL)
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// HIDD Features structure
typedef struct {
/// Service Features
uint8_t svc_features;
/// Number of Report Char. instances to add in the database
uint8_t report_nb;
/// Report Char. Configuration
uint8_t report_char_cfg[HIDD_LE_NB_REPORT_INST_MAX];
} hidd_feature_t;
typedef struct {
BOOLEAN in_use;
BOOLEAN congest;
uint16_t conn_id;
BOOLEAN connected;
BD_ADDR remote_bda;
uint32_t trans_id;
uint8_t cur_srvc_id;
} hidd_clcb_t;
// HID report mapping table
typedef struct {
uint16_t handle; // Handle of report characteristic
uint16_t cccdHandle; // Handle of CCCD for report characteristic
uint8_t id; // Report ID
uint8_t type; // Report type
uint8_t mode; // Protocol mode (report or boot)
} hidRptMap_t;
typedef struct {
/// hidd profile id
uint8_t app_id;
/// Notified handle
uint16_t ntf_handle;
///Attribute handle Table
uint16_t att_tbl[HIDD_LE_CHAR_MAX];
/// Supported Features
hidd_feature_t hidd_feature[HIDD_LE_NB_HIDS_INST_MAX];
/// Current Protocol Mode
uint8_t proto_mode[HIDD_LE_NB_HIDS_INST_MAX];
/// Number of HIDS added in the database
uint8_t hids_nb;
uint8_t pending_evt;
uint16_t pending_hal;
} hidd_inst_t;
/* service engine control block */
typedef struct {
hidd_clcb_t hidd_clcb; /* connection link*/
esp_gatt_if_t gatt_if;
BOOLEAN enabled;
BOOLEAN is_primery;
hidd_inst_t hidd_inst;
uint8_t inst_id;
} hidd_le_env_t;
extern hidd_le_env_t hidd_le_env;
void hidd_le_create_service(BOOLEAN is_primary);
void hidd_rsp (uint32_t trans_id, uint16_t conn_id, uint8_t app_id,
esp_gatt_status_t status, uint8_t event, tGATTS_DATA *p_rsp);
void hidd_read_attr_value(tGATTS_DATA *p_data, uint32_t trans_id);
tGATT_STATUS hidd_le_init (void);
#endif ///HIDD_LE_PROFILE_CFG

View File

@ -26,9 +26,6 @@
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
#ifndef SIZE_MAX
#define SIZE_MAX 254
#endif
/*Timer Related Defination*/ /*Timer Related Defination*/
//by Snake.T //by Snake.T

View File

@ -94,6 +94,10 @@
#define CLASSIC_BT_INCLUDED FALSE #define CLASSIC_BT_INCLUDED FALSE
#endif /* CLASSIC_BT_INCLUDED */ #endif /* CLASSIC_BT_INCLUDED */
#ifndef CONFIG_GATTC_CACHE_NVS_FLASH
#define CONFIG_GATTC_CACHE_NVS_FLASH FALSE
#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */
/****************************************************************************** /******************************************************************************
** **
** BLE features ** BLE features
@ -111,13 +115,25 @@
#define GATTC_INCLUDED FALSE #define GATTC_INCLUDED FALSE
#endif /* CONFIG_GATTC_ENABLE */ #endif /* CONFIG_GATTC_ENABLE */
#if (CONFIG_GATTC_ENABLE && CONFIG_GATTC_CACHE_NVS_FLASH)
#define GATTC_CACHE_NVS TRUE
#else
#define GATTC_CACHE_NVS FALSE
#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */
#if (CONFIG_SMP_ENABLE) #if (CONFIG_SMP_ENABLE)
#define SMP_INCLUDED TRUE #define SMP_INCLUDED TRUE
#define BLE_PRIVACY_SPT TRUE #define BLE_PRIVACY_SPT TRUE
#else #else
#define SMP_INCLUDED FALSE #define SMP_INCLUDED FALSE
#define BLE_PRIVACY_SPT FALSE #define BLE_PRIVACY_SPT FALSE
#endif /* CONFIG_GATTC_ENABLE */ #endif /* CONFIG_SMP_ENABLE */
#if (CONFIG_BT_SSP_ENABLE)
#define BT_SSP_INCLUDED TRUE
#else
#define BT_SSP_INCLUDED FALSE
#endif /* CONFIG_BT_SSP_ENABLE */
#if (CONFIG_BT_ACL_CONNECTIONS) #if (CONFIG_BT_ACL_CONNECTIONS)
#define MAX_ACL_CONNECTIONS CONFIG_BT_ACL_CONNECTIONS #define MAX_ACL_CONNECTIONS CONFIG_BT_ACL_CONNECTIONS
@ -297,6 +313,16 @@
#define BTA_AV_CO_CP_SCMS_T FALSE//FALSE #define BTA_AV_CO_CP_SCMS_T FALSE//FALSE
#endif #endif
#ifndef QUEUE_CONGEST_SIZE
#define QUEUE_CONGEST_SIZE 40
#endif
#ifndef CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK
#define SCAN_QUEUE_CONGEST_CHECK FALSE
#else
#define SCAN_QUEUE_CONGEST_CHECK CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK
#endif
/* This feature is used to eanble interleaved scan*/ /* This feature is used to eanble interleaved scan*/
#ifndef BTA_HOST_INTERLEAVE_SEARCH #ifndef BTA_HOST_INTERLEAVE_SEARCH
#define BTA_HOST_INTERLEAVE_SEARCH FALSE//FALSE #define BTA_HOST_INTERLEAVE_SEARCH FALSE//FALSE
@ -571,7 +597,7 @@
#define BTM_DEFAULT_DISC_INTERVAL 0x0800 #define BTM_DEFAULT_DISC_INTERVAL 0x0800
#endif #endif
/* /*
* {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS} * {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS}
* *
* SERVICE_CLASS:0x5A (Bit17 -Networking,Bit19 - Capturing,Bit20 -Object Transfer,Bit22 -Telephony) * SERVICE_CLASS:0x5A (Bit17 -Networking,Bit19 - Capturing,Bit20 -Object Transfer,Bit22 -Telephony)
@ -744,6 +770,14 @@
#define BTM_BLE_CONFORMANCE_TESTING FALSE #define BTM_BLE_CONFORMANCE_TESTING FALSE
#endif #endif
/******************************************************************************
**
** CONTROLLER TO HOST FLOW CONTROL
**
******************************************************************************/
#define C2H_FLOW_CONTROL_INCLUDED TRUE
/****************************************************************************** /******************************************************************************
** **
** L2CAP ** L2CAP
@ -1127,6 +1161,20 @@
#define SMP_LINK_TOUT_MIN 2 #define SMP_LINK_TOUT_MIN 2
#endif #endif
#endif #endif
/******************************************************************************
**
** BT_SSP
**
******************************************************************************/
#ifndef BT_SSP_INCLUDED
#define BT_SSP_INCLUDED FALSE
#endif
#if BT_SSP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == FALSE
#error "Can't have SSP without CLASSIC BT"
#endif
/****************************************************************************** /******************************************************************************
** **
** SDP ** SDP

View File

@ -32,6 +32,18 @@ typedef struct {
UINT8 ble_resp_key; UINT8 ble_resp_key;
UINT8 ble_max_key_size; UINT8 ble_max_key_size;
#endif #endif
} tBTE_APPL_CFG; } tBTE_APPL_CFG;
extern tBTE_APPL_CFG bte_appl_cfg; extern tBTE_APPL_CFG bte_appl_cfg;
typedef struct {
#if ((CLASSIC_BT_INCLUDED == TRUE) && (BT_SSP_INCLUDED == TRUE))
UINT8 bt_auth_req;
UINT8 bt_io_cap;
UINT8 *bt_oob_auth_data;
#endif
} tBTE_BT_APPL_CFG;
extern tBTE_BT_APPL_CFG bte_bt_appl_cfg;

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