Compare commits

...

280 Commits

Author SHA1 Message Date
MacChu0315
48d6bf6bd6
Merge b2575902ed into 3c99557eee 2024-09-15 12:46:33 +08:00
Shen Meng Jing
3c99557eee Merge branch 'docs/update_cn_translation' into 'master'
Some checks failed
docker / docker (push) Has been cancelled
docs: Update CN translation for several docs

Closes DOC-8745 and DOC-8735

See merge request espressif/esp-idf!33071
2024-09-14 19:03:31 +08:00
Jiang Jiang Jian
db50b1ac63 Merge branch 'bugfix/support_cert_test' into 'master'
All chip support cert_test

Closes WIFI-5432, IDFGH-12197, and IDFHG-10756

See merge request espressif/esp-idf!27977
2024-09-14 16:44:21 +08:00
Konstantin Kondrashov
efdc853b45 Merge branch 'feature/esp32c61_esp_timer_systimer' into 'master'
feat(esp_timer): Updates systimer and esp_timer for ESP32-C61

Closes IDF-9284, IDF-10955, IDF-9307, and IDF-9308

See merge request espressif/esp-idf!33439
2024-09-14 16:08:40 +08:00
Armando (Dou Yiwen)
f4dd74ed96 Merge branch 'change/improve_xip_docs' into 'master'
psram: improve xip docs

See merge request espressif/esp-idf!33482
2024-09-14 15:59:03 +08:00
morris
46cccdea5f Merge branch 'change/mipi_dsi_remove_unused_ll' into 'master'
refactor(mipi_dsi): remove unused LL functions

See merge request espressif/esp-idf!33489
2024-09-14 15:52:37 +08:00
Konstantin Kondrashov
1489514ee5 Merge branch 'contrib/github_pr_14469' into 'master'
fix(spinlock): comparison of integer expressions of different signedness (GitHub PR)

Closes IDFGH-13581

See merge request espressif/esp-idf!33272
2024-09-14 15:34:41 +08:00
Kevin (Lao Kaiyao)
c45e084145 Merge branch 'bugfix/check_sdm_clock_range' into 'master'
refactor(sdm): add check and error info to the clock division

See merge request espressif/esp-idf!33394
2024-09-14 15:07:38 +08:00
Jiang Jiang Jian
b435473323 Merge branch 'ci/wifi_power_save_got_ip_time' into 'master'
ci: increase test_wifi_power_save got ip timeout

Closes IDFCI-2379, IDFCI-2122, and IDFCI-2132

See merge request espressif/esp-idf!33538
2024-09-14 14:52:31 +08:00
Wang Meng Yang
cda2846558 Merge branch 'feature/support_bt_avrcp_cover_art' into 'master'
feat(bt/bluedroid): Support BT AVRCP Cover Art

Closes BT-3231

See merge request espressif/esp-idf!32538
2024-09-14 14:37:19 +08:00
Konstantin Kondrashov
48b1cd53d9 Merge branch 'bugfix/check_bootloader_size_with_sign' into 'master'
fix(esptool_py): Check the size of the bootloader + signature block

Closes IDFCI-1686

See merge request espressif/esp-idf!33417
2024-09-14 14:35:21 +08:00
Chen Yudong
353c1ea77e ci: increase test_wifi_power_save got ip timeout 2024-09-14 11:26:54 +08:00
Armando
6c4fb48783 doc(psram): clarify why psram speed is faster than flash 2024-09-14 11:13:20 +08:00
Armando
256ef127dd fix(linker): fixed extern linker symbol type from int to char 2024-09-14 11:11:55 +08:00
Mu Hai Dong
dacc1f94dd Apply 1 suggestion(s) to 1 file(s)
Co-authored-by: Jiang Jiang Jian <jack@espressif.com>
2024-09-14 10:37:30 +08:00
muhaidong
30a48b126e fix(phy): esp32s2 and esph2 support rf cert_test 2024-09-14 10:37:14 +08:00
muhaidong
aa80dbe251 fix(phy): fix esp32 build fail issue
Closes https://github.com/espressif/esp-idf/issues/11972
2024-09-14 10:33:58 +08:00
xiehang
c53cedb947 fix(phy): All chip support cert_test 2024-09-14 10:33:58 +08:00
Michael (XIAO Xufeng)
28340977bd Merge branch 'doc/spi_flash_hpm_dc_aware_version' into 'master'
doc(spi_flash): add version number for bootloader version using explicit DC_AWARE

See merge request espressif/esp-idf!33470
2024-09-14 10:19:07 +08:00
Armando (Dou Yiwen)
c7415fc78d Merge branch 'fix/fix_csi_bridge_clock_enable_issue' into 'master'
csi: bridge clock enable shared control issue

See merge request espressif/esp-idf!33498
2024-09-14 10:01:27 +08:00
Gao Xu
e5fcc53755 Merge branch 'fix/fix_isp_color_contrast_max_value' into 'master'
Fix/fix isp color contrast max value

See merge request espressif/esp-idf!33507
2024-09-14 09:20:32 +08:00
Kevin (Lao Kaiyao)
bd38d80ff0 Merge branch 'bugfix/reserve_mspi_pin_regarding_line_mode' into 'master'
fix(gpio_reserve): reserve the mspi pin regarding line mode

See merge request espressif/esp-idf!33488
2024-09-13 22:22:28 +08:00
Jiang Jiang Jian
f98e288e24 Merge branch 'ci/enable_esp32c5_target_test' into 'master'
Ci: enable esp32c5/c61 basic wifi test

See merge request espressif/esp-idf!32253
2024-09-13 20:17:58 +08:00
Island
5f6971bfa7 Merge branch 'bugfix/fixed_multi_conn_example_crash_issue' into 'master'
fix(nimble): fiexed the crash issue of examples/bluetooth/nimble/ble_multi_conn

See merge request espressif/esp-idf!33491
2024-09-13 19:17:58 +08:00
Jiang Jiang Jian
16461de2b2 Merge branch 'bugfix/fixed_rx_bar_from_null_bss_issue' into 'master'
fix(wifi): fixed softap rx bar from null bss issue

Closes WIFI-6541, FCS-1423, FCS-1424, and IDFGH-13416

See merge request espressif/esp-idf!30680
2024-09-13 19:05:17 +08:00
linruihao
eb2307af36 fix(bt/bluedroid): Fixed some bugs in AVRCP 2024-09-13 17:58:49 +08:00
linruihao
147a249d7a feat(bt/bluedroid): Support AVRCP Cover Art feature in a2dp_sink demo 2024-09-13 17:58:49 +08:00
linruihao
0de83be0fe feat(bt/bluedroid): Add Kconfig options to controll AVRCP Cover Art feature 2024-09-13 17:58:49 +08:00
linruihao
cb0d073551 feat(bt/bluedroid): Support AVRCP Cover Art feature 2024-09-13 17:58:49 +08:00
linruihao
d7298a71c3 feat(bt/bluedroid): Support GOEP Client basic feature 2024-09-13 17:58:49 +08:00
linruihao
da858edb7a feat(bt/bluedroid): Support OBEX over L2CAP 2024-09-13 17:58:49 +08:00
Radek Tandler
928addee19 Merge branch 'feature/storage_nvs_doc_update' into 'master'
docs: Improved API Guides - File system considerations for NVS

See merge request espressif/esp-idf!33465
2024-09-13 17:54:21 +08:00
Wu Zheng Hui
21ee174957 Merge branch 'fix/allows_to_forcibly_disable_sleep_submodes' into 'master'
fix(esp_hw_support): allows to forcefully disable sleep submode

Closes IDFCI-2380 and PM-228

See merge request espressif/esp-idf!33481
2024-09-13 17:52:37 +08:00
Armando
9e9225dbc2 change(rcc): change rcc var i to rcc_cnt 2024-09-13 17:00:07 +08:00
Armando
45b7b7dc1c fix(csi): fixed csi bridge clock closed by csi host driver issue 2024-09-13 17:00:07 +08:00
Chen Yudong
a8482f580a ci: enable esp32c5/c6 wifi basic target tests 2024-09-13 16:42:47 +08:00
Jiang Jiang Jian
965986bcf1 Merge branch 'fix/esp32_tx_shake_issue' into 'master'
fix(wifi):fix esp32c2 tx shake issue

Closes WIFIBUG-489 and WIFIBUG-763

See merge request espressif/esp-idf!31908
2024-09-13 15:56:31 +08:00
Roland Dobai
82ddb6920c Merge branch 'fix/docs_tools_c5_c61' into 'master'
Docs: Remove tools from the docs_not_updated list

Closes IDF-9490 and IDF-10167

See merge request espressif/esp-idf!33496
2024-09-13 15:50:44 +08:00
Shu Chen
4d4062a2b8 Merge branch 'feat/thread_dns_ext_resolve' into 'master'
feat(openthread): Replace netconn external resolve hook with dns external hook

See merge request espressif/esp-idf!33344
2024-09-13 15:45:25 +08:00
David Čermák
d4f60febdd Merge branch 'feat/lwip_2.2.0' into 'master'
feat(lwip): Support for new lwip release 2.2.0

Closes IDFGH-11237

See merge request espressif/esp-idf!30388
2024-09-13 15:38:23 +08:00
muhaidong
8daa2e308b fix(wifi): fix some wifi issues
1. fixed softap rx bar from null bss issue
2. fixed multi country info issue
https://github.com/espressif/esp-idf/issues/14323
2024-09-13 15:14:32 +08:00
Xu Xiao
e035e798b7 Merge branch 'feat/add_support_for_ap_choose' into 'master'
feat(wifi): add support for ap choose

Closes WIFIBUG-732, WIFIBUG-741, WIFIBUG-744, WIFIBUG-735, WIFI-6430, and BT-3853

See merge request espressif/esp-idf!33353
2024-09-13 15:03:02 +08:00
gaoxu
5e46dba0f7 fix(adc): fix isp contrast and saturation max value 2024-09-13 14:21:06 +08:00
Roland Dobai
899879cfad fix(docs): Remove tools from the docs_not_updated list 2024-09-13 14:20:20 +08:00
laokaiyao
c6e7e82524 change(sdm): delete the confusing part in sdm programming guide 2024-09-13 14:13:20 +08:00
laokaiyao
d9d316b97d refactor(sdm): add check and error info to the clock division 2024-09-13 14:13:20 +08:00
Erhan Kurubas
d8d57e1965 Merge branch 'sysview_sbom_file' into 'master'
feat(sysview): add sbom manifest file

Closes IDF-8232

See merge request espressif/esp-idf!33330
2024-09-13 13:25:48 +08:00
morris
5ddeab65e3 refactor(mipi_dsi): remove unused LL functions
MIPI DSI PHY reference clock is controlled in hp_sys_clkrst register
2024-09-13 12:24:12 +08:00
xuxiao
73079de058 fix(phy): update libphy to fix tx power is not correct after enable tsens 2024-09-13 11:34:18 +08:00
xuxiao
ffb227ebd2 feat(wifi): add support for ap choose 2024-09-13 11:34:18 +08:00
Jiang Jiang Jian
68d504b4fd Merge branch 'ci/fix_bt_ci' into 'master'
test(ci): fix bt ci that there is no flash_80m config

See merge request espressif/esp-idf!33499
2024-09-13 11:33:51 +08:00
C.S.M
bfdb9f308d test(ci): fix bt ci that there is no flash_80m config 2024-09-13 11:06:20 +08:00
laokaiyao
a80603c05b fix(gpio_reserve): reserve the mspi pin regarding line mode 2024-09-13 11:02:07 +08:00
Fu Hanxi
a760bd2472 Merge branch 'feat/split_pytest_requirements' into 'master'
feat: split pytest requirements to base and test-specific

Closes IDFCI-2307 and IDFCI-2376

See merge request espressif/esp-idf!33429
2024-09-13 02:44:44 +08:00
Fu Hanxi
bc36fda936
ci: temp disable esp32p4 for loadable ram 2024-09-12 15:04:00 +02:00
Shen Weilong
798b7c92c4 fix(ble): fiexed the crash issue of examples/bluetooth/nimble/ble_multi_conn 2024-09-12 20:36:39 +08:00
Fu Hanxi
dc1851bd5a docs: fix indentation error in s3 spi_flash kconfig 2024-09-12 20:18:46 +08:00
Fu Hanxi
1fa6d49f6f ci: remove idf-env.json before install.sh for macos jobs 2024-09-12 20:18:46 +08:00
Fu Hanxi
dca0465095 feat: split pytest requirements to base and test-specific 2024-09-12 20:18:46 +08:00
Abhik Roy
1889851d7c Merge branch 'contrib/github_pr_14411' into 'master'
fix(esp_netif): Fixed initializer order of ESP_IP macros for C++ (GitHub PR)

Closes IDFGH-13520

See merge request espressif/esp-idf!33175
2024-09-12 18:44:40 +08:00
morris
c6433de7cc Merge branch 'feat/rgb_lcd_example_lvgl9' into 'master'
feat(rgb_lcd): adapt to LVGL v9

See merge request espressif/esp-idf!33479
2024-09-12 18:32:26 +08:00
Song Ruo Jing
2cef80666b Merge branch 'feature/gpio_add_direction' into 'master'
feat(gpio): allow appending mode to IOs

See merge request espressif/esp-idf!33181
2024-09-12 18:20:11 +08:00
Jiang Jiang Jian
8b962f91a2 Merge branch 'ble_feat/esp32c5_mp_support_ble_light_sleep' into 'master'
feat(ble): support ble light sleep on esp32c5

Closes BLERP-1006

See merge request espressif/esp-idf!33325
2024-09-12 16:59:58 +08:00
David Čermák
4dd715922f Merge branch 'fix/freertos_sim_nonblock_select' into 'master'
fix(freertos): Made select function non-blocking on Linux target (GitHub PR)

Closes IDFGH-13569 and IDFGH-13498

See merge request espressif/esp-idf!33331
2024-09-12 16:57:58 +08:00
Roman Leonov
fac1966c9b Merge branch 'refactor/usb_host_ext_hub_cleanup' into 'master'
refactor(hub): Cleaned up dev_tree_node debug output, moved node freeing

See merge request espressif/esp-idf!33380
2024-09-12 16:01:36 +08:00
David Cermak
015ab1d18f fix(lwip): Fix linker/fr symbol for tcp_output_control segment
In lwip-2.1.3 tcp_output_control_segment() is used to send RST, empty
ACK, keepalive or zero window probe.
In lwip-2.2.0 this works the same, but the function is used when we
don't know the interface to send to (and if used it finds it and calls)
tcp_output_control_segment_netif().
When `LWIP_EXTRA_IRAM_OPTIMIZATION=y` we would ideally move both
variants to IRAM, but the pcb variant (tcp_output_control_segment) could
be optimized away on some targets and toolchain versions.
(esp32c6 with riscv32-esp-elf/esp-14.2.0_20240906)
It should be sufficient to keep tcp_output_control_segment_netif in IRAM
for most common performance usecases.
2024-09-12 09:52:13 +02:00
Konstantin Kondrashov
7b0b80f46f fix(examples): Increases partition table offset for SBV2+FE test 2024-09-12 15:38:18 +08:00
Konstantin Kondrashov
d2123cf531 fix(esptool_py): Check the size of the bootloader + signature block 2024-09-12 15:38:18 +08:00
Liu Xiao Yu
52175a6548 Merge branch 'refactor/supplement_plic_intr_rv_util_apis' into 'master'
refactor(intr): add plic and intc interrupt rv util apis

See merge request espressif/esp-idf!33244
2024-09-12 15:28:24 +08:00
morris
6e8a958754 feat(rgb_lcd): adapt to LVGL v9
This commit mainly refactor the RGB_LCD example to use the latest LVGL
V9 library.
2024-09-12 15:13:27 +08:00
wuzhenghui
0cd6532d36
docs(sleep_mode): update outdated sleep mode configure API in docs 2024-09-12 15:09:31 +08:00
wuzhenghui
37fa09f1dc
fix(esp_hw_support): allows to forcefully disable submodes at mode initialization 2024-09-12 15:09:25 +08:00
Konstantin Kondrashov
3081a4ea49 feat(esp_timer): Updates systimer and esp_timer 2024-09-12 14:26:37 +08:00
Konstantin Kondrashov
00991f1bf5 Merge branch 'feature/esp32c61_re_enable_base_mac_address_test' into 'master'
feat(system): Re-enables the pytest_base_mac_address test for ESP32-C61

Closes IDF-10956

See merge request espressif/esp-idf!33441
2024-09-12 13:24:07 +08:00
Mahavir Jain
fd192e0e9e Merge branch 'fix/ds_tries_acquiring_mpi_lock_twice' into 'master'
Clean up DS trying to re-acquire MPI lock post common crypto lock layer

See merge request espressif/esp-idf!33056
2024-09-12 12:18:22 +08:00
C.S.M
3008d11a68 Merge branch 'refactor/flash_frequency_esptool' into 'master'
refactor(spi_flash): Refactor the flash frequency config file

Closes IDF-10488

See merge request espressif/esp-idf!33427
2024-09-12 10:37:58 +08:00
Marius Vikhammer
35a6671072 Merge branch 'feature/c6_misc_core' into 'master'
feat(system): misc core-system C61 bringup changes

Closes IDF-10954, IDF-10986, IDF-10957, IDF-9281, and IDF-9257

See merge request espressif/esp-idf!33297
2024-09-12 09:46:30 +08:00
Marius Vikhammer
5486653a18 Merge branch 'contrib/github_pr_14422' into 'master'
feat(esp_system,ulp): LP core reserved mem optionally executable from HP core (GitHub PR)

Closes IDFGH-13533

See merge request espressif/esp-idf!33139
2024-09-12 09:10:22 +08:00
Konstantin Kondrashov
e8dab4c257 Merge branch 'feature/esp32c61_update_efuses' into 'master'
feat(efuse): Updates efuse table for esp32c61

Closes IDF-11057 and IDF-9282

See merge request espressif/esp-idf!33436
2024-09-12 01:20:20 +08:00
Xiao Xufeng
ba06e0cfc8 docs(spi_flash): add version number for bootloader version using explicit DC_AWARE 2024-09-12 00:09:15 +08:00
snake-4
09bbc75d96 fix(esp_netif): Fixed initializer order of ESP_IP macros for C++ 2024-09-12 01:25:42 +10:00
Wu Zheng Hui
6abe40e590 Merge branch 'feature/optimize_esp32p4_active_power_eco1' into 'master'
feat(system): Optimize esp32p4 active state  power consumption

Closes PM-103 and IDF-7688

See merge request espressif/esp-idf!32950
2024-09-11 23:15:29 +08:00
Abhik Roy
3aee7c920d Merge branch 'examples/icmpv6_ping_ll_support' into 'master'
fix(examples/icmpv6): Added support for pinging link-local address

Closes FCS-1499

See merge request espressif/esp-idf!32168
2024-09-11 22:58:58 +08:00
David Cermak
4d046b3732 feat(lwip): Reference official lwip-2.2.0-esp 2024-09-11 16:48:07 +02:00
David Cermak
b61a5e7636 change(openthread): Update prebuilt OT lib to comply with lwip ABI 2024-09-11 16:48:07 +02:00
David Cermak
c098388a2f fix(lwip): Use ACD light module for simple DHCP-ARP check 2024-09-11 16:48:07 +02:00
David Cermak
720b74026c fix(esp_netif): Use internal DHCP struct 2024-09-11 16:48:06 +02:00
David Cermak
e8ac6af67e fix(esp_netif): Fix per pppos callback update in new lwip 2024-09-11 16:48:06 +02:00
David Cermak
22f213b518 feat(lwip): Add support for lwip 2.2.0-esp release 2024-09-11 16:48:00 +02:00
Peter Marcisovsky
2e100a3518 Merge branch 'fix/usb_host_change_log_level' into 'master'
fix(usb_host): Update log level and error poropagation

See merge request espressif/esp-idf!33361
2024-09-11 22:37:24 +08:00
radek.tandler
65df4d6e34 fix(storage/nvs): improved documentation section in file system considerations
fix(storage/nvs): improved documentation section in file system considerations1
2024-09-11 16:10:10 +02:00
Wu Zheng Hui
f3c4d57f13 Merge branch 'fix/fix_clock_retention_link_context' into 'master'
fix(esp_hw_support): add clock retention contents for esp32c6 & esp32h2

Closes IDF-9629

See merge request espressif/esp-idf!33411
2024-09-11 21:12:23 +08:00
Rahul Tank
c6bed070d6 Merge branch 'feat/add_ext_adv_param_v2' into 'master'
feat(nimble): Add support for ext adv param v2 HCI command

Closes BLERP-499

See merge request espressif/esp-idf!32863
2024-09-11 18:47:07 +08:00
Abhik Roy
e1102e6794 fix(examples/icmpv6): Added support for pinging link-local address 2024-09-11 20:45:26 +10:00
Xiaoyu Liu
3d403a4ba8 refactor(intr): unify riscv freertos set/clear intr mask from isr apis
refactor(intr): find a potential bug that clic intr mask need extra nop ops
2024-09-11 18:26:07 +08:00
Xiaoyu Liu
8a608da2b0 refactor(intr): add plic and intc interrupt rv util apis
refactor(intr): remove the extra instructions in plic and intc
2024-09-11 18:26:07 +08:00
Song Ruo Jing
e1d3d830ce refactor(gpio): public some IO configuration functions
This allows different peripheral drivers to act on the same IO.
2024-09-11 18:07:46 +08:00
Sudeep Mohanty
1b6a829e81 Merge branch 'feat/lp_core_lp_adc_support' into 'master'
feat(lp_adc): Addded support for LP ADC for the LP core on esp32p4

Closes IDF-6875 and IDF-10205

See merge request espressif/esp-idf!33117
2024-09-11 17:16:40 +08:00
Wu Zheng Hui
eab98765ad Merge branch 'feature/introduce_internal_sleep_sub_mode_configure_api' into 'master'
feat(esp_hw_support): introduce internal sleep sub mode configure api

Closes PM-216

See merge request espressif/esp-idf!30687
2024-09-11 17:01:59 +08:00
Wang Meng Yang
c27614fdaa Merge branch 'bugfix/fix_missing_per_adv_sync_est_evt' into 'master'
fix(bt): Update bt lib for ESP32-C3 and ESP32-S3(c66a703)

Closes BT-3859

See merge request espressif/esp-idf!33363
2024-09-11 16:40:26 +08:00
Jiang Jiang Jian
31c60963b5 Merge branch 'bugfix/roaming_app_support_wifi_disconnect' into 'master'
Stops roaming app upon application initiated disconnect

Closes WIFIBUG-551 and WIFIBUG-636

See merge request espressif/esp-idf!30738
2024-09-11 16:10:33 +08:00
Lou Tian Hao
c7d532049a Merge branch 'feature/esp32c61_light_sleep_support_stage_2' into 'master'
feat(esp_hw_support): esp32c61 sleep support (Stage 2: support basic pmu sleep function)

Closes IDF-9248, IDF-9247, IDF-9246, IDF-10993, IDF-9250, PM-203, and IDF-9244

See merge request espressif/esp-idf!33294
2024-09-11 15:11:58 +08:00
Song Ruo Jing
832e08c82f Merge branch 'feature/esp32c61_lp_io_support' into 'master'
feat(lp_io): Add LP_IO support for ESP32C61

Closes IDF-9317

See merge request espressif/esp-idf!33013
2024-09-11 14:45:54 +08:00
Roland Dobai
0b43a55625 Merge branch 'feat/update_tools_in_tools_json' into 'master'
feat(tools): Update tools: cmake, ninja, ccache

Closes IDF-10686 and IDFGH-13476

See merge request espressif/esp-idf!32726
2024-09-11 14:40:19 +08:00
Kapil Gupta
b66f4444d7 fix(esp_wifi): Stop roaming app when station stops 2024-09-11 12:01:31 +05:30
C.S.M
44ff115557 refactor(spi_flash): Refactor the flash frequency config file 2024-09-11 14:13:26 +08:00
Marius Vikhammer
40352943e3 ci(system): re-enable system test app for C61 2024-09-11 14:05:11 +08:00
Marius Vikhammer
b93e2a6915 test(intr): fix intr dump test for C61 and re-enable it 2024-09-11 14:05:11 +08:00
Marius Vikhammer
e1e02cae0c feat(system): enable WDT support on esp32c61 2024-09-11 14:05:11 +08:00
Rahul Tank
1f41827bc3 Merge branch 'bugfix/bidirectioanl_data_transfer_ble_spp' into 'master'
fix(nimble): Added support for bidirectional data trasfer

Closes BLERP-1021

See merge request espressif/esp-idf!33402
2024-09-11 14:02:51 +08:00
C.S.M
f5a2a1ff82 Merge branch 'fix/i2c_out_od_reg_value' into 'master'
fix(i2c): Fix the i2c sda/scl force out register value on some esp chips(c6,h2,p4,c5,c61)

See merge request espressif/esp-idf!33299
2024-09-11 13:52:37 +08:00
C.S.M
04e925e4a8 Merge branch 'feature/suspend_bringup' into 'master'
feat(spi_flash): Add suspend support on esp32c5, esp32c61

Closes IDF-9255 and IDF-8648

See merge request espressif/esp-idf!33364
2024-09-11 13:48:11 +08:00
Konstantin Kondrashov
2af66dac25 Merge branch 'feature/ipc_isr_riscv_test_enable' into 'master'
feat(system): Enables test_ipc_isr_riscv for ESP32-P4

Closes IDF-8353

See merge request espressif/esp-idf!33440
2024-09-11 12:56:30 +08:00
Kapil Gupta
09b421674b fix(esp_wifi): Remove duplicate declaration of function 2024-09-11 10:03:38 +05:30
jgujarathi
e411e43b4b fix(examples) : Common component's wifi disconnect handler should ignore roaming disconnect
- Common component's wifi disconnect handler should ignore roaming disconnect (WIFI_REASON_ROAMING)
  as connect gets issued internally in these cases.
2024-09-11 11:39:43 +08:00
jgujarathi
6547315dde fix(esp_wifi): Stops roaming app upon application initiated disconnect
Stops roaming app when the application initiates a disconnect.
Roaming app if enabled will be restarted when the station reconnects again.
2024-09-11 11:39:43 +08:00
jgujarathi
e2ba2cfbe2 fix(esp_supplicant): Fix compilation issues with btm and rrm status funcs
- Ensure that the btm and rrm status funcs can be used even if 80211.kv
  are not enabled in menuconfig. They will return false in such cases.
2024-09-11 11:39:43 +08:00
wangtao@espressif.com
c46cb415bd fix(wifi): fix esp32c2 tx shake issue 2024-09-11 11:32:25 +08:00
linruihao
b4100e5362 fix(bt): Update bt lib for ESP32-C3 and ESP32-S3(c66a703)
- Fixed missing sync established event after canceling sync
2024-09-11 11:14:19 +08:00
wuzhenghui
21f79616bd
change(esp_driver_spi): increase SPI_PER_TRANS_POLLING peformance tolerance 2024-09-11 10:53:45 +08:00
wuzhenghui
13e42707a0
feat(esp_hw_support): add clk tree source gate management api 2024-09-11 10:53:01 +08:00
wuzhenghui
c41d432397
fix(ulp): fix uart driver delete order in lp uart test case 2024-09-11 10:53:00 +08:00
wuzhenghui
71fb3d2f31
fix(esp_system): fix test rodata being prefetched into cache unexpectedly 2024-09-11 10:53:00 +08:00
wuzhenghui
05e74480f5
feat(esp_system): gate some clock by default to optmize esp32p4 active power 2024-09-11 10:53:00 +08:00
Zhang Xiao Yan
fba9b50456 Merge branch 'docs/update_startup_for_single_core_chip' into 'master'
docs: update startup.rst description for single-core chip support

See merge request espressif/esp-idf!33393
2024-09-11 10:32:44 +08:00
Zhang Xiao Yan
56ac70430e docs: update startup.rst description for single-core chip support 2024-09-11 10:32:44 +08:00
Wang Tao
9b242a4817 Merge branch 'feat/add_protect_for_softap_send_no_bss_deauth' into 'master'
feat(wifi): add protect for softap when sending mgmt frame to not connected station

Closes WIFIBUG-453、WIFIBUG-624、WIFIBUG-416、WIFIBUG-439、WIFI-6569

See merge request espressif/esp-idf!31780
2024-09-11 10:21:08 +08:00
WanqQixiang
f62628d334 feat(openthread): Replace netconn external resolve hook with dns external hook 2024-09-11 09:59:06 +08:00
Kevin (Lao Kaiyao)
a0e954b941 Merge branch 'refactor/prepare_to_split_soc_include_folder' into 'master'
refactor(soc): create soc include folders

See merge request espressif/esp-idf!33303
2024-09-11 09:58:15 +08:00
Zhang Xiao Yan
afd74267c8 Merge branch 'docs/add_application_examples_ble_mesh' into 'master'
docs: update application examples for BLE mesh

See merge request espressif/esp-idf!32187
2024-09-11 09:56:29 +08:00
Ivan Grokhotkov
0a2dc3b2d6 Merge branch 'doc/sdmmc_emmc_support' into 'master'
docs(sdmmc): update information about eMMC support

Closes DOC-8906

See merge request espressif/esp-idf!33022
2024-09-10 22:06:33 +08:00
Song Ruo Jing
9994f493ed feat(lp_io): Add LP_IO support for ESP32C61 2024-09-10 20:50:31 +08:00
Armando (Dou Yiwen)
87b295a35f Merge branch 'feat/ram_loadable_app_c5_c61' into 'master'
ram_app: support c5 c61, fixed PMA15 occupied by ROM issue

Closes IDF-8644, IDF-9251, IDF-10315, and IDF-10951

See merge request espressif/esp-idf!33381
2024-09-10 20:25:36 +08:00
Konstantin Kondrashov
75c917eef8 feat(system): Re-enables the pytest_base_mac_address test for ESP32-C61 2024-09-10 15:09:32 +03:00
Konstantin Kondrashov
f555812975 feat(system): Enables test_ipc_isr_riscv for ESP32-P4 2024-09-10 15:02:42 +03:00
Lou Tianhao
d242b662c4 change(pm): remove some cache regs that don not need to backup now 2024-09-10 19:37:50 +08:00
Lou Tianhao
50ec7f990c fix(ci): take some actions to pass ci 2024-09-10 19:37:50 +08:00
Lou Tianhao
ac76402aff fix(pm): write back cache for psram 2024-09-10 19:37:50 +08:00
Lou Tianhao
d5c58a1d8c fix(pm): add hp power_supply_wait_time_us to avoid power glitch 2024-09-10 19:37:45 +08:00
Rahul Tank
c7a238054a feat(nimble): Add support for ext adv param v2 HCI command 2024-09-10 16:59:40 +05:30
Konstantin Kondrashov
8539760e79 feat(efuse): Updates efuse table for esp32c61 2024-09-10 14:16:29 +03:00
Mahavir Jain
02c3445c66 Merge branch 'fix/adding_check_for_nvs_partition' into 'master'
fix(nvs_sec_provider): Added check for nvs_keys partition

See merge request espressif/esp-idf!33212
2024-09-10 18:11:26 +08:00
cjin
50d410e1c8 feat(ble): support ble light sleep on esp32c5 2024-09-10 15:19:22 +08:00
Ivan Grokhotkov
f789b4eb45 Merge branch 'bugfix/build_test_better_errors' into 'master'
test(build_system): print failed command and output when test fails

