mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Compare commits
459 Commits
581082fa43
...
fda362cce7
Author | SHA1 | Date | |
---|---|---|---|
|
fda362cce7 | ||
|
46acfdce96 | ||
|
945af68d74 | ||
|
5d792910be | ||
|
82a29b7d21 | ||
|
0c9d7c9dd0 | ||
|
3629909b11 | ||
|
3a35b26de1 | ||
|
2a6be654cd | ||
|
3000402fcf | ||
|
b0712b6a2b | ||
|
e051b921b8 | ||
|
98fdb1a97f | ||
|
c01512f4b0 | ||
|
19d512ebee | ||
|
9be8822b61 | ||
|
1d7241acc1 | ||
|
903c11ff1a | ||
|
e24005c8db | ||
|
1ac6043bce | ||
|
52002bf92d | ||
|
bc0404ae03 | ||
|
46350e362e | ||
|
6be09eb5b8 | ||
|
3b6f8b1f3d | ||
|
9529c4ece4 | ||
|
a30ed69f69 | ||
|
180bc4bd8c | ||
|
3edbd0741a | ||
|
a71e0fc028 | ||
|
f5b55b2967 | ||
|
564d777018 | ||
|
d9c15bb772 | ||
|
d70f24e414 | ||
|
8320e4281b | ||
|
db8ffcacf4 | ||
|
ae67021e1e | ||
|
446528d40f | ||
|
c44e7dcb14 | ||
|
28f12bfb47 | ||
|
675fac1a6c | ||
|
072ea6bb44 | ||
|
9588953e07 | ||
|
d57ee7d87e | ||
|
dad039e27f | ||
|
eeb55c3f04 | ||
|
1604cef916 | ||
|
d63beec095 | ||
|
a30edf60eb | ||
|
13d4235d73 | ||
|
ca331a2521 | ||
|
c2366d5df6 | ||
|
67c5d37e75 | ||
|
70ff700f56 | ||
|
80eee8214e | ||
|
8ff8b520f3 | ||
|
fe29994924 | ||
|
c843c2c4fe | ||
|
00eb97725b | ||
|
9b3eda0974 | ||
|
6b9242b5c7 | ||
|
86c1ad216c | ||
|
3c72084932 | ||
|
f0903aef6b | ||
|
8e4cc79a27 | ||
|
3c65f1b654 | ||
|
32c7694f56 | ||
|
115dec68ae | ||
|
da4a0798f4 | ||
|
4c7d9f9859 | ||
|
c62555d132 | ||
|
5bef0f5664 | ||
|
7e2a7bd5b2 | ||
|
bff2f9b2dd | ||
|
79da963c62 | ||
|
2a12872d0a | ||
|
b4749b88d9 | ||
|
fde00f570a | ||
|
b01fd6b026 | ||
|
534c3288ae | ||
|
cba8c5d7ca | ||
|
b3ccc09ec3 | ||
|
81f4ef73c3 | ||
|
391dd7b9ad | ||
|
b8d23b334b | ||
|
9ca231e76e | ||
|
64203d1403 | ||
|
dcd433e62c | ||
|
ed92c2c226 | ||
|
d1a00f5808 | ||
|
d071bb4c56 | ||
|
bf9d01bf2a | ||
|
22facff58c | ||
|
3415ff27d6 | ||
|
97e42349aa | ||
|
2dbb811747 | ||
|
6a82497bdc | ||
|
5c43055e3e | ||
|
6f3241a34b | ||
|
2109f81102 | ||
|
01f521f3a0 | ||
|
eb606b9777 | ||
|
eb676c0afc | ||
|
91ad4bcbce | ||
|
fb1b91c8d7 | ||
|
c36674eaa8 | ||
|
7a03ac385d | ||
|
02cd0253a1 | ||
|
f8894140ee | ||
|
6ade64eb05 | ||
|
4d2c44f511 | ||
|
0ef9ecb715 | ||
|
c929a01931 | ||
|
afe08638a0 | ||
|
453850eff2 | ||
|
28a92e56db | ||
|
27cf5267a1 | ||
|
a1b8fc9635 | ||
|
6a0ec48b11 | ||
|
26be72307b | ||
|
7667d9ebbe | ||
|
fcd751e79c | ||
|
84791fce2f | ||
|
a360c737ea | ||
|
40892b67c5 | ||
|
4b74e4e595 | ||
|
030470efa6 | ||
|
1a065dc37a | ||
|
5f865a81b9 | ||
|
cb2624fb3f | ||
|
ef1bffa937 | ||
|
0244f7a9b5 | ||
|
812fbb7874 | ||
|
328de495de | ||
|
4281f58229 | ||
|
fe47676a8b | ||
|
794c60411b | ||
|
f68d16e7ad | ||
|
200241b9aa | ||
|
82c8973add | ||
|
75fec0bdff | ||
|
4e4fb3a57b | ||
|
2113e99aeb | ||
|
cfb78587f3 | ||
|
9725f3af74 | ||
|
6ec1e9107f | ||
|
ccd8486462 | ||
|
2512588884 | ||
|
5a5c004691 | ||
|
f9e7305efd | ||
|
7834519af8 | ||
|
0b70e296a0 | ||
|
83809910d2 | ||
|
dd3d5f1598 | ||
|
3c99557eee | ||
|
db50b1ac63 | ||
|
efdc853b45 | ||
|
f4dd74ed96 | ||
|
46cccdea5f | ||
|
1489514ee5 | ||
|
c45e084145 | ||
|
b435473323 | ||
|
205e66c9fd | ||
|
1cfb537813 | ||
|
cda2846558 | ||
|
48b1cd53d9 | ||
|
bf52e37fa8 | ||
|
353c1ea77e | ||
|
6c4fb48783 | ||
|
256ef127dd | ||
|
dacc1f94dd | ||
|
30a48b126e | ||
|
aa80dbe251 | ||
|
c53cedb947 | ||
|
436bcd6c06 | ||
|
cdb9f2b098 | ||
|
8bf68ff07b | ||
|
28340977bd | ||
|
c7415fc78d | ||
|
e5fcc53755 | ||
|
bd38d80ff0 | ||
|
f98e288e24 | ||
|
5f6971bfa7 | ||
|
16461de2b2 | ||
|
eb2307af36 | ||
|
147a249d7a | ||
|
0de83be0fe | ||
|
cb0d073551 | ||
|
d7298a71c3 | ||
|
da858edb7a | ||
|
928addee19 | ||
|
21ee174957 | ||
|
5fe1f22b34 | ||
|
9e9225dbc2 | ||
|
45b7b7dc1c | ||
|
a8482f580a | ||
|
ee9a072c82 | ||
|
2da0f66e9a | ||
|
27a88b83fb | ||
|
965986bcf1 | ||
|
82ddb6920c | ||
|
4d4062a2b8 | ||
|
d4f60febdd | ||
|
8daa2e308b | ||
|
e035e798b7 | ||
|
5e46dba0f7 | ||
|
899879cfad | ||
|
c6e7e82524 | ||
|
d9d316b97d | ||
|
d8d57e1965 | ||
|
5ddeab65e3 | ||
|
73079de058 | ||
|
ffb227ebd2 | ||
|
68d504b4fd | ||
|
bfdb9f308d | ||
|
a80603c05b | ||
|
a760bd2472 | ||
|
bc36fda936 | ||
|
798b7c92c4 | ||
|
dc1851bd5a | ||
|
1fa6d49f6f | ||
|
dca0465095 | ||
|
53a8345e60 | ||
|
83393cdec8 | ||
|
1889851d7c | ||
|
c6433de7cc | ||
|
2cef80666b | ||
|
8b962f91a2 | ||
|
4dd715922f | ||
|
fac1966c9b | ||
|
015ab1d18f | ||
|
7b0b80f46f | ||
|
d2123cf531 | ||
|
52175a6548 | ||
|
6e8a958754 | ||
|
0cd6532d36 | ||
|
37fa09f1dc | ||
|
3081a4ea49 | ||
|
00991f1bf5 | ||
|
fd192e0e9e | ||
|
3008d11a68 | ||
|
35a6671072 | ||
|
5486653a18 | ||
|
8fd3e8c0d3 | ||
|
e8dab4c257 | ||
|
ba06e0cfc8 | ||
|
09bbc75d96 | ||
|
6abe40e590 | ||
|
3aee7c920d | ||
|
4d046b3732 | ||
|
b61a5e7636 | ||
|
c098388a2f | ||
|
720b74026c | ||
|
e8ac6af67e | ||
|
22f213b518 | ||
|
2e100a3518 | ||
|
65df4d6e34 | ||
|
f3c4d57f13 | ||
|
c6bed070d6 | ||
|
e1102e6794 | ||
|
3d403a4ba8 | ||
|
8a608da2b0 | ||
|
08a1e1350c | ||
|
e1d3d830ce | ||
|
12fc7a677e | ||
|
1b6a829e81 | ||
|
eab98765ad | ||
|
c27614fdaa | ||
|
31c60963b5 | ||
|
c7d532049a | ||
|
832e08c82f | ||
|
0b43a55625 | ||
|
b66f4444d7 | ||
|
44ff115557 | ||
|
40352943e3 | ||
|
b93e2a6915 | ||
|
e1e02cae0c | ||
|
1f41827bc3 | ||
|
f5a2a1ff82 | ||
|
04e925e4a8 | ||
|
2af66dac25 | ||
|
09b421674b | ||
|
e411e43b4b | ||
|
6547315dde | ||
|
e2ba2cfbe2 | ||
|
c46cb415bd | ||
|
b4100e5362 | ||
|
21f79616bd | ||
|
13e42707a0 | ||
|
c41d432397 | ||
|
71fb3d2f31 | ||
|
05e74480f5 | ||
|
fba9b50456 | ||
|
56ac70430e | ||
|
e4e23087ee | ||
|
e4a372ab76 | ||
|
9b242a4817 | ||
|
f62628d334 | ||
|
a0e954b941 | ||
|
afd74267c8 | ||
|
0a2dc3b2d6 | ||
|
9994f493ed | ||
|
87b295a35f | ||
|
75c917eef8 | ||
|
f555812975 | ||
|
d242b662c4 | ||
|
50ec7f990c | ||
|
ac76402aff | ||
|
d5c58a1d8c | ||
|
c7a238054a | ||
|
8539760e79 | ||
|
02c3445c66 | ||
|
50d410e1c8 | ||
|
f789b4eb45 | ||
|
71fe7543f1 | ||
|
0b75e75f2c | ||
|
594880dae4 | ||
|
1e5efd7fa7 | ||
|
d604e09274 | ||
|
f972cd4bbd | ||
|
85da8402be | ||
|
72266fd7ce | ||
|
c2f6144daa | ||
|
0e30c42625 | ||
|
aaf1f868d5 | ||
|
ef221d007a | ||
|
bc0b04d779 | ||
|
9c81fe6114 | ||
|
17fc026c48 | ||
|
42cf1d8867 | ||
|
46af50ee5a | ||
|
d4447739a9 | ||
|
fd94fe1161 | ||
|
c9434aaebf | ||
|
0926a700c2 | ||
|
691b6e245b | ||
|
9e864ffe26 | ||
|
65f49c6a7b | ||
|
f0a2091e4d | ||
|
58775cce6e | ||
|
d5341bd455 | ||
|
f7129481ed | ||
|
4cbf2eb899 | ||
|
2172aaf6a2 | ||
|
952533bee3 | ||
|
5141f01e56 | ||
|
8d75f0d198 | ||
|
489ba7c2fa | ||
|
9a47de53e1 | ||
|
a90000856c | ||
|
599c14d8f0 | ||
|
2014e5ae10 | ||
|
737bbb4a91 | ||
|
fe43c8f1b5 | ||
|
10f10ad313 | ||
|
1263b97c5b | ||
|
6933ba39bc | ||
|
24047f9a04 | ||
|
3362e18432 | ||
|
160bd658fc | ||
|
57d39c3923 | ||
|
401b395106 | ||
|
eee58bb717 | ||
|
2dc4ca4fa6 | ||
|
d529da25c4 | ||
|
1370511dff | ||
|
29b028076a | ||
|
664c2e6b77 | ||
|
6f1671c9c9 | ||
|
f1c0fc0bbd | ||
|
205e814563 | ||
|
5737ba06c3 | ||
|
a262e879d1 | ||
|
725b9ec81e | ||
|
06fdb02435 | ||
|
5e4d6190d8 | ||
|
4d2881dac1 | ||
|
7498f4655a | ||
|
4c87af6359 | ||
|
47212eaa3a | ||
|
a9d960a81f | ||
|
fd79c593fb | ||
|
0272fc405b | ||
|
5184d7ec98 | ||
|
7555686649 | ||
|
b1df2688ce | ||
|
417edbb2e2 | ||
|
92fc3e9a5d | ||
|
65d18fce4c | ||
|
5bb93061a3 | ||
|
f90b847cb1 | ||
|
c605620073 | ||
|
70d4414eeb | ||
|
6f37ff7a8f | ||
|
24ae042bba | ||
|
ca05aa5cd2 | ||
|
386420067a | ||
|
f6003fb8bf | ||
|
dba8722bc0 | ||
|
e7c0d69215 | ||
|
057b6b72ba | ||
|
3ccdd8b397 | ||
|
9ec1042dff | ||
|
17fed13a27 | ||
|
646d2f9e4a | ||
|
f36fb4cdb0 | ||
|
0f11052406 | ||
|
b341791f78 | ||
|
ab4e658af6 | ||
|
53dff5357f | ||
|
227f80ff88 | ||
|
5dff189341 | ||
|
d0ec6fc04d | ||
|
d74ff5224c | ||
|
4955a199a8 | ||
|
d7ea73ad66 | ||
|
c2b5339275 | ||
|
72bcaf1d74 | ||
|
19bf686d5e | ||
|
3857f779cc | ||
|
5e4674775b | ||
|
c4f60d91f1 | ||
|
331fd7f79f | ||
|
5316a36175 | ||
|
fb55646270 | ||
|
4854bf8640 | ||
|
cac0ef9d11 | ||
|
54db1cda8b | ||
|
7dd15bee31 | ||
|
73987108cd | ||
|
7b417fc3f2 | ||
|
88527faff8 | ||
|
1c22f6c4e8 | ||
|
be1c677bdd | ||
|
c564817862 | ||
|
8a5184e68e | ||
|
9becdfdc6d | ||
|
d025ff4073 | ||
|
f3eaa7abae | ||
|
d15e53d876 | ||
|
727c6a82ea | ||
|
f8202963e6 | ||
|
8a39db3fae | ||
|
215f95c110 | ||
|
25189b190f | ||
|
ccf5989505 | ||
|
f0ca91b103 | ||
|
a55d8bf12b | ||
|
c9d4913393 | ||
|
520fda61cd | ||
|
67a8480aec | ||
|
fce2680e91 | ||
|
8842e5764f | ||
|
58f18216ed | ||
|
681b372668 | ||
|
04168efcaf | ||
|
3b97011e39 | ||
|
5e9ac5bdf7 | ||
|
fc27c6609c |
@ -1,4 +1,4 @@
|
||||
[codespell]
|
||||
skip = build,*.yuv,components/fatfs/src/*,alice.txt,*.rgb,components/wpa_supplicant/*,components/esp_wifi/*,*.pem
|
||||
ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,wel,ot,fane,assertIn
|
||||
ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,wel,ot,fane,assertIn,registr
|
||||
write-changes = true
|
||||
|
@ -59,6 +59,7 @@
|
||||
/CONTRIBUTING.md @esp-idf-codeowners/docs
|
||||
/Kconfig @esp-idf-codeowners/build-config
|
||||
/README*.md @esp-idf-codeowners/docs
|
||||
/ROADMAP*.md @esp-idf-codeowners/docs
|
||||
/SUPPORT_POLICY*.md @esp-idf-codeowners/docs
|
||||
/add_path.sh @esp-idf-codeowners/tools
|
||||
/conftest.py @esp-idf-codeowners/ci
|
||||
|
@ -156,11 +156,12 @@ build_clang_test_apps_esp32s3:
|
||||
extends:
|
||||
- .build_cmake_clang_template
|
||||
variables:
|
||||
# For RISCV clang generates '.linker-options' sections of type 'llvm_linker_options' in asm files.
|
||||
# See (https://llvm.org/docs/Extensions.html#linker-options-section-linker-options).
|
||||
# Binutils gas ignores them with warning.
|
||||
# TODO: LLVM-333, Use integrated assembler.
|
||||
TEST_BUILD_OPTS_EXTRA: "--ignore-warning-str 'Warning: unrecognized section type'"
|
||||
# https://reviews.llvm.org/D90108.
|
||||
# GNU 'as' lets .weak override .globl since binutils-gdb
|
||||
# https://github.com/bminor/binutils-gdb/commit/5ca547dc2399a0a5d9f20626d4bf5547c3ccfddd (1996)
|
||||
# while MC lets the last directive win (PR38921).
|
||||
# For RISCV chips we use integrated assembler by default, so suppress this warning to pass CI pipeline.
|
||||
TEST_BUILD_OPTS_EXTRA: "--ignore-warning-str 'changed binding to STB_WEAK'"
|
||||
|
||||
build_clang_test_apps_esp32c3:
|
||||
extends:
|
||||
|
@ -147,16 +147,16 @@ variables:
|
||||
# install latest python packages
|
||||
# target test jobs
|
||||
if [[ "${CI_JOB_STAGE}" == "target_test" ]]; then
|
||||
run_cmd bash install.sh --enable-ci --enable-pytest
|
||||
run_cmd bash install.sh --enable-ci --enable-pytest --enable-test-specific
|
||||
elif [[ "${CI_JOB_STAGE}" == "build_doc" ]]; then
|
||||
run_cmd bash install.sh --enable-ci --enable-docs
|
||||
elif [[ "${CI_JOB_STAGE}" == "build" ]]; then
|
||||
run_cmd bash install.sh --enable-ci --enable-pytest
|
||||
run_cmd bash install.sh --enable-ci
|
||||
else
|
||||
if ! echo "${CI_JOB_NAME}" | egrep ".*pytest.*"; then
|
||||
run_cmd bash install.sh --enable-ci
|
||||
else
|
||||
run_cmd bash install.sh --enable-ci --enable-pytest
|
||||
run_cmd bash install.sh --enable-ci --enable-pytest --enable-test-specific
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -223,6 +223,8 @@ variables:
|
||||
- *common-before_scripts
|
||||
# On macOS, these tools need to be installed
|
||||
- export IDF_TOOLS_PATH="${HOME}/.espressif_runner_${CI_RUNNER_ID}_${CI_CONCURRENT_ID}"
|
||||
# remove idf-env.json, since it may contains enabled "features"
|
||||
- rm -f $IDF_TOOLS_PATH/idf-env.json
|
||||
- $IDF_PATH/tools/idf_tools.py --non-interactive install cmake ninja
|
||||
# This adds tools (compilers) and the version-specific Python environment to PATH
|
||||
- *setup_tools_and_idf_python_venv
|
||||
|
@ -83,6 +83,8 @@
|
||||
|
||||
- "tools/idf_monitor.py"
|
||||
|
||||
- "tools/activate.py"
|
||||
|
||||
- "tools/idf.py"
|
||||
- "tools/idf_py_actions/**/*"
|
||||
- "tools/test_idf_py/**/*"
|
||||
@ -96,6 +98,11 @@
|
||||
- "tools/test_idf_tools/**/*"
|
||||
- "tools/install_util.py"
|
||||
|
||||
- "tools/export_utils/utils.py"
|
||||
- "tools/export_utils/shell_types.py"
|
||||
- "tools/export_utils/console_output.py"
|
||||
- "tools/export_utils/activate_venv.py"
|
||||
|
||||
- "tools/requirements/*"
|
||||
- "tools/requirements.json"
|
||||
- "tools/requirements_schema.json"
|
||||
|
@ -175,6 +175,10 @@ if(CONFIG_COMPILER_DISABLE_GCC13_WARNINGS)
|
||||
"-Wno-dangling-reference")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_DISABLE_GCC14_WARNINGS)
|
||||
list(APPEND compile_options "-Wno-calloc-transposed-args")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS)
|
||||
if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
idf_build_replace_option_from_property(COMPILE_OPTIONS "-Werror" "-Werror=all")
|
||||
|
8
Kconfig
8
Kconfig
@ -587,6 +587,13 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
Enable this option if use GCC 13 or newer, and want to disable warnings which don't appear with
|
||||
GCC 12.
|
||||
|
||||
config COMPILER_DISABLE_GCC14_WARNINGS
|
||||
bool "Disable new warnings introduced in GCC 14"
|
||||
default "n"
|
||||
help
|
||||
Enable this option if use GCC 14 or newer, and want to disable warnings which don't appear with
|
||||
GCC 13.
|
||||
|
||||
config COMPILER_DUMP_RTL_FILES
|
||||
bool "Dump RTL files during compilation"
|
||||
help
|
||||
@ -669,6 +676,5 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
- CONFIG_ESPTOOLPY_FLASHFREQ_120M && CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
|
||||
- CONFIG_SPIRAM_SPEED_120M && CONFIG_SPIRAM_MODE_OCT
|
||||
- CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
|
||||
- CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL
|
||||
- CONFIG_ESP_WIFI_EAP_TLS1_3
|
||||
- CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
||||
|
123
ROADMAP.md
Normal file
123
ROADMAP.md
Normal file
@ -0,0 +1,123 @@
|
||||
# ESP-IDF Project Roadmap 2024
|
||||
|
||||
This document outlines the goals of ESP-IDF project and is shared for the convenience of our customers. It is important to clarify that this document is not a binding commitment to our customers. Instead, its primary purpose is to offer a clear roadmap and direction for the project's development. By openly sharing this information, we aim to enhance our customers' understanding, promote transparency and ensure alignment with the overarching objectives of the ESP-IDF project.
|
||||
|
||||
## Project Overview
|
||||
|
||||
### Project Goals
|
||||
|
||||
In both minor and major releases, we integrate new chip support to enhance our product range. By expanding the chip matrix, we broaden the scope of our offerings, catering to a wider audience with diverse needs. This proactive approach ensures that our products remain at the forefront of technological advancements, consistently meeting and exceeding customer expectations.
|
||||
|
||||
Furthermore, we prioritize bugfix releases for active branches, focusing on improving the stability and performance of products already in production. By addressing bugs promptly, we aim to enhance the overall user experience and provide tangible benefits to customers relying on our solutions. This proactive maintenance strategy reflects our commitment to delivering reliable, high-quality products to our valued customer base.
|
||||
|
||||
Below are the main objectives that ESP-IDF project/teams would like to implement in 2024.
|
||||
|
||||
- New Chip Support
|
||||
|
||||
- Add support for ESP32-P4
|
||||
- Add support for ESP32-C5
|
||||
- Add support for ESP32-C61
|
||||
|
||||
- More Minor Releases
|
||||
|
||||
- Release IDF v5.3 in 2024
|
||||
- Release IDF v5.4 at the start of 2025
|
||||
|
||||
- More Bugfix Releases
|
||||
|
||||
- Release v4.4.8 for IDF v4.4 before ESP-IDF v4.4 goes End of Life in July 2024
|
||||
- Do more bugfix releases for IDF v5.1 before release/5.1 enters maintenance period in June 2024
|
||||
- Do more bug fixes releases for release/5.2 and release/5.3, and push the two releases to be more stable and production-ready
|
||||
|
||||
- Updates of Libraries
|
||||
|
||||
- Update GDB to 14.2
|
||||
- Update LLVM to 18.1.2
|
||||
- Update MbedTLS to 3.6 (LTS)
|
||||
- Update LWIP to 2.2.0
|
||||
- Change minimal Python requirement to 3.9
|
||||
|
||||
Please note that support status of previous silicones could be found on [ESP-IDF Release and SoC Compatibility](https://github.com/espressif/esp-idf#esp-idf-release-and-soc-compatibility).
|
||||
|
||||
### Roadmap Details
|
||||
|
||||
The ESP-IDF project prioritizes consistent maintenance and updates to ensure our customers remain at the forefront of technological advancements. Our commitment to ongoing development ensures that customers continuously benefit from the latest innovations in the field.
|
||||
|
||||
Moreover, we are dedicated to empowering our customers to leverage newly implemented features and enhanced functionalities through iterative improvements. Our steadfast commitment to pushing boundaries ensures that clients not only keep pace with evolving technology but also extract optimal value from the cutting-edge capabilities of our products.
|
||||
|
||||
Below are the main roadmap details for functional areas inside ESP-IDF.
|
||||
|
||||
- New Chip Support
|
||||
|
||||
- Add full support for ESP32-P4 in ESP-IDF v5.3, refer to [ESP32-P4 Support Status](https://github.com/espressif/esp-idf/issues/12996)
|
||||
- Add preview support for ESP32-C5 in ESP-IDF v5.3 and full support for ESP32-C5 in ESP-IDF v5.4, refer to [ESP32-C5 Support Status](https://github.com/espressif/esp-idf/issues/14021)
|
||||
- Add preview support for the early samples of ESP32-C61 in ESP-IDF v5.4 and full support for mass production version in ESP-IDF v5.4.x. Refer to [ESP32-C61 Support Status](https://developer.espressif.com/pages/chip-support-status/esp32c61/#esp-idf)
|
||||
|
||||
- Bugfix releases
|
||||
|
||||
- Do bugfix release IDF v4.4.8 and stop maintaining ESP-IDF v4.4 in July 2024
|
||||
- Release bugfix IDF v5.0.6 and IDF v5.0.7 in 2024 (maintenance period)
|
||||
- Release bugfix IDF v5.1.3 and IDF v5.1.4 in H1 of 2024, and release IDF v5.1.5 in H2 of 2024
|
||||
- Push release/5.1 to maintenance period from June 2024
|
||||
- Do more bug fixes releases for release/5.2 (IDF v5.2.1, IDF v5.2.2, IDF v5.2.3) and release/5.3 (IDF v5.3.1, IDF v5.3.2), and push releases to be more stable and more production-ready
|
||||
|
||||
## ESP-IDF Planning information
|
||||
|
||||
For the full list of ESP-IDF releases, please visit https://github.com/espressif/esp-idf/releases
|
||||
|
||||
### ESP-IDF Major Releases
|
||||
|
||||
No Major Releases planned
|
||||
|
||||
### ESP-IDF Minor Releases
|
||||
|
||||
#### Quarter One
|
||||
|
||||
- v5.2-RC1, estimate release date: 2024/02/02
|
||||
- v5.2 final release, estimate release date: 2024/02/08
|
||||
|
||||
#### Quarter Two
|
||||
|
||||
- v5.3-beta1, estimate release date:: 2024/05/13
|
||||
- v5.3-beta2, estimate release date:: 2024/05/31
|
||||
- v5.3-RC1, estimate release date:: 2024/07/08
|
||||
|
||||
#### Quarter Three
|
||||
|
||||
- v5.3-RC2, estimate release date:: 2024/07/26
|
||||
- v5.3 final release, estimate release date:: 2024/08/02
|
||||
|
||||
#### Quarter Four
|
||||
|
||||
- v5.4-beta1, estimate release date:: 2024/11/08
|
||||
- v5.4-beta2, estimate release date:: 2024/11/29
|
||||
- v5.4-RC1, estimate release date:: 2025/01/09
|
||||
- v5.4-RC2, estimate release date:: 2025/01/29
|
||||
- v5.4 final release, estimate release date: 2025/02/05
|
||||
|
||||
### ESP-IDF Bugfix Releases
|
||||
|
||||
#### Quarter One
|
||||
|
||||
- v5.1.3, estimate release date: 2024/02/08
|
||||
- v5.0.6, estimate release date: 2024/02/18
|
||||
- v4.4.7, estimate release date:: 2024/03/19
|
||||
- v5.2.1, estimate release date:: 2024/03/31
|
||||
|
||||
#### Quarter Two
|
||||
|
||||
- v5.1.4, estimate release date:: 2024/05/06
|
||||
- v5.2.2, estimate release date:: 2024/06/17
|
||||
- v4.4.8, estimate release date:: 2024/07/19
|
||||
|
||||
#### Quarter Three
|
||||
|
||||
- v5.0.7, estimate release date: 2024/08/22
|
||||
- v5.3.1, estimate release date: 2024/09/16
|
||||
- v5.2.3, estimate release date: 2024/10/10
|
||||
|
||||
#### Quarter Four
|
||||
|
||||
- v5.1.5, estimate release date: 2024/11/04 (Maintenance period since June 2024)
|
||||
- v5.3.2, estimate release date: 2024/12/31
|
||||
- v5.2.4, estimate release date: 2025/02/20 (Service period ends Feb. 2025)
|
@ -26,8 +26,6 @@
|
||||
#define ESP_APPTRACE_MAX_VPRINTF_ARGS 256
|
||||
#define ESP_APPTRACE_HOST_BUF_SIZE 256
|
||||
|
||||
#define ESP_APPTRACE_PRINT_LOCK 0
|
||||
|
||||
const static char *TAG = "esp_apptrace";
|
||||
|
||||
/** tracing module internal data */
|
||||
@ -90,7 +88,7 @@ void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size)
|
||||
return;
|
||||
}
|
||||
// currently down buffer is supported for JTAG interface only
|
||||
// TODO: one more argument should be added to this function to specify HW inteface: JTAG, UART0 etc
|
||||
// TODO: one more argument should be added to this function to specify HW interface: JTAG, UART0 etc
|
||||
ch = &s_trace_channels[ESP_APPTRACE_DEST_JTAG];
|
||||
if (ch->hw != NULL) {
|
||||
if (ch->hw->down_buffer_config != NULL) {
|
||||
|
@ -9,12 +9,14 @@
|
||||
#include "esp_app_trace_util.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define ESP_APPTRACE_PRINT_LOCK 0
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// Locks /////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if ESP_APPTRACE_PRINT_LOCK
|
||||
static esp_apptrace_lock_t s_log_lock = {.irq_stat = 0, .portmux = portMUX_INITIALIZER_UNLOCKED};
|
||||
static esp_apptrace_lock_t s_log_lock = { .mux = portMUX_INITIALIZER_UNLOCKED };
|
||||
#endif
|
||||
|
||||
int esp_apptrace_log_lock(void)
|
||||
@ -31,7 +33,7 @@ int esp_apptrace_log_lock(void)
|
||||
|
||||
void esp_apptrace_log_unlock(void)
|
||||
{
|
||||
#if ESP_APPTRACE_PRINT_LOCK
|
||||
#if ESP_APPTRACE_PRINT_LOCK
|
||||
esp_apptrace_lock_give(&s_log_lock);
|
||||
#endif
|
||||
}
|
||||
@ -87,7 +89,7 @@ esp_err_t esp_apptrace_lock_give(esp_apptrace_lock_t *lock)
|
||||
uint8_t *esp_apptrace_rb_produce(esp_apptrace_rb_t *rb, uint32_t size)
|
||||
{
|
||||
uint8_t *ptr = rb->data + rb->wr;
|
||||
// check for avalable space
|
||||
// check for available space
|
||||
if (rb->rd <= rb->wr) {
|
||||
// |?R......W??|
|
||||
if (rb->wr + size >= rb->size) {
|
||||
|
6
components/app_trace/sys_view/SEGGER/sbom.yml
Normal file
6
components/app_trace/sys_view/SEGGER/sbom.yml
Normal file
@ -0,0 +1,6 @@
|
||||
name: 'SystemView'
|
||||
version: '3.42'
|
||||
cpe: cpe:2.3:a:segger:systemview:{}:*:*:*:*:*:*:*
|
||||
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||
originator: 'Organization: SEGGER Microcontroller GmbH'
|
||||
description: Real-time recording and visualization tool for embedded systems.
|
@ -157,7 +157,7 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp
|
||||
}
|
||||
}
|
||||
|
||||
new_entry = (ota_ops_entry_t *) calloc(sizeof(ota_ops_entry_t), 1);
|
||||
new_entry = (ota_ops_entry_t *) calloc(1, sizeof(ota_ops_entry_t));
|
||||
if (new_entry == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/app_update/test_apps:
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c61"]
|
||||
temporary: true
|
||||
reason: target esp32c61 is not supported yet # TODO: [ESP32C61] IDF-9245
|
@ -1,2 +0,0 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
@ -1,26 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
DEFAULT_TIMEOUT = 20
|
||||
TEST_SUBMENU_PATTERN_PYTEST = re.compile(rb'\s+\((\d+)\)\s+"([^"]+)"\r?\n')
|
||||
|
||||
|
||||
def run_multiple_stages(dut: Dut, test_case_num: int, stages: int) -> None:
|
||||
for stage in range(1, stages + 1):
|
||||
dut.write(str(test_case_num))
|
||||
dut.expect(TEST_SUBMENU_PATTERN_PYTEST, timeout=DEFAULT_TIMEOUT)
|
||||
dut.write(str(stage))
|
||||
if stage != stages:
|
||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
# TODO: [ESP32C61] IDF-9245, IDF-9247, IDF-10983
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='C61 has not supported deep sleep')
|
||||
@pytest.mark.generic
|
||||
def test_app_update(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=90)
|
@ -0,0 +1,12 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/app_update/test_apps:
|
||||
enable:
|
||||
- if: CONFIG_NAME == "defaults" and IDF_TARGET != "linux"
|
||||
- if: CONFIG_NAME == "xip_psram" and IDF_TARGET in ["esp32s2", "esp32s3", "esp32p4"]
|
||||
# S2 doesn't have ROM for flash
|
||||
- if: CONFIG_NAME == "xip_psram_with_rom_impl" and IDF_TARGET in ["esp32s3", "esp32p4"]
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c61"]
|
||||
temporary: true
|
||||
reason: target esp32c61 is not supported yet # TODO: [ESP32C61] IDF-9245
|
@ -0,0 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
@ -1,4 +1,4 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES cmock test_utils app_update bootloader_support nvs_flash driver spi_flash
|
||||
PRIV_REQUIRES cmock test_utils app_update bootloader_support nvs_flash driver spi_flash esp_psram
|
||||
WHOLE_ARCHIVE)
|
@ -6,6 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
@ -113,3 +114,11 @@ TEST_CASE("esp_ota_get_partition_description", "[ota]")
|
||||
};
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, bootloader_common_get_partition_description(¬_app_pos, &app_desc1));
|
||||
}
|
||||
|
||||
TEST_CASE("esp_ota_get_running_partition points to correct address", "[spi_flash]")
|
||||
{
|
||||
const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, "factory");
|
||||
const esp_partition_t* part = esp_ota_get_running_partition();
|
||||
ESP_LOGI("running bin", "0x%p", (void*)part->address);
|
||||
TEST_ASSERT_EQUAL_HEX32(factory->address, part->address);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
DEFAULT_TIMEOUT = 20
|
||||
TEST_SUBMENU_PATTERN_PYTEST = re.compile(rb'\s+\((\d+)\)\s+"([^"]+)"\r?\n')
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'defaults',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_app_update(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=90)
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
# TODO: [ESP32C61] IDF-9245, IDF-10983
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='C61 has not supported deep sleep')
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'xip_psram',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_app_update_xip_psram(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=90)
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'xip_psram_with_rom_impl',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_app_update_xip_psram_rom_impl(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=90)
|
@ -0,0 +1,2 @@
|
||||
# don't delete.
|
||||
# used for CI to compile a default config when 'sdkconfig.ci.xxxx' is exist
|
@ -0,0 +1,2 @@
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
@ -0,0 +1,3 @@
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
|
||||
CONFIG_SPI_FLASH_ROM_IMPL=y
|
@ -158,13 +158,23 @@ menu "Bootloader config"
|
||||
int "Number of the GPIO input for factory reset"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
range 0 39 if IDF_TARGET_ESP32
|
||||
range 0 44 if IDF_TARGET_ESP32S2
|
||||
range 0 46 if IDF_TARGET_ESP32S2
|
||||
range 0 48 if IDF_TARGET_ESP32S3
|
||||
range 0 20 if IDF_TARGET_ESP32C2
|
||||
range 0 21 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C61
|
||||
range 0 28 if IDF_TARGET_ESP32C5
|
||||
range 0 30 if IDF_TARGET_ESP32C6
|
||||
range 0 27 if IDF_TARGET_ESP32H2
|
||||
range 0 54 if IDF_TARGET_ESP32P4
|
||||
default 4
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled (note that on some SoCs.
|
||||
not all pins have an internal pull-up, consult the hardware datasheet for details.) To trigger a factory
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled. To trigger a factory
|
||||
reset, this GPIO must be held high or low (as configured) on startup.
|
||||
|
||||
Note that on some SoCs not all pins have an internal pull-up and certain pins are already
|
||||
used by ROM bootloader as bootstrapping. Refer to the technical reference manual for further
|
||||
details on the selected SoC.
|
||||
|
||||
choice BOOTLOADER_FACTORY_RESET_PIN_LEVEL
|
||||
bool "Factory reset GPIO level"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
@ -210,14 +220,25 @@ menu "Bootloader config"
|
||||
config BOOTLOADER_NUM_PIN_APP_TEST
|
||||
int "Number of the GPIO input to boot TEST partition"
|
||||
depends on BOOTLOADER_APP_TEST
|
||||
range 0 39
|
||||
range 0 39 if IDF_TARGET_ESP32
|
||||
range 0 46 if IDF_TARGET_ESP32S2
|
||||
range 0 48 if IDF_TARGET_ESP32S3
|
||||
range 0 20 if IDF_TARGET_ESP32C2
|
||||
range 0 21 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C61
|
||||
range 0 28 if IDF_TARGET_ESP32C5
|
||||
range 0 30 if IDF_TARGET_ESP32C6
|
||||
range 0 27 if IDF_TARGET_ESP32H2
|
||||
range 0 54 if IDF_TARGET_ESP32P4
|
||||
default 18
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a test app, this GPIO must be pulled low on reset.
|
||||
After the GPIO input is deactivated and the device reboots, the old application will boot.
|
||||
(factory or OTA[x]).
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
|
||||
Note that on some SoCs not all pins have an internal pull-up and certain pins are already
|
||||
used by ROM bootloader as bootstrapping. Refer to the technical reference manual for further
|
||||
details on the selected SoC.
|
||||
|
||||
choice BOOTLOADER_APP_TEST_PIN_LEVEL
|
||||
bool "App test GPIO level"
|
||||
|
@ -1,11 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <esp_err.h>
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -27,6 +28,11 @@ esp_err_t bootloader_init_spi_flash(void);
|
||||
void bootloader_flash_hardware_init(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialise mspi core clock
|
||||
*/
|
||||
void bootloader_init_mspi_clock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -48,8 +48,18 @@ void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_init_mspi_clock(void)
|
||||
{
|
||||
// Set source mspi pll clock as 80M in bootloader stage.
|
||||
// SPLL clock on C5 is 480MHz , and mspi_pll needs 80MHz
|
||||
// in this stage, set divider as 6
|
||||
mspi_ll_clock_src_sel(MSPI_CLK_SRC_SPLL);
|
||||
mspi_ll_fast_set_hs_divider(6);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)
|
||||
{
|
||||
bootloader_init_mspi_clock();
|
||||
uint32_t spi_clk_div = 0;
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_1:
|
||||
@ -204,11 +214,7 @@ static void bootloader_spi_flash_resume(void)
|
||||
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
// Set source mspi pll clock as 80M in bootloader stage.
|
||||
// SPLL clock on C5 is 480MHz , and mspi_pll needs 80MHz
|
||||
// in this stage, set divider as 6
|
||||
mspi_ll_clock_src_sel(MSPI_CLK_SRC_SPLL);
|
||||
mspi_ll_fast_set_hs_divider(6);
|
||||
bootloader_init_mspi_clock();
|
||||
|
||||
bootloader_init_flash_configure();
|
||||
bootloader_spi_flash_resume();
|
||||
|
@ -46,8 +46,19 @@ void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_init_mspi_clock(void)
|
||||
{
|
||||
// Set source mspi pll clock as 80M in bootloader stage.
|
||||
// SPLL clock on C61 is 480MHz , and mspi_pll needs 80MHz
|
||||
// in this stage, set divider as 6
|
||||
mspi_ll_clock_src_sel(MSPI_CLK_SRC_SPLL);
|
||||
mspi_ll_fast_set_hs_divider(6);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)
|
||||
{
|
||||
bootloader_init_mspi_clock();
|
||||
|
||||
uint32_t spi_clk_div = 0;
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_1:
|
||||
@ -198,13 +209,7 @@ static void bootloader_spi_flash_resume(void)
|
||||
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
|
||||
// Set source mspi pll clock as 80M in bootloader stage.
|
||||
// SPLL clock on C61 is 480MHz , and mspi_pll needs 80MHz
|
||||
// in this stage, set divider as 6
|
||||
mspi_ll_clock_src_sel(MSPI_CLK_SRC_SPLL);
|
||||
mspi_ll_fast_set_hs_divider(6);
|
||||
|
||||
bootloader_init_mspi_clock();
|
||||
bootloader_init_flash_configure();
|
||||
bootloader_spi_flash_resume();
|
||||
bootloader_flash_unlock();
|
||||
|
@ -19,10 +19,12 @@
|
||||
#include "bootloader_init.h"
|
||||
#include "hal/mmu_hal.h"
|
||||
#include "hal/mmu_ll.h"
|
||||
#include "hal/spimem_flash_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "esp_private/bootloader_flash_internal.h"
|
||||
|
||||
void IRAM_ATTR bootloader_flash_update_id()
|
||||
void IRAM_ATTR bootloader_flash_update_id(void)
|
||||
{
|
||||
esp_rom_spiflash_chip_t *chip = &rom_spiflash_legacy_data->chip;
|
||||
chip->device_id = bootloader_read_flash_id();
|
||||
@ -33,15 +35,23 @@ void bootloader_flash_update_size(uint32_t size)
|
||||
rom_spiflash_legacy_data->chip.chip_size = size;
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||
void IRAM_ATTR bootloader_flash_cs_timing_config(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(SPI_MEM_C_USER_REG, SPI_MEM_C_CS_HOLD_M | SPI_MEM_C_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_MEM_C_CTRL2_REG, SPI_MEM_C_CS_HOLD_TIME_V, 0, SPI_MEM_C_CS_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_C_CTRL2_REG, SPI_MEM_C_CS_SETUP_TIME_V, 0, SPI_MEM_C_CS_SETUP_TIME_S);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_init_mspi_clock(void)
|
||||
{
|
||||
_spimem_flash_ll_select_clk_source(0, FLASH_CLK_SRC_SPLL);
|
||||
_spimem_ctrlr_ll_set_core_clock(0, 6);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)
|
||||
{
|
||||
bootloader_init_mspi_clock();
|
||||
|
||||
uint32_t spi_clk_div = 0;
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_1:
|
||||
|
@ -30,7 +30,7 @@ int bootloader_clock_get_rated_freq_mhz(void)
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
return 160;
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C61 //TODO: [ESP32C61] IDF-9282
|
||||
#elif CONFIG_IDF_TARGET_ESP32C61
|
||||
return 160;
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
|
@ -16,12 +16,6 @@
|
||||
#include "hal/apm_hal.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C61 // TODO: IDF-9230 Remove the workaround when APM supported on C61!
|
||||
#include "soc/hp_apm_reg.h"
|
||||
#include "soc/lp_apm_reg.h"
|
||||
#endif
|
||||
|
||||
|
||||
void bootloader_init_mem(void)
|
||||
{
|
||||
|
||||
@ -38,13 +32,6 @@ void bootloader_init_mem(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C61 // TODO: IDF-9230 Remove the workaround when APM supported on C61!
|
||||
// disable apm filter
|
||||
REG_WRITE(LP_APM_FUNC_CTRL_REG, 0);
|
||||
REG_WRITE(HP_APM_FUNC_CTRL_REG, 0);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE
|
||||
// protect memory region
|
||||
esp_cpu_configure_region_protection();
|
||||
|
@ -875,7 +875,7 @@ static void set_cache_and_start_app(
|
||||
}
|
||||
//we use the MMU_LL_END_DROM_ENTRY_ID mmu entry as a map page for app to find the boot partition
|
||||
mmu_hal_map_region(0, MMU_TARGET_FLASH0, MMU_LL_END_DROM_ENTRY_VADDR, drom_addr_aligned, CONFIG_MMU_PAGE_SIZE, &actual_mapped_len);
|
||||
ESP_EARLY_LOGV(TAG, "mapped one page of the rodata, from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, actual_mapped_len);
|
||||
ESP_EARLY_LOGV(TAG, "mapped one page of the rodata, from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, MMU_LL_END_DROM_ENTRY_VADDR, actual_mapped_len);
|
||||
#endif
|
||||
|
||||
//-----------------------MAP IROM--------------------------
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
static SHA_CTX ctx;
|
||||
|
||||
//TODO: [ESP32C61] IDF-9234
|
||||
|
||||
bootloader_sha256_handle_t bootloader_sha256_start()
|
||||
{
|
||||
// Enable SHA hardware
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_private/bootloader_flash_internal.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "hal/assist_debug_ll.h"
|
||||
#include "hal/mmu_hal.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
@ -55,7 +56,7 @@ static const char *TAG = "boot.esp32p4";
|
||||
|
||||
static void wdt_reset_cpu0_info_enable(void)
|
||||
{
|
||||
//TODO: IDF-7688
|
||||
_assist_debug_ll_enable_bus_clock(true);
|
||||
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
|
||||
}
|
||||
|
||||
@ -109,12 +110,12 @@ static inline void bootloader_hardware_init(void)
|
||||
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1, 10);
|
||||
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 10);
|
||||
|
||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
// IDF-10019 TODO: This is temporarily for ESP32P4-ECO0, please remove it when eco0 is not widly used.
|
||||
int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused));
|
||||
if (likely(ESP_CHIP_REV_ABOVE(chip_version, 1))) {
|
||||
spimem_flash_ll_select_clk_source(0, FLASH_CLK_SRC_SPLL);
|
||||
spimem_ctrlr_ll_set_core_clock(0, 6);
|
||||
bootloader_init_mspi_clock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
|
@ -6,6 +6,8 @@ endif()
|
||||
|
||||
if(CONFIG_IDF_TARGET_ESP32S3)
|
||||
set(target_name "esp32c3")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C61)
|
||||
set(target_name "esp32c6")
|
||||
else()
|
||||
set(target_name "${idf_target}")
|
||||
endif()
|
||||
@ -156,6 +158,8 @@ if(CONFIG_BT_ENABLED)
|
||||
host/bluedroid/stack/avdt/include
|
||||
host/bluedroid/stack/a2dp/include
|
||||
host/bluedroid/stack/rfcomm/include
|
||||
host/bluedroid/stack/obex/include
|
||||
host/bluedroid/stack/goep/include
|
||||
host/bluedroid/stack/include
|
||||
host/bluedroid/common/include
|
||||
host/bluedroid/config/include)
|
||||
@ -183,6 +187,8 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/bta/av/bta_av_aact.c"
|
||||
"host/bluedroid/bta/av/bta_av_act.c"
|
||||
"host/bluedroid/bta/av/bta_av_api.c"
|
||||
"host/bluedroid/bta/av/bta_av_ca_act.c"
|
||||
"host/bluedroid/bta/av/bta_av_ca_sm.c"
|
||||
"host/bluedroid/bta/av/bta_av_cfg.c"
|
||||
"host/bluedroid/bta/av/bta_av_ci.c"
|
||||
"host/bluedroid/bta/av/bta_av_main.c"
|
||||
@ -378,6 +384,8 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/stack/gatt/gatt_sr.c"
|
||||
"host/bluedroid/stack/gatt/gatt_sr_hash.c"
|
||||
"host/bluedroid/stack/gatt/gatt_utils.c"
|
||||
"host/bluedroid/stack/goep/goepc_api.c"
|
||||
"host/bluedroid/stack/goep/goepc_main.c"
|
||||
"host/bluedroid/stack/hcic/hciblecmds.c"
|
||||
"host/bluedroid/stack/hcic/hcicmds.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_api.c"
|
||||
@ -389,6 +397,9 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/stack/l2cap/l2c_ucd.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_utils.c"
|
||||
"host/bluedroid/stack/l2cap/l2cap_client.c"
|
||||
"host/bluedroid/stack/obex/obex_api.c"
|
||||
"host/bluedroid/stack/obex/obex_main.c"
|
||||
"host/bluedroid/stack/obex/obex_tl_l2cap.c"
|
||||
"host/bluedroid/stack/rfcomm/port_api.c"
|
||||
"host/bluedroid/stack/rfcomm/port_rfc.c"
|
||||
"host/bluedroid/stack/rfcomm/port_utils.c"
|
||||
@ -845,7 +856,16 @@ if(CONFIG_BT_ENABLED)
|
||||
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32s3")
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
elseif(CONFIG_BT_CONTROLLER_ENABLED)
|
||||
add_prebuilt_library(libble_app "controller/lib_${target_name}/${target_name}-bt-lib/libble_app.a")
|
||||
if(CONFIG_IDF_TARGET_ESP32C6)
|
||||
add_prebuilt_library(libble_app
|
||||
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C61)
|
||||
add_prebuilt_library(libble_app
|
||||
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a")
|
||||
else()
|
||||
add_prebuilt_library(libble_app
|
||||
"controller/lib_${target_name}/${target_name}-bt-lib/libble_app.a")
|
||||
endif()
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
|
||||
endif()
|
||||
|
||||
|
@ -42,9 +42,9 @@
|
||||
#if (BTC_L2CAP_INCLUDED == TRUE)
|
||||
#include "btc_l2cap.h"
|
||||
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
|
||||
#if (BTC_SDP_INCLUDED == TRUE)
|
||||
#if (BTC_SDP_COMMON_INCLUDED == TRUE)
|
||||
#include "btc_sdp.h"
|
||||
#endif /* #if (BTC_SDP_INCLUDED == TRUE) */
|
||||
#endif /* #if (BTC_SDP_COMMON_INCLUDED == TRUE) */
|
||||
#if BTC_HF_INCLUDED
|
||||
#include "btc_hf_ag.h"
|
||||
#endif/* #if BTC_HF_INCLUDED */
|
||||
@ -138,9 +138,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
#if (BTC_L2CAP_INCLUDED == TRUE)
|
||||
[BTC_PID_L2CAP] = {btc_l2cap_call_handler, btc_l2cap_cb_handler },
|
||||
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
|
||||
#if (BTC_SDP_INCLUDED == TRUE)
|
||||
#if (BTC_SDP_COMMON_INCLUDED == TRUE)
|
||||
[BTC_PID_SDP] = {btc_sdp_call_handler, btc_sdp_cb_handler },
|
||||
#endif /* #if (BTC_SDP_INCLUDED == TRUE) */
|
||||
#endif /* #if (BTC_SDP_COMMON_INCLUDED == TRUE) */
|
||||
#if BTC_HF_INCLUDED
|
||||
[BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler},
|
||||
#endif /* #if BTC_HF_INCLUDED */
|
||||
@ -295,8 +295,8 @@ static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout)
|
||||
/**
|
||||
* transfer an message to another module in the different task.
|
||||
* @param msg message
|
||||
* @param arg paramter
|
||||
* @param arg_len length of paramter
|
||||
* @param arg parameter
|
||||
* @param arg_len length of parameter
|
||||
* @param copy_func deep copy function
|
||||
* @param free_func deep free function
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
@ -342,7 +342,7 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg
|
||||
}
|
||||
|
||||
/**
|
||||
* transfer an message to another module in tha same task.
|
||||
* transfer an message to another module in the same task.
|
||||
* @param msg message
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
|
@ -200,8 +200,8 @@ choice BT_CTRL_DFT_TX_POWER_LEVEL
|
||||
bool "+15dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P18
|
||||
bool "+18dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P21
|
||||
bool "+21dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P20
|
||||
bool "+20dBm"
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_EFF
|
||||
@ -221,7 +221,7 @@ config BT_CTRL_DFT_TX_POWER_LEVEL_EFF
|
||||
default 12 if BT_CTRL_DFT_TX_POWER_LEVEL_P12
|
||||
default 13 if BT_CTRL_DFT_TX_POWER_LEVEL_P15
|
||||
default 14 if BT_CTRL_DFT_TX_POWER_LEVEL_P18
|
||||
default 15 if BT_CTRL_DFT_TX_POWER_LEVEL_P21
|
||||
default 15 if BT_CTRL_DFT_TX_POWER_LEVEL_P20
|
||||
default 0
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
|
@ -40,12 +40,12 @@
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "soc/retention_periph_defs.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#include "soc/regdma.h"
|
||||
#include "bt_osi_mem.h"
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#include "esp_private/sleep_modem.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@ -128,8 +128,8 @@ extern void r_ble_rtc_wake_up_state_clr(void);
|
||||
extern int os_msys_init(void);
|
||||
extern void os_msys_deinit(void);
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra);
|
||||
extern void esp_ble_set_wakeup_overhead(uint32_t overhead);
|
||||
extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra);
|
||||
extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead);
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
extern void r_esp_ble_change_rtc_freq(uint32_t freq);
|
||||
extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
|
||||
@ -303,12 +303,7 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
|
||||
switch (slow_clk_src) {
|
||||
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
|
||||
uint32_t chip_version = efuse_hal_chip_revision();
|
||||
if (chip_version == 0) {
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (400 - 1));
|
||||
} else{
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1));
|
||||
}
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (480 - 1));
|
||||
break;
|
||||
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW:
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
|
||||
@ -373,57 +368,48 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
// TODO: IDF-10765
|
||||
// static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
|
||||
// {
|
||||
// uint8_t size;
|
||||
// int extra = *(int *)arg;
|
||||
// const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra);
|
||||
// esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
// if (err == ESP_OK) {
|
||||
// ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
|
||||
// }
|
||||
// return err;
|
||||
// return ESP_OK;
|
||||
// }
|
||||
static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
|
||||
{
|
||||
uint8_t size;
|
||||
int extra = *(int *)arg;
|
||||
sleep_retention_entries_config_t *ble_mac_modem_config = r_esp_ble_mac_retention_link_get(&size, extra);
|
||||
esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
|
||||
}
|
||||
return err;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
|
||||
{
|
||||
// TODO: IDF-10765
|
||||
// int retention_args = extra;
|
||||
// sleep_retention_module_init_param_t init_param = {
|
||||
// .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } },
|
||||
// .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB)
|
||||
// };
|
||||
// esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
|
||||
// if (err == ESP_OK) {
|
||||
// err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
// }
|
||||
// return err;
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
|
||||
return ESP_OK;
|
||||
int retention_args = extra;
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } },
|
||||
.depends = BIT(SLEEP_RETENTION_MODULE_BT_BB)
|
||||
};
|
||||
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
|
||||
if (err == ESP_OK) {
|
||||
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void sleep_modem_ble_mac_modem_state_deinit(void)
|
||||
{
|
||||
// TODO: IDF-10765
|
||||
// esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
// if (err == ESP_OK) {
|
||||
// err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
// assert(err == ESP_OK);
|
||||
// }
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
|
||||
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
if (err == ESP_OK) {
|
||||
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
assert(err == ESP_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void sleep_modem_light_sleep_overhead_set(uint32_t overhead)
|
||||
{
|
||||
// TODO: IDF-10765
|
||||
// esp_ble_set_wakeup_overhead(overhead);
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
|
||||
r_esp_ble_set_wakeup_overhead(overhead);
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
|
||||
|
||||
esp_err_t controller_sleep_init(void)
|
||||
{
|
||||
esp_err_t rc = 0;
|
||||
@ -446,7 +432,7 @@ esp_err_t controller_sleep_init(void)
|
||||
}
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
/* Create a new regdma link for BLE related register restoration */
|
||||
rc = sleep_modem_ble_mac_modem_state_init(1);
|
||||
rc = sleep_modem_ble_mac_modem_state_init(0);
|
||||
assert(rc == 0);
|
||||
esp_sleep_enable_bt_wakeup();
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer");
|
||||
|
@ -0,0 +1 @@
|
||||
source "$IDF_PATH/components/bt/controller/esp32c6/Kconfig.in"
|
@ -1 +1 @@
|
||||
Subproject commit e652624750341aca124e9f850e261b0c1ac63529
|
||||
Subproject commit e5c7ef0bf701d02c2203e26081fdd348d45935e5
|
@ -1 +1 @@
|
||||
Subproject commit d874f55e1132416fe18293ae1aa9ac73c40b3261
|
||||
Subproject commit 5c913171361dac0821e15e83cc0cf604149e1b84
|
@ -1 +1 @@
|
||||
Subproject commit 53056440bc6e76f5bf00fd920769a4979dcc7d66
|
||||
Subproject commit b4f67e85c54cc8f55b5130e47805dc8c906a736c
|
@ -1 +1 @@
|
||||
Subproject commit f95513f22be7b21429b01ba05dbfbc98097b5e67
|
||||
Subproject commit 3f15aa1d602aedf510dd9c686b3f7e5ea8a44002
|
@ -1 +1 @@
|
||||
Subproject commit 58a293a2b4c305157723908ea29c2776f5803bbc
|
||||
Subproject commit 50f567fff506f63b4d06ebea80d0405fe9e39568
|
@ -1 +1 @@
|
||||
Subproject commit 8312e0e0d5390d04fd282e8005528d2b5c351c08
|
||||
Subproject commit cba99c5a2e7f5d4bccb04e8f3f968dc888bb5667
|
@ -84,9 +84,30 @@ config BT_A2DP_ENABLE
|
||||
bool "A2DP"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
default n
|
||||
select BT_AVRCP_ENABLED
|
||||
help
|
||||
Advanced Audio Distribution Profile
|
||||
|
||||
config BT_AVRCP_ENABLED
|
||||
bool
|
||||
depends on BT_A2DP_ENABLE
|
||||
default y
|
||||
help
|
||||
Audio/Video Remote Control Profile, AVRCP and A2DP are coupled in Bluedroid,
|
||||
AVRCP still controlled by A2DP option, this is a dummy option currently
|
||||
|
||||
menu "AVRCP Features"
|
||||
depends on BT_AVRCP_ENABLED
|
||||
|
||||
config BT_AVRCP_CT_COVER_ART_ENABLED
|
||||
bool "AVRCP CT Cover Art"
|
||||
default y
|
||||
select BT_GOEPC_ENABLED
|
||||
help
|
||||
This enable Cover Art feature of AVRCP CT role
|
||||
|
||||
endmenu
|
||||
|
||||
config BT_SPP_ENABLED
|
||||
bool "SPP"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
@ -102,6 +123,14 @@ config BT_L2CAP_ENABLED
|
||||
This enables the Logical Link Control and Adaptation Layer Protocol.
|
||||
Only supported classic bluetooth.
|
||||
|
||||
config BT_SDP_COMMON_ENABLED
|
||||
bool "BT SDP COMMON"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
default y if BT_L2CAP_ENABLED
|
||||
default n
|
||||
help
|
||||
This enables common SDP operation, such as SDP record creation and deletion.
|
||||
|
||||
menuconfig BT_HFP_ENABLE
|
||||
bool "Hands Free/Handset Profile"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
@ -136,19 +165,18 @@ endchoice
|
||||
|
||||
config BT_HFP_WBS_ENABLE
|
||||
bool "Wide Band Speech"
|
||||
depends on BT_HFP_AUDIO_DATA_PATH_HCI
|
||||
depends on BT_HFP_ENABLE && BT_HFP_AUDIO_DATA_PATH_HCI
|
||||
default y
|
||||
help
|
||||
This enables Wide Band Speech. Should disable it when SCO data path is PCM.
|
||||
Otherwise there will be no data transmitted via GPIOs.
|
||||
|
||||
|
||||
menuconfig BT_HID_ENABLED
|
||||
bool "Classic BT HID"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
default n
|
||||
help
|
||||
This enables the BT HID Host
|
||||
This enables the BT HID functionalities
|
||||
|
||||
config BT_HID_HOST_ENABLED
|
||||
bool "Classic BT HID Host"
|
||||
@ -163,6 +191,13 @@ config BT_HID_DEVICE_ENABLED
|
||||
help
|
||||
This enables the BT HID Device
|
||||
|
||||
config BT_GOEPC_ENABLED
|
||||
bool
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
default n
|
||||
help
|
||||
This enables the BT GOEP Profile Client role
|
||||
|
||||
config BT_BLE_ENABLED
|
||||
bool "Bluetooth Low Energy"
|
||||
depends on BT_BLUEDROID_ENABLED
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -232,6 +232,149 @@ esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
|
||||
esp_err_t esp_avrc_ct_cover_art_connect(uint16_t mtu)
|
||||
{
|
||||
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
|
||||
(!btc_avrc_ct_connected_p())) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!btc_avrc_ct_check_cover_art_support()) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (mtu > ESP_AVRC_CA_MTU_MAX || mtu < ESP_AVRC_CA_MTU_MIN) {
|
||||
mtu = ESP_AVRC_CA_MTU_MAX;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CT_API_COVER_ART_CONNECT_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
arg.ca_conn.mtu = mtu;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_cover_art_disconnect(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!btc_avrc_ct_check_cover_art_support()) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CT_API_COVER_ART_DISCONNECT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_cover_art_get_image_properties(uint8_t *image_handle)
|
||||
{
|
||||
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
|
||||
(!btc_avrc_ct_connected_p())) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!btc_avrc_ct_check_cover_art_support()) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (image_handle == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_PROPERTIES_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
memcpy(arg.ca_get_img_prop.image_handle, image_handle, ESP_AVRC_CA_IMAGE_HANDLE_LEN);
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_cover_art_get_image(uint8_t *image_handle, uint8_t *image_descriptor, uint16_t image_descriptor_len)
|
||||
{
|
||||
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
|
||||
(!btc_avrc_ct_connected_p())) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!btc_avrc_ct_check_cover_art_support()) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (image_handle == NULL || image_descriptor == NULL || image_descriptor_len == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
|
||||
memcpy(arg.ca_get_img.image_handle, image_handle, ESP_AVRC_CA_IMAGE_HANDLE_LEN);
|
||||
arg.ca_get_img.image_descriptor_len = image_descriptor_len;
|
||||
arg.ca_get_img.image_descriptor = image_descriptor;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), btc_avrc_arg_deep_copy, btc_avrc_arg_deep_free);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_cover_art_get_linked_thumbnail(uint8_t *image_handle)
|
||||
{
|
||||
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
|
||||
(!btc_avrc_ct_connected_p())) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!btc_avrc_ct_check_cover_art_support()) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (image_handle == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CT_API_COVER_ART_GET_LINKED_THUMBNAIL_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
memcpy(arg.ca_get_lk_thn.image_handle, image_handle, ESP_AVRC_CA_IMAGE_HANDLE_LEN);
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* #if BTC_AV_CA_INCLUDED */
|
||||
|
||||
/*********************************************************************************************/
|
||||
/** following is the API of AVRCP target role **/
|
||||
/*********************************************************************************************/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,12 +8,43 @@
|
||||
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "stack/sdpdefs.h"
|
||||
|
||||
#include "btc_sdp.h"
|
||||
#include "esp_sdp_api.h"
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE)
|
||||
#if (defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE)
|
||||
|
||||
static bool esp_sdp_record_integrity_check(esp_bluetooth_sdp_record_t *record)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if (record != NULL) {
|
||||
switch (record->hdr.type) {
|
||||
case ESP_SDP_TYPE_DIP_SERVER:
|
||||
if (record->dip.vendor_id_source != ESP_SDP_VENDOR_ID_SRC_BT &&
|
||||
record->dip.vendor_id_source != ESP_SDP_VENDOR_ID_SRC_USB) {
|
||||
LOG_ERROR("Invalid vendor_id_source!\n");
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (record->hdr.service_name_length > ESP_SDP_SERVER_NAME_MAX ||
|
||||
strlen(record->hdr.service_name) + 1 != record->hdr.service_name_length) {
|
||||
LOG_ERROR("Invalid server name!\n");
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("record is NULL!\n");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_sdp_register_callback(esp_sdp_cb_t callback)
|
||||
{
|
||||
@ -85,9 +116,7 @@ esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (record == NULL || record->hdr.service_name_length > ESP_SDP_SERVER_NAME_MAX
|
||||
|| strlen(record->hdr.service_name)+1 != record->hdr.service_name_length) {
|
||||
LOG_ERROR("Invalid server name!\n");
|
||||
if (!esp_sdp_record_integrity_check(record)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@ -100,7 +129,7 @@ esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record)
|
||||
msg.act = BTC_SDP_ACT_CREATE_RECORD;
|
||||
|
||||
memset(&arg, 0, sizeof(btc_sdp_args_t));
|
||||
arg.creat_record.record = (bluetooth_sdp_record *)record;
|
||||
arg.create_record.record = (bluetooth_sdp_record *)record;
|
||||
|
||||
/* Switch to BTC context */
|
||||
stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t),
|
||||
@ -127,4 +156,4 @@ esp_err_t esp_sdp_remove_record(int record_handle)
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE
|
||||
#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -18,6 +18,10 @@ extern "C" {
|
||||
|
||||
#define ESP_AVRC_TRANS_LABEL_MAX 15 /*!< max transaction label */
|
||||
|
||||
#define ESP_AVRC_CA_IMAGE_HANDLE_LEN 7 /* The image handle length is fixed to 7, specified by Basic Image Profile */
|
||||
#define ESP_AVRC_CA_MTU_MIN 255 /* Minimal MTU can be used in Cover Art OBEX connection */
|
||||
#define ESP_AVRC_CA_MTU_MAX 1691 /* Maximum MTU can be used in Cover Art OBEX connection */
|
||||
|
||||
/// AVRC feature bit mask
|
||||
typedef enum {
|
||||
ESP_AVRC_FEAT_RCTG = 0x0001, /*!< remote control target */
|
||||
@ -30,14 +34,18 @@ typedef enum {
|
||||
|
||||
/// AVRC supported features flag retrieved in SDP record
|
||||
typedef enum {
|
||||
/* CT and TG common features flag */
|
||||
ESP_AVRC_FEAT_FLAG_CAT1 = 0x0001, /*!< category 1 */
|
||||
ESP_AVRC_FEAT_FLAG_CAT2 = 0x0002, /*!< category 2 */
|
||||
ESP_AVRC_FEAT_FLAG_CAT3 = 0x0004, /*!< category 3 */
|
||||
ESP_AVRC_FEAT_FLAG_CAT4 = 0x0008, /*!< category 4 */
|
||||
ESP_AVRC_FEAT_FLAG_BROWSING = 0x0040, /*!< browsing */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE_PROP = 0x0080, /*!< Cover Art GetImageProperties */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE = 0x0100, /*!< Cover Art GetImage */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_LINKED_THUMBNAIL = 0x0200, /*!< Cover Art GetLinkedThumbnail */
|
||||
/* CT only features flag */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE_PROP = 0x0080, /*!< CT support Cover Art GetImageProperties */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE = 0x0100, /*!< CT support Cover Art GetImage */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_LINKED_THUMBNAIL = 0x0200, /*!< CT support Cover Art GetLinkedThumbnail */
|
||||
/* TG only features flag */
|
||||
ESP_AVRC_FEAT_FLAG_TG_COVER_ART = 0x0100, /*!< TG support Cover Art */
|
||||
} esp_avrc_feature_flag_t;
|
||||
|
||||
/// AVRC passthrough command code
|
||||
@ -135,6 +143,8 @@ typedef enum {
|
||||
ESP_AVRC_CT_REMOTE_FEATURES_EVT = 5, /*!< feature of remote device indication event */
|
||||
ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT = 6, /*!< supported notification events capability of peer device */
|
||||
ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT = 7, /*!< set absolute volume response event */
|
||||
ESP_AVRC_CT_COVER_ART_STATE_EVT = 8, /*!< cover art client connection state changed event */
|
||||
ESP_AVRC_CT_COVER_ART_DATA_EVT = 9, /*!< cover art client data event */
|
||||
} esp_avrc_ct_cb_event_t;
|
||||
|
||||
/// AVRC Target callback events
|
||||
@ -155,7 +165,8 @@ typedef enum {
|
||||
ESP_AVRC_MD_ATTR_TRACK_NUM = 0x8, /*!< track position on the album */
|
||||
ESP_AVRC_MD_ATTR_NUM_TRACKS = 0x10, /*!< number of tracks on the album */
|
||||
ESP_AVRC_MD_ATTR_GENRE = 0x20, /*!< track genre */
|
||||
ESP_AVRC_MD_ATTR_PLAYING_TIME = 0x40 /*!< total album playing time in miliseconds */
|
||||
ESP_AVRC_MD_ATTR_PLAYING_TIME = 0x40, /*!< total album playing time in milliseconds */
|
||||
ESP_AVRC_MD_ATTR_COVER_ART = 0x80 /*!< cover art image handle */
|
||||
} esp_avrc_md_attr_mask_t;
|
||||
|
||||
/// AVRC event notification ids
|
||||
@ -261,6 +272,12 @@ typedef enum {
|
||||
ESP_AVRC_PLAYBACK_ERROR = 0xFF, /*!< error */
|
||||
} esp_avrc_playback_stat_t;
|
||||
|
||||
/// AVRC Cover Art connection error code
|
||||
typedef enum {
|
||||
ESP_AVRC_COVER_ART_DISCONNECTED, /*!< Cover Art connection disconnected or connection failed */
|
||||
ESP_AVRC_COVER_ART_CONNECTED, /*!< Cover Art connection established */
|
||||
} esp_avrc_cover_art_conn_state_t;
|
||||
|
||||
/// AVRCP notification parameters
|
||||
typedef union
|
||||
{
|
||||
@ -337,6 +354,24 @@ typedef union {
|
||||
struct avrc_ct_set_volume_rsp_param {
|
||||
uint8_t volume; /*!< the volume which has actually been set, range is 0 to 0x7f, means 0% to 100% */
|
||||
} set_volume_rsp; /*!< set absolute volume response event */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_COVER_ART_STATE_EVT
|
||||
*/
|
||||
struct avrc_ct_cover_art_state_param {
|
||||
esp_avrc_cover_art_conn_state_t state; /*!< indicate the Cover Art connection status */
|
||||
esp_bt_status_t reason; /*!< the disconnect reason of Cover Art connection */
|
||||
} cover_art_state; /*!< AVRC Cover Art connection state change event */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_COVER_ART_DATA_EVT
|
||||
*/
|
||||
struct avrc_ct_cover_art_data_param {
|
||||
esp_bt_status_t status; /*!< indicate whether the get operation is success, p_data is valid only when status is ESP_BT_STATUS_SUCCESS */
|
||||
bool final; /*!< indicate whether this data event is the final one, true if we have received the entire object */
|
||||
uint16_t data_len; /*!< the data length of this data event, in bytes */
|
||||
uint8_t *p_data; /*!< pointer to data, should copy to other buff before event callback return */
|
||||
} cover_art_data; /*!< AVRC Cover Art data event */
|
||||
} esp_avrc_ct_cb_param_t;
|
||||
|
||||
/// AVRC target callback parameters
|
||||
@ -656,11 +691,11 @@ bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_b
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get the requested event notification capabilies on local AVRC target. The capability is returned
|
||||
* @brief Get the requested event notification capabilities on local AVRC target. The capability is returned
|
||||
* in a bit mask representation in evt_set. This function should be called after esp_avrc_tg_init().
|
||||
*
|
||||
* For capability type "ESP_AVRC_RN_CAP_ALLOWED_EVT, the retrieved event set is constant and
|
||||
* it covers all of the notifcation events that can possibly be supported with current
|
||||
* it covers all of the notification events that can possibly be supported with current
|
||||
* implementation.
|
||||
*
|
||||
* For capability type ESP_AVRC_RN_CAP_SUPPORTED_EVT, the event set covers the notification
|
||||
@ -729,6 +764,92 @@ bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_e
|
||||
esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp,
|
||||
esp_avrc_rn_param_t *param);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Start the process to establish OBEX connection used in Cover Art Client. Once the operation done,
|
||||
* ESP_AVRC_CT_COVER_ART_STATE_EVT will come, operation result can be found in event param. This API
|
||||
* can be used only when AVRC Cover Art feature is enabled.
|
||||
*
|
||||
* @param[in] mtu: MTU used in lower level connection, should not smaller than ESP_AVRC_CA_MTU_MIN or larger than
|
||||
* ESP_AVRC_CA_MTU_MAX, if value is not valid, will be reset to ESP_AVRC_CA_MTU_MAX. This can limit
|
||||
* the max data length in cover_art_data event.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC CT is not initialized
|
||||
* - ESP_ERR_NOT_SUPPORTED: if peer device does not support Cover Art function
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_cover_art_connect(uint16_t mtu);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Start the process to release the OBEX connection used in Cover Art Client.Once the operation done,
|
||||
* ESP_AVRC_CT_COVER_ART_STATE_EVT will come, operation result can be found in event param. This API
|
||||
* can be used only when AVRC Cover Art feature is enabled.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC CT is not initialized
|
||||
* - ESP_ERR_NOT_SUPPORTED: if peer device does not support Cover Art function
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_cover_art_disconnect(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Start the process to get image properties from Cover Art server. This API can be used only when AVRC
|
||||
* Cover Art feature is enabled.
|
||||
*
|
||||
* @param[in] image_handle: pointer to image handle with a length of ESP_AVRC_CA_IMAGE_HANDLE_LEN bytes, can be freed
|
||||
* after this function return
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC CT is not initialized
|
||||
* - ESP_ERR_NOT_SUPPORTED: if peer device does not support Cover Art function
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_cover_art_get_image_properties(uint8_t *image_handle);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Start the process to get image from Cover Art server. This API can be used only when AVRC Cover Art
|
||||
* feature is enabled.
|
||||
*
|
||||
* @param[in] image_handle: pointer to image handle with a length of ESP_AVRC_CA_IMAGE_HANDLE_LEN bytes, can be freed
|
||||
* after this function return
|
||||
*
|
||||
* @param[in] image_descriptor: pointer to image descriptor, will be cache internally by bluetooth stack, can be freed
|
||||
* once this api return
|
||||
*
|
||||
* @param[in] image_descriptor_len: the length of image descriptor
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC CT is not initialized
|
||||
* - ESP_ERR_NOT_SUPPORTED: if peer device does not support Cover Art function
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_cover_art_get_image(uint8_t *image_handle, uint8_t *image_descriptor, uint16_t image_descriptor_len);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Start the process to get linked thumbnail from Cover Art server. This API can be used only when AVRC
|
||||
* Cover Art feature is enabled.
|
||||
*
|
||||
* @param[in] image_handle: pointer to image handle with a length of ESP_AVRC_CA_IMAGE_HANDLE_LEN bytes, can be freed
|
||||
* after this function return
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC CT is not initialized
|
||||
* - ESP_ERR_NOT_SUPPORTED: if peer device does not support Cover Art function
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_cover_art_get_linked_thumbnail(uint8_t *image_handle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -242,6 +242,7 @@ typedef union {
|
||||
*/
|
||||
struct gatts_rsp_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
uint16_t handle; /*!< Attribute handle which send response */
|
||||
} rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -17,6 +17,17 @@ extern "C" {
|
||||
#define ESP_SDP_SERVER_NAME_MAX 32 /*!< Service name max length */
|
||||
#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 /*!< OPP supported format list maximum length */
|
||||
|
||||
#define ESP_SDP_UUID_MAP_MAS 0x1132 /*!< Message Access Service UUID */
|
||||
#define ESP_SDP_UUID_MAP_MNS 0x1133 /*!< Message Notification Service UUID */
|
||||
#define ESP_SDP_UUID_PBAP_PSE 0x112F /*!< Phone Book Server Equipment UUID */
|
||||
#define ESP_SDP_UUID_PBAP_PCE 0x112E /*!< Phone Book Client Equipment UUID */
|
||||
#define ESP_SDP_UUID_OPP 0x1105 /*!< Object Push Profile UUID */
|
||||
#define ESP_SDP_UUID_SAP 0x112D /*!< SIM Access Profile UUID */
|
||||
#define ESP_SDP_UUID_DIP 0x1200 /*!< Device Identification Profile UUID */
|
||||
|
||||
#define ESP_SDP_BUILD_BT_UUID16(uuid16_val) \
|
||||
(esp_bt_uuid_t) { .len = ESP_UUID_LEN_16, .uuid = {.uuid16 = (uint16_t)(uuid16_val),}, }
|
||||
|
||||
typedef enum {
|
||||
ESP_SDP_SUCCESS = 0, /*!< Successful operation. */
|
||||
ESP_SDP_FAILURE, /*!< Generic failure. */
|
||||
@ -31,7 +42,7 @@ typedef enum {
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_SDP_INIT_EVT = 0, /*!< When SDP is initialized, the event comes */
|
||||
ESP_SDP_DEINIT_EVT = 1, /*!< When SDP is deinitialized, the event comes */
|
||||
ESP_SDP_DEINIT_EVT = 1, /*!< When SDP is de-initialized, the event comes */
|
||||
ESP_SDP_SEARCH_COMP_EVT = 2, /*!< When SDP search complete, the event comes */
|
||||
ESP_SDP_CREATE_RECORD_COMP_EVT = 3, /*!< When create SDP records complete, the event comes */
|
||||
ESP_SDP_REMOVE_RECORD_COMP_EVT = 4, /*!< When remove a SDP record complete, the event comes */
|
||||
@ -47,29 +58,34 @@ typedef enum {
|
||||
ESP_SDP_TYPE_PBAP_PSE, /*!< Phone Book Profile - Server */
|
||||
ESP_SDP_TYPE_PBAP_PCE, /*!< Phone Book Profile - Client */
|
||||
ESP_SDP_TYPE_OPP_SERVER, /*!< Object Push Profile */
|
||||
ESP_SDP_TYPE_SAP_SERVER /*!< SIM Access Profile */
|
||||
ESP_SDP_TYPE_SAP_SERVER, /*!< SIM Access Profile */
|
||||
ESP_SDP_TYPE_DIP_SERVER, /*!< Device Identification Profile */
|
||||
} esp_bluetooth_sdp_types_t;
|
||||
|
||||
/**
|
||||
* @brief Some signals need additional pointers, hence we introduce a
|
||||
* generic way to handle these pointers.
|
||||
* @brief SDP header structure
|
||||
*/
|
||||
typedef struct bluetooth_sdp_hdr_overlay {
|
||||
esp_bluetooth_sdp_types_t type; /*!< SDP type */
|
||||
esp_bt_uuid_t uuid; /*!< UUID type, include uuid and uuid length */
|
||||
esp_bt_uuid_t uuid; /*!< UUID type, include uuid and uuid length, only needed to be set for RAW record creation */
|
||||
uint32_t service_name_length; /*!< Service name length */
|
||||
char *service_name; /*!< service name */
|
||||
int32_t rfcomm_channel_number; /*!< rfcomm channel number, if not used set to -1*/
|
||||
int32_t l2cap_psm; /*!< l2cap psm, if not used set to -1 */
|
||||
int32_t profile_version; /*!< profile version */
|
||||
|
||||
// User pointers, only used for some signals - see esp_bluetooth_sdp_ops_record_t
|
||||
int user1_ptr_len; /*!< see esp_bluetooth_sdp_ops_record_t */
|
||||
uint8_t *user1_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */
|
||||
int user2_ptr_len; /*!< see esp_bluetooth_sdp_ops_record_t */
|
||||
uint8_t *user2_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */
|
||||
char *service_name; /*!< Service name */
|
||||
int32_t rfcomm_channel_number; /*!< RFCOMM channel number, if not used set to -1*/
|
||||
int32_t l2cap_psm; /*!< L2CAP psm, if not used set to -1 */
|
||||
int32_t profile_version; /*!< Profile version */
|
||||
int user1_ptr_len; /*!< User data1 length, only used for searching RAW record */
|
||||
uint8_t *user1_ptr; /*!< User data1 pointer to the raw SDP response data, only used for searching RAW record */
|
||||
int user2_ptr_len __attribute__((deprecated)); /*!< User data2 length, only used for searching RAW record */
|
||||
uint8_t *user2_ptr __attribute__((deprecated)); /*!< User data2 pointer, only used for searching RAW record */
|
||||
} esp_bluetooth_sdp_hdr_overlay_t;
|
||||
|
||||
/**
|
||||
* @brief Raw SDP record
|
||||
*/
|
||||
typedef struct bluetooth_sdp_raw_record {
|
||||
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
|
||||
} esp_bluetooth_sdp_raw_record_t;
|
||||
|
||||
/**
|
||||
* @brief Message Access Profile - Server parameters
|
||||
*/
|
||||
@ -93,7 +109,7 @@ typedef struct bluetooth_sdp_mns_record {
|
||||
*/
|
||||
typedef struct bluetooth_sdp_pse_record {
|
||||
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
|
||||
uint32_t supported_features; /*!< Pbap Supported Features */
|
||||
uint32_t supported_features; /*!< PBAP Supported Features */
|
||||
uint32_t supported_repositories; /*!< Supported Repositories */
|
||||
} esp_bluetooth_sdp_pse_record_t;
|
||||
|
||||
@ -120,17 +136,43 @@ typedef struct bluetooth_sdp_sap_record {
|
||||
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
|
||||
} esp_bluetooth_sdp_sap_record_t;
|
||||
|
||||
/**
|
||||
* @brief Vendor ID source
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_SDP_VENDOR_ID_SRC_BT = 1, /*!< Bluetooth assigned vendor id source */
|
||||
ESP_SDP_VENDOR_ID_SRC_USB = 2, /*!< USB assigned vendor id source */
|
||||
} esp_sdp_vendor_id_source_t;
|
||||
|
||||
/**
|
||||
* @brief Device Identification Profile parameters
|
||||
*
|
||||
* @note Only one primary Device Identification service record can be added in the SDP database. If primary
|
||||
* Device Identification service is created multiple times, only the last one will take effect.
|
||||
*/
|
||||
typedef struct bluetooth_sdp_dip_record {
|
||||
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
|
||||
uint16_t vendor; /*!< Vendor ID */
|
||||
uint16_t vendor_id_source; /*!< Vendor ID source, 0x0001 for Bluetooth, 0x0002 for USB, other values reserved, see `esp_sdp_vendor_id_source_t` */
|
||||
uint16_t product; /*!< Product ID */
|
||||
uint16_t version; /*!< Release version in format 0xJJMN(JJ – major number, M – minor number, N – sub-minor number) */
|
||||
bool primary_record; /*!< Indicate if the record is primary, shall set to true if there is a only single device
|
||||
record, others shall be set to false */
|
||||
} esp_bluetooth_sdp_dip_record_t;
|
||||
|
||||
/**
|
||||
* @brief SDP record parameters union
|
||||
*/
|
||||
typedef union {
|
||||
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
|
||||
esp_bluetooth_sdp_raw_record_t raw; /*!< Raw SDP search data for unknown UUIDs */
|
||||
esp_bluetooth_sdp_mas_record_t mas; /*!< Message Access Profile - Server */
|
||||
esp_bluetooth_sdp_mns_record_t mns; /*!< Message Access Profile - Client (Notification Server) */
|
||||
esp_bluetooth_sdp_pse_record_t pse; /*!< Phone Book Profile - Server */
|
||||
esp_bluetooth_sdp_pce_record_t pce; /*!< Phone Book Profile - Client */
|
||||
esp_bluetooth_sdp_ops_record_t ops; /*!< Object Push Profile */
|
||||
esp_bluetooth_sdp_sap_record_t sap; /*!< SIM Access Profile */
|
||||
esp_bluetooth_sdp_dip_record_t dip; /*!< Device Identification Profile */
|
||||
} esp_bluetooth_sdp_record_t;
|
||||
|
||||
/**
|
||||
@ -141,32 +183,32 @@ typedef union {
|
||||
* @brief ESP_SDP_INIT_EVT
|
||||
*/
|
||||
struct sdp_init_evt_param {
|
||||
esp_sdp_status_t status; /*!< status */
|
||||
esp_sdp_status_t status; /*!< Status */
|
||||
} init; /*!< SDP callback param of ESP_SDP_INIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_SDP_DEINIT_EVT
|
||||
*/
|
||||
struct sdp_deinit_evt_param {
|
||||
esp_sdp_status_t status; /*!< status */
|
||||
esp_sdp_status_t status; /*!< Status */
|
||||
} deinit; /*!< SDP callback param of ESP_SDP_DEINIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_SDP_SEARCH_COMP_EVT
|
||||
*/
|
||||
struct sdp_search_evt_param {
|
||||
esp_sdp_status_t status; /*!< status */
|
||||
esp_bd_addr_t remote_addr; /*!< remote device address */
|
||||
esp_bt_uuid_t sdp_uuid; /*!< service uuid */
|
||||
esp_sdp_status_t status; /*!< Status */
|
||||
esp_bd_addr_t remote_addr; /*!< Remote device address */
|
||||
esp_bt_uuid_t sdp_uuid; /*!< Service uuid */
|
||||
int record_count; /*!< Number of SDP records */
|
||||
esp_bluetooth_sdp_record_t *records;/*!< SDP records */
|
||||
esp_bluetooth_sdp_record_t *records; /*!< SDP records */
|
||||
} search; /*!< SDP callback param of ESP_SDP_SEARCH_COMP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_SDP_CREATE_RECORD_COMP_EVT
|
||||
*/
|
||||
struct sdp_crate_record_evt_param {
|
||||
esp_sdp_status_t status; /*!< status */
|
||||
struct sdp_create_record_evt_param {
|
||||
esp_sdp_status_t status; /*!< Status */
|
||||
int record_handle; /*!< SDP record handle */
|
||||
} create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */
|
||||
|
||||
@ -174,11 +216,10 @@ typedef union {
|
||||
* @brief ESP_SDP_REMOVE_RECORD_COMP_EVT
|
||||
*/
|
||||
struct sdp_remove_record_evt_param {
|
||||
esp_sdp_status_t status; /*!< status */
|
||||
esp_sdp_status_t status; /*!< Status */
|
||||
} remove_record; /*!< SDP callback param of ESP_SDP_REMOVE_RECORD_COMP_EVT */
|
||||
|
||||
} esp_sdp_cb_param_t; /*!< SDP callback parameter union type */
|
||||
|
||||
} esp_sdp_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief SDP callback function type.
|
||||
|
@ -37,6 +37,10 @@
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
#include "bta/bta_ar_api.h"
|
||||
#endif
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
#include "stack/goep_common.h"
|
||||
#include "stack/goepc_api.h"
|
||||
#endif
|
||||
|
||||
#define LOG_TAG "bt_bta_av"
|
||||
// #include "osi/include/log.h"
|
||||
@ -98,6 +102,10 @@ void bta_av_del_rc(tBTA_AV_RCB *p_rcb)
|
||||
|
||||
p_scb = NULL;
|
||||
if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
/* reset cover art state */
|
||||
bta_av_ca_reset(p_rcb);
|
||||
#endif
|
||||
if (p_rcb->shdl) {
|
||||
/* Validate array index*/
|
||||
if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) {
|
||||
@ -127,9 +135,6 @@ void bta_av_del_rc(tBTA_AV_RCB *p_rcb)
|
||||
}
|
||||
/* else ACP && connected. do not clear the handle yet */
|
||||
AVRC_Close(rc_handle);
|
||||
if (rc_handle == bta_av_cb.rc_acp_handle) {
|
||||
bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE;
|
||||
}
|
||||
APPL_TRACE_EVENT("end del_rc handle: %d status=0x%x, rc_acp_handle:%d, lidx:%d",
|
||||
p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, p_rcb->lidx);
|
||||
}
|
||||
@ -302,7 +307,7 @@ UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx)
|
||||
bda = p_scb->peer_addr;
|
||||
status = BTA_AV_RC_ROLE_INT;
|
||||
} else {
|
||||
if ((p_rcb = bta_av_get_rcb_by_shdl(shdl)) != NULL ) {
|
||||
if (shdl != 0 && ((p_rcb = bta_av_get_rcb_by_shdl(shdl)) != NULL)) {
|
||||
APPL_TRACE_ERROR("bta_av_rc_create ACP handle exist for shdl:%d", shdl);
|
||||
return p_rcb->handle;
|
||||
}
|
||||
@ -1143,7 +1148,7 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
|
||||
p_data->conn_chg.peer_addr[5]);
|
||||
if (p_lcb_rc->conn_msk && bdcmp(p_lcb_rc->addr, p_data->conn_chg.peer_addr) == 0) {
|
||||
/* AVRCP is already connected.
|
||||
* need to update the association betwen SCB and RCB */
|
||||
* need to update the association between SCB and RCB */
|
||||
p_lcb_rc->conn_msk = 0; /* indicate RC ONLY is not connected */
|
||||
p_lcb_rc->lidx = 0;
|
||||
p_scb->rc_handle = p_cb->rc_acp_handle;
|
||||
@ -1484,6 +1489,51 @@ static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle)
|
||||
}
|
||||
}
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_extra_tg_cover_art_l2cap_psm
|
||||
**
|
||||
** Description Extra the AVRC Cover Art L2CAP PSM of peer device from the
|
||||
** SDP record
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static UINT16 bta_av_extra_tg_cover_art_l2cap_psm(void)
|
||||
{
|
||||
tBTA_AV_CB *p_cb = &bta_av_cb;
|
||||
tSDP_DISC_REC *p_rec = NULL;
|
||||
tSDP_DISC_ATTR *p_add_prot_desc, *p_prot_desc;
|
||||
tSDP_PROTOCOL_ELEM elem_l2cap, elem_obex;
|
||||
UINT16 l2cap_psm = 0;
|
||||
|
||||
while (TRUE) {
|
||||
/* get next record; if none found, we're done */
|
||||
if ((p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, p_rec)) == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
p_add_prot_desc = SDP_FindAttributeInRec(p_rec, ATTR_ID_ADDITION_PROTO_DESC_LISTS);
|
||||
if ((p_add_prot_desc != NULL) && (SDP_DISC_ATTR_TYPE(p_add_prot_desc->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE)) {
|
||||
/* Walk through all protocol descriptor list */
|
||||
for (p_prot_desc = p_add_prot_desc->attr_value.v.p_sub_attr; p_prot_desc; p_prot_desc = p_prot_desc->p_next_attr) {
|
||||
if(SDP_FindProtocolListElem(p_prot_desc, UUID_PROTOCOL_L2CAP, &elem_l2cap)
|
||||
&& SDP_FindProtocolListElem(p_prot_desc, UUID_PROTOCOL_OBEX, &elem_obex))
|
||||
{
|
||||
/* found */
|
||||
l2cap_psm = elem_l2cap.params[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return l2cap_psm;
|
||||
}
|
||||
|
||||
#endif /* BTA_AV_CA_INCLUDED */
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_check_peer_rc_features
|
||||
@ -1539,6 +1589,10 @@ tBTA_AV_FEAT bta_av_check_peer_rc_features (UINT16 service_uuid, UINT16 *rc_feat
|
||||
if (categories & AVRC_SUPF_CT_BROWSE) {
|
||||
peer_features |= (BTA_AV_FEAT_BROWSE);
|
||||
}
|
||||
if ((service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) && (categories & AVRC_SUPF_TG_COVER_ART)) {
|
||||
/* remote target support cover art */
|
||||
peer_features |= BTA_AV_FEAT_COVER_ART;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1573,6 +1627,9 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
tBTA_AV_FEAT peer_features; /* peer features mask */
|
||||
UINT16 peer_ct_features; /* peer features mask as controller */
|
||||
UINT16 peer_tg_features; /* peer features mask as target */
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
UINT16 obex_l2cap_psm = 0; /* target obex l2cap psm */
|
||||
#endif
|
||||
UNUSED(p_data);
|
||||
|
||||
APPL_TRACE_DEBUG("bta_av_rc_disc_done disc:x%x", p_cb->disc);
|
||||
@ -1600,7 +1657,11 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
/* check peer version and whether support CT and TG role */
|
||||
peer_features = bta_av_check_peer_rc_features (UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_ct_features);
|
||||
peer_features |= bta_av_check_peer_rc_features (UUID_SERVCLASS_AV_REM_CTRL_TARGET, &peer_tg_features);
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
if (peer_features & BTA_AV_FEAT_COVER_ART) {
|
||||
obex_l2cap_psm = bta_av_extra_tg_cover_art_l2cap_psm();
|
||||
}
|
||||
#endif
|
||||
p_cb->disc = 0;
|
||||
utl_freebuf((void **) &p_cb->p_disc_db);
|
||||
|
||||
@ -1618,6 +1679,9 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
p_cb->rcb[rc_handle].peer_features = peer_features;
|
||||
p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features;
|
||||
p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features;
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
p_cb->rcb[rc_handle].cover_art_l2cap_psm = obex_l2cap_psm;
|
||||
#endif
|
||||
}
|
||||
#if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
|
||||
else {
|
||||
@ -1636,6 +1700,11 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
}
|
||||
} else {
|
||||
p_cb->rcb[rc_handle].peer_features = peer_features;
|
||||
p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features;
|
||||
p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features;
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
p_cb->rcb[rc_handle].cover_art_l2cap_psm = obex_l2cap_psm;
|
||||
#endif
|
||||
rc_feat.rc_handle = rc_handle;
|
||||
rc_feat.peer_features = peer_features;
|
||||
rc_feat.peer_ct_features = peer_ct_features;
|
||||
@ -1676,6 +1745,10 @@ void bta_av_rc_closed(tBTA_AV_DATA *p_data)
|
||||
p_rcb->peer_features = 0;
|
||||
p_rcb->peer_ct_features = 0;
|
||||
p_rcb->peer_tg_features = 0;
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
/* reset cover art state */
|
||||
bta_av_ca_reset(p_rcb);
|
||||
#endif
|
||||
APPL_TRACE_DEBUG(" shdl:%d, lidx:%d", p_rcb->shdl, p_rcb->lidx);
|
||||
if (p_rcb->shdl) {
|
||||
if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) {
|
||||
@ -1711,7 +1784,8 @@ void bta_av_rc_closed(tBTA_AV_DATA *p_data)
|
||||
bta_av_del_rc(p_rcb);
|
||||
|
||||
/* if the AVRCP is no longer listening, create the listening channel */
|
||||
if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG) {
|
||||
if (bta_av_cb.rc_acp_handle == p_msg->handle && bta_av_cb.features & BTA_AV_FEAT_RCTG) {
|
||||
bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE;
|
||||
bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
|
||||
}
|
||||
}
|
||||
@ -1748,6 +1822,7 @@ void bta_av_rc_disc(UINT8 disc)
|
||||
tAVRC_SDP_DB_PARAMS db_params;
|
||||
UINT16 attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
|
||||
ATTR_ID_BT_PROFILE_DESC_LIST,
|
||||
ATTR_ID_ADDITION_PROTO_DESC_LISTS,
|
||||
ATTR_ID_SUPPORTED_FEATURES
|
||||
};
|
||||
UINT8 hdi;
|
||||
@ -1785,7 +1860,7 @@ void bta_av_rc_disc(UINT8 disc)
|
||||
if (p_cb->p_disc_db) {
|
||||
/* set up parameters */
|
||||
db_params.db_len = BTA_AV_DISC_BUF_SIZE;
|
||||
db_params.num_attr = 3;
|
||||
db_params.num_attr = 4;
|
||||
db_params.p_db = p_cb->p_disc_db;
|
||||
db_params.p_attrs = attr_list;
|
||||
|
||||
|
@ -613,4 +613,77 @@ void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p
|
||||
}
|
||||
}
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvCaOpen
|
||||
**
|
||||
** Description Open a Cover Art OBEX connection to peer device. This function
|
||||
** can only be used if peer device TG support Cover Art feature and
|
||||
** AV is enabled with feature BTA_AV_FEAT_METADATA.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvCaOpen(UINT8 rc_handle, UINT16 mtu)
|
||||
{
|
||||
tBTA_AV_API_CA_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_CA_OPEN *) osi_malloc(sizeof(tBTA_AV_API_CA_OPEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_CA_OPEN_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
p_buf->mtu = mtu;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvCaClose
|
||||
**
|
||||
** Description Close a Cover Art OBEX connection.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvCaClose(UINT8 rc_handle)
|
||||
{
|
||||
tBTA_AV_API_CA_CLOSE *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_CA_CLOSE *) osi_malloc(sizeof(tBTA_AV_API_CA_CLOSE))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_CA_CLOSE_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvCaGet
|
||||
**
|
||||
** Description Start the process to get image properties, get image or get
|
||||
** linked thumbnail. This function can only be used if Cover Art
|
||||
** OBEX connection is established.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvCaGet(UINT8 rc_handle, tBTA_AV_GET_TYPE type, UINT8 *image_handle, UINT8 *image_descriptor, UINT16 image_descriptor_len)
|
||||
{
|
||||
tBTA_AV_API_CA_GET *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_CA_GET *) osi_malloc(sizeof(tBTA_AV_API_CA_GET))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_CA_GET_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
p_buf->type = type;
|
||||
memcpy(p_buf->image_handle, image_handle, BTA_AV_CA_IMG_HDL_LEN);
|
||||
p_buf->image_descriptor = image_descriptor;
|
||||
p_buf->image_descriptor_len = image_descriptor_len;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BTA_AV_CA_INCLUDED */
|
||||
|
||||
#endif /* BTA_AV_INCLUDED */
|
||||
|
495
components/bt/host/bluedroid/bta/av/bta_av_ca_act.c
Normal file
495
components/bt/host/bluedroid/bta/av/bta_av_ca_act.c
Normal file
@ -0,0 +1,495 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "bta/bta_av_api.h"
|
||||
#include "bta_av_int.h"
|
||||
#include "stack/avdt_api.h"
|
||||
#include "bta/utl.h"
|
||||
#include "stack/l2c_api.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/list.h"
|
||||
#include "stack/goep_common.h"
|
||||
#include "stack/goepc_api.h"
|
||||
#include "stack/obex_api.h"
|
||||
#include "common/bt_trace.h"
|
||||
|
||||
#define COVER_ART_HEADER_ID_IMG_HANDLE 0x30
|
||||
#define COVER_ART_HEADER_ID_IMG_DESCRIPTOR 0x71
|
||||
static const UINT8 cover_art_uuid[16] = {0x71, 0x63, 0xDD, 0x54, 0x4A, 0x7E, 0x11, 0xE2, 0xB4, 0x7C, 0x00, 0x50, 0xC2, 0x49, 0x00, 0x48};
|
||||
static const char *cover_art_img_type_img = "x-bt/img-img";
|
||||
static const char *cover_art_img_type_thm = "x-bt/img-thm";
|
||||
static const char *cover_art_img_type_prop = "x-bt/img-properties";
|
||||
|
||||
#define COVER_ART_IMG_TYPE_IMG_LEN 13
|
||||
#define COVER_ART_IMG_TYPE_THM_LEN 13
|
||||
#define COVER_ART_IMG_TYPE_PROP_LEN 20
|
||||
|
||||
|
||||
static BOOLEAN find_rcb_idx_by_goep_handle(UINT16 handle, UINT16 *out_idx)
|
||||
{
|
||||
for (UINT16 i = 0; i < BTA_AV_NUM_RCB; ++i) {
|
||||
if (bta_av_cb.rcb[i].handle != BTA_AV_RC_HANDLE_NONE && bta_av_cb.rcb[i].cover_art_goep_hdl == handle) {
|
||||
*out_idx = i;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static UINT8 get_rcb_idx(tBTA_AV_RCB *p_rcb)
|
||||
{
|
||||
return (p_rcb - &bta_av_cb.rcb[0]);
|
||||
}
|
||||
|
||||
static void get_peer_bd_addr(tBTA_AV_RCB *p_rcb, BD_ADDR out_addr)
|
||||
{
|
||||
/* check if this rcb is related to a scb */
|
||||
if (p_rcb->shdl && p_rcb->shdl <= BTA_AV_NUM_STRS) {
|
||||
tBTA_AV_SCB *p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
|
||||
bdcpy(out_addr, p_scb->peer_addr);
|
||||
}
|
||||
/* else, try get peer addr from lcb */
|
||||
else if (p_rcb->lidx && p_rcb->lidx <= BTA_AV_NUM_LINKS + 1)
|
||||
{
|
||||
bdcpy(out_addr, bta_av_cb.lcb[p_rcb->lidx-1].addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void report_data_event(BT_HDR *pkt, UINT8 *p_data, UINT16 data_len, BOOLEAN final)
|
||||
{
|
||||
tBTA_AV_CA_DATA ca_data;
|
||||
ca_data.status = BT_STATUS_SUCCESS;
|
||||
ca_data.final = final;
|
||||
ca_data.data_len = data_len;
|
||||
ca_data.p_data = p_data;
|
||||
ca_data.p_hdr = pkt;
|
||||
(*bta_av_cb.p_cback)(BTA_AV_CA_DATA_EVT, (tBTA_AV *) &ca_data);
|
||||
}
|
||||
|
||||
static void report_error_data_event(UINT16 status)
|
||||
{
|
||||
tBTA_AV_CA_DATA ca_data;
|
||||
ca_data.status = status;
|
||||
ca_data.final = TRUE;
|
||||
ca_data.data_len = 0;
|
||||
ca_data.p_data = NULL;
|
||||
ca_data.p_hdr = NULL;
|
||||
(*bta_av_cb.p_cback)(BTA_AV_CA_DATA_EVT, (tBTA_AV *) &ca_data);
|
||||
}
|
||||
|
||||
static void build_and_send_connect_req(tBTA_AV_RCB *p_rcb)
|
||||
{
|
||||
tOBEX_PARSE_INFO info = {0};
|
||||
info.opcode = OBEX_OPCODE_CONNECT;
|
||||
info.obex_version_number = 0x15;
|
||||
info.max_packet_length = p_rcb->cover_art_max_rx;
|
||||
/* before OBEX connect response, we dont know cover_art_max_tx, use BT_SMALL_BUFFER_SIZE as tx buff size */
|
||||
if (GOEPC_PrepareRequest(p_rcb->cover_art_goep_hdl, &info, BT_SMALL_BUFFER_SIZE) == GOEP_SUCCESS) {
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, OBEX_HEADER_ID_TARGET, (UINT8 *)cover_art_uuid, 16);
|
||||
GOEPC_SendRequest(p_rcb->cover_art_goep_hdl);
|
||||
}
|
||||
}
|
||||
|
||||
static void build_and_send_disconnect_req(tBTA_AV_RCB *p_rcb)
|
||||
{
|
||||
tOBEX_PARSE_INFO info = {0};
|
||||
info.opcode = OBEX_OPCODE_DISCONNECT;
|
||||
if (GOEPC_PrepareRequest(p_rcb->cover_art_goep_hdl, &info, BT_SMALL_BUFFER_SIZE) == GOEP_SUCCESS) {
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, OBEX_HEADER_ID_CONNECTION_ID, (UINT8 *)(&p_rcb->cover_art_cid), 4);
|
||||
GOEPC_SendRequest(p_rcb->cover_art_goep_hdl);
|
||||
}
|
||||
}
|
||||
|
||||
static void build_and_send_empty_get_req(tBTA_AV_RCB *p_rcb)
|
||||
{
|
||||
tOBEX_PARSE_INFO info = {0};
|
||||
info.opcode = OBEX_OPCODE_GET_FINAL;
|
||||
/* empty get request, use a small buff size */
|
||||
UINT16 tx_buff_size = BT_SMALL_BUFFER_SIZE < p_rcb->cover_art_max_tx ? BT_SMALL_BUFFER_SIZE : p_rcb->cover_art_max_tx;
|
||||
if (GOEPC_PrepareRequest(p_rcb->cover_art_goep_hdl, &info, tx_buff_size) == GOEP_SUCCESS) {
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, OBEX_HEADER_ID_CONNECTION_ID, (UINT8 *)(&p_rcb->cover_art_cid), 4);
|
||||
GOEPC_SendRequest(p_rcb->cover_art_goep_hdl);
|
||||
}
|
||||
}
|
||||
|
||||
static void close_goepc_and_disconnect(tBTA_AV_RCB *p_rcb)
|
||||
{
|
||||
if (p_rcb->cover_art_goep_hdl) {
|
||||
GOEPC_Close(p_rcb->cover_art_goep_hdl);
|
||||
}
|
||||
p_rcb->cover_art_goep_hdl = 0;
|
||||
p_rcb->cover_art_cid = 0;
|
||||
p_rcb->cover_art_max_tx = 0;
|
||||
p_rcb->cover_art_max_rx = 0;
|
||||
|
||||
tBTA_AV_DATA *p_data = (tBTA_AV_DATA *) osi_malloc(sizeof(tBTA_AV_DATA));
|
||||
if (p_data == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
p_data->hdr.event = BTA_AV_CA_GOEP_DISCONNECT_EVT;
|
||||
p_data->hdr.layer_specific = get_rcb_idx(p_rcb);
|
||||
p_data->ca_disconnect.reason = BT_STATUS_FAIL;
|
||||
bta_sys_sendmsg(p_data);
|
||||
}
|
||||
|
||||
static void image_handle_to_utf16(const UINT8 *image_handle, UINT8 *buffer)
|
||||
{
|
||||
UINT8 pos = 0;
|
||||
for (int i = 0 ; i < BTA_AV_CA_IMG_HDL_LEN ; i++){
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = image_handle[i];
|
||||
}
|
||||
buffer[pos++] = 0;
|
||||
buffer[pos++] = 0;
|
||||
}
|
||||
|
||||
void bta_av_ca_goep_event_handler(UINT16 handle, UINT8 event, tGOEPC_MSG *p_msg)
|
||||
{
|
||||
tBTA_AV_DATA *p_data = NULL;
|
||||
UINT16 rcb_idx;
|
||||
if (!find_rcb_idx_by_goep_handle(handle, &rcb_idx)) {
|
||||
/* can not find a rcb, go error */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (event == GOEPC_RESPONSE_EVT || event == GOEPC_OPENED_EVT || event == GOEPC_CLOSED_EVT) {
|
||||
p_data = (tBTA_AV_DATA *) osi_malloc(sizeof(tBTA_AV_DATA));
|
||||
assert(p_data != NULL);
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case GOEPC_OPENED_EVT:
|
||||
p_data->hdr.layer_specific = rcb_idx;
|
||||
p_data->hdr.event = BTA_AV_CA_GOEP_CONNECT_EVT;
|
||||
p_data->ca_connect.max_rx = p_msg->opened.our_mtu;
|
||||
break;
|
||||
case GOEPC_CLOSED_EVT:
|
||||
p_data->hdr.layer_specific = rcb_idx;
|
||||
p_data->hdr.event = BTA_AV_CA_GOEP_DISCONNECT_EVT;
|
||||
p_data->ca_disconnect.reason = BT_STATUS_FAIL;
|
||||
break;
|
||||
case GOEPC_RESPONSE_EVT:
|
||||
p_data->hdr.layer_specific = rcb_idx;
|
||||
p_data->ca_response.pkt = p_msg->response.pkt;
|
||||
p_data->ca_response.opcode = p_msg->response.opcode;
|
||||
p_data->ca_response.srm_en = p_msg->response.srm_en;
|
||||
p_data->ca_response.srm_wait = p_msg->response.srm_wait;
|
||||
if (p_msg->response.final) {
|
||||
p_data->hdr.event = BTA_AV_CA_RESPONSE_FINAL_EVT;
|
||||
}
|
||||
else {
|
||||
p_data->hdr.event = BTA_AV_CA_RESPONSE_EVT;
|
||||
}
|
||||
break;
|
||||
case GOEPC_MTU_CHANGED_EVT:
|
||||
case GOEPC_CONGEST_EVT:
|
||||
case GOEPC_UNCONGEST_EVT:
|
||||
/* ignore these event */
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
if (p_data) {
|
||||
bta_sys_sendmsg(p_data);
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
/* can not find rcb, just free resource and disconnect */
|
||||
if (p_data != NULL) {
|
||||
osi_free(p_data);
|
||||
}
|
||||
if (event == GOEPC_RESPONSE_EVT && p_msg->response.pkt != NULL) {
|
||||
osi_free(p_msg->response.pkt);
|
||||
}
|
||||
if (event != GOEPC_CLOSED_EVT) {
|
||||
GOEPC_Close(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void bta_av_ca_api_open(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
tOBEX_SVR_INFO svr = {0};
|
||||
svr.tl = OBEX_OVER_L2CAP;
|
||||
svr.l2cap.psm = p_rcb->cover_art_l2cap_psm;
|
||||
svr.l2cap.pref_mtu = p_data->api_ca_open.mtu;
|
||||
/* reuse the security mask store in bta_av_cb, when support multi connection, this may need change */
|
||||
svr.l2cap.sec_mask = bta_av_cb.sec_mask;
|
||||
p_rcb->cover_art_max_rx = p_data->api_ca_open.mtu;
|
||||
get_peer_bd_addr(p_rcb, svr.l2cap.addr);
|
||||
|
||||
if (GOEPC_Open(&svr, bta_av_ca_goep_event_handler, &p_rcb->cover_art_goep_hdl) != GOEP_SUCCESS) {
|
||||
/* open failed */
|
||||
if ((p_data = (tBTA_AV_DATA *) osi_malloc(sizeof(tBTA_AV_DATA))) == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
p_data->hdr.event = BTA_AV_CA_GOEP_DISCONNECT_EVT;
|
||||
p_data->hdr.layer_specific = get_rcb_idx(p_rcb);
|
||||
p_data->ca_disconnect.reason = BT_STATUS_FAIL;
|
||||
bta_sys_sendmsg(p_data);
|
||||
}
|
||||
}
|
||||
|
||||
void bta_av_ca_api_close(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
/* this is a normal disconnect, just build and send OBEX disconnect request */
|
||||
build_and_send_disconnect_req(p_rcb);
|
||||
}
|
||||
|
||||
void bta_av_ca_api_get(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
tOBEX_PARSE_INFO info = {0};
|
||||
UINT8 image_handle_utf16[BTA_AV_CA_IMG_HDL_UTF16_LEN];
|
||||
info.opcode = OBEX_OPCODE_GET_FINAL;
|
||||
/* limit the tx buff size to BT_DEFAULT_BUFFER_SIZE */
|
||||
UINT16 tx_buff_size = BT_DEFAULT_BUFFER_SIZE < p_rcb->cover_art_max_tx ? BT_DEFAULT_BUFFER_SIZE : p_rcb->cover_art_max_tx;
|
||||
if (GOEPC_PrepareRequest(p_rcb->cover_art_goep_hdl, &info, tx_buff_size) != GOEP_SUCCESS) {
|
||||
/* something error */
|
||||
goto error;
|
||||
}
|
||||
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, OBEX_HEADER_ID_CONNECTION_ID, (UINT8 *)(&p_rcb->cover_art_cid), 4);
|
||||
switch (p_data->api_ca_get.type)
|
||||
{
|
||||
case BTA_AV_CA_GET_IMAGE_PROPERTIES:
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, OBEX_HEADER_ID_TYPE, (const UINT8 *)cover_art_img_type_prop, COVER_ART_IMG_TYPE_PROP_LEN);
|
||||
break;
|
||||
case BTA_AV_CA_GET_IMAGE:
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, OBEX_HEADER_ID_TYPE, (const UINT8 *)cover_art_img_type_img, COVER_ART_IMG_TYPE_IMG_LEN);
|
||||
break;
|
||||
case BTA_AV_CA_GET_LINKED_THUMBNAIL:
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, OBEX_HEADER_ID_TYPE, (const UINT8 *)cover_art_img_type_thm, COVER_ART_IMG_TYPE_THM_LEN);
|
||||
break;
|
||||
default:
|
||||
/* should not go here */
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
image_handle_to_utf16(p_data->api_ca_get.image_handle, image_handle_utf16);
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, COVER_ART_HEADER_ID_IMG_HANDLE, (UINT8 *)image_handle_utf16, BTA_AV_CA_IMG_HDL_UTF16_LEN);
|
||||
if (p_data->api_ca_get.type == BTA_AV_CA_GET_IMAGE) {
|
||||
GOEPC_RequestAddHeader(p_rcb->cover_art_goep_hdl, COVER_ART_HEADER_ID_IMG_DESCRIPTOR, (UINT8 *)p_data->api_ca_get.image_descriptor, p_data->api_ca_get.image_descriptor_len);
|
||||
}
|
||||
/* always request to enable srm */
|
||||
GOEPC_RequestSetSRM(p_rcb->cover_art_goep_hdl, TRUE, FALSE);
|
||||
|
||||
if (GOEPC_SendRequest(p_rcb->cover_art_goep_hdl) != GOEP_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
error:
|
||||
close_goepc_and_disconnect(p_rcb);
|
||||
}
|
||||
|
||||
void bta_av_ca_response(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
tOBEX_PARSE_INFO info;
|
||||
OBEX_ParseResponse(p_data->ca_response.pkt, p_data->ca_response.opcode, &info);
|
||||
/* we always use a final get */
|
||||
if (p_data->ca_response.opcode == OBEX_OPCODE_GET_FINAL
|
||||
&& (info.response_code == OBEX_RESPONSE_CODE_CONTINUE || info.response_code == (OBEX_RESPONSE_CODE_CONTINUE | OBEX_FINAL_BIT_MASK)))
|
||||
{
|
||||
UINT8 *header = NULL;
|
||||
UINT8 *body_data = NULL;
|
||||
UINT16 body_data_len = 0;
|
||||
while((header = OBEX_GetNextHeader(p_data->ca_response.pkt, &info)) != NULL) {
|
||||
switch (*header)
|
||||
{
|
||||
case OBEX_HEADER_ID_BODY:
|
||||
/* actually,END_OF_BODY should not in this continue response */
|
||||
case OBEX_HEADER_ID_END_OF_BODY:
|
||||
if (body_data == NULL) {
|
||||
/* first body header */
|
||||
body_data = header + 3; /* skip opcode, length */
|
||||
body_data_len = OBEX_GetHeaderLength(header) - 3;
|
||||
}
|
||||
else {
|
||||
/* another body header found */
|
||||
report_data_event(NULL, body_data, body_data_len, FALSE);
|
||||
body_data = header + 3; /* skip opcode, length */
|
||||
body_data_len = OBEX_GetHeaderLength(header) - 3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (body_data != NULL) {
|
||||
/* the only one or the last body data */
|
||||
report_data_event(p_data->ca_response.pkt, body_data, body_data_len, FALSE);
|
||||
}
|
||||
else {
|
||||
/* not any body data */
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
}
|
||||
|
||||
/* if SRM not enable, we need to send a empty get request */
|
||||
if (!p_data->ca_response.srm_en || p_data->ca_response.srm_wait) {
|
||||
build_and_send_empty_get_req(p_rcb);
|
||||
}
|
||||
}
|
||||
else {
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
close_goepc_and_disconnect(p_rcb);
|
||||
}
|
||||
|
||||
void bta_av_ca_response_final(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
tOBEX_PARSE_INFO info;
|
||||
OBEX_ParseResponse(p_data->ca_response.pkt, p_data->ca_response.opcode, &info);
|
||||
UINT8 *header = NULL;
|
||||
if (p_data->ca_response.opcode == OBEX_OPCODE_CONNECT) {
|
||||
/* we expect a success response code with final bit set */
|
||||
if (info.response_code == (OBEX_RESPONSE_CODE_OK | OBEX_FINAL_BIT_MASK)) {
|
||||
if (info.max_packet_length < 255) {
|
||||
p_rcb->cover_art_max_tx = 255;
|
||||
}
|
||||
else {
|
||||
p_rcb->cover_art_max_tx = info.max_packet_length;
|
||||
}
|
||||
BOOLEAN cid_found = false;
|
||||
while((header = OBEX_GetNextHeader(p_data->ca_response.pkt, &info)) != NULL) {
|
||||
if (*header == OBEX_HEADER_ID_CONNECTION_ID) {
|
||||
cid_found = true;
|
||||
memcpy((UINT8 *)(&p_rcb->cover_art_cid), header + 1, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cid_found) {
|
||||
goto error;
|
||||
}
|
||||
tBTA_AV_CA_STATUS ca_status;
|
||||
ca_status.connected = TRUE;
|
||||
ca_status.reason = BT_STATUS_SUCCESS;
|
||||
(*bta_av_cb.p_cback)(BTA_AV_CA_STATUS_EVT, (tBTA_AV *) &ca_status);
|
||||
/* done, free response packet */
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
}
|
||||
else {
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (p_data->ca_response.opcode == OBEX_OPCODE_GET_FINAL) {
|
||||
UINT8 *body_data = NULL;
|
||||
UINT16 body_data_len = 0;
|
||||
/* check response code is success */
|
||||
if (info.response_code == (OBEX_RESPONSE_CODE_OK | OBEX_FINAL_BIT_MASK)) {
|
||||
while((header = OBEX_GetNextHeader(p_data->ca_response.pkt, &info)) != NULL) {
|
||||
switch (*header)
|
||||
{
|
||||
/* actually, BODY should not in this final response */
|
||||
case OBEX_HEADER_ID_BODY:
|
||||
case OBEX_HEADER_ID_END_OF_BODY:
|
||||
if (body_data == NULL) {
|
||||
/* first body header */
|
||||
body_data = header + 3; /* skip opcode, length */
|
||||
body_data_len = OBEX_GetHeaderLength(header) - 3;
|
||||
}
|
||||
else {
|
||||
/* another body header found */
|
||||
report_data_event(NULL, body_data, body_data_len, FALSE);
|
||||
body_data = header + 3; /* skip opcode, length */
|
||||
body_data_len = OBEX_GetHeaderLength(header) - 3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (body_data != NULL) {
|
||||
/* the only one or the last body data, packet will be free by upper layer */
|
||||
report_data_event(p_data->ca_response.pkt, body_data, body_data_len, TRUE);
|
||||
}
|
||||
else {
|
||||
/* not any body data */
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
}
|
||||
}
|
||||
else {
|
||||
report_error_data_event(BT_STATUS_FAIL);
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
}
|
||||
}
|
||||
else if (p_data->ca_response.opcode == OBEX_OPCODE_DISCONNECT) {
|
||||
/* received disconnect response, close l2cap channel and reset cover art value */
|
||||
bta_av_ca_force_disconnect(p_rcb, p_data);
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
}
|
||||
else {
|
||||
osi_free(p_data->ca_response.pkt);
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
close_goepc_and_disconnect(p_rcb);
|
||||
}
|
||||
|
||||
void bta_av_ca_goep_connect(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
/* goep connection open, use a smaller value as max_rx */
|
||||
if (p_rcb->cover_art_max_rx > p_data->ca_connect.max_rx) {
|
||||
p_rcb->cover_art_max_rx = p_data->ca_connect.max_rx;
|
||||
}
|
||||
build_and_send_connect_req(p_rcb);
|
||||
}
|
||||
|
||||
void bta_av_ca_goep_disconnect(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
p_rcb->cover_art_goep_hdl = 0;
|
||||
p_rcb->cover_art_max_rx = 0;
|
||||
p_rcb->cover_art_max_tx = 0;
|
||||
p_rcb->cover_art_cid = 0;
|
||||
|
||||
tBTA_AV_CA_STATUS ca_status;
|
||||
ca_status.connected = FALSE;
|
||||
ca_status.reason = p_data->ca_disconnect.reason;
|
||||
(*bta_av_cb.p_cback)(BTA_AV_CA_STATUS_EVT, (tBTA_AV *) &ca_status);
|
||||
}
|
||||
|
||||
void bta_av_ca_force_disconnect(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
if (p_rcb->cover_art_goep_hdl) {
|
||||
GOEPC_Close(p_rcb->cover_art_goep_hdl);
|
||||
}
|
||||
/* dont reset p_rcb->cover_art_l2cap_psm */
|
||||
p_rcb->cover_art_goep_hdl = 0;
|
||||
p_rcb->cover_art_cid = 0;
|
||||
p_rcb->cover_art_max_tx = 0;
|
||||
p_rcb->cover_art_max_rx = 0;
|
||||
tBTA_AV_CA_STATUS ca_status;
|
||||
ca_status.connected = FALSE;
|
||||
/* force disconnect by upper, set reason to success */
|
||||
ca_status.reason = BT_STATUS_SUCCESS;
|
||||
(*bta_av_cb.p_cback)(BTA_AV_CA_STATUS_EVT, (tBTA_AV *) &ca_status);
|
||||
}
|
||||
|
||||
void bta_av_ca_reset(tBTA_AV_RCB *p_rcb)
|
||||
{
|
||||
if (p_rcb->cover_art_goep_hdl) {
|
||||
GOEPC_Close(p_rcb->cover_art_goep_hdl);
|
||||
}
|
||||
p_rcb->cover_art_l2cap_psm = 0;
|
||||
p_rcb->cover_art_goep_hdl = 0;
|
||||
p_rcb->cover_art_state = 0;
|
||||
p_rcb->cover_art_cid = 0;
|
||||
p_rcb->cover_art_max_tx = 0;
|
||||
p_rcb->cover_art_max_rx = 0;
|
||||
}
|
||||
|
||||
#endif /* BTA_AV_CA_INCLUDED */
|
170
components/bt/host/bluedroid/bta/av/bta_av_ca_sm.c
Normal file
170
components/bt/host/bluedroid/bta/av/bta_av_ca_sm.c
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "bta/bta_av_api.h"
|
||||
#include "bta_av_int.h"
|
||||
#include "stack/avdt_api.h"
|
||||
#include "bta/utl.h"
|
||||
#include "stack/l2c_api.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/list.h"
|
||||
|
||||
#include "common/bt_trace.h"
|
||||
|
||||
/* state machine states */
|
||||
enum {
|
||||
BTA_AV_CA_INIT_ST,
|
||||
BTA_AV_CA_OPENING_ST,
|
||||
BTA_AV_CA_CONNECTING_ST,
|
||||
BTA_AV_CA_CONNECTED_ST,
|
||||
BTA_AV_CA_GETTING_ST,
|
||||
BTA_AV_CA_CLOSING_ST
|
||||
};
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_AV_API_CA_OPEN,
|
||||
BTA_AV_API_CA_CLOSE,
|
||||
BTA_AV_API_CA_GET,
|
||||
BTA_AV_CA_RESPONSE,
|
||||
BTA_AV_CA_RESPONSE_FINAL,
|
||||
BTA_AV_CA_GOEP_CONNECT,
|
||||
BTA_AV_CA_GOEP_DISCONNECT,
|
||||
BTA_AV_CA_FORCE_DISCONNECT,
|
||||
BTA_AV_CA_NUM_ACTIONS
|
||||
};
|
||||
|
||||
#define BTA_AV_CA_IGNORE BTA_AV_CA_NUM_ACTIONS
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_AV_CA_ACTION)(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
|
||||
/* action functions */
|
||||
const tBTA_AV_CA_ACTION bta_av_ca_action[] = {
|
||||
bta_av_ca_api_open,
|
||||
bta_av_ca_api_close,
|
||||
bta_av_ca_api_get,
|
||||
bta_av_ca_response,
|
||||
bta_av_ca_response_final,
|
||||
bta_av_ca_goep_connect,
|
||||
bta_av_ca_goep_disconnect,
|
||||
bta_av_ca_force_disconnect,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* state table information */
|
||||
#define BTA_AV_CA_ACTION_COL 0 /* position of actions */
|
||||
#define BTA_AV_CA_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_AV_CA_NUM_COLS 2 /* number of columns in state tables */
|
||||
|
||||
/* state table for init state */
|
||||
static const UINT8 bta_av_ca_st_init[][BTA_AV_CA_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* API_CA_OPEN_EVT */ {BTA_AV_API_CA_OPEN, BTA_AV_CA_OPENING_ST },
|
||||
/* API_CA_CLOSE_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_INIT_ST },
|
||||
/* API_CA_GET_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_INIT_ST },
|
||||
/* CA_RESPONSE_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_INIT_ST },
|
||||
/* CA_RESPONSE_FINAL_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_INIT_ST },
|
||||
/* CA_GOEP_CONNECT_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_INIT_ST },
|
||||
/* CA_GOEP_DISCONNECT_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_INIT_ST },
|
||||
};
|
||||
|
||||
/* state table for opening state */
|
||||
static const UINT8 bta_av_ca_st_opening[][BTA_AV_CA_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* API_CA_OPEN_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_OPENING_ST },
|
||||
/* API_CA_CLOSE_EVT */ {BTA_AV_CA_FORCE_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
/* API_CA_GET_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_OPENING_ST },
|
||||
/* CA_RESPONSE_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_OPENING_ST },
|
||||
/* CA_RESPONSE_FINAL_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_OPENING_ST },
|
||||
/* CA_GOEP_CONNECT_EVT */ {BTA_AV_CA_GOEP_CONNECT, BTA_AV_CA_CONNECTING_ST },
|
||||
/* CA_GOEP_DISCONNECT_EVT */ {BTA_AV_CA_GOEP_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
};
|
||||
|
||||
/* state table for connecting state */
|
||||
static const UINT8 bta_av_ca_st_connecting[][BTA_AV_CA_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* API_CA_OPEN_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTING_ST },
|
||||
/* API_CA_CLOSE_EVT */ {BTA_AV_CA_FORCE_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
/* API_CA_GET_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTING_ST },
|
||||
/* CA_RESPONSE_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTING_ST },
|
||||
/* CA_RESPONSE_FINAL_EVT */ {BTA_AV_CA_RESPONSE_FINAL, BTA_AV_CA_CONNECTED_ST },
|
||||
/* CA_GOEP_CONNECT_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTING_ST },
|
||||
/* CA_GOEP_DISCONNECT_EVT */ {BTA_AV_CA_GOEP_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
};
|
||||
|
||||
/* state table for connected state */
|
||||
static const UINT8 bta_av_ca_st_connected[][BTA_AV_CA_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* API_CA_OPEN_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTED_ST },
|
||||
/* API_CA_CLOSE_EVT */ {BTA_AV_API_CA_CLOSE, BTA_AV_CA_CLOSING_ST },
|
||||
/* API_CA_GET_EVT */ {BTA_AV_API_CA_GET, BTA_AV_CA_GETTING_ST },
|
||||
/* CA_RESPONSE_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTED_ST },
|
||||
/* CA_RESPONSE_FINAL_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTED_ST },
|
||||
/* CA_GOEP_CONNECT_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CONNECTED_ST },
|
||||
/* CA_GOEP_DISCONNECT_EVT */ {BTA_AV_CA_GOEP_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
};
|
||||
|
||||
/* state table for getting state */
|
||||
static const UINT8 bta_av_ca_st_getting[][BTA_AV_CA_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* API_CA_OPEN_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_GETTING_ST },
|
||||
/* API_CA_CLOSE_EVT */ {BTA_AV_CA_FORCE_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
/* API_CA_GET_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_GETTING_ST },
|
||||
/* CA_RESPONSE_EVT */ {BTA_AV_CA_RESPONSE, BTA_AV_CA_GETTING_ST },
|
||||
/* CA_RESPONSE_FINAL_EVT */ {BTA_AV_CA_RESPONSE_FINAL, BTA_AV_CA_CONNECTED_ST },
|
||||
/* CA_GOEP_CONNECT_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_GETTING_ST },
|
||||
/* CA_GOEP_DISCONNECT_EVT */ {BTA_AV_CA_GOEP_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
};
|
||||
|
||||
/* state table for closing state */
|
||||
static const UINT8 bta_av_ca_st_closing[][BTA_AV_CA_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* API_CA_OPEN_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CLOSING_ST },
|
||||
/* API_CA_CLOSE_EVT */ {BTA_AV_CA_FORCE_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
/* API_CA_GET_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CLOSING_ST },
|
||||
/* CA_RESPONSE_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CLOSING_ST },
|
||||
/* CA_RESPONSE_FINAL_EVT */ {BTA_AV_CA_RESPONSE_FINAL, BTA_AV_CA_INIT_ST },
|
||||
/* CA_GOEP_CONNECT_EVT */ {BTA_AV_CA_IGNORE, BTA_AV_CA_CLOSING_ST },
|
||||
/* CA_GOEP_DISCONNECT_EVT */ {BTA_AV_CA_GOEP_DISCONNECT, BTA_AV_CA_INIT_ST },
|
||||
};
|
||||
|
||||
/* type for state table */
|
||||
typedef const UINT8 (*tBTA_AV_CA_ST_TBL)[BTA_AV_CA_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
static const tBTA_AV_CA_ST_TBL bta_av_ca_st_tbl[] = {
|
||||
bta_av_ca_st_init,
|
||||
bta_av_ca_st_opening,
|
||||
bta_av_ca_st_connecting,
|
||||
bta_av_ca_st_connected,
|
||||
bta_av_ca_st_getting,
|
||||
bta_av_ca_st_closing
|
||||
};
|
||||
|
||||
void bta_av_ca_sm_execute(tBTA_AV_RCB *p_rcb, UINT16 event, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
tBTA_AV_CA_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_av_ca_st_tbl[p_rcb->cover_art_state];
|
||||
|
||||
event -= BTA_AV_CA_FIRST_SM_EVT;
|
||||
|
||||
/* set next state */
|
||||
p_rcb->cover_art_state = state_table[event][BTA_AV_CA_NEXT_STATE];
|
||||
|
||||
/* execute action functions */
|
||||
if ((action = state_table[event][BTA_AV_CA_ACTION_COL]) != BTA_AV_CA_IGNORE) {
|
||||
(*bta_av_ca_action[action])(p_rcb, p_data);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BTA_AV_CA_INCLUDED */
|
@ -461,7 +461,7 @@ static void bta_av_a2dp_report_cback(UINT8 handle, AVDT_REPORT_TYPE type,
|
||||
**
|
||||
** Function bta_av_api_sink_enable
|
||||
**
|
||||
** Description activate, deactive A2DP Sink,
|
||||
** Description activate, deactivate A2DP Sink,
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
@ -593,7 +593,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the Calss of Device (Audio & Capturing/Rendering service class bit) */
|
||||
/* Set the Class of Device (Audio & Capturing/Rendering service class bit) */
|
||||
if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
|
||||
cod.service = BTM_COD_SERVICE_CAPTURING | BTM_COD_SERVICE_AUDIO;
|
||||
cod.major = BTM_COD_MAJOR_AUDIO;
|
||||
@ -1248,6 +1248,13 @@ BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
|
||||
APPL_TRACE_VERBOSE("AV sm event=0x%x(%s)\n", event, bta_av_evt_code(event));
|
||||
/* state machine events */
|
||||
bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA *) p_msg);
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
} else if (event >= BTA_AV_CA_FIRST_SM_EVT && event <= BTA_AV_CA_LAST_SM_EVT) {
|
||||
if (p_msg->layer_specific < BTA_AV_NUM_RCB) {
|
||||
tBTA_AV_RCB *p_rcb = &bta_av_cb.rcb[p_msg->layer_specific];
|
||||
bta_av_ca_sm_execute(p_rcb, p_msg->event, (tBTA_AV_DATA *) p_msg);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
APPL_TRACE_VERBOSE("handle=0x%x\n", p_msg->layer_specific);
|
||||
tBTA_AV_SCB *p_scb = bta_av_hndl_to_scb(p_msg->layer_specific);
|
||||
|
@ -85,7 +85,16 @@ enum {
|
||||
BTA_AV_ROLE_CHANGE_EVT,
|
||||
BTA_AV_AVDT_DELAY_RPT_EVT,
|
||||
BTA_AV_ACP_CONNECT_EVT,
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
/* these events are handled by the Cover Art Client state machine */
|
||||
BTA_AV_API_CA_OPEN_EVT,
|
||||
BTA_AV_API_CA_CLOSE_EVT,
|
||||
BTA_AV_API_CA_GET_EVT,
|
||||
BTA_AV_CA_RESPONSE_EVT,
|
||||
BTA_AV_CA_RESPONSE_FINAL_EVT,
|
||||
BTA_AV_CA_GOEP_CONNECT_EVT,
|
||||
BTA_AV_CA_GOEP_DISCONNECT_EVT,
|
||||
#endif
|
||||
/* these events are handled outside of the state machine */
|
||||
BTA_AV_API_ENABLE_EVT,
|
||||
BTA_AV_API_REGISTER_EVT,
|
||||
@ -115,6 +124,12 @@ enum {
|
||||
#define BTA_AV_FIRST_SM_EVT BTA_AV_API_DISABLE_EVT
|
||||
#define BTA_AV_LAST_SM_EVT BTA_AV_AVRC_NONE_EVT
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
/* events for AVRC Cover Art state machine */
|
||||
#define BTA_AV_CA_FIRST_SM_EVT BTA_AV_API_CA_OPEN_EVT
|
||||
#define BTA_AV_CA_LAST_SM_EVT BTA_AV_CA_GOEP_DISCONNECT_EVT
|
||||
#endif
|
||||
|
||||
/* events for AV stream control block state machine */
|
||||
#define BTA_AV_FIRST_SSM_EVT BTA_AV_API_OPEN_EVT
|
||||
|
||||
@ -348,6 +363,52 @@ typedef struct {
|
||||
BT_HDR hdr;
|
||||
} tBTA_AV_API_GET_DELAY_VALUE;
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
|
||||
/* data type for BTA_AV_API_CA_OPEN_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 mtu;
|
||||
} tBTA_AV_API_CA_OPEN;
|
||||
|
||||
/* data type for BTA_AV_API_CA_CLOSE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
} tBTA_AV_API_CA_CLOSE;
|
||||
|
||||
/* data type for BTA_AV_API_CA_GET_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_AV_GET_TYPE type;
|
||||
UINT8 image_handle[7];
|
||||
/* Image descriptor used in get image function */
|
||||
UINT16 image_descriptor_len;
|
||||
UINT8 *image_descriptor;
|
||||
} tBTA_AV_API_CA_GET;
|
||||
|
||||
/* data type for BTA_AV_CA_RESPONSE_EVT and BTA_AV_CA_RESPONSE_FINAL_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BT_HDR *pkt;
|
||||
UINT8 opcode;
|
||||
BOOLEAN srm_en;
|
||||
BOOLEAN srm_wait;
|
||||
} tBTA_AV_CA_RESPONSE;
|
||||
|
||||
/* data type for BTA_AV_CA_CONNECT_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 max_rx;
|
||||
} tBTA_AV_CA_CONNECT;
|
||||
|
||||
/* data type for BTA_AV_CA_DISCONNECT_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 reason;
|
||||
} tBTA_AV_CA_DISCONNECT;
|
||||
|
||||
#endif /* BTA_AV_CA_INCLUDED */
|
||||
|
||||
/* initiator/acceptor role for adaption */
|
||||
#define BTA_AV_ROLE_AD_INT 0x00 /* initiator */
|
||||
#define BTA_AV_ROLE_AD_ACP 0x01 /* acceptor */
|
||||
@ -382,6 +443,14 @@ typedef union {
|
||||
tBTA_AV_API_META_RSP api_meta_rsp;
|
||||
tBTA_AV_API_SET_DELAY_VALUE api_set_delay_vlaue;
|
||||
tBTA_AV_API_GET_DELAY_VALUE api_get_delay_value;
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
tBTA_AV_API_CA_OPEN api_ca_open;
|
||||
tBTA_AV_API_CA_CLOSE api_ca_close;
|
||||
tBTA_AV_API_CA_GET api_ca_get;
|
||||
tBTA_AV_CA_RESPONSE ca_response;
|
||||
tBTA_AV_CA_CONNECT ca_connect;
|
||||
tBTA_AV_CA_DISCONNECT ca_disconnect;
|
||||
#endif
|
||||
} tBTA_AV_DATA;
|
||||
|
||||
typedef void (tBTA_AV_VDP_DATA_ACT)(void *p_scb);
|
||||
@ -405,8 +474,8 @@ typedef union {
|
||||
#define BTA_AV_Q_TAG_START 0x02 /* before start sending media packets */
|
||||
#define BTA_AV_Q_TAG_STREAM 0x03 /* during streaming */
|
||||
|
||||
#define BTA_AV_WAIT_ACP_CAPS_ON 0x01 /* retriving the peer capabilities */
|
||||
#define BTA_AV_WAIT_ACP_CAPS_STARTED 0x02 /* started while retriving peer capabilities */
|
||||
#define BTA_AV_WAIT_ACP_CAPS_ON 0x01 /* retrieving the peer capabilities */
|
||||
#define BTA_AV_WAIT_ACP_CAPS_STARTED 0x02 /* started while retrieving peer capabilities */
|
||||
#define BTA_AV_WAIT_ROLE_SW_RES_OPEN 0x04 /* waiting for role switch result after API_OPEN, before STR_OPENED */
|
||||
#define BTA_AV_WAIT_ROLE_SW_RES_START 0x08 /* waiting for role switch result before streaming */
|
||||
#define BTA_AV_WAIT_ROLE_SW_STARTED 0x10 /* started while waiting for role switch result */
|
||||
@ -462,7 +531,7 @@ typedef struct {
|
||||
BOOLEAN use_rc; /* TRUE if AVRCP is allowed */
|
||||
BOOLEAN started; /* TRUE if stream started */
|
||||
UINT8 co_started; /* non-zero, if stream started from call-out perspective */
|
||||
BOOLEAN recfg_sup; /* TRUE if the first attempt to reconfigure the stream was successfull, else False if command fails */
|
||||
BOOLEAN recfg_sup; /* TRUE if the first attempt to reconfigure the stream was successful, else False if command fails */
|
||||
BOOLEAN suspend_sup; /* TRUE if Suspend stream is supported, else FALSE if suspend command fails */
|
||||
BOOLEAN deregistring; /* TRUE if deregistering */
|
||||
BOOLEAN sco_suspend; /* TRUE if SUSPEND is issued automatically for SCO */
|
||||
@ -471,7 +540,7 @@ typedef struct {
|
||||
UINT8 wait; /* set 0x1, when getting Caps as ACP, set 0x2, when started */
|
||||
UINT8 q_tag; /* identify the associated q_info union member */
|
||||
BOOLEAN no_rtp_hdr; /* TRUE if add no RTP header*/
|
||||
UINT8 disc_rsn; /* disconenction reason */
|
||||
UINT8 disc_rsn; /* disconnection reason */
|
||||
UINT16 uuid_int; /*intended UUID of Initiator to connect to */
|
||||
} tBTA_AV_SCB;
|
||||
|
||||
@ -481,6 +550,13 @@ typedef struct {
|
||||
|
||||
#define BTA_AV_RC_CONN_MASK 0x20
|
||||
|
||||
#define BTA_AV_CA_IMG_HDL_UTF16_LEN 16 /* Cover Art image handle in utf-16 format, fixed to 16 */
|
||||
|
||||
#define BTA_AV_CA_SRM_DISABLE 0x00
|
||||
#define BTA_AV_CA_SRM_ENABLE_REQ 0x01
|
||||
#define BTA_AV_CA_SRM_WAIT 0x02
|
||||
#define BTA_AV_CA_SRM_ENABLE 0x03
|
||||
|
||||
/* type for AV RCP control block */
|
||||
/* index to this control block is the rc handle */
|
||||
typedef struct {
|
||||
@ -491,6 +567,14 @@ typedef struct {
|
||||
tBTA_AV_FEAT peer_features; /* peer features mask */
|
||||
UINT16 peer_ct_features;
|
||||
UINT16 peer_tg_features;
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
UINT16 cover_art_l2cap_psm; /* OBEX over L2CAP PSM */
|
||||
UINT16 cover_art_goep_hdl; /* Cover Art client GOEP connection handle */
|
||||
UINT8 cover_art_state; /* Cover Art client state machine */
|
||||
UINT32 cover_art_cid; /* Cover Art client connection id */
|
||||
UINT16 cover_art_max_tx; /* max packet length peer device can receive */
|
||||
UINT16 cover_art_max_rx; /* max packet length we can receive */
|
||||
#endif
|
||||
} tBTA_AV_RCB;
|
||||
#define BTA_AV_NUM_RCB (BTA_AV_NUM_STRS + 2)
|
||||
|
||||
@ -705,6 +789,19 @@ extern void bta_av_do_disc_vdp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_vdp_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_reg_vdp (tAVDT_CS *p_cs, char *p_service_name, void *p_data);
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
extern void bta_av_ca_api_open(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_api_close(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_api_get(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_response(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_response_final(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_goep_connect(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_goep_disconnect(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_force_disconnect(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_sm_execute(tBTA_AV_RCB *p_rcb, UINT16 event, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ca_reset(tBTA_AV_RCB *p_rcb);
|
||||
#endif
|
||||
|
||||
#endif ///BTA_AV_INCLUDED == TRUE
|
||||
|
||||
#endif /* BTA_AV_INT_H */
|
||||
|
@ -2385,7 +2385,12 @@ void bta_dm_queue_search (tBTA_DM_MSG *p_data)
|
||||
osi_free(bta_dm_search_cb.p_search_queue);
|
||||
}
|
||||
|
||||
bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
|
||||
tBTA_DM_API_SEARCH *search_queue = osi_malloc(sizeof(tBTA_DM_API_SEARCH));
|
||||
if (search_queue == NULL) {
|
||||
APPL_TRACE_ERROR("%s: couldn't allocate memory", __func__);
|
||||
return;
|
||||
}
|
||||
bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *) search_queue;
|
||||
memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_SEARCH));
|
||||
|
||||
}
|
||||
@ -2406,7 +2411,12 @@ void bta_dm_queue_disc (tBTA_DM_MSG *p_data)
|
||||
osi_free(bta_dm_search_cb.p_search_queue);
|
||||
}
|
||||
|
||||
bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
|
||||
tBTA_DM_API_DISCOVER *search_queue = osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
|
||||
if (search_queue == NULL) {
|
||||
APPL_TRACE_ERROR("%s: couldn't allocate memory", __func__);
|
||||
return;
|
||||
}
|
||||
bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)search_queue;
|
||||
memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_DISCOVER));
|
||||
}
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "stack/btm_api.h"
|
||||
#include "btm_int.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "bta/utl.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
@ -1091,17 +1092,62 @@ tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info,
|
||||
if (bta_dm_di_cb.di_num < BTA_DI_NUM_MAX) {
|
||||
if (SDP_SetLocalDiRecord((tSDP_DI_RECORD *)p_device_info, p_handle) == SDP_SUCCESS) {
|
||||
if (!p_device_info->primary_record) {
|
||||
bta_dm_di_cb.di_handle[bta_dm_di_cb.di_num] = *p_handle;
|
||||
bta_dm_di_cb.di_num ++;
|
||||
for (uint8_t i = 1; i < BTA_DI_NUM_MAX; i++) {
|
||||
if (!bta_dm_di_cb.di_handle[i]) {
|
||||
bta_dm_di_cb.di_handle[i] = *p_handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bta_dm_di_cb.di_num++;
|
||||
} else if (!bta_dm_di_cb.di_handle[0]) {
|
||||
bta_dm_di_cb.di_handle[0] = *p_handle;
|
||||
bta_dm_di_cb.di_num++;
|
||||
} else {
|
||||
assert(bta_dm_di_cb.di_handle[0] == (*p_handle));
|
||||
}
|
||||
|
||||
if (!bta_dm_di_cb.uuid_added) {
|
||||
bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION);
|
||||
bta_dm_di_cb.uuid_added = TRUE;
|
||||
}
|
||||
|
||||
status = BTA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmRemoveLocalDiRecord
|
||||
**
|
||||
** Description This function removes a DI record from the local SDP database.
|
||||
**
|
||||
** Returns BTA_SUCCESS if record is removed successfully, otherwise error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_STATUS BTA_DmRemoveLocalDiRecord(UINT32 handle)
|
||||
{
|
||||
tBTA_STATUS status = BTA_FAILURE;
|
||||
|
||||
for (uint8_t i = 0; i < BTA_DI_NUM_MAX; i++) {
|
||||
if (bta_dm_di_cb.di_handle[i] == handle) {
|
||||
if (SDP_DeleteRecord(handle)) {
|
||||
bta_dm_di_cb.di_handle[i] = 0;
|
||||
bta_dm_di_cb.di_num--;
|
||||
status = BTA_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bta_dm_di_cb.di_num == 0 && bta_dm_di_cb.uuid_added) {
|
||||
bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -1590,6 +1590,7 @@ typedef struct {
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
tSDP_DISCOVERY_DB *p_di_db; /* pointer to the DI discovery database */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
BOOLEAN uuid_added;
|
||||
UINT8 di_num; /* total local DI record number */
|
||||
UINT32 di_handle[BTA_DI_NUM_MAX]; /* local DI record handle, the first one is primary record */
|
||||
} tBTA_DM_DI_CB;
|
||||
|
@ -2190,6 +2190,17 @@ extern UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr );
|
||||
*******************************************************************************/
|
||||
extern tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info,
|
||||
UINT32 *p_handle );
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmRemoveLocalDiRecord
|
||||
**
|
||||
** Description This function removes a DI record from the local SDP database.
|
||||
**
|
||||
** Returns BTA_SUCCESS if record is removed successfully, otherwise error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_STATUS BTA_DmRemoveLocalDiRecord(UINT32 handle);
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -43,14 +43,14 @@
|
||||
#define BTA_AV_FAIL_STREAM 3 /* stream connection failed */
|
||||
#define BTA_AV_FAIL_RESOURCES 4 /* no resources */
|
||||
#define BTA_AV_FAIL_ROLE 5 /* failed due to role management related issues */
|
||||
#define BTA_AV_FAIL_GET_CAP 6 /* get capability failed due to no SEP availale on the peer */
|
||||
#define BTA_AV_FAIL_GET_CAP 6 /* get capability failed due to no SEP available on the peer */
|
||||
|
||||
typedef UINT8 tBTA_AV_STATUS;
|
||||
|
||||
/* AV features masks */
|
||||
#define BTA_AV_FEAT_RCTG 0x0001 /* remote control target */
|
||||
#define BTA_AV_FEAT_RCCT 0x0002 /* remote control controller */
|
||||
#define BTA_AV_FEAT_PROTECT 0x0004 /* streaming media contect protection */
|
||||
#define BTA_AV_FEAT_PROTECT 0x0004 /* streaming media context protection */
|
||||
#define BTA_AV_FEAT_VENDOR 0x0008 /* remote control vendor dependent commands */
|
||||
#define BTA_AV_FEAT_REPORT 0x0020 /* use reporting service for VDP */
|
||||
#define BTA_AV_FEAT_METADATA 0x0040 /* remote control Metadata Transfer command/response */
|
||||
@ -60,6 +60,7 @@ typedef UINT8 tBTA_AV_STATUS;
|
||||
#define BTA_AV_FEAT_ADV_CTRL 0x0200 /* remote control Advanced Control command/response */
|
||||
#define BTA_AV_FEAT_DELAY_RPT 0x0400 /* allow delay reporting */
|
||||
#define BTA_AV_FEAT_ACP_START 0x0800 /* start stream when 2nd SNK was accepted */
|
||||
#define BTA_AV_FEAT_COVER_ART 0x1000 /* remote control target cover art */
|
||||
|
||||
/* Internal features */
|
||||
#define BTA_AV_FEAT_NO_SCO_SSPD 0x8000 /* Do not suspend av streaming as to AG events(SCO or Call) */
|
||||
@ -107,6 +108,7 @@ typedef UINT8 tBTA_AV_HNDL;
|
||||
#define BTA_AV_MAX_VDP_MTU 1008
|
||||
#endif
|
||||
|
||||
#define BTA_AV_CA_IMG_HDL_LEN 7 /* Cover Art image handle len, fixed to 7 */
|
||||
|
||||
/* codec type */
|
||||
#define BTA_AV_CODEC_SBC A2D_MEDIA_CT_SBC /* SBC media codec type */
|
||||
@ -224,6 +226,12 @@ typedef UINT8 tBTA_AV_CODE;
|
||||
|
||||
typedef UINT8 tBTA_AV_ERR;
|
||||
|
||||
/* type codes for BTA_AV_API_CA_GET */
|
||||
#define BTA_AV_CA_GET_IMAGE_PROPERTIES 0x01
|
||||
#define BTA_AV_CA_GET_IMAGE 0x02
|
||||
#define BTA_AV_CA_GET_LINKED_THUMBNAIL 0x03
|
||||
|
||||
typedef UINT8 tBTA_AV_GET_TYPE;
|
||||
|
||||
/* AV callback events */
|
||||
#define BTA_AV_ENABLE_EVT 0 /* AV enabled */
|
||||
@ -253,8 +261,13 @@ typedef UINT8 tBTA_AV_ERR;
|
||||
#define BTA_AV_SET_DELAY_VALUE_EVT 22 /* set delay reporting value */
|
||||
#define BTA_AV_GET_DELAY_VALUE_EVT 23 /* get delay reporting value */
|
||||
#define BTA_AV_SNK_PSC_CFG_EVT 24 /* Protocol service capabilities. */
|
||||
|
||||
/* still keep Cover Art event here if Cover Art feature not enabled */
|
||||
#define BTA_AV_CA_STATUS_EVT 25 /* Cover Art Client status event */
|
||||
#define BTA_AV_CA_DATA_EVT 26 /* Cover Art response body data */
|
||||
|
||||
/* Max BTA event */
|
||||
#define BTA_AV_MAX_EVT 25
|
||||
#define BTA_AV_MAX_EVT 27
|
||||
|
||||
|
||||
/* function types for call-out functions */
|
||||
@ -482,6 +495,25 @@ typedef struct {
|
||||
} tBTA_AV_SNK_PSC_CFG;
|
||||
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
|
||||
/* data associated with BTA_AV_CA_STATUS_EVT */
|
||||
typedef struct {
|
||||
BOOLEAN connected; /* whether Cover Art connection is connected */
|
||||
UINT16 reason; /* connect failed or disconnect reason */
|
||||
} tBTA_AV_CA_STATUS;
|
||||
|
||||
/* data associated with BTA_AV_CA_DATA_EVT */
|
||||
typedef struct {
|
||||
UINT16 status; /* OBEX response status */
|
||||
BOOLEAN final; /* final data packet */
|
||||
UINT16 data_len; /* data len */
|
||||
UINT8 *p_data; /* point to the data in p_hdr */
|
||||
BT_HDR *p_hdr; /* after data pass to application, free this packet */
|
||||
} tBTA_AV_CA_DATA;
|
||||
|
||||
#endif
|
||||
|
||||
/* union of data associated with AV callback */
|
||||
typedef union {
|
||||
tBTA_AV_CHNL chnl;
|
||||
@ -506,6 +538,10 @@ typedef union {
|
||||
tBTA_AV_RC_FEAT rc_feat;
|
||||
tBTA_AV_DELAY delay;
|
||||
tBTA_AV_SNK_PSC_CFG psc;
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
tBTA_AV_CA_STATUS ca_status;
|
||||
tBTA_AV_CA_DATA ca_data;
|
||||
#endif
|
||||
} tBTA_AV;
|
||||
|
||||
/* union of data associated with AV Media callback */
|
||||
@ -865,6 +901,47 @@ void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
|
||||
*******************************************************************************/
|
||||
void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt);
|
||||
|
||||
#if BTA_AV_CA_INCLUDED
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvCaOpen
|
||||
**
|
||||
** Description Open a Cover Art OBEX connection to peer device. This function
|
||||
** can only be used if peer device TG support Cover Art feature and
|
||||
** AV is enabled with feature BTA_AV_FEAT_METADATA.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvCaOpen(UINT8 rc_handle, UINT16 pref_packet_len);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvCaClose
|
||||
**
|
||||
** Description Close a Cover Art OBEX connection.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvCaClose(UINT8 rc_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvCaGet
|
||||
**
|
||||
** Description Start the process to get image properties, get image or get
|
||||
** linked thumbnail. This function can only be used if Cover Art
|
||||
** OBEX connection is established.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvCaGet(UINT8 rc_handle, tBTA_AV_GET_TYPE type, UINT8 *image_handle, UINT8 *image_descriptor, UINT16 image_descriptor_len);
|
||||
|
||||
#endif /* BTA_AV_CA_INCLUDED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -41,7 +41,7 @@ typedef UINT8 tBTA_SDP_STATUS;
|
||||
/* SDP I/F callback events */
|
||||
/* events received by tBTA_SDP_DM_CBACK */
|
||||
#define BTA_SDP_ENABLE_EVT 0 /* SDP service enabled */
|
||||
#define BTA_SDP_DISENABLE_EVT 1 /* SDP service disenabled */
|
||||
#define BTA_SDP_DISABLE_EVT 1 /* SDP service disenabled */
|
||||
#define BTA_SDP_SEARCH_EVT 2 /* SDP search started */
|
||||
#define BTA_SDP_SEARCH_COMP_EVT 3 /* SDP search complete */
|
||||
#define BTA_SDP_CREATE_RECORD_USER_EVT 4 /* SDP create record complete */
|
||||
@ -67,10 +67,17 @@ typedef struct {
|
||||
int handle;
|
||||
} tBTA_SDP_CREATE_RECORD_USER;
|
||||
|
||||
/* data associated with BTA_SDP_REMOVE_RECORD_USER_EVT */
|
||||
typedef struct {
|
||||
tBTA_SDP_STATUS status;
|
||||
int handle;
|
||||
} tBTA_SDP_REMOVE_RECORD_USER;
|
||||
|
||||
typedef union {
|
||||
tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */
|
||||
tBTA_SDP_SEARCH_COMP sdp_search_comp; /* BTA_SDP_SEARCH_COMP_EVT */
|
||||
tBTA_SDP_CREATE_RECORD_USER sdp_create_record; /* BTA_SDP_CREATE_RECORD_USER_EVT */
|
||||
tBTA_SDP_REMOVE_RECORD_USER sdp_remove_record; /* BTA_SDP_REMOVE_RECORD_USER_EVT */
|
||||
} tBTA_SDP;
|
||||
|
||||
/* SDP DM Interface callback */
|
||||
@ -78,8 +85,10 @@ typedef void (tBTA_SDP_DM_CBACK)(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *use
|
||||
|
||||
/* MCE configuration structure */
|
||||
typedef struct {
|
||||
UINT16 sdp_raw_size; /* The size of p_sdp_raw_data */
|
||||
UINT16 sdp_db_size; /* The size of p_sdp_db */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
UINT8 *p_sdp_raw_data; /* The data buffer to keep raw data */
|
||||
tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
} tBTA_SDP_CFG;
|
||||
@ -108,14 +117,28 @@ extern tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback);
|
||||
**
|
||||
** Function BTA_SdpDisable
|
||||
**
|
||||
** Description Disable the SDP search I/F service.
|
||||
** Description This function is used to request a callback to perform disable
|
||||
** operation. The registered callback will be called with event
|
||||
** BTA_SDP_DISABLE_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpDisable(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpCleanup
|
||||
**
|
||||
** Description Cleanup the SDP search I/F service.
|
||||
** Free buffer for SDP configuration structure.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS if successful.
|
||||
** BTA_SDP_FAIL if internal failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpDisable(void);
|
||||
extern tBTA_SDP_STATUS BTA_SdpCleanup(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -91,7 +91,8 @@ typedef UINT16 tBTA_SYS_HW_MODULE;
|
||||
#define BTA_ID_GATTC 31 /* GATT Client */
|
||||
#define BTA_ID_GATTS 32 /* GATT Client */
|
||||
#define BTA_ID_SDP 33 /* SDP Client */
|
||||
#define BTA_ID_BLUETOOTH_MAX 34 /* last BT profile */
|
||||
#define BTA_ID_GOEPC 34 /* GOEP Client */
|
||||
#define BTA_ID_BLUETOOTH_MAX 35 /* last BT profile */
|
||||
|
||||
/* GENERIC */
|
||||
#define BTA_ID_PRM 38
|
||||
@ -142,7 +143,7 @@ typedef void (tBTA_SYS_CONN_CBACK)(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8
|
||||
typedef void (tBTA_SYS_SSR_CFG_CBACK)(UINT8 id, UINT8 app_id, UINT16 latency, UINT16 tout);
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
/* eir callback for adding/removeing UUID */
|
||||
/* eir callback for adding/removing UUID */
|
||||
typedef void (tBTA_SYS_EIR_CBACK)(tBT_UUID uuid, BOOLEAN adding);
|
||||
#endif
|
||||
|
||||
|
@ -53,6 +53,7 @@ const tBTA_SDP_ACTION bta_sdp_action[] = {
|
||||
bta_sdp_search, /* BTA_SDP_API_SEARCH_EVT */
|
||||
bta_sdp_create_record, /* BTA_SDP_API_CREATE_RECORD_USER_EVT */
|
||||
bta_sdp_remove_record, /* BTA_SDP_API_REMOVE_RECORD_USER_EVT */
|
||||
bta_sdp_disable, /* BTA_SDP_API_DISABLE_EVT */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -140,6 +140,47 @@ static void bta_create_mns_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_dip_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
UINT16 pversion = -1;
|
||||
|
||||
record->dip.hdr.type = SDP_TYPE_DIP_SERVER;
|
||||
record->dip.hdr.service_name_length = 0;
|
||||
record->dip.hdr.service_name = NULL;
|
||||
record->dip.hdr.rfcomm_channel_number = 0;
|
||||
record->dip.hdr.l2cap_psm = -1;
|
||||
record->dip.hdr.profile_version = 0;
|
||||
|
||||
p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID);
|
||||
if (p_attr) {
|
||||
record->dip.vendor = p_attr->attr_value.v.u16;
|
||||
}
|
||||
|
||||
p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID_SOURCE);
|
||||
if (p_attr) {
|
||||
record->dip.vendor_id_source = p_attr->attr_value.v.u16;
|
||||
}
|
||||
p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_ID);
|
||||
if (p_attr) {
|
||||
record->dip.product = p_attr->attr_value.v.u16;
|
||||
}
|
||||
|
||||
p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_VERSION);
|
||||
if (p_attr) {
|
||||
record->dip.version = p_attr->attr_value.v.u16;
|
||||
}
|
||||
|
||||
p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRIMARY_RECORD);
|
||||
if (p_attr) {
|
||||
record->dip.primary_record = (BOOLEAN)p_attr->attr_value.v.u8;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PNP_INFORMATION, &pversion)) {
|
||||
record->dip.hdr.profile_version = pversion;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
@ -354,29 +395,29 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
|
||||
record->hdr.type = SDP_TYPE_RAW;
|
||||
record->hdr.service_name_length = 0;
|
||||
record->hdr.service_name = NULL;
|
||||
record->hdr.rfcomm_channel_number = -1;
|
||||
record->hdr.l2cap_psm = -1;
|
||||
record->hdr.profile_version = -1;
|
||||
record->raw.hdr.type = SDP_TYPE_RAW;
|
||||
record->raw.hdr.service_name_length = 0;
|
||||
record->raw.hdr.service_name = NULL;
|
||||
record->raw.hdr.rfcomm_channel_number = -1;
|
||||
record->raw.hdr.l2cap_psm = -1;
|
||||
record->raw.hdr.profile_version = -1;
|
||||
|
||||
/* Try to extract a service name */
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
record->raw.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->raw.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
record->raw.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
|
||||
/* Try to extract an RFCOMM channel */
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->pse.hdr.rfcomm_channel_number = pe.params[0];
|
||||
record->raw.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
|
||||
record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
|
||||
record->raw.hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_used;
|
||||
record->raw.hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
|
||||
}
|
||||
|
||||
|
||||
@ -415,7 +456,10 @@ static void bta_sdp_search_cback(UINT16 result, void *user_data)
|
||||
/* generate the matching record data pointer */
|
||||
if (p_rec != NULL) {
|
||||
status = BTA_SDP_SUCCESS;
|
||||
if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) {
|
||||
if (uuid->uu.uuid16 == UUID_SERVCLASS_PNP_INFORMATION) {
|
||||
APPL_TRACE_DEBUG("%s() - found DIP uuid\n", __func__);
|
||||
bta_create_dip_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid\n", __func__);
|
||||
bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) {
|
||||
@ -526,6 +570,10 @@ void bta_sdp_search(tBTA_SDP_MSG *p_data)
|
||||
SDP_InitDiscoveryDb (p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
|
||||
bta_sdp_search_uuid, 0, NULL);
|
||||
|
||||
/* tell SDP to keep the raw data */
|
||||
p_bta_sdp_cfg->p_sdp_db->raw_size = p_bta_sdp_cfg->sdp_raw_size;
|
||||
p_bta_sdp_cfg->p_sdp_db->raw_data = p_bta_sdp_cfg->p_sdp_raw_data;
|
||||
|
||||
if (!SDP_ServiceSearchAttributeRequest2(p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db,
|
||||
bta_sdp_search_cback, (void *)bta_sdp_search_uuid)) {
|
||||
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
|
||||
@ -558,7 +606,7 @@ void bta_sdp_create_record(tBTA_SDP_MSG *p_data)
|
||||
APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event);
|
||||
tBTA_SDP_CREATE_RECORD_USER bta_sdp = {0};
|
||||
bta_sdp.status = BTA_SDP_SUCCESS;
|
||||
bta_sdp.handle = (int)p_data->record.user_data;
|
||||
bta_sdp.handle = -1;
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, (tBTA_SDP *)&bta_sdp, p_data->record.user_data);
|
||||
}
|
||||
@ -576,10 +624,30 @@ void bta_sdp_create_record(tBTA_SDP_MSG *p_data)
|
||||
void bta_sdp_remove_record(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event);
|
||||
tBTA_SDP_REMOVE_RECORD_USER bta_sdp;
|
||||
bta_sdp.status = BTA_SDP_SUCCESS;
|
||||
bta_sdp.handle = -1;
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, (tBTA_SDP *)&bta_sdp, p_data->record.user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_disable
|
||||
**
|
||||
** Description Removes an SDP record
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_disable(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s()\n", __func__);
|
||||
tBTA_SDP bta_sdp;
|
||||
bta_sdp.status = BTA_SDP_SUCCESS;
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, &bta_sdp, p_data->record.user_data);
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_DISABLE_EVT, &bta_sdp, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,9 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
|
||||
#if BTA_DYNAMIC_MEMORY == TRUE
|
||||
/* Malloc buffer for SDP configuration structure */
|
||||
p_bta_sdp_cfg->p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(p_bta_sdp_cfg->sdp_db_size);
|
||||
if (p_bta_sdp_cfg->p_sdp_db == NULL) {
|
||||
p_bta_sdp_cfg->p_sdp_raw_data = (UINT8 *)osi_malloc(p_bta_sdp_cfg->sdp_raw_size);
|
||||
if (p_bta_sdp_cfg->p_sdp_db == NULL || p_bta_sdp_cfg->p_sdp_raw_data == NULL) {
|
||||
BTA_SdpCleanup();
|
||||
return BTA_SDP_FAILURE;
|
||||
}
|
||||
#endif
|
||||
@ -101,15 +103,34 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpDisable(void)
|
||||
{
|
||||
BT_HDR *p_buf = NULL;
|
||||
tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
|
||||
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_SDP_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
status = BTA_SDP_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
tBTA_SDP_STATUS BTA_SdpCleanup(void)
|
||||
{
|
||||
bta_sys_deregister(BTA_ID_SDP);
|
||||
#if BTA_DYNAMIC_MEMORY == TRUE
|
||||
/* Free buffer for SDP configuration structure */
|
||||
if (p_bta_sdp_cfg->p_sdp_db) {
|
||||
osi_free(p_bta_sdp_cfg->p_sdp_db);
|
||||
p_bta_sdp_cfg->p_sdp_db = NULL;
|
||||
}
|
||||
|
||||
if (p_bta_sdp_cfg->p_sdp_raw_data) {
|
||||
osi_free(p_bta_sdp_cfg->p_sdp_raw_data);
|
||||
p_bta_sdp_cfg->p_sdp_raw_data = NULL;
|
||||
}
|
||||
#endif
|
||||
return (status);
|
||||
return BTA_SDP_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -30,16 +30,24 @@
|
||||
#define BTA_SDP_DB_SIZE 1500
|
||||
#endif
|
||||
|
||||
#ifndef BTA_SDP_RAW_DATA_SIZE
|
||||
#define BTA_SDP_RAW_DATA_SIZE 1024
|
||||
#endif
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
static UINT8 bta_sdp_raw_data[BTA_SDP_RAW_DATA_SIZE];
|
||||
static UINT8 __attribute__ ((aligned(4))) bta_sdp_db_data[BTA_SDP_DB_SIZE];
|
||||
#endif
|
||||
|
||||
/* SDP configuration structure */
|
||||
tBTA_SDP_CFG bta_sdp_cfg = {
|
||||
BTA_SDP_RAW_DATA_SIZE,
|
||||
BTA_SDP_DB_SIZE,
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
bta_sdp_raw_data,
|
||||
(tSDP_DISCOVERY_DB *)bta_sdp_db_data /* The data buffer to keep SDP database */
|
||||
#else
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
@ -42,6 +42,7 @@ enum {
|
||||
BTA_SDP_API_SEARCH_EVT,
|
||||
BTA_SDP_API_CREATE_RECORD_USER_EVT,
|
||||
BTA_SDP_API_REMOVE_RECORD_USER_EVT,
|
||||
BTA_SDP_API_DISABLE_EVT,
|
||||
BTA_SDP_MAX_INT_EVT
|
||||
};
|
||||
|
||||
@ -105,6 +106,7 @@ extern void bta_sdp_enable (tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_search (tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_create_record(tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_remove_record(tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_disable(tBTA_SDP_MSG *p_data);
|
||||
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
#if BTC_AV_INCLUDED
|
||||
|
||||
// global variable to inidcate avrc is initialized with a2dp
|
||||
// global variable to indicate avrc is initialized with a2dp
|
||||
bool g_av_with_rc;
|
||||
// global variable to indicate a2dp is initialized
|
||||
bool g_a2dp_on_init;
|
||||
@ -127,6 +127,8 @@ static btc_av_cb_t *btc_av_cb_ptr = NULL;
|
||||
case BTA_AV_META_MSG_EVT: \
|
||||
case BTA_AV_RC_FEAT_EVT: \
|
||||
case BTA_AV_REMOTE_RSP_EVT: \
|
||||
case BTA_AV_CA_STATUS_EVT: \
|
||||
case BTA_AV_CA_DATA_EVT: \
|
||||
{ \
|
||||
btc_rc_handler(e, d);\
|
||||
}break; \
|
||||
@ -382,6 +384,8 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data)
|
||||
case BTA_AV_META_MSG_EVT:
|
||||
case BTA_AV_RC_FEAT_EVT:
|
||||
case BTA_AV_REMOTE_RSP_EVT:
|
||||
case BTA_AV_CA_STATUS_EVT:
|
||||
case BTA_AV_CA_DATA_EVT:
|
||||
btc_rc_handler(event, (tBTA_AV *)p_data);
|
||||
break;
|
||||
|
||||
@ -1355,7 +1359,7 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
|
||||
/* send a command to BT Media Task */
|
||||
btc_a2dp_sink_reset_decoder((UINT8 *)p_data);
|
||||
|
||||
/* currently only supportes SBC */
|
||||
/* currently only supports SBC */
|
||||
a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
|
||||
if (a2d_status == A2D_SUCCESS) {
|
||||
btc_msg_t msg;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -40,7 +40,7 @@ static void btc_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 c
|
||||
** Static variables
|
||||
******************************************************************************/
|
||||
|
||||
/* flag indicating wheter TG/CT is initialized */
|
||||
/* flag indicating whether TG/CT is initialized */
|
||||
static uint32_t s_rc_ct_init;
|
||||
static uint32_t s_rc_tg_init;
|
||||
|
||||
@ -157,6 +157,11 @@ bool btc_avrc_ct_rn_evt_supported(uint8_t event_id)
|
||||
true : false;
|
||||
}
|
||||
|
||||
bool btc_avrc_ct_check_cover_art_support(void)
|
||||
{
|
||||
return (btc_rc_cb.rc_features & BTA_AV_FEAT_COVER_ART);
|
||||
}
|
||||
|
||||
bool btc_avrc_tg_init_p(void)
|
||||
{
|
||||
return (s_rc_tg_init == BTC_RC_TG_INIT_MAGIC);
|
||||
@ -181,6 +186,52 @@ bool btc_avrc_ct_connected_p(void)
|
||||
(btc_rc_cb.rc_features & BTA_AV_FEAT_RCTG);
|
||||
}
|
||||
|
||||
void btc_avrc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
btc_avrc_args_t *dst = (btc_avrc_args_t *)p_dest;
|
||||
btc_avrc_args_t *src = (btc_avrc_args_t *)p_src;
|
||||
size_t len;
|
||||
|
||||
switch (msg->act) {
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
case BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_EVT:
|
||||
len = src->ca_get_img.image_descriptor_len;
|
||||
dst->ca_get_img.image_descriptor = (uint8_t *)osi_malloc(len);
|
||||
if (dst->ca_get_img.image_descriptor) {
|
||||
memcpy(dst->ca_get_img.image_descriptor, src->ca_get_img.image_descriptor, len);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __FUNCTION__, msg->act);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
BTC_TRACE_DEBUG("%s Unhandled deep copy %d\n", __FUNCTION__, msg->act);
|
||||
UNUSED(dst);
|
||||
UNUSED(src);
|
||||
UNUSED(len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_avrc_arg_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
btc_avrc_args_t *arg = (btc_avrc_args_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
case BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_EVT:
|
||||
if (arg->ca_get_img.image_descriptor) {
|
||||
osi_free(arg->ca_get_img.image_descriptor);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
BTC_TRACE_DEBUG("%s Unhandled deep free %d\n", __FUNCTION__, msg->act);
|
||||
UNUSED(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_avrc_tg_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
btc_avrc_tg_args_t *dst = (btc_avrc_tg_args_t *) p_dest;
|
||||
@ -499,14 +550,28 @@ static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
|
||||
// clean up the state
|
||||
btc_rc_cb.rc_handle = 0;
|
||||
btc_rc_cb.rc_connected = FALSE;
|
||||
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
bool cover_art_connected = btc_rc_cb.rc_cover_art_connected;
|
||||
btc_rc_cb.rc_cover_art_connected = FALSE;
|
||||
#endif
|
||||
btc_rc_cb.rc_features = 0;
|
||||
btc_rc_cb.rc_ct_features = 0;
|
||||
btc_rc_cb.rc_tg_features = 0;
|
||||
memset(btc_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
|
||||
memset(btc_rc_cb.rc_ntf, 0, sizeof(btc_rc_cb.rc_ntf));
|
||||
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
/* report connection state */
|
||||
if (cover_art_connected) {
|
||||
/* if rc disconnect, cover art disconnect too */
|
||||
esp_avrc_ct_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t));
|
||||
param.cover_art_state.state = ESP_AVRC_COVER_ART_DISCONNECTED;
|
||||
param.cover_art_state.reason = BT_STATUS_FAIL;
|
||||
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_COVER_ART_STATE_EVT, ¶m);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc_features & BTA_AV_FEAT_RCTG) {
|
||||
esp_avrc_ct_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t));
|
||||
@ -751,7 +816,7 @@ static void btc_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 c
|
||||
|
||||
btc_rc_cb.rc_ntf[event_id - 1].registered = TRUE;
|
||||
btc_rc_cb.rc_ntf[event_id - 1].label = label;
|
||||
BTC_TRACE_EVENT("%s: New registerd notification: event_id:0x%x, label:0x%x",
|
||||
BTC_TRACE_EVENT("%s: New registered notification: event_id:0x%x, label:0x%x",
|
||||
__FUNCTION__, event_id, label);
|
||||
|
||||
// set up callback
|
||||
@ -947,7 +1012,7 @@ void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
|
||||
memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t));
|
||||
param.conn_stat.connected = true;
|
||||
memcpy(param.conn_stat.remote_bda, btc_rc_cb.rc_addr, sizeof(esp_bd_addr_t));
|
||||
btc_avrc_tg_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, ¶m);
|
||||
btc_avrc_tg_cb_to_app(ESP_AVRC_TG_CONNECTION_STATE_EVT, ¶m);
|
||||
}
|
||||
} while (0);
|
||||
btc_rc_cb.rc_features = p_data->rc_feat.peer_features;
|
||||
@ -967,6 +1032,36 @@ void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
|
||||
handle_rc_passthrough_cmd(&p_data->remote_cmd);
|
||||
}
|
||||
break;
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
case BTA_AV_CA_STATUS_EVT: {
|
||||
btc_rc_cb.rc_cover_art_connected = p_data->ca_status.connected;
|
||||
esp_avrc_ct_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t));
|
||||
if (p_data->ca_status.connected) {
|
||||
param.cover_art_state.state = ESP_AVRC_COVER_ART_CONNECTED;
|
||||
}
|
||||
else {
|
||||
param.cover_art_state.state = ESP_AVRC_COVER_ART_DISCONNECTED;
|
||||
}
|
||||
param.cover_art_state.reason = p_data->ca_status.reason;
|
||||
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_COVER_ART_STATE_EVT, ¶m);
|
||||
}
|
||||
break;
|
||||
case BTA_AV_CA_DATA_EVT: {
|
||||
esp_avrc_ct_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t));
|
||||
param.cover_art_data.status = p_data->ca_data.status;
|
||||
param.cover_art_data.final = p_data->ca_data.final;
|
||||
param.cover_art_data.data_len = p_data->ca_data.data_len;
|
||||
param.cover_art_data.p_data = p_data->ca_data.p_data;
|
||||
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_COVER_ART_DATA_EVT, ¶m);
|
||||
/* free the data packet now */
|
||||
if (p_data->ca_data.p_hdr != NULL) {
|
||||
osi_free(p_data->ca_data.p_hdr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* BTC_AV_CA_INCLUDED */
|
||||
default:
|
||||
BTC_TRACE_DEBUG("Unhandled RC event : 0x%x", event);
|
||||
}
|
||||
@ -1041,7 +1136,7 @@ static void btc_avrc_ct_deinit(void)
|
||||
BTC_TRACE_API("## %s ##", __FUNCTION__);
|
||||
|
||||
if (g_a2dp_on_deinit) {
|
||||
BTC_TRACE_WARNING("A2DP already deinit, AVRC CT shuold deinit in advance of A2DP !!!");
|
||||
BTC_TRACE_WARNING("A2DP already deinit, AVRC CT should deinit in advance of A2DP !!!");
|
||||
}
|
||||
|
||||
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
|
||||
@ -1255,7 +1350,7 @@ static bt_status_t btc_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code
|
||||
BTA_AvRemoteCmd(btc_rc_cb.rc_handle, tl,
|
||||
(tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
BTC_TRACE_API("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
|
||||
BTC_TRACE_API("%s: successfully sent passthrough command to BTA", __FUNCTION__);
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
@ -1267,6 +1362,64 @@ static bt_status_t btc_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code
|
||||
return status;
|
||||
}
|
||||
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
|
||||
static void btc_avrc_ct_cover_art_connect(UINT16 mtu)
|
||||
{
|
||||
if (!btc_rc_cb.rc_cover_art_connected) {
|
||||
BTA_AvCaOpen(btc_rc_cb.rc_handle, mtu);
|
||||
}
|
||||
else {
|
||||
BTC_TRACE_WARNING("%s: cover art already connected", __FUNCTION__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void btc_avrc_ct_cover_art_disconnect(void)
|
||||
{
|
||||
if (btc_rc_cb.rc_cover_art_connected) {
|
||||
BTA_AvCaClose(btc_rc_cb.rc_handle);
|
||||
}
|
||||
else {
|
||||
BTC_TRACE_WARNING("%s: cover art not connected", __FUNCTION__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void btc_avrc_ct_cover_art_get_image_properties(UINT8 *image_handle)
|
||||
{
|
||||
if (btc_rc_cb.rc_cover_art_connected) {
|
||||
BTA_AvCaGet(btc_rc_cb.rc_handle, BTA_AV_CA_GET_IMAGE_PROPERTIES, image_handle, NULL, 0);
|
||||
}
|
||||
else {
|
||||
BTC_TRACE_WARNING("%s: cover art not connected", __FUNCTION__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void btc_avrc_ct_cover_art_get_image(UINT8 *image_handle, UINT8 *image_descriptor, UINT16 image_descriptor_len)
|
||||
{
|
||||
if (btc_rc_cb.rc_cover_art_connected) {
|
||||
BTA_AvCaGet(btc_rc_cb.rc_handle, BTA_AV_CA_GET_IMAGE, image_handle, image_descriptor, image_descriptor_len);
|
||||
}
|
||||
else {
|
||||
BTC_TRACE_WARNING("%s: cover art not connected", __FUNCTION__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void btc_avrc_ct_cover_art_get_linked_thumbnail(UINT8 *image_handle)
|
||||
{
|
||||
if (btc_rc_cb.rc_cover_art_connected) {
|
||||
BTA_AvCaGet(btc_rc_cb.rc_handle, BTA_AV_CA_GET_LINKED_THUMBNAIL, image_handle, NULL, 0);
|
||||
}
|
||||
else {
|
||||
BTC_TRACE_WARNING("%s: cover art not connected", __FUNCTION__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* BTC_AV_CA_INCLUDED */
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -1298,7 +1451,7 @@ static void btc_avrc_tg_init(void)
|
||||
}
|
||||
|
||||
if (g_a2dp_on_init) {
|
||||
BTC_TRACE_WARNING("AVRC Taget is expected to be initialized in advance of A2DP !!!");
|
||||
BTC_TRACE_WARNING("AVRC Target is expected to be initialized in advance of A2DP !!!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1320,7 +1473,7 @@ static void btc_avrc_tg_deinit(void)
|
||||
BTC_TRACE_API("## %s ##", __FUNCTION__);
|
||||
|
||||
if (g_a2dp_on_deinit) {
|
||||
BTC_TRACE_WARNING("A2DP already deinit, AVRC TG shuold deinit in advance of A2DP !!!");
|
||||
BTC_TRACE_WARNING("A2DP already deinit, AVRC TG should deinit in advance of A2DP !!!");
|
||||
}
|
||||
|
||||
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
|
||||
@ -1418,6 +1571,28 @@ void btc_avrc_ct_call_handler(btc_msg_t *msg)
|
||||
btc_avrc_ct_send_set_absolute_volume_cmd(arg->set_abs_vol_cmd.tl, arg->set_abs_vol_cmd.volume);
|
||||
break;
|
||||
}
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
case BTC_AVRC_CT_API_COVER_ART_CONNECT_EVT: {
|
||||
btc_avrc_ct_cover_art_connect(arg->ca_conn.mtu);
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_CT_API_COVER_ART_DISCONNECT_EVT: {
|
||||
btc_avrc_ct_cover_art_disconnect();
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_PROPERTIES_EVT: {
|
||||
btc_avrc_ct_cover_art_get_image_properties(arg->ca_get_img_prop.image_handle);
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_EVT: {
|
||||
btc_avrc_ct_cover_art_get_image(arg->ca_get_img.image_handle, arg->ca_get_img.image_descriptor, arg->ca_get_img.image_descriptor_len);
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_CT_API_COVER_ART_GET_LINKED_THUMBNAIL_EVT: {
|
||||
btc_avrc_ct_cover_art_get_linked_thumbnail(arg->ca_get_lk_thn.image_handle);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
BTC_TRACE_WARNING("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -469,7 +469,7 @@ static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gat
|
||||
if(gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_16 &&
|
||||
gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_32 &&
|
||||
gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_128) {
|
||||
BTC_TRACE_ERROR("%s, The Charateristic uuid length = %d is invalid", __func__,\
|
||||
BTC_TRACE_ERROR("%s, The Characteristic uuid length = %d is invalid", __func__,\
|
||||
gatts_attr_db[i+1].att_desc.uuid_length);
|
||||
return ESP_GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
@ -481,7 +481,7 @@ static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gat
|
||||
uuid == ESP_GATT_UUID_CHAR_SRVR_CONFIG || uuid == ESP_GATT_UUID_CHAR_PRESENT_FORMAT ||
|
||||
uuid == ESP_GATT_UUID_CHAR_AGG_FORMAT || uuid == ESP_GATT_UUID_CHAR_VALID_RANGE ||
|
||||
uuid == ESP_GATT_UUID_EXT_RPT_REF_DESCR || uuid == ESP_GATT_UUID_RPT_REF_DESCR) {
|
||||
BTC_TRACE_ERROR("%s, The charateristic value uuid = %d is invalid", __func__, uuid);
|
||||
BTC_TRACE_ERROR("%s, The characteristic value uuid = %d is invalid", __func__, uuid);
|
||||
return ESP_GATT_INVALID_PDU;
|
||||
}
|
||||
}
|
||||
@ -694,6 +694,7 @@ void btc_gatts_call_handler(btc_msg_t *msg)
|
||||
}
|
||||
|
||||
param.rsp.status = 0;
|
||||
param.rsp.conn_id = BTC_GATT_GET_CONN_ID(arg->send_rsp.conn_id);
|
||||
btc_gatts_cb_to_app(ESP_GATTS_RESPONSE_EVT, BTC_GATT_GET_GATT_IF(arg->send_rsp.conn_id), ¶m);
|
||||
break;
|
||||
}
|
||||
|
@ -34,39 +34,32 @@ typedef enum {
|
||||
SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server
|
||||
SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client
|
||||
SDP_TYPE_OPP_SERVER, // Object Push Profile
|
||||
SDP_TYPE_SAP_SERVER // SIM Access Profile
|
||||
SDP_TYPE_SAP_SERVER, // SIM Access Profile
|
||||
SDP_TYPE_DIP_SERVER, // Device Identification Profile
|
||||
} bluetooth_sdp_types;
|
||||
|
||||
typedef struct _bluetooth_sdp_hdr {
|
||||
bluetooth_sdp_types type;
|
||||
esp_bt_uuid_t uuid;
|
||||
uint32_t service_name_length;
|
||||
char *service_name;
|
||||
int32_t rfcomm_channel_number;
|
||||
int32_t l2cap_psm;
|
||||
int32_t profile_version;
|
||||
} bluetooth_sdp_hdr;
|
||||
|
||||
/**
|
||||
* Some signals need additional pointers, hence we introduce a
|
||||
* generic way to handle these pointers.
|
||||
*/
|
||||
typedef struct _bluetooth_sdp_hdr_overlay {
|
||||
bluetooth_sdp_types type;
|
||||
esp_bt_uuid_t bt_uuid;
|
||||
esp_bt_uuid_t uuid;
|
||||
uint32_t service_name_length;
|
||||
char *service_name;
|
||||
int32_t rfcomm_channel_number;
|
||||
int32_t l2cap_psm;
|
||||
int32_t profile_version;
|
||||
|
||||
// User pointers, only used for some signals - see bluetooth_sdp_ops_record
|
||||
int user1_ptr_len;
|
||||
uint8_t *user1_ptr;
|
||||
int user2_ptr_len;
|
||||
uint8_t *user2_ptr;
|
||||
int user2_ptr_len; // not used
|
||||
uint8_t *user2_ptr; // not used
|
||||
} bluetooth_sdp_hdr_overlay;
|
||||
|
||||
typedef struct _bluetooth_sdp_raw_record {
|
||||
bluetooth_sdp_hdr_overlay hdr;
|
||||
} bluetooth_sdp_raw_record;
|
||||
|
||||
typedef struct _bluetooth_sdp_mas_record {
|
||||
bluetooth_sdp_hdr_overlay hdr;
|
||||
uint32_t mas_instance_id;
|
||||
@ -99,14 +92,25 @@ typedef struct _bluetooth_sdp_sap_record {
|
||||
bluetooth_sdp_hdr_overlay hdr;
|
||||
} bluetooth_sdp_sap_record;
|
||||
|
||||
typedef struct _bluetooth_sdp_dip_record {
|
||||
bluetooth_sdp_hdr_overlay hdr;
|
||||
uint16_t vendor;
|
||||
uint16_t vendor_id_source;
|
||||
uint16_t product;
|
||||
uint16_t version;
|
||||
bool primary_record;
|
||||
} bluetooth_sdp_dip_record;
|
||||
|
||||
typedef union {
|
||||
bluetooth_sdp_hdr_overlay hdr;
|
||||
bluetooth_sdp_raw_record raw;
|
||||
bluetooth_sdp_mas_record mas;
|
||||
bluetooth_sdp_mns_record mns;
|
||||
bluetooth_sdp_pse_record pse;
|
||||
bluetooth_sdp_pce_record pce;
|
||||
bluetooth_sdp_ops_record ops;
|
||||
bluetooth_sdp_sap_record sap;
|
||||
bluetooth_sdp_dip_record dip;
|
||||
} bluetooth_sdp_record;
|
||||
|
||||
#endif /* __BT_SDP_H__ */
|
||||
|
@ -39,7 +39,14 @@ typedef enum {
|
||||
BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT,
|
||||
BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT,
|
||||
BTC_AVRC_CTRL_API_SND_SET_PLAYER_SETTING_EVT,
|
||||
BTC_AVRC_CTRL_API_SND_SET_ABSOLUTE_VOLUME_EVT
|
||||
BTC_AVRC_CTRL_API_SND_SET_ABSOLUTE_VOLUME_EVT,
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
BTC_AVRC_CT_API_COVER_ART_CONNECT_EVT,
|
||||
BTC_AVRC_CT_API_COVER_ART_DISCONNECT_EVT,
|
||||
BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_PROPERTIES_EVT,
|
||||
BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_EVT,
|
||||
BTC_AVRC_CT_API_COVER_ART_GET_LINKED_THUMBNAIL_EVT,
|
||||
#endif
|
||||
} btc_avrc_act_t;
|
||||
|
||||
typedef struct {
|
||||
@ -77,6 +84,28 @@ typedef struct {
|
||||
uint8_t volume;
|
||||
} set_abs_vol_cmd_t;
|
||||
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
|
||||
typedef struct {
|
||||
uint16_t mtu;
|
||||
} ca_conn_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t image_handle[7];
|
||||
} ca_get_img_prop_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t image_handle[7];
|
||||
uint16_t image_descriptor_len;
|
||||
uint8_t *image_descriptor;
|
||||
} ca_get_img_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t image_handle[7];
|
||||
} ca_get_lk_thn_t;
|
||||
|
||||
#endif /* BTC_AV_CA_INCLUDED */
|
||||
|
||||
/* btc_avrc_args_t */
|
||||
typedef union {
|
||||
pt_cmd_t pt_cmd;
|
||||
@ -85,6 +114,12 @@ typedef union {
|
||||
ps_cmd_t ps_cmd;
|
||||
get_caps_cmd_t get_caps_cmd;
|
||||
set_abs_vol_cmd_t set_abs_vol_cmd;
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
ca_conn_t ca_conn;
|
||||
ca_get_img_prop_t ca_get_img_prop;
|
||||
ca_get_img_t ca_get_img;
|
||||
ca_get_lk_thn_t ca_get_lk_thn;
|
||||
#endif
|
||||
} btc_avrc_args_t;
|
||||
|
||||
/* btc_avrc_tg_act_t */
|
||||
@ -124,6 +159,9 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN rc_connected;
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
BOOLEAN rc_cover_art_connected;
|
||||
#endif
|
||||
UINT8 rc_handle;
|
||||
tBTA_AV_FEAT rc_features;
|
||||
UINT16 rc_ct_features;
|
||||
@ -162,6 +200,8 @@ BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr);
|
||||
********************************************************************************/
|
||||
void btc_avrc_ct_call_handler(btc_msg_t *msg);
|
||||
void btc_avrc_tg_call_handler(btc_msg_t *msg);
|
||||
void btc_avrc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
void btc_avrc_arg_deep_free(btc_msg_t *msg);
|
||||
void btc_avrc_tg_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
void btc_avrc_tg_arg_deep_free(btc_msg_t *msg);
|
||||
|
||||
@ -179,6 +219,7 @@ uint16_t btc_avrc_tg_get_rn_supported_evt(void);
|
||||
bool btc_avrc_tg_check_rn_supported_evt(uint16_t evt_set);
|
||||
bool btc_avrc_tg_rn_evt_supported(uint8_t event_id);
|
||||
bool btc_avrc_ct_rn_evt_supported(uint8_t event_id);
|
||||
bool btc_avrc_ct_check_cover_art_support(void);
|
||||
|
||||
#endif ///BTC_AV_INCLUDED == TRUE
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -13,7 +13,7 @@
|
||||
#include "bta/bta_sdp_api.h"
|
||||
#include "bt_sdp.h"
|
||||
|
||||
#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE)
|
||||
#if (defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE)
|
||||
|
||||
typedef enum {
|
||||
BTC_SDP_ACT_INIT = 0,
|
||||
@ -32,9 +32,9 @@ typedef union {
|
||||
} search;
|
||||
|
||||
//BTC_SDP_ACT_CREATE_RECORD
|
||||
struct creat_record_arg {
|
||||
struct create_record_arg {
|
||||
bluetooth_sdp_record *record;
|
||||
} creat_record;
|
||||
} create_record;
|
||||
|
||||
//BTC_SDP_ACT_REMOVE_RECORD
|
||||
struct remove_record_arg {
|
||||
@ -49,5 +49,5 @@ void btc_sdp_arg_deep_free(btc_msg_t *msg);
|
||||
void btc_sdp_call_handler(btc_msg_t *msg);
|
||||
void btc_sdp_cb_handler(btc_msg_t *msg);
|
||||
|
||||
#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE
|
||||
#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE
|
||||
#endif ///__BTC_SDP_H__
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,19 @@
|
||||
#define UC_BT_A2DP_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//AVRCP
|
||||
#ifdef CONFIG_BT_AVRCP_ENABLED
|
||||
#define UC_BT_AVRCP_ENABLED TRUE
|
||||
#ifdef CONFIG_BT_AVRCP_CT_COVER_ART_ENABLED
|
||||
#define UC_BT_AVRCP_CT_COVER_ART_ENABLED CONFIG_BT_AVRCP_CT_COVER_ART_ENABLED
|
||||
#else
|
||||
#define UC_BT_AVRCP_CT_COVER_ART_ENABLED FALSE
|
||||
#endif
|
||||
#else
|
||||
#define UC_BT_AVRCP_ENABLED FALSE
|
||||
#define UC_BT_AVRCP_CT_COVER_ART_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//SPP
|
||||
#ifdef CONFIG_BT_SPP_ENABLED
|
||||
#define UC_BT_SPP_ENABLED CONFIG_BT_SPP_ENABLED
|
||||
@ -53,6 +66,13 @@
|
||||
#define UC_BT_L2CAP_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//SDP common
|
||||
#ifdef CONFIG_BT_SDP_COMMON_ENABLED
|
||||
#define UC_BT_SDP_COMMON_ENABLED CONFIG_BT_SDP_COMMON_ENABLED
|
||||
#else
|
||||
#define UC_BT_SDP_COMMON_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//HFP(AG)
|
||||
#ifdef CONFIG_BT_HFP_AG_ENABLE
|
||||
#define UC_BT_HFP_AG_ENABLED CONFIG_BT_HFP_AG_ENABLE
|
||||
@ -104,6 +124,13 @@
|
||||
#define UC_BT_ENC_KEY_SIZE_CTRL_MODE 0
|
||||
#endif
|
||||
|
||||
//GOEPC (BT)
|
||||
#ifdef CONFIG_BT_GOEPC_ENABLED
|
||||
#define UC_BT_GOEPC_ENABLED CONFIG_BT_GOEPC_ENABLED
|
||||
#else
|
||||
#define UC_BT_GOEPC_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//BLE
|
||||
#ifdef CONFIG_BT_BLE_ENABLED
|
||||
#define UC_BT_BLE_ENABLED CONFIG_BT_BLE_ENABLED
|
||||
|
@ -91,6 +91,11 @@
|
||||
#define SBC_DEC_INCLUDED TRUE
|
||||
#define BTC_AV_SRC_INCLUDED TRUE
|
||||
#define SBC_ENC_INCLUDED TRUE
|
||||
#if UC_BT_AVRCP_CT_COVER_ART_ENABLED
|
||||
#define BTA_AV_CA_INCLUDED TRUE
|
||||
#define BTC_AV_CA_INCLUDED TRUE
|
||||
#define AVRC_CA_INCLUDED TRUE
|
||||
#endif /* UC_BT_AVRCP_CT_COVER_ART_ENABLED */
|
||||
#endif /* UC_BT_A2DP_ENABLED */
|
||||
|
||||
#if (UC_BT_SPP_ENABLED == TRUE)
|
||||
@ -103,10 +108,13 @@
|
||||
#if (UC_BT_L2CAP_ENABLED == TRUE)
|
||||
#define BTA_JV_INCLUDED TRUE
|
||||
#define BTC_L2CAP_INCLUDED TRUE
|
||||
#define BTC_SDP_INCLUDED TRUE
|
||||
#define VND_BT_JV_BTA_L2CAP TRUE
|
||||
#endif /* UC_BT_L2CAP_ENABLED */
|
||||
|
||||
#if (UC_BT_SDP_COMMON_ENABLED == TRUE)
|
||||
#define BTC_SDP_COMMON_INCLUDED TRUE
|
||||
#endif /* UC_BT_SDP_COMMON_ENABLED */
|
||||
|
||||
#if (UC_BT_HFP_AG_ENABLED == TRUE) || (UC_BT_HFP_CLIENT_ENABLED == TRUE)
|
||||
#ifndef RFCOMM_INCLUDED
|
||||
#define RFCOMM_INCLUDED TRUE
|
||||
@ -168,6 +176,13 @@
|
||||
#define BTC_HD_INCLUDED TRUE
|
||||
#endif /* UC_BT_HID_DEVICE_ENABLED */
|
||||
|
||||
#if UC_BT_GOEPC_ENABLED
|
||||
#ifndef OBEX_INCLUDED
|
||||
#define OBEX_INCLUDED TRUE
|
||||
#endif
|
||||
#define GOEPC_INCLUDED TRUE
|
||||
#endif /* UC_BT_GOEPC_ENABLED */
|
||||
|
||||
#endif /* UC_BT_CLASSIC_ENABLED */
|
||||
|
||||
/* This is set to enable use of GAP L2CAP connections. */
|
||||
@ -373,6 +388,10 @@
|
||||
#define BTC_AV_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTC_AV_CA_INCLUDED
|
||||
#define BTC_AV_CA_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTC_AV_SINK_INCLUDED
|
||||
#define BTC_AV_SINK_INCLUDED FALSE
|
||||
#endif
|
||||
@ -446,6 +465,10 @@
|
||||
#define BTA_AV_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_AV_CA_INCLUDED
|
||||
#define BTA_AV_CA_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_AV_SINK_INCLUDED
|
||||
#define BTA_AV_SINK_INCLUDED FALSE
|
||||
#endif
|
||||
@ -1287,7 +1310,7 @@
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define BTM_BLE_ADV_TX_POWER {-12, -9, -6, -3, 0, 3, 6, 9}
|
||||
#else
|
||||
#define BTM_BLE_ADV_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21}
|
||||
#define BTM_BLE_ADV_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 20}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -1295,7 +1318,7 @@
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define BTM_TX_POWER {-12, -9, -6, -3, 0, 3, 6, 9}
|
||||
#else
|
||||
#define BTM_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21}
|
||||
#define BTM_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 20}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -1500,7 +1523,7 @@
|
||||
|
||||
/* The maximum number of attributes in each record. */
|
||||
#ifndef SDP_MAX_REC_ATTR
|
||||
#if (defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)) || (defined(BTC_SDP_INCLUDED) && (BTC_SDP_INCLUDED==TRUE))
|
||||
#if (defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)) || (defined(BTC_SDP_COMMON_INCLUDED) && (BTC_SDP_COMMON_INCLUDED==TRUE))
|
||||
#define SDP_MAX_REC_ATTR 25
|
||||
#else
|
||||
#define SDP_MAX_REC_ATTR 8
|
||||
@ -1806,6 +1829,26 @@
|
||||
#define OBX_FCR_TX_POOL_ID 3
|
||||
#endif
|
||||
|
||||
/* Maximum OBEX connection allowed */
|
||||
#ifndef OBEX_MAX_CONNECTION
|
||||
#define OBEX_MAX_CONNECTION 3
|
||||
#endif
|
||||
|
||||
/* Maximum OBEX server allowed */
|
||||
#ifndef OBEX_MAX_SERVER
|
||||
#define OBEX_MAX_SERVER 2
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
** GOEP
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
/* Maximum GOEP client connection allowed */
|
||||
#ifndef GOEPC_MAX_CONNECTION
|
||||
#define GOEPC_MAX_CONNECTION 3
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
@ -2138,6 +2181,20 @@
|
||||
#define HID_HOST_REPAGE_WIN (2)
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
** Definitions for OBEX
|
||||
*/
|
||||
#ifndef OBEX_INCLUDED
|
||||
#define OBEX_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
** Definitions for OBEX
|
||||
*/
|
||||
#ifndef GOEPC_INCLUDED
|
||||
#define GOEPC_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
* A2DP Definitions
|
||||
*/
|
||||
@ -2176,6 +2233,10 @@
|
||||
#define AVRC_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef AVRC_CA_INCLUDED
|
||||
#define AVRC_CA_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef AVRC_METADATA_INCLUDED
|
||||
#if AVRC_INCLUDED == TRUE
|
||||
#define AVRC_METADATA_INCLUDED TRUE
|
||||
|
@ -316,6 +316,27 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
|
||||
#define AVRC_TRACE_EVENT(fmt, args...) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVRC,EVENT)) BT_PRINT_D("BT_AVRC", fmt, ## args);}
|
||||
#define AVRC_TRACE_DEBUG(fmt, args...) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVRC,DEBUG)) BT_PRINT_D("BT_AVRC", fmt, ## args);}
|
||||
|
||||
/* Define tracing for OBEX */
|
||||
#define OBEX_TRACE_ERROR(fmt, args...) {if (obex_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(AVRC, ERROR)) BT_PRINT_E("BT_OBEX", fmt, ## args);}
|
||||
#define OBEX_TRACE_WARNING(fmt, args...) {if (obex_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(AVRC, WARNING)) BT_PRINT_W("BT_OBEX", fmt, ## args);}
|
||||
#define OBEX_TRACE_API(fmt, args...) {if (obex_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(AVRC,API)) BT_PRINT_I("BT_OBEX", fmt, ## args);}
|
||||
#define OBEX_TRACE_EVENT(fmt, args...) {if (obex_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVRC,EVENT)) BT_PRINT_D("BT_OBEX", fmt, ## args);}
|
||||
#define OBEX_TRACE_DEBUG(fmt, args...) {if (obex_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVRC,DEBUG)) BT_PRINT_D("BT_OBEX", fmt, ## args);}
|
||||
|
||||
/* Define tracing for OBEX_TL_L2CAP */
|
||||
#define OBEX_TL_L2CAP_TRACE_ERROR(fmt, args...) {if (obex_tl_l2cap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(AVRC, ERROR)) BT_PRINT_E("OBEX_TL_L2CAP", fmt, ## args);}
|
||||
#define OBEX_TL_L2CAP_TRACE_WARNING(fmt, args...) {if (obex_tl_l2cap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(AVRC, WARNING)) BT_PRINT_W("OBEX_TL_L2CAP", fmt, ## args);}
|
||||
#define OBEX_TL_L2CAP_TRACE_API(fmt, args...) {if (obex_tl_l2cap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(AVRC,API)) BT_PRINT_I("OBEX_TL_L2CAP", fmt, ## args);}
|
||||
#define OBEX_TL_L2CAP_TRACE_EVENT(fmt, args...) {if (obex_tl_l2cap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVRC,EVENT)) BT_PRINT_D("OBEX_TL_L2CAP", fmt, ## args);}
|
||||
#define OBEX_TL_L2CAP_TRACE_DEBUG(fmt, args...) {if (obex_tl_l2cap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVRC,DEBUG)) BT_PRINT_D("OBEX_TL_L2CAP", fmt, ## args);}
|
||||
|
||||
/* Define tracing for GOEPC */
|
||||
#define GOEPC_TRACE_ERROR(fmt, args...) {if (goepc_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(AVRC, ERROR)) BT_PRINT_E("BT_GOEPC", fmt, ## args);}
|
||||
#define GOEPC_TRACE_WARNING(fmt, args...) {if (goepc_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(AVRC, WARNING)) BT_PRINT_W("BT_GOEPC", fmt, ## args);}
|
||||
#define GOEPC_TRACE_API(fmt, args...) {if (goepc_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(AVRC,API)) BT_PRINT_I("BT_GOEPC", fmt, ## args);}
|
||||
#define GOEPC_TRACE_EVENT(fmt, args...) {if (goepc_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVRC,EVENT)) BT_PRINT_D("BT_GOEPC", fmt, ## args);}
|
||||
#define GOEPC_TRACE_DEBUG(fmt, args...) {if (goepc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVRC,DEBUG)) BT_PRINT_D("BT_GOEPC", fmt, ## args);}
|
||||
|
||||
/* MCAP
|
||||
*/
|
||||
#define MCA_TRACE_ERROR(fmt, args...) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(MCA, ERROR)) BT_PRINT_E("BT_MCA", fmt, ## args);}
|
||||
@ -484,6 +505,26 @@ extern UINT8 btif_trace_level;
|
||||
#define AVRC_TRACE_DEBUG(fmt, args...)
|
||||
#define AVRC_TRACE_API(fmt, args...)
|
||||
|
||||
/* Define tracing for OBEX */
|
||||
#define OBEX_TRACE_ERROR(fmt, args...)
|
||||
#define OBEX_TRACE_WARNING(fmt, args...)
|
||||
#define OBEX_TRACE_API(fmt, args...)
|
||||
#define OBEX_TRACE_EVENT(fmt, args...)
|
||||
#define OBEX_TRACE_DEBUG(fmt, args...)
|
||||
|
||||
#define OBEX_TL_L2CAP_TRACE_ERROR(fmt, args...)
|
||||
#define OBEX_TL_L2CAP_TRACE_WARNING(fmt, args...)
|
||||
#define OBEX_TL_L2CAP_TRACE_API(fmt, args...)
|
||||
#define OBEX_TL_L2CAP_TRACE_EVENT(fmt, args...)
|
||||
#define OBEX_TL_L2CAP_TRACE_DEBUG(fmt, args...)
|
||||
|
||||
/* Define tracing for GOEPC */
|
||||
#define GOEPC_TRACE_ERROR(fmt, args...)
|
||||
#define GOEPC_TRACE_WARNING(fmt, args...)
|
||||
#define GOEPC_TRACE_API(fmt, args...)
|
||||
#define GOEPC_TRACE_EVENT(fmt, args...)
|
||||
#define GOEPC_TRACE_DEBUG(fmt, args...)
|
||||
|
||||
/* MCAP
|
||||
*/
|
||||
#define MCA_TRACE_ERROR(fmt, args...)
|
||||
|
@ -269,7 +269,7 @@ static void start_up(void)
|
||||
#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||
|
||||
#if (BLE_50_FEATURE_SUPPORT == TRUE && BLE_42_FEATURE_SUPPORT == FALSE)
|
||||
if (HCI_LE_ENHANCED_PRIVACY_SUPPORTED(controller_param.features_ble.as_array)) {
|
||||
if (HCI_LE_EXT_ADV_SUPPORTED(controller_param.features_ble.as_array)) {
|
||||
response = AWAIT_COMMAND(controller_param.packet_factory->make_read_max_adv_data_len());
|
||||
controller_param.packet_parser->parse_ble_read_adv_max_len_response(
|
||||
response,
|
||||
|
@ -186,7 +186,9 @@ static void parse_ble_read_resolving_list_size_response(
|
||||
{
|
||||
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_RESOLVING_LIST_SIZE, 1 /* bytes after */);
|
||||
if (stream) {
|
||||
STREAM_TO_UINT8(*resolving_list_size_ptr, stream);
|
||||
}
|
||||
|
||||
osi_free(response);
|
||||
}
|
||||
@ -198,10 +200,14 @@ static void parse_ble_read_suggested_default_data_length_response(
|
||||
{
|
||||
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */);
|
||||
if (stream) {
|
||||
STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream);
|
||||
STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream);
|
||||
}
|
||||
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
#if (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||
static void parse_ble_read_adv_max_len_response(
|
||||
BT_HDR *response,
|
||||
@ -209,8 +215,10 @@ static void parse_ble_read_adv_max_len_response(
|
||||
{
|
||||
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */);
|
||||
if (stream) {
|
||||
// Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length
|
||||
STREAM_TO_UINT16(*adv_max_len_ptr, stream);
|
||||
}
|
||||
|
||||
osi_free(response);
|
||||
}
|
||||
@ -254,6 +262,7 @@ static uint8_t *read_command_complete_header(
|
||||
STREAM_TO_UINT8(status, stream);
|
||||
|
||||
if (status != HCI_SUCCESS) {
|
||||
HCI_TRACE_ERROR("%s failed: opcode 0x%04x, status 0x%02x", __func__, opcode, status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,8 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Stack Configuation Related Init Definaton
|
||||
* TODO: Now Just Unmask these defination until stack layer is OK
|
||||
/* Stack Configuration Related Init Definaton
|
||||
* TODO: Now Just Unmask these definition until stack layer is OK
|
||||
*/
|
||||
|
||||
#ifndef BTA_INCLUDED
|
||||
@ -91,6 +91,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(OBEX_INCLUDED) && OBEX_INCLUDED == TRUE)
|
||||
#include "stack/obex_api.h"
|
||||
#endif
|
||||
|
||||
#if (defined(GOEPC_INCLUDED) && GOEPC_INCLUDED == TRUE)
|
||||
#include "stack/goep_common.h"
|
||||
#include "stack/goepc_api.h"
|
||||
#endif
|
||||
|
||||
//BTA Modules
|
||||
#if BTA_INCLUDED == TRUE && BTA_DYNAMIC_MEMORY == TRUE
|
||||
#include "bta/bta_api.h"
|
||||
@ -267,6 +276,14 @@ void BTE_DeinitStack(void)
|
||||
}
|
||||
#endif // BTA_INCLUDED == TRUE
|
||||
|
||||
#if (defined(GOEPC_INCLUDED) && GOEPC_INCLUDED == TRUE)
|
||||
GOEPC_Deinit();
|
||||
#endif
|
||||
|
||||
#if (defined(OBEX_INCLUDED) && OBEX_INCLUDED == TRUE)
|
||||
OBEX_Deinit();
|
||||
#endif
|
||||
|
||||
#if (defined(HID_DEV_INCLUDED) && HID_DEV_INCLUDED == TRUE)
|
||||
HID_DevDeinit();
|
||||
#endif
|
||||
@ -388,6 +405,18 @@ bt_status_t BTE_InitStack(void)
|
||||
MCA_Init();
|
||||
#endif
|
||||
|
||||
#if (defined(OBEX_INCLUDED) && OBEX_INCLUDED == TRUE)
|
||||
if (OBEX_Init() != OBEX_SUCCESS) {
|
||||
goto error_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(GOEPC_INCLUDED) && GOEPC_INCLUDED == TRUE)
|
||||
if (GOEPC_Init() != GOEP_SUCCESS) {
|
||||
goto error_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
//BTA Modules
|
||||
#if (BTA_INCLUDED == TRUE && BTA_DYNAMIC_MEMORY == TRUE)
|
||||
if ((bta_sys_cb_ptr = (tBTA_SYS_CB *)osi_malloc(sizeof(tBTA_SYS_CB))) == NULL) {
|
||||
|
@ -430,9 +430,9 @@ BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
|
||||
tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
|
||||
int i;
|
||||
|
||||
AVCT_TRACE_WARNING("avct_lcb_last_ccb");
|
||||
AVCT_TRACE_DEBUG("avct_lcb_last_ccb");
|
||||
for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
|
||||
AVCT_TRACE_WARNING("%x: aloc:%d, lcb:%p/%p, ccb:%p/%p",
|
||||
AVCT_TRACE_DEBUG("%x: aloc:%d, lcb:%p/%p, ccb:%p/%p",
|
||||
i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
|
||||
if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last)) {
|
||||
return FALSE;
|
||||
|
@ -29,8 +29,8 @@
|
||||
|
||||
#if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE)
|
||||
|
||||
#ifndef SDP_AVRCP_1_5
|
||||
#define SDP_AVRCP_1_5 TRUE
|
||||
#ifndef SDP_AVRCP_1_6
|
||||
#define SDP_AVRCP_1_6 TRUE
|
||||
#endif
|
||||
|
||||
#ifndef SDP_AVCTP_1_4
|
||||
@ -52,7 +52,7 @@ const tSDP_PROTOCOL_ELEM avrc_proto_list [] = {
|
||||
#if SDP_AVCTP_1_4 == TRUE
|
||||
{UUID_PROTOCOL_AVCTP, 1, {AVCT_REV_1_4, 0} }
|
||||
#else
|
||||
#if (SDP_AVRCP_1_4 == TRUE || SDP_AVRCP_1_5 == TRUE)
|
||||
#if SDP_AVRCP_1_6 == TRUE
|
||||
{UUID_PROTOCOL_AVCTP, 1, {AVCT_REV_1_3, 0} }
|
||||
#else
|
||||
#if AVRC_METADATA_INCLUDED == TRUE
|
||||
@ -64,7 +64,7 @@ const tSDP_PROTOCOL_ELEM avrc_proto_list [] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if SDP_AVRCP_1_5 == TRUE
|
||||
#if SDP_AVRCP_1_6 == TRUE
|
||||
const tSDP_PROTO_LIST_ELEM avrc_add_proto_list [] = {
|
||||
{
|
||||
AVRC_NUM_PROTO_ELEMS,
|
||||
@ -251,7 +251,7 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide
|
||||
|
||||
/* add service class id list */
|
||||
class_list[0] = service_uuid;
|
||||
#if (SDP_AVCTP_1_4 == TRUE || SDP_AVRCP_1_5 == TRUE)
|
||||
#if (SDP_AVCTP_1_4 == TRUE || SDP_AVRCP_1_6 == TRUE)
|
||||
if ( service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL ) {
|
||||
class_list[1] = UUID_SERVCLASS_AV_REM_CTRL_CONTROL;
|
||||
count = 2;
|
||||
@ -263,7 +263,7 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide
|
||||
result &= SDP_AddProtocolList(sdp_handle, AVRC_NUM_PROTO_ELEMS, (tSDP_PROTOCOL_ELEM *)avrc_proto_list);
|
||||
|
||||
/* add profile descriptor list */
|
||||
#if SDP_AVRCP_1_5 == TRUE
|
||||
#if SDP_AVRCP_1_6 == TRUE
|
||||
if (browsing_en) {
|
||||
add_additional_protocol_list = TRUE;
|
||||
} else if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET &&
|
||||
@ -277,7 +277,7 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide
|
||||
result &= SDP_AddAdditionProtoLists( sdp_handle, 1, (tSDP_PROTO_LIST_ELEM *)avrc_add_proto_list);
|
||||
}
|
||||
|
||||
result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_5);
|
||||
result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_6);
|
||||
#else
|
||||
#if AVRC_METADATA_INCLUDED == TRUE
|
||||
result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_3);
|
||||
@ -292,6 +292,13 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_provide
|
||||
} else if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET && media_player_virtual_filesystem_supported) {
|
||||
supported_feature |= AVRC_SUPF_TG_BROWSE;
|
||||
}
|
||||
#if AVRC_CA_INCLUDED
|
||||
if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL || service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
|
||||
supported_feature |= AVRC_SUPF_CT_COVER_ART_GIP;
|
||||
supported_feature |= AVRC_SUPF_CT_COVER_ART_GI;
|
||||
supported_feature |= AVRC_SUPF_CT_COVER_ART_GLT;
|
||||
}
|
||||
#endif
|
||||
/* add supported feature */
|
||||
p = temp;
|
||||
UINT16_TO_BE_STREAM(p, supported_feature);
|
||||
@ -383,7 +390,7 @@ bt_status_t AVRC_Init(void)
|
||||
**
|
||||
** Function AVRC_Deinit
|
||||
**
|
||||
** Description This function is called at stack shotdown to free the
|
||||
** Description This function is called at stack shutdown to free the
|
||||
** control block (if using dynamic memory), and deinitializes the
|
||||
** control block and tracing level.
|
||||
**
|
||||
|
@ -543,7 +543,7 @@ static tBTM_PM_MODE btm_pm_get_set_mode(UINT8 pm_id, tBTM_PM_MCB *p_cb, tBTM_PM_
|
||||
** Function btm_pm_snd_md_req
|
||||
** Description get the resulting mode and send the resuest to host controller
|
||||
** Returns tBTM_STATUS
|
||||
**, BOOLEAN *p_chg_ind
|
||||
**
|
||||
*******************************************************************************/
|
||||
static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, UINT16 link_hdl, tBTM_PM_PWR_MD *p_mode)
|
||||
{
|
||||
@ -565,6 +565,8 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, UINT16 link_hdl, tBTM_PM_PWR_M
|
||||
/* already in the resulting mode */
|
||||
if ( (mode == BTM_PM_MD_ACTIVE) ||
|
||||
((md_res.max >= p_cb->interval) && (md_res.min <= p_cb->interval)) ) {
|
||||
// Clear request change indication because already in result mode
|
||||
p_cb->chg_ind = FALSE;
|
||||
return BTM_CMD_STORED;
|
||||
}
|
||||
/* Otherwise, needs to wake, then sleep */
|
||||
@ -689,7 +691,7 @@ static void btm_pm_check_stored(void)
|
||||
** Description This function is called when an HCI command status event occurs
|
||||
** for power manager related commands.
|
||||
**
|
||||
** Input Parms status - status of the event (HCI_SUCCESS if no errors)
|
||||
** Input Params status - status of the event (HCI_SUCCESS if no errors)
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
@ -717,7 +719,7 @@ void btm_pm_proc_cmd_status(UINT8 status)
|
||||
#if BTM_PM_DEBUG == TRUE
|
||||
BTM_TRACE_DEBUG( "btm_pm_proc_cmd_status new state:0x%x", p_cb->state);
|
||||
#endif // BTM_PM_DEBUG
|
||||
} else { /* the command was not successfull. Stay in the same state */
|
||||
} else { /* the command was not successful. Stay in the same state */
|
||||
pm_status = BTM_PM_STS_ERROR;
|
||||
}
|
||||
|
||||
@ -743,7 +745,7 @@ void btm_pm_proc_cmd_status(UINT8 status)
|
||||
**
|
||||
** Description This function is called when an HCI mode change event occurs.
|
||||
**
|
||||
** Input Parms hci_status - status of the event (HCI_SUCCESS if no errors)
|
||||
** Input Params hci_status - status of the event (HCI_SUCCESS if no errors)
|
||||
** hci_handle - connection handle associated with the change
|
||||
** mode - HCI_MODE_ACTIVE, HCI_MODE_HOLD, HCI_MODE_SNIFF, or HCI_MODE_PARK
|
||||
** interval - number of baseband slots (meaning depends on mode)
|
||||
|
376
components/bt/host/bluedroid/stack/goep/goepc_api.c
Normal file
376
components/bt/host/bluedroid/stack/goep/goepc_api.c
Normal file
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "osi/osi.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#include "stack/obex_api.h"
|
||||
#include "stack/goep_common.h"
|
||||
#include "stack/goepc_api.h"
|
||||
#include "goep_int.h"
|
||||
|
||||
#if (GOEPC_INCLUDED == TRUE)
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_Init
|
||||
**
|
||||
** Description Initialize GOEP Client role, must call before using any
|
||||
** other GOEPC APIs
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_Init(void)
|
||||
{
|
||||
#if (GOEP_DYNAMIC_MEMORY)
|
||||
if (!goepc_cb_ptr) {
|
||||
goepc_cb_ptr = (tGOEPC_CB *)osi_malloc(sizeof(tGOEPC_CB));
|
||||
if (!goepc_cb_ptr) {
|
||||
return GOEP_NO_RESOURCES;
|
||||
}
|
||||
}
|
||||
#endif /* #if (GOEP_DYNAMIC_MEMORY) */
|
||||
memset(&goepc_cb, 0, sizeof(tGOEPC_CB));
|
||||
goepc_cb.trace_level = BT_TRACE_LEVEL_ERROR;
|
||||
return GOEP_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_Deinit
|
||||
**
|
||||
** Description Deinit GOEP Client role, once deinit, can not use any other
|
||||
** GOEPC APIs until call GOEPC_Init again
|
||||
**
|
||||
*******************************************************************************/
|
||||
void GOEPC_Deinit(void)
|
||||
{
|
||||
#if (GOEP_DYNAMIC_MEMORY)
|
||||
if (goepc_cb_ptr) {
|
||||
osi_free(goepc_cb_ptr);
|
||||
goepc_cb_ptr = NULL;
|
||||
}
|
||||
#endif /* #if (GOEP_DYNAMIC_MEMORY) */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_Open
|
||||
**
|
||||
** Description Start the progress to establish a GOEP connection to server
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed, when the
|
||||
** connection is established, GOEPC_OPENED_EVT will come
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_Open(tOBEX_SVR_INFO *svr, tGOEPC_EVT_CBACK callback, UINT16 *out_handle)
|
||||
{
|
||||
UINT16 ret = GOEP_SUCCESS;
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
|
||||
do {
|
||||
/* check parameter, allow out_handle to be NULL */
|
||||
if (svr == NULL || callback == NULL) {
|
||||
ret = GOEP_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
p_ccb = goepc_allocate_ccb();
|
||||
if (p_ccb == NULL) {
|
||||
ret = GOEP_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
if (OBEX_CreateConn(svr, goepc_obex_callback, &p_ccb->obex_handle) != OBEX_SUCCESS) {
|
||||
ret = GOEP_TL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* success */
|
||||
p_ccb->callback = callback;
|
||||
p_ccb->state = GOEPC_STATE_OPENING;
|
||||
if (out_handle) {
|
||||
*out_handle = p_ccb->allocated;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (ret != GOEP_SUCCESS && p_ccb != NULL) {
|
||||
goepc_free_ccb(p_ccb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_Close
|
||||
**
|
||||
** Description Close a GOEP connection immediately
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_Close(UINT16 handle)
|
||||
{
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
|
||||
UINT16 ccb_idx = handle - 1;
|
||||
if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) {
|
||||
return GOEP_BAD_HANDLE;
|
||||
}
|
||||
|
||||
p_ccb = &goepc_cb.ccb[ccb_idx];
|
||||
if (p_ccb->obex_handle) {
|
||||
OBEX_RemoveConn(p_ccb->obex_handle);
|
||||
}
|
||||
goepc_free_ccb(p_ccb);
|
||||
|
||||
return GOEP_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_SendRequest
|
||||
**
|
||||
** Description Send the prepared request packet to server
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_SendRequest(UINT16 handle)
|
||||
{
|
||||
UINT16 ret = GOEP_SUCCESS;
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
BOOLEAN final = FALSE;
|
||||
|
||||
do {
|
||||
UINT16 ccb_idx = handle - 1;
|
||||
if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) {
|
||||
ret = GOEP_BAD_HANDLE;
|
||||
break;
|
||||
}
|
||||
p_ccb = &goepc_cb.ccb[ccb_idx];
|
||||
|
||||
if (p_ccb->pkt == NULL) {
|
||||
ret = GOEP_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
final = OBEX_CheckFinalBit(p_ccb->pkt);
|
||||
/* check whether state machine allow this operation */
|
||||
if (!goepc_check_obex_req_allow(p_ccb->state, final)) {
|
||||
ret = GOEP_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_ccb->congest) {
|
||||
ret = GOEP_CONGEST;
|
||||
break;
|
||||
}
|
||||
|
||||
/* execute srm state machine */
|
||||
goepc_srm_sm_execute(p_ccb, TRUE, p_ccb->pkt_srm_en, p_ccb->pkt_srm_wait);
|
||||
|
||||
tGOEPC_DATA data;
|
||||
data.pkt = p_ccb->pkt;
|
||||
|
||||
p_ccb->last_pkt_opcode = p_ccb->curr_pkt_opcode;
|
||||
p_ccb->pkt = NULL;
|
||||
p_ccb->pkt_srm_en = FALSE;
|
||||
p_ccb->pkt_srm_wait = FALSE;
|
||||
|
||||
/* execute main state machine */
|
||||
if (final) {
|
||||
goepc_sm_execute(p_ccb, GOEPC_SM_EVENT_REQ_FB, &data);
|
||||
}
|
||||
else {
|
||||
goepc_sm_execute(p_ccb, GOEPC_SM_EVENT_REQ, &data);
|
||||
}
|
||||
/* since goepc_sm_execute may free ccb, can not access ccb here */
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_PrepareRequest
|
||||
**
|
||||
** Description Prepare a request packet, packet will be store internally
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_PrepareRequest(UINT16 handle, tOBEX_PARSE_INFO *info, UINT16 buff_size)
|
||||
{
|
||||
UINT16 ret = GOEP_SUCCESS;
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
BT_HDR *pkt = NULL;
|
||||
|
||||
do {
|
||||
UINT16 ccb_idx = handle - 1;
|
||||
if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) {
|
||||
ret = GOEP_BAD_HANDLE;
|
||||
break;
|
||||
}
|
||||
p_ccb = &goepc_cb.ccb[ccb_idx];
|
||||
|
||||
if (info == NULL || buff_size < OBEX_MIN_PACKET_SIZE) {
|
||||
ret = GOEP_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_ccb->pkt != NULL) {
|
||||
ret = GOEP_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!goepc_check_obex_req_param(info)) {
|
||||
ret = GOEP_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (OBEX_BuildRequest(info, buff_size, &pkt) != OBEX_SUCCESS) {
|
||||
ret = GOEP_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
p_ccb->curr_pkt_opcode = info->opcode;
|
||||
p_ccb->pkt = pkt;
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_DropRequest
|
||||
**
|
||||
** Description Drop the prepared internal request packet
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_DropRequest(UINT16 handle)
|
||||
{
|
||||
UINT16 ccb_idx = handle - 1;
|
||||
if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) {
|
||||
return GOEP_BAD_HANDLE;
|
||||
}
|
||||
|
||||
tGOEPC_CCB *p_ccb = &goepc_cb.ccb[ccb_idx];
|
||||
if (p_ccb->pkt == NULL) {
|
||||
return GOEP_INVALID_STATE;
|
||||
}
|
||||
|
||||
osi_free(p_ccb->pkt);
|
||||
p_ccb->pkt = NULL;
|
||||
p_ccb->pkt_srm_en = FALSE;
|
||||
p_ccb->pkt_srm_wait = FALSE;
|
||||
return GOEP_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_RequestSetSRM
|
||||
**
|
||||
** Description Modify the prepared internal request packet, append SRM header
|
||||
** or SRMP header
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_RequestSetSRM(UINT16 handle, BOOLEAN srm_en, BOOLEAN srm_wait)
|
||||
{
|
||||
UINT16 ret = GOEP_SUCCESS;
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
|
||||
do {
|
||||
UINT16 ccb_idx = handle - 1;
|
||||
if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) {
|
||||
ret = GOEP_BAD_HANDLE;
|
||||
break;
|
||||
}
|
||||
p_ccb = &goepc_cb.ccb[ccb_idx];
|
||||
|
||||
if (!srm_en && !srm_wait) {
|
||||
ret = GOEP_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_ccb->pkt == NULL) {
|
||||
ret = GOEP_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (srm_en) {
|
||||
if (OBEX_AppendHeaderSRM(p_ccb->pkt, OBEX_SRM_ENABLE) == OBEX_SUCCESS) {
|
||||
p_ccb->pkt_srm_en = TRUE;
|
||||
}
|
||||
else {
|
||||
ret = GOEP_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (srm_wait) {
|
||||
if (OBEX_AppendHeaderSRMP(p_ccb->pkt, OBEX_SRMP_WAIT) == OBEX_SUCCESS) {
|
||||
p_ccb->pkt_srm_wait = TRUE;
|
||||
}
|
||||
else {
|
||||
ret = GOEP_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GOEPC_RequestAddHeader
|
||||
**
|
||||
** Description Modify the prepared internal request packet, append header
|
||||
**
|
||||
** Returns GOEP_SUCCESS if successful, otherwise failed
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GOEPC_RequestAddHeader(UINT16 handle, UINT8 header_id, const UINT8 *data, UINT16 data_len)
|
||||
{
|
||||
UINT16 ret = GOEP_SUCCESS;
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
|
||||
do {
|
||||
UINT16 ccb_idx = handle - 1;
|
||||
if (ccb_idx >= GOEPC_MAX_CONNECTION || !goepc_cb.ccb[ccb_idx].allocated) {
|
||||
ret = GOEP_BAD_HANDLE;
|
||||
break;
|
||||
}
|
||||
p_ccb = &goepc_cb.ccb[ccb_idx];
|
||||
|
||||
if (p_ccb->pkt == NULL) {
|
||||
ret = GOEP_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == NULL || data_len == 0) {
|
||||
ret = GOEP_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (OBEX_AppendHeaderRaw(p_ccb->pkt, header_id, data, data_len) != OBEX_SUCCESS) {
|
||||
ret = GOEP_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* #if (GOEPC_INCLUDED == TRUE) */
|
528
components/bt/host/bluedroid/stack/goep/goepc_main.c
Normal file
528
components/bt/host/bluedroid/stack/goep/goepc_main.c
Normal file
@ -0,0 +1,528 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "osi/osi.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#include "stack/obex_api.h"
|
||||
#include "stack/goep_common.h"
|
||||
#include "stack/goepc_api.h"
|
||||
#include "goep_int.h"
|
||||
|
||||
#if (GOEPC_INCLUDED == TRUE)
|
||||
|
||||
#if GOEP_DYNAMIC_MEMORY == FALSE
|
||||
tGOEPC_CB goepc_cb;
|
||||
#else
|
||||
tGOEPC_CB *goepc_cb_ptr = NULL;
|
||||
#endif
|
||||
|
||||
tGOEPC_CCB *goepc_allocate_ccb(void)
|
||||
{
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
for (int i = 0; i < GOEPC_MAX_CONNECTION; ++i) {
|
||||
if (!goepc_cb.ccb[i].allocated) {
|
||||
goepc_cb.ccb[i].allocated = i + 1;
|
||||
p_ccb = &goepc_cb.ccb[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return p_ccb;
|
||||
}
|
||||
|
||||
void goepc_free_ccb(tGOEPC_CCB *p_ccb)
|
||||
{
|
||||
if (p_ccb->pkt != NULL) {
|
||||
osi_free(p_ccb->pkt);
|
||||
}
|
||||
memset(p_ccb, 0, sizeof(tGOEPC_CCB));
|
||||
}
|
||||
|
||||
BOOLEAN goepc_check_obex_req_param(tOBEX_PARSE_INFO *info)
|
||||
{
|
||||
BOOLEAN ret = TRUE;
|
||||
switch (info->opcode)
|
||||
{
|
||||
case OBEX_OPCODE_CONNECT:
|
||||
if (info->max_packet_length < 255 || info->obex_version_number == 0) {
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
case OBEX_OPCODE_DISCONNECT:
|
||||
case OBEX_OPCODE_PUT:
|
||||
case OBEX_OPCODE_PUT_FINAL:
|
||||
case OBEX_OPCODE_GET:
|
||||
case OBEX_OPCODE_GET_FINAL:
|
||||
case OBEX_OPCODE_SETPATH:
|
||||
case OBEX_OPCODE_ACTION:
|
||||
case OBEX_OPCODE_SESSION:
|
||||
/* opcode allowed */
|
||||
break;
|
||||
case OBEX_OPCODE_ABORT:
|
||||
default:
|
||||
ret = FALSE;
|
||||
/* opcode not allowed */
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static tGOEPC_CCB *find_ccb_by_obex_handle(UINT16 obex_handle)
|
||||
{
|
||||
tGOEPC_CCB *p_ccb = NULL;
|
||||
for (int i = 0; i < GOEPC_MAX_CONNECTION; ++i) {
|
||||
if (goepc_cb.ccb[i].allocated && goepc_cb.ccb[i].obex_handle == obex_handle) {
|
||||
p_ccb = &goepc_cb.ccb[i];
|
||||
}
|
||||
}
|
||||
return p_ccb;
|
||||
}
|
||||
|
||||
static void goepc_extra_srm_rsp(UINT8 opcode, BT_HDR *pkt, BOOLEAN *srm_en, BOOLEAN *srm_wait)
|
||||
{
|
||||
tOBEX_PARSE_INFO info;
|
||||
BOOLEAN srm_found = FALSE;
|
||||
BOOLEAN srmp_found = FALSE;
|
||||
if (OBEX_ParseResponse(pkt, opcode, &info) == OBEX_SUCCESS) {
|
||||
UINT8 *header = NULL;
|
||||
while((header = OBEX_GetNextHeader(pkt, &info)) != NULL) {
|
||||
switch (*header)
|
||||
{
|
||||
case OBEX_HEADER_ID_SRM:
|
||||
if (header[1] == OBEX_SRM_ENABLE) {
|
||||
*srm_en = TRUE;
|
||||
}
|
||||
srm_found = TRUE;
|
||||
break;
|
||||
case OBEX_HEADER_ID_SRM_PARAM:
|
||||
switch (header[1])
|
||||
{
|
||||
case OBEX_SRMP_ADD_PKT:
|
||||
/* goep should not use this */
|
||||
break;
|
||||
case OBEX_SRMP_WAIT:
|
||||
*srm_wait = TRUE;
|
||||
break;
|
||||
case OBEX_SRMP_ADD_PKT_WAIT:
|
||||
/* goep should not use this */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
srmp_found = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (srm_found && srmp_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_act_congest(tGOEPC_CCB *p_ccb)
|
||||
{
|
||||
p_ccb->congest = TRUE;
|
||||
p_ccb->callback(p_ccb->allocated, GOEPC_CONGEST_EVT, NULL);
|
||||
}
|
||||
|
||||
static void goepc_act_uncongest(tGOEPC_CCB *p_ccb)
|
||||
{
|
||||
p_ccb->congest = FALSE;
|
||||
p_ccb->callback(p_ccb->allocated, GOEPC_UNCONGEST_EVT, NULL);
|
||||
}
|
||||
|
||||
static void goepc_act_mtu_chg(tGOEPC_CCB *p_ccb, tGOEPC_MTU_CHG *mtu_chg)
|
||||
{
|
||||
tGOEPC_MSG msg;
|
||||
msg.mtu_changed.peer_mtu = mtu_chg->peer_mtu;
|
||||
msg.mtu_changed.our_mtu = mtu_chg->our_mtu;
|
||||
p_ccb->peer_mtu = mtu_chg->peer_mtu;
|
||||
p_ccb->our_mtu = mtu_chg->our_mtu;
|
||||
p_ccb->callback(p_ccb->allocated, GOEPC_MTU_CHANGED_EVT, &msg);
|
||||
}
|
||||
|
||||
void goepc_obex_callback(UINT16 handle, UINT8 event, tOBEX_MSG *msg)
|
||||
{
|
||||
tGOEPC_DATA data;
|
||||
UINT8 goepc_sm_event = GOEPC_SM_EVENT_DISCONNECT;
|
||||
BOOLEAN exec_sm = FALSE;
|
||||
tGOEPC_CCB *p_ccb = find_ccb_by_obex_handle(handle);
|
||||
if (p_ccb == NULL) {
|
||||
GOEPC_TRACE_ERROR("goepc_obex_callback can not find a ccb\n");
|
||||
/* can not find a ccb in goepc, free resource and remove this connection */
|
||||
if (event == OBEX_DATA_EVT && msg->data.pkt) {
|
||||
osi_free(msg->data.pkt);
|
||||
}
|
||||
OBEX_RemoveConn(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case OBEX_CONNECT_EVT:
|
||||
data.connected.peer_mtu = msg->connect.peer_mtu;
|
||||
data.connected.our_mtu = msg->connect.our_mtu;
|
||||
goepc_sm_event = GOEPC_SM_EVENT_CONNECT;
|
||||
exec_sm = TRUE;
|
||||
break;
|
||||
case OBEX_MTU_CHANGE_EVT:
|
||||
data.mtu_chg.peer_mtu = msg->mtu_change.peer_mtu;
|
||||
data.mtu_chg.our_mtu = msg->mtu_change.our_mtu;
|
||||
goepc_act_mtu_chg(p_ccb, &data.mtu_chg);
|
||||
break;
|
||||
case OBEX_DISCONNECT_EVT:
|
||||
/* when we received this event, obex connection already disconnect */
|
||||
p_ccb->obex_handle = 0;
|
||||
goepc_sm_event = GOEPC_SM_EVENT_DISCONNECT;;
|
||||
exec_sm = TRUE;
|
||||
break;
|
||||
case OBEX_CONGEST_EVT:
|
||||
goepc_act_congest(p_ccb);
|
||||
break;
|
||||
case OBEX_UNCONGEST_EVT:
|
||||
goepc_act_uncongest(p_ccb);
|
||||
break;
|
||||
case OBEX_DATA_EVT:
|
||||
data.pkt = msg->data.pkt;
|
||||
if (OBEX_CheckContinueResponse(data.pkt)) {
|
||||
/* in OBEX 1.0, final bit of response code will always set, we need to check this */
|
||||
goepc_sm_event = GOEPC_SM_EVENT_RSP;
|
||||
}
|
||||
else if (OBEX_CheckFinalBit(data.pkt)) {
|
||||
goepc_sm_event = GOEPC_SM_EVENT_RSP_FB;
|
||||
}
|
||||
else {
|
||||
goepc_sm_event = GOEPC_SM_EVENT_RSP;
|
||||
}
|
||||
exec_sm = TRUE;
|
||||
break;
|
||||
default:
|
||||
/* other event, ignore */
|
||||
break;
|
||||
}
|
||||
|
||||
if (exec_sm) {
|
||||
goepc_sm_execute(p_ccb, goepc_sm_event, &data);
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_sm_act_connect(tGOEPC_CCB *p_ccb, tGOEPC_CONNECTED *connected)
|
||||
{
|
||||
tGOEPC_MSG msg;
|
||||
msg.opened.peer_mtu = connected->peer_mtu;
|
||||
msg.opened.our_mtu = connected->our_mtu;
|
||||
p_ccb->peer_mtu = connected->peer_mtu;
|
||||
p_ccb->our_mtu = connected->our_mtu;
|
||||
|
||||
/* main state machine transfer to OPENED_IDLE */
|
||||
p_ccb->state = GOEPC_STATE_OPENED_IDLE;
|
||||
p_ccb->callback(p_ccb->allocated, GOEPC_OPENED_EVT, &msg);
|
||||
}
|
||||
|
||||
static void goepc_sm_act_disconnect(tGOEPC_CCB *p_ccb)
|
||||
{
|
||||
tGOEPC_MSG msg;
|
||||
if (p_ccb->obex_handle) {
|
||||
OBEX_RemoveConn(p_ccb->obex_handle);
|
||||
}
|
||||
msg.closed.reason = GOEP_TL_ERROR;
|
||||
p_ccb->callback(p_ccb->allocated, GOEPC_CLOSED_EVT, &msg);
|
||||
/* free ccb, main state machine end */
|
||||
goepc_free_ccb(p_ccb);
|
||||
}
|
||||
|
||||
static void goepc_sm_act_send_req(tGOEPC_CCB *p_ccb, BT_HDR *pkt)
|
||||
{
|
||||
UINT16 ret = OBEX_SendPacket(p_ccb->obex_handle, pkt);
|
||||
if (ret == OBEX_SUCCESS) {
|
||||
/* main state machine transfer to OPENED_REQ */
|
||||
p_ccb->state = GOEPC_STATE_OPENED_REQ;
|
||||
}
|
||||
else {
|
||||
/* send failed, something error in transport layer, disconnect */
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_sm_act_send_req_fb(tGOEPC_CCB *p_ccb, BT_HDR *pkt)
|
||||
{
|
||||
UINT16 ret = OBEX_SendPacket(p_ccb->obex_handle, pkt);
|
||||
if (ret == OBEX_SUCCESS) {
|
||||
/* main state machine transfer to OPENED_RSP */
|
||||
p_ccb->state = GOEPC_STATE_OPENED_RSP;
|
||||
}
|
||||
else {
|
||||
/* send failed, something error in transport layer, disconnect */
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_sm_act_rsp(tGOEPC_CCB *p_ccb, BT_HDR *pkt)
|
||||
{
|
||||
/* handle srm state transfer */
|
||||
BOOLEAN srm_en = FALSE;
|
||||
BOOLEAN srm_wait = FALSE;
|
||||
goepc_extra_srm_rsp(p_ccb->last_pkt_opcode, pkt, &srm_en, &srm_wait);
|
||||
goepc_srm_sm_execute(p_ccb, FALSE, srm_en, srm_wait);
|
||||
/* main state machine not change */
|
||||
|
||||
tGOEPC_MSG msg;
|
||||
msg.response.opcode = p_ccb->last_pkt_opcode;
|
||||
msg.response.final = FALSE;
|
||||
msg.response.srm_en = (p_ccb->srm_state == GOEPC_SRM_STATE_ENABLE_WAIT || p_ccb->srm_state == GOEPC_SRM_STATE_ENABLE);
|
||||
msg.response.srm_wait = (p_ccb->srm_state == GOEPC_SRM_STATE_ENABLE_WAIT);
|
||||
msg.response.pkt = pkt;
|
||||
p_ccb->callback(p_ccb->allocated, GOEPC_RESPONSE_EVT, &msg);
|
||||
}
|
||||
|
||||
static void goepc_sm_act_rsp_fb(tGOEPC_CCB *p_ccb, BT_HDR *pkt)
|
||||
{
|
||||
tGOEPC_MSG msg;
|
||||
msg.response.opcode = p_ccb->last_pkt_opcode;
|
||||
msg.response.final = TRUE;
|
||||
msg.response.srm_en = FALSE;
|
||||
msg.response.srm_wait = FALSE;
|
||||
msg.response.pkt = pkt;
|
||||
/* operation complete, reset srm state */
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_IDLE;
|
||||
/* main state machine transfer to OPENED_IDLE */
|
||||
p_ccb->state = GOEPC_STATE_OPENED_IDLE;
|
||||
p_ccb->callback(p_ccb->allocated, GOEPC_RESPONSE_EVT, &msg);
|
||||
}
|
||||
|
||||
|
||||
static void goepc_sm_state_opening(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case GOEPC_SM_EVENT_CONNECT:
|
||||
goepc_sm_act_connect(p_ccb, &p_data->connected);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_DISCONNECT:
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_RSP:
|
||||
case GOEPC_SM_EVENT_RSP_FB:
|
||||
GOEPC_TRACE_ERROR("goepc_sm_state_opening received unexpected response from peer\n");
|
||||
if (p_data->pkt != NULL) {
|
||||
osi_free(p_data->pkt);
|
||||
}
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
break;
|
||||
default:
|
||||
GOEPC_TRACE_ERROR("goepc_sm_state_opening unexpected event: 0x%x\n", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_sm_state_opened_idle(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case GOEPC_SM_EVENT_DISCONNECT:
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_REQ:
|
||||
goepc_sm_act_send_req(p_ccb, p_data->pkt);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_REQ_FB:
|
||||
goepc_sm_act_send_req_fb(p_ccb, p_data->pkt);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_RSP:
|
||||
case GOEPC_SM_EVENT_RSP_FB:
|
||||
GOEPC_TRACE_ERROR("goepc_sm_state_opened_idle received unexpected response from peer\n");
|
||||
/* peer sent a packet to us when we didn't request */
|
||||
if (p_data->pkt != NULL) {
|
||||
osi_free(p_data->pkt);
|
||||
}
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
break;
|
||||
default:
|
||||
GOEPC_TRACE_ERROR("goepc_sm_state_opened_idle unexpected event: 0x%x\n", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_sm_state_opened_req(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case GOEPC_SM_EVENT_DISCONNECT:
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_REQ:
|
||||
goepc_sm_act_send_req(p_ccb, p_data->pkt);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_REQ_FB:
|
||||
goepc_sm_act_send_req_fb(p_ccb, p_data->pkt);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_RSP:
|
||||
goepc_sm_act_rsp(p_ccb, p_data->pkt);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_RSP_FB:
|
||||
goepc_sm_act_rsp_fb(p_ccb, p_data->pkt);
|
||||
break;
|
||||
default:
|
||||
GOEPC_TRACE_ERROR("goepc_sm_state_opened_req unexpected event: 0x%x\n", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_sm_state_opened_rsp(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case GOEPC_SM_EVENT_DISCONNECT:
|
||||
goepc_sm_act_disconnect(p_ccb);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_REQ_FB:
|
||||
goepc_sm_act_send_req_fb(p_ccb, p_data->pkt);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_RSP:
|
||||
goepc_sm_act_rsp(p_ccb, p_data->pkt);
|
||||
break;
|
||||
case GOEPC_SM_EVENT_RSP_FB:
|
||||
goepc_sm_act_rsp_fb(p_ccb, p_data->pkt);
|
||||
break;
|
||||
default:
|
||||
GOEPC_TRACE_ERROR("goepc_sm_state_opened_rsp unexpected event: 0x%x\n", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN goepc_check_obex_req_allow(UINT8 state, BOOLEAN final)
|
||||
{
|
||||
BOOLEAN ret = FALSE;
|
||||
if (final) {
|
||||
switch (state)
|
||||
{
|
||||
case GOEPC_STATE_OPENED_IDLE:
|
||||
case GOEPC_STATE_OPENED_REQ:
|
||||
case GOEPC_STATE_OPENED_RSP:
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (state)
|
||||
{
|
||||
case GOEPC_STATE_OPENED_IDLE:
|
||||
case GOEPC_STATE_OPENED_REQ:
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void goepc_sm_execute(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data)
|
||||
{
|
||||
switch (p_ccb->state)
|
||||
{
|
||||
case GOEPC_STATE_INIT:
|
||||
/* do nothing */
|
||||
break;
|
||||
case GOEPC_STATE_OPENING:
|
||||
goepc_sm_state_opening(p_ccb, event, p_data);
|
||||
break;
|
||||
case GOEPC_STATE_OPENED_IDLE:
|
||||
goepc_sm_state_opened_idle(p_ccb, event, p_data);
|
||||
break;
|
||||
case GOEPC_STATE_OPENED_REQ:
|
||||
goepc_sm_state_opened_req(p_ccb, event, p_data);
|
||||
break;
|
||||
case GOEPC_STATE_OPENED_RSP:
|
||||
goepc_sm_state_opened_rsp(p_ccb, event, p_data);
|
||||
break;
|
||||
default:
|
||||
GOEPC_TRACE_ERROR("goepc_sm_execute unexpected state: 0x%x\n", p_ccb->state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_srm_sm_act_req(tGOEPC_CCB *p_ccb, BOOLEAN srm_en, BOOLEAN srm_wait)
|
||||
{
|
||||
switch (p_ccb->srm_state)
|
||||
{
|
||||
case GOEPC_SRM_STATE_IDLE:
|
||||
if (srm_en) {
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_REQ;
|
||||
p_ccb->srm_wait = srm_wait;
|
||||
}
|
||||
else {
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_DISABLE;
|
||||
}
|
||||
break;
|
||||
case GOEPC_SRM_STATE_ENABLE_WAIT:
|
||||
if (!srm_wait) {
|
||||
p_ccb->srm_wait = FALSE;
|
||||
}
|
||||
if (!p_ccb->srm_wait && !p_ccb->srm_peer_wait) {
|
||||
/* no more wait, transfer to ENABLE */
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void goepc_srm_sm_act_rsp(tGOEPC_CCB *p_ccb, BOOLEAN srm_en, BOOLEAN srm_wait)
|
||||
{
|
||||
switch (p_ccb->srm_state)
|
||||
{
|
||||
case GOEPC_SRM_STATE_IDLE:
|
||||
/* peer can not request to enable srm, ignore */
|
||||
break;
|
||||
case GOEPC_SRM_STATE_REQ:
|
||||
if (srm_en) {
|
||||
p_ccb->srm_peer_wait = srm_wait;
|
||||
if (p_ccb->srm_wait || p_ccb->srm_peer_wait) {
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE_WAIT;
|
||||
}
|
||||
else {
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_DISABLE;
|
||||
}
|
||||
break;
|
||||
case GOEPC_SRM_STATE_ENABLE_WAIT:
|
||||
if (!srm_wait) {
|
||||
p_ccb->srm_peer_wait = FALSE;
|
||||
}
|
||||
if (!p_ccb->srm_wait && !p_ccb->srm_peer_wait) {
|
||||
/* no more wait, transfer to ENABLE */
|
||||
p_ccb->srm_state = GOEPC_SRM_STATE_ENABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void goepc_srm_sm_execute(tGOEPC_CCB *p_ccb, BOOLEAN is_req, BOOLEAN srm_en, BOOLEAN srm_wait)
|
||||
{
|
||||
if (is_req) {
|
||||
goepc_srm_sm_act_req(p_ccb, srm_en, srm_wait);
|
||||
}
|
||||
else {
|
||||
goepc_srm_sm_act_rsp(p_ccb, srm_en, srm_wait);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if (GOEPC_INCLUDED == TRUE) */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user