See merge request espressif/esp-idf!32962
2024-09-10 15:18:41 +08:00
Ivan Grokhotkov
71fe7543f1
docs(sdmmc): update information about eMMC support
Related to https://esp32.com/viewtopic.php?f=13&t=41088

Co-authored-by: Zhang Shu Xian <zhangshuxian@espressif.com>
2024-09-10 09:14:54 +02:00
Sudeep Mohanty
0b75e75f2c feat(lp_adc): Added example to demonstrate LP ADC usage from LP Core
This commit adds an example which demonstrates how to configure and use
the LP ADC from the LP core while the main core is in deep sleep.
2024-09-10 08:45:11 +02:00
Sudeep Mohanty
594880dae4 test(lp_adc): Added LP Core unit tests for testing LP ADC
Added a unit test to verify that LP ADC1 works and can be read from the
LP Core.
2024-09-10 08:45:11 +02:00
Sudeep Mohanty
1e5efd7fa7 feat(lp_adc): Added support to read LP ADC from the LP core
This commit adds APIs to initialize and configure the LP ADC from the HP
core and also adds APIs to read the raw and converted ADC values from the LP core.
2024-09-10 08:45:11 +02:00
Sudeep Mohanty
d604e09274 feat(lp_adc): Added support for LP ADC initialization to the esp_adc oneshot driver
This commit adds support for LP ADC initialization to the esp_adc
oneshot driver, when it is used from the HP core.
2024-09-10 08:45:11 +02:00
Sudeep Mohanty
f972cd4bbd feat(clk): Addded support for LP ADC clock source for esp32p4
This commit adds support for the LP ADC clock source on the esp32p4.
2024-09-10 08:45:11 +02:00
wangtao@espressif.com
85da8402be feat(wifi): add protect for softap send no bss deauth 2024-09-10 14:23:43 +08:00
Jiang Jiang Jian
72266fd7ce Merge branch 'feature/support_coexist_debug' into 'master'
feat(coex): support GPIO debug

Closes WIFI-6625

See merge request espressif/esp-idf!32371
2024-09-10 14:17:52 +08:00
C.S.M
c2f6144daa fix(i2c): Fix the i2c sda/scl force out register value on some esp chips 2024-09-10 13:45:50 +08:00
andylinpersonal
0e30c42625 feat(esp_system,ulp): Make LP core reserved memory optionally executable in HP core 2024-09-10 12:17:38 +08:00
hrushikesh.bhosale
aaf1f868d5 fix(nvs_sec_provider): Added check for nvs_keys partition
Added check to whether nvs_keys partition is provided or not in partiton csv.
Converted nvs_sec_provider_register_flash_enc_ctr and nvs_sec_provider_register_hmac_ctr
functions from __attribute__(constructor) to ESP_SYSTEM_INIT_FN.
2024-09-10 12:12:02 +08:00
Mahavir Jain
ef221d007a Merge branch 'feat/update_protocol_docs_for_esp32c61' into 'master'
docs(protocols): Updated the protocol docs for esp32c61

Closes IDF-10178

See merge request espressif/esp-idf!33384
2024-09-10 12:10:37 +08:00
Omar Chebib
bc0b04d779 Merge branch 'staging/enabling_panic_test_esp32c61' into 'master'
test(panic): enable tests for esp32c61

Closes IDF-10994

See merge request espressif/esp-idf!33277
2024-09-10 11:37:38 +08:00
Armando
9c81fe6114 fix(mspi): fixed mspi clock wrong on ram loadable app on c61, enable tests on c5 c61 2024-09-10 11:12:03 +08:00
Armando
17fc026c48 fix(pma): fixed pma 15 occupied by rom on c5 issue 2024-09-10 11:12:02 +08:00
Armando
42cf1d8867 fix(mspi): fixed mspi clock wrong on ram loadable app on c5 2024-09-10 11:12:02 +08:00
Lou Tianhao
46af50ee5a fix(pm): mspi cannot access flash when pd pll source 2024-09-10 10:45:57 +08:00
Lou Tianhao
d4447739a9 example(light_sleep); enable lp_timer/gpio/uart wakeup for esp32c61 2024-09-10 10:45:57 +08:00
Lou Tianhao
fd94fe1161 feat(pm): support cpu retention for esp32c61 2024-09-10 10:45:52 +08:00
Lou Tianhao
c9434aaebf change(pm): update pmu analog param for lightsleep(including pu xtal and fosc) & deepsleep 2024-09-10 10:44:13 +08:00
Lou Tianhao
0926a700c2 feat(pm): support basic pmu sleep 2024-09-10 10:44:13 +08:00
liuning
691b6e245b feat(coex): support GPIO debug 2024-09-10 10:40:15 +08:00
C.S.M
9e864ffe26 feat(spi_flash): Add suspend support on esp32c5, esp32c61 2024-09-10 10:36:27 +08:00
laokaiyao
65f49c6a7b refactor(soc): create soc include folders 2024-09-10 09:56:11 +08:00
morris
f0a2091e4d Merge branch 'bugfix/i2c_clear_bus_wrong_calue' into 'master'
fix(i2c): Fix the wrong return value of esp32,esp32s2,esp32s3

See merge request espressif/esp-idf!33403
2024-09-10 09:30:49 +08:00
Roland Dobai
d5341bd455 Merge branch 'fix/fix_shell_detection' into 'master'
fix(activate): use exe instead of comm for parent shell detection

Closes IDF-11080

See merge request espressif/esp-idf!33378
2024-09-09 23:03:22 +08:00
David Cermak
f7129481ed fix(freertos): Update select on Linux target to handle edge cases
* Handle not found "select()" symbol if dlsym() return NULL
* Handle minimum wait time if remaining time < designated minimum sleep
time
2024-09-09 16:52:51 +02:00
Astha Verma
4cbf2eb899 fix(nimble): Added support for bidirectional data trasfer 2024-09-09 18:36:21 +05:30
wuzhenghui
2172aaf6a2
fix(esp_hw_support): add clock retention contents 2024-09-09 20:49:06 +08:00
C.S.M
5141f01e56 fix(i2c): Fix the wrong return value of esp32,esp32s2,esp32s3 2024-09-09 19:15:02 +08:00
Armando (Dou Yiwen)
8d75f0d198 Merge branch 'fix/ram_loadable_app_p4' into 'master'
ram_app: fixed ram loadable app on p4

Closes IDF-8994

See merge request espressif/esp-idf!33312
2024-09-09 18:07:26 +08:00
Jiang Jiang Jian
489ba7c2fa Merge branch 'bugfix/enable_ci_build_by_esp32p4_with_extconn' into 'master'
fix(wifi): enable ci build by sdkconfig.ci.esp32p4_with_extconn

See merge request espressif/esp-idf!33319
2024-09-09 17:27:36 +08:00
Jiang Jiang Jian
9a47de53e1 Merge branch 'feat/support_esp32c2_eco4_rom_mbedtls_v3.6.0_lts' into 'master'
feat(mbedtls): support esp32c2 rev2.0 ROM mbedTLS v3.6.0-LTS

Closes IDF-10680

See merge request espressif/esp-idf!33227
2024-09-09 16:53:53 +08:00
Chai Ji’e
a90000856c Merge branch 'bugfix/fix_wrong_sleep_memory_param_p4_c5_c61' into 'master'
fix(sleep): fix_wrong_sleep_param_for_lp_memory_retention

See merge request espressif/esp-idf!33304
2024-09-09 15:45:18 +08:00
Alexey Lapshin
599c14d8f0 Merge branch 'feature/update-toolchain-to-esp-14.2.0_20240903' into 'master'
feat(tools): update toolchain version to esp-14.2.0_20240906

Closes IDFGH-13033, IDFGH-13355, and IDFGH-13360

See merge request espressif/esp-idf!33295
2024-09-09 14:22:47 +08:00
C.S.M
2014e5ae10 Merge branch 'fix/bus_clear_error' into 'master'
fix(i2c): Fix possible error state in clear the bus

Closes IDFGH-12655

See merge request espressif/esp-idf!33174
2024-09-09 11:51:17 +08:00
hrushikesh.bhosale
737bbb4a91 docs(protocols): Updated the protocol docs for esp32c61
Checked and updated the not_updated_docs for esp32c61 for
protocols examples
2024-09-09 08:55:37 +05:30
Zhang Xiao Yan
10f10ad313 Merge branch 'docs/update_application_examples_phy' into 'master'
docs: add application examples for phy.rst

See merge request espressif/esp-idf!32470
2024-09-09 10:47:11 +08:00
Linda
1263b97c5b docs: update application examples for BLE mesh 2024-09-09 10:45:55 +08:00
Armando
6933ba39bc fix(system): fixed ram loadable app on p4 2024-09-09 10:31:48 +08:00
morris
24047f9a04 Merge branch 'docs/sync_psram_noinit_and_bss_description' into 'master'
docs(psram): sync psram noinit description

See merge request espressif/esp-idf!33360
2024-09-09 10:00:07 +08:00
Peter Marcisovsky
3362e18432 fix(usb_host): Update log level and error poropagation 2024-09-08 18:43:42 +02:00
Wang Meng Yang
160bd658fc Merge branch 'bugfix/exit_sniff_immed_enter_sniff' into 'master'
fix(bt/bluedroid): Fix the protocol stack to exit sniff mode

Closes BTQABR2023-291

See merge request espressif/esp-idf!33305
2024-09-08 15:49:31 +08:00
Alexey Lapshin
57d39c3923 fix(driver_spi): supress overlapping buffers warning for GCC analyzer 2024-09-08 13:53:52 +07:00
Alexey Lapshin
401b395106 fix(hal): supress overlapping buffers warning for GCC analyzer 2024-09-08 13:53:52 +07:00
Alexey Lapshin
eee58bb717 fix(camera_dsi): update esp_cam_sensor example dependency 2024-09-08 13:53:52 +07:00
Alexey Lapshin
2dc4ca4fa6 fix(ci): ignore .section field for check_public_headers.py 2024-09-08 13:53:52 +07:00
Alexey Lapshin
d529da25c4 fix(driver_dac): fix GCC 14 analyzer warnings
error: check of 's_ddp' for NULL after already dereferencing it
2024-09-08 13:53:52 +07:00
Alexey Lapshin
1370511dff fix(esp_timer): place esp_timer_get_time test to IRAM 2024-09-08 13:53:52 +07:00
Alexey Lapshin
29b028076a feat(cxx): change test value of __cplusplus to 202302L 2024-09-08 13:53:52 +07:00
Alexey Lapshin
664c2e6b77 feat(build): add CONFIG_COMPILER_DISABLE_GCC14_WARNINGS option 2024-09-08 13:53:52 +07:00
Alexey Lapshin
6f1671c9c9 fix(i2c): fix memory allocation size in example 2024-09-08 13:53:52 +07:00
Alexey Lapshin
f1c0fc0bbd fix(bt): fix alloc-size warning
Warning: allocation of insufficient size '36' for type 'tBTA_DM_MSG'
with size '320' [-Werror=alloc-size]
2024-09-08 13:53:52 +07:00
Alexey Lapshin
205e814563 fix(esp_psram): fix dead code compilation 2024-09-08 13:53:52 +07:00
Alexey Lapshin
5737ba06c3 fix(esp_hw_support): fix acessing array bellow bounds 2024-09-08 13:53:52 +07:00
Alexey Lapshin
a262e879d1 fix(esp_http_server): fix GCC 14 analyzer warnings 2024-09-08 13:53:52 +07:00
Alexey Lapshin
725b9ec81e fix(freertos): fix GCC 14 analyzer warnings 2024-09-08 13:53:52 +07:00
Alexey Lapshin
06fdb02435 fix(newlib): fix GCC 14 analyzer warnings 2024-09-08 13:53:52 +07:00
Alexey Lapshin
5e4d6190d8 fix(pthread): fix GCC 14 analyzer warnings 2024-09-08 13:53:52 +07:00
Alexey Lapshin
4d2881dac1 fix(hal): fix GCC 14 analyzer warnings 2024-09-08 13:53:52 +07:00
Alexey Lapshin
7498f4655a fix(esp_system): fix GCC 14 analyzer warnings 2024-09-08 13:53:52 +07:00
Alexey Lapshin
4c87af6359 fix(build): fix calloc warnings 2024-09-08 13:53:52 +07:00
Alexey Lapshin
47212eaa3a feat(tools): update toolchain version to esp-14.2.0_20240903
Closes https://github.com/espressif/esp-idf/issues/13979
Closes https://github.com/espressif/esp-idf/issues/14273
Closes https://github.com/espressif/esp-idf/issues/14267
2024-09-08 13:52:22 +07:00
Roman Leonov
a9d960a81f refactor(hub): Cleaned up dev_tree_node debug output, moved node freeing 2024-09-06 22:44:37 +02:00
wuzhenghui
fd79c593fb fix(ci): increase uart driver test memory leak threshold 2024-09-07 02:04:43 +08:00
wuzhenghui
0272fc405b change(esp_hw_support): update test cases with new sub-mode setting API 2024-09-07 02:04:43 +08:00
wuzhenghui
5184d7ec98 change(esp_hw_support): replace esp_sleep_periph_use_8m with new API 2024-09-07 02:04:43 +08:00
wuzhenghui
7555686649 change(esp_hw_support): replace rtc_sleep_enable_ultra_low with new API 2024-09-07 02:04:43 +08:00
wuzhenghui
b1df2688ce change(esp_hw_support): replace esp_sleep_enable_adc_tsens_monitor with new API 2024-09-07 02:04:43 +08:00
wuzhenghui
417edbb2e2 feat(esp_hw_support): introduce sub sleep mode config API 2024-09-07 02:04:38 +08:00
Wan Lei
92fc3e9a5d Merge branch 'refa/replce_esp_dma_xxx_malloc_api' into 'master'
refa(spi): clean up esp_dma_xxx memory allocation code

Closes IDF-9656

See merge request espressif/esp-idf!31239
2024-09-06 22:08:22 +08:00
Frantisek Hrbata
65d18fce4c fix(activate): use exe instead of comm for parent shell detection
Currently, we are using psutil.Process().name(), which includes the
command as entered on the command line. This becomes an issue if the
export script is initiated within another script.

run.sh

    #!/usr/bin/bash
    . ./export.sh

In this case the activate script will see `run.sh` instead of bash.

/proc/<pid>/com vs /proc/<pid>/exe

Use exe(), which contains the full executable path to fix this.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-09-06 15:58:24 +02:00
Jiang Guang Ming
5bb93061a3 feat(mbedtls): support rom mbedtls threading layer 2024-09-06 19:27:57 +08:00
Marek Fiala
f90b847cb1 Merge branch 'fix/correct_shell_detection' into 'master'
fix(tools): Corrected detect_shell

See merge request espressif/esp-idf!33365
2024-09-06 19:22:15 +08:00
Alexey Lapshin
c605620073 Merge branch 'fix/keep-got-sections-for-riscv' into 'master'
feat(esp_system): drop .got* sections and add hint

See merge request espressif/esp-idf!32969
2024-09-06 19:21:06 +08:00
Guillaume Souchere
6f37ff7a8f Merge branch 'fix/bootloader-factory-reset-test-app-pin-range' into 'master'
fix(bootloader): Update pin range for factory reset and app test configurations

Closes IDFGH-13623

See merge request espressif/esp-idf!33342
2024-09-06 17:21:38 +08:00
Marek Fiala
24ae042bba fix(tools): Corrected detect_shell
When comparing process name with python,
lowercase the process name in condition.
2024-09-06 11:11:50 +02:00
Wang Meng Yang
ca05aa5cd2 Merge branch 'feature/add_di_api' into 'master'
Feature/add di api

Closes IDFGH-11785

See merge request espressif/esp-idf!32872
2024-09-06 17:11:19 +08:00
Jiang Jiang Jian
386420067a Merge branch 'bugfix/ftm_apsta_bw_issue' into 'master'
Fix FTM issues in AP-STA mode

Closes WIFIBUG-634

See merge request espressif/esp-idf!32276
2024-09-06 16:26:35 +08:00
shenmengjing
f6003fb8bf docs: Update CN translation for several docs 2024-09-06 16:17:32 +08:00
morris
dba8722bc0 Merge branch 'feat/support_esp32c2_eco4_rom_systimer_hal' into 'master'
feat(esp_rom): support esp32c2 rev2.0(ECO4) rom systimer hal

Closes IDF-10677

See merge request espressif/esp-idf!33335
2024-09-06 16:06:10 +08:00
Roland Dobai
e7c0d69215 Merge branch 'feature/python_activation' into 'master'
feat: add python script to activate ESP-IDF environment

Closes IDF-4803

See merge request espressif/esp-idf!31334
2024-09-06 14:37:53 +08:00
Chen Jichang
057b6b72ba docs(psram): sync psram noinit description 2024-09-06 14:30:54 +08:00
C.S.M
3ccdd8b397 fix(i2c): Fix possible error state in clear the bus,
Closes https://github.com/espressif/esp-idf/issues/13647
2024-09-06 14:28:26 +08:00
morris
9ec1042dff Merge branch 'test/fix_mspi_ci_c61' into 'master'
fix(mspi): Fix the mspi ci build test on esp32c61

See merge request espressif/esp-idf!33355
2024-09-06 14:23:53 +08:00
Roland Dobai
17fed13a27 Merge branch 'distutils' into 'master'
fix(tools): remove distutils to support python 3.12

Closes IDFGH-13510

See merge request espressif/esp-idf!33260
2024-09-06 14:23:04 +08:00
Chen Ji Chang
646d2f9e4a Merge branch 'feat/parlio_tx_support_psram_buffer' into 'master'
feat(parlio_tx): support transmit buffer in external PSRAM

Closes IDF-10981

See merge request espressif/esp-idf!33347
2024-09-06 14:00:35 +08:00
C.S.M
f36fb4cdb0 fix(mspi): Fix the mspi ci build test on esp32c61 2024-09-06 13:29:14 +08:00
Rahul Tank
0f11052406 Merge branch 'bugfix/add_notify_flag_for_wifi_prov' into 'master'
fix(wifi_prov): Add notify characteristic flag support

See merge request espressif/esp-idf!32311
2024-09-06 13:27:52 +08:00
Rahul Tank
b341791f78 Merge branch 'bugfix/make_cccd_flags_configurable' into 'master'
fix(nimble): Make CCCD flags configurable

Closes BLERP-954

See merge request espressif/esp-idf!32971
2024-09-06 13:19:17 +08:00
Guillaume Souchere
ab4e658af6 fix(bootloader): Update pin range for factory reset and app test
Update the range for pin selection of BOOTLOADER_NUM_PIN_APP_TEST
and BOOTLOADER_NUM_PIN_FACTORY_RESET based on the selected target.

Closes https://github.com/espressif/esp-idf/issues/14508
2024-09-06 07:18:46 +02:00
Island
53dff5357f Merge branch 'ble_dev/esp32c2eco4_chip_20240903' into 'master'
change(ble): update c2 eco4 ld file

See merge request espressif/esp-idf!33327
2024-09-06 11:24:43 +08:00
Chen Jichang
227f80ff88 feat(parlio_tx): support psram buffer 2024-09-06 11:20:39 +08:00
Armando (Dou Yiwen)
5dff189341 Merge branch 'feat/xip_psram_c5' into 'master'
psram: xip_psram support on c5/c61, also fixed cache writeback/invalidate not work issue on c61

Closes IDF-8688, IDF-9292, and IDF-11008

See merge request espressif/esp-idf!33265
2024-09-06 10:39:57 +08:00
Jiang Guang Ming
d0ec6fc04d fix(mbedtls): MBEDTLS_CMAC_C not effective when MBEDTLS_USE_CRYPTO_ROM_IMPL enabled 2024-09-06 09:55:27 +08:00
Jiang Guang Ming
d74ff5224c feat(mbedtls): support ROM mbedtls v3.6.0 on C2 rev2.0(ECO4) 2024-09-06 09:55:27 +08:00
Jiang Guang Ming
4955a199a8 feat(esp_rom): include rom.mbedtls.eco4.ld with C2 rev2.0(ECO4) select 2024-09-06 09:55:27 +08:00
Jiang Guang Ming
d7ea73ad66 feat(esp_rom): update esp32c2.rom.mbedtls.eco4.ld 2024-09-06 09:55:27 +08:00
Tomas Rezucha
c2b5339275 Merge branch 'feat/usb_disconnect_api' into 'master'
refactor(usb): Update HCD tests to use port power off for disconnections

Closes IDF-11006

See merge request espressif/esp-idf!31179
2024-09-06 09:46:57 +08:00
Marius Vikhammer
72bcaf1d74 Merge branch 'feature/c61_rtc_mem_remove' into 'master'
feat(system): remove references to RTC mem on C61

See merge request espressif/esp-idf!33291
2024-09-06 09:42:01 +08:00
Tomas Rezucha
19bf686d5e feat(usb/host): Enable USB Host tests on P4 2024-09-05 19:41:07 +02:00
Tomas Rezucha
3857f779cc fix(usb/host): Correctly handle unpowered port in HUB 2024-09-05 19:40:52 +02:00
muhaidong
5e4674775b fix(wifi): enable ci build by sdkconfig.ci.esp32p4_with_extconn 2024-09-05 20:29:40 +08:00
Armando
5316a36175 fix(cache): fixed cache writeback/invalidate cannot reach higher vaddr parts 2024-09-05 18:47:02 +08:00
Rahul Tank
fb55646270 fix(nimble): Add notify characteristic flag support 2024-09-05 16:16:08 +05:30
Nachiket Kukade
4854bf8640 fix(esp_wifi): Fix FTM issues in AP-STA mode
Add AP-STA mode support in FTM example
Update wifi libs with below changes -
- Use ex-AP's bandwidth in FTM request when connected
- Allow Bandwidth downgrade in FTM negotiation
- Use separate calibration when Initiator performs 20MHz FTM
  while in-AP is in 40MHz
2024-09-05 16:02:27 +05:30
Darian Leung
cac0ef9d11 refactor(usb): Remove use of usb_phy_action() from unit tests
Currently, USB Host unit tests that require a software triggered disconnection/
reconnection rely on the 'usb_phy_action()' function.

This commit replaces those calls with 'hcd_port_command()' or
'usb_host_lib_set_root_port_power()'.

Note: Also removed 'test_usb_common.h/c' as it is no longer necessary are the
function call replacements.
2024-09-05 12:27:27 +02:00
Darian Leung
54db1cda8b feat(usb): Add usb_host_lib_set_root_port_power()
This commit adds the usb_host_lib_set_root_port_power() function. This provides
a public API for users to power the root port OFF or ON at runtime, thus trigger
a disconnection or allow connections respectively.

In addition, the usb_host_config_t.root_port_unpowered install configuration is
provided to allow users to install the USB Host Library without automatically
powering ON the root port.
2024-09-05 12:27:27 +02:00
Chen Jichang
7dd15bee31 fix(parlio_tx): fix error in first transfer and 1 byte transfer
On p4, the clock was configured in the wrong order causing a dropped
count on the first transmission. And gdma eof event fails to trigger
parlio_tx eof event when transmitting single byte.
2024-09-05 17:12:49 +08:00
Alexey Lapshin
73987108cd feat(esp_system): drop .got* sections and add hint
Closes https://github.com/espressif/esp-idf/issues/14296
2024-09-05 15:47:01 +07:00
Marek Fiala
7b417fc3f2 feat(tools): Add backup option to use legacy export script
This feature serves as an immediate fix in case
the new export approach causes issues.
The user can simply set the environment variable `ESP_IDF_LEGACY_EXPORT`,
and the old export script will be used.
2024-09-05 10:13:05 +02:00
Marek Fiala
88527faff8 feat(tools): Added Windows shells support + refactoring 2024-09-05 10:13:04 +02:00
Frantisek Hrbata
1c22f6c4e8 feat: add python script to activate ESP-IDF environment
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-09-05 10:13:03 +02:00
liqigan
be1c677bdd feat(esp_hid): Create Device ID Service record in esp_hid_device example
Closes https://github.com/espressif/esp-idf/issues/12880
2024-09-05 15:33:03 +08:00
liqigan
c564817862 feat(bt/bluedroid): Add API to create Device ID Service record 2024-09-05 15:32:56 +08:00
liqigan
8a5184e68e change(bt/bluedroid): Limited SDP service discovery operation 2024-09-05 15:32:12 +08:00
liqigan
9becdfdc6d change(bt/bluedroid): Release record data after SDP record created 2024-09-05 15:32:12 +08:00
Omar Chebib
d025ff4073 test(panic): enable tests for esp32c61 2024-09-05 14:50:58 +08:00
Jiang Guang Ming
f3eaa7abae feat(esp_rom): support esp32c2 rev2.0(ECO4) rom systimer hal 2024-09-05 11:04:42 +08:00
wanlei
d15e53d876 refa(spi): clean up esp_dma_xxx memory allocation code 2024-09-05 10:56:30 +08:00
Guilhem Saurel
727c6a82ea fix(tools): python3.12 support
remove distutils use
2024-09-04 18:00:56 +02:00
Erhan Kurubas
f8202963e6 feat(sysview): add sbom manifest file 2024-09-04 18:38:01 +03:00
snake-4
8a39db3fae fix(freertos): Made select function non-blocking on Linux target
The select function wrapper was rewritten to be non-blocking
on Linux systems, as it was stealing all the CPU time
from lower priority tasks when called from a higher priority task.
This is because the FreeRTOS scheduler does not know
that the task thread is sleeping during the system call.

This issue manifests all "slow" system calls on the Linux target,
but handling the case of select fixes the problems for most ESP-IDF components.

The FreeRTOS POSIX port documentation lists this as a known issue,
so user code is responsible handling this case if other system calls are used,
even if unknowingly.

This closes GH issue #14395 "select() blocks the FreeRTOS scheduler on Linux target"
2024-09-04 15:15:26 +02:00
shreeyash
215f95c110 fix(nimble): Make CCCD flags configurable 2024-09-04 17:53:21 +05:30
Shen Weilong
25189b190f change(ble): update c2 eco4 ld file 2024-09-04 20:08:09 +08:00
Marek Fiala
ccf5989505 feat(tools): Exclude modified folders by rebuild 2024-09-04 12:48:15 +02:00
Marek Fiala
f0ca91b103 feat(tools): Update tools: cmake, ninja, ccache
cmake  v3.24.0 -> v3.30.2
ninja  v1.11.1 -> v1.12.1
ccache v4.8    -> v4.10.2

Closes https://github.com/espressif/esp-idf/pull/14376
2024-09-04 12:48:14 +02:00
xiongweichao
a55d8bf12b fix(bt/bluedroid): Fix the protocol stack to exit sniff mode
- Already in result mode but request change indication has not been cleared
2024-09-04 15:08:01 +08:00
chaijie@espressif.com
c9d4913393 fix(sleep): fix_wrong_sleep_param_for_lp_memory_retention 2024-09-04 15:02:15 +08:00
Marius Vikhammer
520fda61cd feat(system): remove references to RTC mem on C61 2024-09-04 11:16:36 +08:00
Armando
fce2680e91 feat(psram): xip psram c61 2024-09-03 18:17:03 +08:00
Armando
8842e5764f feat(psram): xip psram c5 2024-09-03 18:17:03 +08:00
Linda
58f18216ed docs: add application examples for phy.rst 2024-09-02 14:49:31 +08:00
Andste82
681b372668 fix(spinlock): comparison of integer expressions of different signedness 2024-08-30 11:28:16 +02:00
harshal.patil
3b97011e39
fix(esp_security/ds): Clean up DS trying to re-acquire MPI lock post common crypto lock layer 2024-08-23 17:53:55 +05:30
Ivan Grokhotkov
5e9ac5bdf7
test(build_system): print failed command and output when test fails 2024-08-22 13:59:43 +02:00
685 changed files with 18450 additions and 3636 deletions

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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")

View File

@ -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

View 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.

View File

@ -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;
}

View File

@ -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"

View File

@ -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

View File

@ -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();

View File

@ -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();

View File

@ -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:

View File

@ -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

View File

@ -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--------------------------

View File

@ -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)

View File

@ -156,6 +156,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 +185,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 +382,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 +395,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"

View File

@ -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

View File

@ -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");

@ -1 +1 @@
Subproject commit d874f55e1132416fe18293ae1aa9ac73c40b3261
Subproject commit b8ef2c474d392a88ea7e6626f89acf1fa5f30e4a

@ -1 +1 @@
Subproject commit 53056440bc6e76f5bf00fd920769a4979dcc7d66
Subproject commit b4f67e85c54cc8f55b5130e47805dc8c906a736c

View File

@ -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,13 @@ 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 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 +164,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 +190,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

View File

@ -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 **/
/*********************************************************************************************/

View File

@ -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

View File

@ -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
@ -133,8 +141,10 @@ typedef enum {
ESP_AVRC_CT_PLAY_STATUS_RSP_EVT = 3, /*!< play status response event */
ESP_AVRC_CT_CHANGE_NOTIFY_EVT = 4, /*!< notification event */
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_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

View File

@ -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
*/
@ -14,123 +14,163 @@
extern "C" {
#endif
#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_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. */
ESP_SDP_NO_RESOURCE, /*!< No more resource */
ESP_SDP_NEED_INIT, /*!< SDP module shall init first */
ESP_SDP_NEED_DEINIT, /*!< SDP module shall deinit first */
ESP_SDP_NO_CREATE_RECORD, /*!< No record created */
ESP_SDP_SUCCESS = 0, /*!< Successful operation. */
ESP_SDP_FAILURE, /*!< Generic failure. */
ESP_SDP_NO_RESOURCE, /*!< No more resource */
ESP_SDP_NEED_INIT, /*!< SDP module shall init first */
ESP_SDP_NEED_DEINIT, /*!< SDP module shall deinit first */
ESP_SDP_NO_CREATE_RECORD, /*!< No record created */
} esp_sdp_status_t;
/**
* @brief SDP callback function events
*/
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_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 */
ESP_SDP_INIT_EVT = 0, /*!< When SDP is initialized, 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 */
} esp_sdp_cb_event_t;
/**
* @brief SDP record type
*/
typedef enum {
ESP_SDP_TYPE_RAW, /*!< Used to carry raw SDP search data for unknown UUIDs */
ESP_SDP_TYPE_MAP_MAS, /*!< Message Access Profile - Server */
ESP_SDP_TYPE_MAP_MNS, /*!< Message Access Profile - Client (Notification Server) */
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_RAW, /*!< Used to carry raw SDP search data for unknown UUIDs */
ESP_SDP_TYPE_MAP_MAS, /*!< Message Access Profile - Server */
ESP_SDP_TYPE_MAP_MNS, /*!< Message Access Profile - Client (Notification Server) */
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_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 */
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 */
typedef struct {
esp_bluetooth_sdp_types_t type; /*!< SDP type */
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 */
} esp_bluetooth_sdp_hdr_t;
// 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 */
} esp_bluetooth_sdp_hdr_overlay_t;
/**
* @brief Raw SDP record
*/
typedef struct {
esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
esp_bt_uuid_t uuid; /*!< UUID type include uuid and uuid length */
int user1_ptr_len; /*!< Length of raw SDP data */
uint8_t *user1_ptr; /*!< Raw SDP data */
} esp_bluetooth_sdp_raw_record_t;
/**
* @brief Message Access Profile - Server parameters
*/
typedef struct bluetooth_sdp_mas_record {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
uint32_t mas_instance_id; /*!< MAS Instance ID */
uint32_t supported_features; /*!< Map supported features */
uint32_t supported_message_types; /*!< Supported message types */
typedef struct {
esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
uint32_t mas_instance_id; /*!< MAS Instance ID */
uint32_t supported_features; /*!< Map supported features */
uint32_t supported_message_types; /*!< Supported message types */
} esp_bluetooth_sdp_mas_record_t;
/**
* @brief Message Access Profile - Client (Notification Server) parameters
*/
typedef struct bluetooth_sdp_mns_record {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
uint32_t supported_features; /*!< Supported features */
typedef struct {
esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
uint32_t supported_features; /*!< Supported features */
} esp_bluetooth_sdp_mns_record_t;
/**
* @brief Phone Book Profile - Server parameters
*/
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_repositories; /*!< Supported Repositories */
typedef struct {
esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
uint32_t supported_features; /*!< PBAP Supported Features */
uint32_t supported_repositories; /*!< Supported Repositories */
} esp_bluetooth_sdp_pse_record_t;
/**
* @brief Phone Book Profile - Client parameters
*/
typedef struct bluetooth_sdp_pce_record {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
typedef struct {
esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
} esp_bluetooth_sdp_pce_record_t;
/**
* @brief Object Push Profile parameters
*/
typedef struct bluetooth_sdp_ops_record {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
int supported_formats_list_len; /*!< Supported formats list length */
uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; /*!< Supported formats list */
typedef struct {
esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
int supported_formats_list_len; /*!< Supported formats list length */
uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; /*!< Supported formats list */
} esp_bluetooth_sdp_ops_record_t;
/**
* @brief SIM Access Profile parameters
*/
typedef struct bluetooth_sdp_sap_record {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
typedef struct {
esp_bluetooth_sdp_hdr_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 {
esp_bluetooth_sdp_hdr_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_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_hdr_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,44 +181,43 @@ typedef union {
* @brief ESP_SDP_INIT_EVT
*/
struct sdp_init_evt_param {
esp_sdp_status_t status; /*!< status */
} init; /*!< SDP callback param of ESP_SDP_INIT_EVT */
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 */
} deinit; /*!< SDP callback param of ESP_SDP_DEINIT_EVT */
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 */
int record_count; /*!< Number of SDP records */
esp_bluetooth_sdp_record_t *records;/*!< SDP records */
} search; /*!< SDP callback param of ESP_SDP_SEARCH_COMP_EVT */
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 */
} 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 */
int record_handle; /*!< SDP record handle */
} create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */
esp_sdp_status_t status; /*!< Status */
int record_handle; /*!< SDP record handle */
} create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */
/**
* @brief ESP_SDP_REMOVE_RECORD_COMP_EVT
*/
struct sdp_remove_record_evt_param {
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_status_t status; /*!< Status */
} remove_record; /*!< SDP callback param of ESP_SDP_REMOVE_RECORD_COMP_EVT */
} esp_sdp_cb_param_t;
/**
* @brief SDP callback function type.

View File

@ -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;

View File

@ -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 */

View 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 */

View 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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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"
@ -1086,22 +1087,67 @@ UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr )
tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info,
UINT32 *p_handle )
{
tBTA_STATUS status = BTA_FAILURE;
tBTA_STATUS status = BTA_FAILURE;
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));
}
bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION);
status = BTA_SUCCESS;
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
/*******************************************************************************
**

View File

@ -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;

View File

@ -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
/*******************************************************************************
**

View File

@ -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

View File

@ -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 */
@ -108,14 +115,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);
/*******************************************************************************
**

View File

@ -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

View File

@ -49,10 +49,11 @@ typedef void (*tBTA_SDP_ACTION)(tBTA_SDP_MSG *p_data);
/* action function list */
const tBTA_SDP_ACTION bta_sdp_action[] = {
bta_sdp_enable, /* BTA_SDP_API_ENABLE_EVT */
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_enable, /* BTA_SDP_API_ENABLE_EVT */
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 */
};
/*******************************************************************************

View File

@ -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;
@ -375,8 +416,8 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
record->pse.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.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
record->raw.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)) {
@ -558,7 +602,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 +620,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);
}
}

View File

@ -101,15 +101,27 @@ 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 */
osi_free(p_bta_sdp_cfg->p_sdp_db);
p_bta_sdp_cfg->p_sdp_db = NULL;
#endif
return (status);
return BTA_SDP_SUCCESS;
}
/*******************************************************************************

View File

@ -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

View File

@ -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;

View File

@ -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(&param, 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, &param);
}
#endif
if (rc_features & BTA_AV_FEAT_RCTG) {
esp_avrc_ct_cb_param_t param;
memset(&param, 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(&param, 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, &param);
btc_avrc_tg_cb_to_app(ESP_AVRC_TG_CONNECTION_STATE_EVT, &param);
}
} 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(&param, 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, &param);
}
break;
case BTA_AV_CA_DATA_EVT: {
esp_avrc_ct_cb_param_t param;
memset(&param, 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, &param);
/* 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);
}

View File

@ -34,79 +34,77 @@ 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;
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;
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;
} bluetooth_sdp_hdr_overlay;
typedef struct _bluetooth_sdp_raw_record {
bluetooth_sdp_hdr hdr;
esp_bt_uuid_t uuid;
int user1_ptr_len;
uint8_t *user1_ptr;
} bluetooth_sdp_raw_record;
typedef struct _bluetooth_sdp_mas_record {
bluetooth_sdp_hdr_overlay hdr;
uint32_t mas_instance_id;
uint32_t supported_features;
uint32_t supported_message_types;
bluetooth_sdp_hdr hdr;
uint32_t mas_instance_id;
uint32_t supported_features;
uint32_t supported_message_types;
} bluetooth_sdp_mas_record;
typedef struct _bluetooth_sdp_mns_record {
bluetooth_sdp_hdr_overlay hdr;
uint32_t supported_features;
bluetooth_sdp_hdr hdr;
uint32_t supported_features;
} bluetooth_sdp_mns_record;
typedef struct _bluetooth_sdp_pse_record {
bluetooth_sdp_hdr_overlay hdr;
uint32_t supported_features;
uint32_t supported_repositories;
bluetooth_sdp_hdr hdr;
uint32_t supported_features;
uint32_t supported_repositories;
} bluetooth_sdp_pse_record;
typedef struct _bluetooth_sdp_pce_record {
bluetooth_sdp_hdr_overlay hdr;
bluetooth_sdp_hdr hdr;
} bluetooth_sdp_pce_record;
typedef struct _bluetooth_sdp_ops_record {
bluetooth_sdp_hdr_overlay hdr;
int supported_formats_list_len;
uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH];
bluetooth_sdp_hdr hdr;
int supported_formats_list_len;
uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH];
} bluetooth_sdp_ops_record;
typedef struct _bluetooth_sdp_sap_record {
bluetooth_sdp_hdr_overlay hdr;
bluetooth_sdp_hdr hdr;
} bluetooth_sdp_sap_record;
typedef struct _bluetooth_sdp_dip_record {
bluetooth_sdp_hdr 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_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_hdr 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__ */

View File

@ -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

View File

@ -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__

View File

@ -17,7 +17,7 @@
#include "osi/allocator.h"
#include "esp_sdp_api.h"
#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE)
#if (defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE)
typedef enum {
SDP_RECORD_FREE = 0,
@ -25,12 +25,21 @@ typedef enum {
} sdp_state_t;
typedef struct {
sdp_state_t state;
uint8_t di : 1;
uint8_t primary_di : 1;
uint8_t reserved : 6;
} sdp_flag_t;
typedef struct {
uint8_t state;
sdp_flag_t flag;
int sdp_handle;
bluetooth_sdp_record* record_data;
esp_bt_uuid_t uuid;
void* record_data;
} sdp_slot_t;
typedef struct {
bool search_allowed;
sdp_slot_t *sdp_slots[SDP_MAX_RECORDS];
osi_mutex_t sdp_slot_mutex;
} sdp_local_param_t;
@ -48,6 +57,21 @@ static sdp_local_param_t *sdp_local_param_ptr;
#define is_sdp_init() (&sdp_local_param != NULL && sdp_local_param.sdp_slot_mutex != NULL)
#endif
static void btc_sdp_cleanup(void)
{
#if SDP_DYNAMIC_MEMORY == TRUE
if (sdp_local_param_ptr) {
#endif
if (sdp_local_param.sdp_slot_mutex) {
osi_mutex_free(&sdp_local_param.sdp_slot_mutex);
sdp_local_param.sdp_slot_mutex = NULL;
}
#if SDP_DYNAMIC_MEMORY == TRUE
osi_free(sdp_local_param_ptr);
sdp_local_param_ptr = NULL;
}
#endif
}
static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param)
{
@ -57,46 +81,38 @@ static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_
}
}
static void sdp_disable_handler(void)
static int get_sdp_record_size(bluetooth_sdp_record* in_record)
{
btc_msg_t msg;
bt_status_t status;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_SDP;
msg.act = BTA_SDP_DISENABLE_EVT;
status = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
if (status != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed", __func__);
}
}
static int get_sdp_records_size(bluetooth_sdp_record* in_record, int count)
{
bluetooth_sdp_record* record = in_record;
bluetooth_sdp_record *record = in_record;
int records_size = 0;
for(int i = 0; i < count; i++) {
record = &in_record[i];
switch (record->hdr.type) {
case SDP_TYPE_DIP_SERVER:
records_size = sizeof(bluetooth_sdp_record);
break;
case SDP_TYPE_RAW:
if (record->raw.user1_ptr != NULL) {
records_size += record->raw.user1_ptr_len;
}
/* fall through */
default:
records_size += sizeof(bluetooth_sdp_record);
records_size += record->hdr.service_name_length;
if(record->hdr.service_name_length > 0){
if (record->hdr.service_name_length > 0) {
records_size++; /* + '\0' termination of string */
}
records_size += record->hdr.user1_ptr_len;
records_size += record->hdr.user2_ptr_len;
break;
}
return records_size;
}
static void set_sdp_handle(int id, int handle)
static void set_sdp_slot_info(int id, int sdp_handle, esp_bt_uuid_t *uuid)
{
sdp_slot_t *slot = NULL;
BTC_TRACE_DEBUG("%s() id=%d to handle=0x%08x", __func__, id, handle);
BTC_TRACE_DEBUG("%s() id=%d to sdp_handle=0x%08x", __func__, id, sdp_handle);
if(id >= SDP_MAX_RECORDS) {
BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
@ -104,34 +120,68 @@ static void set_sdp_handle(int id, int handle)
}
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
slot = sdp_local_param.sdp_slots[id];
if (slot == NULL) {
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
BTC_TRACE_ERROR("%s() id=%d to handle=0x%08x, set failed", __func__, id, handle);
return;
}
slot->sdp_handle = handle;
do {
slot = sdp_local_param.sdp_slots[id];
if (slot == NULL) {
BTC_TRACE_ERROR("%s() id = %d ", __func__, id);
break;
}
if (slot->state != SDP_RECORD_ALLOCED) {
BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id,
sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED);
break;
}
slot->sdp_handle = sdp_handle;
slot->record_data = NULL;
if (uuid) {
memcpy(&slot->uuid, uuid, sizeof(esp_bt_uuid_t));
} else {
memset(&slot->uuid, 0, sizeof(esp_bt_uuid_t));
}
} while (0);
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
}
static bool get_sdp_record_by_handle(int handle, bluetooth_sdp_record* record)
static void get_sdp_slot_info(int id, int *sdp_handle, esp_bt_uuid_t *uuid, sdp_flag_t *flag)
{
sdp_slot_t *slot = NULL;
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
for (int i = 0; i < SDP_MAX_RECORDS; i++) {
slot = sdp_local_param.sdp_slots[i];
if ((slot != NULL) && (slot->sdp_handle == handle)) {
memcpy(record, slot->record_data, sizeof(bluetooth_sdp_record));
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
return true;
}
if(id >= SDP_MAX_RECORDS) {
BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
return;
}
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
do {
slot = sdp_local_param.sdp_slots[id];
if (slot == NULL) {
break;
}
if (slot->state != SDP_RECORD_ALLOCED) {
BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id,
sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED);
break;
}
if (sdp_handle) {
*sdp_handle = slot->sdp_handle;
}
if (uuid) {
memcpy(uuid, &slot->uuid, sizeof(esp_bt_uuid_t));
}
if (flag) {
*flag = slot->flag;
}
} while (0);
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
return false;
}
static int get_sdp_slot_id_by_handle(int handle)
@ -152,9 +202,10 @@ static int get_sdp_slot_id_by_handle(int handle)
return -1;
}
static sdp_slot_t *start_create_sdp(int id)
static bluetooth_sdp_record *start_create_sdp(int id)
{
sdp_slot_t *sdp_slot = NULL;
sdp_slot_t *slot = NULL;
bluetooth_sdp_record* record_data = NULL;
if(id >= SDP_MAX_RECORDS) {
BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
@ -162,64 +213,94 @@ static sdp_slot_t *start_create_sdp(int id)
}
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
sdp_slot = sdp_local_param.sdp_slots[id];
if (sdp_slot == NULL) {
BTC_TRACE_ERROR("%s() id = %d ", __func__, id);
} else if(sdp_slot->state != SDP_RECORD_ALLOCED) {
BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__,
id, sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED);
/* The record have been removed before this event occurred - e.g. deinit */
sdp_slot = NULL;
}
do {
slot = sdp_local_param.sdp_slots[id];
if (slot == NULL) {
BTC_TRACE_ERROR("%s() id = %d ", __func__, id);
break;
}
if (slot->state != SDP_RECORD_ALLOCED) {
BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id,
sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED);
break;
}
record_data = slot->record_data;
} while (0);
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
return sdp_slot;
return record_data;
}
/* Deep copy all content of in_records into out_records.
* out_records must point to a chunk of memory large enough to contain all
* the data. Use getSdpRecordsSize() to calculate the needed size. */
static void copy_sdp_records(bluetooth_sdp_record* in_records, bluetooth_sdp_record* out_records, int count)
static void copy_sdp_record_common(bluetooth_sdp_record* in_record, bluetooth_sdp_record* out_record)
{
bluetooth_sdp_record *in_record;
bluetooth_sdp_record *out_record;
char *free_ptr = (char*)(&out_records[count]); /* set pointer to after the last entry */
uint8_t *free_ptr = (uint8_t *)(out_record + 1); /* set pointer to after the last entry */
for(int i = 0; i < count; i++) {
in_record = &in_records[i];
out_record = &out_records[i];
*out_record = *in_record;
memcpy(out_record, in_record, sizeof(bluetooth_sdp_record));
if(in_record->hdr.service_name == NULL || in_record->hdr.service_name_length == 0) {
out_record->hdr.service_name = NULL;
out_record->hdr.service_name_length = 0;
} else {
out_record->hdr.service_name = free_ptr; // Update service_name pointer
// Copy string
memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length);
free_ptr += in_record->hdr.service_name_length;
*(free_ptr) = '\0'; // Set '\0' termination of string
free_ptr++;
}
if(in_record->hdr.user1_ptr != NULL) {
out_record->hdr.user1_ptr = (UINT8*)free_ptr; // Update pointer
memcpy(free_ptr, in_record->hdr.user1_ptr, in_record->hdr.user1_ptr_len); // Copy content
free_ptr += in_record->hdr.user1_ptr_len;
}
if(in_record->hdr.user2_ptr != NULL) {
out_record->hdr.user2_ptr = (UINT8*)free_ptr; // Update pointer
memcpy(free_ptr, in_record->hdr.user2_ptr, in_record->hdr.user2_ptr_len); // Copy content
free_ptr += in_record->hdr.user2_ptr_len;
}
if (in_record->hdr.service_name == NULL || in_record->hdr.service_name_length == 0) {
out_record->hdr.service_name = NULL;
out_record->hdr.service_name_length = 0;
} else {
out_record->hdr.service_name = (char *)free_ptr; // Update service_name pointer
// Copy string
memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length);
free_ptr += in_record->hdr.service_name_length;
*(free_ptr) = '\0'; // Set '\0' termination of string
free_ptr++;
}
if (in_record->hdr.type == SDP_TYPE_RAW && in_record->raw.user1_ptr != NULL) {
out_record->raw.user1_ptr = (UINT8 *)free_ptr; // Update pointer
memcpy(free_ptr, in_record->raw.user1_ptr, in_record->raw.user1_ptr_len); // Copy content
free_ptr += in_record->raw.user1_ptr_len;
}
}
static void copy_sdp_record(bluetooth_sdp_record* in_record, bluetooth_sdp_record* out_record)
{
switch (in_record->hdr.type) {
case SDP_TYPE_DIP_SERVER:
memcpy(out_record, in_record, sizeof(bluetooth_sdp_record));
break;
default:
copy_sdp_record_common(in_record, out_record);
break;
}
}
static bool check_if_primary_di_record(bluetooth_sdp_record* record)
{
bool ret = false;
if (record->hdr.type == SDP_TYPE_DIP_SERVER) {
bluetooth_sdp_dip_record *di_record = (bluetooth_sdp_dip_record *)record;
ret = di_record->primary_record;
}
return ret;
}
static bool check_if_di_record(bluetooth_sdp_record* record)
{
return record->hdr.type == SDP_TYPE_DIP_SERVER ? true : false;
}
static int alloc_sdp_slot(bluetooth_sdp_record* in_record)
{
int i;
int record_size = get_sdp_records_size(in_record, 1);
int record_size = get_sdp_record_size(in_record);
bluetooth_sdp_record *record = NULL;
sdp_slot_t **slot = NULL;
bool is_di_record = check_if_di_record(in_record);
bool is_primary_di_record = check_if_primary_di_record(in_record);
bool primary_di_record_found = false;
record = osi_malloc(record_size);
if (record == NULL) {
@ -227,22 +308,42 @@ static int alloc_sdp_slot(bluetooth_sdp_record* in_record)
return -1;
}
copy_sdp_records(in_record, record, 1);
copy_sdp_record(in_record, record);
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
for(i = 0; i < SDP_MAX_RECORDS; i++)
{
slot = &sdp_local_param.sdp_slots[i];
if ((*slot) == NULL) {
if (((*slot) = (sdp_slot_t *)osi_malloc(sizeof(sdp_slot_t))) == NULL) {
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
BTC_TRACE_ERROR("%s() osi_malloc slot failed!", __func__);
osi_free(record);
return -1;
// find the primary di record slot
if (is_di_record && is_primary_di_record) {
for (i = 0; i < SDP_MAX_RECORDS; i++) {
slot = &sdp_local_param.sdp_slots[i];
if ((*slot) && (*slot)->flag.di && (*slot)->flag.primary_di) {
BTC_TRACE_WARNING("%s() overwrite primary di record!", __func__);
if ((*slot)->record_data) {
osi_free((*slot)->record_data);
}
(*slot)->record_data = record;
primary_di_record_found = true;
break;
}
}
}
if (!primary_di_record_found) {
for (i = 0; i < SDP_MAX_RECORDS; i++) {
slot = &sdp_local_param.sdp_slots[i];
if ((*slot) == NULL) {
if (((*slot) = (sdp_slot_t *)osi_malloc(sizeof(sdp_slot_t))) == NULL) {
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
BTC_TRACE_ERROR("%s() osi_malloc slot failed!", __func__);
osi_free(record);
return -1;
}
(*slot)->flag.di = is_di_record;
(*slot)->flag.primary_di = is_primary_di_record;
(*slot)->state = SDP_RECORD_ALLOCED;
(*slot)->record_data = record;
break;
}
(*slot)->state = SDP_RECORD_ALLOCED;
(*slot)->record_data = record;
break;
}
}
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
@ -292,7 +393,7 @@ static int free_sdp_slot(int id)
}
/* Create a raw SDP record based on information stored in a bluetooth_sdp_raw_record */
static int add_raw_sdp(const bluetooth_sdp_record* rec)
static int add_raw_sdp(const bluetooth_sdp_raw_record *rec)
{
tSDP_PROTOCOL_ELEM protoList [2];
UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
@ -310,15 +411,15 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec)
return sdp_handle;
}
if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_16) {
if (rec->uuid.len == ESP_UUID_LEN_16) {
UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
UINT16_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid16);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) {
UINT16_TO_BE_STREAM (p_temp, rec->uuid.uuid.uuid16);
} else if (rec->uuid.len == ESP_UUID_LEN_32) {
UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
UINT32_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid32);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) {
UINT32_TO_BE_STREAM (p_temp, rec->uuid.uuid.uuid32);
} else if (rec->uuid.len == ESP_UUID_LEN_128) {
UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
ARRAY_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid128, LEN_UUID_128);
ARRAY_TO_BE_STREAM (p_temp, rec->uuid.uuid.uuid128, LEN_UUID_128);
} else {
SDP_DeleteRecord(sdp_handle);
sdp_handle = 0;
@ -357,7 +458,7 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp);
}
/* Make the service browseable */
/* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) {
@ -365,12 +466,12 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec)
sdp_handle = 0;
BTC_TRACE_ERROR("%s() FAILED, status = %d", __func__, status);
} else {
if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_16) {
bta_sys_add_uuid(rec->hdr.bt_uuid.uuid.uuid16);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) {
bta_sys_add_uuid_32(rec->hdr.bt_uuid.uuid.uuid32);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) {
bta_sys_add_uuid_128((UINT8 *)&rec->hdr.bt_uuid.uuid.uuid128);
if (rec->uuid.len == ESP_UUID_LEN_16) {
bta_sys_add_uuid(rec->uuid.uuid.uuid16);
} else if (rec->uuid.len == ESP_UUID_LEN_32) {
bta_sys_add_uuid_32(rec->uuid.uuid.uuid32);
} else if (rec->uuid.len == ESP_UUID_LEN_128) {
bta_sys_add_uuid_128((UINT8 *)&rec->uuid.uuid.uuid128);
}
BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle);
}
@ -448,7 +549,7 @@ static int add_maps_sdp(const bluetooth_sdp_mas_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp);
}
/* Make the service browseable */
/* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) {
@ -523,7 +624,7 @@ static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp);
}
/* Make the service browseable */
/* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) {
@ -603,7 +704,7 @@ static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp);
}
/* Make the service browseable */
/* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) {
@ -649,7 +750,7 @@ static int add_pbapc_sdp(const bluetooth_sdp_pce_record* rec)
UUID_SERVCLASS_PHONE_ACCESS,
rec->hdr.profile_version);
/* Make the service browseable */
/* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) {
@ -736,7 +837,7 @@ static int add_opps_sdp(const bluetooth_sdp_ops_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp);
}
/* Make the service browseable */
/* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) {
@ -799,7 +900,7 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
UUID_SERVCLASS_SAP,
rec->hdr.profile_version);
// Make the service browseable
// Make the service browsable
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) {
@ -814,60 +915,126 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
return sdp_handle;
}
static int btc_handle_create_record_event(int id)
static int add_dips_sdp(bluetooth_sdp_dip_record *rec)
{
int handle = -1;
const sdp_slot_t *sdp_slot = NULL;
UINT32 sdp_handle = 0;
tBTA_DI_RECORD device_info = {0};
BTC_TRACE_DEBUG("Sdp Server %s", __func__);
device_info.vendor = rec->vendor;
device_info.vendor_id_source = rec->vendor_id_source;
device_info.product = rec->product;
device_info.version = rec->version;
device_info.primary_record = rec->primary_record;
sdp_slot = start_create_sdp(id);
if(sdp_slot != NULL) {
bluetooth_sdp_record* record = sdp_slot->record_data;
switch(record->hdr.type) {
case SDP_TYPE_RAW:
handle = add_raw_sdp(record);
break;
case SDP_TYPE_MAP_MAS:
handle = add_maps_sdp(&record->mas);
break;
case SDP_TYPE_MAP_MNS:
handle = add_mapc_sdp(&record->mns);
break;
case SDP_TYPE_PBAP_PSE:
handle = add_pbaps_sdp(&record->pse);
break;
case SDP_TYPE_PBAP_PCE:
handle = add_pbapc_sdp(&record->pce);
break;
case SDP_TYPE_OPP_SERVER:
handle = add_opps_sdp(&record->ops);
break;
case SDP_TYPE_SAP_SERVER:
handle = add_saps_sdp(&record->sap);
break;
default:
BTC_TRACE_DEBUG("Record type %d is not supported",record->hdr.type);
break;
}
if(handle != -1) {
set_sdp_handle(id, handle);
}
}
BTA_DmSetLocalDiRecord(&device_info, &sdp_handle);
return handle;
return sdp_handle;
}
static bool btc_sdp_remove_record_event(int handle)
static int btc_handle_create_record_event(int id)
{
bool result = false;
int sdp_handle = 0;
bluetooth_sdp_record *record = start_create_sdp(id);
esp_bt_uuid_t service_uuid = {0};
BTC_TRACE_DEBUG("Sdp Server %s", __func__);
if(handle != -1 && handle != 0) {
result = SDP_DeleteRecord(handle);
if(result == false) {
BTC_TRACE_ERROR(" Unable to remove handle 0x%08x", handle);
if (record != NULL) {
switch (record->hdr.type) {
case SDP_TYPE_RAW:
sdp_handle = add_raw_sdp(&record->raw);
memcpy(&service_uuid, &record->raw.uuid, sizeof(esp_bt_uuid_t));
break;
case SDP_TYPE_MAP_MAS:
sdp_handle = add_maps_sdp(&record->mas);
service_uuid.len = ESP_UUID_LEN_16;
service_uuid.uuid.uuid16 = UUID_SERVCLASS_MESSAGE_ACCESS;
break;
case SDP_TYPE_MAP_MNS:
sdp_handle = add_mapc_sdp(&record->mns);
service_uuid.len = ESP_UUID_LEN_16;
service_uuid.uuid.uuid16 = UUID_SERVCLASS_MESSAGE_NOTIFICATION;
break;
case SDP_TYPE_PBAP_PSE:
sdp_handle = add_pbaps_sdp(&record->pse);
service_uuid.len = ESP_UUID_LEN_16;
service_uuid.uuid.uuid16 = UUID_SERVCLASS_PBAP_PSE;
break;
case SDP_TYPE_PBAP_PCE:
sdp_handle = add_pbapc_sdp(&record->pce);
service_uuid.len = ESP_UUID_LEN_16;
service_uuid.uuid.uuid16 = UUID_SERVCLASS_PBAP_PCE;
break;
case SDP_TYPE_OPP_SERVER:
sdp_handle = add_opps_sdp(&record->ops);
service_uuid.len = ESP_UUID_LEN_16;
service_uuid.uuid.uuid16 = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
break;
case SDP_TYPE_SAP_SERVER:
sdp_handle = add_saps_sdp(&record->sap);
service_uuid.len = ESP_UUID_LEN_16;
service_uuid.uuid.uuid16 = UUID_SERVCLASS_SAP;
break;
case SDP_TYPE_DIP_SERVER:
sdp_handle = add_dips_sdp(&record->dip);
break;
default:
BTC_TRACE_DEBUG("Record type %d is not supported", record->hdr.type);
break;
}
if(sdp_handle != 0) {
set_sdp_slot_info(id, sdp_handle, &service_uuid);
// free the record, since not use it anymore
osi_free(record);
} else {
sdp_handle = -1;
}
} else {
sdp_handle = -1;
}
if (sdp_handle == -1) {
free_sdp_slot(id);
}
return sdp_handle;
}
static bool btc_sdp_remove_record_event(int id, int *p_sdp_handle)
{
BTC_TRACE_DEBUG("Sdp Server %s", __func__);
bool result = false;
int sdp_handle = -1;
sdp_flag_t flag = {0};
esp_bt_uuid_t service_uuid = {0};
get_sdp_slot_info(id, &sdp_handle, &service_uuid, &flag);
if (sdp_handle > 0) {
if (flag.di && BTA_DmRemoveLocalDiRecord(sdp_handle) == BTA_SUCCESS) {
result = true;
} else {
do {
result = SDP_DeleteRecord(sdp_handle);
if (!result) {
BTC_TRACE_ERROR("Unable to remove handle 0x%08x", sdp_handle);
break;
}
if (service_uuid.len == ESP_UUID_LEN_16) {
bta_sys_remove_uuid(service_uuid.uuid.uuid16);
} else if (service_uuid.len == ESP_UUID_LEN_32) {
bta_sys_remove_uuid_32(service_uuid.uuid.uuid32);
} else if (service_uuid.len == ESP_UUID_LEN_128) {
bta_sys_remove_uuid_128((UINT8 *)&service_uuid.uuid.uuid128);
}
} while (0);
}
if (p_sdp_handle) {
*p_sdp_handle = sdp_handle;
}
}
@ -881,18 +1048,18 @@ static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_da
switch (event) {
case BTA_SDP_CREATE_RECORD_USER_EVT: {
if (p_data->status == BTA_SDP_SUCCESS) {
if (p_data->sdp_create_record.status == BTA_SDP_SUCCESS) {
p_data->sdp_create_record.handle = btc_handle_create_record_event((int)user_data);
if (p_data->sdp_create_record.handle < 0) {
p_data->status = BTA_SDP_FAILURE;
p_data->sdp_create_record.status = BTA_SDP_FAILURE;
}
}
}
break;
case BTA_SDP_REMOVE_RECORD_USER_EVT: {
if (p_data->status == BTA_SDP_SUCCESS) {
if (btc_sdp_remove_record_event((int)user_data) == false) {
p_data->status = BTA_SDP_FAILURE;
if (p_data->sdp_remove_record.status == BTA_SDP_SUCCESS) {
if (btc_sdp_remove_record_event((int)user_data, &p_data->sdp_remove_record.handle) == false) {
p_data->sdp_remove_record.status = BTA_SDP_FAILURE;
}
}
}
@ -930,23 +1097,27 @@ static void btc_sdp_init(void)
ret = ESP_SDP_NO_RESOURCE;
break;
}
memset((void *)sdp_local_param_ptr, 0, sizeof(sdp_local_param_t));
#endif
memset(&sdp_local_param, 0, sizeof(sdp_local_param_t));
if (osi_mutex_new(&sdp_local_param.sdp_slot_mutex) != 0) {
#if SDP_DYNAMIC_MEMORY == TRUE
osi_free(sdp_local_param_ptr);
sdp_local_param_ptr = NULL;
#endif
BTC_TRACE_ERROR("%s osi_mutex_new failed\n", __func__);
ret = ESP_SDP_NO_RESOURCE;
break;
}
ret = BTA_SdpEnable(btc_sdp_dm_cback);
if (ret != ESP_SDP_SUCCESS) {
BTC_TRACE_ERROR("%s BTA_SdpEnable failed, ret = %d\n", __func__, ret);
ret = ESP_SDP_FAILURE;
break;
}
sdp_local_param.search_allowed = true;
} while(0);
if (ret != ESP_SDP_SUCCESS) {
btc_sdp_cleanup();
param.init.status = ret;
btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param);
}
@ -956,7 +1127,6 @@ static void btc_sdp_deinit(void)
{
esp_sdp_cb_param_t param;
esp_sdp_status_t ret = ESP_SDP_SUCCESS;
int handle;
do {
if (!is_sdp_init()) {
@ -966,12 +1136,13 @@ static void btc_sdp_deinit(void)
}
for(int i = 0; i < SDP_MAX_RECORDS; i++) {
handle = free_sdp_slot(i);
if (handle > 0) {
BTA_SdpRemoveRecordByUser((void*)handle);
int sdp_handle = -1;
get_sdp_slot_info(i, &sdp_handle, NULL, NULL);
if (sdp_handle > 0) {
BTA_SdpRemoveRecordByUser((void*)i);
}
}
sdp_disable_handler();
BTA_SdpDisable();
} while(0);
if (ret != ESP_SDP_SUCCESS) {
@ -982,7 +1153,7 @@ static void btc_sdp_deinit(void)
static void btc_sdp_create_record(btc_sdp_args_t *arg)
{
int handle;
int slot_id;
esp_sdp_cb_param_t param;
esp_sdp_status_t ret = ESP_SDP_SUCCESS;
@ -993,13 +1164,13 @@ static void btc_sdp_create_record(btc_sdp_args_t *arg)
break;
}
handle = alloc_sdp_slot(arg->creat_record.record);
if (handle < 0) {
slot_id = alloc_sdp_slot(arg->create_record.record);
if (slot_id < 0) {
ret = ESP_SDP_FAILURE;
break;
}
BTA_SdpCreateRecordByUser((void *) handle);
BTA_SdpCreateRecordByUser((void *) slot_id);
} while(0);
if (ret != ESP_SDP_SUCCESS) {
@ -1011,7 +1182,6 @@ static void btc_sdp_create_record(btc_sdp_args_t *arg)
static void btc_sdp_remove_record(btc_sdp_args_t *arg)
{
int handle;
esp_sdp_cb_param_t param;
esp_sdp_status_t ret = ESP_SDP_SUCCESS;
@ -1022,42 +1192,16 @@ static void btc_sdp_remove_record(btc_sdp_args_t *arg)
break;
}
bluetooth_sdp_record rec;
if (get_sdp_record_by_handle(arg->remove_record.record_handle, &rec)) {
if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_16) {
bta_sys_remove_uuid(rec.hdr.bt_uuid.uuid.uuid16);
} else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_32) {
bta_sys_remove_uuid_32(rec.hdr.bt_uuid.uuid.uuid32);
} else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_128) {
bta_sys_remove_uuid_128((UINT8 *)&rec.hdr.bt_uuid.uuid.uuid128);
}
} else {
BTC_TRACE_ERROR("%s SDP record with handle %d not found",
__func__, arg->remove_record.record_handle);
ret = ESP_SDP_NO_CREATE_RECORD;
break;
}
/* Get the Record handle, and free the slot */
/* The application layer record_handle is equivalent to the id of the btc layer */
int slot = get_sdp_slot_id_by_handle(arg->remove_record.record_handle);
if (slot < 0) {
int slot_id = get_sdp_slot_id_by_handle(arg->remove_record.record_handle);
if (slot_id < 0) {
BTC_TRACE_ERROR("%s SDP record with handle %d not found", __func__, arg->remove_record.record_handle);
ret = ESP_SDP_NO_CREATE_RECORD;
break;
}
handle = free_sdp_slot(slot);
BTC_TRACE_DEBUG("Sdp Server %s id=%d to handle=0x%08x",
__func__, arg->remove_record.record_handle, handle);
/* Pass the actual record handle */
if(handle > 0) {
BTA_SdpRemoveRecordByUser((void*) handle);
} else {
ret = ESP_SDP_NO_CREATE_RECORD;
break;
}
BTA_SdpRemoveRecordByUser((void *)slot_id);
} while(0);
if (ret != ESP_SDP_SUCCESS) {
@ -1078,7 +1222,18 @@ static void btc_sdp_search(btc_sdp_args_t *arg)
break;
}
if (!sdp_local_param.search_allowed) {
BTC_TRACE_ERROR("%s SDP search is not allowed!", __func__);
ret = ESP_SDP_NO_RESOURCE;
break;
}
BTA_SdpSearch(arg->search.bd_addr, &arg->search.sdp_uuid);
/**
* ESP_SDP_SEARCH_COMP_EVT will refer service name in BTA sdp database, so it is not allowed to be search until
* the previous search is completed
*/
sdp_local_param.search_allowed = false;
} while(0);
if (ret != ESP_SDP_SUCCESS) {
@ -1089,25 +1244,20 @@ static void btc_sdp_search(btc_sdp_args_t *arg)
void btc_sdp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_sdp_args_t *dst = (btc_sdp_args_t *)p_dest;
btc_sdp_args_t *src = (btc_sdp_args_t *)p_src;
bluetooth_sdp_record **dst_record = &((btc_sdp_args_t *)p_dest)->create_record.record;
bluetooth_sdp_record *src_record = ((btc_sdp_args_t *)p_src)->create_record.record;
switch (msg->act) {
case BTC_SDP_ACT_CREATE_RECORD:
dst->creat_record.record = (bluetooth_sdp_record *)osi_calloc(sizeof(bluetooth_sdp_record));
if (dst->creat_record.record) {
memcpy(dst->creat_record.record, src->creat_record.record, sizeof(bluetooth_sdp_record));
bluetooth_sdp_record *record = (bluetooth_sdp_record *)osi_calloc(get_sdp_record_size(src_record));
if (record) {
copy_sdp_record(src_record, record);
} else {
BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
break;
}
dst->creat_record.record->hdr.service_name = (char *)osi_calloc(src->creat_record.record->hdr.service_name_length);
if (dst->creat_record.record->hdr.service_name) {
strcpy(dst->creat_record.record->hdr.service_name, src->creat_record.record->hdr.service_name);
} else {
BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
}
*dst_record = record;
break;
default:
break;
@ -1117,14 +1267,12 @@ void btc_sdp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
void btc_sdp_arg_deep_free(btc_msg_t *msg)
{
btc_sdp_args_t *arg = (btc_sdp_args_t *)msg->arg;
bluetooth_sdp_record *record = arg->create_record.record;
switch (msg->act) {
case BTC_SDP_ACT_CREATE_RECORD:
if (arg->creat_record.record) {
osi_free(arg->creat_record.record);
}
if (arg->creat_record.record->hdr.service_name) {
osi_free(arg->creat_record.record->hdr.service_name);
if (record) {
osi_free(record);
}
break;
default:
@ -1172,17 +1320,16 @@ void btc_sdp_cb_handler(btc_msg_t *msg)
param.init.status = p_data->status;
btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param);
break;
case BTA_SDP_DISENABLE_EVT:
BTA_SdpDisable();
osi_mutex_free(&sdp_local_param.sdp_slot_mutex);
#if SDP_DYNAMIC_MEMORY == TRUE
osi_free(sdp_local_param_ptr);
sdp_local_param_ptr = NULL;
#endif
case BTA_SDP_DISABLE_EVT:
BTA_SdpCleanup();
btc_sdp_cleanup();
param.deinit.status = ESP_SDP_SUCCESS;
btc_sdp_cb_to_app(ESP_SDP_DEINIT_EVT, &param);
break;
case BTA_SDP_SEARCH_COMP_EVT:
// SDP search completed, now can be searched again
sdp_local_param.search_allowed = true;
param.search.status = p_data->sdp_search_comp.status;
if (param.search.status == ESP_SDP_SUCCESS) {
memcpy(param.search.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR));
@ -1208,7 +1355,17 @@ void btc_sdp_cb_handler(btc_msg_t *msg)
btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, &param);
break;
case BTA_SDP_REMOVE_RECORD_USER_EVT:
param.remove_record.status = p_data->status;
if (p_data->sdp_remove_record.status == BTA_SDP_SUCCESS) {
int slot_id = get_sdp_slot_id_by_handle(p_data->sdp_remove_record.handle);
if (slot_id < 0) {
p_data->sdp_remove_record.status = ESP_SDP_NO_CREATE_RECORD;
break;
} else {
free_sdp_slot(slot_id);
}
}
param.remove_record.status = p_data->sdp_remove_record.status;
btc_sdp_cb_to_app(ESP_SDP_REMOVE_RECORD_COMP_EVT, &param);
break;
default:
@ -1217,4 +1374,4 @@ 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

View File

@ -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
@ -48,16 +61,23 @@
//L2CAP
#ifdef CONFIG_BT_L2CAP_ENABLED
#define UC_BT_L2CAP_ENABLED CONFIG_BT_L2CAP_ENABLED
#define UC_BT_L2CAP_ENABLED CONFIG_BT_L2CAP_ENABLED
#else
#define UC_BT_L2CAP_ENABLED FALSE
#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
#define UC_BT_HFP_AG_ENABLED CONFIG_BT_HFP_AG_ENABLE
#else
#define UC_BT_HFP_AG_ENABLED FALSE
#define UC_BT_HFP_AG_ENABLED FALSE
#endif
//HFP(Client)
@ -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

View File

@ -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
@ -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

View File

@ -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...)

View File

@ -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) {

View File

@ -430,10 +430,10 @@ 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",
i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
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;
}

View File

@ -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.
**

View File

@ -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)

View 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) */

View 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) */

View File

@ -0,0 +1,103 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "common/bt_target.h"
#include "stack/obex_api.h"
#include "stack/goep_common.h"
#include "stack/goepc_api.h"
#if (GOEPC_INCLUDED == TRUE)
/* GOEPC state machine events */
enum {
GOEPC_SM_EVENT_CONNECT = 0,
GOEPC_SM_EVENT_DISCONNECT,
GOEPC_SM_EVENT_REQ,
GOEPC_SM_EVENT_REQ_FB,
GOEPC_SM_EVENT_RSP,
GOEPC_SM_EVENT_RSP_FB,
};
/* GOEPC state machine states */
enum {
GOEPC_STATE_INIT = 0,
GOEPC_STATE_OPENING,
GOEPC_STATE_OPENED_IDLE,
GOEPC_STATE_OPENED_REQ,
GOEPC_STATE_OPENED_RSP,
};
/* GOEPC srm state machine states */
enum {
GOEPC_SRM_STATE_IDLE = 0,
GOEPC_SRM_STATE_REQ,
GOEPC_SRM_STATE_ENABLE_WAIT,
GOEPC_SRM_STATE_ENABLE,
GOEPC_SRM_STATE_DISABLE,
};
/* GOEPC Connection Control block */
typedef struct {
tGOEPC_EVT_CBACK *callback; /* GOEP event callback function */
UINT16 obex_handle; /* OBEX connection handle */
UINT16 peer_mtu; /* lower layer connection peer MTU */
UINT16 our_mtu; /* lower layer connection our MTU */
BOOLEAN congest; /* lower layer connection congestion status */
BT_HDR *pkt; /* packet prepared in this GOEP client */
BOOLEAN pkt_srm_en; /* whether prepared packet had set SRM to enable */
BOOLEAN pkt_srm_wait; /* whether prepared packet had set SRMP to wait */
UINT8 curr_pkt_opcode; /* prepared packet opcode */
UINT8 last_pkt_opcode; /* last sent packet opcode */
BOOLEAN srm_wait; /* whether we had set SRMP to wait */
BOOLEAN srm_peer_wait; /* whether peer had set SRMP to wait */
UINT8 srm_state; /* SRM state machine */
UINT8 state; /* main state machine */
UINT8 allocated; /* 0, not allocated. index+1, otherwise. equal to api handle */
} tGOEPC_CCB;
/* GOEPC Control block */
typedef struct {
tGOEPC_CCB ccb[GOEPC_MAX_CONNECTION]; /* connection control blocks */
UINT8 trace_level; /* trace level */
} tGOEPC_CB;
#if GOEP_DYNAMIC_MEMORY == FALSE
extern tGOEPC_CB goepc_cb;
#else
extern tGOEPC_CB *goepc_cb_ptr;
#define goepc_cb (*goepc_cb_ptr)
#endif
typedef struct {
UINT16 peer_mtu;
UINT16 our_mtu;
} tGOEPC_CONNECTED;
typedef struct {
UINT16 peer_mtu;
UINT16 our_mtu;
} tGOEPC_MTU_CHG;
typedef union {
tGOEPC_CONNECTED connected;
tGOEPC_MTU_CHG mtu_chg;
BT_HDR *pkt;
} tGOEPC_DATA;
tGOEPC_CCB *goepc_allocate_ccb(void);
void goepc_free_ccb(tGOEPC_CCB *p_ccb);
void goepc_obex_callback(UINT16 handle, UINT8 event, tOBEX_MSG *msg);
BOOLEAN goepc_check_obex_req_allow(UINT8 state, BOOLEAN final);
BOOLEAN goepc_check_obex_req_param(tOBEX_PARSE_INFO *info);
void goepc_sm_execute(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data);
void goepc_srm_sm_execute(tGOEPC_CCB *p_ccb, BOOLEAN is_req, BOOLEAN srm_en, BOOLEAN srm_wait);
#endif /* #if (GOEPC_INCLUDED == TRUE) */

View File

@ -99,6 +99,9 @@
#define AVRC_SUPF_CT_CAT3 0x0004 /* Category 3 */
#define AVRC_SUPF_CT_CAT4 0x0008 /* Category 4 */
#define AVRC_SUPF_CT_BROWSE 0x0040 /* Browsing */
#define AVRC_SUPF_CT_COVER_ART_GIP 0x0080 /* Cover Art GetImageProperties */
#define AVRC_SUPF_CT_COVER_ART_GI 0x0100 /* Cover Art GetImage */
#define AVRC_SUPF_CT_COVER_ART_GLT 0x0200 /* Cover Art GetLinkedThumbnail */
#define AVRC_SUPF_TG_CAT1 0x0001 /* Category 1 */
#define AVRC_SUPF_TG_CAT2 0x0002 /* Category 2 */
@ -107,7 +110,8 @@
#define AVRC_SUPF_TG_APP_SETTINGS 0x0010 /* Player Application Settings */
#define AVRC_SUPF_TG_GROUP_NAVI 0x0020 /* Group Navigation */
#define AVRC_SUPF_TG_BROWSE 0x0040 /* Browsing */
#define AVRC_SUPF_TG_MULTI_PLAYER 0x0080 /* Muliple Media Player */
#define AVRC_SUPF_TG_MULTI_PLAYER 0x0080 /* Multiple Media Player */
#define AVRC_SUPF_TG_COVER_ART 0x0100 /* Cover Art */
#define AVRC_META_SUCCESS AVRC_SUCCESS
#define AVRC_META_FAIL AVRC_FAIL
@ -561,7 +565,7 @@ extern 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.
**

View File

@ -35,6 +35,7 @@
#define AVRC_REV_1_3 0x0103
#define AVRC_REV_1_4 0x0104
#define AVRC_REV_1_5 0x0105
#define AVRC_REV_1_6 0x0106
#define AVRC_PACKET_LEN 512 /* Per the spec, you must support 512 byte RC packets */
@ -185,7 +186,7 @@
#define AVRC_PKT_END 3
#define AVRC_PKT_TYPE_MASK 3
/* Define the PDUs carried in the vendor dependant data
/* Define the PDUs carried in the vendor dependent data
*/
#define AVRC_PDU_GET_CAPABILITIES 0x10
#define AVRC_PDU_LIST_PLAYER_APP_ATTR 0x11
@ -297,7 +298,7 @@ typedef UINT8 tAVRC_BATTERY_STATUS;
#define AVRC_MEDIA_ATTR_ID_TRACK_NUM 0x00000004
#define AVRC_MEDIA_ATTR_ID_NUM_TRACKS 0x00000005
#define AVRC_MEDIA_ATTR_ID_GENRE 0x00000006
#define AVRC_MEDIA_ATTR_ID_PLAYING_TIME 0x00000007 /* in miliseconds */
#define AVRC_MEDIA_ATTR_ID_PLAYING_TIME 0x00000007 /* in milliseconds */
#define AVRC_MAX_NUM_MEDIA_ATTR_ID 7
/* Define the possible values of play state

View File

@ -45,6 +45,8 @@
#define HCRP_DYNAMIC_MEMORY TRUE
#define HFP_DYNAMIC_MEMORY TRUE
#define HID_DYNAMIC_MEMORY TRUE
#define OBEX_DYNAMIC_MEMORY TRUE
#define GOEP_DYNAMIC_MEMORY TRUE
#define HSP2_DYNAMIC_MEMORY TRUE
#define ICP_DYNAMIC_MEMORY TRUE
#define OPP_DYNAMIC_MEMORY TRUE
@ -79,6 +81,8 @@
#define HCRP_DYNAMIC_MEMORY FALSE
#define HFP_DYNAMIC_MEMORY FALSE
#define HID_DYNAMIC_MEMORY FALSE
#define OBEX_DYNAMIC_MEMORY FALSE
#define GOEP_DYNAMIC_MEMORY FALSE
#define HSP2_DYNAMIC_MEMORY FALSE
#define ICP_DYNAMIC_MEMORY FALSE
#define OPP_DYNAMIC_MEMORY FALSE
@ -191,6 +195,14 @@
#define HID_DYNAMIC_MEMORY FALSE
#endif
#ifndef OBEX_DYNAMIC_MEMORY
#define OBEX_DYNAMIC_MEMORY FALSE
#endif
#ifndef GOEP_DYNAMIC_MEMORY
#define GOEP_DYNAMIC_MEMORY FALSE
#endif
#ifndef HSP2_DYNAMIC_MEMORY
#define HSP2_DYNAMIC_MEMORY FALSE
#endif

View File

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "common/bt_target.h"
#define GOEP_SUCCESS 0 /* Operation successful */
#define GOEP_FAILURE 1 /* Operation failed */
#define GOEP_NO_RESOURCES 3 /* Not enough resources */
#define GOEP_BAD_HANDLE 4 /* Bad handle */
#define GOEP_INVALID_PARAM 5 /* Invalid parameter */
#define GOEP_INVALID_STATE 6 /* Operation not allow in current state */
#define GOEP_CONGEST 7 /* Congest */
#define GOEP_TL_ERROR 8 /* Lower transport layer error */

View File

@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "common/bt_target.h"
#include "stack/goep_common.h"
#include "stack/obex_api.h"
#if (GOEPC_INCLUDED == TRUE)
enum {
GOEPC_OPENED_EVT, /* connection open */
GOEPC_CLOSED_EVT, /* disconnect unexpected */
GOEPC_MTU_CHANGED_EVT, /* lower layer MTU change */
GOEPC_CONGEST_EVT, /* lower layer connection congest */
GOEPC_UNCONGEST_EVT, /* lower layer connection uncongest */
GOEPC_RESPONSE_EVT /* response from server */
};
typedef struct {
UINT16 peer_mtu; /* peer mtu of lower level connection */
UINT16 our_mtu; /* our mtu of lower level connection */
} tGOEPC_MSG_OPENED;
typedef struct {
UINT8 reason; /* connection close reason */
} tGOEPC_MSG_CLOSED;
typedef struct {
UINT16 peer_mtu; /* peer mtu of lower level connection */
UINT16 our_mtu; /* our mtu of lower level connection */
} tGOEPC_MSG_MTU_CHANGED;
typedef struct {
UINT8 opcode; /* which opcode that this packet response to */
BOOLEAN final; /* whether this is a final packet */
BOOLEAN srm_en; /* whether srm is enable */
BOOLEAN srm_wait; /* whether srm wait is set, set by peer or by us */
BT_HDR *pkt; /* pointer to response packet */
} tGOEPC_MSG_RESPONSE;
typedef union {
tGOEPC_MSG_OPENED opened;
tGOEPC_MSG_CLOSED closed;
tGOEPC_MSG_MTU_CHANGED mtu_changed;
tGOEPC_MSG_RESPONSE response;
} tGOEPC_MSG;
typedef void (tGOEPC_EVT_CBACK)(UINT16 handle, UINT8 event, tGOEPC_MSG *msg);
/*******************************************************************************
* The following APIs are called by bluetooth stack automatically
*******************************************************************************/
extern UINT16 GOEPC_Init(void);
extern void GOEPC_Deinit(void);
/*******************************************************************************
* The following APIs must be executed in btu task
*******************************************************************************/
extern UINT16 GOEPC_Open(tOBEX_SVR_INFO *p_svr, tGOEPC_EVT_CBACK callback, UINT16 *out_handle);
extern UINT16 GOEPC_Close(UINT16 handle);
extern UINT16 GOEPC_SendRequest(UINT16 handle);
extern UINT16 GOEPC_PrepareRequest(UINT16 handle, tOBEX_PARSE_INFO *info, UINT16 buff_size);
extern UINT16 GOEPC_DropRequest(UINT16 handle);
extern UINT16 GOEPC_RequestSetSRM(UINT16 handle, BOOLEAN srm_en, BOOLEAN srm_wait);
extern UINT16 GOEPC_RequestAddHeader(UINT16 handle, UINT8 header_id, const UINT8 *data, UINT16 data_len);
#endif /* #if (GOEPC_INCLUDED == TRUE) */

View File

@ -0,0 +1,264 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "common/bt_target.h"
#if (OBEX_INCLUDED == TRUE)
/* API function return value result codes. */
#define OBEX_SUCCESS 0 /* Operation successful */
#define OBEX_FAILURE 1 /* Operation failed */
#define OBEX_NO_RESOURCES 3 /* Not enough resources */
#define OBEX_BAD_HANDLE 4 /* Bad handle */
#define OBEX_INVALID_PARAM 5 /* Invalid parameter */
#define OBEX_NOT_OPEN 6 /* Connection not open */
#define OBEX_PACKET_TOO_LARGE 7 /* Packet size large than MTU */
#define OBEX_ERROR_TL 8 /* Operation failed in transport layer */
#define OBEX_TRY_AGAIN 9 /* Operation failed, connection congestion, try again */
/*
* OBEX profile definitions
*/
#define OBEX_OPCODE_CONNECT 0x80
#define OBEX_OPCODE_DISCONNECT 0x81
#define OBEX_OPCODE_PUT 0x02
#define OBEX_OPCODE_PUT_FINAL 0x82
#define OBEX_OPCODE_GET 0x03
#define OBEX_OPCODE_GET_FINAL 0x83
#define OBEX_OPCODE_SETPATH 0x85
#define OBEX_OPCODE_ACTION 0x06
#define OBEX_OPCODE_SESSION 0x87
#define OBEX_OPCODE_ABORT 0xFF
#define OBEX_RESPONSE_CODE_CONTINUE 0x10
#define OBEX_RESPONSE_CODE_OK 0x20
#define OBEX_RESPONSE_CODE_CREATED 0x21
#define OBEX_RESPONSE_CODE_ACCEPTED 0x22
#define OBEX_RESPONSE_CODE_NON_AUTHORITATIVE_INFO 0x23
#define OBEX_RESPONSE_CODE_NO_CONTENT 0x24
#define OBEX_RESPONSE_CODE_RESET_CONTENT 0x25
#define OBEX_RESPONSE_CODE_PARTIAL_CONTENT 0x26
#define OBEX_RESPONSE_CODE_MULTIPLE_CHOICES 0x30
#define OBEX_RESPONSE_CODE_MOVED_PERMANENTLY 0x31
#define OBEX_RESPONSE_CODE_MOVED_TEMPORARILY 0x31
#define OBEX_RESPONSE_CODE_SEE_OHTER 0x33
#define OBEX_RESPONSE_CODE_NOT_MODIFIED 0x34
#define OBEX_RESPONSE_CODE_USE_PROXY 0x35
#define OBEX_RESPONSE_CODE_BAD_REQUEST 0x40
#define OBEX_RESPONSE_CODE_UNAUTHORIZED 0x41
#define OBEX_RESPONSE_CODE_PAYMENT_REQUIRED 0x42
#define OBEX_RESPONSE_CODE_FORBIDDEN 0x43
#define OBEX_RESPONSE_CODE_NOT_FOUND 0x44
#define OBEX_RESPONSE_CODE_METHOD_NOT_ALLOWED 0x45
#define OBEX_RESPONSE_CODE_NOT_ACCEPTABLE 0x46
#define OBEX_RESPONSE_CODE_PROXY_AUTHENTICATION_REQUIRED 0x47
#define OBEX_RESPONSE_CODE_REQUEST_TIME_OUT 0x48
#define OBEX_RESPONSE_CODE_CONFLICT 0x49
#define OBEX_RESPONSE_CODE_GONE 0x4A
#define OBEX_RESPONSE_CODE_LENGTH_REQUIRED 0x4B
#define OBEX_RESPONSE_CODE_PRECONDITION_FAILED 0x4C
#define OBEX_RESPONSE_CODE_REQUESTED_ENTITY_TOO_LARGE 0x4D
#define OBEX_RESPONSE_CODE_REQUEST_URL_TOO_LARGE 0x4E
#define OBEX_RESPONSE_CODE_UNSUPPORTED_MEDIA_TYPE 0x4F
#define OBEX_RESPONSE_CODE_INTERNAL_SERVER_ERROR 0x50
#define OBEX_RESPONSE_CODE_NOT_IMPLEMENTED 0x51
#define OBEX_RESPONSE_CODE_BAD_GATEWAY 0x52
#define OBEX_RESPONSE_CODE_SERVICE_UNAVAILABLE 0x53
#define OBEX_RESPONSE_CODE_GATEWAY_TIMEOUT 0x54
#define OBEX_RESPONSE_CODE_HTTP_VERSION_NOT_SUPPORTED 0x55
#define OBEX_RESPONSE_CODE_DATABASE_FULL 0x60
#define OBEX_RESPONSE_CODE_DATABASE_LOCKED 0x61
#define OBEX_FINAL_BIT_MASK 0x80
#define OBEX_CONNECT_FLAGS 0x01 /* support multiple link */
#define OBEX_SETPATH_FLAGS 0x03 /* default flags */
#define OBEX_PACKET_LENGTH_MAX (0xFFFF-1)
#define OBEX_PACKET_LENGTH_MIN 255
#define OBEX_VERSION_NUMBER 0x15
/* Header identifiers */
#define OBEX_HEADER_ID_U2B_MASK 0xC0 /* upper 2 bits of header ID are user to indicate the header encoding */
#define OBEX_HEADER_ID_U2B_TYPE1 0x00 /* null terminated Unicode text, length prefixed with 2 byte unsigned integer */
#define OBEX_HEADER_ID_U2B_TYPE2 0x40 /* byte sequence, length prefixed with 2 byte unsigned integer */
#define OBEX_HEADER_ID_U2B_TYPE3 0x80 /* 1 byte quantity */
#define OBEX_HEADER_ID_U2B_TYPE4 0xC0 /* 4 byte quantity - transmitted in network byte order (high byte first) */
#define OBEX_HEADER_ID_COUNT 0xC0
#define OBEX_HEADER_ID_NAME 0x01
#define OBEX_HEADER_ID_TYPE 0x42
#define OBEX_HEADER_ID_LENGTH 0xC3
#define OBEX_HEADER_ID_TIME_ISO8601 0x44
#define OBEX_HEADER_ID_TIME_4BYTE 0xC4
#define OBEX_HEADER_ID_DESCRIPTION 0x05
#define OBEX_HEADER_ID_TARGET 0x46
#define OBEX_HEADER_ID_HTTP 0x47
#define OBEX_HEADER_ID_BODY 0x48
#define OBEX_HEADER_ID_END_OF_BODY 0x49
#define OBEX_HEADER_ID_WHO 0x4A
#define OBEX_HEADER_ID_CONNECTION_ID 0xCB
#define OBEX_HEADER_ID_APP_PARAM 0x4C
#define OBEX_HEADER_ID_AUTH_CHALLENGE 0x4D
#define OBEX_HEADER_ID_AUTH_RESPONSE 0x4E
#define OBEX_HEADER_ID_CREATOR_ID 0xCF
#define OBEX_HEADER_ID_WAN_UUID 0x50
#define OBEX_HEADER_ID_OBJECT_CLASS 0x51
#define OBEX_HEADER_ID_SESSION_PARAM 0x52
#define OBEX_HEADER_ID_SESSION_SEQ_NUM 0x93
#define OBEX_HEADER_ID_ACTION_ID 0x94
#define OBEX_HEADER_ID_DESTNAME 0x15
#define OBEX_HEADER_ID_PERMISSIONS 0xD6
#define OBEX_HEADER_ID_SRM 0x97
#define OBEX_HEADER_ID_SRM_PARAM 0x98
/* Reserved for future use: 0x19 to 0x2F */
/* User defined: 0x30 to 0x3F */
#define OBEX_ACTION_ID_COPY 0x00
#define OBEX_ACTION_ID_MOVE_RENAME 0x01
#define OBEX_ACTION_ID_SET_PERMISSIONS 0x02
#define OBEX_SRM_DISABLE 0x00
#define OBEX_SRM_ENABLE 0x01
#define OBEX_SRM_SUPPORT 0x02
#define OBEX_SRMP_ADD_PKT 0x00
#define OBEX_SRMP_WAIT 0x01
#define OBEX_SRMP_ADD_PKT_WAIT 0x02
#define OBEX_MIN_PACKET_SIZE 3
enum {
/* client event */
OBEX_CONNECT_EVT, /* connection opened */
OBEX_DISCONNECT_EVT, /* connection disconnected */
/* server event */
OBEX_CONN_INCOME_EVT, /* an incoming connection */
/* client or server event */
OBEX_MTU_CHANGE_EVT, /* connection mtu changed */
OBEX_CONGEST_EVT, /* connection congested */
OBEX_UNCONGEST_EVT, /* connection is not congested */
OBEX_DATA_EVT /* data received */
};
enum {
OBEX_OVER_L2CAP = 0,
OBEX_OVER_RFCOMM,
OBEX_NUM_TL
};
typedef struct
{
UINT16 psm; /* l2cap psm */
UINT16 sec_mask; /* security mask */
UINT16 pref_mtu; /* preferred mtu, limited by L2CAP_MTU_SIZE */
BD_ADDR addr; /* peer bluetooth device address */
} tOBEX_OVER_L2CAP_SVR;
typedef struct
{
UINT8 tl; /* transport type, OBEX_OVER_L2CAP or OBEX_OVER_RFCOMM */
union
{
tOBEX_OVER_L2CAP_SVR l2cap;
};
} tOBEX_SVR_INFO;
typedef struct {
UINT8 opcode;
UINT8 response_code;
/* Connect */
UINT8 obex_version_number;
UINT16 max_packet_length;
/* Connect or SetPath */
UINT8 flags;
/* Internal use */
UINT16 next_header_pos;
} tOBEX_PARSE_INFO;
typedef union {
struct {
UINT16 peer_mtu;
UINT16 our_mtu;
} connect;
struct {
UINT16 svr_handle;
UINT16 peer_mtu;
UINT16 our_mtu;
} conn_income;
struct {
UINT16 peer_mtu;
UINT16 our_mtu;
} mtu_change;
struct {
BT_HDR *pkt;
} data;
} tOBEX_MSG;
typedef void (tOBEX_MSG_CBACK)(UINT16 handle, UINT8 event, tOBEX_MSG *msg);
/*******************************************************************************
* The following APIs are called by bluetooth stack automatically
*******************************************************************************/
extern UINT16 OBEX_Init(void);
extern void OBEX_Deinit(void);
/*******************************************************************************
* The following APIs must be executed in btu task
*******************************************************************************/
extern UINT16 OBEX_CreateConn(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_handle);
extern UINT16 OBEX_RemoveConn(UINT16 handle);
extern UINT16 OBEX_SendPacket(UINT16 handle, BT_HDR *pkt);
extern UINT16 OBEX_RegisterServer(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_svr_handle);
extern UINT16 OBEX_DeregisterServer(UINT16 svr_handle);
/*******************************************************************************
* The following APIs are util function, can be executed in btu or btc task
*******************************************************************************/
extern UINT16 OBEX_BuildRequest(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt);
extern UINT16 OBEX_BuildResponse(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt);
extern UINT16 OBEX_AppendHeader(BT_HDR *pkt, const UINT8 *header);
extern UINT16 OBEX_AppendHeaderRaw(BT_HDR *pkt, UINT8 header_id, const UINT8 *data, UINT16 data_len);
extern UINT16 OBEX_AppendHeaderSRM(BT_HDR *pkt, UINT8 value);
extern UINT16 OBEX_AppendHeaderSRMP(BT_HDR *pkt, UINT8 value);
extern UINT16 OBEX_GetPacketFreeSpace(BT_HDR *pkt);
extern UINT16 OBEX_GetPacketLength(BT_HDR *pkt);
extern UINT16 OBEX_ParseRequest(BT_HDR *pkt, tOBEX_PARSE_INFO *info);
extern UINT16 OBEX_ParseResponse(BT_HDR *pkt, UINT8 opcode, tOBEX_PARSE_INFO *info);
extern BOOLEAN OBEX_CheckFinalBit(BT_HDR *pkt);
extern BOOLEAN OBEX_CheckContinueResponse(BT_HDR *pkt);
extern UINT8 *OBEX_GetNextHeader(BT_HDR *pkt, tOBEX_PARSE_INFO *info);
extern UINT16 OBEX_GetHeaderLength(UINT8 *header);
#endif /* #if (OBEX_INCLUDED == TRUE) */

View File

@ -365,6 +365,20 @@ extern BOOLEAN SDP_FindProtocolListElemInRec (tSDP_DISC_REC *p_rec,
UINT16 layer_uuid,
tSDP_PROTOCOL_ELEM *p_elem);
/*******************************************************************************
**
** Function SDP_FindProtocolListElem
**
** Description This function looks at the protocol list for a specific protocol
** list element.
**
** Returns TRUE if found, FALSE if not
** If found, the passed protocol list element is filled in.
**
*******************************************************************************/
extern BOOLEAN SDP_FindProtocolListElem (tSDP_DISC_ATTR *p_protocol_list,
UINT16 layer_uuid,
tSDP_PROTOCOL_ELEM *p_elem);
/*******************************************************************************
**
@ -409,7 +423,7 @@ extern BOOLEAN SDP_FindProfileVersionInRec (tSDP_DISC_REC *p_rec,
**
** Description This function is called to create a record in the database.
** This would be through the SDP database maintenance API. The
** record is created empty, teh application should then call
** record is created empty, the application should then call
** "add_attribute" to add the record's attributes.
**
** Returns Record handle if OK, else 0.

View File

@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "common/bt_target.h"
#include "stack/obex_api.h"
#include "obex_tl.h"
#include "obex_tl_l2cap.h"
#if (OBEX_INCLUDED == TRUE)
#define OBEX_BT_HDR_MIN_OFFSET OBEX_TL_L2CAP_BT_HDR_MIN_OFFSET /* should set to max value of all transport layer */
#define OBEX_ROLE_CLIENT 0x01
#define OBEX_ROLE_SERVER 0x02
/* OBEX connection state */
#define OBEX_STATE_IDLE 0 /* No connection */
#define OBEX_STATE_OPENING 1 /* Starting to open a connection */
#define OBEX_STATE_OPENED 2 /* Connection opened */
/* Store 16 bits data in big endian format, not modify the p_buf */
#define STORE16BE(p_buf, data) do { *p_buf = ((data)>>8)&0xff; \
*(p_buf+1) = (data)&0xff;} while(0)
/* OBEX Connection Control block */
typedef struct {
tOBEX_MSG_CBACK *callback; /* Connection msg callback function */
UINT16 tl_hdl; /* Transport layer non-zeros connection handle*/
UINT16 tl_peer_mtu; /* Transport layer peer mtu */
UINT16 tl_our_mtu; /* Transport layer our mtu */
UINT8 tl_cong; /* 1 if transport layer congestion, otherwise 0 */
UINT8 tl; /* OBEX_OVER_L2CAP or OBEX_OVER_RFCOMM */
UINT8 allocated; /* 0, not allocated. index+1, otherwise. equal to api handle */
UINT8 state; /* This OBEX connection state */
UINT8 role; /* This OBEX connection role */
} tOBEX_CCB;
/* OBEX Server Control block */
typedef struct {
tOBEX_MSG_CBACK *callback; /* Connection msg callback function */
UINT16 tl_hdl; /* Transport layer non-zeros server handle*/
UINT8 tl; /* OBEX_OVER_L2CAP or OBEX_OVER_RFCOMM */
UINT8 allocated; /* 0, not allocated. index+1, otherwise. */
} tOBEX_SCB;
/* OBEX Control block */
typedef struct {
tOBEX_CCB ccb[OBEX_MAX_CONNECTION]; /* connection control blocks */
tOBEX_SCB scb[OBEX_MAX_SERVER]; /* server control blocks */
tOBEX_TL_OPS *tl_ops[OBEX_NUM_TL]; /* transport operation function pointer */
UINT8 trace_level; /* trace level */
} tOBEX_CB;
#if OBEX_DYNAMIC_MEMORY == FALSE
extern tOBEX_CB obex_cb;
#else
extern tOBEX_CB *obex_cb_ptr;
#define obex_cb (*obex_cb_ptr)
#endif
void obex_tl_l2cap_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg);
tOBEX_CCB *obex_allocate_ccb(void);
tOBEX_SCB *obex_allocate_scb(void);
void obex_free_ccb(tOBEX_CCB *p_ccb);
void obex_free_scb(tOBEX_SCB *p_scb);
#endif /* #if (OBEX_INCLUDED == TRUE) */

View File

@ -0,0 +1,88 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "common/bt_target.h"
#if (OBEX_INCLUDED == TRUE)
/* Return code of obex_tl_send_data */
#define OBEX_TL_FAILED FALSE
#define OBEX_TL_SUCCESS TRUE
#define OBEX_TL_CONGESTED 2
typedef enum {
OBEX_TL_CONN_OPEN_EVT,
OBEX_TL_CONN_INCOME_EVT,
OBEX_TL_DIS_CONN_EVT,
OBEX_TL_CONGEST_EVT,
OBEX_TL_UNCONGEST_EVT,
OBEX_TL_MTU_CHANGE_EVT,
OBEX_TL_DATA_EVT
} tOBEX_TL_EVT;
typedef union {
/* general struct, used to retrieve handle */
struct {
UINT16 hdl;
} any;
/* struct for OBEX_TL_CONN_OPEN_EVT */
struct {
UINT16 hdl;
UINT16 peer_mtu;
UINT16 our_mtu;
} conn_open;
/* struct for OBEX_TL_CONN_INCOME_EVT */
struct {
UINT16 hdl;
UINT16 peer_mtu;
UINT16 our_mtu;
UINT16 svr_hdl;
} conn_income;
/* struct for OBEX_TL_MTU_CHANGE_EVT */
struct {
UINT16 hdl;
UINT16 peer_mtu;
UINT16 our_mtu;
} mtu_chg;
/* struct for OBEX_TL_DATA_EVT */
struct {
UINT16 hdl;
BT_HDR *p_buf;
} data;
} tOBEX_TL_MSG;
typedef struct
{
UINT16 psm; /* l2cap psm */
UINT16 sec_mask; /* security mask */
UINT16 pref_mtu; /* preferred mtu, limited by L2CAP_MTU_SIZE */
BD_ADDR addr; /* peer bluetooth device address */
} tOBEX_TL_L2CAP_SVR;
typedef union
{
tOBEX_TL_L2CAP_SVR l2cap;
} tOBEX_TL_SVR_INFO;
typedef void (tOBEX_TL_CBACK)(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg);
typedef struct {
void (*init)(tOBEX_TL_CBACK *callback);
void (*deinit)(void);
UINT16 (*connect)(tOBEX_TL_SVR_INFO *server);
void (*disconnect)(UINT16 tl_hdl);
UINT16 (*send)(UINT16 tl_hdl, BT_HDR *p_buf);
UINT16 (*bind)(tOBEX_TL_SVR_INFO *server);
void (*unbind)(UINT16 tl_hdl);
} tOBEX_TL_OPS;
#endif /* #if (OBEX_INCLUDED == TRUE) */

View File

@ -0,0 +1,17 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "obex_tl.h"
#if (OBEX_INCLUDED == TRUE)
#define OBEX_TL_L2CAP_BT_HDR_MIN_OFFSET 13 /* L2CAP_MIN_OFFSET */
tOBEX_TL_OPS *obex_tl_l2cap_ops_get(void);
#endif /* #if (OBEX_INCLUDED == TRUE) */

View File

@ -0,0 +1,764 @@
/*
* 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 "obex_int.h"
#include "obex_tl.h"
#include "obex_tl_l2cap.h"
#if (OBEX_INCLUDED == TRUE)
static inline void obex_server_to_tl_server(tOBEX_SVR_INFO *server, tOBEX_TL_SVR_INFO *tl_server)
{
if (server->tl == OBEX_OVER_L2CAP) {
tl_server->l2cap.psm = server->l2cap.psm;
tl_server->l2cap.sec_mask = server->l2cap.sec_mask;
tl_server->l2cap.pref_mtu = server->l2cap.pref_mtu;
bdcpy(tl_server->l2cap.addr, server->l2cap.addr);
}
else {
OBEX_TRACE_ERROR("Unsupported OBEX transport type\n");
assert(0);
}
}
static inline void obex_updata_packet_length(BT_HDR *p_buf, UINT16 len)
{
UINT8 *p_pkt_len = (UINT8 *)(p_buf + 1) + p_buf->offset + 1;
STORE16BE(p_pkt_len, len);
}
/*******************************************************************************
**
** Function OBEX_Init
**
** Description Initialize OBEX Profile, must call before using any other
** OBEX APIs
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_Init(void)
{
#if (OBEX_DYNAMIC_MEMORY)
if (!obex_cb_ptr) {
obex_cb_ptr = (tOBEX_CB *)osi_malloc(sizeof(tOBEX_CB));
if (!obex_cb_ptr) {
return OBEX_NO_RESOURCES;
}
}
#endif /* #if (OBEX_DYNAMIC_MEMORY) */
memset(&obex_cb, 0, sizeof(tOBEX_CB));
obex_cb.tl_ops[OBEX_OVER_L2CAP] = obex_tl_l2cap_ops_get();
if (obex_cb.tl_ops[OBEX_OVER_L2CAP]->init != NULL) {
obex_cb.tl_ops[OBEX_OVER_L2CAP]->init(obex_tl_l2cap_callback);
}
/* Not implement yet */
/*
obex_cb.tl_ops[OBEX_OVER_RFCOMM] = obex_tl_rfcomm_ops_get();
if (obex_cb.tl_ops[OBEX_OVER_RFCOMM]->init != NULL) {
obex_cb.tl_ops[OBEX_OVER_RFCOMM]->init(obex_tl_rfcomm_callback);
}
*/
obex_cb.trace_level = BT_TRACE_LEVEL_ERROR;
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_Deinit
**
** Description Deinit OBEX profile, once deinit, can not use any other
** APIs until call OBEX_Init again
**
*******************************************************************************/
void OBEX_Deinit(void)
{
if (obex_cb.tl_ops[OBEX_OVER_L2CAP]->deinit != NULL) {
obex_cb.tl_ops[OBEX_OVER_L2CAP]->deinit();
}
/*
if (obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit != NULL) {
obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit();
}
*/
#if (OBEX_DYNAMIC_MEMORY)
if (obex_cb_ptr) {
osi_free(obex_cb_ptr);
obex_cb_ptr = NULL;
}
#endif /* #if (OBEX_DYNAMIC_MEMORY) */
}
/*******************************************************************************
**
** Function OBEX_CreateConn
**
** Description Start the progress of creating an OBEX connection
**
** Returns OBEX_SUCCESS if successful, otherwise failed, when the
** connection is opened, an OBEX_CONNECT_EVT will come
**
*******************************************************************************/
UINT16 OBEX_CreateConn(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_handle)
{
UINT16 ret = OBEX_SUCCESS;
tOBEX_CCB *p_ccb = NULL;
do {
if (server->tl >= OBEX_NUM_TL) {
ret = OBEX_INVALID_PARAM;
break;
}
p_ccb = obex_allocate_ccb();
if (p_ccb == NULL) {
ret = OBEX_NO_RESOURCES;
break;
}
tOBEX_TL_SVR_INFO tl_server = {0};
obex_server_to_tl_server(server, &tl_server);
p_ccb->tl = server->tl;
p_ccb->tl_hdl = obex_cb.tl_ops[p_ccb->tl]->connect(&tl_server);
if (p_ccb->tl_hdl == 0) {
ret = OBEX_ERROR_TL;
break;
}
p_ccb->callback = callback;
p_ccb->role = OBEX_ROLE_CLIENT;
p_ccb->state = OBEX_STATE_OPENING;
*out_handle = p_ccb->allocated;
} while (0);
if (ret != OBEX_SUCCESS && p_ccb != NULL) {
obex_free_ccb(p_ccb);
}
return ret;
}
/*******************************************************************************
**
** Function OBEX_RemoveConn
**
** Description Remove an OBEX connection
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_RemoveConn(UINT16 handle)
{
tOBEX_CCB *p_ccb = NULL;
UINT16 ccb_idx = handle - 1;
if (ccb_idx >= OBEX_MAX_CONNECTION || !obex_cb.ccb[ccb_idx].allocated) {
return OBEX_BAD_HANDLE;
}
p_ccb = &obex_cb.ccb[ccb_idx];
obex_cb.tl_ops[p_ccb->tl]->disconnect(p_ccb->tl_hdl);
obex_free_ccb(p_ccb);
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_RegisterServer
**
** Description Register an OBEX server and listen the incoming connection
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_RegisterServer(tOBEX_SVR_INFO *server, tOBEX_MSG_CBACK callback, UINT16 *out_svr_handle)
{
UINT8 ret = OBEX_SUCCESS;
tOBEX_SCB *p_scb = NULL;
do {
if (server->tl >= OBEX_NUM_TL) {
ret = OBEX_INVALID_PARAM;
break;
}
p_scb = obex_allocate_scb();
if (p_scb == NULL) {
ret = OBEX_NO_RESOURCES;
break;
}
tOBEX_TL_SVR_INFO tl_server = {0};
obex_server_to_tl_server(server, &tl_server);
p_scb->tl = server->tl;
p_scb->tl_hdl = obex_cb.tl_ops[p_scb->tl]->bind(&tl_server);
if (p_scb->tl_hdl == 0) {
ret = OBEX_ERROR_TL;
break;
}
p_scb->callback = callback;
if (out_svr_handle) {
/* To avoid confuse with connection handle, left shift 8 bit */
*out_svr_handle = p_scb->allocated << 8;
}
} while (0);
if (ret != OBEX_SUCCESS && p_scb != NULL) {
obex_free_scb(p_scb);
}
return ret;
}
/*******************************************************************************
**
** Function OBEX_DeregisterServer
**
** Description Deregister an OBEX server, if there are still a connection
** alive, the behavior depend on the implementation of transport
** layer
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_DeregisterServer(UINT16 svr_handle)
{
tOBEX_SCB *p_scb = NULL;
UINT16 scb_idx = (svr_handle >> 8) - 1;
if (scb_idx >= OBEX_MAX_SERVER || !obex_cb.scb[scb_idx].allocated) {
return OBEX_BAD_HANDLE;
}
p_scb = &obex_cb.scb[scb_idx];
obex_cb.tl_ops[p_scb->tl]->unbind(p_scb->tl_hdl);
obex_free_scb(p_scb);
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_SendPacket
**
** Description Send a packet to peer OBEX server or client, once call
** this function, the ownership of pkt is lost, do not free
** or modify the pkt any more
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_SendPacket(UINT16 handle, BT_HDR *pkt)
{
UINT16 ret = OBEX_SUCCESS;
BOOLEAN free_pkt = true;
tOBEX_CCB *p_ccb = NULL;
do {
if (pkt == NULL) {
ret = OBEX_INVALID_PARAM;
break;
}
UINT16 ccb_idx = handle - 1;
if (ccb_idx >= OBEX_MAX_CONNECTION || !obex_cb.ccb[ccb_idx].allocated) {
ret = OBEX_BAD_HANDLE;
break;
}
p_ccb = &obex_cb.ccb[ccb_idx];
if (p_ccb->state != OBEX_STATE_OPENED) {
ret = OBEX_NOT_OPEN;
break;
}
if (pkt->len > p_ccb->tl_peer_mtu) {
ret = OBEX_PACKET_TOO_LARGE;
break;
}
ret = obex_cb.tl_ops[p_ccb->tl]->send(p_ccb->tl_hdl, pkt);
/* packet has pass to lower layer, do not free it */
free_pkt = false;
if (ret == OBEX_TL_SUCCESS || ret == OBEX_TL_CONGESTED) {
ret = OBEX_SUCCESS;
}
else {
ret = OBEX_ERROR_TL;
}
} while (0);
if (free_pkt) {
osi_free(pkt);
}
return ret;
}
/*******************************************************************************
**
** Function OBEX_BuildRequest
**
** Description Build a request packet with opcode and additional info,
** packet can free by osi_free
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_BuildRequest(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt)
{
if (buff_size < OBEX_MIN_PACKET_SIZE || info == NULL || out_pkt == NULL) {
return OBEX_INVALID_PARAM;
}
buff_size += sizeof(BT_HDR) + OBEX_BT_HDR_MIN_OFFSET;
BT_HDR *p_buf= (BT_HDR *)osi_malloc(buff_size);
if (p_buf == NULL) {
return OBEX_NO_RESOURCES;
}
UINT16 pkt_len = OBEX_MIN_PACKET_SIZE;
p_buf->offset = OBEX_BT_HDR_MIN_OFFSET;
/* use layer_specific to store the max data length allowed */
p_buf->layer_specific = buff_size - sizeof(BT_HDR) - OBEX_BT_HDR_MIN_OFFSET;
UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
/* byte 0: opcode */
*p_data++ = info->opcode;
/* byte 1, 2: packet length, skip, we will update at last */
UINT8 *p_pkt_len = p_data;
p_data += 2;
switch (info->opcode)
{
case OBEX_OPCODE_CONNECT:
/* byte 3: OBEX version number */
*p_data++ = info->obex_version_number;
/* byte 4: flags */
*p_data++ = info->flags;
/* byte 5, 6: maximum OBEX packet length, recommend to set as our mtu*/
STORE16BE(p_data, info->max_packet_length);
pkt_len += 4;
break;
case OBEX_OPCODE_SETPATH:
/* byte 3: flags */
*p_data++ = info->flags;
/* byte 4: constants, reserved, must be zero */
*p_data++ = 0;
pkt_len += 2;
break;
default:
break;
}
STORE16BE(p_pkt_len, pkt_len);
p_buf->len = pkt_len;
*out_pkt = p_buf;
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_BuildResponse
**
** Description Build a response packet with opcode and response and additional
** info, packet can by free by osi_free
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_BuildResponse(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_pkt)
{
if (buff_size < OBEX_MIN_PACKET_SIZE || info == NULL || out_pkt == NULL) {
return OBEX_INVALID_PARAM;
}
buff_size += sizeof(BT_HDR) + OBEX_BT_HDR_MIN_OFFSET;
BT_HDR *p_buf= (BT_HDR *)osi_malloc(buff_size);
if (p_buf == NULL) {
return OBEX_NO_RESOURCES;
}
UINT16 pkt_len = OBEX_MIN_PACKET_SIZE;
p_buf->offset = OBEX_BT_HDR_MIN_OFFSET;
/* use layer_specific to store the max data length allowed */
p_buf->layer_specific = buff_size - sizeof(BT_HDR) - OBEX_BT_HDR_MIN_OFFSET;
UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
/* byte 0: response code */
*p_data++ = info->response_code;
/* byte 1, 2: packet length, skip, we will update at last */
UINT8 *p_pkt_len = p_data;
p_data += 2;
/* we need to use opcode to decide the response format */
switch (info->opcode)
{
case OBEX_OPCODE_CONNECT:
/* byte 3: OBEX version number */
*p_data++ = info->obex_version_number;
/* byte 4: flags */
*p_data++ = info->flags;
/* byte 5, 6: maximum OBEX packet length, recommend to set as our mtu */
STORE16BE(p_data, info->max_packet_length);
pkt_len += 4;
break;
default:
break;
}
STORE16BE(p_pkt_len, pkt_len);
p_buf->len = pkt_len;
*out_pkt = p_buf;
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_AppendHeader
**
** Description Append a header to specific packet, packet can be request
** or response, the format of header must be valid
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_AppendHeader(BT_HDR *pkt, const UINT8 *header)
{
if (pkt == NULL || header == NULL) {
return OBEX_INVALID_PARAM;
}
UINT16 header_len = 0;
UINT8 header_id = *header;
switch (header_id & OBEX_HEADER_ID_U2B_MASK)
{
case OBEX_HEADER_ID_U2B_TYPE1:
case OBEX_HEADER_ID_U2B_TYPE2:
header_len = (header[1] << 8) + header[2];
break;
case OBEX_HEADER_ID_U2B_TYPE3:
header_len = 2;
break;
case OBEX_HEADER_ID_U2B_TYPE4:
header_len = 5;
break;
default:
break;
}
if (header_len == 0) {
return OBEX_INVALID_PARAM;
}
if (pkt->layer_specific - pkt->len < header_len) {
/* the packet can not hold this header */
return OBEX_NO_RESOURCES;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
UINT8 *p_start = p_data + pkt->len;
memcpy(p_start, header, header_len);
pkt->len += header_len;
/* point to packet len */
p_data++;
STORE16BE(p_data, pkt->len);
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_AppendHeaderRaw
**
** Description Append a header to specific packet, packet can be request
** or response, data not include 2 byte length prefixed
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_AppendHeaderRaw(BT_HDR *pkt, UINT8 header_id, const UINT8 *data, UINT16 data_len)
{
if (pkt == NULL || data == NULL) {
return OBEX_INVALID_PARAM;
}
UINT16 header_len = 0;
BOOLEAN store_header_len = FALSE;
switch (header_id & OBEX_HEADER_ID_U2B_MASK)
{
case OBEX_HEADER_ID_U2B_TYPE1:
case OBEX_HEADER_ID_U2B_TYPE2:
/* header id + 2 byte length prefixed + data */
header_len = data_len + 3;
store_header_len = TRUE;
break;
case OBEX_HEADER_ID_U2B_TYPE3:
header_len = 2;
if (data_len != 1) {
return OBEX_INVALID_PARAM;
}
break;
case OBEX_HEADER_ID_U2B_TYPE4:
header_len = 5;
if (data_len != 4) {
return OBEX_INVALID_PARAM;
}
break;
default:
break;
}
if (header_len == 0) {
return OBEX_INVALID_PARAM;
}
if (pkt->layer_specific - pkt->len < header_len) {
/* the packet can not hold this header */
return OBEX_NO_RESOURCES;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
UINT8 *p_start = p_data + pkt->len;
/* store header id */
*p_start++ = header_id;
if (store_header_len) {
/* store header length */
STORE16BE(p_start, header_len);
p_start+= 2;
}
/* store data */
memcpy(p_start, data, data_len);
pkt->len += header_len;
/* point to packet len */
p_data++;
STORE16BE(p_data, pkt->len);
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_AppendHeaderSRM
**
** Description Append a Single Response Mode header
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_AppendHeaderSRM(BT_HDR *pkt, UINT8 value)
{
return OBEX_AppendHeaderRaw(pkt, OBEX_HEADER_ID_SRM, &value, 1);
}
/*******************************************************************************
**
** Function OBEX_AppendHeaderSRMP
**
** Description Append a Single Response Mode Parameters header
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_AppendHeaderSRMP(BT_HDR *pkt, UINT8 value)
{
return OBEX_AppendHeaderRaw(pkt, OBEX_HEADER_ID_SRM_PARAM, &value, 1);
}
/*******************************************************************************
**
** Function OBEX_GetPacketFreeSpace
**
** Description Get the current free space of a packet, use this to check
** if a packet can hold a header
**
** Returns Current free space of a packet, in bytes
**
*******************************************************************************/
UINT16 OBEX_GetPacketFreeSpace(BT_HDR *pkt)
{
if (pkt == NULL) {
return 0;
}
return pkt->layer_specific - pkt->len;
}
/*******************************************************************************
**
** Function OBEX_GetPacketLength
**
** Description Get the current packet length
**
** Returns Current packet length, in bytes
**
*******************************************************************************/
UINT16 OBEX_GetPacketLength(BT_HDR *pkt)
{
if (pkt == NULL) {
return 0;
}
return pkt->len;
}
/*******************************************************************************
**
** Function OBEX_ParseRequest
**
** Description Parse a request packet
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_ParseRequest(BT_HDR *pkt, tOBEX_PARSE_INFO *info)
{
if (pkt == NULL || info == NULL) {
return OBEX_INVALID_PARAM;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
info->opcode = *p_data;
switch (info->opcode)
{
case OBEX_OPCODE_CONNECT:
info->obex_version_number = p_data[3];
info->flags = p_data[4];
info->max_packet_length = (p_data[5] << 8) + p_data[6];
info->next_header_pos = 7;
break;
case OBEX_OPCODE_SETPATH:
info->flags = p_data[3];
info->next_header_pos = 5;
break;
default:
info->next_header_pos = 3;
break;
}
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_ParseResponse
**
** Description Parse a request response packet
**
** Returns OBEX_SUCCESS if successful, otherwise failed
**
*******************************************************************************/
UINT16 OBEX_ParseResponse(BT_HDR *pkt, UINT8 opcode, tOBEX_PARSE_INFO *info)
{
if (pkt == NULL || info == NULL) {
return OBEX_INVALID_PARAM;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
info->opcode = opcode;
info->response_code = *p_data;
switch (opcode)
{
case OBEX_OPCODE_CONNECT:
info->obex_version_number = p_data[3];
info->flags = p_data[4];
info->max_packet_length = (p_data[5] << 8) + p_data[6];
info->next_header_pos = 7;
break;
default:
info->next_header_pos = 3;
break;
}
return OBEX_SUCCESS;
}
/*******************************************************************************
**
** Function OBEX_CheckFinalBit
**
** Description Check whether a packet had set the final bit
**
** Returns TRUE if final bit set, otherwise, false
**
*******************************************************************************/
BOOLEAN OBEX_CheckFinalBit(BT_HDR *pkt)
{
if (pkt == NULL) {
return FALSE;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
return (*p_data) & OBEX_FINAL_BIT_MASK;
}
/*******************************************************************************
**
** Function OBEX_CheckContinueResponse
**
** Description Check whether a packet is continue response
**
** Returns TRUE if continue response, otherwise, false
**
*******************************************************************************/
BOOLEAN OBEX_CheckContinueResponse(BT_HDR *pkt)
{
if (pkt == NULL) {
return FALSE;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
return (*p_data == 0x90) || (*p_data == 0x10);
}
/*******************************************************************************
**
** Function OBEX_GetHeaderLength
**
** Description Get header length
**
** Returns header length
**
*******************************************************************************/
UINT16 OBEX_GetHeaderLength(UINT8 *header)
{
UINT16 header_len = 0;
UINT8 header_id = *header;
switch (header_id & OBEX_HEADER_ID_U2B_MASK)
{
case OBEX_HEADER_ID_U2B_TYPE1:
case OBEX_HEADER_ID_U2B_TYPE2:
header_len = (header[1] << 8) + header[2];
break;
case OBEX_HEADER_ID_U2B_TYPE3:
header_len = 2;
break;
case OBEX_HEADER_ID_U2B_TYPE4:
header_len = 5;
break;
default:
/* unreachable */
break;
}
return header_len;
}
/*******************************************************************************
**
** Function OBEX_GetNextHeader
**
** Description Get next header pointer from a packet
**
** Returns Pointer to start address of a header, NULL if no more header
** or failed
**
*******************************************************************************/
UINT8 *OBEX_GetNextHeader(BT_HDR *pkt, tOBEX_PARSE_INFO *info)
{
if (pkt == NULL || info == NULL) {
return NULL;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
if (info->next_header_pos == 0 || info->next_header_pos >= pkt->len) {
return NULL;
}
UINT8 *header = p_data + info->next_header_pos;
UINT16 header_len = OBEX_GetHeaderLength(header);
info->next_header_pos += header_len;
return header;
}
#endif /* #if (OBEX_INCLUDED == TRUE) */

View File

@ -0,0 +1,211 @@
/*
* 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 "obex_int.h"
#include "obex_tl.h"
#if (OBEX_INCLUDED == TRUE)
#if OBEX_DYNAMIC_MEMORY == FALSE
tOBEX_CB obex_cb;
#else
tOBEX_CB *obex_cb_ptr = NULL;
#endif
static tOBEX_CCB *obex_find_ccb_by_tl_hdl(UINT8 tl, UINT16 tl_hdl)
{
tOBEX_CCB *p_ccb = NULL;
for (int i = 0; i < OBEX_MAX_CONNECTION; ++i) {
if (obex_cb.ccb[i].allocated && obex_cb.ccb[i].tl == tl && obex_cb.ccb[i].tl_hdl == tl_hdl) {
p_ccb = &obex_cb.ccb[i];
break;
}
}
return p_ccb;
}
static tOBEX_SCB *obex_find_scb_by_tl_hdl(UINT8 tl, UINT16 tl_hdl)
{
tOBEX_SCB *p_scb = NULL;
for (int i = 0; i < OBEX_MAX_SERVER; ++i) {
if (obex_cb.scb[i].allocated && obex_cb.scb[i].tl == tl && obex_cb.scb[i].tl_hdl == tl_hdl) {
p_scb = &obex_cb.scb[i];
break;
}
}
return p_scb;
}
tOBEX_CCB *obex_allocate_ccb(void)
{
tOBEX_CCB *p_ccb = NULL;
for (int i = 0; i < OBEX_MAX_CONNECTION; ++i) {
if (!obex_cb.ccb[i].allocated) {
obex_cb.ccb[i].allocated = i + 1;
p_ccb = &obex_cb.ccb[i];
break;
}
}
return p_ccb;
}
void obex_free_ccb(tOBEX_CCB *p_ccb)
{
assert(p_ccb->allocated != 0);
memset(p_ccb, 0, sizeof(tOBEX_CCB));
}
tOBEX_SCB *obex_allocate_scb(void)
{
tOBEX_SCB *p_scb = NULL;
for (int i = 0; i < OBEX_MAX_SERVER; ++i) {
if (!obex_cb.scb[i].allocated) {
obex_cb.scb[i].allocated = i + 1;
p_scb = &obex_cb.scb[i];
break;
}
}
return p_scb;
}
void obex_free_scb(tOBEX_SCB *p_scb)
{
assert(p_scb->allocated != 0);
memset(p_scb, 0, sizeof(tOBEX_SCB));
}
/* check whether connection mtu is valid, if not, disconnect it */
static bool check_conn_mtu_valid(tOBEX_CCB *p_ccb, BOOLEAN call_cb)
{
if (p_ccb->tl_our_mtu < 255 || p_ccb->tl_peer_mtu < 255) {
if (call_cb && p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_DISCONNECT_EVT, NULL);
}
OBEX_TRACE_ERROR("Check OBEX transport layer MTU failed, disconnect");
obex_cb.tl_ops[p_ccb->tl]->disconnect(p_ccb->tl_hdl);
obex_free_ccb(p_ccb);
return false;
}
return true;
}
void obex_tl_evt_handler(UINT8 tl, tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg)
{
UINT16 tl_hdl = msg->any.hdl;
tOBEX_CCB *p_ccb = obex_find_ccb_by_tl_hdl(tl, tl_hdl);
tOBEX_SCB *p_scb = NULL;
tOBEX_MSG cb_msg = {0};
switch (evt)
{
case OBEX_TL_CONN_OPEN_EVT:
assert(p_ccb != NULL);
p_ccb->tl_peer_mtu = msg->conn_open.peer_mtu;
p_ccb->tl_our_mtu = msg->conn_open.our_mtu;
if (!check_conn_mtu_valid(p_ccb, TRUE)) {
break;
}
p_ccb->state = OBEX_STATE_OPENED;
if (p_ccb->callback) {
cb_msg.connect.peer_mtu = msg->conn_open.peer_mtu;
cb_msg.connect.our_mtu = msg->conn_open.our_mtu;
p_ccb->callback(p_ccb->allocated, OBEX_CONNECT_EVT, &cb_msg);
}
break;
case OBEX_TL_DIS_CONN_EVT:
if (p_ccb != NULL) {
if (p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_DISCONNECT_EVT, NULL);
}
obex_free_ccb(p_ccb);
}
break;
case OBEX_TL_CONGEST_EVT:
assert(p_ccb != NULL);
if (p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_CONGEST_EVT, NULL);
}
break;
case OBEX_TL_UNCONGEST_EVT:
assert(p_ccb != NULL);
if (p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_UNCONGEST_EVT, NULL);
}
break;
case OBEX_TL_MTU_CHANGE_EVT:
assert(p_ccb != NULL);
p_ccb->tl_peer_mtu = msg->mtu_chg.peer_mtu;
p_ccb->tl_our_mtu = msg->mtu_chg.our_mtu;
if (!check_conn_mtu_valid(p_ccb, TRUE)) {
break;
}
if (p_ccb->callback) {
cb_msg.mtu_change.peer_mtu = msg->mtu_chg.peer_mtu;
cb_msg.mtu_change.our_mtu = msg->mtu_chg.our_mtu;
p_ccb->callback(p_ccb->allocated, OBEX_MTU_CHANGE_EVT, &cb_msg);
}
break;
case OBEX_TL_DATA_EVT:
assert(p_ccb != NULL);
if (p_ccb->callback) {
cb_msg.data.pkt = msg->data.p_buf;
p_ccb->callback(p_ccb->allocated, OBEX_DATA_EVT, &cb_msg);
}
else {
/* No callback, just free the packet */
osi_free(msg->data.p_buf);
}
break;
case OBEX_TL_CONN_INCOME_EVT:
/* New connection, p_ccb should be NULL */
assert(p_ccb == NULL);
p_scb = obex_find_scb_by_tl_hdl(tl, msg->conn_income.svr_hdl);
if (p_scb == NULL) {
obex_cb.tl_ops[tl]->disconnect(tl_hdl);
break;
}
if ((p_ccb = obex_allocate_ccb()) == NULL) {
obex_cb.tl_ops[tl]->disconnect(tl_hdl);
break;
}
p_ccb->tl = tl;
p_ccb->tl_hdl = tl_hdl;
p_ccb->role = OBEX_ROLE_SERVER;
p_ccb->tl_peer_mtu = msg->conn_income.peer_mtu;
p_ccb->tl_our_mtu = msg->conn_income.our_mtu;
if (!check_conn_mtu_valid(p_ccb, FALSE)) {
break;
}
p_ccb->state = OBEX_STATE_OPENED;
p_ccb->callback = p_scb->callback;
if (p_ccb->callback) {
cb_msg.conn_income.svr_handle = p_scb->allocated << 8;
cb_msg.conn_income.peer_mtu = msg->conn_income.peer_mtu;
cb_msg.conn_income.our_mtu = msg->conn_income.our_mtu;
p_ccb->callback(p_ccb->allocated, OBEX_CONN_INCOME_EVT, &cb_msg);
}
break;
default:
OBEX_TRACE_ERROR("Unknown OBEX transport event: 0x%x\n", evt);
break;
}
}
void obex_tl_l2cap_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg)
{
obex_tl_evt_handler(OBEX_OVER_L2CAP, evt, msg);
}
#endif /* #if (OBEX_INCLUDED == TRUE) */

View File

@ -0,0 +1,807 @@
/*
* 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/l2c_api.h"
#include "stack/l2cdefs.h"
#include "stack/btm_api.h"
#include "btm_int.h"
#include "obex_tl.h"
#include "obex_tl_l2cap.h"
#if (OBEX_INCLUDED == TRUE)
#define OBEX_TL_L2CAP_NUM_CONN 4
#define OBEX_TL_L2CAP_NUM_SERVER 2
#define OBEX_TL_L2CAP_STATUS_FLAG_CFG_DONE 0x01
#define OBEX_TL_L2CAP_STATUS_FLAG_PEER_CFG_DONE 0x02
#define OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED 0x80
/* ERTM Tx window size */
#define OBEX_TL_L2CAP_FCR_OPT_TX_WINDOW_SIZE 10
/* ERTM Maximum transmissions before disconnecting */
#define OBEX_TL_L2CAP_FCR_OPT_MAX_TX_B4_DISCNT 20
/* ERTM Retransmission timeout (2 secs) */
#define OBEX_TL_L2CAP_FCR_OPT_RETX_TOUT 2000
/* ERTM Monitor timeout (12 secs) */
#define OBEX_TL_L2CAP_FCR_OPT_MONITOR_TOUT 12000
/* ERTM ERTM MPS segment size */
#define OBEX_TL_L2CAP_FCR_OPT_MAX_PDU_SIZE 1010
typedef struct {
UINT16 vpsm; /* psm in our side */
UINT16 lcid; /* local channel id */
UINT16 peer_mtu; /* MTU that peer device set */
UINT16 our_mtu; /* MTU that we set to peer device */
BOOLEAN initiator; /* TRUE if is initiator, otherwise FALSE */
UINT8 id; /* remote channel id */
UINT8 status_flag; /* status flag used in config procedure */
UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, equal to handle */
BD_ADDR addr; /* peer bluetooth device address */
} tOBEX_TL_L2CAP_CCB;
typedef struct {
UINT16 psm; /* psm in our side */
UINT16 pref_mtu; /* preferred mtu */
UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, handle of server will left shift 8 bits */
} tOBEX_TL_L2CAP_SCB;
typedef struct {
tOBEX_TL_CBACK *callback; /* Upper layer callback */
tOBEX_TL_L2CAP_CCB ccb[OBEX_TL_L2CAP_NUM_CONN];
tOBEX_TL_L2CAP_SCB scb[OBEX_TL_L2CAP_NUM_SERVER];
tL2CAP_APPL_INFO l2cap_reg_info; /* Default L2CAP Registration info */
UINT8 trace_level; /* trace level */
} tOBEX_TL_L2CAP_CB;
#if OBEX_DYNAMIC_MEMORY == FALSE
static tOBEX_TL_L2CAP_CB obex_tl_l2cap_cb;
#else
static tOBEX_TL_L2CAP_CB *obex_tl_l2cap_cb_ptr = NULL;
#define obex_tl_l2cap_cb (*obex_tl_l2cap_cb_ptr)
#endif
static tL2CAP_ERTM_INFO obex_tl_l2cap_etm_opts =
{
L2CAP_FCR_ERTM_MODE,
L2CAP_FCR_CHAN_OPT_ERTM | L2CAP_FCR_CHAN_OPT_BASIC, /* Some devices do not support ERTM */
L2CAP_USER_RX_BUF_SIZE,
L2CAP_USER_TX_BUF_SIZE,
L2CAP_FCR_RX_BUF_SIZE,
L2CAP_FCR_TX_BUF_SIZE
};
static tL2CAP_FCR_OPTS obex_tl_l2cap_fcr_opts =
{
L2CAP_FCR_ERTM_MODE,
OBEX_TL_L2CAP_FCR_OPT_TX_WINDOW_SIZE, /* Tx window size */
OBEX_TL_L2CAP_FCR_OPT_MAX_TX_B4_DISCNT, /* Maximum transmissions before disconnecting */
OBEX_TL_L2CAP_FCR_OPT_RETX_TOUT, /* Retransmission timeout (2 secs) */
OBEX_TL_L2CAP_FCR_OPT_MONITOR_TOUT, /* Monitor timeout (12 secs) */
OBEX_TL_L2CAP_FCR_OPT_MAX_PDU_SIZE /* MPS segment size */
};
static tOBEX_TL_L2CAP_CCB *allocate_ccb(void)
{
tOBEX_TL_L2CAP_CCB *p_ccb = NULL;
for(int i = 0; i < OBEX_TL_L2CAP_NUM_CONN; ++i) {
if (obex_tl_l2cap_cb.ccb[i].allocated == 0) {
obex_tl_l2cap_cb.ccb[i].allocated = i + 1;
p_ccb = &obex_tl_l2cap_cb.ccb[i];
break;
}
}
return p_ccb;
}
static void free_ccb(tOBEX_TL_L2CAP_CCB *p_ccb)
{
memset(p_ccb, 0, sizeof(tOBEX_TL_L2CAP_CCB));
}
static tOBEX_TL_L2CAP_CCB *find_ccb_by_lcid(UINT16 lcid)
{
tOBEX_TL_L2CAP_CCB *p_ccb = NULL;
for (int i = 0; i < OBEX_TL_L2CAP_NUM_CONN; ++i) {
if (obex_tl_l2cap_cb.ccb[i].allocated && obex_tl_l2cap_cb.ccb[i].lcid == lcid) {
p_ccb = &obex_tl_l2cap_cb.ccb[i];
break;
}
}
return p_ccb;
}
static tOBEX_TL_L2CAP_CCB *find_ccb_by_hdl(UINT16 hdl)
{
tOBEX_TL_L2CAP_CCB *p_ccb = NULL;
if (hdl > 0 && hdl <= OBEX_TL_L2CAP_NUM_CONN) {
if (obex_tl_l2cap_cb.ccb[hdl-1].allocated == hdl) {
p_ccb = &obex_tl_l2cap_cb.ccb[hdl-1];
}
}
return p_ccb;
}
static tOBEX_TL_L2CAP_CCB *find_ccb_by_psm(UINT16 psm)
{
tOBEX_TL_L2CAP_CCB *p_ccb = NULL;
for(int i = 0; i < OBEX_TL_L2CAP_NUM_CONN; ++i) {
if (obex_tl_l2cap_cb.ccb[i].allocated && obex_tl_l2cap_cb.ccb[i].vpsm == psm) {
p_ccb = &obex_tl_l2cap_cb.ccb[i];
break;
}
}
return p_ccb;
}
static tOBEX_TL_L2CAP_SCB *allocate_scb(void)
{
tOBEX_TL_L2CAP_SCB *p_scb = NULL;
for(int i = 0; i < OBEX_TL_L2CAP_NUM_SERVER; ++i) {
if (obex_tl_l2cap_cb.scb[i].allocated == 0) {
obex_tl_l2cap_cb.scb[i].allocated = i + 1;
p_scb = &obex_tl_l2cap_cb.scb[i];
break;
}
}
return p_scb;
}
static tOBEX_TL_L2CAP_SCB *find_scb_by_psm(UINT16 psm)
{
tOBEX_TL_L2CAP_SCB *p_scb = NULL;
for(int i = 0; i < OBEX_TL_L2CAP_NUM_SERVER; ++i) {
if (obex_tl_l2cap_cb.scb[i].allocated && obex_tl_l2cap_cb.scb[i].psm == psm) {
p_scb = &obex_tl_l2cap_cb.scb[i];
break;
}
}
return p_scb;
}
static void free_scb(tOBEX_TL_L2CAP_SCB *p_scb)
{
memset(p_scb, 0, sizeof(tOBEX_TL_L2CAP_SCB));
}
static tOBEX_TL_L2CAP_SCB *find_scb_by_hdl(UINT16 hdl)
{
tOBEX_TL_L2CAP_SCB *p_scb = NULL;
hdl = hdl >> 8;
if (hdl > 0 && hdl <= OBEX_TL_L2CAP_NUM_SERVER) {
if (obex_tl_l2cap_cb.scb[hdl-1].allocated == hdl) {
p_scb = &obex_tl_l2cap_cb.scb[hdl-1];
}
}
return p_scb;
}
/*******************************************************************************
*
* Function obex_tl_l2cap_sec_check_complete_term
*
* Description OBEX over L2CAP security check complete callback function
* (terminated).
*
******************************************************************************/
static void l2cap_sec_check_complete_term(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tOBEX_TL_L2CAP_CCB *p_ccb = (tOBEX_TL_L2CAP_CCB *)p_ref_data;
if (res == BTM_SUCCESS) {
L2CA_ErtmConnectRsp(p_ccb->addr, p_ccb->id, p_ccb->lcid, L2CAP_CONN_OK, 0, &obex_tl_l2cap_etm_opts);
tL2CAP_CFG_INFO cfg = {0};
cfg.mtu_present = TRUE;
cfg.mtu = p_ccb->our_mtu;
cfg.fcr_present = TRUE;
cfg.fcr = obex_tl_l2cap_fcr_opts;
L2CA_ConfigReq(p_ccb->lcid, &cfg);
}
else{
L2CA_ErtmConnectRsp(p_ccb->addr, p_ccb->id, p_ccb->lcid, L2CAP_CONN_SECURITY_BLOCK, 0, &obex_tl_l2cap_etm_opts);
tOBEX_TL_MSG msg = {0};
msg.any.hdl = p_ccb->allocated;
obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
free_ccb(p_ccb);
}
}
/*******************************************************************************
*
* Function obex_tl_l2cap_sec_check_complete_orig
*
* Description OBEX over L2CAP security check complete callback function
* (originated).
*
******************************************************************************/
static void l2cap_sec_check_complete_orig(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tOBEX_TL_L2CAP_CCB *p_ccb = (tOBEX_TL_L2CAP_CCB *)p_ref_data;
if (res == BTM_SUCCESS) {
tL2CAP_CFG_INFO cfg = {0};
cfg.mtu_present = TRUE;
cfg.mtu = p_ccb->our_mtu;
cfg.fcr_present = TRUE;
cfg.fcr = obex_tl_l2cap_fcr_opts;
L2CA_ConfigReq(p_ccb->lcid, &cfg);
} else {
L2CA_DisconnectReq(p_ccb->lcid);
tOBEX_TL_MSG msg = {0};
msg.any.hdl = p_ccb->allocated;
obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
free_ccb(p_ccb);
}
}
/*******************************************************************************
**
** Function obex_tl_l2cap_connect_ind
**
** Description This is a callback function called by L2CAP when
** L2CA_ConnectInd received.
**
*******************************************************************************/
void obex_tl_l2cap_connect_ind(BD_ADDR addr, UINT16 lcid, UINT16 psm, UINT8 id)
{
tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(psm);
if (p_scb == NULL) {
/* An incoming connection, but no corresponding server found, reject */
L2CA_ErtmConnectRsp (addr, id, lcid, L2CAP_CONN_NO_PSM, 0, &obex_tl_l2cap_etm_opts);
OBEX_TL_L2CAP_TRACE_WARNING("No corresponding server found, reject incoming connection\n");
return;
}
tOBEX_TL_L2CAP_CCB *p_ccb = allocate_ccb();
if (p_ccb == NULL) {
/* No resource, can not allocate ccb, reject */
L2CA_ErtmConnectRsp (addr, id, lcid, L2CAP_CONN_NO_RESOURCES, 0, &obex_tl_l2cap_etm_opts);
OBEX_TL_L2CAP_TRACE_WARNING("Can not allocate a ccb for new connection\n");
return;
}
bdcpy(p_ccb->addr, addr);
p_ccb->initiator = FALSE;
p_ccb->lcid = lcid;
p_ccb->id = id;
p_ccb->vpsm = psm;
p_ccb->our_mtu = p_scb->pref_mtu;
if (btm_sec_mx_access_request(p_ccb->addr, p_ccb->vpsm,
FALSE, BTM_SEC_PROTO_OBEX,
OBEX_TL_L2CAP_NUM_CONN + p_scb->allocated - 1,
&l2cap_sec_check_complete_term, p_ccb) == BTM_CMD_STARTED) {
L2CA_ErtmConnectRsp(addr, id, lcid, L2CAP_CONN_PENDING, 0, &obex_tl_l2cap_etm_opts);
}
}
/*******************************************************************************
**
** Function obex_tl_l2cap_connect_cfm
**
** Description This is a callback function called by L2CAP when
** ConnectCfm received.
**
*******************************************************************************/
void obex_tl_l2cap_connect_cfm(UINT16 lcid, UINT16 result)
{
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid);
if (p_ccb == NULL) {
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_connect_cfm but no ccb found\n");
return;
}
if (result == L2CAP_CONN_OK) {
btm_sec_mx_access_request(p_ccb->addr, p_ccb->vpsm,
TRUE, BTM_SEC_PROTO_OBEX,
p_ccb->allocated - 1,
&l2cap_sec_check_complete_orig, p_ccb);
} else {
OBEX_TL_L2CAP_TRACE_WARNING("l2cap_connect_cfm result != L2CAP_CONN_OK: result: 0x%x\n", result);
tOBEX_TL_MSG msg = {0};
msg.any.hdl = p_ccb->allocated;
obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
free_ccb(p_ccb);
}
}
/*******************************************************************************
**
** Function obex_tl_l2cap_config_ind
**
** Description This is a callback function called by L2CAP when
** L2CA_ConfigInd received.
**
*******************************************************************************/
void obex_tl_l2cap_config_ind(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
{
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid);
if (p_ccb == NULL) {
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_ind but no ccb found\n");
return;
}
tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(p_ccb->vpsm);
if (p_ccb->initiator == FALSE && p_scb == NULL) {
/* not a initiator, but can not find corresponding server */
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_ind, not a initiator, but can not find corresponding server\n");
return;
}
/* save peer mtu if present */
UINT16 peer_mtu = L2CAP_DEFAULT_MTU;
if (p_cfg->mtu_present) {
peer_mtu = p_cfg->mtu;
}
p_cfg->mtu_present = FALSE;
p_cfg->flush_to_present = FALSE;
p_cfg->qos_present = FALSE;
p_cfg->result = L2CAP_CFG_OK;
L2CA_ConfigRsp(p_ccb->lcid, p_cfg);
if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED) {
/* reconfig l2cap channel */
if (p_ccb->peer_mtu != peer_mtu) {
/* only report to upper if mtu change */
p_ccb->peer_mtu = peer_mtu;
tOBEX_TL_MSG msg = {0};
msg.mtu_chg.hdl = p_ccb->allocated;
msg.mtu_chg.peer_mtu = peer_mtu;
msg.mtu_chg.our_mtu = p_ccb->our_mtu;
obex_tl_l2cap_cb.callback(OBEX_TL_MTU_CHANGE_EVT, &msg);
}
return;
}
p_ccb->peer_mtu = peer_mtu;
p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_PEER_CFG_DONE;
if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CFG_DONE) {
p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED;
}
if ((p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED)) {
tOBEX_TL_MSG msg = {0};
if (p_ccb->initiator) {
msg.conn_open.hdl = p_ccb->allocated;
msg.conn_open.peer_mtu = p_ccb->peer_mtu;
msg.conn_open.our_mtu = p_ccb->our_mtu;
obex_tl_l2cap_cb.callback(OBEX_TL_CONN_OPEN_EVT, &msg);
}
else {
msg.conn_income.hdl = p_ccb->allocated;
msg.conn_income.peer_mtu = p_ccb->peer_mtu;
msg.conn_income.our_mtu = p_ccb->our_mtu;
msg.conn_income.svr_hdl = p_scb->allocated << 8;
obex_tl_l2cap_cb.callback(OBEX_TL_CONN_INCOME_EVT, &msg);
}
}
}
/*******************************************************************************
**
** Function obex_tl_l2cap_config_cfm
**
** Description This is a callback function called by L2CAP when
** L2CA_ConfigCnf received.
**
*******************************************************************************/
void obex_tl_l2cap_config_cfm(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
{
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid);
if (p_ccb == NULL) {
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_cfm but no ccb found\n");
return;
}
tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(p_ccb->vpsm);
if (p_ccb->initiator == FALSE && p_scb == NULL) {
/* not a initiator, but can not find corresponding server */
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_config_cfm, not a initiator, but can not find corresponding server\n");
return;
}
if (p_cfg->result != L2CAP_CFG_OK) {
OBEX_TL_L2CAP_TRACE_WARNING("l2cap_config_cfm result != L2CAP_CFG_OK: result: 0x%x\n", p_cfg->result);
L2CA_DisconnectReq(p_ccb->lcid);
tOBEX_TL_MSG msg = {0};
msg.any.hdl = p_ccb->allocated;
obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
free_ccb(p_ccb);
return;
}
p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_CFG_DONE;
if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_PEER_CFG_DONE) {
p_ccb->status_flag |= OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED;
}
if (p_ccb->status_flag & OBEX_TL_L2CAP_STATUS_FLAG_CONNECTED) {
tOBEX_TL_MSG msg = {0};
if (p_ccb->initiator) {
msg.conn_open.hdl = p_ccb->allocated;
msg.conn_open.peer_mtu = p_ccb->peer_mtu;
msg.conn_open.our_mtu = p_ccb->our_mtu;
obex_tl_l2cap_cb.callback(OBEX_TL_CONN_OPEN_EVT, &msg);
}
else {
msg.conn_income.hdl = p_ccb->allocated;
msg.conn_income.peer_mtu = p_ccb->peer_mtu;
msg.conn_income.our_mtu = p_ccb->our_mtu;
msg.conn_income.svr_hdl = p_scb->allocated << 8;
obex_tl_l2cap_cb.callback(OBEX_TL_CONN_INCOME_EVT, &msg);
}
}
}
/*******************************************************************************
**
** Function obex_tl_l2cap_qos_violation_ind
**
** Description This is a callback function called by L2CAP when
** L2CA_QoSViolationIndInd received.
**
*******************************************************************************/
void obex_tl_l2cap_qos_violation_ind(BD_ADDR addr)
{
UNUSED(addr);
}
/*******************************************************************************
**
** Function obex_tl_l2cap_disconnect_ind
**
** Description This is a callback function called by L2CAP when
** L2CA_DisconnectInd received.
**
*******************************************************************************/
void obex_tl_l2cap_disconnect_ind(UINT16 lcid, BOOLEAN is_conf_needed)
{
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid);
if (is_conf_needed) {
L2CA_DisconnectRsp(lcid);
}
if (p_ccb == NULL) {
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_disconnect_ind but no ccb found\n");
return;
}
tOBEX_TL_MSG msg = {0};
msg.any.hdl = p_ccb->allocated;
obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
free_ccb(p_ccb);
}
/*******************************************************************************
**
** Function obex_tl_l2cap_buf_data_ind
**
** Description This is a callback function called by L2CAP when
** data frame is received.
**
*******************************************************************************/
void obex_tl_l2cap_buf_data_ind(UINT16 lcid, BT_HDR *p_buf)
{
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid);
if (p_ccb == NULL) {
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_buf_data_ind but no ccb found\n");
osi_free(p_buf);
return;
}
tOBEX_TL_MSG msg = {0};
msg.data.hdl = p_ccb->allocated;
msg.data.p_buf = p_buf;
obex_tl_l2cap_cb.callback(OBEX_TL_DATA_EVT, &msg);
}
/*******************************************************************************
**
** Function obex_tl_l2cap_congestion_status_ind
**
** Description This is a callback function called by L2CAP when
** L2CAP channel congestion status changes
**
*******************************************************************************/
void obex_tl_l2cap_congestion_status_ind(UINT16 lcid, BOOLEAN is_congested)
{
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_lcid(lcid);
if (p_ccb == NULL) {
OBEX_TL_L2CAP_TRACE_ERROR("l2cap_congestion_status_ind but no ccb found\n");
return;
}
tOBEX_TL_MSG msg = {0};
msg.any.hdl = p_ccb->allocated;
if (is_congested) {
obex_tl_l2cap_cb.callback(OBEX_TL_CONGEST_EVT, &msg);
}
else {
obex_tl_l2cap_cb.callback(OBEX_TL_UNCONGEST_EVT, &msg);
}
}
/*******************************************************************************
**
** Function obex_tl_l2cap_init
**
** Description Initialize OBEX over L2CAP transport layer, callback
** can not be NULL, must be called once before using any
** other APIs
**
*******************************************************************************/
void obex_tl_l2cap_init(tOBEX_TL_CBACK callback)
{
assert(callback != NULL);
#if (OBEX_DYNAMIC_MEMORY)
if (!obex_tl_l2cap_cb_ptr) {
obex_tl_l2cap_cb_ptr = (tOBEX_TL_L2CAP_CB *)osi_malloc(sizeof(tOBEX_TL_L2CAP_CB));
if (!obex_tl_l2cap_cb_ptr) {
OBEX_TL_L2CAP_TRACE_ERROR("OBEX over L2CAP transport layer initialize failed, no memory\n");
assert(0);
}
}
#endif /* #if (OBEX_DYNAMIC_MEMORY) */
memset(&obex_tl_l2cap_cb, 0, sizeof(tOBEX_TL_L2CAP_CB));
obex_tl_l2cap_cb.callback = callback;
obex_tl_l2cap_cb.trace_level = BT_TRACE_LEVEL_ERROR;
tL2CAP_APPL_INFO *p_reg_info = &obex_tl_l2cap_cb.l2cap_reg_info;
p_reg_info->pL2CA_ConnectInd_Cb = NULL; /* obex_tl_l2cap_connect_ind or NULL, depend on server or not */
p_reg_info->pL2CA_ConnectCfm_Cb = obex_tl_l2cap_connect_cfm;
p_reg_info->pL2CA_ConnectPnd_Cb = NULL;
p_reg_info->pL2CA_ConfigInd_Cb = obex_tl_l2cap_config_ind;
p_reg_info->pL2CA_ConfigCfm_Cb = obex_tl_l2cap_config_cfm;
p_reg_info->pL2CA_DisconnectInd_Cb = obex_tl_l2cap_disconnect_ind;
p_reg_info->pL2CA_DisconnectCfm_Cb = NULL;
p_reg_info->pL2CA_QoSViolationInd_Cb = obex_tl_l2cap_qos_violation_ind;
p_reg_info->pL2CA_DataInd_Cb = obex_tl_l2cap_buf_data_ind;
p_reg_info->pL2CA_CongestionStatus_Cb = obex_tl_l2cap_congestion_status_ind;
p_reg_info->pL2CA_TxComplete_Cb = NULL;
}
/*******************************************************************************
**
** Function obex_tl_l2cap_init
**
** Description Deinitialize OBEX over L2CAP transport layer
**
*******************************************************************************/
void obex_tl_l2cap_deinit(void)
{
#if (OBEX_DYNAMIC_MEMORY)
if (obex_tl_l2cap_cb_ptr) {
osi_free(obex_tl_l2cap_cb_ptr);
obex_tl_l2cap_cb_ptr = NULL;
}
#endif /* #if (OBEX_DYNAMIC_MEMORY) */
}
/*******************************************************************************
**
** Function obex_tl_l2cap_connect
**
** Description Start the process of establishing a L2CAP connection
**
** Returns Non-zeros handle, 0 while failed
**
*******************************************************************************/
UINT16 obex_tl_l2cap_connect(tOBEX_TL_SVR_INFO *server)
{
tOBEX_TL_L2CAP_CCB *p_ccb = allocate_ccb();
if (p_ccb == NULL) {
/* can not allocate a ccb */
return 0;
}
if (find_scb_by_psm(server->l2cap.psm) == NULL) {
/* if the psm not register by a server, we register it as outgoing only record */
tL2CAP_APPL_INFO *p_reg_info = &obex_tl_l2cap_cb.l2cap_reg_info;
p_reg_info->pL2CA_ConnectInd_Cb = NULL;
p_ccb->vpsm = L2CA_Register(server->l2cap.psm, p_reg_info);
if (p_ccb->vpsm == 0) {
free_ccb(p_ccb);
return 0;
}
/* set security level */
BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_OBEX, server->l2cap.sec_mask, p_ccb->vpsm, BTM_SEC_PROTO_OBEX, p_ccb->allocated - 1);
}
else {
p_ccb->vpsm = server->l2cap.psm;
}
if (server->l2cap.pref_mtu == 0 || server->l2cap.pref_mtu > L2CAP_MTU_SIZE) {
p_ccb->our_mtu = L2CAP_MTU_SIZE;
}
else {
p_ccb->our_mtu = server->l2cap.pref_mtu;
}
p_ccb->initiator = TRUE;
p_ccb->lcid = L2CA_ErtmConnectReq(p_ccb->vpsm, server->l2cap.addr, &obex_tl_l2cap_etm_opts);
if (p_ccb->lcid == 0) {
free_ccb(p_ccb);
return 0;
}
return p_ccb->allocated;
}
/*******************************************************************************
**
** Function obex_tl_l2cap_disconnect
**
** Description Disconnect a L2CAP connection
**
*******************************************************************************/
void obex_tl_l2cap_disconnect(UINT16 hdl)
{
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_hdl(hdl);
if (p_ccb != NULL) {
L2CA_DisconnectReq(p_ccb->lcid);
if (p_ccb->initiator && find_scb_by_psm(p_ccb->vpsm) == NULL) {
L2CA_Deregister(p_ccb->vpsm);
}
free_ccb(p_ccb);
}
}
/*******************************************************************************
**
** Function obex_tl_l2cap_send_data
**
** Description Start the process of establishing a L2CAP connection
**
** Returns OBEX_TL_SUCCESS, if data accepted
** OBEX_TL_CONGESTED, if data accepted and the channel is congested
** OBEX_TL_FAILED, if error
**
*******************************************************************************/
UINT16 obex_tl_l2cap_send_data(UINT16 hdl, BT_HDR *p_buf)
{
UINT16 ret = OBEX_TL_FAILED;
tOBEX_TL_L2CAP_CCB *p_ccb = find_ccb_by_hdl(hdl);
if (p_ccb == NULL) {
osi_free(p_buf);
return ret;
}
/* Can not send data size larger than peer MTU */
/* Offset should not smaller than L2CAP_MIN_OFFSET */
if (p_buf->len > p_ccb->peer_mtu || p_buf->offset < L2CAP_MIN_OFFSET) {
osi_free(p_buf);
return ret;
}
UINT16 status = L2CA_DataWrite(p_ccb->lcid, p_buf);
switch (status)
{
case L2CAP_DW_SUCCESS:
ret = OBEX_TL_SUCCESS;
break;
case L2CAP_DW_CONGESTED:
ret = OBEX_TL_CONGESTED;
break;
default:
ret = OBEX_TL_FAILED;
break;
}
return ret;
}
/*******************************************************************************
**
** Function obex_tl_l2cap_bind
**
** Description Register a server in L2CAP module
**
** Returns Non-zeros handle, 0 while failed
**
*******************************************************************************/
UINT16 obex_tl_l2cap_bind(tOBEX_TL_SVR_INFO *server)
{
tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_psm(server->l2cap.psm);
if (p_scb != NULL) {
/* psm already used */
return 0;
}
p_scb = allocate_scb();
if (p_scb == NULL) {
/* can not allocate a new scb */
return 0;
}
if (server->l2cap.pref_mtu == 0 || server->l2cap.pref_mtu > L2CAP_MTU_SIZE) {
p_scb->pref_mtu= L2CAP_MTU_SIZE;
}
else {
p_scb->pref_mtu = server->l2cap.pref_mtu;
}
tL2CAP_APPL_INFO *p_reg_info = &obex_tl_l2cap_cb.l2cap_reg_info;
p_reg_info->pL2CA_ConnectInd_Cb = obex_tl_l2cap_connect_ind;
/* Register a l2cap server, in this case, L2CA_Register always return the same psm as input */
p_scb->psm = L2CA_Register(server->l2cap.psm, p_reg_info);
if (p_scb->psm == 0) {
free_scb(p_scb);
return 0;
}
/* set security level */
BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_OBEX, server->l2cap.sec_mask, p_scb->psm, BTM_SEC_PROTO_OBEX, OBEX_TL_L2CAP_NUM_CONN + p_scb->allocated - 1);
BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_OBEX, server->l2cap.sec_mask, p_scb->psm, BTM_SEC_PROTO_OBEX, OBEX_TL_L2CAP_NUM_CONN + p_scb->allocated - 1);
/* left shift 8 bits to avoid confuse with connection handle */
return p_scb->allocated << 8;
}
/*******************************************************************************
**
** Function obex_tl_l2cap_unbind
**
** Description Deregister a server in L2CAP module
**
*******************************************************************************/
void obex_tl_l2cap_unbind(UINT16 tl_hdl)
{
tOBEX_TL_L2CAP_SCB *p_scb = find_scb_by_hdl(tl_hdl);
if (p_scb) {
tOBEX_TL_L2CAP_CCB *p_ccb = NULL;
while ((p_ccb = find_ccb_by_psm(p_scb->psm)) != NULL) {
L2CA_DisconnectReq(p_ccb->lcid);
tOBEX_TL_MSG msg = {0};
msg.any.hdl = p_ccb->allocated;
obex_tl_l2cap_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
free_ccb(p_ccb);
}
L2CA_Deregister(p_scb->psm);
free_scb(p_scb);
}
}
static tOBEX_TL_OPS obex_tl_l2cap_ops = {
.init = obex_tl_l2cap_init,
.deinit = obex_tl_l2cap_deinit,
.connect = obex_tl_l2cap_connect,
.disconnect = obex_tl_l2cap_disconnect,
.bind = obex_tl_l2cap_bind,
.unbind = obex_tl_l2cap_unbind,
.send = obex_tl_l2cap_send_data
};
/*******************************************************************************
**
** Function obex_tl_l2cap_ops_get
**
** Description Get the operation function structure pointer of OBEX over
** L2CAP transport layer
**
** Returns Pointer to operation function structure
**
*******************************************************************************/
tOBEX_TL_OPS *obex_tl_l2cap_ops_get(void)
{
return &obex_tl_l2cap_ops;
}
#endif /* #if (OBEX_INCLUDED == TRUE) */

View File

@ -372,7 +372,7 @@ BOOLEAN SDP_FindServiceUUIDInRec(tSDP_DISC_REC *p_rec, tBT_UUID *p_uuid)
if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) {
/* Look through data element sequence until no more UUIDs */
for (p_extra_sattr = p_sattr->attr_value.v.p_sub_attr; p_extra_sattr; p_extra_sattr = p_extra_sattr->p_next_attr) {
/* Increment past this to see if the next attribut is UUID */
/* Increment past this to see if the next attribute is UUID */
if ((SDP_DISC_ATTR_TYPE(p_extra_sattr->attr_len_type) == UUID_DESC_TYPE)
/* only support 16 bits UUID for now */
&& (SDP_DISC_ATTR_LEN(p_extra_sattr->attr_len_type) == 2)) {
@ -522,7 +522,7 @@ tSDP_DISC_REC *SDP_FindServiceInDb (tSDP_DISCOVERY_DB *p_db, UINT16 service_uuid
if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) {
/* Look through data element sequence until no more UUIDs */
for (p_extra_sattr = p_sattr->attr_value.v.p_sub_attr; p_extra_sattr; p_extra_sattr = p_extra_sattr->p_next_attr) {
/* Increment past this to see if the next attribut is UUID */
/* Increment past this to see if the next attribute is UUID */
if ((SDP_DISC_ATTR_TYPE(p_extra_sattr->attr_len_type) == UUID_DESC_TYPE)
&& (SDP_DISC_ATTR_LEN(p_extra_sattr->attr_len_type) == 2)
/* for a specific uuid, or any one */
@ -768,6 +768,28 @@ BOOLEAN SDP_FindProtocolListElemInRec (tSDP_DISC_REC *p_rec, UINT16 layer_uuid,
return (FALSE);
}
/*******************************************************************************
**
** Function SDP_FindProtocolListElem
**
** Description This function looks at the protocol list for a specific protocol
** list element.
**
** Returns TRUE if found, FALSE if not
** If found, the passed protocol list element is filled in.
**
*******************************************************************************/
BOOLEAN SDP_FindProtocolListElem (tSDP_DISC_ATTR *p_protocol_list, UINT16 layer_uuid, tSDP_PROTOCOL_ELEM *p_elem)
{
#if SDP_CLIENT_ENABLED == TRUE
/* don't check the input protocol descriptor list id, this api may be use in additional protocol descriptor list */
if ((SDP_DISC_ATTR_TYPE(p_protocol_list->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE)) {
return sdp_fill_proto_elem(p_protocol_list, layer_uuid, p_elem);
}
#endif
/* If here, no match found */
return (FALSE);
}
/*******************************************************************************
**

View File

@ -276,7 +276,7 @@ static int sdp_compose_proto_list( UINT8 *p, UINT16 num_elem,
**
** Description This function is called to create a record in the database.
** This would be through the SDP database maintenance API. The
** record is created empty, teh application should then call
** record is created empty, the application should then call
** "add_attribute" to add the record's attributes.
**
** Returns Record handle if OK, else 0.
@ -293,15 +293,15 @@ UINT32 SDP_CreateRecord (void)
/* First, check if there is a free record */
if (p_db->num_records < SDP_MAX_RECORDS) {
p_rec =(tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD));
if (p_rec) {
memset(p_rec, 0, sizeof(tSDP_RECORD));
/* Save previous rec */
if (p_db->num_records) {
p_rec_prev = list_back(p_db->p_record_list);
}
/* Append new record */
list_append(p_db->p_record_list, p_rec);
p_rec = (tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD));
if (p_rec) {
memset(p_rec, 0, sizeof(tSDP_RECORD));
/* Save previous rec */
if (p_db->num_records) {
p_rec_prev = list_back(p_db->p_record_list);
}
/* Append new record */
list_append(p_db->p_record_list, p_rec);
/* We will use a handle of the first unreserved handle plus last record
** number + 1 */
@ -321,10 +321,12 @@ UINT32 SDP_CreateRecord (void)
4, buf);
return (p_rec->record_handle);
} else {
}
else {
SDP_TRACE_ERROR("SDP_CreateRecord fail, memory allocation failed\n");
}
} else {
}
}
else {
SDP_TRACE_ERROR("SDP_CreateRecord fail, exceed maximum records:%d\n", SDP_MAX_RECORDS);
}
#endif
@ -354,17 +356,17 @@ BOOLEAN SDP_DeleteRecord (UINT32 handle)
if (handle == 0 || sdp_cb.server_db.num_records == 0) {
/* Delete all records in the database */
sdp_cb.server_db.num_records = 0;
for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) {
list_remove(sdp_cb.server_db.p_record_list, p_node);
}
for (p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) {
list_remove(sdp_cb.server_db.p_record_list, p_node);
}
/* require new DI record to be created in SDP_SetLocalDiRecord */
sdp_cb.server_db.di_primary_handle = 0;
return (TRUE);
} else {
/* Find the record in the database */
for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) {
p_rec = list_node(p_node);
for (p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) {
p_rec = list_node(p_node);
if (p_rec->record_handle == handle) {
/* Found it. Shift everything up one */
list_remove(sdp_cb.server_db.p_record_list, p_rec);
@ -374,7 +376,7 @@ BOOLEAN SDP_DeleteRecord (UINT32 handle)
SDP_TRACE_DEBUG("SDP_DeleteRecord ok, num_records:%d\n", sdp_cb.server_db.num_records);
/* if we're deleting the primary DI record, clear the */
/* value in the control block */
if ( sdp_cb.server_db.di_primary_handle == handle ) {
if (sdp_cb.server_db.di_primary_handle == handle) {
sdp_cb.server_db.di_primary_handle = 0;
}

@ -1 +1 @@
Subproject commit d1f02191a1b17673ee0f539514f50d2e5fdc7863
Subproject commit 6b890f81c0db10ae4757e27eb1312f4232d8fb56

View File

@ -9,6 +9,7 @@
#include <ctype.h>
#include <string.h>
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "esp_intr_alloc.h"
#include "esp_log.h"
#include "esp_pm.h"
@ -18,6 +19,7 @@
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "freertos/ringbuf.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/adc_share_hw_ctrl.h"
#include "esp_private/sar_periph_ctrl.h"
@ -472,6 +474,9 @@ esp_err_t adc_digi_start(void)
adc_hal_set_controller(ADC_UNIT_2, ADC_HAL_CONTINUOUS_READ_MODE);
adc_hal_digi_init(&s_adc_digi_ctx->hal);
#if !CONFIG_IDF_TARGET_ESP32
esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), true);
#endif
adc_hal_digi_controller_config(&s_adc_digi_ctx->hal, &s_adc_digi_ctx->hal_digi_ctrlr_cfg);
adc_dma_stop(s_adc_digi_ctx);

View File

@ -16,6 +16,7 @@
#include "esp_check.h"
#include "esp_pm.h"
#include "soc/rtc.h"
#include "soc/soc_caps.h"
#include "driver/rtc_io.h"
#include "sys/lock.h"
#include "driver/gpio.h"
@ -26,6 +27,7 @@
#include "hal/adc_hal.h"
#include "hal/adc_ll.h"
#include "hal/adc_hal_common.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/periph_ctrl.h"
#include "driver/adc_types_legacy.h"
#include "esp_clk_tree.h"
@ -775,6 +777,7 @@ int adc1_get_raw(adc1_channel_t channel)
adc_apb_periph_claim();
sar_periph_ctrl_adc_oneshot_power_acquire();
esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true);
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
adc_atten_t atten = s_atten1_single[channel];
@ -832,6 +835,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
adc_apb_periph_claim();
sar_periph_ctrl_adc_oneshot_power_acquire();
esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true);
adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();

View File

@ -14,6 +14,7 @@
#include "esp_intr_alloc.h"
#include "soc/mcpwm_periph.h"
#include "soc/io_mux_reg.h"
#include "soc/soc_caps.h"
#include "hal/mcpwm_hal.h"
#include "hal/gpio_hal.h"
#include "hal/mcpwm_ll.h"
@ -22,6 +23,7 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/gpio.h"
#include "esp_private/esp_clk.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_clk_tree.h"
static const char *TAG = "mcpwm(legacy)";
@ -467,6 +469,7 @@ esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpw
uint32_t group_pre_scale = clk_src_hz / group_resolution;
uint32_t timer_pre_scale = group_resolution / timer_resolution;
esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true);
MCPWM_CLOCK_SRC_ATOMIC() {
mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT);
mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale);
@ -864,6 +867,7 @@ esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_cha
uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num);
uint32_t group_pre_scale = clk_src_hz / group_resolution;
esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true);
MCPWM_CLOCK_SRC_ATOMIC() {
mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT);
mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale);

View File

@ -12,6 +12,7 @@
#include "esp_log.h"
#include "esp_check.h"
#include "driver/gpio.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/gpio.h"
#include "driver/rmt_types_legacy.h"
@ -19,6 +20,7 @@
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/ringbuf.h"
#include "soc/soc_caps.h"
#include "soc/soc_memory_layout.h"
#include "soc/rmt_periph.h"
#include "soc/rmt_struct.h"
@ -438,6 +440,7 @@ esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk)
{
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
RMT_ENTER_CRITICAL();
esp_clk_tree_enable_src((soc_module_clk_t)base_clk, true);
// `rmt_clock_source_t` and `rmt_source_clk_t` are binary compatible, as the underlying enum entries come from the same `soc_module_clk_t`
RMT_CLOCK_SRC_ATOMIC() {
rmt_ll_set_group_clock_src(rmt_contex.hal.regs, channel, (rmt_clock_source_t)base_clk, 1, 0, 0);
@ -603,6 +606,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
#endif
}
esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &rmt_source_clk_hz);
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
RMT_CLOCK_SRC_ATOMIC() {
rmt_ll_set_group_clock_src(dev, channel, clk_src, 1, 0, 0);
rmt_ll_enable_group_clock(dev, true);

View File

@ -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
*/
@ -15,8 +15,10 @@
#include "hal/timer_ll.h"
#include "hal/check.h"
#include "soc/timer_periph.h"
#include "soc/soc_caps.h"
#include "esp_clk_tree.h"
#include "soc/timer_group_reg.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/periph_ctrl.h"
static const char *TIMER_TAG = "timer_group";
@ -326,6 +328,7 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer
if (config->clk_src) {
clk_src = config->clk_src;
}
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
GPTIMER_CLOCK_SRC_ATOMIC() {
// although `clk_src` is of `timer_src_clk_t` type, but it's binary compatible with `gptimer_clock_source_t`,
// as the underlying enum entries come from the same `soc_module_clk_t`

View File

@ -684,7 +684,10 @@ static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
gpio_set_level(sda_io, 1); // STOP, SDA low -> high while SCL is HIGH
i2c_set_pin(i2c_num, sda_io, scl_io, 1, 1, I2C_MODE_MASTER);
#else
i2c_ll_master_clr_bus(i2c_context[i2c_num].hal.dev, I2C_CLR_BUS_SCL_NUM);
i2c_ll_master_clr_bus(i2c_context[i2c_num].hal.dev, I2C_CLR_BUS_SCL_NUM, true);
while (i2c_ll_master_is_bus_clear_done(i2c_context[i2c_num].hal.dev)) {
}
i2c_ll_update(i2c_context[i2c_num].hal.dev);
#endif
return ESP_OK;
}

View File

@ -9,7 +9,7 @@
#include <assert.h>
#include "esp_efuse_table.h"
// md5_digest_table 604cf47a9075de209e7b488c4c6a3cd6
// md5_digest_table 52aee23d9256003919a3d01945678355
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
@ -35,6 +35,10 @@ static const esp_efuse_desc_t WR_DIS_DIS_FORCE_DOWNLOAD[] = {
{EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_FORCE_DOWNLOAD,
};
static const esp_efuse_desc_t WR_DIS_SPI_DOWNLOAD_MSPI_DIS[] = {
{EFUSE_BLK0, 2, 1}, // [] wr_dis of SPI_DOWNLOAD_MSPI_DIS,
};
static const esp_efuse_desc_t WR_DIS_JTAG_SEL_ENABLE[] = {
{EFUSE_BLK0, 2, 1}, // [] wr_dis of JTAG_SEL_ENABLE,
};
@ -47,6 +51,14 @@ static const esp_efuse_desc_t WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
{EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT,
};
static const esp_efuse_desc_t WR_DIS_HYS_EN_PAD[] = {
{EFUSE_BLK0, 2, 1}, // [] wr_dis of HYS_EN_PAD,
};
static const esp_efuse_desc_t WR_DIS_DIS_WIFI6[] = {
{EFUSE_BLK0, 2, 1}, // [] wr_dis of DIS_WIFI6,
};
static const esp_efuse_desc_t WR_DIS_WDT_DELAY_SEL[] = {
{EFUSE_BLK0, 3, 1}, // [] wr_dis of WDT_DELAY_SEL,
};
@ -95,6 +107,22 @@ static const esp_efuse_desc_t WR_DIS_SEC_DPA_LEVEL[] = {
{EFUSE_BLK0, 14, 1}, // [] wr_dis of SEC_DPA_LEVEL,
};
static const esp_efuse_desc_t WR_DIS_XTS_DPA_CLK_ENABLE[] = {
{EFUSE_BLK0, 14, 1}, // [] wr_dis of XTS_DPA_CLK_ENABLE,
};
static const esp_efuse_desc_t WR_DIS_XTS_DPA_PSEUDO_LEVEL[] = {
{EFUSE_BLK0, 14, 1}, // [] wr_dis of XTS_DPA_PSEUDO_LEVEL,
};
static const esp_efuse_desc_t WR_DIS_ECDSA_DISABLE_P192[] = {
{EFUSE_BLK0, 14, 1}, // [] wr_dis of ECDSA_DISABLE_P192,
};
static const esp_efuse_desc_t WR_DIS_ECC_FORCE_CONST_TIME[] = {
{EFUSE_BLK0, 14, 1}, // [] wr_dis of ECC_FORCE_CONST_TIME,
};
static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_EN[] = {
{EFUSE_BLK0, 15, 1}, // [] wr_dis of SECURE_BOOT_EN,
};
@ -103,10 +131,6 @@ static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = {
{EFUSE_BLK0, 16, 1}, // [] wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE,
};
static const esp_efuse_desc_t WR_DIS_SPI_DOWNLOAD_MSPI_DIS[] = {
{EFUSE_BLK0, 17, 1}, // [] wr_dis of SPI_DOWNLOAD_MSPI_DIS,
};
static const esp_efuse_desc_t WR_DIS_FLASH_TPUW[] = {
{EFUSE_BLK0, 18, 1}, // [] wr_dis of FLASH_TPUW,
};
@ -144,7 +168,7 @@ static const esp_efuse_desc_t WR_DIS_SECURE_VERSION[] = {
};
static const esp_efuse_desc_t WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE[] = {
{EFUSE_BLK0, 19, 1}, // [] wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE,
{EFUSE_BLK0, 18, 1}, // [] wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE,
};
static const esp_efuse_desc_t WR_DIS_BLK1[] = {
@ -155,12 +179,60 @@ static const esp_efuse_desc_t WR_DIS_MAC[] = {
{EFUSE_BLK0, 20, 1}, // [WR_DIS.MAC_FACTORY] wr_dis of MAC,
};
static const esp_efuse_desc_t WR_DIS_WAFER_VERSION_MINOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of WAFER_VERSION_MINOR,
};
static const esp_efuse_desc_t WR_DIS_WAFER_VERSION_MAJOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of WAFER_VERSION_MAJOR,
};
static const esp_efuse_desc_t WR_DIS_DISABLE_WAFER_VERSION_MAJOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of DISABLE_WAFER_VERSION_MAJOR,
};
static const esp_efuse_desc_t WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of DISABLE_BLK_VERSION_MAJOR,
};
static const esp_efuse_desc_t WR_DIS_BLK_VERSION_MINOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of BLK_VERSION_MINOR,
};
static const esp_efuse_desc_t WR_DIS_BLK_VERSION_MAJOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of BLK_VERSION_MAJOR,
};
static const esp_efuse_desc_t WR_DIS_FLASH_CAP[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_CAP,
};
static const esp_efuse_desc_t WR_DIS_FLASH_VENDOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_VENDOR,
};
static const esp_efuse_desc_t WR_DIS_PSRAM_CAP[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of PSRAM_CAP,
};
static const esp_efuse_desc_t WR_DIS_PSRAM_VENDOR[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of PSRAM_VENDOR,
};
static const esp_efuse_desc_t WR_DIS_TEMP[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of TEMP,
};
static const esp_efuse_desc_t WR_DIS_PKG_VERSION[] = {
{EFUSE_BLK0, 20, 1}, // [] wr_dis of PKG_VERSION,
};
static const esp_efuse_desc_t WR_DIS_SYS_DATA_PART1[] = {
{EFUSE_BLK0, 21, 1}, // [] wr_dis of BLOCK2,
};
static const esp_efuse_desc_t WR_DIS_BLOCK_SYS_DATA1[] = {
{EFUSE_BLK0, 21, 1}, // [] wr_dis of BLOCK_SYS_DATA1,
static const esp_efuse_desc_t WR_DIS_OPTIONAL_UNIQUE_ID[] = {
{EFUSE_BLK0, 21, 1}, // [] wr_dis of OPTIONAL_UNIQUE_ID,
};
static const esp_efuse_desc_t WR_DIS_BLOCK_USR_DATA[] = {
@ -404,8 +476,56 @@ static const esp_efuse_desc_t MAC[] = {
{EFUSE_BLK1, 0, 8}, // [MAC_FACTORY] MAC address,
};
static const esp_efuse_desc_t BLOCK_SYS_DATA1[] = {
{EFUSE_BLK2, 0, 256}, // [] System data part 1 (reserved),
static const esp_efuse_desc_t WAFER_VERSION_MINOR[] = {
{EFUSE_BLK1, 64, 4}, // [] Minor chip version,
};
static const esp_efuse_desc_t WAFER_VERSION_MAJOR[] = {
{EFUSE_BLK1, 68, 2}, // [] Major chip version,
};
static const esp_efuse_desc_t DISABLE_WAFER_VERSION_MAJOR[] = {
{EFUSE_BLK1, 70, 1}, // [] Disables check of wafer version major,
};
static const esp_efuse_desc_t DISABLE_BLK_VERSION_MAJOR[] = {
{EFUSE_BLK1, 71, 1}, // [] Disables check of blk version major,
};
static const esp_efuse_desc_t BLK_VERSION_MINOR[] = {
{EFUSE_BLK1, 72, 3}, // [] BLK_VERSION_MINOR of BLOCK2,
};
static const esp_efuse_desc_t BLK_VERSION_MAJOR[] = {
{EFUSE_BLK1, 75, 2}, // [] BLK_VERSION_MAJOR of BLOCK2,
};
static const esp_efuse_desc_t FLASH_CAP[] = {
{EFUSE_BLK1, 77, 3}, // [] Flash capacity,
};
static const esp_efuse_desc_t FLASH_VENDOR[] = {
{EFUSE_BLK1, 80, 3}, // [] Flash vendor,
};
static const esp_efuse_desc_t PSRAM_CAP[] = {
{EFUSE_BLK1, 83, 3}, // [] PSRAM capacity,
};
static const esp_efuse_desc_t PSRAM_VENDOR[] = {
{EFUSE_BLK1, 86, 2}, // [] PSRAM vendor,
};
static const esp_efuse_desc_t TEMP[] = {
{EFUSE_BLK1, 88, 2}, // [] Temperature,
};
static const esp_efuse_desc_t PKG_VERSION[] = {
{EFUSE_BLK1, 90, 3}, // [] Package version,
};
static const esp_efuse_desc_t OPTIONAL_UNIQUE_ID[] = {
{EFUSE_BLK2, 0, 128}, // [] Optional unique 128-bit ID,
};
static const esp_efuse_desc_t USER_DATA[] = {
@ -473,6 +593,11 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_FORCE_DOWNLOAD[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_DOWNLOAD_MSPI_DIS[] = {
&WR_DIS_SPI_DOWNLOAD_MSPI_DIS[0], // [] wr_dis of SPI_DOWNLOAD_MSPI_DIS
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_JTAG_SEL_ENABLE[] = {
&WR_DIS_JTAG_SEL_ENABLE[0], // [] wr_dis of JTAG_SEL_ENABLE
NULL
@ -488,6 +613,16 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_HYS_EN_PAD[] = {
&WR_DIS_HYS_EN_PAD[0], // [] wr_dis of HYS_EN_PAD
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_WIFI6[] = {
&WR_DIS_DIS_WIFI6[0], // [] wr_dis of DIS_WIFI6
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WDT_DELAY_SEL[] = {
&WR_DIS_WDT_DELAY_SEL[0], // [] wr_dis of WDT_DELAY_SEL
NULL
@ -548,6 +683,26 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SEC_DPA_LEVEL[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_XTS_DPA_CLK_ENABLE[] = {
&WR_DIS_XTS_DPA_CLK_ENABLE[0], // [] wr_dis of XTS_DPA_CLK_ENABLE
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_XTS_DPA_PSEUDO_LEVEL[] = {
&WR_DIS_XTS_DPA_PSEUDO_LEVEL[0], // [] wr_dis of XTS_DPA_PSEUDO_LEVEL
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ECDSA_DISABLE_P192[] = {
&WR_DIS_ECDSA_DISABLE_P192[0], // [] wr_dis of ECDSA_DISABLE_P192
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ECC_FORCE_CONST_TIME[] = {
&WR_DIS_ECC_FORCE_CONST_TIME[0], // [] wr_dis of ECC_FORCE_CONST_TIME
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_EN[] = {
&WR_DIS_SECURE_BOOT_EN[0], // [] wr_dis of SECURE_BOOT_EN
NULL
@ -558,11 +713,6 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_DOWNLOAD_MSPI_DIS[] = {
&WR_DIS_SPI_DOWNLOAD_MSPI_DIS[0], // [] wr_dis of SPI_DOWNLOAD_MSPI_DIS
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TPUW[] = {
&WR_DIS_FLASH_TPUW[0], // [] wr_dis of FLASH_TPUW
NULL
@ -623,13 +773,73 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[] = {
&WR_DIS_WAFER_VERSION_MINOR[0], // [] wr_dis of WAFER_VERSION_MINOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MAJOR[] = {
&WR_DIS_WAFER_VERSION_MAJOR[0], // [] wr_dis of WAFER_VERSION_MAJOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_WAFER_VERSION_MAJOR[] = {
&WR_DIS_DISABLE_WAFER_VERSION_MAJOR[0], // [] wr_dis of DISABLE_WAFER_VERSION_MAJOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = {
&WR_DIS_DISABLE_BLK_VERSION_MAJOR[0], // [] wr_dis of DISABLE_BLK_VERSION_MAJOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[] = {
&WR_DIS_BLK_VERSION_MINOR[0], // [] wr_dis of BLK_VERSION_MINOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MAJOR[] = {
&WR_DIS_BLK_VERSION_MAJOR[0], // [] wr_dis of BLK_VERSION_MAJOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CAP[] = {
&WR_DIS_FLASH_CAP[0], // [] wr_dis of FLASH_CAP
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_VENDOR[] = {
&WR_DIS_FLASH_VENDOR[0], // [] wr_dis of FLASH_VENDOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_CAP[] = {
&WR_DIS_PSRAM_CAP[0], // [] wr_dis of PSRAM_CAP
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_VENDOR[] = {
&WR_DIS_PSRAM_VENDOR[0], // [] wr_dis of PSRAM_VENDOR
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP[] = {
&WR_DIS_TEMP[0], // [] wr_dis of TEMP
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PKG_VERSION[] = {
&WR_DIS_PKG_VERSION[0], // [] wr_dis of PKG_VERSION
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[] = {
&WR_DIS_SYS_DATA_PART1[0], // [] wr_dis of BLOCK2
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_SYS_DATA1[] = {
&WR_DIS_BLOCK_SYS_DATA1[0], // [] wr_dis of BLOCK_SYS_DATA1
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[] = {
&WR_DIS_OPTIONAL_UNIQUE_ID[0], // [] wr_dis of OPTIONAL_UNIQUE_ID
NULL
};
@ -933,8 +1143,68 @@ const esp_efuse_desc_t* ESP_EFUSE_MAC[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_BLOCK_SYS_DATA1[] = {
&BLOCK_SYS_DATA1[0], // [] System data part 1 (reserved)
const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[] = {
&WAFER_VERSION_MINOR[0], // [] Minor chip version
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[] = {
&WAFER_VERSION_MAJOR[0], // [] Major chip version
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_DISABLE_WAFER_VERSION_MAJOR[] = {
&DISABLE_WAFER_VERSION_MAJOR[0], // [] Disables check of wafer version major
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[] = {
&DISABLE_BLK_VERSION_MAJOR[0], // [] Disables check of blk version major
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[] = {
&BLK_VERSION_MINOR[0], // [] BLK_VERSION_MINOR of BLOCK2
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[] = {
&BLK_VERSION_MAJOR[0], // [] BLK_VERSION_MAJOR of BLOCK2
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[] = {
&FLASH_CAP[0], // [] Flash capacity
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[] = {
&FLASH_VENDOR[0], // [] Flash vendor
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_PSRAM_CAP[] = {
&PSRAM_CAP[0], // [] PSRAM capacity
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_PSRAM_VENDOR[] = {
&PSRAM_VENDOR[0], // [] PSRAM vendor
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_TEMP[] = {
&TEMP[0], // [] Temperature
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[] = {
&PKG_VERSION[0], // [] Package version
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[] = {
&OPTIONAL_UNIQUE_ID[0], // [] Optional unique 128-bit ID
NULL
};

View File

@ -9,16 +9,19 @@
# this will generate new source files, next rebuild all the sources.
# !!!!!!!!!!! #
# This file was generated by regtools.py based on the efuses.yaml file with the version: beb6fa3bf4a43a464c3365fda28815f5
# This file was generated by regtools.py based on the efuses.yaml file with the version: e564f8042b56a475a7714bb28ecdadfa
WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses
WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS
WR_DIS.DIS_ICACHE, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_ICACHE
WR_DIS.DIS_USB_JTAG, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_USB_JTAG
WR_DIS.DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_FORCE_DOWNLOAD
WR_DIS.SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 2, 1, [] wr_dis of SPI_DOWNLOAD_MSPI_DIS
WR_DIS.JTAG_SEL_ENABLE, EFUSE_BLK0, 2, 1, [] wr_dis of JTAG_SEL_ENABLE
WR_DIS.DIS_PAD_JTAG, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_PAD_JTAG
WR_DIS.DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_DOWNLOAD_MANUAL_ENCRYPT
WR_DIS.HYS_EN_PAD, EFUSE_BLK0, 2, 1, [] wr_dis of HYS_EN_PAD
WR_DIS.DIS_WIFI6, EFUSE_BLK0, 2, 1, [] wr_dis of DIS_WIFI6
WR_DIS.WDT_DELAY_SEL, EFUSE_BLK0, 3, 1, [] wr_dis of WDT_DELAY_SEL
WR_DIS.SPI_BOOT_CRYPT_CNT, EFUSE_BLK0, 4, 1, [] wr_dis of SPI_BOOT_CRYPT_CNT
WR_DIS.SECURE_BOOT_KEY_REVOKE0, EFUSE_BLK0, 5, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE0
@ -31,9 +34,12 @@ WR_DIS.KEY_PURPOSE_3, EFUSE_BLK0, 11, 1, [WR_DIS.K
WR_DIS.KEY_PURPOSE_4, EFUSE_BLK0, 12, 1, [WR_DIS.KEY4_PURPOSE] wr_dis of KEY_PURPOSE_4
WR_DIS.KEY_PURPOSE_5, EFUSE_BLK0, 13, 1, [WR_DIS.KEY5_PURPOSE] wr_dis of KEY_PURPOSE_5
WR_DIS.SEC_DPA_LEVEL, EFUSE_BLK0, 14, 1, [] wr_dis of SEC_DPA_LEVEL
WR_DIS.XTS_DPA_CLK_ENABLE, EFUSE_BLK0, 14, 1, [] wr_dis of XTS_DPA_CLK_ENABLE
WR_DIS.XTS_DPA_PSEUDO_LEVEL, EFUSE_BLK0, 14, 1, [] wr_dis of XTS_DPA_PSEUDO_LEVEL
WR_DIS.ECDSA_DISABLE_P192, EFUSE_BLK0, 14, 1, [] wr_dis of ECDSA_DISABLE_P192
WR_DIS.ECC_FORCE_CONST_TIME, EFUSE_BLK0, 14, 1, [] wr_dis of ECC_FORCE_CONST_TIME
WR_DIS.SECURE_BOOT_EN, EFUSE_BLK0, 15, 1, [] wr_dis of SECURE_BOOT_EN
WR_DIS.SECURE_BOOT_AGGRESSIVE_REVOKE, EFUSE_BLK0, 16, 1, [] wr_dis of SECURE_BOOT_AGGRESSIVE_REVOKE
WR_DIS.SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 17, 1, [] wr_dis of SPI_DOWNLOAD_MSPI_DIS
WR_DIS.FLASH_TPUW, EFUSE_BLK0, 18, 1, [] wr_dis of FLASH_TPUW
WR_DIS.DIS_DOWNLOAD_MODE, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_DOWNLOAD_MODE
WR_DIS.DIS_DIRECT_BOOT, EFUSE_BLK0, 18, 1, [] wr_dis of DIS_DIRECT_BOOT
@ -43,11 +49,23 @@ WR_DIS.ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 18, 1, [] wr_dis
WR_DIS.UART_PRINT_CONTROL, EFUSE_BLK0, 18, 1, [] wr_dis of UART_PRINT_CONTROL
WR_DIS.FORCE_SEND_RESUME, EFUSE_BLK0, 18, 1, [] wr_dis of FORCE_SEND_RESUME
WR_DIS.SECURE_VERSION, EFUSE_BLK0, 18, 1, [] wr_dis of SECURE_VERSION
WR_DIS.SECURE_BOOT_DISABLE_FAST_WAKE, EFUSE_BLK0, 19, 1, [] wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE
WR_DIS.SECURE_BOOT_DISABLE_FAST_WAKE, EFUSE_BLK0, 18, 1, [] wr_dis of SECURE_BOOT_DISABLE_FAST_WAKE
WR_DIS.BLK1, EFUSE_BLK0, 20, 1, [] wr_dis of BLOCK1
WR_DIS.MAC, EFUSE_BLK0, 20, 1, [WR_DIS.MAC_FACTORY] wr_dis of MAC
WR_DIS.WAFER_VERSION_MINOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MINOR
WR_DIS.WAFER_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MAJOR
WR_DIS.DISABLE_WAFER_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of DISABLE_WAFER_VERSION_MAJOR
WR_DIS.DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of DISABLE_BLK_VERSION_MAJOR
WR_DIS.BLK_VERSION_MINOR, EFUSE_BLK0, 20, 1, [] wr_dis of BLK_VERSION_MINOR
WR_DIS.BLK_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of BLK_VERSION_MAJOR
WR_DIS.FLASH_CAP, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_CAP
WR_DIS.FLASH_VENDOR, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_VENDOR
WR_DIS.PSRAM_CAP, EFUSE_BLK0, 20, 1, [] wr_dis of PSRAM_CAP
WR_DIS.PSRAM_VENDOR, EFUSE_BLK0, 20, 1, [] wr_dis of PSRAM_VENDOR
WR_DIS.TEMP, EFUSE_BLK0, 20, 1, [] wr_dis of TEMP
WR_DIS.PKG_VERSION, EFUSE_BLK0, 20, 1, [] wr_dis of PKG_VERSION
WR_DIS.SYS_DATA_PART1, EFUSE_BLK0, 21, 1, [] wr_dis of BLOCK2
WR_DIS.BLOCK_SYS_DATA1, EFUSE_BLK0, 21, 1, [] wr_dis of BLOCK_SYS_DATA1
WR_DIS.OPTIONAL_UNIQUE_ID, EFUSE_BLK0, 21, 1, [] wr_dis of OPTIONAL_UNIQUE_ID
WR_DIS.BLOCK_USR_DATA, EFUSE_BLK0, 22, 1, [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA
WR_DIS.CUSTOM_MAC, EFUSE_BLK0, 22, 1, [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC
WR_DIS.BLOCK_KEY0, EFUSE_BLK0, 23, 1, [WR_DIS.KEY0] wr_dis of BLOCK_KEY0
@ -97,7 +115,7 @@ DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 98, 1, [] Repres
DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE, EFUSE_BLK0, 99, 1, [] Represents whether the USB-Serial-JTAG download function is disabled or enabled.\\ 1: Disable\\ 0: Enable\\
ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 100, 1, [] Represents whether security download is enabled or disabled.\\ 1: Enable\\ 0: Disable\\
UART_PRINT_CONTROL, EFUSE_BLK0, 101, 2, [] Represents the types of UART printing
FORCE_SEND_RESUME, EFUSE_BLK0, 103, 1, [] Represents whether ROM code is forced to send a resume commmand during SPI boot
FORCE_SEND_RESUME, EFUSE_BLK0, 103, 1, [] Represents whether ROM code is forced to send a resume command during SPI boot
SECURE_VERSION, EFUSE_BLK0, 104, 16, [] Represents the version used by ESP-IDF anti-rollback feature
SECURE_BOOT_DISABLE_FAST_WAKE, EFUSE_BLK0, 120, 1, [] Represents whether FAST_VERIFY_ON_WAKE is disable or enable when Secure Boot is enable
HYS_EN_PAD, EFUSE_BLK0, 121, 1, [] Represents whether the hysteresis function of corresponding PAD is enabled.\\ 1: enabled\\ 0:disabled\\
@ -112,7 +130,19 @@ MAC, EFUSE_BLK1, 40, 8, [MAC_FACT
, EFUSE_BLK1, 16, 8, [MAC_FACTORY] MAC address
, EFUSE_BLK1, 8, 8, [MAC_FACTORY] MAC address
, EFUSE_BLK1, 0, 8, [MAC_FACTORY] MAC address
BLOCK_SYS_DATA1, EFUSE_BLK2, 0, 256, [] System data part 1 (reserved)
WAFER_VERSION_MINOR, EFUSE_BLK1, 64, 4, [] Minor chip version
WAFER_VERSION_MAJOR, EFUSE_BLK1, 68, 2, [] Major chip version
DISABLE_WAFER_VERSION_MAJOR, EFUSE_BLK1, 70, 1, [] Disables check of wafer version major
DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK1, 71, 1, [] Disables check of blk version major
BLK_VERSION_MINOR, EFUSE_BLK1, 72, 3, [] BLK_VERSION_MINOR of BLOCK2
BLK_VERSION_MAJOR, EFUSE_BLK1, 75, 2, [] BLK_VERSION_MAJOR of BLOCK2
FLASH_CAP, EFUSE_BLK1, 77, 3, [] Flash capacity
FLASH_VENDOR, EFUSE_BLK1, 80, 3, [] Flash vendor
PSRAM_CAP, EFUSE_BLK1, 83, 3, [] PSRAM capacity
PSRAM_VENDOR, EFUSE_BLK1, 86, 2, [] PSRAM vendor
TEMP, EFUSE_BLK1, 88, 2, [] Temperature
PKG_VERSION, EFUSE_BLK1, 90, 3, [] Package version
OPTIONAL_UNIQUE_ID, EFUSE_BLK2, 0, 128, [] Optional unique 128-bit ID
USER_DATA, EFUSE_BLK3, 0, 256, [BLOCK_USR_DATA] User data
USER_DATA.MAC_CUSTOM, EFUSE_BLK3, 200, 48, [MAC_CUSTOM CUSTOM_MAC] Custom MAC
KEY0, EFUSE_BLK4, 0, 256, [BLOCK_KEY0] Key0 or user data

Can't render this file because it contains an unexpected character in line 8 and column 53.

View File

@ -10,7 +10,7 @@ extern "C" {
#include "esp_efuse.h"
// md5_digest_table 604cf47a9075de209e7b488c4c6a3cd6
// md5_digest_table 52aee23d9256003919a3d01945678355
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
@ -22,9 +22,12 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RD_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_ICACHE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_USB_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_FORCE_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_DOWNLOAD_MSPI_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_JTAG_SEL_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_PAD_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MANUAL_ENCRYPT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_HYS_EN_PAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_WIFI6[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WDT_DELAY_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0[];
@ -43,9 +46,12 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_4[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_KEY_PURPOSE_5[];
#define ESP_EFUSE_WR_DIS_KEY5_PURPOSE ESP_EFUSE_WR_DIS_KEY_PURPOSE_5
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SEC_DPA_LEVEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_XTS_DPA_CLK_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_XTS_DPA_PSEUDO_LEVEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ECDSA_DISABLE_P192[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ECC_FORCE_CONST_TIME[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_EN[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_AGGRESSIVE_REVOKE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_DOWNLOAD_MSPI_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TPUW[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DOWNLOAD_MODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DIS_DIRECT_BOOT[];
@ -59,8 +65,20 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SECURE_BOOT_DISABLE_FAST_WAKE[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC[];
#define ESP_EFUSE_WR_DIS_MAC_FACTORY ESP_EFUSE_WR_DIS_MAC
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_WAFER_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CAP[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_VENDOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_CAP[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_VENDOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PKG_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_SYS_DATA1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[];
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[];
#define ESP_EFUSE_WR_DIS_USER_DATA ESP_EFUSE_WR_DIS_BLOCK_USR_DATA
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CUSTOM_MAC[];
@ -144,7 +162,19 @@ extern const esp_efuse_desc_t* ESP_EFUSE_ECDSA_DISABLE_P192[];
extern const esp_efuse_desc_t* ESP_EFUSE_ECC_FORCE_CONST_TIME[];
extern const esp_efuse_desc_t* ESP_EFUSE_MAC[];
#define ESP_EFUSE_MAC_FACTORY ESP_EFUSE_MAC
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK_SYS_DATA1[];
extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_WAFER_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[];
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_PSRAM_CAP[];
extern const esp_efuse_desc_t* ESP_EFUSE_PSRAM_VENDOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEMP[];
extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[];
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[];
#define ESP_EFUSE_BLOCK_USR_DATA ESP_EFUSE_USER_DATA
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[];

View File

@ -23,6 +23,7 @@
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "freertos/ringbuf.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/adc_private.h"
#include "esp_private/adc_share_hw_ctrl.h"
@ -33,6 +34,7 @@
#include "hal/adc_types.h"
#include "hal/adc_hal.h"
#include "hal/dma_types.h"
#include "soc/soc_caps.h"
#include "esp_memory_utils.h"
#include "adc_continuous_internal.h"
#include "esp_private/adc_dma.h"
@ -300,7 +302,9 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle)
}
adc_hal_digi_init(&handle->hal);
#if !CONFIG_IDF_TARGET_ESP32
esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal_digi_ctrlr_cfg.clk_src), true);
#endif
adc_hal_digi_controller_config(&handle->hal, &handle->hal_digi_ctrlr_cfg);
adc_hal_digi_enable(false);

View File

@ -24,11 +24,13 @@
#include "esp_private/adc_private.h"
#include "esp_private/adc_share_hw_ctrl.h"
#include "esp_private/sar_periph_ctrl.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/esp_sleep_internal.h"
#include "hal/adc_types.h"
#include "hal/adc_oneshot_hal.h"
#include "hal/adc_ll.h"
#include "soc/adc_periph.h"
#include "soc/soc_caps.h"
#if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM
#define ADC_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
@ -100,16 +102,24 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
unit->unit_id = init_config->unit_id;
unit->ulp_mode = init_config->ulp_mode;
adc_oneshot_clk_src_t clk_src = ADC_DIGI_CLK_SRC_DEFAULT;
if (init_config->clk_src) {
clk_src = init_config->clk_src;
adc_oneshot_clk_src_t clk_src;
#if SOC_LP_ADC_SUPPORTED
if (init_config->ulp_mode != ADC_ULP_MODE_DISABLE) {
clk_src = LP_ADC_CLK_SRC_LP_DYN_FAST;
} else
#endif /* CONFIG_SOC_LP_ADC_SUPPORTED */
{
clk_src = ADC_DIGI_CLK_SRC_DEFAULT;
if (init_config->clk_src) {
clk_src = init_config->clk_src;
}
}
uint32_t clk_src_freq_hz = 0;
ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz), err, TAG, "clock source not supported");
adc_oneshot_hal_cfg_t config = {
.unit = init_config->unit_id,
.work_mode = (init_config->ulp_mode == ADC_ULP_MODE_FSM) ? ADC_HAL_ULP_FSM_MODE : ADC_HAL_SINGLE_READ_MODE,
.work_mode = (init_config->ulp_mode != ADC_ULP_MODE_DISABLE) ? ADC_HAL_LP_MODE : ADC_HAL_SINGLE_READ_MODE,
.clk_src = clk_src,
.clk_src_freq_hz = clk_src_freq_hz,
};
@ -127,7 +137,7 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
sar_periph_ctrl_adc_oneshot_power_acquire();
} else {
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
esp_sleep_enable_adc_tsens_monitor(true);
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true);
#endif
}
@ -159,6 +169,9 @@ esp_err_t adc_oneshot_config_channel(adc_oneshot_unit_handle_t handle, adc_chann
portENTER_CRITICAL(&rtc_spinlock);
adc_oneshot_hal_channel_config(hal, &cfg, channel);
if (handle->ulp_mode) {
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
esp_clk_tree_enable_src((soc_module_clk_t)(hal->clk_src), true);
#endif
adc_oneshot_hal_setup(hal, channel);
}
portEXIT_CRITICAL(&rtc_spinlock);
@ -176,6 +189,9 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan,
}
portENTER_CRITICAL(&rtc_spinlock);
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true);
#endif
adc_oneshot_hal_setup(&(handle->hal), chan);
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan);
@ -199,6 +215,9 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c
portENTER_CRITICAL_SAFE(&rtc_spinlock);
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true);
#endif
adc_oneshot_hal_setup(&(handle->hal), chan);
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan);
@ -230,7 +249,7 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle)
sar_periph_ctrl_adc_oneshot_power_release();
} else {
#if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED
esp_sleep_enable_adc_tsens_monitor(false);
esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, false);
#endif
}

View File

@ -4,6 +4,12 @@ entries:
if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y:
adc_oneshot: adc_oneshot_read_isr (noflash)
[mapping:esp_hw_support_adc]
archive: libesp_hw_support.a
entries:
if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y:
esp_clk_tree: esp_clk_tree_enable_src (noflash)
[mapping:adc_hal]
archive: libhal.a
entries:

View File

@ -19,7 +19,9 @@ if(CONFIG_ESP_COEX_ENABLED)
endif()
if(CONFIG_ESP_WIFI_ENABLED)
list(APPEND srcs "${idf_target}/esp_coex_adapter.c")
list(APPEND srcs "${idf_target}/esp_coex_adapter.c"
"src/coexist_debug_diagram.c"
"src/coexist_debug.c")
endif()
endif()

View File

@ -40,4 +40,201 @@ menu "Wireless Coexistence"
If enabled, coexist power management will be enabled.
endif
config ESP_COEX_GPIO_DEBUG
bool "GPIO debugging for coexistence"
default n
depends on !PM_SLP_DISABLE_GPIO && !PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
help
Support coexistence GPIO debugging
if (ESP_COEX_GPIO_DEBUG)
choice ESP_COEX_GPIO_DEBUG_DIAG
prompt "Debugging Diagram"
default ESP_COEX_GPIO_DEBUG_DIAG_GENERAL
help
Select type of debugging diagram
config ESP_COEX_GPIO_DEBUG_DIAG_GENERAL
bool "General"
config ESP_COEX_GPIO_DEBUG_DIAG_WIFI
bool "Wi-Fi"
endchoice
config ESP_COEX_GPIO_DEBUG_IO_COUNT
int "Max number of debugging GPIOs"
range 0 12
default 12
config ESP_COEX_GPIO_DEBUG_IO_IDX0
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 0)
int "Actual IO num for Debug IO ID0"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 15 if IDF_TARGET_ESP32
default 4 if IDF_TARGET_ESP32S2
default 19 if IDF_TARGET_ESP32C3
default 4 if IDF_TARGET_ESP32S3
default 18 if IDF_TARGET_ESP32C2
default 4 if IDF_TARGET_ESP32C6
default 2 if IDF_TARGET_ESP32C5
default 4 if IDF_TARGET_ESP32C61
default 1
config ESP_COEX_GPIO_DEBUG_IO_IDX1
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 1)
int "Actual IO num for Debug IO ID1"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 2 if IDF_TARGET_ESP32
default 5 if IDF_TARGET_ESP32S2
default 18 if IDF_TARGET_ESP32C3
default 5 if IDF_TARGET_ESP32S3
default 4 if IDF_TARGET_ESP32C2
default 5 if IDF_TARGET_ESP32C6
default 3 if IDF_TARGET_ESP32C5
default 5 if IDF_TARGET_ESP32C61
default 2
config ESP_COEX_GPIO_DEBUG_IO_IDX2
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 2)
int "Actual IO num for Debug IO ID2"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 0 if IDF_TARGET_ESP32
default 6 if IDF_TARGET_ESP32S2
default 4 if IDF_TARGET_ESP32C3
default 6 if IDF_TARGET_ESP32S3
default 5 if IDF_TARGET_ESP32C2
default 6 if IDF_TARGET_ESP32C6
default 4 if IDF_TARGET_ESP32C5
default 6 if IDF_TARGET_ESP32C61
default 3
config ESP_COEX_GPIO_DEBUG_IO_IDX3
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 3)
int "Actual IO num for Debug IO ID3"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 4 if IDF_TARGET_ESP32
default 7 if IDF_TARGET_ESP32S2
default 5 if IDF_TARGET_ESP32C3
default 7 if IDF_TARGET_ESP32S3
default 6 if IDF_TARGET_ESP32C2
default 7 if IDF_TARGET_ESP32C6
default 5 if IDF_TARGET_ESP32C5
default 7 if IDF_TARGET_ESP32C61
default 4
config ESP_COEX_GPIO_DEBUG_IO_IDX4
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 4)
int "Actual IO num for Debug IO ID4"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 5 if IDF_TARGET_ESP32
default 8 if IDF_TARGET_ESP32S2
default 6 if IDF_TARGET_ESP32C3
default 15 if IDF_TARGET_ESP32S3
default 7 if IDF_TARGET_ESP32C2
default 8 if IDF_TARGET_ESP32C6
default 27 if IDF_TARGET_ESP32C5
default 0 if IDF_TARGET_ESP32C61
default 5
config ESP_COEX_GPIO_DEBUG_IO_IDX5
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 5)
int "Actual IO num for Debug IO ID5"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 18 if IDF_TARGET_ESP32
default 9 if IDF_TARGET_ESP32S2
default 7 if IDF_TARGET_ESP32C3
default 16 if IDF_TARGET_ESP32S3
default 8 if IDF_TARGET_ESP32C2
default 10 if IDF_TARGET_ESP32C6
default 6 if IDF_TARGET_ESP32C5
default 1 if IDF_TARGET_ESP32C61
default 6
config ESP_COEX_GPIO_DEBUG_IO_IDX6
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 6)
int "Actual IO num for Debug IO ID6"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 19 if IDF_TARGET_ESP32
default 10 if IDF_TARGET_ESP32S2
default 8 if IDF_TARGET_ESP32C3
default 17 if IDF_TARGET_ESP32S3
default 9 if IDF_TARGET_ESP32C2
default 11 if IDF_TARGET_ESP32C6
default 7 if IDF_TARGET_ESP32C5
default 8 if IDF_TARGET_ESP32C61
default 7
config ESP_COEX_GPIO_DEBUG_IO_IDX7
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 7)
int "Actual IO num for Debug IO ID7"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 22 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2
default 9 if IDF_TARGET_ESP32C3
default 18 if IDF_TARGET_ESP32S3
default 10 if IDF_TARGET_ESP32C2
default 2 if IDF_TARGET_ESP32C6
default 26 if IDF_TARGET_ESP32C5
default 2 if IDF_TARGET_ESP32C61
default 8
config ESP_COEX_GPIO_DEBUG_IO_IDX8
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 8)
int "Actual IO num for Debug IO ID8"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 13 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2
default 10 if IDF_TARGET_ESP32C3
default 10 if IDF_TARGET_ESP32S3
default 1 if IDF_TARGET_ESP32C2
default 15 if IDF_TARGET_ESP32C6
default 24 if IDF_TARGET_ESP32C5
default 3 if IDF_TARGET_ESP32C61
default 9
config ESP_COEX_GPIO_DEBUG_IO_IDX9
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 9)
int "Actual IO num for Debug IO ID9"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 12 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32S2
default 0 if IDF_TARGET_ESP32C3
default 11 if IDF_TARGET_ESP32S3
default 0 if IDF_TARGET_ESP32C2
default 23 if IDF_TARGET_ESP32C6
default 23 if IDF_TARGET_ESP32C5
default 9 if IDF_TARGET_ESP32C61
default 10
config ESP_COEX_GPIO_DEBUG_IO_IDX10
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 10)
int "Actual IO num for Debug IO ID10"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 14 if IDF_TARGET_ESP32
default 14 if IDF_TARGET_ESP32S2
default 3 if IDF_TARGET_ESP32C3
default 12 if IDF_TARGET_ESP32S3
default 3 if IDF_TARGET_ESP32C2
default 22 if IDF_TARGET_ESP32C6
default 16 if IDF_TARGET_ESP32C5
default 13 if IDF_TARGET_ESP32C61
default 11
config ESP_COEX_GPIO_DEBUG_IO_IDX11
depends on (ESP_COEX_GPIO_DEBUG_IO_COUNT > 11)
int "Actual IO num for Debug IO ID11"
range 0 SOC_GPIO_OUT_RANGE_MAX
default 27 if IDF_TARGET_ESP32
default 15 if IDF_TARGET_ESP32S2
default 2 if IDF_TARGET_ESP32C3
default 13 if IDF_TARGET_ESP32S3
default 2 if IDF_TARGET_ESP32C2
default 21 if IDF_TARGET_ESP32C6
default 0 if IDF_TARGET_ESP32C5
default 12 if IDF_TARGET_ESP32C61
default 12
endif
endmenu # Wireless Coexistence

View File

@ -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
*/
@ -20,6 +20,7 @@
#include "esp_timer.h"
#include "private/esp_coexist_adapter.h"
#include "esp32/rom/ets_sys.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -206,6 +207,15 @@ static int32_t esp_coex_internal_semphr_give_wrapper(void *semphr)
return (int32_t)xSemaphoreGive(((modem_static_queue_t *)semphr)->handle);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._spin_lock_create = esp_coex_common_spin_lock_create_wrapper,
@ -227,5 +237,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -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
*/
@ -22,6 +22,7 @@
#include "esp_private/esp_clk.h"
#include "private/esp_coexist_adapter.h"
#include "esp32c2/rom/ets_sys.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -142,6 +143,15 @@ static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, voi
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -161,5 +171,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -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
*/
@ -23,6 +23,7 @@
#include "private/esp_coexist_adapter.h"
#include "esp32c3/rom/ets_sys.h"
#include "soc/system_reg.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -148,6 +149,15 @@ static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, voi
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -165,5 +175,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -21,6 +21,7 @@
#include "esp_private/esp_clk.h"
#include "private/esp_coexist_adapter.h"
#include "esp32c5/rom/ets_sys.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -141,6 +142,15 @@ static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, voi
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -159,5 +169,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,6 +22,7 @@
#include "esp_private/esp_clk.h"
#include "private/esp_coexist_adapter.h"
#include "esp32c6/rom/ets_sys.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -142,6 +143,15 @@ static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, voi
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -160,5 +170,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -22,6 +22,7 @@
#include "esp_private/esp_clk.h"
#include "private/esp_coexist_adapter.h"
#include "esp32c61/rom/ets_sys.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -142,6 +143,15 @@ static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, voi
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -160,5 +170,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,6 +22,7 @@
#include "esp_private/esp_clk.h"
#include "private/esp_coexist_adapter.h"
#include "esp32h2/rom/ets_sys.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -134,6 +135,15 @@ static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, voi
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -152,5 +162,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -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
*/
@ -22,6 +22,7 @@
#include "esp_private/esp_clk.h"
#include "private/esp_coexist_adapter.h"
#include "esp32s2/rom/ets_sys.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -216,6 +217,15 @@ static int32_t esp_coex_internal_semphr_give_wrapper(void *semphr)
return (int32_t)xSemaphoreGive(((modem_static_queue_t *)semphr)->handle);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -233,5 +243,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -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
*/
@ -23,6 +23,7 @@
#include "private/esp_coexist_adapter.h"
#include "esp32s3/rom/ets_sys.h"
#include "soc/system_reg.h"
#include "private/esp_coexist_debug.h"
#define TAG "esp_coex_adapter"
@ -222,6 +223,15 @@ static int32_t esp_coex_internal_semphr_give_wrapper(void *semphr)
return (int32_t)xSemaphoreGive(((modem_static_queue_t *)semphr)->handle);
}
static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
{
#if CONFIG_ESP_COEX_GPIO_DEBUG
return esp_coexist_debug_matrix_init(evt, sig, rev);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
@ -239,5 +249,6 @@ coex_adapter_funcs_t g_coex_adapter_funcs = {
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -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
*/
@ -116,7 +116,7 @@ const char *esp_coex_version_get(void);
* @deprecated Use esp_coex_status_bit_set() and esp_coex_status_bit_clear() instead.
* Set coexist preference of performance
* For example, if prefer to bluetooth, then it will make A2DP(play audio via classic bt)
* more smooth while wifi is runnning something.
* more smooth while wifi is running something.
* If prefer to wifi, it will do similar things as prefer to bluetooth.
* Default, it prefer to balance.
*
@ -219,6 +219,15 @@ esp_err_t esp_external_coex_set_validate_high(bool is_high_valid);
esp_err_t esp_coex_wifi_i154_enable(void);
#endif
#if CONFIG_ESP_COEX_GPIO_DEBUG
/**
* @brief Enable coexist GPIO debug.
* To fully enable this feature, make sure functions in rom_funcs are out of ROM.
* @return : ESP_OK - success, other - failed
*/
esp_err_t esp_coexist_debug_init(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -46,6 +46,7 @@ typedef struct {
void (* _timer_done)(void *ptimer);
void (* _timer_setfn)(void *ptimer, void *pfunction, void *parg);
void (* _timer_arm_us)(void *ptimer, uint32_t us, bool repeat);
int (* _debug_matrix_init)(int event, int signal, bool rev);
int32_t _magic;
} coex_adapter_funcs_t;

View File

@ -0,0 +1,145 @@
/*
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#if CONFIG_ESP_COEX_GPIO_DEBUG
#include "esp_err.h"
#include "stdbool.h"
#include "soc/soc_caps.h"
#define COEX_GPIO_DEBUG_IO_INVALID SOC_GPIO_PIN_COUNT
/* Debug signal */
#define COEX_GPIO_DEBUG_SIG_RES_US 10
typedef enum {
COEX_GPIO_DEBUG_SIG_POSE,
COEX_GPIO_DEBUG_SIG_NEGA,
} coex_gpio_debug_sig_t;
#define COEX_GPIO_DEBUG_SIG_TO_DURATION(sig) ((sig - COEX_GPIO_DEBUG_SIG_NEGA) * COEX_GPIO_DEBUG_SIG_RES_US)
#define COEX_GPIO_DEBUG_SIG_CHECK_US 100
/* User diagram */
#ifdef CONFIG_ESP_COEX_GPIO_DEBUG_DIAG_GENERAL
#define COEX_GPIO_DEBUG_DIAG_GENERAL 1
#elif defined(CONFIG_ESP_COEX_GPIO_DEBUG_DIAG_WIFI)
#define COEX_GPIO_DEBUG_DIAG_WIFI 1
#endif
/* User configuration validity check */
#define COEX_GPIO_DEBUG_IO_COUNT_MAX 12
#define COEX_GPIO_DEBUG_IO_COUNT CONFIG_ESP_COEX_GPIO_DEBUG_IO_COUNT
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX0)
#define COEX_GPIO_DEBUG_IO_IDX0 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX0 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX0
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX1)
#define COEX_GPIO_DEBUG_IO_IDX1 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX1 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX1
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX2)
#define COEX_GPIO_DEBUG_IO_IDX2 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX2 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX2
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX3)
#define COEX_GPIO_DEBUG_IO_IDX3 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX3 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX3
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX4)
#define COEX_GPIO_DEBUG_IO_IDX4 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX4 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX4
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX5)
#define COEX_GPIO_DEBUG_IO_IDX5 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX5 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX5
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX6)
#define COEX_GPIO_DEBUG_IO_IDX6 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX6 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX6
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX7)
#define COEX_GPIO_DEBUG_IO_IDX7 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX7 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX7
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX8)
#define COEX_GPIO_DEBUG_IO_IDX8 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX8 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX8
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX9)
#define COEX_GPIO_DEBUG_IO_IDX9 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX9 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX9
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX10)
#define COEX_GPIO_DEBUG_IO_IDX10 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX10 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX10
#endif
#if !defined(CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX11)
#define COEX_GPIO_DEBUG_IO_IDX11 COEX_GPIO_DEBUG_IO_INVALID
#else
#define COEX_GPIO_DEBUG_IO_IDX11 CONFIG_ESP_COEX_GPIO_DEBUG_IO_IDX11
#endif
/* wifi callback -> debug */
void wifi_set_gpio_debug_cb(void (* cb)(int, int));
int wifi_gpio_debug_max_event_get(void);
/* functions to check if in ROM */
void lmacProcessTxComplete(void);
void lmacTxFrame(void);
void pm_update_by_connectionless_status(void);
void pm_sleep(void);
void pm_dream(void);
void pm_beacon_monitor_timeout_process(void);
void pm_connectionless_wake_window_timeout_process(void);
void pm_coex_schm_process(void);
void pm_tbtt_process(void);
void pm_rx_beacon_process(void);
void ppTask(void);
void wDev_IndicateFrame(void);
void pm_check_state(void);
void pm_tx_null_data_done_process(void);
void pm_start(void);
void pm_stop(void);
/* coex callback -> debug */
void coex_set_gpio_debug_cb(void (*cb)(int, int));
int coex_gpio_debug_max_event_get(void);
esp_err_t coex_gpio_debug_matrix_init(void);
/* debug -> coex wrapper */
esp_err_t esp_coexist_debug_matrix_init(int evt, int sig, bool rev);
/* debug <-> diagram */
void wifi_bind_io_to_evt(uint8_t io_idx, uint8_t evt);
void coex_bind_io_to_evt(uint8_t io_idx, uint8_t evt);
void diagram_bind_io_to_evt(void);
#endif

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