summaryrefslogtreecommitdiff
path: root/lib/bt/host/bluedroid
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bt/host/bluedroid')
-rw-r--r--lib/bt/host/bluedroid/Kconfig.in409
-rw-r--r--lib/bt/host/bluedroid/api/esp_a2dp_api.c150
-rw-r--r--lib/bt/host/bluedroid/api/esp_avrc_api.c185
-rw-r--r--lib/bt/host/bluedroid/api/esp_ble_cte_api.c224
-rw-r--r--lib/bt/host/bluedroid/api/esp_ble_iso_api.c425
-rw-r--r--lib/bt/host/bluedroid/api/esp_bluedroid_hci.c9
-rw-r--r--lib/bt/host/bluedroid/api/esp_bt_device.c7
-rw-r--r--lib/bt/host/bluedroid/api/esp_bt_main.c32
-rw-r--r--lib/bt/host/bluedroid/api/esp_gap_ble_api.c417
-rw-r--r--lib/bt/host/bluedroid/api/esp_gap_bt_api.c25
-rw-r--r--lib/bt/host/bluedroid/api/esp_gattc_api.c186
-rw-r--r--lib/bt/host/bluedroid/api/esp_gatts_api.c7
-rw-r--r--lib/bt/host/bluedroid/api/esp_hf_ag_api.c87
-rw-r--r--lib/bt/host/bluedroid/api/esp_hf_client_api.c82
-rw-r--r--lib/bt/host/bluedroid/api/esp_hidd_api.c15
-rw-r--r--lib/bt/host/bluedroid/api/esp_hidh_api.c15
-rw-r--r--lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c29
-rw-r--r--lib/bt/host/bluedroid/api/esp_pbac_api.c251
-rw-r--r--lib/bt/host/bluedroid/api/esp_sdp_api.c74
-rw-r--r--lib/bt/host/bluedroid/api/esp_spp_api.c15
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h272
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_a2dp_legacy_api.h77
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h210
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h379
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h660
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h118
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_bt_device.h13
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_bt_main.h14
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h634
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h53
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h15
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h1073
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h621
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h129
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_ag_legacy_api.h77
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h132
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_client_legacy_api.h78
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h37
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h28
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h32
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h41
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_pba_defs.h27
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_pbac_api.h340
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h210
-rw-r--r--lib/bt/host/bluedroid/api/include/api/esp_spp_api.h20
-rw-r--r--lib/bt/host/bluedroid/bta/av/bta_av_aact.c47
-rw-r--r--lib/bt/host/bluedroid/bta/av/bta_av_act.c91
-rw-r--r--lib/bt/host/bluedroid/bta/av/bta_av_api.c90
-rw-r--r--lib/bt/host/bluedroid/bta/av/bta_av_ca_act.c496
-rw-r--r--lib/bt/host/bluedroid/bta/av/bta_av_ca_sm.c170
-rw-r--r--lib/bt/host/bluedroid/bta/av/bta_av_main.c113
-rw-r--r--lib/bt/host/bluedroid/bta/av/bta_av_sbc.c58
-rw-r--r--lib/bt/host/bluedroid/bta/av/include/bta_av_int.h118
-rw-r--r--lib/bt/host/bluedroid/bta/dm/bta_dm_act.c413
-rw-r--r--lib/bt/host/bluedroid/bta/dm/bta_dm_api.c902
-rw-r--r--lib/bt/host/bluedroid/bta/dm/bta_dm_cfg.c16
-rw-r--r--lib/bt/host/bluedroid/bta/dm/bta_dm_co.c12
-rw-r--r--lib/bt/host/bluedroid/bta/dm/bta_dm_main.c122
-rw-r--r--lib/bt/host/bluedroid/bta/dm/bta_dm_pm.c9
-rw-r--r--lib/bt/host/bluedroid/bta/dm/include/bta_dm_int.h665
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/bta_gattc_act.c143
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/bta_gattc_api.c98
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/bta_gattc_main.c18
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c14
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/bta_gatts_act.c41
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/bta_gatts_api.c37
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/bta_gatts_main.c3
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h45
-rw-r--r--lib/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h13
-rw-r--r--lib/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c67
-rw-r--r--lib/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c2
-rw-r--r--lib/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c31
-rw-r--r--lib/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c344
-rw-r--r--lib/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h18
-rw-r--r--lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c2
-rw-r--r--lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c87
-rw-r--r--lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c27
-rw-r--r--lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c334
-rw-r--r--lib/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h19
-rw-r--r--lib/bt/host/bluedroid/bta/hh/bta_hh_le.c40
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_ag_api.h49
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_api.h357
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_ar_api.h6
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_av_api.h96
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_av_sbc.h12
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h90
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h66
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_jv_api.h9
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_pba_client_api.h92
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_pba_defs.h93
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h33
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/bta_sys.h5
-rw-r--r--lib/bt/host/bluedroid/bta/include/bta/utl.h7
-rw-r--r--lib/bt/host/bluedroid/bta/jv/bta_jv_act.c22
-rw-r--r--lib/bt/host/bluedroid/bta/pba/bta_pba_client_act.c702
-rw-r--r--lib/bt/host/bluedroid/bta/pba/bta_pba_client_api.c162
-rw-r--r--lib/bt/host/bluedroid/bta/pba/bta_pba_client_main.c293
-rw-r--r--lib/bt/host/bluedroid/bta/pba/bta_pba_client_sdp.c279
-rw-r--r--lib/bt/host/bluedroid/bta/pba/include/bta_pba_client_int.h177
-rw-r--r--lib/bt/host/bluedroid/bta/sdp/bta_sdp.c9
-rw-r--r--lib/bt/host/bluedroid/bta/sdp/bta_sdp_act.c144
-rw-r--r--lib/bt/host/bluedroid/bta/sdp/bta_sdp_api.c29
-rw-r--r--lib/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c8
-rw-r--r--lib/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h2
-rw-r--r--lib/bt/host/bluedroid/bta/sys/utl.c17
-rw-r--r--lib/bt/host/bluedroid/btc/core/btc_ble_storage.c13
-rw-r--r--lib/bt/host/bluedroid/btc/core/btc_config.c13
-rw-r--r--lib/bt/host/bluedroid/btc/core/btc_dm.c29
-rw-r--r--lib/bt/host/bluedroid/btc/core/btc_main.c51
-rw-r--r--lib/bt/host/bluedroid/btc/core/btc_util.c47
-rw-r--r--lib/bt/host/bluedroid/btc/include/btc/btc_config.h2
-rw-r--r--lib/bt/host/bluedroid/btc/include/btc/btc_main.h4
-rw-r--r--lib/bt/host/bluedroid/btc/include/btc/btc_util.h9
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c67
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c9
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c2
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c61
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink_ext_coedc.c286
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c50
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source_ext_codec.c235
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c292
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h8
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c457
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c395
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c589
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c106
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c36
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c9
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c7
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c136
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c129
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c134
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c83
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c33
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c23
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h80
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h100
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_av.h124
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_av_api.h3
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h50
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h98
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h125
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h5
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_gatt_util.h3
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h5
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_hd.h7
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h15
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h16
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_hh.h2
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h222
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h6
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_pba_client.h90
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h13
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/include/btc_spp.h1
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c384
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c129
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/pba/btc_pba_client.c968
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c717
-rw-r--r--lib/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c40
-rw-r--r--lib/bt/host/bluedroid/common/include/common/bluedroid_user_config.h263
-rw-r--r--lib/bt/host/bluedroid/common/include/common/bt_target.h473
-rw-r--r--lib/bt/host/bluedroid/common/include/common/bt_trace.h192
-rw-r--r--lib/bt/host/bluedroid/config/include/config/stack_config.h7
-rw-r--r--lib/bt/host/bluedroid/config/stack_config.c14
-rw-r--r--lib/bt/host/bluedroid/device/controller.c75
-rw-r--r--lib/bt/host/bluedroid/device/include/device/controller.h5
-rw-r--r--lib/bt/host/bluedroid/external/sbc/decoder/include/oi_codec_sbc.h2
-rw-r--r--lib/bt/host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c12
-rw-r--r--lib/bt/host/bluedroid/hci/ble_hci_iso.c346
-rw-r--r--lib/bt/host/bluedroid/hci/hci_hal_h4.c158
-rw-r--r--lib/bt/host/bluedroid/hci/hci_layer.c2
-rw-r--r--lib/bt/host/bluedroid/hci/hci_packet_factory.c28
-rw-r--r--lib/bt/host/bluedroid/hci/hci_packet_parser.c62
-rw-r--r--lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h85
-rw-r--r--lib/bt/host/bluedroid/hci/include/hci/hci_hal.h3
-rw-r--r--lib/bt/host/bluedroid/hci/include/hci/hci_layer.h3
-rw-r--r--lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h10
-rw-r--r--lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h20
-rw-r--r--lib/bt/host/bluedroid/hci/packet_fragmenter.c6
-rw-r--r--lib/bt/host/bluedroid/main/bte_init.c49
-rw-r--r--lib/bt/host/bluedroid/main/bte_main.c10
-rw-r--r--lib/bt/host/bluedroid/stack/avct/avct_lcb.c6
-rw-r--r--lib/bt/host/bluedroid/stack/avdt/avdt_api.c31
-rw-r--r--lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c24
-rw-r--r--lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c13
-rw-r--r--lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c2
-rw-r--r--lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c23
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_acl.c186
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble.c80
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c351
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c12
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c30
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c36
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c46
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c2
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_cte.c237
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c363
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_iso.c525
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c23
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c21
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_dev.c29
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_devctl.c44
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_inq.c13
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_main.c26
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_pm.c10
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_sco.c59
-rw-r--r--lib/bt/host/bluedroid/stack/btm/btm_sec.c18
-rw-r--r--lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h71
-rw-r--r--lib/bt/host/bluedroid/stack/btm/include/btm_int.h38
-rw-r--r--lib/bt/host/bluedroid/stack/btu/btu_hcif.c766
-rw-r--r--lib/bt/host/bluedroid/stack/btu/btu_init.c11
-rw-r--r--lib/bt/host/bluedroid/stack/btu/btu_task.c4
-rw-r--r--lib/bt/host/bluedroid/stack/gatt/gatt_api.c28
-rw-r--r--lib/bt/host/bluedroid/stack/gatt/gatt_db.c44
-rw-r--r--lib/bt/host/bluedroid/stack/gatt/gatt_main.c12
-rw-r--r--lib/bt/host/bluedroid/stack/gatt/gatt_sr.c25
-rw-r--r--lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c1
-rw-r--r--lib/bt/host/bluedroid/stack/gatt/gatt_utils.c42
-rw-r--r--lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h9
-rw-r--r--lib/bt/host/bluedroid/stack/goep/goepc_api.c376
-rw-r--r--lib/bt/host/bluedroid/stack/goep/goepc_main.c528
-rw-r--r--lib/bt/host/bluedroid/stack/goep/include/goep_int.h103
-rw-r--r--lib/bt/host/bluedroid/stack/hcic/hciblecmds.c942
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h7
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h2
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/avdt_api.h12
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/avrc_api.h8
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h5
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/bt_types.h1
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/btm_api.h60
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h659
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h16
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/gatt_api.h2
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/goep_common.h19
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/goepc_api.h82
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/hcidefs.h140
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h182
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/obex_api.h271
-rw-r--r--lib/bt/host/bluedroid/stack/include/stack/sdp_api.h16
-rw-r--r--lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h14
-rw-r--r--lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c42
-rw-r--r--lib/bt/host/bluedroid/stack/l2cap/l2c_link.c22
-rw-r--r--lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c14
-rw-r--r--lib/bt/host/bluedroid/stack/obex/include/obex_int.h76
-rw-r--r--lib/bt/host/bluedroid/stack/obex/include/obex_tl.h97
-rw-r--r--lib/bt/host/bluedroid/stack/obex/include/obex_tl_l2cap.h18
-rw-r--r--lib/bt/host/bluedroid/stack/obex/include/obex_tl_rfcomm.h18
-rw-r--r--lib/bt/host/bluedroid/stack/obex/obex_api.c776
-rw-r--r--lib/bt/host/bluedroid/stack/obex/obex_main.c216
-rw-r--r--lib/bt/host/bluedroid/stack/obex/obex_tl_l2cap.c811
-rw-r--r--lib/bt/host/bluedroid/stack/obex/obex_tl_rfcomm.c439
-rw-r--r--lib/bt/host/bluedroid/stack/sdp/sdp_api.c26
-rw-r--r--lib/bt/host/bluedroid/stack/sdp/sdp_db.c40
-rw-r--r--lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c3
-rw-r--r--lib/bt/host/bluedroid/stack/smp/smp_act.c12
-rw-r--r--lib/bt/host/bluedroid/stack/smp/smp_utils.c5
256 files changed, 29204 insertions, 3858 deletions
diff --git a/lib/bt/host/bluedroid/Kconfig.in b/lib/bt/host/bluedroid/Kconfig.in
index 58859d35..64b1d92d 100644
--- a/lib/bt/host/bluedroid/Kconfig.in
+++ b/lib/bt/host/bluedroid/Kconfig.in
@@ -43,7 +43,8 @@ config BT_BLUEDROID_MEM_DEBUG
config BT_BLUEDROID_ESP_COEX_VSC
bool "Enable Espressif Vendor-specific HCI commands for coexist status configuration"
depends on BT_BLUEDROID_ENABLED
- default y
+ default y if (ESP_COEX_SW_COEXIST_ENABLE || BT_CONTROLLER_DISABLED)
+ default n
help
Enable Espressif Vendor-specific HCI commands for coexist status configuration
@@ -84,8 +85,38 @@ config BT_A2DP_ENABLE
bool "A2DP"
depends on BT_CLASSIC_ENABLED
default n
+ select BT_AVRCP_ENABLED
+ help
+ Advanced Audio Distribution Profile
+
+config BT_A2DP_USE_EXTERNAL_CODEC
+ bool "Use External Codec for A2DP"
+ depends on BT_A2DP_ENABLE
+ default n
+ help
+ If enable, user shall register audio codec capability to A2DP and encode/decode
+ audio data in application layer. The internal codec in A2DP will be remove in
+ the future, it is recommend to use external codec for new design.
+
+config BT_AVRCP_ENABLED
+ bool
+ depends on BT_A2DP_ENABLE
+ default y
help
- Advanced Audio Distrubution Profile
+ 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"
@@ -102,6 +133,34 @@ config BT_L2CAP_ENABLED
This enables the Logical Link Control and Adaptation Layer Protocol.
Only supported classic bluetooth.
+config BT_SDP_COMMON_ENABLED
+ bool "BT SDP COMMON"
+ depends on BT_CLASSIC_ENABLED
+ default y if BT_L2CAP_ENABLED
+ default n
+ help
+ This enables common SDP operation, such as SDP record creation and deletion.
+
+config BT_SDP_PAD_LEN
+ int "One or more BT SDP attributes total allocated length (bytes)"
+ depends on BT_CLASSIC_ENABLED
+ default 300
+ range BT_SDP_ATTR_LEN 1024
+ help
+ This is the total size of all SDP attributes allowed.
+ Any attributes that exceed this size are truncated.
+ The default value is 300.
+
+config BT_SDP_ATTR_LEN
+ int "Single BT SDP attribute allocated length (bytes)"
+ depends on BT_CLASSIC_ENABLED
+ default 300
+ range 300 1024
+ help
+ This is the maximum allowed size for a single SDP attribute.
+ Any attributes that exceed this size are truncated.
+ The default value is 300.
+
menuconfig BT_HFP_ENABLE
bool "Hands Free/Handset Profile"
depends on BT_CLASSIC_ENABLED
@@ -134,21 +193,29 @@ choice BT_HFP_AUDIO_DATA_PATH
bool "HCI"
endchoice
+config BT_HFP_USE_EXTERNAL_CODEC
+ bool "Use External Codec for HFP"
+ depends on BT_HFP_ENABLE && BT_HFP_AUDIO_DATA_PATH_HCI
+ default n
+ help
+ If enable, user shall encode/decode audio data in application layer. The internal
+ codec in HFP will be remove in the future, it is recommend to use external codec
+ for new design.
+
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 transmited via GPIOs.
-
+ 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 +230,44 @@ config BT_HID_DEVICE_ENABLED
help
This enables the BT HID Device
+config BT_HID_REMOVE_DEVICE_BONDING_ENABLED
+ bool "Remove Device Bonding Information when HID Virtual Cable Unplugging"
+ depends on BT_HID_ENABLED
+ default y
+ help
+ This enables the BT HID to remove device bonding information when virtual cable unplugging,
+ removing device bonding information is optional in HID 1.0 but mandatory in HID 1.1
+
+menuconfig BT_PBAC_ENABLED
+ bool "PBAP Client"
+ depends on BT_CLASSIC_ENABLED
+ default n
+ select BT_GOEPC_ENABLED
+ help
+ This enables the Phone Book Access Profile Client
+
+config BT_PBAC_SUPPORTED_FEAT
+ hex "PBAP Client Supported Features"
+ depends on BT_PBAC_ENABLED
+ default 0x000003FF
+ help
+ Set the supported features of PBAP Client, the default value is supported all features
+
+config BT_PBAC_PREFERRED_MTU
+ int "PBAP Client Preferred MTU"
+ depends on BT_PBAC_ENABLED
+ default 0
+ help
+ MTU is limited by the max MTU of transport layer, and should not be smaller than 255,
+ but can be set to zero to use a default MTU of transport layer
+
+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
@@ -170,7 +275,7 @@ config BT_BLE_ENABLED
help
This enables Bluetooth Low Energy
-config BT_GATTS_ENABLE
+menuconfig BT_GATTS_ENABLE
bool "Include GATT server module(GATTS)"
depends on BT_BLE_ENABLED
default y
@@ -182,8 +287,9 @@ config BT_GATTS_PPCP_CHAR_GAP
depends on BT_GATTS_ENABLE
default n
help
- This enables "Peripheral Preferred Connection Parameters" characteristic (UUID: 0x2A04) in GAP service that has
- connection parameters like min/max connection interval, slave latency and supervision timeout multiplier
+ This enables "Peripheral Preferred Connection Parameters" characteristic (UUID: 0x2A04)
+ in GAP service that has connection parameters like min/max connection interval, slave
+ latency and supervision timeout multiplier
config BT_BLE_BLUFI_ENABLE
bool "Include blufi function"
@@ -259,7 +365,7 @@ config BT_GATTS_APPEARANCE_WRITABLE
help
Enabling this option allows remote GATT clients to write appearance
-config BT_GATTC_ENABLE
+menuconfig BT_GATTC_ENABLE
bool "Include GATT client module(GATTC)"
depends on BT_BLE_ENABLED
default y
@@ -297,7 +403,16 @@ config BT_GATTC_CONNECT_RETRY_COUNT
help
The number of attempts to reconnect if the connection establishment failed
-config BT_BLE_SMP_ENABLE
+config BT_BLE_ESTAB_LINK_CONN_TOUT
+ int "Timeout of BLE connection establishment"
+ depends on BT_GATTC_ENABLE
+ range 1 60
+ default 30
+ help
+ Bluetooth Connection establishment maximum time, if connection time exceeds this value, the connection
+ establishment fails, ESP_GATTC_OPEN_EVT or ESP_GATTS_OPEN_EVT is triggered.
+
+menuconfig BT_BLE_SMP_ENABLE
bool "Include BLE security module(SMP)"
depends on BT_BLE_ENABLED
default y
@@ -312,6 +427,41 @@ config BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE
In order to reduce the pairing time, slave actively initiates connection parameters
update during pairing.
+config BT_BLE_SMP_ID_RESET_ENABLE
+ bool "Reset device identity when all bonding records are deleted"
+ depends on BT_BLE_SMP_ENABLE
+ default n
+ help
+ There are tracking risks associated with using a fixed or static IRK.
+ If enabled this option, Bluedroid will assign a new randomly-generated IRK
+ when all pairing and bonding records are deleted. This would decrease the ability
+ of a previously paired peer to be used to determine whether a device
+ with which it previously shared an IRK is within range.
+
+config BT_BLE_SMP_BOND_NVS_FLASH
+ bool "Save SMP bonding keys to nvs flash"
+ depends on BT_BLE_SMP_ENABLE
+ default y
+ help
+ This select can save SMP bonding keys to nvs flash
+
+config BT_BLE_RPA_SUPPORTED
+ bool "Update RPA to Controller"
+ depends on (BT_BLE_SMP_ENABLE && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR
+ default n if (BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED)
+ default y if BT_CONTROLLER_DISABLED
+ help
+ This enables controller RPA list function.
+ For ESP32, ESP32 only support network privacy mode. If this option is enabled, ESP32 will only accept
+ advertising packets from peer devices that contain private address, HW will not receive the advertising
+ packets contain identity address after IRK changed. If this option is disabled, address resolution will
+ be performed in the host, so the functions that require controller to resolve address in the white list
+ cannot be used. This option is disabled by default on ESP32, please enable or disable this option according
+ to your own needs.
+
+ For other BLE chips, devices support network privacy mode and device privacy mode,
+ users can switch the two modes according to their own needs. So this option is enabled by default.
+
config BT_STACK_NO_LOG
bool "Disable BT debug logs (minimize bin size)"
depends on BT_BLUEDROID_ENABLED
@@ -1072,7 +1222,7 @@ config BT_ACL_CONNECTIONS
is used.
config BT_MULTI_CONNECTION_ENBALE
- bool "Enable BLE multi-conections"
+ bool "Enable BLE multi-connections"
depends on BT_BLE_ENABLED
default y
help
@@ -1092,15 +1242,6 @@ config BT_BLE_DYNAMIC_ENV_MEMORY
help
This select can make the allocation of memory will become more flexible
-config BT_BLE_HOST_QUEUE_CONG_CHECK
- bool "BLE queue congestion check"
- depends on BT_BLE_ENABLED
- default n
- help
- When scanning and scan duplicate is not enabled, if there are a lot of adv packets around
- or application layer handling adv packets is slow, it will cause the controller memory
- to run out. if enabled, adv packets will be lost when host queue is congested.
-
config BT_SMP_ENABLE
bool
depends on BT_BLUEDROID_ENABLED
@@ -1125,15 +1266,6 @@ config BT_BLE_ACT_SCAN_REP_ADV_SCAN
# Memory reserved at start of DRAM for Bluetooth stack
-config BT_BLE_ESTAB_LINK_CONN_TOUT
- int "Timeout of BLE connection establishment"
- depends on BT_BLE_ENABLED
- range 1 60
- default 30
- help
- Bluetooth Connection establishment maximum time, if connection time exceeds this value, the connection
- establishment fails, ESP_GATTC_OPEN_EVT or ESP_GATTS_OPEN_EVT is triggered.
-
config BT_MAX_DEVICE_NAME_LEN
int "length of bluetooth device name"
depends on BT_BLUEDROID_ENABLED
@@ -1144,23 +1276,6 @@ config BT_MAX_DEVICE_NAME_LEN
the complete device name, then only the shortname will be displayed, the rest parts that can't fit in
will be truncated.
-config BT_BLE_RPA_SUPPORTED
- bool "Update RPA to Controller"
- depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR
- default n if (BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED)
- default y if BT_CONTROLLER_DISABLED
- help
- This enables controller RPA list function.
- For ESP32, ESP32 only support network privacy mode. If this option is enabled, ESP32 will only accept
- advertising packets from peer devices that contain private address, HW will not receive the advertising
- packets contain identity address after IRK changed. If this option is disabled, address resolution will
- be performed in the host, so the functions that require controller to resolve address in the white list
- cannot be used. This option is disabled by default on ESP32, please enable or disable this option according
- to your own needs.
-
- For other BLE chips, devices support network privacy mode and device privacy mode,
- users can switch the two modes according to their own needs. So this option is enabled by default.
-
config BT_BLE_RPA_TIMEOUT
int "Timeout of resolvable private address"
depends on BT_BLE_ENABLED
@@ -1170,20 +1285,49 @@ config BT_BLE_RPA_TIMEOUT
This set RPA timeout of Controller and Host.
Default is 900 s (15 minutes). Range is 1 s to 1 hour (3600 s).
-config BT_BLE_50_FEATURES_SUPPORTED
- bool "Enable BLE 5.0 features"
+menuconfig BT_BLE_50_FEATURES_SUPPORTED
+ bool "Enable BLE 5.0 features(please disable BLE 4.2 if enable BLE 5.0)"
depends on (BT_BLE_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_50_SUPPORTED) || BT_CONTROLLER_DISABLED))
default y
help
Enabling this option activates BLE 5.0 features.
This option is universally supported in chips that support BLE, except for ESP32.
+ BLE 4.2 and BLE 5.0 cannot be used simultaneously.
-config BT_BLE_42_FEATURES_SUPPORTED
- bool "Enable BLE 4.2 features"
- depends on (BT_BLE_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_SUPPORTED) || BT_CONTROLLER_DISABLED))
- default n
+config BT_BLE_50_EXTEND_ADV_EN
+ bool "Enable BLE extend advertising"
+ depends on BT_BLE_50_FEATURES_SUPPORTED
+ default y
help
- This enables BLE 4.2 features.
+ This enables BLE extend advertising
+
+config BT_BLE_50_PERIODIC_ADV_EN
+ bool "Enable BLE periodic advertising"
+ depends on BT_BLE_50_FEATURES_SUPPORTED
+ default y
+ help
+ This enables BLE periodic advertising
+
+config BT_BLE_50_EXTEND_SCAN_EN
+ bool "Enable BLE extend scan"
+ depends on BT_BLE_50_FEATURES_SUPPORTED
+ default y
+ help
+ This enables BLE extend scan
+
+config BT_BLE_50_EXTEND_SYNC_EN
+ bool "Enable BLE periodic advertising sync"
+ depends on BT_BLE_50_FEATURES_SUPPORTED
+ default y
+ help
+ This enables BLE periodic advertising sync
+
+config BT_BLE_50_DTM_TEST_EN
+ bool "Enable BLE 5.0 DTM test"
+ depends on BT_BLE_50_FEATURES_SUPPORTED
+ default y
+ help
+ This enables BLE 5.0 direct test mode
config BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER
bool "Enable BLE periodic advertising sync transfer feature"
@@ -1206,9 +1350,166 @@ config BT_BLE_FEAT_CREATE_SYNC_ENH
help
Enable the create sync enhancements
+menuconfig BT_BLE_42_FEATURES_SUPPORTED
+ bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)"
+ depends on BT_BLE_ENABLED
+ default y if IDF_TARGET_ESP32
+ default n
+ help
+ This enables BLE 4.2 features.
+ This option is universally supported by all ESP chips with BLE capabilities.
+ BLE 4.2 and BLE 5.0 cannot be used simultaneously.
+
+config BT_BLE_42_DTM_TEST_EN
+ bool "Enable BLE 4.2 DTM test"
+ depends on BT_BLE_42_FEATURES_SUPPORTED
+ default y
+ help
+ This enables BLE 4.2 direct test mode
+
+config BT_BLE_42_ADV_EN
+ bool "Enable BLE 4.2 advertising"
+ depends on BT_BLE_42_FEATURES_SUPPORTED
+ default y
+ help
+ This enables BLE v4.2 advertising
+
+config BT_BLE_42_SCAN_EN
+ bool "Enable BLE 4.2 scan"
+ depends on BT_BLE_42_FEATURES_SUPPORTED
+ default y
+ help
+ This enables BLE v4.2 scan
+
+menuconfig BT_BLE_FEAT_ISO_EN
+ bool "Enable BLE 5.2 iso feature"
+ depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_AUDIO_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR
+ default n
+ help
+ Enable BLE 5.2 iso
+
+config BT_BLE_FEAT_ISO_60_EN
+ bool "Enable ISO v6.0 feature"
+ depends on BT_BLE_FEAT_ISO_EN
+ default n
+ help
+ Enable iso 6.0 feature
+
+config BT_BLE_FEAT_ISO_BIG_BROCASTER
+ bool "Enable BLE iso BIG brocaster"
+ depends on BT_BLE_FEAT_ISO_EN
+ default y
+ help
+ Enable BLE 5.2 BIG brocaster
+
+config BT_BLE_FEAT_ISO_BIG_SYNCER
+ bool "Enable BLE iso BIG syncer"
+ depends on BT_BLE_FEAT_ISO_EN
+ default y
+ help
+ Enable BLE 5.2 BIG syncer
+
+config BT_BLE_ISO_BIS_MAX_COUNT
+ int "Maximum bis count"
+ depends on BT_BLE_FEAT_ISO_EN && (BT_BLE_FEAT_ISO_BIG_BROCASTER || BT_BLE_FEAT_ISO_BIG_SYNCER)
+ default 2
+ range 1 31
+ help
+ Enable BLE 5.2 CIG peripheral
+
+config BT_BLE_FEAT_ISO_CIG_CENTRAL
+ bool "Enable BLE iso CIG central"
+ depends on BT_BLE_FEAT_ISO_EN
+ default y
+ help
+ Enable BLE 5.2 CIG central
+
+config BT_BLE_FEAT_ISO_CIG_PERIPHERAL
+ bool "Enable BLE iso CIG peripheral"
+ depends on BT_BLE_FEAT_ISO_EN
+ default y
+ help
+ Enable BLE 5.2 CIG peripheral
+
+config BT_BLE_ISO_CIS_MAX_COUNT
+ int "Maximum cis count"
+ depends on BT_BLE_FEAT_ISO_EN && (BT_BLE_FEAT_ISO_CIG_CENTRAL || BT_BLE_FEAT_ISO_CIG_PERIPHERAL)
+ default 2
+ range 1 31
+ help
+ Enable BLE 5.2 CIG peripheral
+
+choice BT_BLE_ISO_FLOW_CONTROL
+ prompt "Select ISO flow control type"
+ depends on BT_BLE_FEAT_ISO_EN
+ default BT_BLE_ISO_NON_STD_FLOW_CTRL
+ help
+ Select ISO flow control type
+
+ config BT_BLE_ISO_STD_FLOW_CTRL
+ bool "ISO standard flow control"
+ help
+ Enable ISO standard flow control
+
+ config BT_BLE_ISO_NON_STD_FLOW_CTRL
+ bool "ISO non-standard flow control"
+ help
+ Enable ISO non-standard flow control
+
+endchoice
+
+menuconfig BT_BLE_FEAT_CTE_EN
+ bool "Enable BLE CTE feature"
+ depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_CTE_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR
+ default n
+ help
+ Enable BLE 5.1 CTE
+
+config BT_BLE_FEAT_CTE_CONNECTIONLESS_EN
+ bool "Enable BLE CTE connectionless feature"
+ depends on BT_BLE_FEAT_CTE_EN
+ default y
+ help
+ Transmission of CTE in periodic advertising
+
+config BT_BLE_FEAT_CTE_CONNECTION_EN
+ bool "Enable BLE CTE connection feature"
+ depends on BT_BLE_FEAT_CTE_EN
+ default y
+ help
+ Transmission of CTE by ACL connection
+
+config BT_BLE_FEAT_POWER_CONTROL
+ bool "Enable BLE power control feature"
+ depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_POWER_CONTROL_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR
+ default n
+ help
+ Enable BLE power control feature
+
+config BT_BLE_FEAT_CONN_SUBRATING
+ bool "Enable BLE connection subrating feature"
+ depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_SUBRATE_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR
+ default n
+ help
+ Enable BLE connection subrating feature
+
+config BT_BLE_VENDOR_HCI_EN
+ bool "Enable BLE Vendor HCI command and event"
+ depends on BT_BLE_ENABLED
+ default y
+ help
+ This enables BLE vendor HCI command and event
+
config BT_BLE_HIGH_DUTY_ADV_INTERVAL
bool "Enable BLE high duty advertising interval feature"
depends on BT_BLE_ENABLED
default n
help
This enable BLE high duty advertising interval feature
+
+config BT_ABORT_WHEN_ALLOCATION_FAILS
+ bool "Abort when memory allocation fails in BT/BLE stack"
+ depends on BT_BLUEDROID_ENABLED
+ default n
+ help
+ This enables abort when memory allocation fails
diff --git a/lib/bt/host/bluedroid/api/esp_a2dp_api.c b/lib/bt/host/bluedroid/api/esp_a2dp_api.c
index be8adcf2..254c43d5 100644
--- a/lib/bt/host/bluedroid/api/esp_a2dp_api.c
+++ b/lib/bt/host/bluedroid/api/esp_a2dp_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,6 +14,37 @@
#if BTC_AV_INCLUDED
+esp_a2d_audio_buff_t *esp_a2d_audio_buff_alloc(uint16_t size)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return NULL;
+ }
+
+ if (size == 0) {
+ return NULL;
+ }
+
+ uint8_t *p_buf = NULL, *p_data;
+ btc_av_audio_buff_alloc(size, &p_buf, &p_data);
+ if (p_buf == NULL) {
+ return NULL;
+ }
+
+ esp_a2d_audio_buff_t *audio_buf = (esp_a2d_audio_buff_t *)p_buf;
+ audio_buf->buff_size = size;
+ audio_buf->data_len = 0;
+ audio_buf->data = p_data;
+ return audio_buf;
+}
+
+void esp_a2d_audio_buff_free(esp_a2d_audio_buff_t *audio_buf)
+{
+ if (audio_buf == NULL) {
+ return;
+ }
+ btc_av_audio_buff_free((uint8_t *)audio_buf);
+}
+
#if BTC_AV_SINK_INCLUDED
esp_err_t esp_a2d_sink_init(void)
{
@@ -36,6 +67,35 @@ esp_err_t esp_a2d_sink_init(void)
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_a2d_sink_register_stream_endpoint(uint8_t seid, const esp_a2d_mcc_t *mcc)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (seid >= ESP_A2D_MAX_SEPS) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_A2DP;
+ msg.act = BTC_AV_SINK_API_REG_SEP_EVT;
+
+ btc_av_args_t arg;
+ memset(&arg, 0, sizeof(btc_av_args_t));
+ arg.reg_sep.seid = seid;
+ memcpy(&arg.reg_sep.mcc, mcc, sizeof(esp_a2d_mcc_t));
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
esp_err_t esp_a2d_sink_deinit(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
@@ -81,6 +141,30 @@ esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback)
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_a2d_sink_register_audio_data_callback(esp_a2d_sink_audio_data_cb_t callback)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (g_a2dp_sink_ongoing_deinit) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_A2DP;
+ msg.act = BTC_AV_SINK_API_REG_AUDIO_DATA_CB_EVT;
+
+ btc_av_args_t arg;
+ memset(&arg, 0, sizeof(btc_av_args_t));
+ arg.audio_data_cb = callback;
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
@@ -229,6 +313,21 @@ esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl)
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_a2d_get_profile_status(esp_a2d_profile_status_t *profile_status)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(profile_status, 0, sizeof(esp_a2d_profile_status_t));
+ btc_a2dp_get_profile_status(profile_status);
+
+ return ESP_OK;
+}
+
#if BTC_AV_SRC_INCLUDED
esp_err_t esp_a2d_source_init(void)
{
@@ -251,6 +350,35 @@ esp_err_t esp_a2d_source_init(void)
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_a2d_source_register_stream_endpoint(uint8_t seid, const esp_a2d_mcc_t *mcc)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (seid >= ESP_A2D_MAX_SEPS) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_A2DP;
+ msg.act = BTC_AV_SRC_API_REG_SEP_EVT;
+
+ btc_av_args_t arg;
+ memset(&arg, 0, sizeof(btc_av_args_t));
+ arg.reg_sep.seid = seid;
+ memcpy(&arg.reg_sep.mcc, mcc, sizeof(esp_a2d_mcc_t));
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
esp_err_t esp_a2d_source_deinit(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
@@ -348,6 +476,26 @@ esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callbac
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_a2d_source_audio_data_send(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED || !btc_av_is_started()) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (audio_buf == NULL || audio_buf->data_len == 0 || conn_hdl == 0) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (!btc_a2d_src_audio_mtu_check(audio_buf->data_len)) {
+ return ESP_ERR_INVALID_SIZE;
+ }
+
+ if (btc_a2d_src_audio_data_send(conn_hdl, audio_buf) != BT_STATUS_SUCCESS) {
+ return ESP_FAIL;
+ }
+ return ESP_OK;
+}
+
#endif /* BTC_AV_SRC_INCLUDED */
#endif /* #if BTC_AV_INCLUDED */
diff --git a/lib/bt/host/bluedroid/api/esp_avrc_api.c b/lib/bt/host/bluedroid/api/esp_avrc_api.c
index 2d3e1532..ff4f601c 100644
--- a/lib/bt/host/bluedroid/api/esp_avrc_api.c
+++ b/lib/bt/host/bluedroid/api/esp_avrc_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -232,6 +232,174 @@ 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;
}
+esp_err_t esp_avrc_ct_send_get_play_status_cmd(uint8_t tl)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (tl > ESP_AVRC_TRANS_LABEL_MAX) {
+ 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_STATUS_API_SND_GET_PLAY_STATUS_EVT;
+
+ btc_avrc_args_t arg;
+ memset(&arg, 0, sizeof(btc_avrc_args_t));
+
+ arg.get_play_status_cmd.tl = tl;
+
+ /* 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;
+}
+
+#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 **/
/*********************************************************************************************/
@@ -474,4 +642,19 @@ esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_
}
+esp_err_t esp_avrc_get_profile_status(esp_avrc_profile_status_t *profile_status)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(profile_status, 0, sizeof(esp_avrc_profile_status_t));
+ btc_avrc_get_profile_status(profile_status);
+
+ return ESP_OK;
+}
+
#endif /* #if BTC_AV_INCLUDED */
diff --git a/lib/bt/host/bluedroid/api/esp_ble_cte_api.c b/lib/bt/host/bluedroid/api/esp_ble_cte_api.c
new file mode 100644
index 00000000..37503c47
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/esp_ble_cte_api.c
@@ -0,0 +1,224 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "esp_bt_device.h"
+#include "esp_bt_main.h"
+#if (BLE_FEAT_CTE_EN == TRUE)
+#include "esp_ble_cte_api.h"
+#include "btc_ble_cte.h"
+#include "btc/btc_manage.h"
+
+
+esp_err_t esp_ble_cte_register_callback(esp_ble_cte_cb_t callback)
+{
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ return (btc_profile_cb_set(BTC_PID_BLE_CTE, callback) == 0 ? ESP_OK : ESP_FAIL);
+}
+
+esp_ble_cte_cb_t esp_ble_cte_get_callback(void)
+{
+ return (esp_ble_cte_cb_t) btc_profile_cb_get(BTC_PID_BLE_CTE);
+}
+
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+esp_err_t esp_ble_cte_set_connectionless_trans_params(esp_ble_cte_connless_trans_params_t *cte_trans_params)
+{
+ btc_msg_t msg;
+ btc_ble_cte_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if ((cte_trans_params == NULL) || (cte_trans_params->antenna_ids == NULL)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_SET_TRANS_PARAMS;
+
+ arg.cte_trans_params.adv_handle = cte_trans_params->adv_handle;
+ arg.cte_trans_params.cte_len = cte_trans_params->cte_len;
+ arg.cte_trans_params.cte_type = cte_trans_params->cte_type;
+ arg.cte_trans_params.cte_count = cte_trans_params->cte_count;
+ arg.cte_trans_params.switching_pattern_len = cte_trans_params->switching_pattern_len;
+ arg.cte_trans_params.antenna_ids = cte_trans_params->antenna_ids;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_cte_set_connectionless_trans_enable(esp_ble_cte_trans_enable_params_t *cte_trans_enable)
+{
+ btc_msg_t msg;
+ btc_ble_cte_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (cte_trans_enable == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_SET_TRANS_ENABLE;
+
+ arg.cte_trans_enable.adv_handle = cte_trans_enable->adv_handle;
+ arg.cte_trans_enable.cte_enable = cte_trans_enable->cte_enable;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), NULL , NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_cte_set_connectionless_iq_sampling_enable(esp_ble_cte_iq_sampling_params_t *iq_sampling_en)
+{
+ btc_msg_t msg;
+ btc_ble_cte_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if ((iq_sampling_en == NULL) || (iq_sampling_en->antenna_ids == NULL)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_SET_IQ_SAMPLING_EN;
+
+ arg.cte_iq_sampling_en.sync_handle = iq_sampling_en->sync_handle;
+ arg.cte_iq_sampling_en.sampling_en = iq_sampling_en->sampling_en;
+ arg.cte_iq_sampling_en.slot_dur = iq_sampling_en->slot_dur;
+ arg.cte_iq_sampling_en.max_sampled_ctes = iq_sampling_en->max_sampled_ctes;
+ arg.cte_iq_sampling_en.switching_pattern_len = iq_sampling_en->switching_pattern_len;
+ arg.cte_iq_sampling_en.antenna_ids = iq_sampling_en->antenna_ids;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+esp_err_t esp_ble_cte_set_connection_receive_params(esp_ble_cte_recv_params_params_t *cte_recv_params)
+{
+ btc_msg_t msg;
+ btc_ble_cte_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if ((cte_recv_params == NULL) || (cte_recv_params->antenna_ids == NULL)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS;
+
+ arg.cte_recv_params.conn_handle = cte_recv_params->conn_handle;
+ arg.cte_recv_params.sampling_en = cte_recv_params->sampling_en;
+ arg.cte_recv_params.slot_dur = cte_recv_params->slot_dur;
+ arg.cte_recv_params.switching_pattern_len = cte_recv_params->switching_pattern_len;
+ arg.cte_recv_params.antenna_ids = cte_recv_params->antenna_ids;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_cte_set_connection_transmit_params(esp_ble_cte_conn_trans_params_t *cte_conn_trans_params)
+{
+ btc_msg_t msg;
+ btc_ble_cte_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if ((cte_conn_trans_params == NULL) || (cte_conn_trans_params->antenna_ids == NULL)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS;
+
+ arg.cte_conn_trans_params.conn_handle = cte_conn_trans_params->conn_handle;
+ arg.cte_conn_trans_params.cte_types = cte_conn_trans_params->cte_types;
+ arg.cte_conn_trans_params.switching_pattern_len = cte_conn_trans_params->switching_pattern_len;
+ arg.cte_conn_trans_params.antenna_ids = cte_conn_trans_params->antenna_ids;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_cte_connection_cte_request_enable(esp_ble_cte_req_en_params_t *cte_conn_req_en)
+{
+ btc_msg_t msg;
+ btc_ble_cte_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (cte_conn_req_en == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_SET_CONN_CTE_REQUEST_EN;
+
+ arg.cte_req_en.conn_handle = cte_conn_req_en->conn_handle;
+ arg.cte_req_en.enable = cte_conn_req_en->enable;
+ arg.cte_req_en.cte_req_interval = cte_conn_req_en->cte_req_interval;
+ arg.cte_req_en.req_cte_len = cte_conn_req_en->req_cte_len;
+ arg.cte_req_en.req_cte_Type = cte_conn_req_en->req_cte_Type;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_cte_connection_cte_response_enable(esp_ble_cte_rsp_en_params_t *cte_conn_rsp_en)
+{
+ btc_msg_t msg;
+ btc_ble_cte_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (cte_conn_rsp_en == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_SET_CONN_CTE_RESPONSE_EN;
+
+ arg.cte_rsp_en.conn_handle = cte_conn_rsp_en->conn_handle;
+ arg.cte_rsp_en.enable = cte_conn_rsp_en->enable;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+esp_err_t esp_ble_cte_read_antenna_information(void)
+{
+ btc_msg_t msg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_CTE;
+ msg.act = BTC_CTE_ACT_READ_ANTENNA_INFOR;
+
+ return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
diff --git a/lib/bt/host/bluedroid/api/esp_ble_iso_api.c b/lib/bt/host/bluedroid/api/esp_ble_iso_api.c
new file mode 100644
index 00000000..826991e6
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/esp_ble_iso_api.c
@@ -0,0 +1,425 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "esp_bt_device.h"
+#include "esp_bt_main.h"
+#include "esp_ble_iso_api.h"
+#include "btc_iso_ble.h"
+#include "btc/btc_manage.h"
+
+
+esp_err_t esp_ble_iso_register_callback(esp_ble_iso_cb_t callback)
+{
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ return (btc_profile_cb_set(BTC_PID_ISO_BLE, callback) == 0 ? ESP_OK : ESP_FAIL);
+}
+
+esp_ble_iso_cb_t esp_ble_iso_get_callback(void)
+{
+ return (esp_ble_iso_cb_t) btc_profile_cb_get(BTC_PID_ISO_BLE);
+}
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+esp_err_t esp_ble_iso_create_big(esp_ble_iso_big_creat_params_t *big_creat_param)
+{
+
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ if (big_creat_param == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_BIG_CREATE;
+
+ memcpy(&arg.iso_big_creat_params, big_creat_param, sizeof(esp_ble_iso_big_creat_params_t));
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_create_big_test(esp_ble_iso_big_creat_test_params_t *big_creat_test_param)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ if (big_creat_test_param == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_BIG_CREATE_TEST;
+
+ memcpy(&arg.iso_big_creat_test_params, big_creat_test_param, sizeof(esp_ble_iso_big_creat_test_params_t));
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_terminate_big(uint8_t big_handle, uint8_t reason)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_BIG_TERMINATE;
+
+ arg.iso_big_terminate_params.big_handle = big_handle;
+ arg.iso_big_terminate_params.reason = reason;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+esp_err_t esp_ble_iso_big_create_sync(esp_ble_iso_big_sync_creat_params_t *big_sync_create_param)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ if (big_sync_create_param == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (big_sync_create_param->num_bis > BLE_ISO_BIS_MAX_COUNT) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_BIG_SYNC_CREATE;
+
+ arg.iso_big_sync_creat_params.big_handle = big_sync_create_param->big_handle;
+ arg.iso_big_sync_creat_params.sync_handle = big_sync_create_param->sync_handle;
+ arg.iso_big_sync_creat_params.encryption = big_sync_create_param->encryption;
+ memcpy(&arg.iso_big_sync_creat_params.bc_code[0], &big_sync_create_param->bc_code[0], 16);
+ arg.iso_big_sync_creat_params.mse = big_sync_create_param->mse;
+ arg.iso_big_sync_creat_params.big_sync_timeout = big_sync_create_param->big_sync_timeout;
+ arg.iso_big_sync_creat_params.num_bis = big_sync_create_param->num_bis;
+ for (uint8_t i = 0; i < big_sync_create_param->num_bis; i++)
+ {
+ arg.iso_big_sync_creat_params.bis[i] = big_sync_create_param->bis[i];
+ }
+
+ // memcpy(&arg.iso_big_sync_creat_params, big_sync_create_param, sizeof(esp_ble_iso_big_sync_creat_params_t));
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_big_terminate_sync(uint8_t big_handle)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_BIG_SYNC_TERMINATE;
+
+ arg.iso_big_sync_terminate_params.big_handle = big_handle;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+esp_err_t esp_ble_iso_set_iso_data_path(esp_ble_iso_set_data_path_params_t *data_path_params)
+{
+ btc_msg_t msg = {0};
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (data_path_params == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (data_path_params->codec_cfg_len && (!data_path_params->codec_cfg)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (data_path_params->codec_cfg && (!data_path_params->codec_cfg_len)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (data_path_params->data_path_dir > ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_SET_DATA_PATH;
+
+ arg.iso_set_data_path_params.conn_handle = data_path_params->iso_handle;
+ arg.iso_set_data_path_params.data_path_dir = data_path_params->data_path_dir;
+ arg.iso_set_data_path_params.data_path_id = data_path_params->data_path_id;
+ arg.iso_set_data_path_params.coding_fmt = data_path_params->coding_fmt;
+ arg.iso_set_data_path_params.company_id = data_path_params->company_id;
+ arg.iso_set_data_path_params.vs_codec_id = data_path_params->vs_codec_id;
+ arg.iso_set_data_path_params.controller_delay = data_path_params->controller_delay;
+ arg.iso_set_data_path_params.codec_cfg_len = data_path_params->codec_cfg_len;
+ arg.iso_set_data_path_params.codec_cfg = data_path_params->codec_cfg;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), btc_iso_ble_arg_deep_copy, btc_iso_ble_arg_deep_free)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_remove_iso_data_path(esp_ble_iso_remove_data_path_params_t *data_path_params)
+{
+ btc_msg_t msg = {0};
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (data_path_params == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (data_path_params->data_path_dir == 0 || data_path_params->data_path_dir > ESP_BLE_ISO_DATA_PATH_DIR_ALL_BIT_MASK) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_REMOVE_DATA_PATH;
+
+ arg.iso_remove_data_path_params.conn_handle = data_path_params->iso_handle;
+ arg.iso_remove_data_path_params.data_path_dir = data_path_params->data_path_dir;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_read_iso_tx_sync(uint16_t iso_handle)
+{
+ btc_msg_t msg = {0};
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_READ_ISO_TX_SYNC;
+
+ arg.iso_read_tx_sync_params.iso_handle = iso_handle;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_read_link_quality(uint16_t iso_handle)
+{
+ btc_msg_t msg = {0};
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_READ_ISO_LINK_QUALITY;
+
+ arg.iso_read_link_quality_params.iso_handle = iso_handle;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+esp_err_t esp_ble_iso_set_cig_parameters(struct esp_ble_iso_set_cig_params *cig_params)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if ((cig_params == NULL) || (cig_params->cis_cnt > BLE_ISO_CIS_MAX_COUNT)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_SET_CIG_PARAMS;
+
+ arg.set_cig_params.cig_id = cig_params->cig_id;
+ arg.set_cig_params.sdu_int_c_to_p = cig_params->sdu_int_c_to_p;
+ arg.set_cig_params.sdu_int_p_to_c = cig_params->sdu_int_p_to_c;
+ arg.set_cig_params.worse_case_SCA = cig_params->worse_case_SCA;
+ arg.set_cig_params.packing = cig_params->packing;
+ arg.set_cig_params.framing = cig_params->framing;
+ arg.set_cig_params.mtl_c_to_p = cig_params->mtl_c_to_p;
+ arg.set_cig_params.mtl_p_to_c = cig_params->mtl_p_to_c;
+ arg.set_cig_params.cis_cnt = cig_params->cis_cnt;
+ memcpy(&arg.set_cig_params.cis_params[0], &cig_params->cis_params[0], sizeof(struct ble_iso_cis_params) * cig_params->cis_cnt);
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+
+}
+
+esp_err_t esp_ble_iso_set_cig_parameters_test(struct esp_ble_iso_set_cig_params_test *cig_params_test)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if ((cig_params_test == NULL) || (cig_params_test->cis_cnt > BLE_ISO_CIS_MAX_COUNT)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_SET_CIG_PARAMS_TEST;
+
+ arg.set_cig_params_test.cig_id = cig_params_test->cig_id;
+ arg.set_cig_params_test.sdu_int_c_to_p = cig_params_test->sdu_int_c_to_p;
+ arg.set_cig_params_test.sdu_int_p_to_c = cig_params_test->sdu_int_p_to_c;
+ arg.set_cig_params_test.ft_c_to_p = cig_params_test->ft_c_to_p;
+ arg.set_cig_params_test.ft_p_to_c = cig_params_test->ft_p_to_c;
+ arg.set_cig_params_test.iso_interval = cig_params_test->iso_interval;
+ arg.set_cig_params_test.worse_case_SCA = cig_params_test->worse_case_SCA;
+ arg.set_cig_params_test.packing = cig_params_test->packing;
+ arg.set_cig_params_test.framing = cig_params_test->framing;
+ arg.set_cig_params_test.cis_cnt = cig_params_test->cis_cnt;
+ memcpy(&arg.set_cig_params_test.cis_params_test[0], &cig_params_test->cis_params_test[0], sizeof(struct ble_iso_cis_params_test) * cig_params_test->cis_cnt);
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+
+}
+
+esp_err_t esp_ble_iso_create_cis(struct esp_ble_iso_create_cis_params *creat_cis_params)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if ((creat_cis_params == NULL) || (creat_cis_params->cis_count > BLE_ISO_CIS_MAX_COUNT)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_CREATE_CIS;
+
+ arg.creat_cis_params.cis_count = creat_cis_params->cis_count;
+ for (uint8_t i = 0; i < creat_cis_params->cis_count; i++)
+ {
+ arg.creat_cis_params.cis_hdls[i].cis_hdl = creat_cis_params->cis_hdl_info[i].cis_hdl;
+ arg.creat_cis_params.cis_hdls[i].acl_hdl = creat_cis_params->cis_hdl_info[i].acl_hdl;
+ }
+
+ //memcpy(&arg.creat_cis_params.cis_hdl_info[0], &creat_cis_params->cis_hdl_info[0], creat_cis_params->cis_count * 4);
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_remove_cig(uint8_t cig_id)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_REMOVE_CIG;
+
+ arg.remove_cig_params.cig_id = cig_id;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+esp_err_t esp_ble_iso_accept_cis_request(uint16_t cis_handle)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_ACCEPT_CIS_REQ;
+
+ arg.accept_cis_req_params.cis_handle = cis_handle;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_iso_reject_cis_request(uint16_t cis_handle, uint8_t reason)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_REJECT_CIS_REQ;
+
+ arg.reject_cis_req_params.cis_handle = cis_handle;
+ arg.reject_cis_req_params.reason = reason;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+esp_err_t esp_ble_iso_disconnect_cis(uint16_t cis_handle, uint8_t reason)
+{
+ btc_msg_t msg;
+ btc_ble_iso_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_ISO_BLE;
+ msg.act = BTC_ISO_ACT_DISCON_CIS;
+
+ arg.discon_cis_params.cis_handle = cis_handle;
+ arg.discon_cis_params.reason = reason;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_iso_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
diff --git a/lib/bt/host/bluedroid/api/esp_bluedroid_hci.c b/lib/bt/host/bluedroid/api/esp_bluedroid_hci.c
index 1676ae88..0e6baf11 100644
--- a/lib/bt/host/bluedroid/api/esp_bluedroid_hci.c
+++ b/lib/bt/host/bluedroid/api/esp_bluedroid_hci.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -16,6 +16,10 @@
#define LOG_TAG "HCI_API"
+#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
+#include "ble_log/ble_log_spi_out.h"
+#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
+
static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 };
esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops)
@@ -63,6 +67,9 @@ void hci_host_send_packet(uint8_t *data, uint16_t len)
#if (BT_HCI_LOG_INCLUDED == TRUE)
bt_hci_log_record_hci_data(data[0], &data[1], len - 1);
#endif
+#if (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
+ ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len);
+#endif // (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
#if (BT_CONTROLLER_INCLUDED == TRUE)
esp_vhci_host_send_packet(data, len);
#else /* BT_CONTROLLER_INCLUDED == TRUE */
diff --git a/lib/bt/host/bluedroid/api/esp_bt_device.c b/lib/bt/host/bluedroid/api/esp_bt_device.c
index ae4ff8ec..d3229e5f 100644
--- a/lib/bt/host/bluedroid/api/esp_bt_device.c
+++ b/lib/bt/host/bluedroid/api/esp_bt_device.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -95,6 +95,11 @@ esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_
}
#endif
+esp_err_t esp_bt_config_file_path_get(char *file_path)
+{
+ return btc_config_file_path_get(file_path);
+}
+
esp_err_t esp_bt_config_file_path_update(const char *file_path)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_UNINITIALIZED);
diff --git a/lib/bt/host/bluedroid/api/esp_bt_main.c b/lib/bt/host/bluedroid/api/esp_bt_main.c
index 92576442..adb7a12a 100644
--- a/lib/bt/host/bluedroid/api/esp_bt_main.c
+++ b/lib/bt/host/bluedroid/api/esp_bt_main.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -128,6 +128,21 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg)
return ESP_ERR_INVALID_ARG;
}
+ if (cfg->sc_en) {
+#if (SC_MODE_INCLUDED == FALSE)
+ LOG_ERROR("Secure Connections should not be enabled when target controller is ESP32.\n");
+ LOG_ERROR("It may trigger unresolved bugs in the controller.\n");
+ return ESP_ERR_INVALID_ARG;
+#endif // SC_MODE_INCLUDED
+
+ if (!cfg->ssp_en) {
+ LOG_ERROR("secure simple pairing should be enabled when secure connection host support is enabled\n");
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ LOG_WARN("Please make sure to clear the bond list before enabling the secure connection host support\n");
+ }
+
#if (BT_CONTROLLER_INCLUDED == TRUE)
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
LOG_ERROR("Controller not initialised\n");
@@ -144,7 +159,7 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg)
osi_mem_dbg_init();
#endif
- ret = bluedriod_config_init(cfg);
+ ret = bluedroid_config_init(cfg);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("Bluedroid stack initialize fail, ret:%d", ret);
return ESP_FAIL;
@@ -228,7 +243,7 @@ esp_err_t esp_bluedroid_deinit(void)
btc_deinit();
- bluedriod_config_deinit();
+ bluedroid_config_deinit();
#if (BT_HCI_LOG_INCLUDED == TRUE)
bt_hci_log_deinit();
@@ -238,3 +253,14 @@ esp_err_t esp_bluedroid_deinit(void)
return ESP_OK;
}
+
+#if defined(CONFIG_EXAMPLE_CI_ID) && defined(CONFIG_EXAMPLE_CI_PIPELINE_ID)
+char *esp_bluedroid_get_example_name(void)
+{
+ static char example_name[ESP_BLE_ADV_NAME_LEN_MAX];
+ memset(example_name, 0, sizeof(example_name));
+ sprintf(example_name, "BE%02X_%05X_%02X", CONFIG_EXAMPLE_CI_ID & 0xFF,
+ CONFIG_EXAMPLE_CI_PIPELINE_ID & 0xFFFFF, CONFIG_IDF_FIRMWARE_CHIP_ID & 0xFF);
+ return example_name;
+}
+#endif
diff --git a/lib/bt/host/bluedroid/api/esp_gap_ble_api.c b/lib/bt/host/bluedroid/api/esp_gap_ble_api.c
index 1d2267e8..a4262fd0 100644
--- a/lib/bt/host/bluedroid/api/esp_gap_ble_api.c
+++ b/lib/bt/host/bluedroid/api/esp_gap_ble_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -28,6 +28,7 @@ esp_gap_ble_cb_t esp_ble_gap_get_callback(void)
}
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data)
{
btc_msg_t msg = {0};
@@ -51,8 +52,9 @@ esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy,
btc_gap_ble_arg_deep_free)== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
-
+#if (BLE_42_SCAN_EN == TRUE)
esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params)
{
btc_msg_t msg = {0};
@@ -99,7 +101,9 @@ esp_err_t esp_ble_gap_stop_scanning(void)
msg.act = BTC_GAP_BLE_ACT_STOP_SCAN;
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params)
{
btc_msg_t msg = {0};
@@ -127,19 +131,7 @@ esp_err_t esp_ble_gap_stop_advertising(void)
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
-
-esp_err_t esp_ble_gap_clear_advertising(void)
-{
- btc_msg_t msg;
-
- ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
-
- msg.sig = BTC_SIG_API_CALL;
- msg.pid = BTC_PID_GAP_BLE;
- msg.act = BTC_GAP_BLE_ACT_CLEAR_ADV;
-
- return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
-}
+#endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params)
@@ -295,83 +287,17 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
esp_err_t esp_ble_gap_config_local_icon (uint16_t icon)
{
- esp_err_t ret;
btc_msg_t msg = {0};
btc_ble_gap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
- switch (icon) {
- case ESP_BLE_APPEARANCE_GENERIC_PHONE:
- case ESP_BLE_APPEARANCE_GENERIC_COMPUTER:
- case ESP_BLE_APPEARANCE_GENERIC_REMOTE:
- case ESP_BLE_APPEARANCE_GENERIC_THERMOMETER:
- case ESP_BLE_APPEARANCE_THERMOMETER_EAR:
- case ESP_BLE_APPEARANCE_GENERIC_HEART_RATE:
- case ESP_BLE_APPEARANCE_HEART_RATE_BELT:
- case ESP_BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE:
- case ESP_BLE_APPEARANCE_BLOOD_PRESSURE_ARM:
- case ESP_BLE_APPEARANCE_BLOOD_PRESSURE_WRIST:
- case ESP_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER:
- case ESP_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP:
- case ESP_BLE_APPEARANCE_PULSE_OXIMETER_WRIST:
- case ESP_BLE_APPEARANCE_GENERIC_GLUCOSE:
- case ESP_BLE_APPEARANCE_GENERIC_WEIGHT:
- case ESP_BLE_APPEARANCE_GENERIC_WALKING:
- case ESP_BLE_APPEARANCE_WALKING_IN_SHOE:
- case ESP_BLE_APPEARANCE_WALKING_ON_SHOE:
- case ESP_BLE_APPEARANCE_WALKING_ON_HIP:
- case ESP_BLE_APPEARANCE_GENERIC_WATCH:
- case ESP_BLE_APPEARANCE_SPORTS_WATCH:
- case ESP_BLE_APPEARANCE_GENERIC_EYEGLASSES:
- case ESP_BLE_APPEARANCE_GENERIC_DISPLAY:
- case ESP_BLE_APPEARANCE_GENERIC_MEDIA_PLAYER:
- case ESP_BLE_APPEARANCE_GENERIC_BARCODE_SCANNER:
- case ESP_BLE_APPEARANCE_HID_BARCODE_SCANNER:
- case ESP_BLE_APPEARANCE_GENERIC_HID:
- case ESP_BLE_APPEARANCE_HID_KEYBOARD:
- case ESP_BLE_APPEARANCE_HID_MOUSE:
- case ESP_BLE_APPEARANCE_HID_JOYSTICK:
- case ESP_BLE_APPEARANCE_HID_GAMEPAD:
- case ESP_BLE_APPEARANCE_HID_DIGITIZER_TABLET:
- case ESP_BLE_APPEARANCE_HID_CARD_READER:
- case ESP_BLE_APPEARANCE_HID_DIGITAL_PEN:
- case ESP_BLE_APPEARANCE_UNKNOWN:
- case ESP_BLE_APPEARANCE_GENERIC_CLOCK:
- case ESP_BLE_APPEARANCE_GENERIC_TAG:
- case ESP_BLE_APPEARANCE_GENERIC_KEYRING:
- case ESP_BLE_APPEARANCE_GENERIC_CYCLING:
- case ESP_BLE_APPEARANCE_CYCLING_COMPUTER:
- case ESP_BLE_APPEARANCE_CYCLING_SPEED:
- case ESP_BLE_APPEARANCE_CYCLING_CADENCE:
- case ESP_BLE_APPEARANCE_CYCLING_POWER:
- case ESP_BLE_APPEARANCE_CYCLING_SPEED_CADENCE:
- case ESP_BLE_APPEARANCE_GENERIC_PERSONAL_MOBILITY_DEVICE:
- case ESP_BLE_APPEARANCE_POWERED_WHEELCHAIR:
- case ESP_BLE_APPEARANCE_MOBILITY_SCOOTER:
- case ESP_BLE_APPEARANCE_GENERIC_CONTINUOUS_GLUCOSE_MONITOR:
- case ESP_BLE_APPEARANCE_GENERIC_INSULIN_PUMP:
- case ESP_BLE_APPEARANCE_INSULIN_PUMP_DURABLE_PUMP:
- case ESP_BLE_APPEARANCE_INSULIN_PUMP_PATCH_PUMP:
- case ESP_BLE_APPEARANCE_INSULIN_PEN:
- case ESP_BLE_APPEARANCE_GENERIC_MEDICATION_DELIVERY:
- case ESP_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS:
- case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION:
- case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV:
- case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD:
- case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV:
- case ESP_BLE_APPEARANCE_STANDALONE_SPEAKER:
- msg.sig = BTC_SIG_API_CALL;
- msg.pid = BTC_PID_GAP_BLE;
- msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON;
- arg.cfg_local_icon.icon = icon;
- ret = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
- break;
- default:
- ret = ESP_ERR_INVALID_ARG;
- break;
- }
- return ret;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON;
+ arg.cfg_local_icon.icon = icon;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gap_update_whitelist(bool add_remove, esp_bd_addr_t remote_bda, esp_ble_wl_addr_type_t wl_addr_type)
@@ -504,22 +430,39 @@ esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t
return ESP_OK;
}
-uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length)
+uint8_t *esp_ble_resolve_adv_data_by_type( uint8_t *adv_data, uint16_t adv_data_len, esp_ble_adv_data_type type, uint8_t *length)
{
+ if (length == NULL) {
+ return NULL;
+ }
+
if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) &&
(type != ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE)) {
- LOG_ERROR("the eir type not define, type = %x\n", type);
+ LOG_ERROR("The advertising data type is not defined, type = %x", type);
+ *length = 0;
return NULL;
}
+ if (adv_data_len == 0) {
+ *length = 0;
+ return NULL;
+ }
if (adv_data == NULL) {
- LOG_ERROR("Invalid p_eir data.\n");
+ LOG_ERROR("Invalid advertising data.");
+ *length = 0;
return NULL;
}
- return (BTM_CheckAdvData( adv_data, type, length));
+ return (BTM_CheckAdvData( adv_data, adv_data_len, type, length));
}
+
+uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length)
+{
+ return esp_ble_resolve_adv_data_by_type( adv_data, ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX, (esp_ble_adv_data_type) type, length);
+}
+
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len)
{
btc_msg_t msg = {0};
@@ -541,6 +484,7 @@ esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_l
btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr)
{
@@ -558,6 +502,7 @@ esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+
#if (BLE_42_FEATURE_SUPPORT == TRUE)
esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len)
{
@@ -906,6 +851,26 @@ esp_err_t esp_gap_ble_set_channels(esp_gap_ble_channels channels)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+esp_err_t esp_ble_gap_read_channel_map(esp_bd_addr_t bd_addr)
+{
+ if (!bd_addr) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ btc_ble_gap_args_t arg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_READ_CHANNEL_MAP;
+
+ memcpy(arg.read_channel_map.bd_addr, bd_addr, ESP_BD_ADDR_LEN);
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
esp_err_t esp_gap_ble_set_authorization(esp_bd_addr_t bd_addr, bool authorize)
{
if (!bd_addr) {
@@ -917,7 +882,7 @@ esp_err_t esp_gap_ble_set_authorization(esp_bd_addr_t bd_addr, bool authorize)
return ESP_FAIL;
}
-#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_DTM_TEST_EN == TRUE)
esp_err_t esp_ble_dtm_tx_start(const esp_ble_dtm_tx_t *tx_params)
{
btc_msg_t msg = {0};
@@ -957,9 +922,9 @@ esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
-#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
-#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params)
{
btc_msg_t msg = {0};
@@ -999,8 +964,9 @@ esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
esp_err_t esp_ble_dtm_stop(void)
{
btc_msg_t msg = {0};
@@ -1013,6 +979,7 @@ esp_err_t esp_ble_dtm_stop(void)
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
esp_err_t esp_ble_gap_set_privacy_mode(esp_ble_addr_type_t addr_type, esp_bd_addr_t addr, esp_ble_privacy_mode_t mode)
{
@@ -1092,6 +1059,7 @@ esp_err_t esp_ble_gap_set_preferred_phy(esp_bd_addr_t bd_addr,
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
esp_err_t esp_ble_gap_ext_adv_set_rand_addr(uint8_t instance, esp_bd_addr_t rand_addr)
{
btc_msg_t msg;
@@ -1247,7 +1215,9 @@ esp_err_t esp_ble_gap_ext_adv_set_clear(void)
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
esp_err_t esp_ble_gap_periodic_adv_set_params(uint8_t instance, const esp_ble_gap_periodic_adv_params_t *params)
{
btc_msg_t msg;
@@ -1342,7 +1312,9 @@ esp_err_t esp_ble_gap_periodic_adv_stop(uint8_t instance)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
esp_err_t esp_ble_gap_periodic_adv_create_sync(const esp_ble_gap_periodic_adv_sync_params_t *params)
{
btc_msg_t msg;
@@ -1456,6 +1428,19 @@ esp_err_t esp_ble_gap_periodic_adv_clear_dev(void)
}
+esp_err_t esp_ble_gap_get_periodic_list_size(uint8_t *size)
+{
+ if (size == NULL) {
+ return ESP_FAIL;
+ }
+ btc_get_periodic_list_size(size);
+
+ return ESP_OK;
+}
+
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
esp_err_t esp_ble_gap_set_ext_scan_params(const esp_ble_ext_scan_params_t *params)
{
btc_msg_t msg;
@@ -1507,6 +1492,7 @@ esp_err_t esp_ble_gap_stop_ext_scan(void)
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr,
esp_ble_gap_phy_mask_t phy_mask,
@@ -1697,6 +1683,7 @@ esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, con
}
#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_VENDOR_HCI_EN == TRUE)
esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cmd_param)
{
btc_msg_t msg = {0};
@@ -1724,3 +1711,243 @@ esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cm
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+
+esp_err_t esp_ble_gap_set_vendor_event_mask(esp_ble_vendor_evt_mask_t event_mask)
+{
+ btc_msg_t msg = {0};
+ btc_ble_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_ACT_SET_VENDOR_EVT_MASK;
+ arg.set_vendor_evt_mask.evt_mask = event_mask;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gap_clear_advertising(void)
+{
+ btc_msg_t msg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_ACT_CLEAR_ADV;
+
+ return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gap_set_csa_support(uint8_t csa_select)
+{
+ btc_msg_t msg;
+ btc_ble_gap_args_t arg;
+
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_SET_CSA_SUPPORT;
+
+ arg.set_csa_support.csa_select = csa_select;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // (BLE_VENDOR_HCI_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+esp_err_t esp_ble_gap_enhanced_read_transmit_power_level(uint16_t conn_handle, esp_ble_tx_power_phy_t phy)
+{
+ btc_msg_t msg = {0};
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_ENH_READ_TRANS_POWER_LEVEL;
+ arg.enh_read_trans_pwr_level.conn_handle = conn_handle;
+ arg.enh_read_trans_pwr_level.phy = phy;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gap_read_remote_transmit_power_level(uint16_t conn_handle, esp_ble_tx_power_phy_t phy)
+{
+ btc_msg_t msg = {0};
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_READ_REM_TRANS_POWER_LEVEL;
+ arg.read_rem_trans_pwr_level.conn_handle = conn_handle;
+ arg.read_rem_trans_pwr_level.phy = phy;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gap_set_path_loss_reporting_params(esp_ble_path_loss_rpt_params_t *path_loss_rpt_params)
+{
+ btc_msg_t msg = {0};
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_SET_PATH_LOSS_REPORT_PARAMS;
+ arg.set_path_loss_rpt_params.conn_handle = path_loss_rpt_params->conn_handle;
+ arg.set_path_loss_rpt_params.high_threshold = path_loss_rpt_params->high_threshold;
+ arg.set_path_loss_rpt_params.high_hysteresis = path_loss_rpt_params->high_hysteresis;
+ arg.set_path_loss_rpt_params.low_threshold = path_loss_rpt_params->low_threshold;
+ arg.set_path_loss_rpt_params.low_hysteresis = path_loss_rpt_params->low_hysteresis;
+ arg.set_path_loss_rpt_params.min_time_spent = path_loss_rpt_params->min_time_spent;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gap_set_path_loss_reporting_enable(uint16_t conn_handle, bool enable)
+{
+ btc_msg_t msg = {0};
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_SET_PATH_LOSS_REPORTING_EN;
+ arg.set_path_loss_rpt_en.conn_handle = conn_handle;
+ arg.set_path_loss_rpt_en.enable = enable;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, bool local_enable, bool remote_enable)
+{
+ btc_msg_t msg = {0};
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_SET_TRANS_POWER_REPORTING_EN;
+ arg.set_trans_pwr_rpting_en.conn_handle = conn_handle;
+ arg.set_trans_pwr_rpting_en.local_enable = local_enable;
+ arg.set_trans_pwr_rpting_en.remote_enable = remote_enable;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+esp_err_t esp_ble_gap_set_default_subrate(esp_ble_default_subrate_param_t *default_subrate_params)
+{
+ btc_msg_t msg = {0};
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (!default_subrate_params) {
+ return ESP_ERR_NOT_ALLOWED;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_SET_DEFALT_SUBRATE;
+
+ arg.default_subrate_param.subrate_min = default_subrate_params->subrate_min;
+ arg.default_subrate_param.subrate_max = default_subrate_params->subrate_max;
+ arg.default_subrate_param.max_latency = default_subrate_params->max_latency;
+ arg.default_subrate_param.continuation_number = default_subrate_params->continuation_number;
+ arg.default_subrate_param.supervision_timeout = default_subrate_params->supervision_timeout;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gap_subrate_request(esp_ble_subrate_req_param_t *subrate_req_params)
+{
+ btc_msg_t msg = {0};
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (!subrate_req_params) {
+ return ESP_ERR_NOT_ALLOWED;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_BLE_SUBRATE_REQUEST;
+
+ arg.subrate_req_param.conn_handle = subrate_req_params->conn_handle;
+ arg.subrate_req_param.subrate_min = subrate_req_params->subrate_min;
+ arg.subrate_req_param.subrate_max = subrate_req_params->subrate_max;
+ arg.subrate_req_param.max_latency = subrate_req_params->max_latency;
+ arg.subrate_req_param.continuation_number = subrate_req_params->continuation_number;
+ arg.subrate_req_param.supervision_timeout = subrate_req_params->supervision_timeout;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+esp_err_t esp_ble_gap_set_host_feature(uint16_t bit_num, uint8_t bit_val)
+{
+ btc_msg_t msg;
+ btc_ble_5_gap_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+#if (BLE_FEAT_ISO_60_EN == TRUE)
+ if (bit_num > 0x07BF) {
+ return ESP_ERR_INVALID_ARG;
+ }
+#else
+ if (bit_num > 0xFF) {
+ return ESP_ERR_INVALID_ARG;
+ }
+#endif
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = BTC_GAP_ACT_SET_HOST_FEATURE;
+
+ arg.set_host_feature_params.bit_num = bit_num;
+ arg.set_host_feature_params.bit_val = bit_val;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE)
diff --git a/lib/bt/host/bluedroid/api/esp_gap_bt_api.c b/lib/bt/host/bluedroid/api/esp_gap_bt_api.c
index 5973a663..86619430 100644
--- a/lib/bt/host/bluedroid/api/esp_gap_bt_api.c
+++ b/lib/bt/host/bluedroid/api/esp_gap_bt_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -184,6 +184,7 @@ esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode)
}
switch (mode) {
+ case ESP_BT_SET_COD_RESERVED_2:
case ESP_BT_SET_COD_MAJOR_MINOR:
case ESP_BT_SET_COD_SERVICE_CLASS:
case ESP_BT_CLR_COD_SERVICE_CLASS:
@@ -321,7 +322,7 @@ esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
return ESP_ERR_INVALID_STATE;
}
- if (!(bluedriod_config_get()->get_ssp_enabled())) {
+ if (!(bluedroid_config_get()->get_ssp_enabled())) {
ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__);
return ESP_ERR_NOT_SUPPORTED;
}
@@ -346,7 +347,7 @@ esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint3
return ESP_ERR_INVALID_STATE;
}
- if (!(bluedriod_config_get()->get_ssp_enabled())) {
+ if (!(bluedroid_config_get()->get_ssp_enabled())) {
ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__);
return ESP_ERR_NOT_SUPPORTED;
}
@@ -370,7 +371,7 @@ esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
return ESP_ERR_INVALID_STATE;
}
- if (!(bluedriod_config_get()->get_ssp_enabled())) {
+ if (!(bluedroid_config_get()->get_ssp_enabled())) {
ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__);
return ESP_ERR_NOT_SUPPORTED;
}
@@ -553,4 +554,20 @@ esp_err_t esp_bt_gap_get_device_name(void)
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+esp_err_t esp_bt_gap_get_profile_status(esp_bt_gap_profile_status_t *profile_status)
+{
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ memset(profile_status, 0, sizeof(esp_bt_gap_profile_status_t));
+ btc_gap_bt_status_get(profile_status);
+
+ return ESP_OK;
+}
+
#endif /* #if BTC_GAP_BT_INCLUDED == TRUE */
diff --git a/lib/bt/host/bluedroid/api/esp_gattc_api.c b/lib/bt/host/bluedroid/api/esp_gattc_api.c
index 5f078b28..83481a85 100644
--- a/lib/bt/host/bluedroid/api/esp_gattc_api.c
+++ b/lib/bt/host/bluedroid/api/esp_gattc_api.c
@@ -67,46 +67,134 @@ esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
-#if (BLE_42_FEATURE_SUPPORT == TRUE)
-esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct)
+
+esp_err_t esp_ble_gattc_enh_open(esp_gatt_if_t gattc_if, esp_ble_gatt_creat_conn_params_t *creat_conn_params)
{
btc_msg_t msg = {0};
btc_ble_gattc_args_t arg;
+ const esp_ble_conn_params_t *conn_params;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (!creat_conn_params) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_OPEN;
arg.open.gattc_if = gattc_if;
- memcpy(arg.open.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
- arg.open.remote_addr_type = remote_addr_type;
- arg.open.is_direct = is_direct;
- arg.open.is_aux = false;
+ memcpy(arg.open.remote_bda, creat_conn_params->remote_bda, ESP_BD_ADDR_LEN);
+ arg.open.remote_addr_type = creat_conn_params->remote_addr_type;
+ arg.open.is_direct = creat_conn_params->is_direct;
+ arg.open.is_aux= creat_conn_params->is_aux;
+ arg.open.own_addr_type = creat_conn_params->own_addr_type;
+ arg.open.phy_mask = creat_conn_params->phy_mask;
+
+ // If not aux open, shouldn't set 2M and coded PHY connection params
+ if (!creat_conn_params->is_aux &&
+ ((creat_conn_params->phy_mask & ESP_BLE_PHY_2M_PREF_MASK) ||
+ (creat_conn_params->phy_mask & ESP_BLE_PHY_CODED_PREF_MASK))) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (creat_conn_params->phy_mask & ESP_BLE_PHY_1M_PREF_MASK) {
+ if (!creat_conn_params->phy_1m_conn_params) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ conn_params = creat_conn_params->phy_1m_conn_params;
+ if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
+ ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
+ ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) &&
+ (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) &&
+ ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) &&
+ (conn_params->interval_min <= conn_params->interval_max)) {
+ memcpy(&arg.open.phy_1m_conn_params, conn_params, sizeof(esp_ble_conn_params_t));
+ } else {
+ LOG_ERROR("%s, invalid 1M PHY connection params: min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__,
+ conn_params->interval_min,
+ conn_params->interval_max,
+ conn_params->latency,
+ conn_params->supervision_timeout);
+ return ESP_ERR_INVALID_ARG;
+ }
+ }
+
+ if (creat_conn_params->phy_mask & ESP_BLE_PHY_2M_PREF_MASK) {
+ if (!creat_conn_params->phy_2m_conn_params) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ conn_params = creat_conn_params->phy_2m_conn_params;
+ if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
+ ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
+ ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) &&
+ (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) &&
+ ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) &&
+ (conn_params->interval_min <= conn_params->interval_max)) {
+ memcpy(&arg.open.phy_2m_conn_params, conn_params, sizeof(esp_ble_conn_params_t));
+ } else {
+ LOG_ERROR("%s, invalid 2M PHY connection params: min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__,
+ conn_params->interval_min,
+ conn_params->interval_max,
+ conn_params->latency,
+ conn_params->supervision_timeout);
+ return ESP_ERR_INVALID_ARG;
+ }
+ }
+
+ if (creat_conn_params->phy_mask & ESP_BLE_PHY_CODED_PREF_MASK) {
+ if (!creat_conn_params->phy_coded_conn_params) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ conn_params = creat_conn_params->phy_coded_conn_params;
+ if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
+ ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
+ ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) &&
+ (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) &&
+ ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) &&
+ (conn_params->interval_min <= conn_params->interval_max)) {
+ memcpy(&arg.open.phy_coded_conn_params, conn_params, sizeof(esp_ble_conn_params_t));
+ } else {
+ LOG_ERROR("%s, invalid Coded PHY connection params: min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__,
+ conn_params->interval_min,
+ conn_params->interval_max,
+ conn_params->latency,
+ conn_params->supervision_timeout);
+ return ESP_ERR_INVALID_ARG;
+ }
+ }
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+
+#if (BLE_42_FEATURE_SUPPORT == TRUE)
+esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct)
+{
+ esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
+ memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
+ creat_conn_params.remote_addr_type = remote_addr_type;
+ creat_conn_params.is_direct = is_direct;
+ creat_conn_params.is_aux = false;
+ creat_conn_params.own_addr_type = 0xff; //undefined, will use local value
+ creat_conn_params.phy_mask = 0x0;
+ return esp_ble_gattc_enh_open(gattc_if, &creat_conn_params);
+}
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
#if (BLE_50_FEATURE_SUPPORT == TRUE)
esp_err_t esp_ble_gattc_aux_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct)
{
- btc_msg_t msg;
- btc_ble_gattc_args_t arg;
-
- ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
-
- msg.sig = BTC_SIG_API_CALL;
- msg.pid = BTC_PID_GATTC;
- msg.act = BTC_GATTC_ACT_AUX_OPEN;
- arg.open.gattc_if = gattc_if;
- memcpy(arg.open.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
- arg.open.remote_addr_type = remote_addr_type;
- arg.open.is_direct = is_direct;
- arg.open.is_aux = true;
-
- return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
-
+ esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
+ memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
+ creat_conn_params.remote_addr_type = remote_addr_type;
+ creat_conn_params.is_direct = is_direct;
+ creat_conn_params.is_aux = true;
+ creat_conn_params.own_addr_type = 0xff; //undefined, will use local value
+ creat_conn_params.phy_mask = 0x0;
+ return esp_ble_gattc_enh_open(gattc_if, &creat_conn_params);
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
@@ -363,10 +451,14 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_CHAR;
@@ -400,10 +492,14 @@ esp_err_t esp_ble_gattc_read_by_type (esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
+ if (start_handle == 0 || end_handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_BY_TYPE;
@@ -432,7 +528,7 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
@@ -468,7 +564,7 @@ esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
@@ -504,10 +600,14 @@ esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_CHAR_DESCR;
@@ -537,10 +637,14 @@ esp_err_t esp_ble_gattc_write_char(esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_WRITE_CHAR;
@@ -576,10 +680,14 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
@@ -615,10 +723,14 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_PREPARE_WRITE;
@@ -652,10 +764,14 @@ esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR;
@@ -694,6 +810,10 @@ esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_REG_FOR_NOTIFY;
@@ -712,6 +832,10 @@ esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (handle == 0) {
+ return ESP_GATT_INVALID_HANDLE;
+ }
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_UNREG_FOR_NOTIFY;
diff --git a/lib/bt/host/bluedroid/api/esp_gatts_api.c b/lib/bt/host/bluedroid/api/esp_gatts_api.c
index 66fa5c66..03c81860 100644
--- a/lib/bt/host/bluedroid/api/esp_gatts_api.c
+++ b/lib/bt/host/bluedroid/api/esp_gatts_api.c
@@ -260,6 +260,11 @@ esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle)
esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, uint16_t attr_handle,
uint16_t value_len, uint8_t *value, bool need_confirm)
{
+ if (value_len > ESP_GATT_MAX_ATTR_LEN) {
+ LOG_ERROR("%s, value_len > ESP_GATT_MAX_ATTR_LEN.", __func__);
+ return ESP_ERR_INVALID_SIZE;
+ }
+
btc_msg_t msg = {0};
btc_ble_gatts_args_t arg;
@@ -272,7 +277,7 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id,
}
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
- LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap channel is congest.", __func__);
return ESP_FAIL;
}
diff --git a/lib/bt/host/bluedroid/api/esp_hf_ag_api.c b/lib/bt/host/bluedroid/api/esp_hf_ag_api.c
index 6eb6a6b5..af3ddb4a 100644
--- a/lib/bt/host/bluedroid/api/esp_hf_ag_api.c
+++ b/lib/bt/host/bluedroid/api/esp_hf_ag_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -528,6 +528,23 @@ esp_err_t esp_hf_ag_out_call(esp_bd_addr_t remote_addr, int num_active, int num_
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_hf_ag_get_profile_status(esp_hf_profile_status_t *profile_status)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(profile_status, 0, sizeof(esp_hf_profile_status_t));
+ btc_hf_get_profile_status(profile_status);
+
+ return ESP_OK;
+}
+
+#if (BTM_SCO_HCI_INCLUDED == TRUE)
+
esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
@@ -548,7 +565,73 @@ esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_h
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
-#if (BTM_SCO_HCI_INCLUDED == TRUE)
+esp_err_t esp_hf_ag_register_audio_data_callback(esp_hf_ag_audio_data_cb_t callback)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_HF;
+ msg.act = BTC_HF_REGISTER_AUDIO_DATA_CALLBACK_EVT;
+
+ btc_hf_args_t arg;
+ memset(&arg, 0, sizeof(btc_hf_args_t));
+ arg.reg_audio_data_cb.callback = callback;
+
+ /* Switch to BTC context */
+ bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL);
+ return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_hf_audio_buff_t *esp_hf_ag_audio_buff_alloc(uint16_t size)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return NULL;
+ }
+
+ if (size == 0) {
+ return NULL;
+ }
+
+ uint8_t *p_buf = NULL, *p_data;
+ BTA_AgAudioBuffAlloc(size, &p_buf, &p_data);
+ if (p_buf == NULL) {
+ return NULL;
+ }
+
+ esp_hf_audio_buff_t *audio_buf = (esp_hf_audio_buff_t *)p_buf;
+ audio_buf->buff_size = size;
+ audio_buf->data_len = 0;
+ audio_buf->data = p_data;
+ return audio_buf;
+}
+
+void esp_hf_ag_audio_buff_free(esp_hf_audio_buff_t *audio_buf)
+{
+ if (audio_buf == NULL) {
+ return;
+ }
+ BTA_AgAudioBuffFree((UINT8 *)audio_buf);
+}
+
+esp_err_t esp_hf_ag_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (audio_buf == NULL || audio_buf->data_len == 0) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (btc_hf_ag_audio_data_send(sync_conn_hdl, (uint8_t *)audio_buf, audio_buf->data, audio_buf->data_len)) {
+ return ESP_OK;
+ }
+ return ESP_FAIL;
+}
+
esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
diff --git a/lib/bt/host/bluedroid/api/esp_hf_client_api.c b/lib/bt/host/bluedroid/api/esp_hf_client_api.c
index 9909f442..78347fc9 100644
--- a/lib/bt/host/bluedroid/api/esp_hf_client_api.c
+++ b/lib/bt/host/bluedroid/api/esp_hf_client_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -515,6 +515,21 @@ esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_hf_client_get_profile_status(esp_hf_client_profile_status_t *profile_status)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(profile_status, 0, sizeof(esp_hf_client_profile_status_t));
+ btc_hf_client_get_profile_status(profile_status);
+
+ return ESP_OK;
+}
+
#if (BTM_SCO_HCI_INCLUDED == TRUE)
esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle)
{
@@ -541,6 +556,71 @@ void esp_hf_client_outgoing_data_ready(void)
BTA_HfClientCiData();
}
+esp_err_t esp_hf_client_register_audio_data_callback(esp_hf_client_audio_data_cb_t callback)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_HF_CLIENT;
+ msg.act = BTC_HF_CLIENT_REGISTER_AUDIO_DATA_CALLBACK_EVT;
+
+ btc_hf_client_args_t arg;
+ memset(&arg, 0, sizeof(btc_hf_client_args_t));
+ arg.reg_audio_data_cb.callback = callback;
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_hf_audio_buff_t *esp_hf_client_audio_buff_alloc(uint16_t size)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return NULL;
+ }
+
+ if (size == 0) {
+ return NULL;
+ }
+
+ uint8_t *p_buf = NULL, *p_data;
+ BTA_HfClientAudioBuffAlloc(size, &p_buf, &p_data);
+ if (p_buf == NULL) {
+ return NULL;
+ }
+
+ esp_hf_audio_buff_t *audio_buf = (esp_hf_audio_buff_t *)p_buf;
+ audio_buf->buff_size = size;
+ audio_buf->data_len = 0;
+ audio_buf->data = p_data;
+ return audio_buf;
+}
+
+void esp_hf_client_audio_buff_free(esp_hf_audio_buff_t *audio_buf)
+{
+ if (audio_buf == NULL) {
+ return;
+ }
+ BTA_HfClientAudioBuffFree((UINT8 *)audio_buf);
+}
+
+esp_err_t esp_hf_client_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (audio_buf == NULL || audio_buf->data_len == 0) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ BTA_HfClientAudioDataSend(sync_conn_hdl, (uint8_t *)audio_buf, audio_buf->data, audio_buf->data_len);
+ return ESP_OK;
+}
+
void esp_hf_client_pcm_resample_init(uint32_t src_sps, uint32_t bits, uint32_t channels)
{
BTA_DmPcmInitSamples(src_sps, bits, channels);
diff --git a/lib/bt/host/bluedroid/api/esp_hidd_api.c b/lib/bt/host/bluedroid/api/esp_hidd_api.c
index 2906e7a8..d7c04366 100644
--- a/lib/bt/host/bluedroid/api/esp_hidd_api.c
+++ b/lib/bt/host/bluedroid/api/esp_hidd_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -167,4 +167,17 @@ esp_err_t esp_bt_hid_device_virtual_cable_unplug(void)
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_bt_hid_device_get_profile_status(esp_hidd_profile_status_t *profile_status)
+{
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(profile_status, 0, sizeof(esp_hidd_profile_status_t));
+ btc_hd_get_profile_status(profile_status);
+
+ return ESP_OK;
+}
+
#endif /* defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE */
diff --git a/lib/bt/host/bluedroid/api/esp_hidh_api.c b/lib/bt/host/bluedroid/api/esp_hidh_api.c
index f9959c39..e029ee65 100644
--- a/lib/bt/host/bluedroid/api/esp_hidh_api.c
+++ b/lib/bt/host/bluedroid/api/esp_hidh_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -247,4 +247,17 @@ esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
+esp_err_t esp_bt_hid_host_get_profile_status(esp_hidh_profile_status_t *profile_status)
+{
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(profile_status, 0, sizeof(esp_hidh_profile_status_t));
+ btc_hh_get_profile_status(profile_status);
+
+ return ESP_OK;
+}
+
#endif /* defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE */
diff --git a/lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c b/lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c
index c78d6f8d..54f79396 100644
--- a/lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c
+++ b/lib/bt/host/bluedroid/api/esp_l2cap_bt_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -116,16 +116,39 @@ esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm)
esp_err_t esp_bt_l2cap_vfs_register(void)
{
+ btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
- return btc_l2cap_vfs_register();
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_L2CAP;
+ msg.act = BTC_L2CAP_ACT_VFS_REGISTER;
+
+ return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_l2cap_vfs_unregister(void)
{
+ btc_msg_t msg;
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_L2CAP;
+ msg.act = BTC_L2CAP_ACT_VFS_UNREGISTER;
+
+ return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_bt_l2cap_get_protocol_status(esp_bt_l2cap_protocol_status_t *status)
+{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
- return btc_l2cap_vfs_unregister();
+ memset(status, 0, sizeof(esp_bt_l2cap_protocol_status_t));
+ btc_l2cap_get_protocol_status(status);
+
+ return ESP_OK;
}
#endif ///defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/api/esp_pbac_api.c b/lib/bt/host/bluedroid/api/esp_pbac_api.c
new file mode 100644
index 00000000..3799038f
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/esp_pbac_api.c
@@ -0,0 +1,251 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "esp_err.h"
+#include "esp_bt_main.h"
+#include "esp_pbac_api.h"
+#include "btc/btc_manage.h"
+#include "btc_pba_client.h"
+
+#if BTC_PBA_CLIENT_INCLUDED
+
+esp_err_t esp_pbac_init(void)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ btc_msg_t msg;
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_INIT_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_pbac_deinit(void)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ btc_msg_t msg;
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_DEINIT_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_pbac_register_callback(esp_pbac_callback_t callback)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (callback == NULL) {
+ return ESP_FAIL;
+ }
+
+ btc_profile_cb_set(BTC_PID_PBA_CLIENT, callback);
+ return ESP_OK;
+}
+
+esp_err_t esp_pbac_connect(esp_bd_addr_t bd_addr)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (bd_addr == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_CONNECT_EVT;
+
+ btc_pba_client_args_t args = {0};
+ memcpy(args.connect.bd_addr.address, bd_addr, sizeof(esp_bd_addr_t));
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_pba_client_args_t), NULL, NULL);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_pbac_disconnect(esp_pbac_conn_hdl_t handle)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (handle == ESP_PBAC_INVALID_HANDLE) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_DISCONNECT_EVT;
+
+ btc_pba_client_args_t args = {0};
+ args.disconnect.handle = handle;
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_pba_client_args_t), NULL, NULL);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+
+esp_err_t esp_pbac_pull_phone_book(esp_pbac_conn_hdl_t handle, const char *name, esp_pbac_pull_phone_book_app_param_t *app_param)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (handle == ESP_PBAC_INVALID_HANDLE || name == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_PULL_PHONE_BOOK_EVT;
+
+ btc_pba_client_args_t args = {0};
+ args.pull_phone_book.handle = handle;
+ args.pull_phone_book.name = (char *)name;
+ if (app_param != NULL) {
+ args.pull_phone_book.include_app_param = true;
+ memcpy(&args.pull_phone_book.app_param, app_param, sizeof(esp_pbac_pull_phone_book_app_param_t));
+ }
+ else {
+ args.pull_phone_book.include_app_param = false;
+ }
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_pba_client_args_t), btc_pba_client_args_deep_copy, btc_pba_client_args_deep_free);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_pbac_set_phone_book(esp_pbac_conn_hdl_t handle, esp_pbac_set_phone_book_flags_t flags, const char *name)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ /* since ESP_PBAC_SET_PHONE_BOOK_FLAGS_ROOT is equal to ESP_PBAC_SET_PHONE_BOOK_FLAGS_DOWN, we dont check XXX_DOWN */
+ if (handle == ESP_PBAC_INVALID_HANDLE || (flags != ESP_PBAC_SET_PHONE_BOOK_FLAGS_ROOT && flags != ESP_PBAC_SET_PHONE_BOOK_FLAGS_UP)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_SET_PHONE_BOOK_EVT;
+
+ btc_pba_client_args_t args = {0};
+ args.set_phone_book.handle = handle;
+ args.set_phone_book.flags = flags;
+ /* set phone book name is allowed to be NULL */
+ args.set_phone_book.name = (char *)name;
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_pba_client_args_t), btc_pba_client_args_deep_copy, btc_pba_client_args_deep_free);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_pbac_set_phone_book2(esp_pbac_conn_hdl_t handle, const char *path)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_SET_PHONE_BOOK2_EVT;
+
+ btc_pba_client_args_t args = {0};
+ args.set_phone_book.handle = handle;
+ args.set_phone_book.name = (char *)path;
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_pba_client_args_t), btc_pba_client_args_deep_copy, btc_pba_client_args_deep_free);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_pbac_pull_vcard_listing(esp_pbac_conn_hdl_t handle, const char *name, esp_pbac_pull_vcard_listing_app_param_t *app_param)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (handle == ESP_PBAC_INVALID_HANDLE || name == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_PULL_VCARD_LISTING_EVT;
+
+ btc_pba_client_args_t args = {0};
+ args.pull_vcard_listing.handle = handle;
+ args.pull_vcard_listing.name = (char *)name;
+ if (app_param != NULL) {
+ args.pull_vcard_listing.include_app_param = true;
+ memcpy(&args.pull_vcard_listing.app_param, app_param, sizeof(esp_pbac_pull_vcard_listing_app_param_t));
+ }
+ else {
+ args.pull_vcard_listing.include_app_param = false;
+ }
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_pba_client_args_t), btc_pba_client_args_deep_copy, btc_pba_client_args_deep_free);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_pbac_pull_vcard_entry(esp_pbac_conn_hdl_t handle, const char *name, esp_pbac_pull_vcard_entry_app_param_t *app_param)
+{
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (handle == ESP_PBAC_INVALID_HANDLE || name == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = BTC_PBA_CLIENT_PULL_VCARD_ENTRY_EVT;
+
+ btc_pba_client_args_t args = {0};
+ args.pull_vcard_entry.handle = handle;
+ args.pull_vcard_entry.name = (char *)name;
+ if (app_param != NULL) {
+ args.pull_vcard_entry.include_app_param = true;
+ memcpy(&args.pull_vcard_entry.app_param, app_param, sizeof(esp_pbac_pull_vcard_entry_app_param_t));
+ }
+ else {
+ args.pull_vcard_entry.include_app_param = false;
+ }
+
+ /* Switch to BTC context */
+ bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_pba_client_args_t), btc_pba_client_args_deep_copy, btc_pba_client_args_deep_free);
+ return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+#endif
diff --git a/lib/bt/host/bluedroid/api/esp_sdp_api.c b/lib/bt/host/bluedroid/api/esp_sdp_api.c
index c47c5ba5..41e143a2 100644
--- a/lib/bt/host/bluedroid/api/esp_sdp_api.c
+++ b/lib/bt/host/bluedroid/api/esp_sdp_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,12 +8,61 @@
#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) {
+ if (record->hdr.type < ESP_SDP_TYPE_RAW || record->hdr.type > ESP_SDP_TYPE_DIP_SERVER) {
+ LOG_ERROR("Invalid type!\n");
+ return false;
+ }
+ 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;
+ case ESP_SDP_TYPE_MAP_MAS:
+ if ((record->mas.mas_instance_id >> 8) || (record->mas.supported_message_types >> 8)) {
+ LOG_ERROR("mas_instance_id and supported_message_types are defined as uint8_t in the spec!\n");
+ ret = false;
+ }
+ break;
+ case ESP_SDP_TYPE_PBAP_PSE:
+ if (record->pse.supported_repositories >> 8) {
+ LOG_ERROR("supported_repositories is defined in the spec as uint8_t!\n");
+ ret = false;
+ }
+ break;
+
+ default:
+ break;
+ }
+ if (record->hdr.type != ESP_SDP_TYPE_DIP_SERVER) {
+ 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;
+ }
+ }
+ } 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 +134,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 +147,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 +174,17 @@ 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
+esp_err_t esp_sdp_get_protocol_status(esp_sdp_protocol_status_t *status)
+{
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(status, 0, sizeof(esp_sdp_protocol_status_t));
+ btc_sdp_get_protocol_status(status);
+
+ return ESP_OK;
+}
+
+#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/api/esp_spp_api.c b/lib/bt/host/bluedroid/api/esp_spp_api.c
index fce84be0..5c01aeb2 100644
--- a/lib/bt/host/bluedroid/api/esp_spp_api.c
+++ b/lib/bt/host/bluedroid/api/esp_spp_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -252,4 +252,17 @@ esp_err_t esp_spp_vfs_unregister(void)
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+esp_err_t esp_spp_get_profile_status(esp_spp_profile_status_t *profile_status)
+{
+ ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+ if (profile_status == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ memset(profile_status, 0, sizeof(esp_spp_profile_status_t));
+ btc_spp_get_profile_status(profile_status);
+
+ return ESP_OK;
+}
+
#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h b/lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h
index 7020750c..71d3d597 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_a2dp_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -9,11 +9,16 @@
#include "esp_err.h"
#include "esp_bt_defs.h"
+#include "esp_a2dp_legacy_api.h"
#ifdef __cplusplus
extern "C" {
#endif
+#define ESP_A2D_MAX_SEPS 1 /*!< Maximum number of Stream Endpoint that supported */
+
+typedef uint16_t esp_a2d_conn_hdl_t; /*!< Connection handle, associate with specific device that connected */
+
/**
* @brief Media codec types supported by A2DP.
*/
@@ -31,6 +36,102 @@ typedef uint8_t esp_a2d_mct_t;
typedef uint16_t esp_a2d_psc_t;
/**
+ * @brief A2DP SBC sampling frequency bit mask in CIE
+ */
+#define ESP_A2D_SBC_CIE_SF_16K (0x8) /*!< SBC sampling frequency 16kHz */
+#define ESP_A2D_SBC_CIE_SF_32K (0x4) /*!< SBC sampling frequency 32kHz */
+#define ESP_A2D_SBC_CIE_SF_44K (0x2) /*!< SBC sampling frequency 44.1kHz */
+#define ESP_A2D_SBC_CIE_SF_48K (0x1) /*!< SBC sampling frequency 48kHz */
+
+/**
+ * @brief A2DP SBC channel mode bit mask in CIE
+ */
+#define ESP_A2D_SBC_CIE_CH_MODE_MONO (0x8) /*!< SBC channel mode Mono */
+#define ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL (0x4) /*!< SBC channel mode Dual Channel */
+#define ESP_A2D_SBC_CIE_CH_MODE_STEREO (0x2) /*!< SBC channel mode Stereo */
+#define ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO (0x1) /*!< SBC channel mode Stereo */
+
+/**
+ * @brief A2DP SBC block length bit mask in CIE
+ */
+#define ESP_A2D_SBC_CIE_BLOCK_LEN_4 (0x8) /*!< SBC block length 4 */
+#define ESP_A2D_SBC_CIE_BLOCK_LEN_8 (0x4) /*!< SBC block length 8 */
+#define ESP_A2D_SBC_CIE_BLOCK_LEN_12 (0x2) /*!< SBC block length 12 */
+#define ESP_A2D_SBC_CIE_BLOCK_LEN_16 (0x1) /*!< SBC block length 16 */
+
+/**
+ * @brief A2DP SBC number of subbands bit mask in CIE
+ */
+#define ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 (0x2) /*!< SBC number of subbands 4 */
+#define ESP_A2D_SBC_CIE_NUM_SUBBANDS_8 (0x1) /*!< SBC number of subbands 8 */
+
+/**
+ * @brief A2DP SBC allocation method bit mask in CIE
+ */
+#define ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN (0x2) /*!< SBC allocation method SNR */
+#define ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS (0x1) /*!< SBC allocation method Loudness */
+
+/**
+ * @brief A2DP SBC media codec capabilities information struct
+ */
+typedef struct {
+ uint8_t ch_mode : 4; /*!< Channel mode */
+ uint8_t samp_freq : 4; /*!< Sampling frequency */
+ uint8_t alloc_mthd : 2; /*!< Allocation method */
+ uint8_t num_subbands : 2; /*!< Number of subbands */
+ uint8_t block_len : 4; /*!< Block length */
+ uint8_t min_bitpool; /*!< Minimum bitpool */
+ uint8_t max_bitpool; /*!< Maximum bitpool */
+} __attribute__((packed)) esp_a2d_cie_sbc_t;
+
+/**
+ * @brief A2DP MPEG-1, 2 media codec capabilities information struct (Not supported yet)
+ */
+typedef struct {
+ uint8_t ch_mode : 4; /*!< Channel mode */
+ uint8_t crc : 1; /*!< CRC protection */
+ uint8_t layer : 3; /*!< Layers of MPEG-1,2 Audio */
+ uint8_t samp_freq : 6; /*!< Sampling frequency */
+ uint8_t mpf : 1; /*!< Media payload format */
+ uint8_t rfu : 1; /*!< Reserved */
+ uint8_t bri1 : 7; /*!< Bit rate index part 1 */
+ uint8_t vbr : 1; /*!< Support of VBR */
+ uint8_t bri2; /*!< Bit rate index part 2 */
+} __attribute__((packed)) esp_a2d_cie_m12_t;
+
+/**
+ * @brief A2DP MPEG-2, 4 media codec capabilities information struct (Not supported yet)
+ */
+typedef struct {
+ uint8_t drc : 1; /*!< Support of MPEG-D DRC */
+ uint8_t obj_type : 7; /*!< Object type */
+ uint8_t samp_freq1 : 8; /*!< Sampling frequency part 1 */
+ uint8_t ch : 4; /*!< Channels */
+ uint8_t samp_freq2 : 4; /*!< Sampling frequency part 2 */
+ uint8_t br1 : 7; /*!< Bit rate part 1 */
+ uint8_t vbr : 1; /*!< Support of VBR */
+ uint8_t br2; /*!< Bit rate part 2 */
+ uint8_t br3; /*!< Bit rate part 3 */
+} __attribute__((packed)) esp_a2d_cie_m24_t;
+
+/**
+ * @brief A2DP ATRAC media codec capabilities information struct (Not supported yet)
+ */
+typedef struct {
+ uint8_t rfu1 : 2; /*!< Reserved */
+ uint8_t ch_mode : 3; /*!< Channel mode */
+ uint8_t version : 3; /*!< Version */
+ uint8_t bri1 : 3; /*!< Bit rate index part 1 */
+ uint8_t vbr : 1; /*!< Support of VBR */
+ uint8_t samp_freq : 2; /*!< Sampling frequency */
+ uint8_t rfu2 : 2; /*!< Reserved */
+ uint8_t bri2; /*!< Bit rate index part 2 */
+ uint8_t bri3; /*!< Bit rate index part 3 */
+ uint16_t max_sul; /*!< Maximum SUL */
+ uint8_t rfu3; /*!< Reserved */
+} __attribute__((packed)) esp_a2d_cie_atrac_t;
+
+/**
* @brief A2DP media codec capabilities union
*/
typedef struct {
@@ -40,10 +141,15 @@ typedef struct {
#define ESP_A2D_CIE_LEN_M24 (6)
#define ESP_A2D_CIE_LEN_ATRAC (7)
union {
- uint8_t sbc[ESP_A2D_CIE_LEN_SBC]; /*!< SBC codec capabilities */
- uint8_t m12[ESP_A2D_CIE_LEN_M12]; /*!< MPEG-1,2 audio codec capabilities */
- uint8_t m24[ESP_A2D_CIE_LEN_M24]; /*!< MPEG-2, 4 AAC audio codec capabilities */
- uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC]; /*!< ATRAC family codec capabilities */
+ uint8_t sbc[ESP_A2D_CIE_LEN_SBC] __attribute__((deprecated)); /*!< SBC codec capabilities, deprecated, use sbc_info instead */
+ uint8_t m12[ESP_A2D_CIE_LEN_M12] __attribute__((deprecated)); /*!< MPEG-1,2 audio codec capabilities, deprecated, use m12_info instead */
+ uint8_t m24[ESP_A2D_CIE_LEN_M24] __attribute__((deprecated)); /*!< MPEG-2, 4 AAC audio codec capabilities, deprecated, use m24_info instead */
+ uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC] __attribute__((deprecated)); /*!< ATRAC family codec capabilities, deprecated, use atrac_info instead */
+
+ esp_a2d_cie_sbc_t sbc_info; /*!< SBC codec capabilities */
+ esp_a2d_cie_m12_t m12_info; /*!< MPEG-1,2 audio codec capabilities */
+ esp_a2d_cie_m24_t m24_info; /*!< MPEG-2, 4 AAC audio codec capabilities */
+ esp_a2d_cie_atrac_t atrac_info; /*!< ATRAC family codec capabilities */
} cie; /*!< A2DP codec information element */
} __attribute__((packed)) esp_a2d_mcc_t;
@@ -104,6 +210,16 @@ typedef enum {
} esp_a2d_init_state_t;
/**
+ * @brief Bluetooth A2DP SEP register states
+ */
+typedef enum {
+ ESP_A2D_SEP_REG_SUCCESS = 0, /*!< A2DP stream endpoint register success */
+ ESP_A2D_SEP_REG_FAIL, /*!< A2DP stream endpoint register generic fail */
+ ESP_A2D_SEP_REG_UNSUPPORTED, /*!< A2DP stream endpoint register fail, unsupported codec type or param */
+ ESP_A2D_SEP_REG_INVALID_STATE, /*!< A2DP stream endpoint register fail, invalid state */
+} esp_a2d_sep_reg_state_t;
+
+/**
* @brief Bluetooth A2DP set delay report value states
*/
typedef enum {
@@ -112,14 +228,24 @@ typedef enum {
} esp_a2d_set_delay_value_state_t;
/**
+ * @brief A2DP profile status parameters
+ */
+typedef struct {
+ bool a2d_snk_inited; /*!< A2DP sink initialization */
+ bool a2d_src_inited; /*!< A2DP source initialization */
+ uint8_t conn_num; /*!< Number of connections */
+} esp_a2d_profile_status_t;
+
+/**
* @brief A2DP callback events
*/
typedef enum {
ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */
ESP_A2D_AUDIO_STATE_EVT, /*!< audio stream transmission state changed event */
- ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured, only used for A2DP SINK */
+ ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured */
ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */
ESP_A2D_PROF_STATE_EVT, /*!< indicate a2dp init&deinit complete */
+ ESP_A2D_SEP_REG_STATE_EVT, /*!< indicate a2dp steam endpoint register status */
ESP_A2D_SNK_PSC_CFG_EVT, /*!< protocol service capabilities configured,only used for A2DP SINK */
ESP_A2D_SNK_SET_DELAY_VALUE_EVT, /*!< indicate a2dp sink set delay report value complete, only used for A2DP SINK */
ESP_A2D_SNK_GET_DELAY_VALUE_EVT, /*!< indicate a2dp sink get delay report value complete, only used for A2DP SINK */
@@ -127,6 +253,17 @@ typedef enum {
} esp_a2d_cb_event_t;
/**
+ * @brief A2DP audio buffer
+ */
+typedef struct {
+ uint16_t buff_size; /*!< audio buff size */
+ uint16_t number_frame; /*!< number of encoded frame in this buff */
+ uint32_t timestamp; /*!< timestamp of the first frame */
+ uint16_t data_len; /*!< audio data len */
+ uint8_t *data; /*!< pointer to audio data start */
+} esp_a2d_audio_buff_t; /*!< struct to store audio data */
+
+/**
* @brief A2DP state callback parameters
*/
typedef union {
@@ -136,6 +273,8 @@ typedef union {
struct a2d_conn_stat_param {
esp_a2d_connection_state_t state; /*!< one of values from esp_a2d_connection_state_t */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
+ esp_a2d_conn_hdl_t conn_hdl; /*!< connection handle */
+ uint16_t audio_mtu; /*!< MTU of audio connection */
esp_a2d_disc_rsn_t disc_rsn; /*!< reason of disconnection for "DISCONNECTED" */
} conn_stat; /*!< A2DP connection status */
@@ -144,7 +283,8 @@ typedef union {
*/
struct a2d_audio_stat_param {
esp_a2d_audio_state_t state; /*!< one of the values from esp_a2d_audio_state_t */
- esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
+ esp_bd_addr_t remote_bda; /*!< remote bluetooth device address*/
+ esp_a2d_conn_hdl_t conn_hdl; /*!< connection handle */
} audio_stat; /*!< audio stream playing state */
/**
@@ -152,6 +292,7 @@ typedef union {
*/
struct a2d_audio_cfg_param {
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
+ esp_a2d_conn_hdl_t conn_hdl; /*!< connection handle */
esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */
} audio_cfg; /*!< media codec configuration information */
@@ -171,6 +312,14 @@ typedef union {
} a2d_prof_stat; /*!< status to indicate a2d prof init or deinit */
/**
+ * @brief ESP_A2D_SEP_REG_STATE_EVT
+ */
+ struct a2d_sep_reg_stat_param {
+ uint8_t seid; /*!< the stream endpoint to register */
+ esp_a2d_sep_reg_state_t reg_state; /*!< stream endpoint register state */
+ } a2d_sep_reg_stat; /*!< status to indicate a2d sep register success or not */
+
+ /**
* @brief ESP_A2D_SNK_PSC_CFG_EVT
*/
struct a2d_psc_cfg_param {
@@ -213,25 +362,31 @@ typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *para
/**
* @brief A2DP sink data callback function
*
- * @param[in] buf : pointer to the data received from A2DP source device and is PCM format decoded from SBC decoder;
- * buf references to a static memory block and can be overwritten by upcoming data
+ * @param[in] conn_hdl: connection handle
*
- * @param[in] len : size(in bytes) in buf
+ * @param[in] audio_buf: pointer to the data received from A2DP source device, should be freed by
+ * calling esp_a2d_audio_buff_free
*/
-typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len);
+typedef void (* esp_a2d_sink_audio_data_cb_t)(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf);
/**
- * @brief A2DP source data read callback function
+ * @brief Allocate a audio buffer to store and send audio data, can be used in both sink and source.
*
- * @param[in] buf : buffer to be filled with PCM data stream from higher layer
+ * @param[in] size: buffer size to allocate
*
- * @param[in] len : size(in bytes) of data block to be copied to buf. -1 is an indication to user
- * that data buffer shall be flushed
+ * @return allocated audio buffer, if Bluedroid is not enabled, no memory, or size is
+ * zeros, will return NULL
+ *
+ */
+esp_a2d_audio_buff_t *esp_a2d_audio_buff_alloc(uint16_t size);
+
+/**
+ * @brief Free a audio buffer allocated by esp_a2d_audio_buff_alloc.
*
- * @return size of bytes read successfully, if the argument len is -1, this value is ignored.
+ * @param[in] audio_buf: audio buffer to free
*
*/
-typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len);
+void esp_a2d_audio_buff_free(esp_a2d_audio_buff_t *audio_buf);
/**
* @brief Register application callback function to A2DP module. This function should be called
@@ -248,23 +403,20 @@ typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len);
*/
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback);
-
/**
- * @brief Register A2DP sink data output function; For now the output is PCM data stream decoded
- * from SBC format. This function should be called only after esp_bluedroid_enable()
- * completes successfully, used only by A2DP sink. The callback is invoked in the context
- * of A2DP sink task whose stack size is configurable through menuconfig.
+ * @brief Register A2DP sink audio data output function, the output format is undecoded audio data
+ * frame in esp_a2d_audio_buff_t, user shall call esp_a2d_audio_buff_free to free the buff
+ * when the data is consumed.
*
- * @param[in] callback: A2DP sink data callback function
+ * @param[in] callback: A2DP sink audio data callback function
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
- * - ESP_FAIL: if callback is a NULL function pointer
+ * - ESP_FAIL: others
*
*/
-esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback);
-
+esp_err_t esp_a2d_sink_register_audio_data_callback(esp_a2d_sink_audio_data_cb_t callback);
/**
*
@@ -282,6 +434,23 @@ esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback);
*/
esp_err_t esp_a2d_sink_init(void);
+/**
+ * @brief Register a a2dp sink Stream Endpoint (SEP) with specific codec capability, shall register
+ * SEP after a2dp sink initializing and before a2dp connection establishing. Register the same
+ * SEP index repeatedly will overwrite the old one.
+ *
+ * @param[in] seid: local SEP identifier, start from 0, less than ESP_A2D_MAX_SEPS
+ *
+ * @param[in] mcc: codec capability, currently only supports SBC
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_ERR_INVALID_ARG: invalid parameter
+ * - ESP_FAIL: others
+ *
+ */
+esp_err_t esp_a2d_sink_register_stream_endpoint(uint8_t seid, const esp_a2d_mcc_t *mcc);
/**
*
@@ -297,7 +466,6 @@ esp_err_t esp_a2d_sink_init(void);
*/
esp_err_t esp_a2d_sink_deinit(void);
-
/**
*
* @brief Connect to remote bluetooth A2DP source device. This API must be called after
@@ -313,7 +481,6 @@ esp_err_t esp_a2d_sink_deinit(void);
*/
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda);
-
/**
*
* @brief Disconnect from the remote A2DP source device. This API must be called after
@@ -359,7 +526,6 @@ esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value);
*/
esp_err_t esp_a2d_sink_get_delay_value(void);
-
/**
*
* @brief Media control commands. This API can be used for both A2DP sink and source
@@ -375,6 +541,17 @@ esp_err_t esp_a2d_sink_get_delay_value(void);
*/
esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl);
+/**
+ * @brief This function is used to get the status of A2DP
+ *
+ * @param[out] profile_status - A2DP status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_a2d_get_profile_status(esp_a2d_profile_status_t *profile_status);
+
/**
*
@@ -392,6 +569,23 @@ esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl);
*/
esp_err_t esp_a2d_source_init(void);
+/**
+ * @brief Register a a2dp source Stream Endpoint (SEP) with specific codec capability, shall register
+ * SEP after a2dp source initializing and before a2dp connection establishing. Register the same
+ * SEP index repeatedly will overwrite the old one.
+ *
+ * @param[in] seid: local SEP identifier, start from 0, less than ESP_A2D_MAX_SEPS
+ *
+ * @param[in] mcc: codec capability, currently, only SBC supported
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_ERR_INVALID_ARG: invalid parameter
+ * - ESP_FAIL: others
+ *
+ */
+esp_err_t esp_a2d_source_register_stream_endpoint(uint8_t seid, const esp_a2d_mcc_t *mcc);
/**
*
@@ -407,23 +601,24 @@ esp_err_t esp_a2d_source_init(void);
*/
esp_err_t esp_a2d_source_deinit(void);
-
/**
- * @brief Register A2DP source data input function. For now, the input shoule be PCM data stream.
- * This function should be called only after esp_bluedroid_enable() completes
- * successfully. The callback is invoked in the context of A2DP source task whose
- * stack size is configurable through menuconfig.
+ * @brief Send a audio buff with encoded audio data to sink, the audio data len shall not bigger than
+ * audio connection mtu (retrieved from ESP_A2D_CONNECTION_STATE_EVT). if the return value is
+ * ESP_OK, then the audio buff is consumed, otherwise, audio buff can be reused by user.
+ *
+ * @param[in] conn_hdl: connection handle
*
- * @param[in] callback: A2DP source data callback function
+ * @param[in] audio_buf: encoded audio data
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
- * - ESP_FAIL: if callback is a NULL function pointer
+ * - ESP_ERR_INVALID_ARG: invalid parameter
+ * - ESP_ERR_INVALID_SIZE: data len bigger than mtu
+ * - ESP_FAIL: buffer queue is full, try again later
*
*/
-esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback);
-
+esp_err_t esp_a2d_source_audio_data_send(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf);
/**
*
@@ -440,7 +635,6 @@ esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callbac
*/
esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda);
-
/**
*
* @brief Disconnect from the remote A2DP sink device. This API must be called
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_a2dp_legacy_api.h b/lib/bt/host/bluedroid/api/include/api/esp_a2dp_legacy_api.h
new file mode 100644
index 00000000..2e59d058
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/include/api/esp_a2dp_legacy_api.h
@@ -0,0 +1,77 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/*
+ * Some legacy APIs of A2DP, will be removed in the future
+ */
+
+#pragma once
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief [Deprecated] A2DP sink data callback function
+ *
+ * @param[in] buf : pointer to the data received from A2DP source device and is PCM format decoded from SBC decoder;
+ * buf references to a static memory block and can be overwritten by upcoming data
+ *
+ * @param[in] len : size(in bytes) in buf
+ */
+typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len);
+
+/**
+ * @brief [Deprecated] A2DP source data read callback function
+ *
+ * @param[in] buf : buffer to be filled with PCM data stream from higher layer
+ *
+ * @param[in] len : size(in bytes) of data block to be copied to buf. -1 is an indication to user
+ * that data buffer shall be flushed
+ *
+ * @return size of bytes read successfully, if the argument len is -1, this value is ignored.
+ *
+ */
+typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len);
+
+/**
+ * @brief [Deprecated] Register A2DP sink data output function; For now the output is PCM data stream decoded
+ * from SBC format. This function should be called only after esp_bluedroid_enable()
+ * completes successfully, used only by A2DP sink. The callback is invoked in the context
+ * of A2DP sink task whose stack size is configurable through menuconfig.
+ *
+ * @param[in] callback: A2DP sink data callback function
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_FAIL: if callback is a NULL function pointer
+ *
+ */
+esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback);
+
+/**
+ * @brief [Deprecated] Register A2DP source data input function. For now, the input should be PCM data stream.
+ * This function should be called only after esp_bluedroid_enable() completes
+ * successfully. The callback is invoked in the context of A2DP source task whose
+ * stack size is configurable through menuconfig.
+ *
+ * @param[in] callback: A2DP source data callback function
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_FAIL: if callback is a NULL function pointer
+ *
+ */
+esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h b/lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h
index f226577e..6fae9c1b 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_avrc_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 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,11 @@ 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_PROF_STATE_EVT = 10, /*!< Indicate AVRCP controller init or deinit complete */
} esp_avrc_ct_cb_event_t;
/// AVRC Target callback events
@@ -145,6 +156,7 @@ typedef enum {
ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT = 3, /*!< set absolute volume command from remote device */
ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT = 4, /*!< register notification event */
ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT = 5, /*!< set application attribute value, attribute refer to esp_avrc_ps_attr_ids_t */
+ ESP_AVRC_TG_PROF_STATE_EVT = 6, /*!< Indicate AVRCP target init or deinit complete */
} esp_avrc_tg_cb_event_t;
/// AVRC metadata attribute mask
@@ -155,7 +167,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 +274,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
{
@@ -277,6 +296,27 @@ typedef struct {
uint8_t attr_val; /*!< player application attribute value */
} esp_avrc_set_app_value_param_t;
+/**
+ * @brief AVRCP profile status parameters
+ */
+typedef struct {
+ bool avrc_ct_inited; /*!< AVRCP CT initialization */
+ bool avrc_tg_inited; /*!< AVRCP TG initialization */
+ uint8_t ct_cover_art_conn_num; /*!< Number of cover art client connections */
+} esp_avrc_profile_status_t;
+
+/**
+ * @brief Bluetooth AVRCP Initiation states
+ */
+typedef enum {
+ ESP_AVRC_INIT_SUCCESS = 0, /*!< Indicate init successful */
+ ESP_AVRC_INIT_ALREADY, /*!< Indicate init repeated */
+ ESP_AVRC_INIT_FAIL, /*!< Indicate init fail */
+ ESP_AVRC_DEINIT_SUCCESS, /*!< Indicate deinit successful */
+ ESP_AVRC_DEINIT_ALREADY, /*!< Indicate deinit repeated */
+ ESP_AVRC_DEINIT_FAIL, /*!< Indicate deinit fail */
+} esp_avrc_init_state_t;
+
/// AVRC controller callback parameters
typedef union {
/**
@@ -307,6 +347,15 @@ typedef union {
} meta_rsp; /*!< metadata attributes response */
/**
+ * @brief ESP_AVRC_CT_PLAY_STATUS_RSP_EVT
+ */
+ struct avrc_ct_get_play_status_rsp_param {
+ uint32_t song_length; /*!< total length of the playing song in milliseconds */
+ uint32_t song_position; /*!< current position of the playing song in milliseconds elapsed */
+ esp_avrc_playback_stat_t play_status; /*!< current status of playing */
+ } play_status_rsp; /*!< get play status command response */
+
+ /**
* @brief ESP_AVRC_CT_CHANGE_NOTIFY_EVT
*/
struct avrc_ct_change_notify_param {
@@ -337,6 +386,32 @@ 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 */
+
+ /**
+ * @brief ESP_AVRC_CT_PROF_STATE_EVT
+ */
+ struct avrc_ct_init_stat_param {
+ esp_avrc_init_state_t state; /*!< avrc ct initialization param */
+ } avrc_ct_init_stat; /*!< status to indicate avrcp ct init or deinit */
+
} esp_avrc_ct_cb_param_t;
/// AVRC target callback parameters
@@ -389,6 +464,13 @@ typedef union {
esp_avrc_set_app_value_param_t *p_vals; /*!< point to the id and value of player application attribute */
} set_app_value; /*!< set player application value */
+ /**
+ * @brief ESP_AVRC_TG_PROF_STATE_EVT
+ */
+ struct avrc_tg_init_stat_param {
+ esp_avrc_init_state_t state; /*!< avrc tg initialization param */
+ } avrc_tg_init_stat; /*!< status to indicate avrcp tg init or deinit */
+
} esp_avrc_tg_cb_param_t;
/**
@@ -429,6 +511,7 @@ esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
* @brief Initialize the bluetooth AVRCP controller module, This function should be called
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
* AVRC should be used along with A2DP and AVRC should be initialized before A2DP.
+ * ESP_AVRC_CT_PROF_STATE_EVT with ESP_AVRC_INIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: success
@@ -443,6 +526,7 @@ esp_err_t esp_avrc_ct_init(void);
* @brief De-initialize AVRCP controller module. This function should be called after
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
* AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP.
+ * ESP_AVRC_CT_PROF_STATE_EVT with ESP_AVRC_DEINIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: success
@@ -551,6 +635,18 @@ esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask);
*/
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state);
+/**
+ * @brief Send get play status command to AVRCP target. This function should be called after
+ * ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
+ *
+ * @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_FAIL: others
+ */
+esp_err_t esp_avrc_ct_send_get_play_status_cmd(uint8_t tl);
/**
* @brief Register application callbacks to AVRCP target module. This function should be
@@ -571,6 +667,7 @@ esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback);
* @brief Initialize the bluetooth AVRCP target module, This function should be called
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
* AVRC should be used along with A2DP and AVRC should be initialized before A2DP.
+ * ESP_AVRC_TG_PROF_STATE_EVT with ESP_AVRC_INIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: success
@@ -585,6 +682,7 @@ esp_err_t esp_avrc_tg_init(void);
* @brief De-initialize AVRCP target module. This function should be called after
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
* AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP.
+ * ESP_AVRC_TG_PROF_STATE_EVT with ESP_AVRC_DEINIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: success
@@ -656,11 +754,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 +827,102 @@ 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);
+
+/**
+ * @brief This function is used to get the status of AVRCP
+ *
+ * @param[out] profile_status - AVRCP status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_avrc_get_profile_status(esp_avrc_profile_status_t *profile_status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h b/lib/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h
new file mode 100644
index 00000000..80dc5b15
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h
@@ -0,0 +1,379 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __ESP_BLE_CTE_API_H__
+#define __ESP_BLE_CTE_API_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// BLE CTE callback event type
+typedef enum {
+ ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT = 0, /*!< When CTE set connectionless transmit parameters complete, the event comes */
+ ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT, /*!< When CTE set connectionless transmit enable complete, the event comes */
+ ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT, /*!< When CTE set connectionless IQ sampling enable complete, the event comes */
+ ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT, /*!< When CTE set connection receive parameters complete, the event comes */
+ ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT, /*!< When CTE set connection transmit parameters complete, the event comes */
+ ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT, /*!< When CTE set connection CTE request enable complete, the event comes */
+ ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT, /*!< When CTE set connection CTE response enable complete, the event comes */
+ ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT, /*!< When CTE read antenna information complete, the event comes */
+ ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT, /*!< When the device receives CTE connectionless IQ information, the event comes */
+ ESP_BLE_CTE_CONN_IQ_REPORT_EVT, /*!< When the device receives CTE connection IQ information , the event comes */
+ ESP_BLE_CTE_REQUEST_FAILED_EVT, /*!< When CTE request progress failed , the event comes */
+ ESP_BLE_CTE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */
+} esp_ble_cte_cb_event_t;
+
+#define ESP_BLE_CTE_SAMPLING_DISABLE (0x00)
+#define ESP_BLE_CTE_SAMPLING_ENABLE (0x01)
+
+#define ESP_BLE_CTE_ADV_WITH_CTE_DISABLE (0x00)
+#define ESP_BLE_CTE_ADV_WITH_CTE_ENABLE (0x01)
+
+// Constant Tone Extension length in 8 µs units
+#define ESP_BLE_CTE_MIN_CTE_LENGTH (0x02)
+#define ESP_BLE_CTE_MAX_CTE_LENGTH (0x14)
+
+#define ESP_BLE_CTE_TYPE_AOA (0x00) /*!< AoA Constant Tone Extension */
+#define ESP_BLE_CTE_TYPE_AOD_WITH_1US (0x01) /*!< AoD Constant Tone Extension with 1 µs slots */
+#define ESP_BLE_CTE_TYPE_AOD_WITH_2US (0x02) /*!< AoD Constant Tone Extension with 2 µs slots */
+typedef uint8_t esp_ble_cte_type_t;
+
+#define ESP_BLE_CTE_MIN_CTE_COUNT (0x01)
+#define ESP_BLE_CTE_MAX_CTE_COUNT (0x10)
+
+#define ESP_BLE_CTE_MIN_SWITCHING_PATTERN_LENGTH (0x02)
+#define ESP_BLE_CTE_MAX_SWITCHING_PATTERN_LENGTH (0x4B)
+
+#define ESP_BLE_CTE_SLOT_DURATION_1US (0x01)
+#define ESP_BLE_CTE_SLOT_DURATION_2US (0x02)
+typedef uint8_t esp_ble_cte_slot_dur_type_t;
+
+#define ESP_BLE_CTE_MIN_SAMPLED_CTES (0x00)
+#define ESP_BLE_CTE_MAX_SAMPLED_CTES (0x10)
+
+#define ESP_BLE_CTE_TYPES_AOA_RESPONSE (0x01)
+#define ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_1US (0x02)
+#define ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_2US (0x04)
+#define ESP_BLE_CTE_TYPES_ALL (ESP_BLE_CTE_TYPES_AOA_RESPONSE | ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_1US | ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_2US)
+typedef uint8_t esp_ble_cte_conn_cte_types_t;
+
+#define ESP_BLE_CTE_REQUEST_FOR_CONNECTION_DISABLE (0x00)
+#define ESP_BLE_CTE_REQUEST_FOR_CONNECTION_ENABLE (0x01)
+
+#define ESP_BLE_CTE_MIN_REQUESTED_CTE_LENGTH (0x02)
+#define ESP_BLE_CTE_MAX_REQUESTED_CTE_LENGTH (0x14)
+
+#define ESP_BLE_CTE_RESPONSE_FOR_CONNECTION_DISABLE (0x00)
+#define ESP_BLE_CTE_RESPONSE_FOR_CONNECTION_ENABLE (0x01)
+
+typedef struct {
+ uint8_t adv_handle; /*!< Used to identify an advertising set */
+ uint8_t cte_len; /*!< Constant Tone Extension length in 8 µs units, range: 0x02 to 0x14 */
+ esp_ble_cte_type_t cte_type; /*!< AoA or AoD Constant Tone Extension */
+ uint8_t cte_count; /*!< The number of Constant Tone Extensions to transmit in each periodic advertising interval, range: 0x01 to 0x10 */
+ uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */
+ uint8_t *antenna_ids; /*!< Antenna ID in the pattern */
+} __attribute__((packed)) esp_ble_cte_connless_trans_params_t;
+
+typedef struct {
+ uint8_t adv_handle; /*!< Identifier for the advertising set in which Constant Tone Extension is being enabled or disabled */
+ uint8_t cte_enable; /*!< Advertising with Constant Tone Extension is enabled or disabled */
+} __attribute__((packed)) esp_ble_cte_trans_enable_params_t;
+
+typedef struct {
+ uint16_t sync_handle; /*!< Identifier for the periodic advertising train */
+ uint8_t sampling_en; /*!< Enable or disable connectionless IQ sampling */
+ esp_ble_cte_slot_dur_type_t slot_dur; /*!< Switching and sampling slots, 1 us or 2 us */
+ uint8_t max_sampled_ctes; /*!< The maximum number of CTE to sample and report in each periodic advertising interval, range: 0x00 - 0x10 */
+ uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */
+ uint8_t *antenna_ids; /*!< Antenna ID in the pattern */
+} __attribute__((packed)) esp_ble_cte_iq_sampling_params_t;
+
+typedef struct {
+ uint16_t conn_handle; /*!< Connection_Handle */
+ uint8_t sampling_en; /*!< Enable or disable connection IQ sampling */
+ esp_ble_cte_slot_dur_type_t slot_dur; /*!< Switching and sampling slots, 1 us or 2 us */
+ uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */
+ uint8_t *antenna_ids; /*!< Antenna ID in the pattern */
+} __attribute__((packed)) esp_ble_cte_recv_params_params_t;
+
+typedef struct {
+ uint16_t conn_handle; /*!< Connection_Handle */
+ esp_ble_cte_conn_cte_types_t cte_types; /*!< Allow AoA or AoD Constant Tone Extension Response */
+ uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */
+ uint8_t *antenna_ids; /*!< Antenna ID in the pattern */
+} __attribute__((packed)) esp_ble_cte_conn_trans_params_t;
+
+typedef struct {
+ uint16_t conn_handle; /*!< Connection_Handle */
+ uint8_t enable; /*!< Enable or disable Constant Tone Extension Request for the connection */
+ uint16_t cte_req_interval; /*!< Requested interval for initiating the CTE Request procedure in number of underlying connection events, range: 0x0000 - 0xFFFF */
+ uint8_t req_cte_len; /*!< Minimum length of the Constant Tone Extension being requested in 8 µs units, range: 0x02 - 0x14 */
+ esp_ble_cte_type_t req_cte_Type; /*!< AoA or AoD Constant Tone Extension, range: 0x00 - 0x02 */
+} __attribute__((packed)) esp_ble_cte_req_en_params_t;
+
+typedef struct {
+ uint16_t conn_handle; /*!< Connection_Handle */
+ uint8_t enable; /*!< Enable or disable Constant Tone Extension Response for the connection */
+} __attribute__((packed)) esp_ble_cte_rsp_en_params_t;
+
+/**
+ * @brief CTE callback parameters union
+ */
+typedef union {
+ /**
+ * @brief ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT
+ */
+ struct ble_set_trans_params_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate setting transmit parameters status, status = (controller error code | 0x100) if status is not equal to 0 */
+ } set_trans_params_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT
+ */
+ struct ble_set_trans_enable_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate setting transmit enable status, status = (controller error code | 0x100) if status is not equal to 0 */
+ } set_trans_enable_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT
+ */
+ struct ble_set_iq_sampling_en_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate setting IQ sampling enable status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t sync_handle; /*!< Sync_Handle identifying the periodic advertising */
+ } iq_sampling_enable_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT
+ */
+ struct ble_set_conn_recv_params_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate setting received parameters status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The connection identifier */
+ } conn_recv_params_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT
+ */
+ struct ble_set_conn_trans_params_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate setting connection transmit parameters status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The connection identifier */
+ } conn_trans_params_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT
+ */
+ struct ble_set_conn_req_en_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate setting connection request enable status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The connection identifier */
+ } conn_req_en_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT
+ */
+ struct ble_set_conn_rsp_en_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate setting connection response enable status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The connection identifier */
+ } conn_rsp_en_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT
+ */
+ struct ble_read_ant_infor_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate reading antenna information status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint8_t supported_switching_sampling_rates; /*!< bit 0: 1 µs switching supported for AoD transmission
+ bit 1: 1 µs sampling supported for AoD reception
+ bit 2: 1 µs switching and sampling supported for AoA reception */
+ uint8_t num_antennae; /*!< The number of antennae supported by the Controller */
+ uint8_t max_switching_pattern_len; /*!< Maximum length of antenna switching pattern supported by the Controller */
+ uint8_t max_cte_len; /*!< Maximum length of a transmitted Constant Tone Extension supported in 8 µs units */
+ } read_ant_infor_cmpl; /*!< Event parameter of ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT
+ */
+ struct ble_cte_connless_iq_rpt_evt_param {
+ uint16_t sync_handle; /*!< Sync_Handle identifying the periodic advertising train */
+ uint8_t channel_idx; /*!< The index of the channel on which the packet was received */
+ int16_t rssi; /*!< RSSI of the packet, Range: -1270 to +200, Units: 0.1 dBm */
+ uint8_t rssi_ant_id; /*!< Antenna ID */
+ uint8_t cte_type; /*!< The type of Constant Tone Extension, range: 0x00 - 0x02 */
+ uint8_t slot_dur; /*!< Switching and sampling slots, 1 us or 2us, range: 0x01 - 0x02 */
+ uint8_t pkt_status; /*!< indicates whether the received packet had a valid CRC, range: 0x00 - 0x02 and 0xFF */
+ uint16_t periodic_evt_counter; /*!< The value of paEventCounter for the reported AUX_SYNC_IND PDU */
+ uint8_t sample_count; /*!< Total number of sample pairs, range: 0x00 and 0x09 - 0x52*/
+ uint8_t *i_sample; /*!< I sample for the reported packet. No valid sample available if value is 0x80 */
+ uint8_t *q_sample; /*!< Q sample for the reported packet. No valid sample available if value is 0x80 */
+ } connless_iq_rpt; /*!< Event parameter of ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_CONN_IQ_REPORT_EVT
+ */
+ struct ble_cte_conn_iq_rpt_evt_param {
+ uint16_t conn_handle; /*!< Connection_Handle */
+ uint8_t rx_phy; /*!< The receiver PHY for the connection, range: 0x01 - 0x02 */
+ uint8_t data_channel_idx; /*!< The index of the data channel on which the Data Physical Channel PDU was received, range: 0x00 - 0x24 */
+ int16_t rssi; /*!< RSSI of the packet, range: -1270 - +200, units: 0.1 dBm */
+ uint8_t rssi_ant_id; /*!< ID of the antenna on which the RSSI is measured */
+ uint8_t cte_type; /*!< AoA or AoD Constant Tone Extension, range: 0x00 - 0x02 */
+ uint8_t slot_dur; /*!< Switching and sampling slots, range: 0x01 - 0x02 */
+ uint8_t pkt_status; /*!< indicates whether the received packet had a valid CRC, range: 0x00 - 0x02 and 0xFF */
+ uint16_t conn_evt_counter; /*!< The value of connEventCounter for the reported PDU */
+ uint8_t sample_count; /*!< Total number of sample pairs, range: 0x00 and 0x09 - 0x52 */
+ uint8_t *i_sample; /*!< I sample for the reported PDU. No valid sample available if value is 0x80 */
+ uint8_t *q_sample; /*!< Q sample for the reported PDU,. No valid sample available if value is 0x80 */
+ } conn_iq_rpt; /*!< Event parameter of ESP_BLE_CTE_CONN_IQ_REPORT_EVT */
+
+ /**
+ * @brief ESP_BLE_CTE_REQUEST_FAILED_EVT
+ */
+ struct ble_cte_req_failed_evt_param{
+ uint8_t reason; /*!< value: 0x00, LL_CTE_RSP PDU received successfully but without a Constant Tone Extension field;
+ value: 0x01 to 0xFF, Peer rejected the request, see [Vol 1] Part F controller error codes and descriptions */
+ uint16_t conn_handle; /*!< Connection_Handle */
+ } req_failed_evt; /*!< Event parameter of ESP_BLE_CTE_REQUEST_FAILED_EVT */
+
+} esp_ble_cte_cb_param_t;
+
+/**
+ * @brief CTE callback function type
+ * @param event : Event type
+ * @param param : Point to callback parameter, currently is union type
+ */
+typedef void (* esp_ble_cte_cb_t)(esp_ble_cte_cb_event_t event, esp_ble_cte_cb_param_t *param);
+
+/**
+ * @brief This function is called to occur cte event
+ *
+ * @param[in] callback: callback function
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_register_callback(esp_ble_cte_cb_t callback);
+
+/**
+ * @brief This function is called to get the current cte callback
+ *
+ * @return
+ * - esp_ble_cte_cb_t : callback function
+ *
+ */
+esp_ble_cte_cb_t esp_ble_cte_get_callback(void);
+
+/**
+ * @brief This function is called to set parameters for the transmission of CTE in the periodic advertising.
+ *
+ * @param[in] cte_trans_params: pointer to User defined cte_trans_params data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_set_connectionless_trans_params(esp_ble_cte_connless_trans_params_t *cte_trans_params);
+
+/**
+ * @brief This function is called to request that the Controller enables or disables the use of CTE in the periodic advertising.
+ *
+ * @param[in] cte_trans_enable: pointer to User defined cte_trans_enable data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_set_connectionless_trans_enable(esp_ble_cte_trans_enable_params_t *cte_trans_enable);
+
+/**
+ * @brief This function is called to request that the Controller enables or disables capturing IQ samples from the CTE
+* of periodic advertising packets.
+ *
+ * @param[in] iq_sampling_en: pointer to User defined iq_sampling_en data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_set_connectionless_iq_sampling_enable(esp_ble_cte_iq_sampling_params_t *iq_sampling_en);
+
+/**
+ * @brief This function is called to enable or disable sampling received CTE fields on the connection.
+ *
+ * @param[in] cte_recv_params: pointer to User defined cte_recv_params data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_set_connection_receive_params(esp_ble_cte_recv_params_params_t *cte_recv_params);
+
+/**
+ * @brief This function is called to set the parameters used for transmitting CTE requested by the peer
+ * device on the connection.
+ *
+ * @param[in] cte_conn_trans_params: pointer to User defined cte_conn_trans_params data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_set_connection_transmit_params(esp_ble_cte_conn_trans_params_t *cte_conn_trans_params);
+
+/**
+ * @brief This function is called to request the Controller to start or stop initiating the CTE Request
+ * procedure on a connection.
+ *
+ * @param[in] cte_conn_req_en: pointer to User defined cte_conn_req_en data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_connection_cte_request_enable(esp_ble_cte_req_en_params_t *cte_conn_req_en);
+
+/**
+ * @brief This function is called to request the Controller to respond to LL_CTE_REQ PDUs with
+ * LL_CTE_RSP PDUs on the specified connection.
+ *
+ * @param[in] cte_conn_rsp_en: pointer to User defined cte_conn_rsp_en data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_connection_cte_response_enable(esp_ble_cte_rsp_en_params_t *cte_conn_rsp_en);
+
+/**
+ * @brief This function is called to read the parameters of a transmitted CTE supported by the Controller.
+ *
+ * @param[in] none.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_cte_read_antenna_information(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ESP_BLE_CTE_API_H__ */
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h b/lib/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h
new file mode 100644
index 00000000..5531393e
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h
@@ -0,0 +1,660 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __ESP_BLE_ISO_API_H__
+#define __ESP_BLE_ISO_API_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// ISO BLE callback event type
+typedef enum {
+ ESP_BLE_ISO_BIG_CREATE_CMPL_EVT = 0, /*!< When BIG create complete, the event comes */
+ ESP_BLE_ISO_BIG_TERMINATE_CMPL_EVT, /*!< When BIG terminate complete, the event comes */
+ ESP_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT, /*!< When BIG sync established, the event comes */
+ ESP_BLE_ISO_BIG_SYNC_LOST_EVT, /*!< When BIG sync lost, the event comes */
+ ESP_BLE_ISO_BIG_SYNC_TERMINATE_CMPL_EVT, /*!< When BIG sync terminate complete, the event comes */
+ ESP_BLE_ISO_BIGINFO_ADV_REPORT_EVT, /*!< When receiving an Advertising PDU that contained a BIGInfo field, the event comes */
+ ESP_BLE_ISO_ISO_DATA_PATH_UPDATE_EVT, /*!< When ISO data path update complete, the event comes */
+ ESP_BLE_ISO_READ_ISO_TX_SYNC_CMPL_EVT, /*!< When reading tx sync complete, the event comes */
+ ESP_BLE_ISO_READ_LINK_QUALITY_CMPL_EVT, /*!< When reading link quality complete, the event comes */
+ ESP_BLE_ISO_SET_CIG_PARAMS_CMPL_EVT, /*!< When CIG parameters set complete, the event comes */
+ ESP_BLE_ISO_CREATE_CIS_CMPL_EVT, /*!< When CIS create complete, the event comes */
+ ESP_BLE_ISO_REMOVE_CIG_CMPL_EVT, /*!< When CIG remove complete, the event comes */
+ ESP_BLE_ISO_CIS_REQUEST_EVT, /*!< When Receiving CIS request event, the event comes */
+ ESP_BLE_ISO_ACCEPT_CIS_REQ_CMPL_EVT, /*!< When CIS request event accept complete, the event comes */
+ ESP_BLE_ISO_REJECT_CIS_REQ_CMPL_EVT, /*!< When CIS request event reject complete, the event comes */
+ ESP_BLE_ISO_CIS_ESTABLISHED_EVT, /*!< When CIS is established, the event comes */
+ ESP_BLE_ISO_CIS_DISCONNECTED_EVT, /*!< When CIS is disconnected, the event comes */
+ ESP_BLE_ISO_EVT_MAX, /*!< when maximum advertising event complete, the event comes */
+} esp_ble_iso_cb_event_t;
+
+typedef enum {
+ ESP_BLE_ISO_DATA_PATH_UNKNOWN = 0,
+ ESP_BLE_ISO_DATA_PATH_SETUP = 1,
+ ESP_BLE_ISO_DATA_PATH_REMOVE = 2,
+ ESP_BLE_ISO_DATA_PATH_MAX,
+} ESP_BLE_ISO_DATA_PATH_UPDATE_TYPE;
+
+#define ESP_BLE_ISO_DATA_PATH_DIR_INPUT (0x00)
+#define ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT (0x01)
+
+#define ESP_BLE_ISO_DATA_PATH_DIR_INPUT_BIT_MASK (1 << 0)
+#define ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT_BIT_MASK (1 << 1)
+#define ESP_BLE_ISO_DATA_PATH_DIR_ALL_BIT_MASK (ESP_BLE_ISO_DATA_PATH_DIR_INPUT_BIT_MASK | ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT_BIT_MASK)
+
+#define ESP_BLE_MAX_BIS_NUM (31)
+#define ESP_BLE_MAX_CIS_NUM (31)
+
+#define BLE_ISO_SDU_INT_MIN (0x0000FF)
+#define BLE_ISO_SDU_INT_MAX (0x0FFFFF)
+
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_500_PPM (0x00)
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_250_PPM (0x01)
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_150_PPM (0x02)
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_100_PPM (0x03)
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_75_PPM (0x04)
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_50_PPM (0x05)
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_30_PPM (0x06)
+#define BLE_ISO_WORST_CASE_SCA_LEVEL_20_PPM (0x07)
+
+#define BLE_ISO_PACKING_SEQUENTIAL (0x00)
+#define BLE_ISO_PACKING_INTERLEAVED (0x00)
+
+#define BLE_ISO_FRAMING_UNFRAMED_PDU (0x00)
+#define BLE_ISO_FRAMING_FRAMED_PDU_SEGMENTABLE_MODE (0x01)
+#define BLE_ISO_FRAMING_FRAMED_PDU_UNSEGMENTABLE_MODE (0x02)
+
+#define BLE_ISO_MAX_TRANSPORT_LATENCY_MIN (0x0005)
+#define BLE_ISO_MAX_TRANSPORT_LATENCY_MAX (0x0FA0)
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+typedef struct {
+ uint8_t big_handle; /*!< Used to identify the BIG, value 0x00 to 0xEF */
+ uint8_t adv_handle; /*!< Used to identify the periodic advertising train, value 0x00 to 0xEF */
+ uint8_t num_bis; /*!< Total number of BISes in the BIG, value 0x01 to 0x1F */
+ uint32_t sdu_interval; /*!< The interval, in microseconds, of periodic SDUs, value 0x0000FF to 0x0FFFFF*/
+ uint16_t max_sdu; /*!< Maximum size of an SDU, in octets, value 0x0001 to 0x0FFF */
+ uint16_t max_transport_latency; /*!< Maximum transport latency, in milliseconds, value 0x0005 to 0x0FA0 */
+ uint8_t rtn; /*!< The number of times that every BIS Data PDU should be retransmitted, value 0x00 to 0x1E */
+ uint8_t phy; /*!< The transmitter PHY of packets, value bit[0, 2] */
+ uint8_t packing; /*!< The preferred method of arranging subevents of multiple BISes, value 0x00 to 0x01 */
+ uint8_t framing; /*!< The format of the BIS Data PDUs and the mode of framed PDUs that the Controller shall use on the specified BIG, value 0x00 to 0x02 */
+ uint8_t encryption; /*!< The encryption mode of the BISes in the BIG, value 0x00 to 0x01 */
+ uint8_t broadcast_code[16]; /*!< The code used to derive the session key that is used to encrypt and decrypt BIS payloads */
+} esp_ble_iso_big_creat_params_t;
+
+typedef struct {
+ uint8_t big_handle; /*!< Used to identify the BIG, value 0x00 to 0xEF */
+ uint8_t adv_handle; /*!< Used to identify the periodic advertising train, value 0x00 to 0xEF */
+ uint8_t num_bis; /*!< Total number of BISes in the BIG, value 0x01 to 0x1F */
+ uint32_t sdu_interval; /*!< The interval, in microseconds, of periodic SDUs, value 0x0000FF to 0x0FFFFF*/
+ uint16_t iso_interval; /*!< the time between two consecutive BIG anchor points, Range: 0x0004 to 0x0C80, Time = N × 1.25 ms */
+ uint8_t nse; /*!< The total number of subevents in each interval of each BIS in the BIG, value 0x01 to 0x1F */
+ uint16_t max_sdu; /*!< Maximum size, in octets, of an SDU */
+ uint16_t max_pdu; /*!< Maximum size, in octets, of payload, value 0x0001 to 0x00FB */
+ uint8_t phy; /*!< The transmitter PHY of packets */
+ uint8_t packing; /*!< The preferred method of arranging subevents of multiple BISes, value 0x00 to 0x01 */
+ uint8_t framing; /*!< The format of the BIS Data PDUs and the mode of framed PDUs that the Controller shall use on the specified BIG, value 0x00 to 0x02 */
+ uint8_t bn; /*!< The number of new payloads in each interval for each BIS, value 0x01 to 0x07 */
+ uint8_t irc; /*!< The number of times the scheduled payloads are transmitted in a given event, value 0x01 to 0x0F */
+ uint8_t pto; /*!< Offset used for pre-transmissions, value 0x00 to 0x0F */
+ uint8_t encryption; /*!< The encryption mode of the BISes in the BIG, value 0x00 to 0x01 */
+ uint8_t broadcast_code[16]; /*!< The code used to derive the session key that is used to encrypt and decrypt BIS payloads */
+} esp_ble_iso_big_creat_test_params_t;
+
+#endif //#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+typedef struct {
+ uint8_t big_handle; /*!< Used to identify the BIG, value 0x00 to 0xEF */
+ uint16_t sync_handle; /*!< Identifier of the periodic advertising train, value 0x0000 to 0x0EFF*/
+ uint8_t encryption; /*!< Broadcast_Code is valid or invalid, value 0x00 to 0x01 */
+ uint8_t bc_code[16]; /*!< 128-bit code used for deriving the session key for decrypting payloads of BISes in the BIG */
+ uint8_t mse; /*!< Maximum number of subevents that should be used to receive data payloads in each BIS event, value 0x00 to 0x1F */
+ uint16_t big_sync_timeout; /*!< Synchronization timeout for the BIG, Range: 0x000A to 0x4000, Time = N × 10 ms, Time Range: 100 ms to 163.84 s*/
+ uint8_t num_bis; /*!< Total number of BISes to synchronize, value 0x01 to 0x1F */
+ uint8_t bis[ESP_BLE_MAX_BIS_NUM]; /*!< Index of a BIS, value 0x01 to 0x1F */
+} esp_ble_iso_big_sync_creat_params_t;
+
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+typedef struct {
+ uint16_t iso_handle; /*!< Connection handle of the CIS or BIS*/
+ uint8_t data_path_dir; /*!< The direction for which the data path is being configured, value 0x00 to 0x01 */
+ uint8_t data_path_id; /*!< The data transport path used, value 0x00 to 0xFE */
+ uint8_t coding_fmt; /*!< See Assigned Numbers for Coding Format */
+ uint16_t company_id; /*!< Company ID, see Assigned Numbers for Company Identifier. Shall be ignored if coding_fmt is not 0xFF*/
+ uint16_t vs_codec_id; /*!< Vendor-defined codec ID, Shall be ignored if coding_fmt is not 0xFF */
+ uint32_t controller_delay; /*!< Controller delay in microseconds, range: 0x000000 to 0x3D0900, time range: 0 s to 4 s*/
+ uint8_t codec_cfg_len; /*!< Length of codec configuration */
+ uint8_t *codec_cfg; /*!< Codec-specific configuration data */
+} esp_ble_iso_set_data_path_params_t;
+
+typedef struct {
+ uint16_t iso_handle; /*!< Connection handle of the CIS or BIS. Range: 0x0000 to 0x0EFF */
+ uint8_t data_path_dir; /*!< which directions are to have the data path removed */
+} __attribute__((packed)) esp_ble_iso_remove_data_path_params_t;
+
+struct ble_iso_cis_params {
+ uint8_t cis_id; /*!< Used to identify a CIS */
+ uint16_t max_sdu_c_to_p; /*!< Maximum size, in octets, of the payload from the Central’s Host */
+ uint16_t max_sdu_p_to_c; /*!< Maximum size, in octets, of the payload from the Peripheral’s Host */
+ uint8_t phy_c_to_p; /*!< The transmitter PHY of packets from the Central */
+ uint8_t phy_p_to_c; /*!< The transmitter PHY of packets from the Peripheral */
+ uint8_t rtn_c_to_p; /*!< Number of times every CIS Data PDU should be retransmitted from the Central to the Peripheral */
+ uint8_t rtn_p_to_c; /*!< Number of times every CIS Data PDU should be retransmitted from the Peripheral to the Central */
+} __attribute__((packed));
+
+struct ble_iso_cis_params_test {
+ uint8_t cis_id; /*!< Used to identify a CIS */
+ uint8_t nse; /*!< Maximum number of subevents in each CIS event */
+ uint16_t max_sdu_c_to_p; /*!< Maximum size, in octets, of the payload from the Central’s Host */
+ uint16_t max_sdu_p_to_c; /*!< Maximum size, in octets, of the payload from the Peripheral’s Host */
+ uint16_t max_pdu_c_to_p; /*!< Maximum size, in octets, of the payload from the Central’s Link Layer to the Peripheral’s Link Layer */
+ uint16_t max_pdu_p_to_c; /*!< Maximum size, in octets, of the payload from the Peripheral’s Link Layer to the Central’s Link Layer */
+ uint8_t phy_c_to_p; /*!< The transmitter PHY of packets from the Central */
+ uint8_t phy_p_to_c; /*!< The transmitter PHY of packets from the Peripheral */
+ uint8_t bn_c_to_p; /*!< The burst number for Central to Peripheral */
+ uint8_t bn_p_to_c; /*!< The burst number for Peripheral to Central */
+} __attribute__((packed));
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+struct esp_ble_iso_set_cig_params {
+ uint8_t cig_id; /*!< Used to identify the CIG */
+ uint32_t sdu_int_c_to_p; /*!< The interval, in microseconds, of periodic SDUs */
+ uint32_t sdu_int_p_to_c; /*!< The interval, in microseconds, of periodic SDUs */
+ uint8_t worse_case_SCA; /*!< The worst-case sleep clock accuracy of all the Peripherals that will participate in the CIG */
+ uint8_t packing; /*!< The preferred method of arranging subevents of multiple CISes */
+ uint8_t framing; /*!< The format of the CIS Data PDUs of the specified CISes' framing mode that the Host is requesting for the CIG */
+ uint16_t mtl_c_to_p; /*!< The maximum transport latency from the Central to the Peripheral, in milliseconds */
+ uint16_t mtl_p_to_c; /*!< The maximum transport latency from the Peripheral to the Central, in milliseconds */
+ uint8_t cis_cnt; /*!< Total number of CIS configurations in the CIG being added or modified */
+ struct ble_iso_cis_params cis_params[ESP_BLE_MAX_CIS_NUM]; /*!< */
+}__attribute__((packed));
+
+struct esp_ble_iso_set_cig_params_test {
+ uint8_t cig_id; /*!< Used to identify the CIG */
+ uint32_t sdu_int_c_to_p; /*!< The interval, in microseconds, of periodic SDUs */
+ uint32_t sdu_int_p_to_c; /*!< The interval, in microseconds, of periodic SDUs */
+ uint8_t ft_c_to_p; /*!< The flush timeout in multiples of ISO_Interval for each payload sent from the Central to Peripheral */
+ uint8_t ft_p_to_c; /*!< The flush timeout in multiples of ISO_Interval for each payload sent from the Peripheral to Central */
+ uint16_t iso_interval; /*!< Time between consecutive CIS anchor points. Range: 0x0004 to 0x0C80, Time = N × 1.25 ms, Time Range: 5 ms to 4 s */
+ uint8_t worse_case_SCA; /*!< The worst-case sleep clock accuracy of all the Peripherals that will participate in the CIG */
+ uint8_t packing; /*!< The preferred method of arranging subevents of multiple CISes */
+ uint8_t framing; /*!< The format of the CIS Data PDUs of the specified CISes' framing mode that the Host is requesting for the CIG */
+ uint8_t cis_cnt; /*!< Total number of CIS configurations in the CIG being added or modified */
+ struct ble_iso_cis_params_test cis_params_test[ESP_BLE_MAX_CIS_NUM];
+} __attribute__((packed));
+
+struct esp_ble_gatt_cis_hdl {
+ uint16_t cis_hdl; /*!< Connection handle of a CIS */
+ uint16_t acl_hdl; /*!< Connection handle of an ACL connection */
+}__attribute__((packed));
+
+struct esp_ble_iso_create_cis_params {
+ uint8_t cis_count; /*!< Total number of CISes to be created */
+ struct esp_ble_gatt_cis_hdl cis_hdl_info[ESP_BLE_MAX_CIS_NUM];
+}__attribute__((packed));
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+/**
+ * @brief ISO callback parameters union
+ */
+typedef union {
+ /**
+ * @brief ESP_BLE_ISO_BIG_CREATE_CMPL_EVT
+ */
+ struct ble_big_create_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate the BIG was successfully created */
+ uint8_t big_handle; /*!< The identifier of the BIG */
+ uint32_t big_sync_delay; /*!< The maximum time, in microseconds, for transmission of PDUs of all BISes in a BIG event */
+ uint32_t transport_latency; /*!< The actual transport latency, in microseconds */
+ uint8_t phy; /*!< The PHY used to create the BIG */
+ uint8_t nse; /*!< The number of subevents in each BIS event in the BIG. The value shall be an integer multiple of BN */
+ uint8_t bn; /*!< The number of new payloads in each BIS event */
+ uint8_t pto; /*!< Offset used for pre-transmissions */
+ uint8_t irc; /*!< The number of times a payload is transmitted in a BIS event */
+ uint16_t max_pdu; /*!< Maximum size, in octets, of the payload */
+ uint16_t iso_interval; /*!< The time between two consecutive BIG anchor points, Time = N × 1.25 ms */
+ uint8_t num_bis; /*!< Total number of BISes in the BIG */
+ uint16_t bis_handle[ESP_BLE_MAX_BIS_NUM]; /*!< Connection handle of a BIS */
+ } create_big_cmpl; /*!< Event parameter of ESP_BLE_ISO_BIG_CREATE_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_BIG_TERMINATE_CMPL_EVT
+ */
+ struct ble_big_term_cmpl_evt_param {
+ esp_bt_status_t status;/*!< Indicate BIG terminate complete */
+ uint8_t big_handle; /*!< The identifier of the BIG */
+ uint8_t reason; /*!< Reason for termination. See [Vol 1] Part F, Controller Error Codes for a list of error codes and descriptions */
+ } term_big_cmpl; /*!< Event parameter of ESP_BLE_ISO_BIG_TERMINATE_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT
+ */
+ struct ble_big_sync_estab_evt_param {
+ esp_bt_status_t status; /*!< Indicate synchronization to the BIG is completed */
+ uint8_t big_handle; /*!< The identifier of the BIG */
+ uint32_t transport_latency; /*!< The actual transport latency, in microseconds */
+ uint8_t nse; /*!< The number of subevents in each BIS event in the BIG */
+ uint8_t bn; /*!< The number of new payloads in each BIS event */
+ uint8_t pto; /*!< The offset in number of ISO_Intervals for pre transmissions of data packets */
+ uint8_t irc; /*!< The number of times a payload is transmitted in a BIS event */
+ uint16_t max_pdu; /*!< The maximum size of every BIS Data PDU for every BIS in the BIG */
+ uint16_t iso_interval; /*!< The time duration between two consecutive BIG anchor points */
+ uint8_t num_bis; /*!< The total number of BISes in the BIG */
+ uint16_t bis_handle[ESP_BLE_MAX_BIS_NUM]; /*!< Connection handle of a BIS in the BIG */
+ } big_sync_estab; /*!< Event parameter of ESP_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT */
+ /**
+ * @brief ESP_BLE_ISO_BIG_SYNC_LOST_EVT
+ */
+ struct ble_big_sync_lost_evt_param {
+ uint8_t big_handle; /*!< The identifier of a BIG */
+ uint8_t reason; /*!< The synchronization to BIG is terminated. See [Vol 1] Part F, Controller Error Codes for a list of error codes and descriptions */
+ } big_sync_lost; /*!< Event parameter of ESP_BLE_ISO_BIG_SYNC_LOST_EVT */
+ /**
+ * @brief ESP_BLE_ISO_BIG_SYNC_TERMINATE_CMPL_EVT
+ */
+ struct ble_big_sync_term_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate BIG sync terminate success or not */
+ uint8_t big_handle; /*!< Identifier of the BIG */
+ } term_big_sync; /*!< Event parameter of ESP_BLE_ISO_BIG_SYNC_TERMINATE_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_BIGINFO_ADV_REPORT_EVT
+ */
+ struct ble_biginfo_report_evt_param {
+ uint16_t sync_handle; /*!< Identify the periodic advertising train containing the BIGInfo field */
+ uint8_t num_bis; /*!< The total number of BISes in the BIG */
+ uint8_t nse; /*!< The total number of subevents that are used to transmit BIS Data PDUs for each BIS in a BIG event */
+ uint16_t iso_interval; /*!< The time duration between two consecutive BIG anchor points */
+ uint8_t bn; /*!< The number of new payloads for each BIS */
+ uint8_t pto; /*!< The offset in number of ISO_Intervals for pre transmissions of data packets */
+ uint8_t irc; /*!< The number of times the scheduled data packet is transmitted */
+ uint16_t max_pdu; /*!< The maximum size of every BIS Data PDU for every BIS in the BIG */
+ uint32_t sdu_interval; /*!< The time interval of the periodic SDUs */
+ uint16_t max_sdu; /*!< The maximum size of an SDU */
+ uint8_t phy; /*!< The transmitter PHY of packets */
+ uint8_t framing; /*!< The format of the BIS Data PDUs and the mode of framed PDUs that the Controller used on the specified BIG */
+ uint8_t encryption; /*!< The encryption mode of the BISes in the BIG */
+ } biginfo_report; /*!< Event parameter of ESP_BLE_ISO_BIGINFO_ADV_REPORT_EVT */
+ /**
+ * @brief ESP_BLE_ISO_ISO_DATA_PATH_UPDATE_EVT
+ */
+ struct ble_iso_data_path_update_evt_param {
+ esp_bt_status_t status; /*!< Indicate data path update success status */
+ ESP_BLE_ISO_DATA_PATH_UPDATE_TYPE op_type; /*!< data path update type, setup or remove */
+ uint16_t iso_hdl; /*!< Connection handle of the CIS or BIS */
+ } data_path; /*!< Event parameter of ESP_BLE_ISO_ISO_DATA_PATH_UPDATE_EVT */
+ /**
+ * @brief ESP_BLE_ISO_READ_ISO_TX_SYNC_CMPL_EVT
+ */
+ struct ble_iso_read_tx_sync_evt_param {
+ esp_bt_status_t status; /*!< Indicate tx sync read success status */
+ uint16_t iso_hdl; /*!< Connection handle of the CIS or BIS */
+ uint16_t pkt_seq_num; /*!< The packet sequence number of an SDU */
+ uint32_t tx_time_stamp; /*!< The CIG reference point or BIG anchor point of a transmitted SDU derived using the Controller's free running reference clock (in microseconds) */
+ uint32_t time_offset; /*!< The time offset, in microseconds, that is associated with a transmitted SDU */
+ } read_tx_sync; /*!< Event parameter of ESP_BLE_ISO_READ_ISO_TX_SYNC_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_READ_LINK_QUALITY_CMPL_EVT
+ */
+ struct ble_iso_read_link_quality_evt_param {
+ esp_bt_status_t status; /*!< Indicate link quality read success status */
+ uint16_t iso_hdl; /*!< The identifier of the BIS or CIS */
+ uint32_t tx_unacked_pkts; /*!< for CIS, The Link Layer does not receive an acknowledgment for a CIS Data PDU that it transmitted at least once by its flush point*/
+ uint32_t tx_flushed_pkts; /*!< for CIS, The Link Layer does not transmit a specific payload by its flush point */
+ uint32_t tx_last_subevt_pkts; /*!< for CIS in Peripheral role, The Link Layer transmits a CIS Data PDU in the last subevent of a CIS event */
+ uint32_t retransmitted_pkts; /*!< for CIS, The Link Layer retransmits a CIS Data PDU */
+ uint32_t crc_error_pkts; /*!< for CIS and BIS, The Link Layer receives a packet with a CRC error */
+ uint32_t rx_unreceived_pkts; /*!< for CIS and BIS, The Link Layer does not receive a specific payload by its flush point (on a CIS) or the end of the event */
+ uint32_t duplicate_pkts; /*!< for CIS, The Link Layer receives a retransmission of a CIS Data PDU */
+ } read_link_quality; /*!< Event parameter of ESP_BLE_ISO_READ_LINK_QUALITY_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_SET_CIG_PARAMS_CMPL_EVT
+ */
+ struct ble_iso_set_cig_params_evt_param {
+ esp_bt_status_t status; /*!< Indicate CIG parameters update success status */
+ uint8_t cig_id; /*!< Used to identify a CIG */
+ uint8_t cis_count; /*!< Total number of CIS configurations added or modified by this command */
+ uint16_t cis_hdl[ESP_BLE_MAX_CIS_NUM]; /*!< Connection handle of the CIS in the CIG */
+ } set_cig_params; /*!< Event parameter of ESP_BLE_ISO_SET_CIG_PARAMS_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_CREATE_CIS_CMPL_EVT
+ */
+ struct ble_iso_create_cis_params_evt_param {
+ esp_bt_status_t status; /*!< Indicate creating cis success status */
+ } create_cis; /*!< Event parameter of ESP_BLE_ISO_CREATE_CIS_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_CIS_ESTABLISHED_EVT
+ */
+ struct ble_iso_cis_estab_evt_params{
+ esp_bt_status_t status; /*!< Indicate the CIS is successfully established or not */
+ uint16_t cis_handle; /*!< Connection handle of the CIS */
+ uint32_t cig_sync_delay; /*!< The maximum time, in microseconds, for transmission of PDUs of all CISes in a CIG event */
+ uint32_t cis_sync_delay; /*!< he maximum time, in microseconds, for transmission of PDUs of the speci-fied CIS in a CIG event */
+ uint32_t trans_lat_c_to_p; /*!< The actual transport latency, in microseconds, from Central to Peripheral */
+ uint32_t trans_lat_p_to_c; /*!< The actual transport latency, in microseconds, from Peripheral to Central */
+ uint8_t phy_c_to_p; /*!< The transmitter PHY of packets from the Central */
+ uint8_t phy_p_to_c; /*!< The transmitter PHY of packets from the Peripheral */
+ uint8_t nse; /*!< Maximum number of subevents in each CIS event */
+ uint8_t bn_c_to_p; /*!< The burst number for Central to Peripheral transmission */
+ uint8_t bn_p_to_c; /*!< The burst number for Peripheral to Central transmission */
+ uint8_t ft_c_to_p; /*!< The flush timeout, in multiples of the ISO_Interval for the CIS, for each payload sent from the Central to the Peripheral */
+ uint8_t ft_p_to_c; /*!< The flush timeout, in multiples of the ISO_Interval for the CIS, for each payload sent from the Peripheral to the Central */
+ uint16_t max_pdu_c_to_p; /*!< Maximum size, in octets, of the payload from Central to Peripheral */
+ uint16_t max_pdu_p_to_c; /*!< Maximum size, in octets, of the payload from Peripheral to Central */
+ uint16_t iso_interval; /*!< The time between two consecutive CIS anchor points, Time = N × 1.25 ms */
+#if (BLE_FEAT_ISO_60_EN == TRUE)
+ uint32_t sub_interval; /*!< Time, in microseconds, between the start of consecutive subevents in a CIS event */
+ uint16_t max_sdu_c_to_p; /*!< Maximum size, in octets, of the payload from the Central’s Host */
+ uint16_t max_sdu_p_to_c; /*!< Maximum size, in octets, of the payload from the Peripheral’s Host */
+ uint32_t sdu_int_c_to_p; /*!< Time, in microseconds, between the start of consecutive SDUs sent by the Central */
+ uint32_t sdu_int_p_to_c; /*!< Time, in microseconds, between the start of consecutive SDUs sent by the Peripheral */
+ uint8_t framing; /*!< The format of the CIS Data PDUs and the mode of framed PDUs that the Controller used on the specified CIG */
+#endif // #if (BLE_FEAT_ISO_60_EN == TRUE)
+ } cis_estab; /*!< Event parameter of ESP_BLE_ISO_CIS_ESTABLISHED_EVT */
+ /**
+ * @brief ESP_BLE_ISO_CIS_DISCONNECTED_EVT
+ */
+ struct ble_iso_cis_dis_evt_params{
+ uint16_t cis_handle; /*!< Connection handle of the CIS */
+ uint8_t reason; /*!< Reason for disconnection. See [Vol 1] Part F, Controller Error Codes for error codes and descriptions */
+ } cis_disconnected; /*!< Event parameter of ESP_BLE_ISO_CIS_DISCONNECTED_EVT */
+ /**
+ * @brief ESP_BLE_ISO_CIS_REQUEST_EVT
+ */
+ struct ble_iso_cis_request_evt_params{
+ uint16_t acl_handle; /*!< Connection handle of the ACL */
+ uint16_t cis_handle; /*!< Connection handle of the CIS */
+ uint8_t cig_id; /*!< Identifier of the CIG */
+ uint8_t cis_id; /*!< Identifier of the CIS */
+ } cis_request; /*!< Event parameter of ESP_BLE_ISO_CIS_REQUEST_EVT */
+ /**
+ * @brief ESP_BLE_ISO_REMOVE_CIG_CMPL_EVT
+ */
+ struct ble_iso_remove_cig_params{
+ esp_bt_status_t status; /*!< Indicate CIG remove succeeded or not*/
+ uint8_t cig_id; /*!< Identifier of a CIG */
+ } remove_cig; /*!< Event parameter of ESP_BLE_ISO_REMOVE_CIG_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_ACCEPT_CIS_REQ_CMPL_EVT
+ */
+ struct ble_iso_accept_req_evt_params{
+ esp_bt_status_t status; /*!< Indicate the CIS request is accepted successfully */
+ } accept_req; /*!< Event parameter of ESP_BLE_ISO_ACCEPT_CIS_REQ_CMPL_EVT */
+ /**
+ * @brief ESP_BLE_ISO_REJECT_CIS_REQ_CMPL_EVT
+ */
+ struct ble_iso_reject_req_evt_params{
+ esp_bt_status_t status; /*!< Indicate the CIS request is rejected successfully */
+ uint16_t cis_handle; /*!< The connection handle of the CIS to be rejected */
+ } reject_req; /*!< Event parameter of ESP_BLE_ISO_REJECT_CIS_REQ_CMPL_EVT */
+
+} esp_ble_iso_cb_param_t;
+
+/**
+ * @brief ISO callback function type
+ * @param event : Event type
+ * @param param : Point to callback parameter, currently is union type
+ */
+typedef void (* esp_ble_iso_cb_t)(esp_ble_iso_cb_event_t event, esp_ble_iso_cb_param_t *param);
+
+/**
+ * @brief This function is called to occur iso event, such as scan result
+ *
+ * @param[in] callback: callback function
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_register_callback(esp_ble_iso_cb_t callback);
+
+/**
+ * @brief This function is called to get the current iso callback
+ *
+ * @return
+ * - esp_ble_iso_cb_t : callback function
+ *
+ */
+esp_ble_iso_cb_t esp_ble_iso_get_callback(void);
+
+
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+/**
+ * @brief This function is called to create BIG.
+ *
+ * @param[in] big_creat_param: pointer to User defined big_creat_param data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_create_big(esp_ble_iso_big_creat_params_t *big_creat_param);
+
+/**
+ * @brief This function is called to create BIG test.
+ *
+ * @param[in] big_creat_test_param: pointer to User defined big_creat_test_param data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_create_big_test(esp_ble_iso_big_creat_test_params_t *big_creat_test_param);
+
+/**
+ * @brief This function is called to terminate a BIG.
+ *
+ * @param[in] big_handle: Used to identify the BIG.
+ * @param[in] reason: indicate the reason why the BIG is to be terminated.
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_terminate_big(uint8_t big_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+/**
+ * @brief This function is called to create BIG sync.
+ *
+ * @param[in] big_sync_create_param: pointer to User defined big_sync_create_param data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_big_create_sync(esp_ble_iso_big_sync_creat_params_t *big_sync_create_param);
+
+/**
+ * @brief This function is called to terminate BIG sync.
+ *
+ * @param[in] big_handle: Identifier of the BIG.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_big_terminate_sync(uint8_t big_handle);
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+/**
+ * @brief This function is called to set iso data path.
+ *
+ * @param[in] data_path_params: pointer to User defined data_path_params data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_set_iso_data_path(esp_ble_iso_set_data_path_params_t *data_path_params);
+
+/**
+ * @brief This function is called to remove iso data path.
+ *
+ * @param[in] data_path_params: pointer to User defined data_path_params data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_remove_iso_data_path(esp_ble_iso_remove_data_path_params_t *data_path_params);
+
+/**
+ * @brief This function is called to read tx sync.
+ *
+ * @param[in] iso_handle: Connection handle of the CIS or BIS.
+
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_read_iso_tx_sync(uint16_t iso_handle);
+
+/**
+ * @brief This function is called to read link quality.
+ *
+ * @param[in] iso_handle: Connection handle of the CIS or BIS.
+
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_read_link_quality(uint16_t iso_handle);
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+/**
+ * @brief This function is called to accept cis request.
+ *
+ * @param[in] cis_handle: Connection handle of the CIS
+
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_accept_cis_request(uint16_t cis_handle);
+
+/**
+ * @brief This function is called to reject cis request.
+ *
+ * @param[in] cis_handle: Connection handle of the CIS
+ * @param[in] reason: The reason for rejecting the CIS request
+ *
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_reject_cis_request(uint16_t cis_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+/**
+ * @brief This function is called to set cig parameters.
+ *
+ * @param[in] cig_params: pointer to User defined cig_params data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_set_cig_parameters(struct esp_ble_iso_set_cig_params *cig_params);
+
+/**
+ * @brief This function is called to set cig test parameters.
+ *
+ * @param[in] cig_params_test: pointer to User defined cig_params_test data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_set_cig_parameters_test(struct esp_ble_iso_set_cig_params_test *cig_params_test);
+
+/**
+ * @brief This function is called to create cis.
+ *
+ * @param[in] creat_cis_params: pointer to User defined creat_cis_params data structure.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_create_cis(struct esp_ble_iso_create_cis_params *creat_cis_params);
+
+/**
+ * @brief This function is called to remove CIG.
+ *
+ * @param[in] cig_id: Identifier of a CIG.
+
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_remove_cig(uint8_t cig_id);
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+/**
+ * @brief This function is called to disconnect cis.
+ *
+ * @param[in] cis_handle: Connection handle of the CIS
+ * @param[in] reason: The reason for disconnecting the CIS. ESP_HCI_ERR_REMOTE_USER_TERM_CONN is recommended.
+ *
+ * The value of the reason is one of the following values:
+ * - ESP_HCI_ERR_AUTH_FAIL
+ * - ESP_HCI_ERR_REMOTE_USER_TERM_CONN
+ * - ESP_HCI_ERR_REMOTE_LOW_RESOURCES
+ * - ESP_HCI_ERR_REMOTE_POWER_OFF
+ * - ESP_HCI_ERR_UNSUPP_REMOTE_FEATURE
+ * - ESP_HCI_ERR_PAIRING_NOT_SUPPORTED
+ * - ESP_HCI_ERR_UNACCEPT_CONN_PARAM
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_iso_disconnect_cis(uint16_t cis_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ESP_BLE_ISO_API_H__ */
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h b/lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h
index 182f8760..d6a2718a 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_bt_defs.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -19,7 +19,83 @@ extern "C" {
return ESP_ERR_INVALID_STATE; \
}
-#define ESP_BT_STATUS_BASE_FOR_HCI_ERR 0X0100 /* base for converting HCI error code to ESP status */
+#define ESP_BT_STATUS_BASE_FOR_HCI_ERR 0X0100 /* base for converting HCI error code to ESP status */
+
+/* See [Vol 1] Part F, Controller Error Codes for a list of error codes and descriptions */
+
+#define ESP_HCI_ERR_SUCCESS 0x00 /* Success */
+#define ESP_HCI_ERR_UNKNOWN_CMD 0x01 /* Unknown HCI Command */
+#define ESP_HCI_ERR_UNKNOWN_CONN_ID 0x02 /* Unknown Connection Identifier */
+#define ESP_HCI_ERR_HW_FAILURE 0x03 /* Hardware Failure */
+#define ESP_HCI_ERR_PAGE_TIMEOUT 0x04 /* Page Timeout */
+#define ESP_HCI_ERR_AUTH_FAIL 0x05 /* Authentication Failure */
+#define ESP_HCI_ERR_PIN_OR_KEY_MISSING 0x06 /* PIN or Key Missing */
+#define ESP_HCI_ERR_MEM_CAPACITY_EXCEEDED 0x07 /* Memory Capacity Exceeded */
+#define ESP_HCI_ERR_CONN_TIMEOUT 0x08 /* Connection Timeout */
+#define ESP_HCI_ERR_CONN_LIMIT_EXCEEDED 0x09 /* Connection Limit Exceeded */
+#define ESP_HCI_ERR_SYNC_CONN_LIMIT_EXCEEDED 0x0A /* ASynchronous Connection Limit To A Device Exceeded */
+#define ESP_HCI_ERR_CONN_ALREADY_EXISTS 0x0B /* Connection Already Exists */
+#define ESP_HCI_ERR_CMD_DISALLOWED 0x0C /* Command Disallowed */
+#define ESP_HCI_ERR_INSUFFICIENT_RESOURCES 0x0D /* Connection Rejected due to Limited Resources */
+#define ESP_HCI_ERR_INSUFFICIENT_SECURITY 0x0E /* Connection Rejected Due To Security Reasons */
+#define ESP_HCI_ERR_BD_ADDR_UNACCEPTABLE 0x0F /* Connection Rejected due to Unacceptable BD_ADDR */
+#define ESP_HCI_ERR_CONN_ACCEPT_TIMEOUT 0x10 /* Connection Accept Timeout Exceeded */
+#define ESP_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL 0x11 /* Unsupported Feature or Parameter Value */
+#define ESP_HCI_ERR_INVALID_PARAM 0x12 /* Invalid HCI Command Parameters */
+#define ESP_HCI_ERR_REMOTE_USER_TERM_CONN 0x13 /* Remote User Terminated Connection */
+#define ESP_HCI_ERR_REMOTE_LOW_RESOURCES 0x14 /* Remote Device Terminated Connection due to Low Resources */
+#define ESP_HCI_ERR_REMOTE_POWER_OFF 0x15 /* Remote Device Terminated Connection due to Power Off */
+#define ESP_HCI_ERR_LOCALHOST_TERM_CONN 0x16 /* Connection Terminated By Local Host */
+#define ESP_HCI_ERR_REPEATED_ATTEMPTS 0x17 /* Repeated Attempts */
+#define ESP_HCI_ERR_PAIRING_NOT_ALLOWED 0x18 /* Pairing Not Allowed */
+#define ESP_HCI_ERR_UNKNOWN_LMP_PDU 0x19 /* Unknown LMP PDU */
+#define ESP_HCI_ERR_UNSUPP_REMOTE_FEATURE 0x1A /* Unsupported Remote Feature */
+#define ESP_HCI_ERR_SCO_OFFSET_REJECTED 0x1B /* SCO Offset Rejected */
+#define ESP_HCI_ERR_SCO_INTERVAL_REJECTED 0x1C /* SCO Interval Rejected */
+#define ESP_HCI_ERR_SCO_AIR_MODE_REJECTED 0x1D /* SCO Air Mode Rejected */
+#define ESP_HCI_ERR_INVALID_LL_PARAM 0x1E /* Invalid LMP Parameters / Invalid LL Parameters */
+#define ESP_HCI_ERR_UNSPECIFIED 0x1F /* Unspecified Error */
+#define ESP_HCI_ERR_UNSUPP_LL_PARAM_VAL 0x20 /* Unsupported LMP Parameter Value / Unsupported LL Parameter Value */
+#define ESP_HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21 /* Role Change Not Allowed */
+#define ESP_HCI_ERR_LL_RESP_TIMEOUT 0x22 /* LMP Response Timeout / LL Response Timeout */
+#define ESP_HCI_ERR_LL_PROC_COLLISION 0x23 /* LMP Error Transaction Collision / LL Procedure Collision */
+#define ESP_HCI_ERR_LMP_PDU_NOT_ALLOWED 0x24 /* LMP PDU Not Allowed */
+#define ESP_HCI_ERR_ENC_MODE_NOT_ACCEPTABLE 0x25 /* Encryption Mode Not Acceptable */
+#define ESP_HCI_ERR_LINK_KEY_CANNOT_BE_CHANGED 0x26 /* Link Key cannot be Changed */
+#define ESP_HCI_ERR_REQUESTED_QOS_NOT_SUPPORTED 0x27 /* Requested QoS Not Supported */
+#define ESP_HCI_ERR_INSTANT_PASSED 0x28 /* Instant Passed */
+#define ESP_HCI_ERR_PAIRING_NOT_SUPPORTED 0x29 /* Pairing With Unit Key Not Supported */
+#define ESP_HCI_ERR_DIFF_TRANS_COLLISION 0x2A /* Different Transaction Collision */
+#define ESP_HCI_ERR_UNDEFINED_0x2B 0x2B /* Reserved for future use */
+#define ESP_HCI_ERR_QOS_UNACCEPTABLE_PARAM 0x2C /* QoS Unacceptable Parameter */
+#define ESP_HCI_ERR_QOS_REJECTED 0x2D /* QoS Rejected */
+#define ESP_HCI_ERR_CHAN_ASSESS_NOT_SUPPORTED 0x2E /* Channel Classification Not Supported */
+#define ESP_HCI_ERR_INSUFF_SECURITY 0x2F /* Insufficient Security */
+#define ESP_HCI_ERR_PARAM_OUT_OF_MANDATORY_RANGE 0x30 /* Parameter Out Of Mandatory Range */
+#define ESP_HCI_ERR_UNDEFINED_0x31 0x31 /* Reserved for future use */
+#define ESP_HCI_ERR_ROLE_SWITCH_PENDING 0x32 /* Role Switch Pending */
+#define ESP_HCI_ERR_UNDEFINED_0x33 0x33 /* Reserved for future use */
+#define ESP_HCI_ERR_RESERVED_SLOT_VIOLATION 0x34 /* Reserved Slot Violation */
+#define ESP_HCI_ERR_ROLE_SWITCH_FAILED 0x35 /* Role Switch Failed */
+#define ESP_HCI_ERR_EXT_INQ_RESP_TOO_LARGE 0x36 /* Extended Inquiry Response Too Large */
+#define ESP_HCI_ERR_SIMPLE_PAIR_NOT_SUPP_BY_HOST 0x37 /* Secure Simple Pairing Not Supported By Host */
+#define ESP_HCI_ERR_HOST_BUSY_PAIRING 0x38 /* Host Busy - Pairing*/
+#define ESP_HCI_ERR_CONN_REJECTED_DUE_TO_NO_CHAN 0x39 /* Connection Rejected due to No Suitable Channel Found */
+#define ESP_HCI_ERR_CONTROLLER_BUSY 0x3A /* Controller Busy */
+#define ESP_HCI_ERR_UNACCEPT_CONN_PARAM 0x3B /* Unacceptable Connection Parameters */
+#define ESP_HCI_ERR_ADV_TIMEOUT 0x3C /* Advertising Timeout */
+#define ESP_HCI_ERR_TERM_DUE_TO_MIC_FAIL 0x3D /* Connection Terminated due to MIC Failure */
+#define ESP_HCI_ERR_CONN_FAIL_TO_ESTAB 0x3E /* Connection Failed to be Established / Synchronization Timeout */
+#define ESP_HCI_ERR_MAC_CONN_FAILED 0x3F /* Previously used */
+#define ESP_HCI_ERR_CLOCK_ADJUST_REJECTED 0x40 /* Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging */
+#define ESP_HCI_ERR_SUBMAP_NOT_DEFINED 0x41 /* Type0 Submap Not Defined */
+#define ESP_HCI_ERR_UNKNOWN_ADV_IDENTIFIER 0x42 /* Unknown Advertising Identifier */
+#define ESP_HCI_ERR_LIMIT_REACHED 0x43 /* Limit Reached */
+#define ESP_HCI_ERR_OP_CANCELLED_BY_HOST 0x44 /* Operation Cancelled by Host */
+#define ESP_HCI_ERR_PACKET_TOO_LONG 0x45 /* Packet Too Long */
+#define ESP_HCI_ERR_TOO_LATE 0x46 /* Too Late */
+#define ESP_HCI_ERR_TOO_EARLY 0x47 /* Too Early */
+#define ESP_HCI_ERR_INSUFFICIENT_CHANNELS 0x48 /* Insufficient Channels */
/* relate to BT_STATUS_xxx in bt_def.h */
/// Status Return Value
@@ -110,6 +186,14 @@ typedef enum {
ESP_BT_STATUS_HCI_CONN_TOUT_DUE_TO_MIC_FAILURE,
ESP_BT_STATUS_HCI_CONN_FAILED_ESTABLISHMENT,
ESP_BT_STATUS_HCI_MAC_CONNECTION_FAILED,
+ ESP_BT_STATUS_HCI_CCA_REJECTED,
+ ESP_BT_STATUS_HCI_TYPE0_SUBMAP_NOT_DEFINED,
+ ESP_BT_STATUS_HCI_UNKNOWN_ADV_ID,
+ ESP_BT_STATUS_HCI_LIMIT_REACHED,
+ ESP_BT_STATUS_HCI_OPT_CANCEL_BY_HOST,
+ ESP_BT_STATUS_HCI_PKT_TOO_LONG,
+ ESP_BT_STATUS_HCI_TOO_LATE,
+ ESP_BT_STATUS_HCI_TOO_EARLY,
} esp_bt_status_t;
@@ -137,6 +221,25 @@ typedef uint8_t esp_link_key[ESP_BT_OCTET16_LEN]; /* Link Key */
#define ESP_BLE_CONN_SUP_TOUT_MIN 0x000A /*!< relate to BTM_BLE_CONN_SUP_TOUT_MIN in stack/btm_ble_api.h */
#define ESP_BLE_CONN_SUP_TOUT_MAX 0x0C80 /*!< relate to ESP_BLE_CONN_SUP_TOUT_MAX in stack/btm_ble_api.h */
+#define ESP_BLE_PHY_1M_PREF_MASK (1 << 0) /*!< The Host prefers use the LE1M transmitter or receiver PHY */
+#define ESP_BLE_PHY_2M_PREF_MASK (1 << 1) /*!< The Host prefers use the LE2M transmitter or receiver PHY */
+#define ESP_BLE_PHY_CODED_PREF_MASK (1 << 2) /*!< The Host prefers use the LE CODED transmitter or receiver PHY */
+typedef uint8_t esp_ble_phy_mask_t;
+
+/**
+* @brief create connection parameters
+*/
+typedef struct {
+ uint16_t scan_interval; /*!< Initial scan interval, in units of 0.625ms, the range is 0x0004(2.5ms) to 0xFFFF(10.24s). */
+ uint16_t scan_window; /*!< Initial scan window, in units of 0.625ms, the range is 0x0004(2.5ms) to 0xFFFF(10.24s). */
+ uint16_t interval_min; /*!< Minimum connection interval, in units of 1.25ms, the range is 0x0006(7.5ms) to 0x0C80(4s). */
+ uint16_t interval_max; /*!< Maximum connection interval, in units of 1.25ms, the range is 0x0006(7.5ms) to 0x0C80(4s). */
+ uint16_t latency; /*!< Connection latency, the range is 0x0000(0) to 0x01F3(499). */
+ uint16_t supervision_timeout; /*!< Connection supervision timeout, in units of 10ms, the range is from 0x000A(100ms) to 0x0C80(32s). */
+ uint16_t min_ce_len; /*!< Minimum connection event length, in units of 0.625ms, setting to 0 for no preferred parameters. */
+ uint16_t max_ce_len; /*!< Maximum connection event length, in units of 0.625ms, setting to 0 for no preferred parameters. */
+} esp_ble_conn_params_t;
+
/// Check the param is valid or not
#define ESP_BLE_IS_VALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) )
@@ -179,8 +282,11 @@ typedef enum {
/// white list address type
typedef enum {
- BLE_WL_ADDR_TYPE_PUBLIC = 0x00,
- BLE_WL_ADDR_TYPE_RANDOM = 0x01,
+ BLE_WL_ADDR_TYPE_PUBLIC = 0x00, /*!< Public Device Address */
+ BLE_WL_ADDR_TYPE_RANDOM = 0x01, /*!< Random Device Address */
+#if (CONFIG_BT_BLE_50_FEATURES_SUPPORTED)
+ BLE_WL_ADDR_TYPE_ANONYMOUS = 0xFF, /*!< Devices sending anonymous advertisements, use to enable anonymous advertising report for scanning */
+#endif // (CONFIG_BT_BLE_50_FEATURES_SUPPORTED)
} esp_ble_wl_addr_type_t;
/// Used to exchange the encryption key in the init key & response key
@@ -201,6 +307,10 @@ typedef uint8_t esp_ble_key_mask_t; /* the key mask type */
#define ESP_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define ESP_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
+#define ESP_BLE_ADV_NAME_LEN_MAX 29
+
+#define ESP_INVALID_CONN_HANDLE 0xfff
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_bt_device.h b/lib/bt/host/bluedroid/api/include/api/esp_bt_device.h
index 6e12765c..60758f1e 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_bt_device.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_bt_device.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -129,6 +129,17 @@ esp_err_t esp_bt_dev_get_device_name(void) __attribute__((deprecated("Please use
esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_coex_op_t op, uint8_t status);
/**
+ * @brief This function is used to get the path name of the Bluetooth bond keys
+ * saved in the NVS module.
+ * @param[out] file_path: buffer to store the config file path, max length NVS_KEY_NAME_MAX_SIZE
+ *
+ * @return
+ * - ESP_OK: success
+ *
+ */
+esp_err_t esp_bt_config_file_path_get(char *file_path);
+
+/**
* @brief This function is used to update the path name of bluetooth bond keys saved in the NVS module
* and need to be called before esp_bluedroid_init().
* @param[in] file_path: the name of config file path, the length of file_path should be less than NVS_NS_NAME_MAX_SIZE
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_bt_main.h b/lib/bt/host/bluedroid/api/include/api/esp_bt_main.h
index b13ae94d..b9b60e3d 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_bt_main.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_bt_main.h
@@ -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
*/
@@ -30,11 +30,13 @@ typedef enum {
*/
typedef struct {
bool ssp_en; /*!< Whether SSP(secure simple pairing) or legacy pairing is used for Classic Bluetooth */
+ bool sc_en; /*!< Whether secure connection host support is enabled or disabled for Classic Bluetooth */
} esp_bluedroid_config_t;
#define BT_BLUEDROID_INIT_CONFIG_DEFAULT() \
{ \
.ssp_en = true, \
+ .sc_en = false, \
}
/**
@@ -55,7 +57,10 @@ esp_bluedroid_status_t esp_bluedroid_get_status(void);
esp_err_t esp_bluedroid_enable(void);
/**
- * @brief Disable bluetooth, must prior to esp_bluedroid_deinit().
+ * @brief Disable Bluetooth, must be called prior to esp_bluedroid_deinit().
+ *
+ * @note Before calling this API, ensure that all activities related to
+ * the application, such as connections, scans, etc., are properly closed.
*
* @return
* - ESP_OK : Succeed
@@ -92,6 +97,11 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg);
*/
esp_err_t esp_bluedroid_deinit(void);
+#if defined(CONFIG_EXAMPLE_CI_ID) && defined(CONFIG_EXAMPLE_CI_PIPELINE_ID)
+// Only for internal used (CI example test)
+char *esp_bluedroid_get_example_name(void);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h
index ea52baf0..066103fa 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -229,6 +229,23 @@ typedef enum {
ESP_GAP_BLE_ADD_DEV_TO_RESOLVING_LIST_COMPLETE_EVT, /*!< when add a device to the resolving list completes, the event comes*/
ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT, /*!< When vendor hci command complete, the event comes */
ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT, /*!< When set privacy mode complete, the event comes */
+ ESP_GAP_BLE_SET_CSA_SUPPORT_COMPLETE_EVT, /*!< When set CSA support complete, the event comes */
+ ESP_GAP_BLE_SET_VENDOR_EVT_MASK_COMPLETE_EVT, /*!< When set vendor event mask complete, the event comes */
+ ESP_GAP_BLE_VENDOR_HCI_EVT, /*!< When BLE vendor HCI event received, the event comes */
+ // BLE power control
+ ESP_GAP_BLE_ENH_READ_TRANS_PWR_LEVEL_EVT, /*!< When reading the current and maximum transmit power levels of the local Controller complete, the event comes */
+ ESP_GAP_BLE_READ_REMOTE_TRANS_PWR_LEVEL_EVT, /*!< When reading the transmit power level used by the remote Controller on the ACL connection complete, the event comes */
+ ESP_GAP_BLE_SET_PATH_LOSS_RPTING_PARAMS_EVT, /*!< when set the path loss threshold reporting parameters complete, the event comes */
+ ESP_GAP_BLE_SET_PATH_LOSS_RPTING_ENABLE_EVT, /*!< when enable or disable path loss reporting complete, the event comes */
+ ESP_GAP_BLE_SET_TRANS_PWR_RPTING_ENABLE_EVT, /*!< when enable or disable the reporting to the local Host of transmit power level changes complete, the event comes */
+ ESP_GAP_BLE_PATH_LOSS_THRESHOLD_EVT, /*!< when receive a path loss threshold crossing, the event comes */
+ ESP_GAP_BLE_TRANS_PWR_RPTING_EVT, /*!< when receive a transmit power level report, the event comes */
+ // BLE connection subrating
+ ESP_GAP_BLE_SET_DEFAULT_SUBRATE_COMPLETE_EVT, /*!< when set default subrate complete, the event comes */
+ ESP_GAP_BLE_SUBRATE_REQUEST_COMPLETE_EVT, /*!< when subrate request command complete, the event comes */
+ ESP_GAP_BLE_SUBRATE_CHANGE_EVT, /*!< when Connection Subrate Update procedure has completed and some parameters of the specified connection have changed, the event comes */
+ ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT, /*!< When host feature set complete, the event comes */
+ ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT, /*!< When BLE channel map result is received, the event comes */
ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */
} esp_gap_ble_cb_event_t;
@@ -631,6 +648,7 @@ typedef struct
{
esp_bd_addr_t bd_addr; /*!< peer address */
esp_ble_bond_key_info_t bond_key; /*!< the bond key information */
+ esp_ble_addr_type_t bd_addr_type; /*!< peer address type */
} esp_ble_bond_dev_t; /*!< the ble bond device type */
@@ -662,20 +680,54 @@ typedef struct {
} esp_ble_local_oob_data_t;
/**
+* @brief Definition of the authentication failed reason
+*/
+typedef enum {
+ // Failure reason defined in Bluetooth Core Spec 5.0 Vol3, Part H, 3.5.5
+ ESP_AUTH_SMP_PASSKEY_FAIL = 78, /*!< The user input of passkey failed */
+ ESP_AUTH_SMP_OOB_FAIL, /*!< The OOB data is not available */
+ ESP_AUTH_SMP_PAIR_AUTH_FAIL, /*!< The authentication requirements cannot be met */
+ ESP_AUTH_SMP_CONFIRM_VALUE_FAIL, /*!< The confirm value does not match the calculated comparison value */
+ ESP_AUTH_SMP_PAIR_NOT_SUPPORT, /*!< Pairing is not supported by the device */
+ ESP_AUTH_SMP_ENC_KEY_SIZE, /*!< The resultant encryption key size is not long enough */
+ ESP_AUTH_SMP_INVALID_CMD, /*!< The SMP command received is not supported by this device */
+ ESP_AUTH_SMP_UNKNOWN_ERR, /*!< Pairing failed due to an unspecified reason */
+ ESP_AUTH_SMP_REPEATED_ATTEMPT, /*!< Pairing or authentication procedure is disallowed */
+ ESP_AUTH_SMP_INVALID_PARAMETERS, /*!< The command length is invalid or that a parameter is outside the specified range */
+ ESP_AUTH_SMP_DHKEY_CHK_FAIL, /*!< The DHKey Check value received doesn’t match the one calculated by the local device */
+ ESP_AUTH_SMP_NUM_COMP_FAIL, /*!< The confirm values in the numeric comparison protocol do not match */
+ ESP_AUTH_SMP_BR_PARING_IN_PROGR, /*!< Pairing Request sent over the BR/EDR transport is in progress */
+ ESP_AUTH_SMP_XTRANS_DERIVE_NOT_ALLOW, /*!< The BR/EDR Link Key or BLE LTK cannot be used to derive */
+
+ // Failure reason defined in Bluedroid Host
+ ESP_AUTH_SMP_INTERNAL_ERR, /*!< Internal error in pairing procedure */
+ ESP_AUTH_SMP_UNKNOWN_IO, /*!< Unknown IO capability, unable to decide association model */
+ ESP_AUTH_SMP_INIT_FAIL, /*!< SMP pairing initiation failed */
+ ESP_AUTH_SMP_CONFIRM_FAIL, /*!< The confirm value does not match */
+ ESP_AUTH_SMP_BUSY, /*!< Pending security request on going */
+ ESP_AUTH_SMP_ENC_FAIL, /*!< The Controller failed to start encryption */
+ ESP_AUTH_SMP_STARTED, /*!< SMP pairing process started */
+ ESP_AUTH_SMP_RSP_TIMEOUT, /*!< Security Manager timeout due to no SMP command being received */
+ ESP_AUTH_SMP_DIV_NOT_AVAIL, /*!< Encrypted Diversifier value not available */
+ ESP_AUTH_SMP_UNSPEC_ERR, /*!< Unspecified failed reason */
+ ESP_AUTH_SMP_CONN_TOUT, /*!< Pairing process failed due to connection timeout */
+} esp_ble_auth_fail_rsn_t;
+
+/**
* @brief Structure associated with ESP_AUTH_CMPL_EVT
*/
typedef struct
{
- esp_bd_addr_t bd_addr; /*!< BD address peer device. */
- bool key_present; /*!< Valid link key value in key element */
- esp_link_key key; /*!< Link key associated with peer device. */
- uint8_t key_type; /*!< The type of Link Key */
- bool success; /*!< TRUE of authentication succeeded, FALSE if failed. */
- uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */
- esp_ble_addr_type_t addr_type; /*!< Peer device address type */
- esp_bt_dev_type_t dev_type; /*!< Device type */
- esp_ble_auth_req_t auth_mode; /*!< authentication mode */
-} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */
+ esp_bd_addr_t bd_addr; /*!< BD address of peer device */
+ bool key_present; /*!< True if the link key value is valid; false otherwise */
+ esp_link_key key; /*!< Link key associated with peer device */
+ uint8_t key_type; /*!< The type of link key */
+ bool success; /*!< True if authentication succeeded; false otherwise */
+ esp_ble_auth_fail_rsn_t fail_reason; /*!< The HCI reason/error code for failure when success is false */
+ esp_ble_addr_type_t addr_type; /*!< Peer device address type */
+ esp_bt_dev_type_t dev_type; /*!< Device type */
+ esp_ble_auth_req_t auth_mode; /*!< Authentication mode */
+} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */
/**
* @brief union associated with ble security
@@ -846,6 +898,10 @@ typedef uint8_t esp_ble_gap_adv_type_t;
/// Extend advertising tx power, range: [-127, +126] dBm
#define EXT_ADV_TX_PWR_NO_PREFERENCE (127) /*!< host has no preference for tx power */
+
+/// max number of advertising sets to enable or disable
+#define EXT_ADV_NUM_SETS_MAX (10) /*!< max evt instance num */
+
/**
* @brief ext adv parameters
*/
@@ -926,19 +982,27 @@ typedef struct {
esp_ble_gap_sync_t filter_policy; /*!< Configures the filter policy for periodic advertising sync:
0: Use Advertising SID, Advertiser Address Type, and Advertiser Address parameters to determine the advertiser to listen to.
1: Use the Periodic Advertiser List to determine the advertiser to listen to. */
- #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
+#if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
esp_ble_gap_sync_t reports_disabled; /*!< Supported only by esp32c2, esp32c6, and esp32h2; can be set by menuconfig:
0: Reporting initially enabled.
1: Reporting initially disabled. */
esp_ble_gap_sync_t filter_duplicates; /*!< Supported only by esp32c2, esp32c6, and esp32h2; can be set by menuconfig:
0: Duplicate filtering initially disabled.
1: Duplicate filtering initially enabled. */
- #endif
+#endif // (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
uint8_t sid; /*!< SID of the periodic advertising */
esp_ble_addr_type_t addr_type; /*!< Address type of the periodic advertising */
esp_bd_addr_t addr; /*!< Address of the periodic advertising */
uint16_t skip; /*!< Maximum number of periodic advertising events that can be skipped */
uint16_t sync_timeout; /*!< Synchronization timeout */
+#if (CONFIG_BT_BLE_FEAT_CTE_EN)
+ uint8_t sync_cte_type; /*!< Whether to only synchronize to periodic advertising with certain types of CTE (Constant Tone Extension)
+ bit 0: Do not sync to packets with an AoA CTE
+ bit 1: Do not sync to packets with an AoD CTE with 1 μs slots
+ bit 2: Do not sync to packets with an AoD CTE with 2 μs slots
+ bit 3: Do not sync to packets with a type 3 CTE (currently reserved for future use)
+ bit 4: Do not sync to packets without a CTE */
+#endif // BT_BLE_FEAT_CTE_EN
} esp_ble_gap_periodic_adv_sync_params_t;
/**
@@ -970,13 +1034,20 @@ typedef struct {
uint16_t sync_handle; /*!< periodic advertising train handle */
uint8_t tx_power; /*!< periodic advertising tx power*/
int8_t rssi; /*!< periodic advertising rssi */
+#if (CONFIG_BT_BLE_FEAT_CTE_EN) // #if (BLE_FEAT_CTE_EN == TRUE)
+ uint8_t cte_type; /*!< The type of Constant Tone Extension
+ 0x00: AoA Constant Tone Extension
+ 0x01: AoD Constant Tone Extension with 1 μs slots
+ 0x02: AoD Constant Tone Extension with 2 μs slots
+ 0xFF: No Constant Tone Extension */
+#endif // BT_BLE_FEAT_CTE_EN
esp_ble_gap_ext_adv_data_status_t data_status; /*!< periodic advertising data type*/
uint8_t data_length; /*!< periodic advertising data length */
uint8_t data[251]; /*!< periodic advertising data */
} esp_ble_gap_periodic_adv_report_t;
/**
-* @brief perodic adv sync establish parameters
+* @brief periodic adv sync establish parameters
*/
typedef struct {
uint8_t status; /*!< periodic advertising sync status */
@@ -1031,11 +1102,123 @@ typedef struct {
} esp_ble_gap_past_params_t;
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
-typedef enum{
+typedef enum {
ESP_BLE_NETWORK_PRIVACY_MODE = 0X00, /*!< Network Privacy Mode for peer device (default) */
ESP_BLE_DEVICE_PRIVACY_MODE = 0X01, /*!< Device Privacy Mode for peer device */
} esp_ble_privacy_mode_t;
+#define ESP_BLE_VENDOR_SCAN_REQ_RECV_EVT_MASK BIT(0) /*!< Vendor BLE legacy SCAN_REQ received event mask */
+#define ESP_BLE_VENDOR_CHMAP_UPDATE_EVT_MASK BIT(1) /*!< Vendor BLE channel map update event mask */
+#define ESP_BLE_VENDOR_SLEEP_WAKEUP_EVT_MASK BIT(3) /*!< Vendor BLE sleep wakeup event mask */
+#define ESP_BLE_VENDOR_CONN_REQ_RECV_EVT_MASK BIT(4) /*!< Vendor BLE CONNECT_IND and AUX_CONNECT_REQ received event mask */
+#define ESP_BLE_VENDOR_CONN_RSP_RECV_EVT_MASK BIT(5) /*!< Vendor BLE AUX_CONNECT_RSP received event mask */
+typedef uint32_t esp_ble_vendor_evt_mask_t;
+
+#define ESP_BLE_VENDOR_PDU_RECV_EVT (0) /*!< Vendor BLE specify PDU received event */
+#define ESP_BLE_VENDOR_CHAN_MAP_UPDATE_EVT (1) /*!< Vendor BLE channel map update complete event */
+#define ESP_BLE_VENDOR_SLEEP_WAKEUP_EVT (2) /*!< Vendor BLE sleep wakeup event */
+typedef uint8_t esp_ble_vendor_evt_t;
+
+typedef enum {
+ ESP_BLE_VENDOR_PDU_SCAN_REQ = 0, /*!< SCAN_REQ PDU type */
+ ESP_BLE_VENDOR_PDU_CONN_REQ, /*!< CONNECT_IND and AUX_CONNECT_REQ PDU type */
+ ESP_BLE_VENDOR_PDU_CONN_RSP, /*!< AUX_CONNECT_RSP PDU type */
+} esp_ble_vendor_pdu_t;
+
+/**
+ * @brief BLE vendor event parameters union
+ */
+typedef union {
+ /**
+ * @brief ESP_BLE_VENDOR_PDU_RECV_EVT
+ */
+ struct ble_pdu_recv_evt_param {
+ esp_ble_vendor_pdu_t type; /*!< The type of LE PDU */
+ uint8_t handle; /*!< The handle of advertising set */
+ esp_ble_addr_type_t addr_type; /*!< The address type of peer device */
+ esp_bd_addr_t peer_addr; /*!< The address of peer device */
+ } pdu_recv; /*!< Event parameter of ESP_BLE_VENDOR_PDU_RECV_EVT */
+ /**
+ * @brief ESP_BLE_VENDOR_CHAN_MAP_UPDATE_EVT
+ */
+ struct ble_chan_map_update_evt_param {
+ uint8_t status; /*!< Indicate the channel map update status (HCI error code) */
+ uint16_t conn_handle; /*!< The connection handle */
+ esp_gap_ble_channels ch_map; /*!< The channel map after updated */
+ } chan_map_update; /*!< Event parameter of ESP_BLE_VENDOR_CHAN_MAP_UPDATE_EVT */
+ /**
+ * @brief ESP_BLE_VENDOR_SLEEP_WAKEUP_EVT
+ */
+ struct ble_sleep_wakeup_evt_param {
+ // No parameters
+ } sleep_wakeup; /*!< Event parameter of ESP_BLE_VENDOR_SLEEP_WAKEUP_EVT */
+} esp_ble_vendor_evt_param_t;
+
+/**
+* @brief path loss report parameters
+*/
+typedef struct {
+ uint16_t conn_handle; /*!< Connection_Handle */
+ uint8_t high_threshold; /*!< High threshold for the path loss (dB) */
+ uint8_t high_hysteresis; /*!< Hysteresis value for the high threshold (dB) */
+ uint8_t low_threshold; /*!< Low threshold for the path loss (dB) */
+ uint8_t low_hysteresis; /*!< Hysteresis value for the low threshold (dB) */
+ uint16_t min_time_spent; /*!< Minimum time in number of connection events to be observed
+ once the path loss crosses the threshold before an event is generated */
+} esp_ble_path_loss_rpt_params_t;
+
+typedef enum {
+ /*!< No PHY is set, should not be used */
+ ESP_BLE_CONN_TX_POWER_PHY_NONE = 0,
+ /*!< LE 1M PHY */
+ ESP_BLE_CONN_TX_POWER_PHY_1M = 0x01,
+ /*!< LE 2M PHY */
+ ESP_BLE_CONN_TX_POWER_PHY_2M = 0x02,
+ /*!< LE Coded PHY using S=8 coding */
+ ESP_BLE_CONN_TX_POWER_PHY_CODED_S8 = 0x03,
+ /*!< LE Coded PHY using S=2 coding */
+ ESP_BLE_CONN_TX_POWER_PHY_CODED_S2 = 0x04,
+} esp_ble_tx_power_phy_t;
+
+typedef enum {
+ /*!< Low zone entered */
+ ESP_BLE_CONN_PATH_LOSS_ZONE_ENTERED_LOW = 0x00,
+ /*!< Middle zone entered */
+ ESP_BLE_CONN_PATH_LOSS_ZONE_ENTERED_MIDDLE = 0x01,
+ /*!< High zone entered */
+ ESP_BLE_CONN_PATH_LOSS_ZONE_ENTERED_HIGH = 0x02,
+} esp_ble_path_loss_zone_t;
+
+/**
+* @brief Connection subrating default parameters
+*/
+typedef struct {
+ uint16_t subrate_min; /*!< Minimum subrate factor allowed in requests by a Peripheral. Range: 0x0001 to 0x01F4, default: 0x0001 */
+ uint16_t subrate_max; /*!< Maximum subrate factor allowed in requests by a Peripheral. Range: 0x0001 to 0x01F4, default: 0x0001. subrate_max × (max_latency + 1) should not be greater than 500 */
+ uint16_t max_latency; /*!< Maximum Peripheral latency allowed in requests by a Peripheral, in units of subrated connection intervals.
+ Range: 0x0000 to 0x01F3, default: 0x0000 */
+ uint16_t continuation_number; /*!< Minimum number of underlying connection events to remain active after a packet containing a Link Layer
+ PDU with a non-zero Length field is sent or received in requests by a Peripheral. Range: 0x0000 to 0x01F3,
+ default: 0x0000. continuation_number should not greater than or equal to subrate_max */
+ uint16_t supervision_timeout; /*!< Maximum supervision timeout allowed in requests by a Peripheral (N * 10 ms). Range: 0x000A to 0x0C80,
+ Time Range: 100 ms to 32 s, default: 0x0C80 (32 s) */
+} esp_ble_default_subrate_param_t;
+
+/**
+* @brief Connection subrating request parameters
+*/
+typedef struct {
+ uint16_t conn_handle; /*!< Connection handle of the ACL */
+ uint16_t subrate_min; /*!< Minimum subrate factor to be applied to the underlying connection interval. Range: 0x0001 to 0x01F4 */
+ uint16_t subrate_max; /*!< Maximum subrate factor to be applied to the underlying connection interval. Range: 0x0001 to 0x01F4 */
+ uint16_t max_latency; /*!< Maximum Peripheral latency for the connection in units of subrated connection intervals. Range: 0x0000 to 0x01F3 */
+ uint16_t continuation_number; /*!< Minimum number of underlying connection events to remain active after a packet containing
+ a Link Layer PDU with a non-zero Length field is sent or received. Range: 0x0000 to 0x01F3 */
+ uint16_t supervision_timeout; /*!< Supervision timeout for this connection (N * 10 ms). Range: 0x000A to 0x0C80, Time Range: 100 ms to 32 s
+ The supervision_timeout, in milliseconds, shall be greater than 2 × current connection interval × subrate_max × (max_latency + 1) */
+} esp_ble_subrate_req_param_t;
+
+
/**
* @brief Gap callback parameters union
*/
@@ -1122,12 +1305,6 @@ typedef union {
struct ble_adv_stop_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate adv stop operation success status */
} adv_stop_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT */
- /**
- * @brief ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT
- */
- struct ble_adv_clear_cmpl_evt_param {
- esp_bt_status_t status; /*!< Indicate adv clear operation success status */
- } adv_clear_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT */
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
/**
* @brief ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT
@@ -1141,13 +1318,13 @@ typedef union {
struct ble_update_conn_params_evt_param {
esp_bt_status_t status; /*!< Indicate update connection parameters success status */
esp_bd_addr_t bda; /*!< Bluetooth device address */
- uint16_t min_int; /*!< Min connection interval */
- uint16_t max_int; /*!< Max connection interval */
+ uint16_t min_int; /*!< Minimum connection interval. If the master initiates the connection parameter update, this value is not applicable for the slave and will be set to zero. */
+ uint16_t max_int; /*!< Maximum connection interval. If the master initiates the connection parameter update, this value is not applicable for the slave and will be set to zero. */
uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
- uint16_t conn_int; /*!< Current connection interval */
+ uint16_t conn_int; /*!< Current connection interval in milliseconds, calculated as N × 1.25 ms */
uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
- Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec */
- } update_conn_params; /*!< Event parameter of ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */
+ This value is calculated as N × 10 ms */
+ } update_conn_params; /*!< Event parameter for ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */
/**
* @brief ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT
*/
@@ -1205,6 +1382,14 @@ typedef union {
esp_bd_addr_t remote_addr; /*!< The remote device address */
} read_rssi_cmpl; /*!< Event parameter of ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT */
/**
+ * @brief ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT
+ */
+ struct ble_read_ble_channel_map_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Status of the read channel map operation */
+ uint8_t channel_map[ESP_GAP_BLE_CHANNELS_LEN]; /*!< The BLE channel map, represented as a 5-byte array */
+ esp_bd_addr_t remote_addr; /*!< The remote device address */
+ } read_ble_channel_map_cmpl; /*!< Event parameter of ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT */
+ /**
* @brief ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT
*/
struct ble_update_whitelist_cmpl_evt_param {
@@ -1251,77 +1436,93 @@ typedef union {
struct ble_set_perf_phy_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate perf phy set status */
} set_perf_phy; /*!< Event parameter of ESP_GAP_BLE_SET_PREFERRED_PHY_COMPLETE_EVT */
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
/**
* @brief ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT
*/
struct ble_ext_adv_set_rand_addr_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate extend advertising random address set status */
+ uint8_t instance; /*!< extend advertising handle */
} ext_adv_set_rand_addr; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT
*/
struct ble_ext_adv_set_params_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate extend advertising parameters set status */
+ uint8_t instance; /*!< extend advertising handle */
} ext_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT
*/
struct ble_ext_adv_data_set_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate extend advertising data set status */
+ uint8_t instance; /*!< extend advertising handle */
} ext_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT
*/
struct ble_ext_adv_scan_rsp_set_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate extend advertising scan response data set status */
+ uint8_t instance; /*!< extend advertising handle */
} scan_rsp_set; /*!< Event parameter of ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT
*/
struct ble_ext_adv_start_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate advertising start operation success status */
+ uint8_t instance_num; /*!< extend advertising handle numble*/
+ uint8_t instance[EXT_ADV_NUM_SETS_MAX]; /*!< extend advertising handle list*/
} ext_adv_start; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT
*/
struct ble_ext_adv_stop_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate advertising stop operation success status */
+ uint8_t instance_num; /*!< extend advertising handle numble*/
+ uint8_t instance[EXT_ADV_NUM_SETS_MAX]; /*!< extend advertising handle list*/
} ext_adv_stop; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT
*/
struct ble_ext_adv_set_remove_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate advertising stop operation success status */
+ uint8_t instance; /*!< extend advertising handle */
} ext_adv_remove; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT
*/
struct ble_ext_adv_set_clear_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate advertising stop operation success status */
+ uint8_t instance; /*!< extend advertising handle */
} ext_adv_clear; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT */
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
/**
* @brief ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT
*/
struct ble_periodic_adv_set_params_cmpl_param {
esp_bt_status_t status; /*!< Indicate periodic advertisingparameters set status */
+ uint8_t instance; /*!< extend advertising handle */
} peroid_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT
*/
struct ble_periodic_adv_data_set_cmpl_param {
esp_bt_status_t status; /*!< Indicate periodic advertising data set status */
+ uint8_t instance; /*!< extend advertising handle */
} period_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT
*/
struct ble_periodic_adv_start_cmpl_param {
esp_bt_status_t status; /*!< Indicate periodic advertising start status */
+ uint8_t instance; /*!< extend advertising handle */
} period_adv_start; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT
*/
struct ble_periodic_adv_stop_cmpl_param {
esp_bt_status_t status; /*!< Indicate periodic advertising stop status */
+ uint8_t instance; /*!< extend advertising handle */
} period_adv_stop; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT
@@ -1506,6 +1707,19 @@ typedef union {
uint16_t num_of_pkt; /*!< number of packets received, only valid if update_evt is DTM_TEST_STOP_EVT and shall be reported as 0 for a transmitter */
} dtm_state_update; /*!< Event parameter of ESP_GAP_BLE_DTM_TEST_UPDATE_EVT */
/**
+ * @brief ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT
+ */
+ struct ble_set_privacy_mode_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate privacy mode set operation success status */
+ } set_privacy_mode_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT */
+#if (BLE_VENDOR_HCI_EN == TRUE)
+ /**
+ * @brief ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT
+ */
+ struct ble_adv_clear_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate adv clear operation success status */
+ } adv_clear_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT */
+ /**
* @brief ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT
*/
struct vendor_cmd_cmpl_evt_param {
@@ -1514,11 +1728,136 @@ typedef union {
uint8_t *p_param_buf; /*!< The point of parameter buffer */
} vendor_cmd_cmpl; /*!< Event parameter of ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT */
/**
- * @brief ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT
+ * @brief ESP_GAP_BLE_SET_CSA_SUPPORT_COMPLETE_EVT
+ */
+ struct ble_set_csa_support_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate CSA support set operation success status */
+ } set_csa_support_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_CSA_SUPPORT_COMPLETE_EVT */
+ /**
+ * @brief ESP_GAP_BLE_SET_VENDOR_EVT_MASK_COMPLETE_EVT
+ */
+ struct ble_set_vendor_evt_mask_cmpl_evt_param {
+ esp_bt_status_t status; /*!< Indicate set vendor event mask operation success status */
+ } set_vendor_evt_mask_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_VENDOR_EVT_MASK_COMPLETE_EVT */
+ /**
+ * @brief ESP_GAP_BLE_VENDOR_HCI_EVT
+ */
+ struct ble_vendor_hci_event_evt_param {
+ esp_ble_vendor_evt_t subevt_code; /*!< Subevent code for BLE vendor HCI event */
+ esp_ble_vendor_evt_param_t param; /*!< Event parameter of BLE vendor HCI subevent */
+ uint8_t param_len; /*!< The length of the event parameter buffer (for internal use only) */
+ uint8_t *param_buf; /*!< The pointer of the event parameter buffer (for internal use only) */
+ } vendor_hci_evt; /*!< Event parameter of ESP_GAP_BLE_VENDOR_HCI_EVT */
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ /**
+ * @brief ESP_GAP_BLE_ENH_READ_TRANS_PWR_LEVEL_EVT
+ */
+ struct ble_enh_read_trans_pwr_level_param {
+ esp_bt_status_t status; /*!< Indicate enhance reading transmit power level complete status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< Connection_Handle */
+ uint8_t phy; /*!< 1M, 2M, Coded S2 or Coded S8 phy
+ 0x01: LE 1M PHY
+ 0x02: LE 2M PHY
+ 0x03: LE Coded PHY with S=8 data coding
+ 0x04: LE Coded PHY with S=2 data coding
+ */
+ int8_t cur_tx_pwr_level; /*!< Current transmit power level, Range: -127 to 20, Units: dBm */
+ int8_t max_tx_pwr_level; /*!< Maximum transmit power level, Range: -127 to 20, Units: dBm */
+ } enh_trans_pwr_level_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_CSA_SUPPORT_COMPLETE_EVT */
+ /**
+ * @brief ESP_GAP_BLE_READ_REMOTE_TRANS_PWR_LEVEL_EVT
+ */
+ struct ble_read_remote_trans_pwr_level_param {
+ esp_bt_status_t status; /*!< Indicate reading remote transmit power level complete status, status = (controller error code | 0x100) if status is not equal to 0 */
+ } read_remote_trans_pwr_level_cmpl; /*!< Event parameter of ESP_GAP_BLE_READ_REMOTE_TRANS_PWR_LEVEL_EVT */
+ /**
+ * @brief ESP_GAP_BLE_SET_PATH_LOSS_RPTING_PARAMS_EVT
+ */
+ struct ble_set_path_loss_rpting_param {
+ esp_bt_status_t status; /*!< Indicate setting path loss reporting paramwters complete status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The ACL connection identifier */
+ } set_path_loss_rpting_params; /*!< Event parameter of ESP_GAP_BLE_SET_PATH_LOSS_RPTING_PARAMS_EVT */
+ /**
+ * @brief ESP_GAP_BLE_SET_PATH_LOSS_RPTING_ENABLE_EVT
+ */
+ struct ble_set_path_loss_rpting_enable {
+ esp_bt_status_t status; /*!< Indicate setting path loss reporting enable complete status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The ACL connection identifier */
+ } set_path_loss_rpting_enable; /*!< Event parameter of ESP_GAP_BLE_SET_PATH_LOSS_RPTING_ENABLE_EVT */
+ /**
+ * @brief ESP_GAP_BLE_SET_TRANS_PWR_RPTING_ENABLE_EVT
+ */
+ struct ble_set_trans_pwr_rpting_enable {
+ esp_bt_status_t status; /*!< Indicate setting transmit power reporting enable complete status, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The ACL connection identifier */
+ } set_trans_pwr_rpting_enable; /*!< Event parameter of ESP_GAP_BLE_SET_TRANS_PWR_RPTING_ENABLE_EVT */
+ /**
+ * @brief ESP_GAP_BLE_PATH_LOSS_THRESHOLD_EVT
+ */
+ struct ble_path_loss_thres_evt {
+ uint16_t conn_handle; /*!< The ACL connection identifier */
+ uint8_t cur_path_loss; /*!< Current path loss (always zero or positive), Units: dB */
+ esp_ble_path_loss_zone_t zone_entered; /*!< which zone was entered. If cur_path_loss is set to 0xFF then zone_entered shall be ignored */
+ } path_loss_thres_evt; /*!< Event parameter of ESP_GAP_BLE_PATH_LOSS_THRESHOLD_EVT */
+ /**
+ * @brief ESP_GAP_BLE_TRANS_PWR_RPTING_EVT
+ */
+ struct ble_trans_power_report_evt {
+ esp_bt_status_t status; /*!< Indicate esp_ble_gap_read_remote_transmit_power_level() command success, status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< The ACL connection identifier */
+ uint8_t reason; /*!< indicate why the event was sent and the device whose transmit power level is being reported
+ 0x00: Local transmit power changed
+ 0x01: Remote transmit power changed
+ 0x02: esp_ble_gap_read_remote_transmit_power_level() command completed,
+ In this case, the phy, tx_power_level, tx_power_level_flag and delta parameters shall refer to the remote device */
+ esp_ble_tx_power_phy_t phy; /*!< 1M, 2M, Coded S2 or Coded S8 phy
+ 0x01: LE 1M PHY
+ 0x02: LE 2M PHY
+ 0x03: LE Coded PHY with S=8 data coding
+ 0x04: LE Coded PHY with S=2 data coding */
+ int8_t tx_power_level; /*!< Transmit power level, range: -127 to 20, units: dBm
+ 0x7E: Remote device is not managing power levels on this PHY
+ 0x7F: Transmit power level is not available */
+ uint8_t tx_power_level_flag; /*!< whether the transmit power level that is being reported has reached its minimum and/or maximum level */
+ int8_t delta; /*!< Change in transmit power level (positive indicates increased power, negative indicates decreased power, zero indicates unchanged) Units: dB.
+ 0x7F: Change is not available or is out of range */
+ } trans_power_report_evt; /*!< Event parameter of ESP_GAP_BLE_TRANS_PWR_RPTING_EVT */
+
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ /**
+ * @brief ESP_GAP_BLE_SET_DEFAULT_SUBRATE_COMPLETE_EVT
+ */
+ struct ble_default_subrate_evt {
+ esp_bt_status_t status; /*!< Indicate setting default subrate command success, status = (controller error code | 0x100) if status is not equal to 0 */
+ } set_default_subrate_evt; /*!< Event parameter of ESP_GAP_BLE_SET_DEFAULT_SUBRATE_COMPLETE_EVT */
+ /**
+ * @brief ESP_GAP_BLE_SUBRATE_REQUEST_COMPLETE_EVT
+ */
+ struct ble_subrate_request_evt {
+ esp_bt_status_t status; /*!< Indicate subrate request command success, status = (controller error code | 0x100) if status is not equal to 0 */
+ } subrate_req_cmpl_evt; /*!< Event parameter of ESP_GAP_BLE_SUBRATE_REQUEST_COMPLETE_EVT */
+ /**
+ * @brief ESP_GAP_BLE_SUBRATE_CHANGE_EVT
+ */
+ struct ble_subrate_change_evt {
+ esp_bt_status_t status; /*!< command succeeded or this event was generated following a request from the peer device. status = (controller error code | 0x100) if status is not equal to 0 */
+ uint16_t conn_handle; /*!< connection handle */
+ uint16_t subrate_factor; /*!< New subrate factor applied to the specified underlying connection interval, range 0x0001 to 0x01F4 */
+ uint16_t peripheral_latency; /*!< New Peripheral latency for the connection in number of subrated connection events, range: 0x0000 to 0x01F3 */
+ uint16_t continuation_number; /*!< Number of underlying connection events to remain active after a packet containing a Link Layer PDU with a non-zero Length field is sent or received, range: 0x0000 to 0x01F3 */
+ uint16_t supervision_timeout; /*!< New supervision timeout for this connection(Time = N × 10 ms). Range: 0x000A to 0x0C80, Time Range: 100 ms to 32 s */
+ } subrate_change_evt; /*!< Event parameter of ESP_GAP_BLE_SUBRATE_CHANGE_EVT */
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ /**
+ * @brief ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT
*/
- struct ble_set_privacy_mode_cmpl_evt_param {
- esp_bt_status_t status; /*!< Indicate privacy mode set operation success status */
- } set_privacy_mode_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT */
+ struct ble_set_host_feature_evt_param {
+ esp_bt_status_t status; /*!< Indicate host feature update success status */
+ } host_feature; /*!< Event parameter of ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT */
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
} esp_ble_gap_cb_param_t;
/**
@@ -1533,6 +1872,8 @@ typedef void (* esp_gap_ble_cb_t)(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_p
*
* @param[in] callback: callback function
*
+ * @note Avoid performing time-consuming operations within the callback functions.
+ *
* @return
* - ESP_OK : success
* - other : failed
@@ -1583,7 +1924,8 @@ esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params);
/**
* @brief This procedure keep the device scanning the peer device which advertising on the air
*
- * @param[in] duration: Keeping the scanning time, the unit is second.
+ * @param[in] duration: The scanning duration in seconds.
+ * Set to 0 for continuous scanning until explicitly stopped.
*
* @return
* - ESP_OK : success
@@ -1748,15 +2090,19 @@ esp_err_t esp_ble_gap_clear_rand_addr(void);
esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable);
/**
- * @brief set local gap appearance icon
+ * @brief Set the local GAP appearance icon.
*
+ * @note This API does not restrict the input icon value.
+ * If an undefined or incorrect icon value is used, the device icon may not display properly.
*
- * @param[in] icon - External appearance value, these values are defined by the Bluetooth SIG, please refer to
+ * For a complete list of valid appearance values, please refer to "2.6.2 Appearance Category ranges" at:
* https://www.bluetooth.com/specifications/assigned-numbers/
*
+ * @param[in] icon - External appearance value (16-bit), as defined by the Bluetooth SIG.
+ *
* @return
- * - ESP_OK : success
- * - other : failed
+ * - ESP_OK : Success
+ * - ESP_FAIL : Internal failure
*
*/
esp_err_t esp_ble_gap_config_local_icon (uint16_t icon);
@@ -1850,17 +2196,41 @@ esp_err_t esp_ble_gap_get_device_name(void);
*
*/
esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t * addr_type);
+
+/**
+ * @brief This function is called to get ADV data for a specific type.
+ *
+ * @note This is the recommended function to use for resolving ADV data by type.
+ * It improves upon the deprecated `esp_ble_resolve_adv_data` function by
+ * including an additional parameter to specify the length of the ADV data,
+ * thereby offering better safety and reliability.
+ *
+ * @param[in] adv_data - pointer of ADV data which to be resolved
+ * @param[in] adv_data_len - the length of ADV data which to be resolved.
+ * @param[in] type - finding ADV data type
+ * @param[out] length - return the length of ADV data not including type
+ *
+ * @return pointer of ADV data
+ *
+ */
+uint8_t *esp_ble_resolve_adv_data_by_type( uint8_t *adv_data, uint16_t adv_data_len, esp_ble_adv_data_type type, uint8_t *length);
+
/**
* @brief This function is called to get ADV data for a specific type.
*
- * @param[in] adv_data - pointer of ADV data which to be resolved
- * @param[in] type - finding ADV data type
- * @param[out] length - return the length of ADV data not including type
+ * @note This function has been deprecated and will be removed in a future release.
+ * Please use `esp_ble_resolve_adv_data_by_type` instead, which provides
+ * better parameter validation and supports more accurate data resolution.
*
- * @return pointer of ADV data
+ * @param[in] adv_data - pointer of ADV data which to be resolved
+ * @param[in] type - finding ADV data type
+ * @param[out] length - return the length of ADV data not including type
+ *
+ * @return pointer of ADV data
*
*/
uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);
+
#if (BLE_42_FEATURE_SUPPORT == TRUE)
/**
* @brief This function is called to set raw advertising data. User need to fill
@@ -1902,6 +2272,7 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d
* - other : failed
*/
esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr);
+
#if (BLE_42_FEATURE_SUPPORT == TRUE)
/**
* @brief This function is called to add a device info into the duplicate scan exceptional list.
@@ -2150,6 +2521,18 @@ esp_err_t esp_ble_get_current_conn_params(esp_bd_addr_t bd_addr, esp_gap_conn_pa
esp_err_t esp_gap_ble_set_channels(esp_gap_ble_channels channels);
/**
+* @brief This function is used to read the current channel map
+* for the connection identified by remote address.
+*
+* @param[in] bd_addr : BD address of the peer device
+*
+* @return - ESP_OK : success
+* - other : failed
+*
+*/
+esp_err_t esp_ble_gap_read_channel_map(esp_bd_addr_t bd_addr);
+
+/**
* @brief This function is called to authorized a link after Authentication(MITM protection)
*
* @param[in] bd_addr: BD address of the peer device.
@@ -2397,15 +2780,17 @@ esp_err_t esp_ble_gap_periodic_adv_stop(uint8_t instance);
esp_err_t esp_ble_gap_set_ext_scan_params(const esp_ble_ext_scan_params_t *params);
/**
-* @brief This function is used to enable scanning.
+* @brief Enables extended scanning.
*
-* @param[in] duration Scan duration time, where Time = N * 10 ms. Range: 0x0001 to 0xFFFF.
-* @param[in] period Time interval from when the Controller started its last Scan Duration until it begins the subsequent Scan Duration.
-* Time = N * 1.28 sec. Range: 0x0001 to 0xFFFF.
+* @param[in] duration Scan duration in units of 10 ms.
+* - Range: 0x0001 to 0xFFFF (Time = N * 10 ms).
+* - 0x0000: Scan continuously until explicitly disabled.
*
+* @param[in] period Time interval between the start of consecutive scan durations, in units of 1.28 seconds.
+* - Range: 0x0001 to 0xFFFF (Time = N * 1.28 sec).
+* - 0x0000: Scan continuously.
* @return - ESP_OK : success
* - other : failed
-*
*/
esp_err_t esp_ble_gap_start_ext_scan(uint32_t duration, uint16_t period);
@@ -2490,6 +2875,17 @@ esp_err_t esp_ble_gap_periodic_adv_remove_dev_from_list(esp_ble_addr_type_t addr
esp_err_t esp_ble_gap_periodic_adv_clear_dev(void);
/**
+ * @brief Retrieve the capacity of the periodic advertiser list in the controller.
+ *
+ * @param[out] size: Pointer to a variable where the capacity of the periodic advertiser list will be stored.
+ *
+ * @return
+ * - ESP_OK : Success
+ * - Others : Failure
+ */
+esp_err_t esp_ble_gap_get_periodic_list_size(uint8_t *size);
+
+/**
* @brief This function is used to set aux connection parameters
*
* @param[in] addr : device address
@@ -2507,7 +2903,6 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr,
const esp_ble_gap_conn_params_t *phy_1m_conn_params,
const esp_ble_gap_conn_params_t *phy_2m_conn_params,
const esp_ble_gap_conn_params_t *phy_coded_conn_params);
-
#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
@@ -2667,6 +3062,155 @@ esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cm
*/
esp_err_t esp_ble_gap_set_privacy_mode(esp_ble_addr_type_t addr_type, esp_bd_addr_t addr, esp_ble_privacy_mode_t mode);
+/**
+ * @brief This function is used to set which channel selection algorithm(CSA) is supported.
+ *
+ * @note - This function should only be used when there are BLE compatibility issues about channel hopping after connected.
+ * For example, if the peer device only supports CSA#1, this function can be called to make the Controller use CSA#1.
+ * - This function is not supported on ESP32.
+ *
+ * @param[in] csa_select: 0: Channel Selection Algorighm will be selected by Controller
+ * 1: Select the LE Channel Selection Algorighm #1
+ * 2: Select the LE Channel Selection Algorighm #2
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_set_csa_support(uint8_t csa_select);
+
+/**
+ * @brief This function is used to control which vendor events are generated by the HCI for the Host.
+ *
+ * @param[in] event_mask: The BLE vendor HCI event mask
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_set_vendor_event_mask(esp_ble_vendor_evt_mask_t event_mask);
+
+/**
+ * @brief This function is used to read the current and maximum transmit power levels of the local Controller.
+ *
+ *
+ * @param[in] conn_handle: The ACL connection identified.
+ * @param[in] phy: 1M, 2M, Coded S2 or Coded S8.
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_enhanced_read_transmit_power_level(uint16_t conn_handle, esp_ble_tx_power_phy_t phy);
+
+/**
+ * @brief This function is used to read the transmit power level used by the remote Controller on the ACL connection.
+ *
+ *
+ * @param[in] conn_handle: The ACL connection identifier.
+ * @param[in] phy: 1M, 2M, Coded S2 or Coded S8.
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_read_remote_transmit_power_level(uint16_t conn_handle, esp_ble_tx_power_phy_t phy);
+
+/**
+ * @brief This function is used to set the path loss threshold reporting parameters.
+ *
+ *
+ * @param[in] path_loss_rpt_params: The path loss threshold reporting parameters.
+ *
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_set_path_loss_reporting_params(esp_ble_path_loss_rpt_params_t *path_loss_rpt_params);
+
+/**
+ * @brief This function is used to enable or disable path loss reporting.
+ *
+ *
+ * @param[in] conn_handle: The ACL connection identifier.
+ * @param[in] enable: Reporting disabled or enabled.
+ *
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_set_path_loss_reporting_enable(uint16_t conn_handle, bool enable);
+
+/**
+ * @brief This function is used to enable or disable the reporting to the local Host of transmit power level changes in the local and remote Controllers.
+ *
+ *
+ * @param[in] conn_handle: The ACL connection identifier.
+ * @param[in] local_enable: Disable or enable local transmit power reports.
+ * @param[in] remote_enable: Disable or enable remote transmit power reports.
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, bool local_enable, bool remote_enable);
+
+/**
+ * @brief This function is used to set the initial values for the acceptable parameters for subrating requests,
+ * for all future ACL connections where the Controller is the Central. This command does not affect any
+ * existing connection.
+ *
+ *
+ * @param[in] default_subrate_params: The default subrate parameters.
+ *
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_set_default_subrate(esp_ble_default_subrate_param_t *default_subrate_params);
+
+/**
+ * @brief This function is used by a Central or a Peripheral to request a change to the subrating factor and/or other parameters
+ * applied to an existing connection.
+ *
+ * If this API is issued on the Central, the following rules shall apply when the Controller initiates the Connection Subrate Update procedure:
+ * 1. The Peripheral latency shall be less than or equal to max_latency.
+ * 2. The subrate factor shall be between subrate_min and subrate_max.
+ * 3. The continuation number shall be equal to the lesser of continuation_number and (subrate factor - 1).
+ * 4. The connection supervision timeout shall be equal to supervision_timeout.
+ *
+ * If this API is issued on the Peripheral, the following rules shall apply when the Controller initiates the Connection Subrate Request procedure:
+ * 1. The Peripheral latency shall be less than or equal to max_latency.
+ * 2. The minimum and maximum subrate factors shall be between subrate_min and subrate_max.
+ * 3. The continuation number shall be equal to the lesser of continuation_number and (maximum subrate factor - 1).
+ * 4.The connection supervision timeout shall be equal to supervision_timeout.
+ *
+ *
+ * @param[in] subrate_req_params: The subrate request parameters.
+ *
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_ble_gap_subrate_request(esp_ble_subrate_req_param_t *subrate_req_params);
+
+/**
+ * @brief This function is called to set host feature.
+ *
+ * @param[in] bit_num: the bit position in the FeatureSet.
+ * @param[in] bit_val: the feature is enabled or disabled
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_gap_set_host_feature(uint16_t bit_num, uint8_t bit_val);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h
index 7c75927f..1c05ffc5 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -33,8 +33,9 @@ typedef enum {
ESP_BT_SET_COD_MAJOR_MINOR = 0x01, /*!< overwrite major, minor class */
ESP_BT_SET_COD_SERVICE_CLASS = 0x02, /*!< set the bits in the input, the current bit will remain */
ESP_BT_CLR_COD_SERVICE_CLASS = 0x04, /*!< clear the bits in the input, others will remain */
- ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class */
- ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class */
+ ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class, reserved_2 remain unchanged */
+ ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class, reserved_2 remain unchanged */
+ ESP_BT_SET_COD_RESERVED_2 = 0x10, /*!< overwrite the two least significant bits reserved_2 whose default value is 0b00; other values of reserved_2 are invalid according to Bluetooth Core Specification 5.4 */
} esp_bt_cod_mode_t;
#define ESP_BT_GAP_AFH_CHANNELS_LEN 10
@@ -209,6 +210,28 @@ typedef enum {
ESP_BT_COD_MAJOR_DEV_UNCATEGORIZED = 31, /*!< Uncategorized: device not specified */
} esp_bt_cod_major_dev_t;
+/// Minor device class field of Class of Device for Peripheral Major Class
+typedef enum {
+ ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD = 0x10, /*!< Keyboard */
+ ESP_BT_COD_MINOR_PERIPHERAL_POINTING = 0x20, /*!< Pointing */
+ ESP_BT_COD_MINOR_PERIPHERAL_COMBO = 0x30, /*!< Combo
+ ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD, ESP_BT_COD_MINOR_PERIPHERAL_POINTING
+ and ESP_BT_COD_MINOR_PERIPHERAL_COMBO can be OR'd with one of the
+ following values to identify a multifunctional device. e.g.
+ ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD | ESP_BT_COD_MINOR_PERIPHERAL_GAMEPAD
+ ESP_BT_COD_MINOR_PERIPHERAL_POINTING | ESP_BT_COD_MINOR_PERIPHERAL_SENSING_DEVICE
+ */
+ ESP_BT_COD_MINOR_PERIPHERAL_JOYSTICK = 0x01, /*!< Joystick */
+ ESP_BT_COD_MINOR_PERIPHERAL_GAMEPAD = 0x02, /*!< Gamepad */
+ ESP_BT_COD_MINOR_PERIPHERAL_REMOTE_CONTROL = 0x03, /*!< Remote Control */
+ ESP_BT_COD_MINOR_PERIPHERAL_SENSING_DEVICE = 0x04, /*!< Sensing Device */
+ ESP_BT_COD_MINOR_PERIPHERAL_DIGITIZING_TABLET = 0x05, /*!< Digitizing Tablet */
+ ESP_BT_COD_MINOR_PERIPHERAL_CARD_READER = 0x06, /*!< Card Reader */
+ ESP_BT_COD_MINOR_PERIPHERAL_DIGITAL_PAN = 0x07, /*!< Digital Pan */
+ ESP_BT_COD_MINOR_PERIPHERAL_HAND_SCANNER = 0x08, /*!< Hand Scanner */
+ ESP_BT_COD_MINOR_PERIPHERAL_HAND_GESTURAL_INPUT = 0x09, /*!< Hand Gestural Input */
+} esp_bt_cod_minor_peripheral_t;
+
/// Bits of major device class field
#define ESP_BT_COD_MAJOR_DEV_BIT_MASK (0x1f00) /*!< Major device bit mask */
#define ESP_BT_COD_MAJOR_DEV_BIT_OFFSET (8) /*!< Major device bit offset */
@@ -290,6 +313,14 @@ typedef enum {
#define ESP_BT_GAP_TPOLL_DFT (0x0028) /*!< Default poll interval, unit is 625 microseconds */
#define ESP_BT_GAP_TPOLL_MAX (0x1000) /*!< Maximum poll interval, unit is 625 microseconds */
+/** GAP status */
+typedef struct {
+ esp_bt_gap_discovery_state_t disc_stat; /*!< Device Discovery state */
+ esp_bt_connection_mode_t conn_mode; /*!< Connection mode */
+ esp_bt_discovery_mode_t disc_mode; /*!< Discovery mode */
+ uint8_t bredr_acl_link_num; /*!< Number of bredr link connections */
+} esp_bt_gap_profile_status_t;
+
/// GAP state callback parameters
typedef union {
/**
@@ -417,8 +448,9 @@ typedef union {
* @brief ESP_BT_GAP_MODE_CHG_EVT
*/
struct mode_chg_param {
- esp_bd_addr_t bda; /*!< remote bluetooth device address*/
- esp_bt_pm_mode_t mode; /*!< PM mode*/
+ esp_bd_addr_t bda; /*!< remote bluetooth device address */
+ esp_bt_pm_mode_t mode; /*!< PM mode */
+ uint16_t interval; /*!< Number of baseband slots. unit is 0.625ms */
} mode_chg; /*!< mode change event parameter struct */
/**
@@ -959,6 +991,17 @@ esp_err_t esp_bt_gap_set_device_name(const char *name);
*/
esp_err_t esp_bt_gap_get_device_name(void);
+/**
+ * @brief Get the status of GAP
+ *
+ * @param[out] profile_status - GAP status
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ */
+esp_err_t esp_bt_gap_get_profile_status(esp_bt_gap_profile_status_t *profile_status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h b/lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h
index 77f03e8b..e8cc134c 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_gatt_defs.h
@@ -478,7 +478,7 @@ typedef uint8_t esp_gatt_char_prop_t;
*
* This definition specifies the maximum number of bytes that a GATT attribute can hold.
*/
-#define ESP_GATT_MAX_ATTR_LEN 512 /*!< As same as GATT_MAX_ATTR_LEN. */
+#define ESP_GATT_MAX_ATTR_LEN 517 /*!< As same as GATT_MAX_ATTR_LEN. */
/**
* @brief Enumerates the possible sources of a GATT service discovery.
@@ -682,6 +682,19 @@ typedef struct {
esp_bt_uuid_t uuid; /*!< Included service UUID. */
} esp_gattc_incl_svc_elem_t;
+/** @brief Represents a creat connection element. */
+typedef struct {
+ esp_bd_addr_t remote_bda; /*!< The Bluetooth address of the remote device */
+ esp_ble_addr_type_t remote_addr_type; /*!< Address type of the remote device */
+ bool is_direct; /*!< Direct connection or background auto connection(by now, background auto connection is not supported */
+ bool is_aux; /*!< Set to true for BLE 5.0 or higher to enable auxiliary connections; set to false for BLE 4.2 or lower. */
+ esp_ble_addr_type_t own_addr_type; /*!< Specifies the address type used in the connection request. Set to 0xFF if the address type is unknown. */
+ esp_ble_phy_mask_t phy_mask; /*!< Indicates which PHY connection parameters will be used. When is_aux is false, only the connection params for 1M PHY can be specified */
+ const esp_ble_conn_params_t *phy_1m_conn_params; /*!< Connection parameters for the LE 1M PHY */
+ const esp_ble_conn_params_t *phy_2m_conn_params; /*!< Connection parameters for the LE 2M PHY */
+ const esp_ble_conn_params_t *phy_coded_conn_params; /*!< Connection parameters for the LE Coded PHY */
+} esp_ble_gatt_creat_conn_params_t;
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h
index 13bf16a3..0d9837a5 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_gattc_api.h
@@ -15,411 +15,465 @@
extern "C" {
#endif
-/// GATT Client callback function events
+/**
+ * @brief GATT Client callback function events
+ */
typedef enum {
- ESP_GATTC_REG_EVT = 0, /*!< When GATT client is registered, the event comes */
- ESP_GATTC_UNREG_EVT = 1, /*!< When GATT client is unregistered, the event comes */
- ESP_GATTC_OPEN_EVT = 2, /*!< When GATT virtual connection is set up, the event comes */
- ESP_GATTC_READ_CHAR_EVT = 3, /*!< When GATT characteristic is read, the event comes */
- ESP_GATTC_WRITE_CHAR_EVT = 4, /*!< When GATT characteristic write operation completes, the event comes */
- ESP_GATTC_CLOSE_EVT = 5, /*!< When GATT virtual connection is closed, the event comes */
- ESP_GATTC_SEARCH_CMPL_EVT = 6, /*!< When GATT service discovery is completed, the event comes */
- ESP_GATTC_SEARCH_RES_EVT = 7, /*!< When GATT service discovery result is got, the event comes */
- ESP_GATTC_READ_DESCR_EVT = 8, /*!< When GATT characteristic descriptor read completes, the event comes */
- ESP_GATTC_WRITE_DESCR_EVT = 9, /*!< When GATT characteristic descriptor write completes, the event comes */
- ESP_GATTC_NOTIFY_EVT = 10, /*!< When GATT notification or indication arrives, the event comes */
- ESP_GATTC_PREP_WRITE_EVT = 11, /*!< When GATT prepare-write operation completes, the event comes */
- ESP_GATTC_EXEC_EVT = 12, /*!< When write execution completes, the event comes */
- ESP_GATTC_ACL_EVT = 13, /*!< When ACL connection is up, the event comes */
- ESP_GATTC_CANCEL_OPEN_EVT = 14, /*!< When GATT client ongoing connection is cancelled, the event comes */
- ESP_GATTC_SRVC_CHG_EVT = 15, /*!< When "service changed" occurs, the event comes */
- ESP_GATTC_ENC_CMPL_CB_EVT = 17, /*!< When encryption procedure completes, the event comes */
- ESP_GATTC_CFG_MTU_EVT = 18, /*!< When configuration of MTU completes, the event comes */
- ESP_GATTC_ADV_DATA_EVT = 19, /*!< When advertising of data, the event comes */
- ESP_GATTC_MULT_ADV_ENB_EVT = 20, /*!< When multi-advertising is enabled, the event comes */
- ESP_GATTC_MULT_ADV_UPD_EVT = 21, /*!< When multi-advertising parameters are updated, the event comes */
- ESP_GATTC_MULT_ADV_DATA_EVT = 22, /*!< When multi-advertising data arrives, the event comes */
- ESP_GATTC_MULT_ADV_DIS_EVT = 23, /*!< When multi-advertising is disabled, the event comes */
- ESP_GATTC_CONGEST_EVT = 24, /*!< When GATT connection congestion comes, the event comes */
- ESP_GATTC_BTH_SCAN_ENB_EVT = 25, /*!< When batch scan is enabled, the event comes */
- ESP_GATTC_BTH_SCAN_CFG_EVT = 26, /*!< When batch scan storage is configured, the event comes */
- ESP_GATTC_BTH_SCAN_RD_EVT = 27, /*!< When Batch scan read event is reported, the event comes */
- ESP_GATTC_BTH_SCAN_THR_EVT = 28, /*!< When Batch scan threshold is set, the event comes */
- ESP_GATTC_BTH_SCAN_PARAM_EVT = 29, /*!< When Batch scan parameters are set, the event comes */
- ESP_GATTC_BTH_SCAN_DIS_EVT = 30, /*!< When Batch scan is disabled, the event comes */
- ESP_GATTC_SCAN_FLT_CFG_EVT = 31, /*!< When Scan filter configuration completes, the event comes */
- ESP_GATTC_SCAN_FLT_PARAM_EVT = 32, /*!< When Scan filter parameters are set, the event comes */
- ESP_GATTC_SCAN_FLT_STATUS_EVT = 33, /*!< When Scan filter status is reported, the event comes */
- ESP_GATTC_ADV_VSC_EVT = 34, /*!< When advertising vendor spec content event is reported, the event comes */
- ESP_GATTC_REG_FOR_NOTIFY_EVT = 38, /*!< When register for notification of a service completes, the event comes */
- ESP_GATTC_UNREG_FOR_NOTIFY_EVT = 39, /*!< When unregister for notification of a service completes, the event comes */
- ESP_GATTC_CONNECT_EVT = 40, /*!< When the ble physical connection is set up, the event comes */
- ESP_GATTC_DISCONNECT_EVT = 41, /*!< When the ble physical connection disconnected, the event comes */
- ESP_GATTC_READ_MULTIPLE_EVT = 42, /*!< When the ble characteristic or descriptor multiple complete, the event comes */
- ESP_GATTC_QUEUE_FULL_EVT = 43, /*!< When the gattc command queue full, the event comes */
- ESP_GATTC_SET_ASSOC_EVT = 44, /*!< When the ble gattc set the associated address complete, the event comes */
- ESP_GATTC_GET_ADDR_LIST_EVT = 45, /*!< When the ble get gattc address list in cache finish, the event comes */
- ESP_GATTC_DIS_SRVC_CMPL_EVT = 46, /*!< When the ble discover service complete, the event comes */
- ESP_GATTC_READ_MULTI_VAR_EVT = 47, /*!< When read multiple variable characteristic complete, the event comes */
+ ESP_GATTC_REG_EVT = 0, /*!< This event is triggered when a GATT Client application is registered using `esp_ble_gattc_app_register`. */
+ ESP_GATTC_UNREG_EVT = 1, /*!< This event is triggered when a GATT Client application is unregistered using `esp_ble_gattc_app_unregister`. */
+ ESP_GATTC_OPEN_EVT = 2, /*!< This event is triggered when a GATT virtual connection is set up using `esp_ble_gattc_open`. */
+ ESP_GATTC_READ_CHAR_EVT = 3, /*!< This event is triggered upon the completion of a GATT characteristic read operation using `esp_ble_gattc_read_char`. */
+ ESP_GATTC_WRITE_CHAR_EVT = 4, /*!< This event is triggered upon the completion of a GATT characteristic write operation using `esp_ble_gattc_write_char`. */
+ ESP_GATTC_CLOSE_EVT = 5, /*!< This event is triggered when a GATT virtual connection is closed via `esp_ble_gattc_close`, or when the physical connection is terminated. */
+ ESP_GATTC_SEARCH_CMPL_EVT = 6, /*!< This event is triggered upon the completion of a service discovery using `esp_ble_gattc_search_service`. */
+ ESP_GATTC_SEARCH_RES_EVT = 7, /*!< This event is triggered each time a service result is obtained using `esp_ble_gattc_search_service`. */
+ ESP_GATTC_READ_DESCR_EVT = 8, /*!< This event is triggered upon the completion of a GATT characteristic descriptor read operation using `esp_ble_gattc_read_char_descr`. */
+ ESP_GATTC_WRITE_DESCR_EVT = 9, /*!< This event is triggered upon the completion of a GATT characteristic descriptor write operation using `esp_ble_gattc_write_char_descr`. */
+ ESP_GATTC_NOTIFY_EVT = 10, /*!< This event is triggered when a GATT notification or indication is received from the Server. */
+ ESP_GATTC_PREP_WRITE_EVT = 11, /*!< This event is triggered upon the completion of a GATT prepare-write operation using `esp_ble_gattc_prepare_write`. */
+ ESP_GATTC_EXEC_EVT = 12, /*!< This event is triggered upon the completion of a GATT write execution using `esp_ble_gattc_execute_write` .*/
+ ESP_GATTC_ACL_EVT = 13, /*!< Deprecated. */
+ ESP_GATTC_CANCEL_OPEN_EVT = 14, /*!< Deprecated. */
+ ESP_GATTC_SRVC_CHG_EVT = 15, /*!< This event is triggered when a service changed indication is received from the Server, indicating that the attribute database on the Server has been modified (e.g., services have been added, removed). */
+ ESP_GATTC_ENC_CMPL_CB_EVT = 17, /*!< Deprecated. */
+ ESP_GATTC_CFG_MTU_EVT = 18, /*!< This event is triggered upon the completion of the MTU configuration with `esp_ble_gattc_send_mtu_req`. */
+ ESP_GATTC_ADV_DATA_EVT = 19, /*!< Deprecated. */
+ ESP_GATTC_MULT_ADV_ENB_EVT = 20, /*!< Deprecated. */
+ ESP_GATTC_MULT_ADV_UPD_EVT = 21, /*!< Deprecated. */
+ ESP_GATTC_MULT_ADV_DATA_EVT = 22, /*!< Deprecated. */
+ ESP_GATTC_MULT_ADV_DIS_EVT = 23, /*!< Deprecated. */
+ ESP_GATTC_CONGEST_EVT = 24, /*!< This event is triggered when the GATT connection is congested. */
+ ESP_GATTC_BTH_SCAN_ENB_EVT = 25, /*!< Deprecated. */
+ ESP_GATTC_BTH_SCAN_CFG_EVT = 26, /*!< Deprecated. */
+ ESP_GATTC_BTH_SCAN_RD_EVT = 27, /*!< Deprecated. */
+ ESP_GATTC_BTH_SCAN_THR_EVT = 28, /*!< Deprecated. */
+ ESP_GATTC_BTH_SCAN_PARAM_EVT = 29, /*!< Deprecated. */
+ ESP_GATTC_BTH_SCAN_DIS_EVT = 30, /*!< Deprecated. */
+ ESP_GATTC_SCAN_FLT_CFG_EVT = 31, /*!< Deprecated. */
+ ESP_GATTC_SCAN_FLT_PARAM_EVT = 32, /*!< Deprecated. */
+ ESP_GATTC_SCAN_FLT_STATUS_EVT = 33, /*!< Deprecated. */
+ ESP_GATTC_ADV_VSC_EVT = 34, /*!< Deprecated. */
+ ESP_GATTC_REG_FOR_NOTIFY_EVT = 38, /*!< This event is triggered upon the completion of a service notification registration using `esp_ble_gattc_register_for_notify`. */
+ ESP_GATTC_UNREG_FOR_NOTIFY_EVT = 39, /*!< This event is triggered upon the completion of a service notification unregistration using `esp_ble_gattc_unregister_for_notify`. */
+ ESP_GATTC_CONNECT_EVT = 40, /*!< This event is triggered when the physical connection is set up. */
+ ESP_GATTC_DISCONNECT_EVT = 41, /*!< This event is triggered when the physical connection is terminated. */
+ ESP_GATTC_READ_MULTIPLE_EVT = 42, /*!< This event is triggered when the multiple characteristic or descriptor values are retrieved using `esp_ble_gattc_read_multiple`. */
+ ESP_GATTC_QUEUE_FULL_EVT = 43, /*!< This event is triggered when the GATTC command queue is full. */
+ ESP_GATTC_SET_ASSOC_EVT = 44, /*!< This event is triggered when the association between the source and the remote address is added or deleted using `esp_ble_gattc_cache_assoc`. */
+ ESP_GATTC_GET_ADDR_LIST_EVT = 45, /*!< This event is triggered when retrieving the address list from the GATTC cache is completed using `esp_ble_gattc_cache_get_addr_list`. */
+ ESP_GATTC_DIS_SRVC_CMPL_EVT = 46, /*!< This event is triggered when the GATT service discovery is completed. */
+ ESP_GATTC_READ_MULTI_VAR_EVT = 47, /*!< This event is triggered when multiple variable length characteristic values are retrieved using `esp_ble_gattc_read_multiple`. */
} esp_gattc_cb_event_t;
/**
- * @brief Gatt client callback parameters union
+ * @brief GATT Client callback parameters
*/
typedef union {
+
/**
- * @brief ESP_GATTC_REG_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_REG_EVT`
*/
struct gattc_reg_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t app_id; /*!< Application id which input in register API */
- } reg; /*!< Gatt client callback param of ESP_GATTC_REG_EVT */
+ uint16_t app_id; /*!< Application ID */
+ } reg; /*!< Callback parameter for the event `ESP_GATTC_REG_EVT` */
/**
- * @brief ESP_GATTC_OPEN_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_OPEN_EVT`.
*/
struct gattc_open_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
+ uint16_t conn_id; /*!< Connection ID */
+ esp_bd_addr_t remote_bda; /*!< Remote Bluetooth device address */
uint16_t mtu; /*!< MTU size */
- } open; /*!< Gatt client callback param of ESP_GATTC_OPEN_EVT */
+ } open; /*!< Callback parameter for the event `ESP_GATTC_OPEN_EVT` */
/**
- * @brief ESP_GATTC_CLOSE_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_CLOSE_EVT`
*/
struct gattc_close_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
+ uint16_t conn_id; /*!< Connection ID */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- esp_gatt_conn_reason_t reason; /*!< The reason of gatt connection close */
- } close; /*!< Gatt client callback param of ESP_GATTC_CLOSE_EVT */
+ esp_gatt_conn_reason_t reason; /*!< The reason of GATT connection close */
+ } close; /*!< Callback parameter for the event `ESP_GATTC_CLOSE_EVT` */
/**
- * @brief ESP_GATTC_CFG_MTU_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_CFG_MTU_EVT`
*/
struct gattc_cfg_mtu_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
+ uint16_t conn_id; /*!< Connection ID */
uint16_t mtu; /*!< MTU size */
- } cfg_mtu; /*!< Gatt client callback param of ESP_GATTC_CFG_MTU_EVT */
+ } cfg_mtu; /*!< Callback parameter for the event `ESP_GATTC_CFG_MTU_EVT` */
/**
- * @brief ESP_GATTC_SEARCH_CMPL_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_SEARCH_CMPL_EVT`
*/
struct gattc_search_cmpl_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
+ uint16_t conn_id; /*!< Connection ID */
esp_service_source_t searched_service_source; /*!< The source of the service information */
- } search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */
+ } search_cmpl; /*!< Callback parameter for the event `ESP_GATTC_SEARCH_CMPL_EVT` */
/**
- * @brief ESP_GATTC_SEARCH_RES_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_SEARCH_RES_EVT`
*/
struct gattc_search_res_evt_param {
- uint16_t conn_id; /*!< Connection id */
+ uint16_t conn_id; /*!< Connection ID */
uint16_t start_handle; /*!< Service start handle */
uint16_t end_handle; /*!< Service end handle */
- esp_gatt_id_t srvc_id; /*!< Service id, include service uuid and other information */
- bool is_primary; /*!< True if this is the primary service */
- } search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */
+ esp_gatt_id_t srvc_id; /*!< Service ID, including service UUID and other information */
+ bool is_primary; /*!< True indicates a primary service, false otherwise */
+ } search_res; /*!< Callback parameter for the event `ESP_GATTC_SEARCH_RES_EVT` */
/**
- * @brief ESP_GATTC_READ_CHAR_EVT, ESP_GATTC_READ_DESCR_EVT, ESP_GATTC_READ_MULTIPLE_EVT, ESP_GATTC_READ_MULTI_VAR_EVT
+ * @brief Callback parameter for the events: `ESP_GATTC_READ_CHAR_EVT`, `ESP_GATTC_READ_DESCR_EVT`,
+ * `ESP_GATTC_READ_MULTIPLE_EVT`, `ESP_GATTC_READ_MULTI_VAR_EVT`
*/
struct gattc_read_char_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
+ uint16_t conn_id; /*!< Connection ID */
uint16_t handle; /*!< Characteristic handle */
uint8_t *value; /*!< Characteristic value */
uint16_t value_len; /*!< Characteristic value length */
- } read; /*!< Gatt client callback param of ESP_GATTC_READ_CHAR_EVT */
+ } read; /*!< Callback parameter for events: `ESP_GATTC_READ_CHAR_EVT`, `ESP_GATTC_READ_DESCR_EVT`,
+ `ESP_GATTC_READ_MULTIPLE_EVT`, `ESP_GATTC_READ_MULTI_VAR_EVT` */
/**
- * @brief ESP_GATTC_WRITE_CHAR_EVT, ESP_GATTC_PREP_WRITE_EVT, ESP_GATTC_WRITE_DESCR_EVT
+ * @brief Callback parameter for the events: `ESP_GATTC_WRITE_CHAR_EVT`, `ESP_GATTC_PREP_WRITE_EVT`, `ESP_GATTC_WRITE_DESCR_EVT`.
*/
struct gattc_write_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- uint16_t handle; /*!< The Characteristic or descriptor handle */
- uint16_t offset; /*!< The prepare write offset, this value is valid only when prepare write */
- } write; /*!< Gatt client callback param of ESP_GATTC_WRITE_DESCR_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ uint16_t handle; /*!< The characteristic or descriptor handle */
+ uint16_t offset; /*!< The position offset to write. This value is valid only for prepare write operation. */
+ } write; /*!< Callback parameter for the events: `ESP_GATTC_WRITE_CHAR_EVT`, `ESP_GATTC_PREP_WRITE_EVT`, `ESP_GATTC_WRITE_DESCR_EVT` */
/**
- * @brief ESP_GATTC_EXEC_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_EXEC_EVT`
*/
struct gattc_exec_cmpl_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- } exec_cmpl; /*!< Gatt client callback param of ESP_GATTC_EXEC_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ } exec_cmpl; /*!< Callback parameter for the event `ESP_GATTC_EXEC_EVT` */
/**
- * @brief ESP_GATTC_NOTIFY_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_NOTIFY_EVT`
*/
struct gattc_notify_evt_param {
- uint16_t conn_id; /*!< Connection id */
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- uint16_t handle; /*!< The Characteristic or descriptor handle */
- uint16_t value_len; /*!< Notify attribute value */
+ uint16_t conn_id; /*!< Connection ID */
+ esp_bd_addr_t remote_bda; /*!< Remote Bluetooth device address. */
+ uint16_t handle; /*!< The characteristic or descriptor handle */
+ uint16_t value_len; /*!< Notify attribute value length in bytes */
uint8_t *value; /*!< Notify attribute value */
- bool is_notify; /*!< True means notify, false means indicate */
- } notify; /*!< Gatt client callback param of ESP_GATTC_NOTIFY_EVT */
+ bool is_notify; /*!< True means notification; false means indication */
+ } notify; /*!< Callback parameter for the event `ESP_GATTC_NOTIFY_EVT` */
/**
- * @brief ESP_GATTC_SRVC_CHG_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_SRVC_CHG_EVT`
*/
struct gattc_srvc_chg_evt_param {
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- } srvc_chg; /*!< Gatt client callback param of ESP_GATTC_SRVC_CHG_EVT */
+ esp_bd_addr_t remote_bda; /*!< Remote Bluetooth device address */
+ } srvc_chg; /*!< Callback parameter for the event `ESP_GATTC_SRVC_CHG_EVT` */
/**
- * @brief ESP_GATTC_CONGEST_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_CONGEST_EVT`
*/
struct gattc_congest_evt_param {
- uint16_t conn_id; /*!< Connection id */
- bool congested; /*!< Congested or not */
- } congest; /*!< Gatt client callback param of ESP_GATTC_CONGEST_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ bool congested; /*!< True indicates that the connection is congested, false otherwise */
+ } congest; /*!< Callback parameter for the event `ESP_GATTC_CONGEST_EVT` */
/**
- * @brief ESP_GATTC_REG_FOR_NOTIFY_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_REG_FOR_NOTIFY_EVT`
*/
struct gattc_reg_for_notify_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t handle; /*!< The characteristic or descriptor handle */
- } reg_for_notify; /*!< Gatt client callback param of ESP_GATTC_REG_FOR_NOTIFY_EVT */
+ } reg_for_notify; /*!< Callback parameter for the event `ESP_GATTC_REG_FOR_NOTIFY_EVT` */
/**
- * @brief ESP_GATTC_UNREG_FOR_NOTIFY_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_UNREG_FOR_NOTIFY_EVT`
*/
struct gattc_unreg_for_notify_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t handle; /*!< The characteristic or descriptor handle */
- } unreg_for_notify; /*!< Gatt client callback param of ESP_GATTC_UNREG_FOR_NOTIFY_EVT */
+ } unreg_for_notify; /*!< Callback parameter for the event `ESP_GATTC_UNREG_FOR_NOTIFY_EVT` */
/**
- * @brief ESP_GATTC_CONNECT_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_CONNECT_EVT`
*/
struct gattc_connect_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint8_t link_role; /*!< Link role : master role = 0 ; slave role = 1*/
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- esp_gatt_conn_params_t conn_params; /*!< current connection parameters */
- esp_ble_addr_type_t ble_addr_type; /*!< Remote BLE device address type */
- uint16_t conn_handle; /*!< HCI connection handle */
- } connect; /*!< Gatt client callback param of ESP_GATTC_CONNECT_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ uint8_t link_role; /*!< Link role : master role = 0; slave role = 1 */
+ esp_bd_addr_t remote_bda; /*!< Remote device address */
+ esp_gatt_conn_params_t conn_params; /*!< Current connection parameters */
+ esp_ble_addr_type_t ble_addr_type; /*!< Remote device address type */
+ uint16_t conn_handle; /*!< HCI connection handle */
+ } connect; /*!< Callback parameter for the event `ESP_GATTC_CONNECT_EVT` */
/**
- * @brief ESP_GATTC_DISCONNECT_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_DISCONNECT_EVT`
*/
struct gattc_disconnect_evt_param {
- esp_gatt_conn_reason_t reason; /*!< disconnection reason */
- uint16_t conn_id; /*!< Connection id */
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- } disconnect; /*!< Gatt client callback param of ESP_GATTC_DISCONNECT_EVT */
+ esp_gatt_conn_reason_t reason; /*!< Disconnection reason */
+ uint16_t conn_id; /*!< Connection ID */
+ esp_bd_addr_t remote_bda; /*!< Remote device address */
+ } disconnect; /*!< Callback parameter for the event `ESP_GATTC_DISCONNECT_EVT` */
+
/**
- * @brief ESP_GATTC_SET_ASSOC_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_SET_ASSOC_EVT`
*/
struct gattc_set_assoc_addr_cmp_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- } set_assoc_cmp; /*!< Gatt client callback param of ESP_GATTC_SET_ASSOC_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ } set_assoc_cmp; /*!< Callback parameter for the event `ESP_GATTC_SET_ASSOC_EVT` */
+
/**
- * @brief ESP_GATTC_GET_ADDR_LIST_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_GET_ADDR_LIST_EVT`
*/
struct gattc_get_addr_list_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint8_t num_addr; /*!< The number of address in the gattc cache address list */
- esp_bd_addr_t *addr_list; /*!< The pointer to the address list which has been get from the gattc cache */
- } get_addr_list; /*!< Gatt client callback param of ESP_GATTC_GET_ADDR_LIST_EVT */
+ uint8_t num_addr; /*!< The number of addresses in the local GATTC cache address list */
+ esp_bd_addr_t *addr_list; /*!< The pointer to the address list which has been retrieved from the local GATTC cache */
+ } get_addr_list; /*!< Callback parameter for the event `ESP_GATTC_GET_ADDR_LIST_EVT` */
/**
- * @brief ESP_GATTC_QUEUE_FULL_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_QUEUE_FULL_EVT`
*/
struct gattc_queue_full_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- bool is_full; /*!< The gattc command queue is full or not */
- } queue_full; /*!< Gatt client callback param of ESP_GATTC_QUEUE_FULL_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ bool is_full; /*!< True indicates the GATTC command queue is full; false otherwise. */
+ } queue_full; /*!< Callback parameter for the event `ESP_GATTC_QUEUE_FULL_EVT` */
/**
- * @brief ESP_GATTC_DIS_SRVC_CMPL_EVT
+ * @brief Callback parameter for the event `ESP_GATTC_DIS_SRVC_CMPL_EVT`
*/
struct gattc_dis_srvc_cmpl_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- } dis_srvc_cmpl; /*!< Gatt client callback param of ESP_GATTC_DIS_SRVC_CMPL_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ } dis_srvc_cmpl; /*!< Callback parameter for the event `ESP_GATTC_DIS_SRVC_CMPL_EVT` */
-} esp_ble_gattc_cb_param_t; /*!< GATT client callback parameter union type */
+} esp_ble_gattc_cb_param_t;
/**
* @brief GATT Client callback function type
- * @param event : Event type
- * @param gattc_if : GATT client access interface, normally
- * different gattc_if correspond to different profile
- * @param param : Point to callback parameter, currently is union type
+ *
+ * @param[in] event Event type
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] param The pointer to callback parameter
*/
typedef void (* esp_gattc_cb_t)(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
/**
- * @brief This function is called to register application callbacks
- * with GATTC module.
+ * @brief Register GATT Client application callbacks
*
- * @param[in] callback : pointer to the application callback function.
+ * @param[in] callback The pointer to the application callback function
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note Avoid performing time-consuming operations within the callback functions.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback);
/**
- * @brief This function is called to get the current application callbacks
- * with BTA GATTC module.
+ * @brief Get the current application callbacks
*
* @return
- * - esp_gattC_cb_t : current callback
- *
+ * - esp_gattc_cb_t: Current callback
*/
esp_gattc_cb_t esp_ble_gattc_get_callback(void);
/**
- * @brief This function is called to register application callbacks
- * with GATTC module.
+ * @brief Register a GATT Client application
*
- * @param[in] app_id : Application Identify (UUID), for different application
+ * @param[in] app_id The UUID for different application
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_REG_EVT`.
+ * 2. The maximum number of applications is limited to 4.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_ARG: The input `app_id` exceeds `ESP_APP_ID_MAX` (0x7fff) defined in esp_bt_defs.h
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_app_register(uint16_t app_id);
-
/**
- * @brief This function is called to unregister an application
- * from GATTC module.
+ * @brief Unregister a GATT Client application
*
- * @param[in] gattc_if: Gatt client access interface.
+ * @param[in] gattc_if GATT Client access interface
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note This function triggers `ESP_GATTC_UNREG_EVT`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if);
-#if (BLE_42_FEATURE_SUPPORT == TRUE)
/**
- * @brief Open a direct connection or add a background auto connection
+ * @brief Create an ACL connection
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] remote_bda: remote device bluetooth device address.
- * @param[in] remote_addr_type: remote device bluetooth device the address type.
- * @param[in] is_direct: direct connection or background auto connection(by now, background auto connection is not supported).
+ * @note
+ * 1. Do not enable `BT_BLE_42_FEATURES_SUPPORTED` and `BT_BLE_50_FEATURES_SUPPORTED` in the menuconfig simultaneously.
+ * 1. The function always triggers `ESP_GATTC_CONNECT_EVT` and `ESP_GATTC_OPEN_EVT`.
+ * 2. When the device acts as GATT server, besides the above two events, this function triggers `ESP_GATTS_CONNECT_EVT` as well.
+ * 3. This function will establish an ACL connection as a Central and a virtual connection as a GATT Client. If the ACL connection already exists, it will create a virtual connection only.
+
+ *
+ * @param[in] gattc_if: GATT client access interface.
+ * @param[in] esp_gatt_create_conn: Pointer to the structure containing connection parameters.
*
* @return
- * - ESP_OK: success
- * - other: failed
+ * - ESP_OK: Success
+ * - others: Operation failed
*
*/
+esp_err_t esp_ble_gattc_enh_open(esp_gatt_if_t gattc_if, esp_ble_gatt_creat_conn_params_t *esp_gatt_create_conn);
+
+/**
+ * @brief Create an ACL connection when `BT_BLE_42_FEATURES_SUPPORTED` is enabled in the menuconfig
+ *
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] remote_bda Remote device address
+ * @param[in] remote_addr_type Remote device address type
+ * @param[in] is_direct `True` indicates a direct connection, while `False` indicates a background auto connection. By now, background auto connection is not supported, please always pass True to this parameter.
+ *
+ * @note
+ * 1. The function always triggers `ESP_GATTC_CONNECT_EVT` and `ESP_GATTC_OPEN_EVT`.
+ * 2. When the device acts as GATT server, besides the above two events, this function triggers `ESP_GATTS_CONNECT_EVT` as well.
+ * 3. This function will establish an ACL connection as a Central and a virtual connection as a GATT Client. If the ACL connection already exists, it will create a virtual connection only.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
+ */
+#if (BLE_42_FEATURE_SUPPORT == TRUE)
esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct);
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
+/**
+ * @brief Create an ACL connection when `BT_BLE_50_FEATURES_SUPPORTED` is enabled in the menuconfig
+ *
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] remote_bda Remote device address
+ * @param[in] remote_addr_type Remote device address type
+ * @param[in] is_direct `True` indicates a direct connection, while `False` indicates a background auto connection. By now, background auto connection is not supported, please always pass True to this parameter.
+ *
+ * @note
+ * 1. The function always triggers `ESP_GATTC_CONNECT_EVT` and `ESP_GATTC_OPEN_EVT`.
+ * 2. When the device acts as GATT server, besides the above two events, this function triggers `ESP_GATTS_CONNECT_EVT` as well.
+ * 3. This function will establish an ACL connection as a Central and a virtual connection as a GATT Client. If the ACL connection already exists, it will create a virtual connection only.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
+ */
#if (BLE_50_FEATURE_SUPPORT == TRUE)
esp_err_t esp_ble_gattc_aux_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct);
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
/**
- * @brief Close the virtual connection to the GATT server. gattc may have multiple virtual GATT server connections when multiple app_id registered,
- * this API only close one virtual GATT server connection. if there exist other virtual GATT server connections,
- * it does not disconnect the physical connection.
- * if you want to disconnect the physical connection directly, you can use esp_ble_gap_disconnect(esp_bd_addr_t remote_device).
+ * @brief Close the virtual GATT Client connection
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID to be closed.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID to be closed
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_CLOSE_EVT`.
+ * 2. There may be multiple virtual GATT server connections when multiple `app_id` got registered.
+ * 3. This API closes one virtual GATT server connection only, if there exist other virtual GATT server connections. It does not close the physical connection.
+ * 4. The API `esp_ble_gap_disconnect` can be used to disconnect the physical connection directly.
+ * 5. If there is only one virtual GATT connection left, this API will terminate the ACL connection in addition and triggers `ESP_GATTC_DISCONNECT_EVT`. Then there is no need to call `esp_ble_gap_disconnect` anymore.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
-esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id);
-
+esp_err_t esp_ble_gattc_close(esp_gatt_if_t gattc_if, uint16_t conn_id);
/**
- * @brief Configure the MTU size in the GATT channel. This can be done
- * only once per connection. Before using, use esp_ble_gatt_set_local_mtu()
- * to configure the local MTU size.
+ * @brief Configure the MTU size in the GATT channel
*
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_CFG_MTU_EVT`.
+ * 2. You could call `esp_ble_gatt_set_local_mtu` to set the desired MTU size locally before this API. If not set, the GATT channel uses the default MTU size (23 bytes).
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gattc_send_mtu_req (esp_gatt_if_t gattc_if, uint16_t conn_id);
-
/**
- * @brief This function is called to get service from local cache.
- * This function report service search result by a callback
- * event, and followed by a service search complete event.
- * Note: 128-bit base UUID will automatically be converted to a 16-bit UUID in the search results. Other types of UUID remain unchanged.
+ * @brief Search services from the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID.
- * @param[in] filter_uuid: a UUID of the service application is interested in.
- * If Null, discover for all services.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] filter_uuid A UUID of the intended service. If NULL is passed, this API will return all services.
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_SEARCH_RES_EVT` each time a service is retrieved.
+ * 2. This function triggers `ESP_GATTC_SEARCH_CMPL_EVT` when the search is completed.
+ * 3. The 128-bit base UUID will be converted to a 16-bit UUID automatically in the search results. Other types of UUID remain unchanged.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *filter_uuid);
/**
- * @brief Find all the service with the given service uuid in the gattc cache, if the svc_uuid is NULL, find all the service.
- * Note: It just get service from local cache, won't get from remote devices. If want to get it from remote device, need
- * to used the esp_ble_gattc_cache_refresh, then call esp_ble_gattc_get_service again.
+ * @brief Get the service with the given service UUID in the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] svc_uuid: the pointer to the service uuid.
- * @param[out] result: The pointer to the service which has been found in the gattc cache.
- * @param[inout] count: input the number of service want to find,
- * it will output the number of service has been found in the gattc cache with the given service uuid.
- * @param[in] offset: Offset of the service position to get.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] svc_uuid The pointer to the service UUID. If NULL is passed, the API will retrieve all services.
+ * @param[out] result The pointer to the service which has been found in the local GATTC cache
+ * @param[inout] count The number of services to retrieve. It will be updated with the actual number of services found.
+ * @param[in] offset The position offset to retrieve
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `esp_ble_gattc_cache_refresh` can be used to discover services again.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *svc_uuid,
esp_gattc_service_elem_t *result, uint16_t *count, uint16_t offset);
/**
- * @brief Find all the characteristic with the given service in the gattc cache
- * Note: It just get characteristic from local cache, won't get from remote devices.
+ * @brief Get all characteristics with the given handle range in the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] start_handle: the attribute start handle.
- * @param[in] end_handle: the attribute end handle
- * @param[out] result: The pointer to the characteristic in the service.
- * @param[inout] count: input the number of characteristic want to find,
- * it will output the number of characteristic has been found in the gattc cache with the given service.
- * @param[in] offset: Offset of the characteristic position to get.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle The attribute start handle
+ * @param[in] end_handle The attribute end handle
+ * @param[out] result The pointer to the characteristic in the service
+ * @param[inout] count The number of characteristics to retrieve. It will be updated with the actual number of characteristics found.
+ * @param[in] offset The position offset to retrieve
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle` or `end_handle`
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -429,21 +483,24 @@ esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
uint16_t *count, uint16_t offset);
/**
- * @brief Find all the descriptor with the given characteristic in the gattc cache
- * Note: It just get descriptor from local cache, won't get from remote devices.
+ * @brief Get all descriptors with the given characteristic in the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] char_handle: the given characteristic handle
- * @param[out] result: The pointer to the descriptor in the characteristic.
- * @param[inout] count: input the number of descriptor want to find,
- * it will output the number of descriptor has been found in the gattc cache with the given characteristic.
- * @param[in] offset: Offset of the descriptor position to get.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID which identifies the server
+ * @param[in] char_handle The given characteristic handle
+ * @param[out] result The pointer to the descriptor in the characteristic
+ * @param[inout] count The number of descriptors to retrieve. It will be updated with the actual number of descriptors found.
+ * @param[in] offset The position offset to retrieve
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `char_handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE: Invalid GATT `char_handle`
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -451,24 +508,26 @@ esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if,
esp_gattc_descr_elem_t *result,
uint16_t *count, uint16_t offset);
-
/**
- * @brief Find the characteristic with the given characteristic uuid in the gattc cache
- * Note: It just get characteristic from local cache, won't get from remote devices.
+ * @brief Get the characteristic with the given characteristic UUID in the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] start_handle: the attribute start handle
- * @param[in] end_handle: the attribute end handle
- * @param[in] char_uuid: the characteristic uuid
- * @param[out] result: The pointer to the characteristic in the service.
- * @param[inout] count: input the number of characteristic want to find,
- * it will output the number of characteristic has been found in the gattc cache with the given service.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle The attribute start handle
+ * @param[in] end_handle The attribute end handle
+ * @param[in] char_uuid The characteristic UUID
+ * @param[out] result The pointer to the characteristic in the service
+ * @param[inout] count The number of characteristics to retrieve. It will be updated with the actual number of characteristics found.
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle` or `end_handle`
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -479,23 +538,25 @@ esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
uint16_t *count);
/**
- * @brief Find the descriptor with the given characteristic uuid in the gattc cache
- * Note: It just get descriptor from local cache, won't get from remote devices.
+ * @brief Get the descriptor with the given characteristic UUID in the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] start_handle: the attribute start handle
- * @param[in] end_handle: the attribute end handle
- * @param[in] char_uuid: the characteristic uuid.
- * @param[in] descr_uuid: the descriptor uuid.
- * @param[out] result: The pointer to the descriptor in the given characteristic.
- * @param[inout] count: input the number of descriptor want to find,
- * it will output the number of descriptor has been found in the gattc cache with the given characteristic.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle The attribute start handle
+ * @param[in] end_handle The attribute end handle
+ * @param[in] char_uuid The characteristic UUID
+ * @param[in] descr_uuid The descriptor UUID.
+ * @param[out] result The pointer to the descriptor in the given characteristic.
+ * @param[inout] count The number of descriptors want to retrieve. It will be updated with the actual number of descriptors found.
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -507,21 +568,24 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if,
uint16_t *count);
/**
- * @brief Find the descriptor with the given characteristic handle in the gattc cache
- * Note: It just get descriptor from local cache, won't get from remote devices.
+ * @brief Get the descriptor with the given characteristic handle in the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] char_handle: the characteristic handle.
- * @param[in] descr_uuid: the descriptor uuid.
- * @param[out] result: The pointer to the descriptor in the given characteristic.
- * @param[inout] count: input the number of descriptor want to find,
- * it will output the number of descriptor has been found in the gattc cache with the given characteristic.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID which identifies the server
+ * @param[in] char_handle The characteristic handle
+ * @param[in] descr_uuid The descriptor UUID
+ * @param[out] result The pointer to the descriptor in the given characteristic
+ * @param[inout] count The number of descriptors want to retrieve. It will be updated with the actual number of descriptors found.
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `char_handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE: Invalid GATT `char_handle`
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -531,22 +595,24 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
uint16_t *count);
/**
- * @brief Find the include service with the given service handle in the gattc cache
- * Note: It just get include service from local cache, won't get from remote devices.
+ * @brief Get the included services with the given service handle in the local GATTC cache.
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] start_handle: the attribute start handle
- * @param[in] end_handle: the attribute end handle
- * @param[in] incl_uuid: the include service uuid
- * @param[out] result: The pointer to the include service in the given service.
- * @param[inout] count: input the number of include service want to find,
- * it will output the number of include service has been found in the gattc cache with the given service.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID which identifies the server
+ * @param[in] start_handle The attribute start handle
+ * @param[in] end_handle The attribute end handle
+ * @param[in] incl_uuid The included service UUID
+ * @param[out] result The pointer to the included service with the given service handle.
+ * @param[inout] count The number of included services to retrieve. It will be updated with the actual number of included services found.
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -556,23 +622,27 @@ esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
esp_gattc_incl_svc_elem_t *result,
uint16_t *count);
-
/**
- * @brief Find the attribute count with the given service or characteristic in the gattc cache
+ * @brief Get the attribute count with the given service or characteristic in the local GATTC cache
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] type: the attribute type.
- * @param[in] start_handle: the attribute start handle, if the type is ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore
- * @param[in] end_handle: the attribute end handle, if the type is ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore
- * @param[in] char_handle: the characteristic handle, this parameter valid when the type is ESP_GATT_DB_DESCRIPTOR. If the type
- * isn't ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore.
- * @param[out] count: output the number of attribute has been found in the gattc cache with the given attribute type.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] type The attribute type
+ * @param[in] start_handle The attribute start handle. If the type is `ESP_GATT_DB_DESCRIPTOR`, this parameter will be ignored.
+ * @param[in] end_handle The attribute end handle. If the type is `ESP_GATT_DB_DESCRIPTOR`, this parameter will be ignored.
+ * @param[in] char_handle The characteristic handle. This parameter is valid only if the type is `ESP_GATT_DB_DESCRIPTOR`.
+ * @param[out] count The number of attributes found in the local GATTC cache with the given attribute type
*
- * @return
- * - ESP_OK: success
- * - other: failed
*
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `start_handle` must be greater than 0, and smaller than `end_handle` if the `type` is not `ESP_GATT_DB_DESCRIPTOR`.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle`, `end_handle`
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `count`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -583,38 +653,47 @@ esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
uint16_t *count);
/**
- * @brief This function is called to get the GATT database.
- * Note: It just get attribute data base from local cache, won't get from remote devices.
+ * @brief Get the GATT database elements
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] start_handle: the attribute start handle
- * @param[in] end_handle: the attribute end handle
- * @param[in] conn_id: connection ID which identify the server.
- * @param[in] db: output parameter which will contain the GATT database copy.
- * Caller is responsible for freeing it.
- * @param[in] count: number of elements in database.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] start_handle The attribute start handle
+ * @param[in] end_handle The attribute end handle
+ * @param[in] conn_id Connection ID
+ * @param[out] db The pointer to GATT database elements
+ * @param[inout] count The number of elements in the database to retrieve. It will be updated with the actual number of elements found.
+ *
+ * @note
+ * 1. This API does not trigger any event.
+ * 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
*
* @return
- * - ESP_OK: success
- * - other: failed
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle`, `end_handle`
+ * - ESP_GATT_INVALID_PDU: NULL pointer to `db` or NULL pointer to `count` or the count value is 0
+ * - ESP_FAIL: Failure due to other reasons
*
*/
esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
esp_gattc_db_elem_t *db, uint16_t *count);
/**
- * @brief This function is called to read a service's characteristics of
- * the given characteristic handle
+ * @brief Read the characteristics value of the given characteristic handle
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] handle : characteritic handle to read.
- * @param[in] auth_req : authenticate request type
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] handle Characteristic handle to read
+ * @param[in] auth_req Authenticate request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_READ_CHAR_EVT`.
+ * 2. This function should be called only after the connection has been established.
+ * 3. `handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_GATT_INVALID_HANDLE: Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -622,20 +701,25 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
esp_gatt_auth_req_t auth_req);
/**
- * @brief This function is called to read a service's characteristics of
- * the given characteristic UUID
+ * @brief Read the characteristics value of the given characteristic UUID.
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] start_handle : the attribute start handle.
- * @param[in] end_handle : the attribute end handle
- * @param[in] uuid : The UUID of attribute which will be read.
- * @param[in] auth_req : authenticate request type
+ * @param[in] gattc_if GATT Client access interface.
+ * @param[in] conn_id Connection ID
+ * @param[in] start_handle The attribute start handle
+ * @param[in] end_handle The attribute end handle
+ * @param[in] uuid The pointer to UUID of attribute to read
+ * @param[in] auth_req Authenticate request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_READ_CHAR_EVT`.
+ * 2. This function should be called only after the connection has been established.
+ * 3. `start_handle` must be greater than 0, and smaller than `end_handle`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_ILLEGAL_PARAMETER: NULL pointer to `uuid`
+ * - ESP_ERR_INVALID_STATE: The connection has not been established
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_read_by_type (esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -645,75 +729,92 @@ esp_err_t esp_ble_gattc_read_by_type (esp_gatt_if_t gattc_if,
esp_gatt_auth_req_t auth_req);
/**
- * @brief This function is called to read multiple characteristic or
- * characteristic descriptors.
+ * @brief Read multiple characteristic or descriptor values
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] read_multi : pointer to the read multiple parameter.
- * @param[in] auth_req : authenticate request type
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID which specifies the server
+ * @param[in] read_multi Pointer to `esp_gattc_multi_t`
+ * @param[in] auth_req Authenticate request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_READ_MULTIPLE_EVT`.
+ * 2. This function should be called only after the connection has been established.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
uint16_t conn_id, esp_gattc_multi_t *read_multi,
esp_gatt_auth_req_t auth_req);
/**
- * @brief This function is called to read multiple variable length characteristic or
- * characteristic descriptors.
+ * @brief Read multiple variable length characteristic values.
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] read_multi : pointer to the read multiple parameter.
- * @param[in] auth_req : authenticate request type
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] read_multi The pointer to the `esp_gattc_multi_t`
+ * @param[in] auth_req Authenticate request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_READ_MULTI_VAR_EVT`.
+ * 2. This function should be called only after the connection has been established.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if,
uint16_t conn_id, esp_gattc_multi_t *read_multi,
esp_gatt_auth_req_t auth_req);
/**
- * @brief This function is called to read a characteristics descriptor.
+ * @brief Read a characteristics descriptor
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] handle : descriptor handle to read.
- * @param[in] auth_req : authenticate request type
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] handle Descriptor handle to read
+ * @param[in] auth_req Authenticate request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_READ_DESCR_EVT`.
+ * 2. This function should be called only after the connection has been established.
+ * 3. `handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_GATT_INVALID_HANDLE:Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
uint16_t conn_id,
uint16_t handle,
esp_gatt_auth_req_t auth_req);
-
/**
- * @brief This function is called to write characteristic value.
+ * @brief Write the characteristic value of a given characteristic handle
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] handle : characteristic handle to write.
- * @param[in] value_len: length of the value to be written.
- * @param[in] value : the value to be written.
- * @param[in] write_type : the type of attribute write operation.
- * @param[in] auth_req : authentication request.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] handle The characteristic handle to write
+ * @param[in] value_len The length of the value to write in bytes
+ * @param[in] value The value to write
+ * @param[in] write_type The type of Attribute write operation
+ * @param[in] auth_req Authentication request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_WRITE_CHAR_EVT`.
+ * 2. This function should be called only after the connection has been established.
+ * 3. `handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_GATT_INVALID_HANDLE:Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -723,22 +824,27 @@ esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req);
-
/**
- * @brief This function is called to write characteristic descriptor value.
+ * @brief Write Characteristic descriptor value of a given descriptor handle
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID
- * @param[in] handle : descriptor handle to write.
- * @param[in] value_len: length of the value to be written.
- * @param[in] value : the value to be written.
- * @param[in] write_type : the type of attribute write operation.
- * @param[in] auth_req : authentication request.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] handle The descriptor handle to write.
+ * @param[in] value_len The length of the value to write in bytes.
+ * @param[in] value The value to write
+ * @param[in] write_type The type of Attribute write operation
+ * @param[in] auth_req Authentication request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_WRITE_DESCR_EVT`.
+ * 2. This function should be called only after the connection has been established.
+ * 3. `handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_GATT_INVALID_HANDLE:Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -748,22 +854,29 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req);
-
/**
- * @brief This function is called to prepare write a characteristic value.
- *
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] handle : characteristic handle to prepare write.
- * @param[in] offset : offset of the write value.
- * @param[in] value_len: length of the value to be written.
- * @param[in] value : the value to be written.
- * @param[in] auth_req : authentication request.
+ * @brief Prepare to write a characteristic value which is longer than the MTU size to a specified characteristic handle
+ *
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] handle Characteristic handle to prepare to write
+ * @param[in] offset The position offset to write
+ * @param[in] value_len The length of the value to write in bytes
+ * @param[in] value The value to write
+ * @param[in] auth_req Authentication request type
+ *
+ * @note
+ * 1. This function should be called only after the connection has been established.
+ * 2. After using this API, use `esp_ble_gattc_execute_write` to write.
+ * 3. This function triggers `ESP_GATTC_PREP_WRITE_EVT`.
+ * 4. If `value_len` is less than or equal to MTU size, it is recommended to `esp_ble_gattc_write_char` to write directly.
+ * 5. `handle` must be greater than 0.
*
* @return
- * - ESP_OK: success
- * - other: failed
- *
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_GATT_INVALID_HANDLE:Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -773,22 +886,27 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
uint8_t *value,
esp_gatt_auth_req_t auth_req);
-
/**
- * @brief This function is called to prepare write a characteristic descriptor value.
+ * @brief Prepare to write a characteristic descriptor value at a given handle
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] handle : characteristic descriptor handle to prepare write.
- * @param[in] offset : offset of the write value.
- * @param[in] value_len: length of the value to be written.
- * @param[in] value : the value to be written.
- * @param[in] auth_req : authentication request.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] handle Characteristic descriptor handle to prepare to write
+ * @param[in] offset The position offset to write
+ * @param[in] value_len The length of the value to write in bytes
+ * @param[in] value The value to write
+ * @param[in] auth_req Authentication request type
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_WRITE_CHAR_EVT`.
+ * 2. This function should be called only after the connection has been established.
+ * 3. `handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_GATT_INVALID_HANDLE:Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -798,112 +916,123 @@ esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
uint8_t *value,
esp_gatt_auth_req_t auth_req);
-
/**
- * @brief This function is called to execute write a prepare write sequence.
+ * @brief Execute a prepared writing sequence
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] conn_id : connection ID.
- * @param[in] is_execute : execute or cancel.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] is_execute True if it is to execute the writing sequence; false if it is to cancel the writing sequence.
*
- * @return
- * - ESP_OK: success
- * - other: failed
+ * @note This function triggers `ESP_GATTC_EXEC_EVT`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, bool is_execute);
-
/**
- * @brief This function is called to register for notification of a service.
+ * @brief Register to receive notification/indication of a characteristic.
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] server_bda : target GATT server.
- * @param[in] handle : GATT characteristic handle.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] server_bda Target GATT server device address
+ * @param[in] handle Target GATT characteristic handle
*
- * @return
- * - ESP_OK: registration succeeds
- * - other: failed
+ * @note
+ * 1. This function triggers `ESP_GATTC_REG_FOR_NOTIFY_EVT`.
+ * 2. You should call `esp_ble_gattc_write_char_descr()` after this API to write Client Characteristic Configuration (CCC) descriptor to the value of 1 (Enable Notification) or 2 (Enable Indication).
+ * 3. `handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE:Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
esp_bd_addr_t server_bda,
uint16_t handle);
-
/**
- * @brief This function is called to de-register for notification of a service.
+ * @brief Unregister the notification of a service.
*
- * @param[in] gattc_if: Gatt client access interface.
- * @param[in] server_bda : target GATT server.
- * @param[in] handle : GATT characteristic handle.
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] server_bda Target GATT server device address
+ * @param[in] handle Target GATT characteristic handle
*
+ * @note
+ * 1. This function triggers `ESP_GATTC_UNREG_FOR_NOTIFY_EVT`.
+ * 2. You should call `esp_ble_gattc_write_char_descr()` after this API to write Client Characteristic Configuration (CCC) descriptor value to 0.
+ * 3. `handle` must be greater than 0
* @return
- * - ESP_OK: unregister succeeds
- * - other: failed
- *
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE:Invalid `handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
esp_bd_addr_t server_bda,
uint16_t handle);
-
/**
-* @brief Refresh the server cache store in the gattc stack of the remote device. If
-* the device is connected, this API will restart the discovery of service information of the remote device
-*
-* @param[in] remote_bda: remote device BD address.
-*
-* @return
-* - ESP_OK: success
-* - other: failed
-*
-*/
+ * @brief Refresh the cache of the remote device
+ *
+ * @param[in] remote_bda Remote device address
+ *
+ * @note
+ * 1. If the device is connected, this API will restart the discovery of service information of the remote device.
+ * 2. This function triggers `ESP_GATTC_DIS_SRVC_CMPL_EVT` only after the ACL connection is established. Otherwise, no events will be triggered.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
+ */
esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda);
/**
-* @brief Add or delete the associated address with the source address.
-* Note: The role of this API is mainly when the client side has stored a server-side database,
-* when it needs to connect another device, but the device's attribute database is the same
-* as the server database stored on the client-side, calling this API can use the database
-* that the device has stored used as the peer server database to reduce the attribute
-* database search and discovery process and speed up the connection time.
-* The associated address mains that device want to used the database has stored in the local cache.
-* The source address mains that device want to share the database to the associated address device.
-*
-* @param[in] gattc_if: Gatt client access interface.
-* @param[in] src_addr: the source address which provide the attribute table.
-* @param[in] assoc_addr: the associated device address which went to share the attribute table with the source address.
-* @param[in] is_assoc: true add the associated device address, false remove the associated device address.
-* @return
-* - ESP_OK: success
-* - other: failed
-*
-*/
+ * @brief Add or remove the association between the address in the local GATTC cache with the source address of the remote device
+ *
+ * @param[in] gattc_if GATT Client access interface
+ * @param[in] src_addr The source address intended to be associated to the `assoc_addr` which has been stored in the local GATTC cache
+ * @param[in] assoc_addr The associated device address intended to share the attribute table with the source address
+ * @param[in] is_assoc True if adding the association; false if removing the association.
+ *
+ * @note
+ * 1. This API is primarily used when the client has a stored server-side database (`assoc_addr`) and needs to connect to
+ * another device (`src_addr`) with the same attribute database. By invoking this API, the stored database is utilized
+ * as the peer server database, eliminating the need for attribute database search and discovery. This reduces
+ * processing time and accelerates the connection process.
+ * 2. The attribute table of a device with `assoc_addr` must be stored in the local GATTC cache first.
+ * Then, the attribute table of the device with `src_addr` must be the same as the one with `assoc_addr`.
+ * 3. This function triggers `ESP_GATTC_SET_ASSOC_EVT`.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
+ */
esp_err_t esp_ble_gattc_cache_assoc(esp_gatt_if_t gattc_if, esp_bd_addr_t src_addr,
esp_bd_addr_t assoc_addr, bool is_assoc);
+
/**
-* @brief Get the address list which has store the attribute table in the gattc cache. There will
-* callback ESP_GATTC_GET_ADDR_LIST_EVT event when get address list complete.
-*
-* @param[in] gattc_if: Gatt client access interface.
-* @return
-* - ESP_OK: success
-* - other: failed
-*
-*/
+ * @brief Get the address list stored in the local GATTC cache
+ *
+ * @param[in] gattc_if GATT Client access interface
+ *
+ * @note This function triggers `ESP_GATTC_GET_ADDR_LIST_EVT`.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
+ */
esp_err_t esp_ble_gattc_cache_get_addr_list(esp_gatt_if_t gattc_if);
/**
-* @brief Clean the service cache of this device in the gattc stack,
-*
-* @param[in] remote_bda: remote device BD address.
-*
-* @return
-* - ESP_OK: success
-* - other: failed
-*
-*/
+ * @brief Clean the service cache of the target device in the local GATTC cache
+ *
+ * @param[in] remote_bda Remote device address
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
+ */
esp_err_t esp_ble_gattc_cache_clean(esp_bd_addr_t remote_bda);
#ifdef __cplusplus
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h b/lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h
index 0eb7ddd9..64222210 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_gatts_api.h
@@ -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
*/
@@ -17,579 +17,606 @@ extern "C" {
/// GATT Server callback function events
typedef enum {
- ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */
- ESP_GATTS_READ_EVT = 1, /*!< When gatt client request read operation, the event comes */
- ESP_GATTS_WRITE_EVT = 2, /*!< When gatt client request write operation, the event comes */
- ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< When gatt client request execute write, the event comes */
- ESP_GATTS_MTU_EVT = 4, /*!< When set mtu complete, the event comes */
- ESP_GATTS_CONF_EVT = 5, /*!< When receive confirm, the event comes */
- ESP_GATTS_UNREG_EVT = 6, /*!< When unregister application id, the event comes */
- ESP_GATTS_CREATE_EVT = 7, /*!< When create service complete, the event comes */
- ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< When add included service complete, the event comes */
- ESP_GATTS_ADD_CHAR_EVT = 9, /*!< When add characteristic complete, the event comes */
- ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< When add descriptor complete, the event comes */
- ESP_GATTS_DELETE_EVT = 11, /*!< When delete service complete, the event comes */
- ESP_GATTS_START_EVT = 12, /*!< When start service complete, the event comes */
- ESP_GATTS_STOP_EVT = 13, /*!< When stop service complete, the event comes */
- ESP_GATTS_CONNECT_EVT = 14, /*!< When gatt client connect, the event comes */
- ESP_GATTS_DISCONNECT_EVT = 15, /*!< When gatt client disconnect, the event comes */
- ESP_GATTS_OPEN_EVT = 16, /*!< When connect to peer, the event comes */
- ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< When disconnect from peer, the event comes */
- ESP_GATTS_CLOSE_EVT = 18, /*!< When gatt server close, the event comes */
- ESP_GATTS_LISTEN_EVT = 19, /*!< When gatt listen to be connected the event comes */
- ESP_GATTS_CONGEST_EVT = 20, /*!< When congest happen, the event comes */
+ ESP_GATTS_REG_EVT = 0, /*!< This event is triggered when a GATT Server application is registered using `esp_ble_gatts_app_register`. */
+ ESP_GATTS_READ_EVT = 1, /*!< This event is triggered when the read request from the Client is received. */
+ ESP_GATTS_WRITE_EVT = 2, /*!< This event is triggered when the write request from the Client is received. */
+ ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< This event is triggered when the write execution request from the Client is received. */
+ ESP_GATTS_MTU_EVT = 4, /*!< This event is triggered when the MTU configuration request from the Client is received. */
+ ESP_GATTS_CONF_EVT = 5, /*!< This event is triggered when the confirmation from the Client is received. */
+ ESP_GATTS_UNREG_EVT = 6, /*!< This event is triggered when a GATT Server application is unregistered using `esp_ble_gatts_app_unregister`. */
+ ESP_GATTS_CREATE_EVT = 7, /*!< This event is triggered when a GATT Server service is created using `esp_ble_gatts_create_service`. */
+ ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< This event is triggered when an included service is added using `esp_ble_gatts_add_included_service`. */
+ ESP_GATTS_ADD_CHAR_EVT = 9, /*!< This event is triggered when a characteristic is added to the service using `esp_ble_gatts_add_char`. */
+ ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< This event is triggered when a characteristic descriptor is added to the service using `esp_ble_gatts_add_char_descr`. */
+ ESP_GATTS_DELETE_EVT = 11, /*!< This event is triggered when the service is deleted using `esp_ble_gatts_delete_service`. */
+ ESP_GATTS_START_EVT = 12, /*!< This event is triggered when the service is started using `esp_ble_gatts_start_service`. */
+ ESP_GATTS_STOP_EVT = 13, /*!< This event is triggered when the service is stopped using `esp_ble_gatts_stop_service`. */
+ ESP_GATTS_CONNECT_EVT = 14, /*!< This event is triggered when a physical connection is set up. */
+ ESP_GATTS_DISCONNECT_EVT = 15, /*!< This event is triggered when a physical connection is terminated. */
+ ESP_GATTS_OPEN_EVT = 16, /*!< This event is triggered when a virtual connection is created using `esp_ble_gatts_open`. */
+ ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< Deprecated. */
+ ESP_GATTS_CLOSE_EVT = 18, /*!< This event is triggered when a virtual connection is closed using `esp_ble_gatts_close`. */
+ ESP_GATTS_LISTEN_EVT = 19, /*!< Deprecated. */
+ ESP_GATTS_CONGEST_EVT = 20, /*!< This event is triggered when the GATT connection is congested. */
/* following is extra event */
- ESP_GATTS_RESPONSE_EVT = 21, /*!< When gatt send response complete, the event comes */
- ESP_GATTS_CREAT_ATTR_TAB_EVT = 22, /*!< When gatt create table complete, the event comes */
- ESP_GATTS_SET_ATTR_VAL_EVT = 23, /*!< When gatt set attr value complete, the event comes */
- ESP_GATTS_SEND_SERVICE_CHANGE_EVT = 24, /*!< When gatt send service change indication complete, the event comes */
+ ESP_GATTS_RESPONSE_EVT = 21, /*!< This event is triggered when a response is sent to the request using `esp_ble_gatts_send_response`. */
+ ESP_GATTS_CREAT_ATTR_TAB_EVT = 22, /*!< This event is triggered when a service attribute table is created using `esp_ble_gatts_create_attr_tab`. */
+ ESP_GATTS_SET_ATTR_VAL_EVT = 23, /*!< This event is triggered when an attribute value is set using `esp_ble_gatts_set_attr_value`. */
+ ESP_GATTS_SEND_SERVICE_CHANGE_EVT = 24, /*!< This event is triggered when a service change indication is sent using `esp_ble_gatts_send_service_change_indication`. */
} esp_gatts_cb_event_t;
/**
- * @brief Gatt server callback parameters union
+ * @brief GATT Server callback parameters
*/
typedef union {
/**
- * @brief ESP_GATTS_REG_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_REG_EVT`
*/
struct gatts_reg_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t app_id; /*!< Application id which input in register API */
- } reg; /*!< Gatt server callback param of ESP_GATTS_REG_EVT */
+ uint16_t app_id; /*!< Application ID */
+ } reg; /*!< Callback parameter for the event `ESP_GATTS_REG_EVT` */
/**
- * @brief ESP_GATTS_READ_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_READ_EVT`
*/
struct gatts_read_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint32_t trans_id; /*!< Transfer id */
- esp_bd_addr_t bda; /*!< The bluetooth device address which been read */
+ uint16_t conn_id; /*!< Connection ID */
+ uint32_t trans_id; /*!< Transfer ID */
+ esp_bd_addr_t bda; /*!< The device address to read */
uint16_t handle; /*!< The attribute handle */
- uint16_t offset; /*!< Offset of the value, if the value is too long */
- bool is_long; /*!< The value is too long or not */
- bool need_rsp; /*!< The read operation need to do response */
- } read; /*!< Gatt server callback param of ESP_GATTS_READ_EVT */
+ uint16_t offset; /*!< The position offset to read. If the length of value is less than or equal to the MTU size, this value is 0. */
+ bool is_long; /*!< True indicates that the length of value is greater than the MTU size; false otherwise. */
+ bool need_rsp; /*!< True indicates that the `esp_ble_gatts_send_response` is required in the following step; false otherwise. */
+ } read; /*!< Callback parameter for the event `ESP_GATTS_READ_EVT` */
/**
- * @brief ESP_GATTS_WRITE_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_WRITE_EVT`
*/
struct gatts_write_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint32_t trans_id; /*!< Transfer id */
- esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
+ uint16_t conn_id; /*!< Connection ID */
+ uint32_t trans_id; /*!< Transfer ID */
+ esp_bd_addr_t bda; /*!< The device address to write */
uint16_t handle; /*!< The attribute handle */
- uint16_t offset; /*!< Offset of the value, if the value is too long */
- bool need_rsp; /*!< The write operation need to do response */
- bool is_prep; /*!< This write operation is prepare write */
- uint16_t len; /*!< The write attribute value length */
+ uint16_t offset; /*!< The position offset to write. If the length of value is less than or equal to the MTU size, this value is 0.*/
+ bool need_rsp; /*!< True indicates that the `esp_ble_gatts_send_response` is required in the following step; false otherwise. */
+ bool is_prep; /*!< True indicates the write operation is a prepared write operation */
+ uint16_t len; /*!< The length of the write attribute value in bytes */
uint8_t *value; /*!< The write attribute value */
- } write; /*!< Gatt server callback param of ESP_GATTS_WRITE_EVT */
+ } write; /*!< Callback parameter for the event `ESP_GATTS_WRITE_EVT` */
/**
- * @brief ESP_GATTS_EXEC_WRITE_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_EXEC_WRITE_EVT`
*/
struct gatts_exec_write_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint32_t trans_id; /*!< Transfer id */
- esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
-#define ESP_GATT_PREP_WRITE_CANCEL 0x00 /*!< Prepare write flag to indicate cancel prepare write */
-#define ESP_GATT_PREP_WRITE_EXEC 0x01 /*!< Prepare write flag to indicate execute prepare write */
- uint8_t exec_write_flag; /*!< Execute write flag */
- } exec_write; /*!< Gatt server callback param of ESP_GATTS_EXEC_WRITE_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ uint32_t trans_id; /*!< Transfer ID */
+ esp_bd_addr_t bda; /*!< The bluetooth device address to write */
+ #define ESP_GATT_PREP_WRITE_CANCEL 0x00 /*!< Flag to indicate the cancellation of a prepare write operation */
+ #define ESP_GATT_PREP_WRITE_EXEC 0x01 /*!< Flag to indicate the execution of a prepare write operation */
+ uint8_t exec_write_flag; /*!< Execute write flag: `ESP_GATT_PREP_WRITE_CANCEL` or `ESP_GATT_PREP_WRITE_EXEC` */
+ } exec_write; /*!< Callback parameter for the event `ESP_GATTS_EXEC_WRITE_EVT` */
/**
- * @brief ESP_GATTS_MTU_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_MTU_EVT`
*/
struct gatts_mtu_evt_param {
- uint16_t conn_id; /*!< Connection id */
+ uint16_t conn_id; /*!< Connection ID */
uint16_t mtu; /*!< MTU size */
- } mtu; /*!< Gatt server callback param of ESP_GATTS_MTU_EVT */
+ } mtu; /*!< Callback parameter for the event `ESP_GATTS_MTU_EVT` */
/**
- * @brief ESP_GATTS_CONF_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_CONF_EVT`
*/
struct gatts_conf_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- uint16_t handle; /*!< attribute handle */
- uint16_t len; /*!< The indication or notification value length, len is valid when send notification or indication failed */
- uint8_t *value; /*!< The indication or notification value , value is valid when send notification or indication failed */
- } conf; /*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */
+ uint16_t conn_id; /*!< Connection ID */
+ uint16_t handle; /*!< Attribute handle */
+ uint16_t len; /*!< The length of indication or notification value in bytes. The length is invalid if the notification or indication failed. */
+ uint8_t *value; /*!< The indication or notification value. The value is invalid if the notification or indication failed. */
+ } conf; /*!< Callback parameter for the event `ESP_GATTS_CONF_EVT` */
/**
- * @brief ESP_GATTS_UNREG_EVT
- */
-
- /**
- * @brief ESP_GATTS_CREATE_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_CREATE_EVT`
*/
struct gatts_create_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t service_handle; /*!< Service attribute handle */
- esp_gatt_srvc_id_t service_id; /*!< Service id, include service uuid and other information */
- } create; /*!< Gatt server callback param of ESP_GATTS_CREATE_EVT */
+ esp_gatt_srvc_id_t service_id; /*!< Service ID, including service UUID and other information */
+ } create; /*!< Callback parameter for the event `ESP_GATTS_CREATE_EVT` */
/**
- * @brief ESP_GATTS_ADD_INCL_SRVC_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_ADD_INCL_SRVC_EVT`
*/
struct gatts_add_incl_srvc_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t attr_handle; /*!< Included service attribute handle */
uint16_t service_handle; /*!< Service attribute handle */
- } add_incl_srvc; /*!< Gatt server callback param of ESP_GATTS_ADD_INCL_SRVC_EVT */
+ } add_incl_srvc; /*!< Callback parameter for the event `ESP_GATTS_ADD_INCL_SRVC_EVT` */
/**
- * @brief ESP_GATTS_ADD_CHAR_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_ADD_CHAR_EVT`
*/
struct gatts_add_char_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t attr_handle; /*!< Characteristic attribute handle */
uint16_t service_handle; /*!< Service attribute handle */
- esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */
- } add_char; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_EVT */
+ esp_bt_uuid_t char_uuid; /*!< Characteristic UUID */
+ } add_char; /*!< Callback parameter for the event `ESP_GATTS_ADD_CHAR_EVT` */
/**
- * @brief ESP_GATTS_ADD_CHAR_DESCR_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_ADD_CHAR_DESCR_EVT`
*/
struct gatts_add_char_descr_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t attr_handle; /*!< Descriptor attribute handle */
uint16_t service_handle; /*!< Service attribute handle */
- esp_bt_uuid_t descr_uuid; /*!< Characteristic descriptor uuid */
- } add_char_descr; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_DESCR_EVT */
+ esp_bt_uuid_t descr_uuid; /*!< Characteristic descriptor UUID */
+ } add_char_descr; /*!< Callback parameter for the event `ESP_GATTS_ADD_CHAR_DESCR_EVT` */
/**
- * @brief ESP_GATTS_DELETE_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_DELETE_EVT`
*/
struct gatts_delete_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t service_handle; /*!< Service attribute handle */
- } del; /*!< Gatt server callback param of ESP_GATTS_DELETE_EVT */
+ } del; /*!< Callback parameter for the event `ESP_GATTS_DELETE_EVT` */
/**
- * @brief ESP_GATTS_START_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_START_EVT`
*/
struct gatts_start_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t service_handle; /*!< Service attribute handle */
- } start; /*!< Gatt server callback param of ESP_GATTS_START_EVT */
+ } start; /*!< Callback parameter for the event `ESP_GATTS_START_EVT` */
/**
- * @brief ESP_GATTS_STOP_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_STOP_EVT`
*/
struct gatts_stop_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint16_t service_handle; /*!< Service attribute handle */
- } stop; /*!< Gatt server callback param of ESP_GATTS_STOP_EVT */
+ } stop; /*!< Callback parameter for the event `ESP_GATTS_STOP_EVT` */
/**
- * @brief ESP_GATTS_CONNECT_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_CONNECT_EVT`
*/
struct gatts_connect_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint8_t link_role; /*!< Link role : master role = 0 ; slave role = 1*/
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- esp_gatt_conn_params_t conn_params; /*!< current Connection parameters */
- esp_ble_addr_type_t ble_addr_type; /*!< Remote BLE device address type */
- uint16_t conn_handle; /*!< HCI connection handle */
- } connect; /*!< Gatt server callback param of ESP_GATTS_CONNECT_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ uint8_t link_role; /*!< Link role: master role = 0; slave role = 1 */
+ esp_bd_addr_t remote_bda; /*!< Remote device address */
+ esp_gatt_conn_params_t conn_params; /*!< Current connection parameters */
+ esp_ble_addr_type_t ble_addr_type; /*!< Remote device address type */
+ uint16_t conn_handle; /*!< HCI connection handle */
+ } connect; /*!< Callback parameter for the event `ESP_GATTS_CONNECT_EVT` */
/**
- * @brief ESP_GATTS_DISCONNECT_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_DISCONNECT_EVT`
*/
struct gatts_disconnect_evt_param {
- uint16_t conn_id; /*!< Connection id */
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- esp_gatt_conn_reason_t reason; /*!< Indicate the reason of disconnection */
- } disconnect; /*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ esp_bd_addr_t remote_bda; /*!< Remote device address */
+ esp_gatt_conn_reason_t reason; /*!< The reason of disconnection */
+ } disconnect; /*!< Callback parameter for the event `ESP_GATTS_DISCONNECT_EVT` */
/**
- * @brief ESP_GATTS_OPEN_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_OPEN_EVT`
*/
struct gatts_open_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- } open; /*!< Gatt server callback param of ESP_GATTS_OPEN_EVT */
+ } open; /*!< Callback parameter for the event `ESP_GATTS_OPEN_EVT` */
/**
- * @brief ESP_GATTS_CANCEL_OPEN_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_CANCEL_OPEN_EVT`
*/
struct gatts_cancel_open_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- } cancel_open; /*!< Gatt server callback param of ESP_GATTS_CANCEL_OPEN_EVT */
+ } cancel_open; /*!< Callback parameter for the event `ESP_GATTS_CANCEL_OPEN_EVT` */
/**
- * @brief ESP_GATTS_CLOSE_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_CLOSE_EVT`
*/
struct gatts_close_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- } close; /*!< Gatt server callback param of ESP_GATTS_CLOSE_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ } close; /*!< Callback parameter for the event `ESP_GATTS_CLOSE_EVT` */
/**
- * @brief ESP_GATTS_LISTEN_EVT
- */
- /**
- * @brief ESP_GATTS_CONGEST_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_CONGEST_EVT`
*/
struct gatts_congest_evt_param {
- uint16_t conn_id; /*!< Connection id */
- bool congested; /*!< Congested or not */
- } congest; /*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ bool congested; /*!< True indicates the connection is congested; false otherwise. */
+ } congest; /*!< Callback parameter for the event `ESP_GATTS_CONGEST_EVT` */
/**
- * @brief ESP_GATTS_RESPONSE_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_RESPONSE_EVT`
*/
struct gatts_rsp_evt_param {
esp_gatt_status_t status; /*!< Operation status */
- uint16_t handle; /*!< Attribute handle which send response */
- } rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
+ uint16_t conn_id; /*!< Connection ID */
+ uint16_t handle; /*!< Attribute handle which sends the response */
+ } rsp; /*!< Callback parameter for the event `ESP_GATTS_RESPONSE_EVT` */
/**
- * @brief ESP_GATTS_CREAT_ATTR_TAB_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_CREAT_ATTR_TAB_EVT`
*/
struct gatts_add_attr_tab_evt_param{
esp_gatt_status_t status; /*!< Operation status */
- esp_bt_uuid_t svc_uuid; /*!< Service uuid type */
- uint8_t svc_inst_id; /*!< Service id */
- uint16_t num_handle; /*!< The number of the attribute handle to be added to the gatts database */
- uint16_t *handles; /*!< The number to the handles */
- } add_attr_tab; /*!< Gatt server callback param of ESP_GATTS_CREAT_ATTR_TAB_EVT */
+ esp_bt_uuid_t svc_uuid; /*!< Service UUID type */
+ uint8_t svc_inst_id; /*!< Service ID */
+ uint16_t num_handle; /*!< The number of the attribute handles which have been added to the GATT Service table */
+ uint16_t *handles; /*!< The handles which have been added to the table */
+ } add_attr_tab; /*!< Callback parameter for the event `ESP_GATTS_CREAT_ATTR_TAB_EVT` */
/**
- * @brief ESP_GATTS_SET_ATTR_VAL_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_SET_ATTR_VAL_EVT`
*/
struct gatts_set_attr_val_evt_param{
uint16_t srvc_handle; /*!< The service handle */
- uint16_t attr_handle; /*!< The attribute handle */
- esp_gatt_status_t status; /*!< Operation status*/
- } set_attr_val; /*!< Gatt server callback param of ESP_GATTS_SET_ATTR_VAL_EVT */
+ uint16_t attr_handle; /*!< The attribute handle */
+ esp_gatt_status_t status; /*!< Operation status */
+ } set_attr_val; /*!< Callback parameter for the event `ESP_GATTS_SET_ATTR_VAL_EVT` */
/**
- * @brief ESP_GATTS_SEND_SERVICE_CHANGE_EVT
+ * @brief Callback parameter for the event `ESP_GATTS_SEND_SERVICE_CHANGE_EVT`
*/
struct gatts_send_service_change_evt_param{
- esp_gatt_status_t status; /*!< Operation status*/
- } service_change; /*!< Gatt server callback param of ESP_GATTS_SEND_SERVICE_CHANGE_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ } service_change; /*!< Callback parameter for the event `ESP_GATTS_SEND_SERVICE_CHANGE_EVT` */
} esp_ble_gatts_cb_param_t;
/**
* @brief GATT Server callback function type
- * @param event : Event type
- * @param gatts_if : GATT server access interface, normally
- * different gatts_if correspond to different profile
- * @param param : Point to callback parameter, currently is union type
+ *
+ * @param[in] event Event type
+ * @param[in] gatts_if GATT Server access interface. Typically, different `gatts_if` values correspond to different profiles.
+ * @param[in] param The pointer to the callback parameter, which is of a union type.
*/
typedef void (* esp_gatts_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
/**
- * @brief This function is called to register application callbacks
- * with BTA GATTS module.
+ * @brief Register GATT Server application callbacks
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @param[in] callback The pointer to the application callback function
+ *
+ * @note Avoid performing time-consuming operations within the callback functions.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback);
/**
- * @brief This function is called to get the current application callbacks
- * with BTA GATTS module.
+ * @brief Get the current GATT Server application callback
*
* @return
- * - esp_gatts_cb_t : current callback
- *
+ * - esp_gatts_cb_t: Current callback
*/
esp_gatts_cb_t esp_ble_gatts_get_callback(void);
/**
- * @brief This function is called to register application identifier
+ * @brief Register GATT Server application
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @param[in] app_id: The UUID for different application
*
+ * @note
+ * 1. This function triggers `ESP_GATTS_REG_EVT`.
+ * 2. The maximum number of applications is limited to 6.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_ARG: The input `app_id` exceeds `ESP_APP_ID_MAX` (0x7fff) defined in esp_bt_defs.h.
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gatts_app_register(uint16_t app_id);
-
-
/**
- * @brief unregister with GATT Server.
+ * @brief Unregister an GATT Server application
*
- * @param[in] gatts_if: GATT server access interface
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @param[in] gatts_if GATT Server access interface.
+ *
+ * @note
+ * 1. This function triggers `ESP_GATTS_UNREG_EVT`.
+ * 2. The maximum number of applications is limited to 6.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if);
-
/**
- * @brief Create a service. When service creation is done, a callback
- * event ESP_GATTS_CREATE_EVT is called to report status
- * and service ID to the profile. The service ID obtained in
- * the callback function needs to be used when adding included
- * service and characteristics/descriptors into the service.
+ * @brief Create a GATT Server service
*
- * @param[in] gatts_if: GATT server access interface
- * @param[in] service_id: service ID.
- * @param[in] num_handle: number of handle requested for this service.
+ * @param[in] gatts_if GATT Server access interface
+ * @param[in] service_id The pointer to the Service ID
+ * @param[in] num_handle The number of handles requested for this service.
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note
+ * 1. This function triggers `ESP_GATTS_CREATE_EVT`.
+ * 2. `num_handle` should not be greater than CONFIG_BT_GATT_MAX_SR_ATTRIBUTES.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
esp_gatt_srvc_id_t *service_id, uint16_t num_handle);
/**
- * @brief Create a service attribute tab.
- * @param[in] gatts_attr_db: the pointer to the service attr tab
- * @param[in] gatts_if: GATT server access interface
- * @param[in] max_nb_attr: the number of attribute to be added to the service database.
- * @param[in] srvc_inst_id: the instance id of the service
+ * @brief Create a service attribute table
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @param[in] gatts_attr_db The pointer to the service attribute table
+ * @param[in] gatts_if GATT Server access interface
+ * @param[in] max_nb_attr The number of attributes to be added to the service database
+ * @param[in] srvc_inst_id The instance ID of the service
*
+ * @note
+ * 1. This function triggers `ESP_GATTS_CREAT_ATTR_TAB_EVT`.
+ * 2. `max_nb_attr` should not be greater than CONFIG_BT_GATT_MAX_SR_ATTRIBUTES.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_ARG: Invalid `max_nb_attr`
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db,
esp_gatt_if_t gatts_if,
uint16_t max_nb_attr,
uint8_t srvc_inst_id);
/**
- * @brief This function is called to add an included service. This function have to be called between
- * 'esp_ble_gatts_create_service' and 'esp_ble_gatts_add_char'. After included
- * service is included, a callback event ESP_GATTS_ADD_INCL_SRVC_EVT
- * is reported the included service ID.
+ * @brief Add an included service
*
- * @param[in] service_handle: service handle to which this included service is to
- * be added.
- * @param[in] included_service_handle: the service ID to be included.
+ * @param[in] service_handle Target service handle to add
+ * @param[in] included_service_handle The handle of included service to be added
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note
+ * 1. This function triggers `ESP_GATTS_ADD_INCL_SRVC_EVT`.
+ * 2. This function has to be called between `esp_ble_gatts_create_service` and `esp_ble_gatts_add_char`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle);
-
-
/**
- * @brief This function is called to add a characteristic into a service.
+ * @brief Add a characteristic into a service.
*
- * @param[in] service_handle: service handle to which this included service is to
- * be added.
- * @param[in] char_uuid : Characteristic UUID.
- * @param[in] perm : Characteristic value declaration attribute permission.
- * @param[in] property : Characteristic Properties
- * @param[in] char_val : Characteristic value
- * @param[in] control : attribute response control byte
+ * @param[in] service_handle Target service handle to add the characteristic
+ * @param[in] char_uuid The pointer to the characteristic UUID
+ * @param[in] perm Characteristic value declaration attribute permission
+ * @param[in] property Characteristic Properties
+ * @param[in] char_val The pointer to the characteristic value
+ * @param[in] control The pointer to the attribute response control byte
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note
+ * 1. This function triggers `ESP_GATTS_ADD_CHAR_EVT`.
+ * 2. `control->auto_rsp` should be set to `ESP_GATT_AUTO_RSP` or `ESP_GATT_RSP_BY_APP`.
+ * 3. For stack respond attribute (`ESP_GATT_AUTO_RSP`), `char_val` should not be NULL and `char_val->attr_max_len` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_ARG: Invalid arguments
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid,
esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
esp_attr_control_t *control);
-
/**
- * @brief This function is called to add characteristic descriptor. When
- * it's done, a callback event ESP_GATTS_ADD_DESCR_EVT is called
- * to report the status and an ID number for this descriptor.
- *
- * @param[in] service_handle: service handle to which this characteristic descriptor is to
- * be added.
- * @param[in] perm: descriptor access permission.
- * @param[in] descr_uuid: descriptor UUID.
- * @param[in] char_descr_val : Characteristic descriptor value
- * @param[in] control : attribute response control byte
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @brief Add a characteristic descriptor
+ *
+ * @param[in] service_handle Target service handle to add the characteristic descriptor
+ * @param[in] descr_uuid The pointer to the descriptor UUID
+ * @param[in] perm Descriptor access permission
+ * @param[in] char_descr_val The pointer to the characteristic descriptor value
+ * @param[in] control The pointer to the attribute response control byte
*
+ * @note
+ * 1. This function triggers `ESP_GATTS_ADD_CHAR_DESCR_EVT`.
+ * 2. `control->auto_rsp` should be set to `ESP_GATT_AUTO_RSP` or `ESP_GATT_RSP_BY_APP`.
+ * 3. For stack respond attribute (`ESP_GATT_AUTO_RSP`), `char_val` should not be NULL and `char_val->attr_max_len` must be greater than 0.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_ARG: Invalid arguments
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
esp_bt_uuid_t *descr_uuid,
esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
esp_attr_control_t *control);
-
-
/**
- * @brief This function is called to delete a service. When this is done,
- * a callback event ESP_GATTS_DELETE_EVT is report with the status.
+ * @brief Delete a service
*
- * @param[in] service_handle: service_handle to be deleted.
+ * @param[in] service_handle Target service handle to delete
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note This function triggers `ESP_GATTS_DELETE_EVT`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle);
-
-
/**
- * @brief This function is called to start a service.
+ * @brief Start a service
*
- * @param[in] service_handle: the service handle to be started.
+ * @param[in] service_handle Target service handle to start
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note This function triggers `ESP_GATTS_START_EVT`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_start_service(uint16_t service_handle);
-
-
/**
- * @brief This function is called to stop a service.
+ * @brief Stop a service.
*
- * @param[in] service_handle - service to be topped.
+ * @param[in] service_handle Target service handle to stop
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note This function triggers `ESP_GATTS_STOP_EVT`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle);
-
-
/**
- * @brief Send indicate or notify to GATT client.
- * Set param need_confirm as false will send notification, otherwise indication.
- * Note: the size of indicate or notify data need less than MTU size,see "esp_ble_gattc_send_mtu_req".
- *
- * @param[in] gatts_if: GATT server access interface
- * @param[in] conn_id - connection id to indicate.
- * @param[in] attr_handle - attribute handle to indicate.
- * @param[in] value_len - indicate value length.
- * @param[in] value: value to indicate.
- * @param[in] need_confirm - Whether a confirmation is required.
- * false sends a GATT notification, true sends a GATT indication.
+ * @brief Send indication or notification to a GATT Client
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @param[in] gatts_if GATT Server access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] attr_handle Attribute handle to indicate
+ * @param[in] value_len Indication value length in bytes
+ * @param[in] value Value to indicate
+ * @param[in] need_confirm True if a confirmation is required, which is a GATT indication; false if the confirmation is not required, which is a GATT notification.
+ *
+ * @note
+ * 1. This function triggers `ESP_GATTS_CONF_EVT`.
+ * 2. The size of indication or notification data must be less than or equal to MTU size, see `esp_ble_gattc_send_mtu_req`.
+ * 3. This function should be called only after the connection has been established.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, uint16_t attr_handle,
uint16_t value_len, uint8_t *value, bool need_confirm);
-
/**
- * @brief This function is called to send a response to a request.
+ * @brief Send a response to a request
*
- * @param[in] gatts_if: GATT server access interface
- * @param[in] conn_id - connection identifier.
- * @param[in] trans_id - transfer id
- * @param[in] status - response status
- * @param[in] rsp - response data.
+ * @param[in] gatts_if GATT Server access interface
+ * @param[in] conn_id Connection ID
+ * @param[in] trans_id Transfer ID
+ * @param[in] status Response status
+ * @param[in] rsp The pointer to the response data
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note
+ * 1. This function triggers `ESP_GATTS_RESPONSE_EVT`.
+ * 2. This function should be called only after the connection has been established.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_ERR_INVALID_STATE: The connection has not been established.
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
esp_gatt_status_t status, esp_gatt_rsp_t *rsp);
-
/**
- * @brief This function is called to set the attribute value by the application
+ * @brief Set the attribute value
*
- * @param[in] attr_handle: the attribute handle which to be set
- * @param[in] length: the value length
- * @param[in] value: the pointer to the attribute value
+ * @param[in] attr_handle Target attribute handle to set the value
+ * @param[in] length The value length in bytes
+ * @param[in] value The pointer to the attribute value
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note This function triggers `ESP_GATTS_SET_ATTR_VAL_EVT`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value);
/**
- * @brief Retrieve attribute value
+ * @brief Retrieve attribute value
*
- * @param[in] attr_handle: Attribute handle.
- * @param[out] length: pointer to the attribute value length
- * @param[out] value: Pointer to attribute value payload, the value cannot be modified by user
+ * @param[in] attr_handle Attribute handle
+ * @param[out] length The pointer to the attribute value length in bytes
+ * @param[out] value The pointer to attribute value payload. This value cannot be modified by user.
*
- * @return
- * - ESP_GATT_OK : success
- * - other : failed
+ * @note
+ * 1. This function does not trigger any event.
+ * 2. `attr_handle` must be greater than 0.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_GATT_INVALID_HANDLE: Invalid `attr_handle`
+ * - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value);
-
/**
- * @brief Open a direct open connection or add a background auto connection
+ * @brief Create an ACL connection when `BT_BLE_42_FEATURES_SUPPORTED` is enabled in the menuconfig
*
- * @param[in] gatts_if: GATT server access interface
- * @param[in] remote_bda: remote device bluetooth device address.
- * @param[in] is_direct: direct connection or background auto connection
+ * @param[in] gatts_if GATT Server access interface
+ * @param[in] remote_bda Remote device address
+ * @param[in] is_direct `True` indicates a direct connection, while `False` indicates a background auto connection. Currently, background auto connection is not supported, so please always set this parameter to True.
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note
+ * 1. The function always triggers `ESP_GATTS_CONNECT_EVT` and `ESP_GATTS_OPEN_EVT`.
+ * 2. When the device acts as GATT Server, besides the above two events, this function triggers `ESP_GATTS_CONNECT_EVT` as well.
+ * 3. This function will establish an ACL connection as a Central and a virtual connection as a GATT Server. If the ACL connection already exists, it will create a virtual connection only.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct);
/**
- * @brief Close a connection a remote device.
+ * @brief Close a connection with a remote device
*
- * @param[in] gatts_if: GATT server access interface
- * @param[in] conn_id: connection ID to be closed.
+ * @param[in] gatts_if GATT Server access interface
+ * @param[in] conn_id Connection ID to be closed
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note
+ * 1. This function triggers `ESP_GATTS_CLOSE_EVT`.
+ * 2. There may be multiple virtual GATT server connections when multiple `app_id` got registered.
+ * 3. This API closes one virtual GATT server connection only, if there exist other virtual GATT server connections. It does not close the physical connection.
+ * 4. The API `esp_ble_gap_disconnect` can be used to disconnect the physical connection directly.
+ * 5. If there is only one virtual GATT connection left, this API will terminate the ACL connection in addition, and trigger `ESP_GATTS_DISCONNECT_EVT`. Then there is no need to call `esp_ble_gap_disconnect` anymore.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id);
/**
- * @brief Send service change indication
+ * @brief Send service change indication
*
- * @param[in] gatts_if: GATT server access interface
- * @param[in] remote_bda: remote device bluetooth device address.
+ * @param[in] gatts_if GATT Server access interface
+ * @param[in] remote_bda Remote device address.
* If remote_bda is NULL then it will send service change
* indication to all the connected devices and if not then
- * to a specific device
+ * to a specific device.
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * @note This function triggers `ESP_GATTS_SEND_SERVICE_CHANGE_EVT`.
*
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda);
/**
- * @brief Print local database (GATT service table)
+ * @brief Display the Server's local attribute database.
*
- * @return
- * - ESP_OK : success
- * - other : failed
+ * This API prints the local attribute database of the BLE server, including details
+ * of all services, characteristics, and descriptors.
*
+ * @note
+ * 1. This function does not trigger any event.
+ * 2. It is primarily intended for debugging purposes to verify the server's current configuration.
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Failure
*/
esp_err_t esp_ble_gatts_show_local_database(void);
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h
index 84086118..f34c52c4 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,6 +10,7 @@
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_hf_defs.h"
+#include "esp_hf_ag_legacy_api.h"
#ifdef __cplusplus
extern "C" {
@@ -63,6 +64,7 @@ typedef enum
ESP_HF_WBS_RESPONSE_EVT, /*!< Codec Status */
ESP_HF_BCS_RESPONSE_EVT, /*!< Final Codec Choice */
ESP_HF_PKT_STAT_NUMS_GET_EVT, /*!< Request number of packet different status */
+ ESP_HF_PROF_STATE_EVT, /*!< Indicate HF init or deinit complete */
} esp_hf_cb_event_t;
/// Dial type of ESP_HF_DIAL_EVT
@@ -73,6 +75,14 @@ typedef enum
ESP_HF_DIAL_MEM, /*!< Dial with a memory position */
} esp_hf_dial_type_t;
+
+/// HFP AG profile status parameters
+typedef struct {
+ bool hfp_ag_inited; /*!< hfp ag initialization */
+ uint8_t slc_conn_num; /*!< Number of Service Level Connections */
+ uint8_t sync_conn_num; /*!< Number of (e)SCO Connections */
+} esp_hf_profile_status_t;
+
/// HFP AG callback parameters
typedef union
{
@@ -92,7 +102,8 @@ typedef union
struct hf_audio_stat_param {
esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */
esp_hf_audio_state_t state; /*!< Audio connection state */
- uint16_t sync_conn_handle; /*!< (e)SCO connection handle */
+ esp_hf_sync_conn_hdl_t sync_conn_handle; /*!< (e)SCO connection handle */
+ uint16_t preferred_frame_size; /*!< Valid only when Voice Over HCI is enabled, recommended frame size to send */
} audio_stat; /*!< AG callback param of ESP_HF_AUDIO_STATE_EVT */
/**
@@ -223,45 +234,37 @@ typedef union
uint32_t tx_discarded; /*!< the total number of packets send lost */
} pkt_nums; /*!< AG callback param of ESP_HF_PKT_STAT_NUMS_GET_EVT */
+ /**
+ * @brief ESP_HF_PROF_STATE_EVT
+ */
+ struct ag_prof_stat_param {
+ esp_hf_prof_state_t state; /*!< hf profile state param */
+ } prof_stat; /*!< status to indicate hf prof init or deinit */
+
} esp_hf_cb_param_t; /*!< HFP AG callback param compound*/
/**
- * @brief AG incoming data callback function, the callback is useful in case of
- * Voice Over HCI.
+ * @brief HF AG callback function type
*
- * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
- * buffer is allocated inside bluetooth protocol stack and will be released after
- * invoke of the callback is finished.
+ * @param event : Event type
*
- * @param[in] len : size(in bytes) in buf
+ * @param param : Pointer to callback parameter
*/
-typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
+typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param);
/**
- * @brief AG outgoing data callback function, the callback is useful in case of
- * Voice Over HCI. Once audio connection is set up and the application layer has
- * prepared data to send, the lower layer will call this function to read data
- * and then send. This callback is supposed to be implemented as non-blocking,
- * and if data is not enough, return value 0 is supposed.
+ * @brief HFP AG incoming audio data callback function, user should copy audio_buf struct
+ * to other place before return. This callback is used in case of Voice Over HCI.
*
- * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
- * buffer is allocated inside bluetooth protocol stack and will be released after
- * invoke of the callback is finished.
+ * @param[in] sync_conn_hdl: (e)SCO connection handle
*
- * @param[in] len : size(in bytes) in buf
+ * @param[in] audio_buf: pointer to incoming data(payload of HCI synchronous data packet), user
+ * should free audio buffer by calling esp_hf_ag_audio_buff_free
*
- * @return length of data successfully read
- */
-typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
-
-/**
- * @brief HF AG callback function type
- *
- * @param event : Event type
+ * @param[in] is_bad_frame: whether this packet is marked as bad frame by baseband
*
- * @param param : Pointer to callback parameter
*/
-typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param);
+typedef void (* esp_hf_ag_audio_data_cb_t)(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf, bool is_bad_frame);
/************************************************************************************
** ESP HF API
@@ -284,6 +287,7 @@ esp_err_t esp_hf_ag_register_callback(esp_hf_cb_t callback);
*
* @brief Initialize the bluetooth HF AG module.
* This function should be called after esp_bluedroid_enable() completes successfully.
+ * ESP_HF_PROF_STATE_EVT with ESP_HF_INIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: if the initialization request is sent successfully
@@ -297,6 +301,7 @@ esp_err_t esp_hf_ag_init(void);
*
* @brief De-initialize for HF AG module.
* This function should be called only after esp_bluedroid_enable() completes successfully.
+ * ESP_HF_PROF_STATE_EVT with ESP_HF_DEINIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: success
@@ -504,13 +509,13 @@ esp_err_t esp_hf_ag_cind_response(esp_bd_addr_t remote_addr,
/**
*
- * @brief Reponse for AT+COPS command from HF Client.
+ * @brief Response for AT+COPS command from HF Client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] name: current operator name
* @return
- * - ESP_OK: reponse for AT+COPS command is sent to lower layer
+ * - ESP_OK: response for AT+COPS command is sent to lower layer
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@@ -529,7 +534,7 @@ esp_err_t esp_hf_ag_cops_response(esp_bd_addr_t remote_addr, char *name);
* @param[in] mode: current call mode (voice/data/fax)
* @param[in] mpty: single or multi type
* @param[in] number: current call number
- * @param[in] type: international type or unknow
+ * @param[in] type: international type or unknown
* @return
* - ESP_OK: response to AT+CLCC command is sent to lower layer
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
@@ -668,19 +673,58 @@ esp_err_t esp_hf_ag_end_call(esp_bd_addr_t remote_addr, int num_active, int num_
char *number, esp_hf_call_addr_type_t call_addr_type);
/**
- * @brief Register AG data output function.
- * The callback is only used in the case that Voice Over HCI is enabled.
+ * @brief Register HFP AG audio data output function; the callback is only used in
+ * the case that Voice Over HCI is enabled.
*
- * @param[in] recv: HFP client incoming data callback function
- * @param[in] send: HFP client outgoing data callback function
+ * @param[in] callback: HFP AG incoming audio data callback function
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
- * - ESP_FAIL: if callback is a NULL function pointer
+ * - ESP_FAIL: others
*
*/
-esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send);
+esp_err_t esp_hf_ag_register_audio_data_callback(esp_hf_ag_audio_data_cb_t callback);
+
+/**
+ * @brief Allocate a audio buffer to store and send audio data. This function is only
+ * used in the case that Voice Over HCI is enabled.
+ *
+ * @param[in] size: buffer size to allocate
+ *
+ * @return allocated audio buffer, if Bluedroid is not enabled, no memory, or size is
+ * zeros, will return NULL
+ *
+ */
+esp_hf_audio_buff_t *esp_hf_ag_audio_buff_alloc(uint16_t size);
+
+/**
+ * @brief Free a audio buffer allocated by esp_hf_ag_audio_buff_alloc. This function
+ * is only used in the case that Voice Over HCI is enabled.
+ *
+ * @param[in] audio_buf: audio buffer to free
+ *
+ */
+void esp_hf_ag_audio_buff_free(esp_hf_audio_buff_t *audio_buf);
+
+/**
+ * @brief Send audio data, the audio buffer should by allocated by esp_hf_ag_audio_buff_alloc.
+ * If the length of the audio data is equal to preferred_frame_size indicated by
+ * ESP_HF_AUDIO_STATE_EVT, then we can reduce one memory copy inside the Bluedroid stack.
+ * This function is only used in the case that Voice Over HCI is enabled.
+ *
+ * @param[in] sync_conn_hdl: (e)SCO connection handle
+ *
+ * @param[in] audio_buf: audio buffer that audio data stored
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_ERR_INVALID_ARG: invalid parameter
+ * - ESP_FAIL: others
+ *
+ */
+esp_err_t esp_hf_ag_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf);
/**
*
@@ -700,14 +744,15 @@ esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_h
esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle);
/**
- * @brief Trigger the lower-layer to fetch and send audio data.
+ * @brief This function is used to get the status of hfp ag
*
- * This function is only used in the case that Voice Over HCI is enabled.
- * As a precondition to use this API, Service Level Connection shall exist with HFP client.
- * After this function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
+ * @param[out] profile_status - hfp ag status
*
+ * @return
+ * - ESP_OK: success
+ * - other: failed
*/
-void esp_hf_ag_outgoing_data_ready(void);
+esp_err_t esp_hf_ag_get_profile_status(esp_hf_profile_status_t *profile_status);
#ifdef __cplusplus
}
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_legacy_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_legacy_api.h
new file mode 100644
index 00000000..7cd0769b
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_ag_legacy_api.h
@@ -0,0 +1,77 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/*
+ * Some legacy APIs of HFP AG, will be removed in the future
+ */
+
+#pragma once
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+#include "esp_hf_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief AG incoming data callback function, the callback is useful in case of
+ * Voice Over HCI.
+ *
+ * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
+ * buffer is allocated inside bluetooth protocol stack and will be released after
+ * invoke of the callback is finished.
+ *
+ * @param[in] len : size(in bytes) in buf
+ */
+typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
+
+/**
+ * @brief AG outgoing data callback function, the callback is useful in case of
+ * Voice Over HCI. Once audio connection is set up and the application layer has
+ * prepared data to send, the lower layer will call this function to read data
+ * and then send. This callback is supposed to be implemented as non-blocking,
+ * and if data is not enough, return value 0 is supposed.
+ *
+ * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
+ * buffer is allocated inside bluetooth protocol stack and will be released after
+ * invoke of the callback is finished.
+ *
+ * @param[in] len : size(in bytes) in buf
+ *
+ * @return length of data successfully read
+ */
+typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
+
+/**
+ * @brief Register AG data output function.
+ * The callback is only used in the case that Voice Over HCI is enabled.
+ *
+ * @param[in] recv: HFP client incoming data callback function
+ * @param[in] send: HFP client outgoing data callback function
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_FAIL: if callback is a NULL function pointer
+ *
+ */
+esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send);
+
+/**
+ * @brief Trigger the lower-layer to fetch and send audio data.
+ *
+ * This function is only used in the case that Voice Over HCI is enabled.
+ * As a precondition to use this API, Service Level Connection shall exist with HFP client.
+ * After this function is called, lower layer will invoke esp_hf_ag_outgoing_data_cb_t to fetch data
+ *
+ */
+void esp_hf_ag_outgoing_data_ready(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h
index 9353fc03..53bf0396 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_client_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,6 +10,7 @@
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_hf_defs.h"
+#include "esp_hf_client_legacy_api.h"
#ifdef __cplusplus
extern "C" {
@@ -42,6 +43,15 @@ typedef enum {
ESP_HF_CLIENT_IN_BAND_RINGTONE_PROVIDED,
} esp_hf_client_in_band_ring_state_t;
+/**
+ * @brief HF client profile status parameters
+ */
+typedef struct {
+ bool hf_client_inited; /*!< hf client initialization */
+ uint8_t slc_conn_num; /*!< Number of Service Level Connections */
+ uint8_t sync_conn_num; /*!< Number of (e)SCO Connections */
+} esp_hf_client_profile_status_t;
+
/* features masks of AG */
#define ESP_HF_CLIENT_PEER_FEAT_3WAY 0x01 /* Three-way calling */
#define ESP_HF_CLIENT_PEER_FEAT_ECNR 0x02 /* Echo cancellation and/or noise reduction */
@@ -97,6 +107,7 @@ typedef enum {
ESP_HF_CLIENT_BINP_EVT, /*!< requested number of last voice tag from AG */
ESP_HF_CLIENT_RING_IND_EVT, /*!< ring indication event */
ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT, /*!< requested number of packet different status */
+ ESP_HF_CLIENT_PROF_STATE_EVT, /*!< Indicate HF CLIENT init or deinit complete */
} esp_hf_client_cb_event_t;
/// HFP client callback parameters
@@ -117,7 +128,8 @@ typedef union {
struct hf_client_audio_stat_param {
esp_hf_client_audio_state_t state; /*!< audio connection state */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
- uint16_t sync_conn_handle; /*!< (e)SCO connection handle */
+ esp_hf_sync_conn_hdl_t sync_conn_handle; /*!< (e)SCO connection handle */
+ uint16_t preferred_frame_size; /*!< valid only when Voice Over HCI is enabled, recommended frame size to send */
} audio_stat; /*!< HF callback param of ESP_HF_CLIENT_AUDIO_STATE_EVT */
/**
@@ -266,35 +278,28 @@ typedef union {
uint32_t tx_discarded; /*!< the total number of packets send lost */
} pkt_nums; /*!< HF callback param of ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT */
-} esp_hf_client_cb_param_t; /*!< HFP client callback parameters */
+ /**
+ * @brief ESP_HF_CLIENT_PROF_STATE_EVT
+ */
+ struct hf_client_prof_stat_param {
+ esp_hf_prof_state_t state; /*!< hf client profile state param */
+ } prof_stat; /*!< status to indicate hf client prof init or deinit */
-/**
- * @brief HFP client incoming data callback function, the callback is useful in case of
- * Voice Over HCI.
- * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
- * buffer is allocated inside bluetooth protocol stack and will be released after
- * invoke of the callback is finished.
- * @param[in] len : size(in bytes) in buf
- */
-typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
+} esp_hf_client_cb_param_t; /*!< HFP client callback parameters */
/**
- * @brief HFP client outgoing data callback function, the callback is useful in case of
- * Voice Over HCI. Once audio connection is set up and the application layer has
- * prepared data to send, the lower layer will call this function to read data
- * and then send. This callback is supposed to be implemented as non-blocking,
- * and if data is not enough, return value 0 is supposed.
+ * @brief HFP client incoming audio data callback function, user should copy audio_buf struct
+ * to other place before return. This callback is used in case of Voice Over HCI.
*
- * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
- * buffer is allocated inside bluetooth protocol stack and will be released after
- * invoke of the callback is finished.
+ * @param[in] sync_conn_hdl: (e)SCO connection handle
*
- * @param[in] len : size(in bytes) in buf
+ * @param[in] audio_buf: pointer to incoming data(payload of HCI synchronous data packet), user
+ * should free audio buffer by calling esp_hf_client_audio_buff_free
*
- * @return length of data successfully read
+ * @param[in] is_bad_frame: whether this packet is marked as bad frame by baseband
*
*/
-typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len);
+typedef void (* esp_hf_client_audio_data_cb_t)(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf, bool is_bad_frame);
/**
* @brief HFP client callback function type
@@ -323,6 +328,7 @@ esp_err_t esp_hf_client_register_callback(esp_hf_client_cb_t callback);
*
* @brief Initialize the bluetooth HFP client module.
* This function should be called after esp_bluedroid_enable() completes successfully.
+ * ESP_HF_CLIENT_PROF_STATE_EVT with ESP_HF_INIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: if the initialization request is sent successfully
@@ -336,6 +342,7 @@ esp_err_t esp_hf_client_init(void);
*
* @brief De-initialize for HFP client module.
* This function should be called only after esp_bluedroid_enable() completes successfully.
+ * ESP_HF_CLIENT_PROF_STATE_EVT with ESP_HF_DEINIT_SUCCESS will reported to the APP layer.
*
* @return
* - ESP_OK: success
@@ -422,7 +429,7 @@ esp_err_t esp_hf_client_start_voice_recognition(void);
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
- * - ESP_OK: stoping voice recognition is sent to lower layer
+ * - ESP_OK: stopping voice recognition is sent to lower layer
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@@ -652,50 +659,74 @@ esp_err_t esp_hf_client_request_last_voice_tag_number(void);
*/
esp_err_t esp_hf_client_send_nrec(void);
-
/**
- * @brief Register HFP client data output function; the callback is only used in
- * the case that Voice Over HCI is enabled.
*
- * @param[in] recv: HFP client incoming data callback function
+ * @brief Get the number of packets received and sent
+ * This function is only used in the case that Voice Over HCI is enabled and the audio state is connected.
+ * When the operation is completed, the callback function will be called with ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT.
*
- * @param[in] send: HFP client outgoing data callback function
+ * @param[in] sync_conn_handle: the (e)SCO connection handle
*
* @return
- * - ESP_OK: success
+ * - ESP_OK: if the request is sent successfully
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
- * - ESP_FAIL: if callback is a NULL function pointer
+ * - ESP_FAIL: others
*
*/
-esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv,
- esp_hf_client_outgoing_data_cb_t send);
+esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle);
/**
+ * @brief Register HFP client audio data output function; the callback is only used in
+ * the case that Voice Over HCI is enabled.
*
- * @brief Get the number of packets received and sent
- * This function is only used in the case that Voice Over HCI is enabled and the audio state is connected.
- * When the operation is completed, the callback function will be called with ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT.
- *
- * @param[in] sync_conn_handle: the (e)SCO connection handle
+ * @param[in] callback: HFP client incoming audio data callback function
*
* @return
- * - ESP_OK: if the request is sent successfully
+ * - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
-esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle);
+esp_err_t esp_hf_client_register_audio_data_callback(esp_hf_client_audio_data_cb_t callback);
/**
- * @brief Trigger the lower-layer to fetch and send audio data.
- * This function is only only used in the case that Voice Over HCI is enabled. After this
- * function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data.
+ * @brief Allocate a audio buffer to store and send audio data. This function is only
+ * used in the case that Voice Over HCI is enabled.
*
- * As a precondition to use this API, Service Level Connection shall exist with AG.
+ * @param[in] size: buffer size to allocate
+ *
+ * @return allocated audio buffer, if Bluedroid is not enabled, no memory, or size is
+ * zeros, will return NULL
*
*/
-void esp_hf_client_outgoing_data_ready(void);
+esp_hf_audio_buff_t *esp_hf_client_audio_buff_alloc(uint16_t size);
+/**
+ * @brief Free a audio buffer allocated by esp_hf_client_audio_buff_alloc. This function
+ * is only used in the case that Voice Over HCI is enabled.
+ *
+ * @param[in] audio_buf: audio buffer to free
+ *
+ */
+void esp_hf_client_audio_buff_free(esp_hf_audio_buff_t *audio_buf);
+
+/**
+ * @brief Send audio data, the audio buffer should by allocated by esp_hf_client_audio_buff_alloc.
+ * If the length of the audio data is equal to preferred_frame_size indicated by
+ * ESP_HF_CLIENT_AUDIO_STATE_EVT, then we can reduce one memory copy inside the Bluedroid stack.
+ * This function is only used in the case that Voice Over HCI is enabled.
+ *
+ * @param[in] sync_conn_hdl: (e)SCO connection handle
+ *
+ * @param[in] audio_buf: audio buffer that audio data stored
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_ERR_INVALID_ARG: invalid parameter
+ *
+ */
+esp_err_t esp_hf_client_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf);
/**
* @brief Initialize the down sampling converter. This is a utility function that can
@@ -728,6 +759,17 @@ void esp_hf_client_pcm_resample_deinit(void);
*/
int32_t esp_hf_client_pcm_resample(void *src, uint32_t in_bytes, void *dst);
+/**
+ * @brief This function is used to get the status of hf client
+ *
+ * @param[out] profile_status - hf client status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_hf_client_get_profile_status(esp_hf_client_profile_status_t *profile_status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_client_legacy_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_client_legacy_api.h
new file mode 100644
index 00000000..6441bfc4
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_client_legacy_api.h
@@ -0,0 +1,78 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/*
+ * Some legacy APIs of HFP HF, will be removed in the future
+ */
+
+#pragma once
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+#include "esp_hf_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief HFP client incoming data callback function, the callback is useful in case of
+ * Voice Over HCI.
+ * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
+ * buffer is allocated inside bluetooth protocol stack and will be released after
+ * invoke of the callback is finished.
+ * @param[in] len : size(in bytes) in buf
+ */
+typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
+
+/**
+ * @brief HFP client outgoing data callback function, the callback is useful in case of
+ * Voice Over HCI. Once audio connection is set up and the application layer has
+ * prepared data to send, the lower layer will call this function to read data
+ * and then send. This callback is supposed to be implemented as non-blocking,
+ * and if data is not enough, return value 0 is supposed.
+ *
+ * @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
+ * buffer is allocated inside bluetooth protocol stack and will be released after
+ * invoke of the callback is finished.
+ *
+ * @param[in] len : size(in bytes) in buf
+ *
+ * @return length of data successfully read
+ *
+ */
+typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len);
+
+/**
+ * @brief Register HFP client data output function; the callback is only used in
+ * the case that Voice Over HCI is enabled.
+ *
+ * @param[in] recv: HFP client incoming data callback function
+ *
+ * @param[in] send: HFP client outgoing data callback function
+ *
+ * @return
+ * - ESP_OK: success
+ * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+ * - ESP_FAIL: if callback is a NULL function pointer
+ *
+ */
+esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv,
+ esp_hf_client_outgoing_data_cb_t send);
+
+/**
+ * @brief Trigger the lower-layer to fetch and send audio data.
+ * This function is only only used in the case that Voice Over HCI is enabled. After this
+ * function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data.
+ *
+ * As a precondition to use this API, Service Level Connection shall exist with AG.
+ *
+ */
+void esp_hf_client_outgoing_data_ready(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h b/lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h
index b7671ff1..e6ca2e70 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_hf_defs.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,6 +13,18 @@
extern "C" {
#endif
+typedef uint16_t esp_hf_sync_conn_hdl_t;
+
+/// profile states
+typedef enum {
+ ESP_HF_INIT_SUCCESS = 0, /*!< Indicate init successful */
+ ESP_HF_INIT_ALREADY, /*!< Indicate init repeated */
+ ESP_HF_INIT_FAIL, /*!< Indicate init fail */
+ ESP_HF_DEINIT_SUCCESS, /*!< Indicate deinit successful */
+ ESP_HF_DEINIT_ALREADY, /*!< Indicate deinit repeated */
+ ESP_HF_DEINIT_FAIL, /*!< Indicate deinit fail */
+} esp_hf_prof_state_t;
+
/// in-band ring tone state
typedef enum {
ESP_HF_IN_BAND_RINGTONE_NOT_PROVIDED = 0,
@@ -128,7 +140,7 @@ typedef enum {
/// +CLCC address type
typedef enum {
- ESP_HF_CALL_ADDR_TYPE_UNKNOWN = 0x81, /*!< unkown address type */
+ ESP_HF_CALL_ADDR_TYPE_UNKNOWN = 0x81, /*!< unknown address type */
ESP_HF_CALL_ADDR_TYPE_INTERNATIONAL = 0x91, /*!< international address */
} esp_hf_call_addr_type_t;
@@ -160,7 +172,7 @@ typedef enum
ESP_HF_NREC_START
} esp_hf_nrec_t;
-///+CCWA resposne status
+///+CCWA response status
typedef enum {
ESP_HF_CALL_WAITING_INACTIVE,
ESP_HF_CALL_WAITING_ACTIVE,
@@ -239,6 +251,25 @@ typedef enum {
ESP_HF_CME_NETWORK_NOT_ALLOWED = 32, /*!< network not allowed --emergency calls only */
} esp_hf_cme_err_t;
+/* Since HFP uses a fixed set of mSBC codec parameters, define it here */
+#define ESP_HF_MSBC_CHANNEL_MODE "Mono" /*!< mSBC channel mode */
+#define ESP_HF_MSBC_SAMPLING_RATE "16 kHz" /*!< mSBC sampling rate */
+#define ESP_HF_MSBC_ALLOCATION_METHOD "Loudness" /*!< mSBC allocation method */
+#define ESP_HF_MSBC_SUBBANDS 8 /*!< mSBC subbands */
+#define ESP_HF_MSBC_BLOCK_LENGTH 15 /*!< mSBC block length */
+#define ESP_HF_MSBC_BITPOOL 26 /*!< mSBC bitpool */
+/* frame size after mSBC encoded */
+#define ESP_HF_MSBC_ENCODED_FRAME_SIZE 57 /*!< mSBC frame size */
+
+/**
+ * @brief HFP audio buffer
+ */
+typedef struct {
+ uint16_t buff_size; /*!< buffer size */
+ uint16_t data_len; /*!< audio data length, data length should not greater than buffer size */
+ uint8_t *data; /*!< pointer to audio data start */
+} esp_hf_audio_buff_t; /*!< struct to store audio data */
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h
index a2af1659..f16bbcb0 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_hidd_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -146,6 +146,16 @@ typedef enum {
} esp_hidd_status_t;
/**
+ * @brief HID device profile status parameters
+ */
+typedef struct {
+ bool hidd_inited; /*!< HID device initialization */
+ uint8_t conn_num; /*!< Number of connections */
+ uint8_t plug_vc_dev_num; /*!< Number of plugged virtual cable devices */
+ uint8_t reg_app_num; /*!< Number of HID device application registrations */
+} esp_hidd_profile_status_t;
+
+/**
* @brief HID device callback parameters union
*/
typedef union {
@@ -335,6 +345,11 @@ esp_err_t esp_bt_hid_device_unregister_app(void);
* called after esp_bt_hid_device_init(). When the operation is complete, the callback function will
* be called with ESP_HIDD_OPEN_EVT.
*
+ * @note The connection between the HID Host and the HID Device is established as a virtual cable by default.
+ * A new HID Host connection request will only be accepted after the previous HID Host has been
+ * explicitly unplugged. For details on disconnection and virtual cable unplugging, please refer to API
+ * `esp_bt_hid_device_disconnect` and `esp_bt_hid_device_virtual_cable_unplug`.
+ *
* @param[in] bd_addr: Remote host bluetooth device address.
*
* @return
@@ -406,6 +421,17 @@ esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error);
*/
esp_err_t esp_bt_hid_device_virtual_cable_unplug(void);
+/**
+ * @brief This function is used to get the status of hid device
+ *
+ * @param[out] profile_status - HID device status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_bt_hid_device_get_profile_status(esp_hidd_profile_status_t *profile_status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h b/lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h
index 46f8a15b..51a0d43f 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_hidh_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -104,7 +104,7 @@ typedef enum {
typedef enum {
ESP_HIDH_DEV_ATTR_VIRTUAL_CABLE = 0x0001, /*!< whether Virtual Cables is supported */
ESP_HIDH_DEV_ATTR_NORMALLY_CONNECTABLE = 0x0002, /*!< whether device is in Page Scan mode when there is no active connection */
- ESP_HIDH_DEV_ATTR_RECONNECT_INITIATE = 0x0004, /*!< whether the HID device inititates the reconnection process */
+ ESP_HIDH_DEV_ATTR_RECONNECT_INITIATE = 0x0004, /*!< whether the HID device initiates the reconnection process */
} esp_hidh_dev_attr_t;
/**
@@ -128,12 +128,21 @@ typedef struct {
int vendor_id; /*!< Device ID information: vendor ID */
int product_id; /*!< Device ID information: product ID */
int version; /*!< Device ID information: version */
- uint8_t ctry_code; /*!< SDP attrbutes of HID devices: HID country code (https://www.usb.org/sites/default/files/hid1_11.pdf) */
- int dl_len; /*!< SDP attrbutes of HID devices: HID device descriptor length */
- uint8_t dsc_list[BTHH_MAX_DSC_LEN]; /*!< SDP attrbutes of HID devices: HID device descriptor definition */
+ uint8_t ctry_code; /*!< SDP attributes of HID devices: HID country code (https://www.usb.org/sites/default/files/hid1_11.pdf) */
+ int dl_len; /*!< SDP attributes of HID devices: HID device descriptor length */
+ uint8_t dsc_list[BTHH_MAX_DSC_LEN]; /*!< SDP attributes of HID devices: HID device descriptor definition */
} esp_hidh_hid_info_t;
/**
+ * @brief HID host profile status parameters
+ */
+typedef struct {
+ bool hidh_inited; /*!< HID host initialization */
+ uint8_t conn_num; /*!< Number of connections */
+ uint8_t plug_vc_dev_num; /*!< Number of plugged virtual cable devices*/
+} esp_hidh_profile_status_t;
+
+/**
* @brief HID host callback parameters union
*/
typedef union {
@@ -157,7 +166,7 @@ typedef union {
struct hidh_open_evt_param {
esp_hidh_status_t status; /*!< operation status */
esp_hidh_connection_state_t conn_status; /*!< connection status */
- bool is_orig; /*!< indicate if host intiate the connection */
+ bool is_orig; /*!< indicate if host initiate the connection */
uint8_t handle; /*!< device handle */
esp_bd_addr_t bd_addr; /*!< device address */
} open; /*!< HIDH callback param of ESP_HIDH_OPEN_EVT */
@@ -475,6 +484,17 @@ esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type
*/
esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len);
+/**
+ * @brief This function is used to get the status of hid host
+ *
+ * @param[out] profile_status - HID host status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_bt_hid_host_get_profile_status(esp_hidh_profile_status_t *profile_status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h b/lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h
index f11c932f..982cbdaa 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -41,6 +41,14 @@ typedef enum {
typedef uint32_t esp_bt_l2cap_cntl_flags_t;
/**
+ * @brief L2CAP status parameters
+ */
+typedef struct {
+ bool l2cap_inited; /*!< l2cap initialization */
+ uint8_t conn_num; /*!< Number of connections */
+} esp_bt_l2cap_protocol_status_t;
+
+/**
* @brief L2CAP callback function events
*/
typedef enum {
@@ -51,6 +59,8 @@ typedef enum {
ESP_BT_L2CAP_START_EVT = 18, /*!< When L2CAP server started, the event comes */
ESP_BT_L2CAP_CL_INIT_EVT = 19, /*!< When L2CAP client initiated a connection, the event comes */
ESP_BT_L2CAP_SRV_STOP_EVT = 36, /*!< When L2CAP server stopped, the event comes */
+ ESP_BT_L2CAP_VFS_REGISTER_EVT = 38, /*!< When L2CAP VFS register, the event comes */
+ ESP_BT_L2CAP_VFS_UNREGISTER_EVT = 39, /*!< When L2CAP VFS unregister, the event comes */
} esp_bt_l2cap_cb_event_t;
/**
@@ -114,9 +124,23 @@ typedef union {
*/
struct l2cap_srv_stop_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
- uint8_t psm; /*!< local psm */
+ uint16_t psm; /*!< local psm */
} srv_stop; /*!< L2CAP callback param of ESP_BT_L2CAP_SRV_STOP_EVT */
+ /**
+ * @brief ESP_BT_L2CAP_VFS_REGISTER_EVT
+ */
+ struct l2cap_vfs_register_evt_param {
+ esp_bt_l2cap_status_t status; /*!< status */
+ } vfs_register; /*!< L2CAP callback param of ESP_BT_L2CAP_VFS_REGISTER_EVT */
+
+ /**
+ * @brief ESP_BT_L2CAP_VFS_UNREGISTER_EVT
+ */
+ struct l2cap_vfs_unregister_evt_param {
+ esp_bt_l2cap_status_t status; /*!< status */
+ } vfs_unregister; /*!< L2CAP callback param of ESP_BT_L2CAP_VFS_UNREGISTER_EVT */
+
} esp_bt_l2cap_cb_param_t;
/**
@@ -226,6 +250,7 @@ esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm);
/**
* @brief This function is used to register VFS.
* Only supports write, read and close.
+ * When the operation is completed, the callback function will be called with ESP_BT_L2CAP_VFS_REGISTER_EVT.
* This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @return
@@ -236,6 +261,7 @@ esp_err_t esp_bt_l2cap_vfs_register(void);
/**
* @brief This function is used to unregister VFS.
+ * When the operation is completed, the callback function will be called with ESP_BT_L2CAP_VFS_UNREGISTER_EVT.
* This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @return
@@ -244,6 +270,17 @@ esp_err_t esp_bt_l2cap_vfs_register(void);
*/
esp_err_t esp_bt_l2cap_vfs_unregister(void);
+/**
+ * @brief This function is used to get the status of L2CAP
+ *
+ * @param[out] status - l2cap status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_bt_l2cap_get_protocol_status(esp_bt_l2cap_protocol_status_t *status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_pba_defs.h b/lib/bt/host/bluedroid/api/include/api/esp_pba_defs.h
new file mode 100644
index 00000000..c3a6f510
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/include/api/esp_pba_defs.h
@@ -0,0 +1,27 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "esp_bt_defs.h"
+
+/* Supported repositories bit mask */
+#define ESP_PBA_SUPPORTED_REPO_LOCAL_PHONE_BOOK 0x01
+#define ESP_PBA_SUPPORTED_REPO_SIM_CARD 0x02
+#define ESP_PBA_SUPPORTED_REPO_SPEED_DIAL 0x04
+#define ESP_PBA_SUPPORTED_REPO_FAVORITES 0x08
+
+/* Supported features bit mask */
+#define ESP_PBA_SUPPORTED_FEAT_DOWNLOAD 0x0001
+#define ESP_PBA_SUPPORTED_FEAT_BROWSING 0x0002
+#define ESP_PBA_SUPPORTED_FEAT_DATABASE_IDENTIFIER 0x0004
+#define ESP_PBA_SUPPORTED_FEAT_FOLDER_VERSION_COUNTERS 0x0008
+#define ESP_PBA_SUPPORTED_FEAT_VCARD_SELECTING 0x0010
+#define ESP_PBA_SUPPORTED_FEAT_ENHANCED_MISSED_CALLS 0x0020
+#define ESP_PBA_SUPPORTED_FEAT_X_BT_UCI_VCARD_PROPERTY 0x0040
+#define ESP_PBA_SUPPORTED_FEAT_X_BT_UID_VCARD_PROPERTY 0x0080
+#define ESP_PBA_SUPPORTED_FEAT_CONTACT_REFERENCING 0x0100
+#define ESP_PBA_SUPPORTED_FEAT_DEFAULT_CONTACT_IMAGE_FORMAT 0x0200
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_pbac_api.h b/lib/bt/host/bluedroid/api/include/api/esp_pbac_api.h
new file mode 100644
index 00000000..131d53f8
--- /dev/null
+++ b/lib/bt/host/bluedroid/api/include/api/esp_pbac_api.h
@@ -0,0 +1,340 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+#include "esp_pba_defs.h"
+
+#define ESP_PBAC_INVALID_HANDLE 0 /*!< invalid handle value */
+
+typedef uint16_t esp_pbac_conn_hdl_t;
+
+/**
+ * @brief PBA client callback events
+ */
+typedef enum {
+ ESP_PBAC_INIT_EVT, /*!< PBA client initialized event */
+ ESP_PBAC_DEINIT_EVT, /*!< PBA client de-initialized event */
+ ESP_PBAC_CONNECTION_STATE_EVT, /*!< PBA client connection state changed event */
+ ESP_PBAC_PULL_PHONE_BOOK_RESPONSE_EVT, /*!< Response of pull phone book */
+ ESP_PBAC_SET_PHONE_BOOK_RESPONSE_EVT, /*!< Response of set phone book */
+ ESP_PBAC_PULL_VCARD_LISTING_RESPONSE_EVT, /*!< Response of pull vCard listing */
+ ESP_PBAC_PULL_VCARD_ENTRY_RESPONSE_EVT, /*!< Response of pull vCard entry */
+} esp_pbac_event_t;
+
+/**
+ * @brief PBA client status code
+ */
+typedef enum {
+ ESP_PBAC_SUCCESS = 0, /*!< Operation success */
+ ESP_PBAC_FAILURE, /*!< Generic failure */
+ ESP_PBAC_ALREADY_CONN, /*!< Connection to peer device already exist */
+ ESP_PBAC_NO_RESOURCE, /*!< No more resource */
+ ESP_PBAC_SDP_FAIL, /*!< Connection failed in SDP */
+ ESP_PBAC_GOEP_FAIL, /*!< Operation failed in GOEP */
+ ESP_PBAC_AUTH_FAIL, /*!< Connection failed in OBEX authentication */
+ ESP_PBAC_DEINIT, /*!< Connection closed due to pba client is deinit */
+
+ /* these error code is related to OBEX */
+ ESP_PBAC_BAD_REQUEST = 0xC0, /*!< Server couldn't understand request */
+ ESP_PBAC_UNAUTHORIZED = 0xC1, /*!< Unauthorized */
+ ESP_PBAC_FORBIDDEN = 0xC3, /*!< Operation is understood but refused */
+ ESP_PBAC_NOT_FOUND = 0xC4, /*!< Not found */
+ ESP_PBAC_NOT_ACCEPTABLE = 0xC6, /*!< Not Acceptable */
+ ESP_PBAC_PRECONDITION_FAILED = 0xCC, /*!< Precondition failed */
+ ESP_PBAC_NOT_IMPLEMENTED = 0xD1, /*!< Not implemented */
+ ESP_PBAC_SERVICE_UNAVAILABLE = 0xD3, /*!< Service unavailable */
+} esp_pbac_status_t;
+
+/**
+ * @brief PBA client set phone book flags
+ */
+typedef enum {
+ ESP_PBAC_SET_PHONE_BOOK_FLAGS_ROOT = 0x02, /*!< Go back to root, name should set to empty string, not NULL */
+ ESP_PBAC_SET_PHONE_BOOK_FLAGS_DOWN = 0x02, /*!< Go down 1 level, name should set to child folder */
+ ESP_PBAC_SET_PHONE_BOOK_FLAGS_UP = 0x03, /*!< Go up 1 level, name is optional */
+} esp_pbac_set_phone_book_flags_t;
+
+/**
+ * @brief PBA client pull phone book optional application parameter
+ */
+typedef struct {
+ uint8_t include_property_selector : 1; /*!< 1 if app param include property_selector */
+ uint8_t include_format : 1; /*!< 1 if app param include format */
+ uint8_t include_max_list_count : 1; /*!< 1 if app param include max_list_count */
+ uint8_t include_list_start_offset : 1; /*!< 1 if app param include list_start_offset */
+ uint8_t include_reset_new_missed_calls : 1; /*!< 1 if app param include reset_new_missed_calls */
+ uint8_t include_vcard_selector : 1; /*!< 1 if app param include vcard_selector */
+ uint8_t include_vcard_selector_operator : 1; /*!< 1 if app param include vcard_selector_operator */
+ uint8_t format; /*!< 0x00 = 2.1, 0x01 = 3.0 */
+ uint8_t reset_new_missed_calls; /*!< 0x01 = Reset */
+ uint8_t vcard_selector_operator; /*!< 0x00 = OR, 0x01 = AND */
+ uint16_t max_list_count; /*!< 0x0000 to 0xFFFF */
+ uint16_t list_start_offset; /*!< 0x0000 to 0xFFFF */
+ uint64_t property_selector; /*!< 64 bits mask */
+ uint64_t vcard_selector; /*!< 64 bits mask */
+} esp_pbac_pull_phone_book_app_param_t;
+
+/**
+ * @brief PBA client pull vCard listing optional application parameter
+ */
+typedef struct {
+ uint8_t include_order : 1; /*!< 1 if app param include order */
+ uint8_t include_search_value : 1; /*!< 1 if app param include search_value */
+ uint8_t include_search_property : 1; /*!< 1 if app param include search_property */
+ uint8_t include_max_list_count : 1; /*!< 1 if app param include max_list_count */
+ uint8_t include_list_start_offset : 1; /*!< 1 if app param include list_start_offset */
+ uint8_t include_reset_new_missed_calls : 1; /*!< 1 if app param include reset_new_missed_calls */
+ uint8_t include_vcard_selector : 1; /*!< 1 if app param include vcard_selector */
+ uint8_t include_vcard_selector_operator : 1; /*!< 1 if app param include vcard_selector_operator */
+ uint8_t order; /*!< 0x00 = indexed, 0x01 = alphanumeric */
+ uint8_t search_property; /*!< 0x00 = Name, 0x01 = Number, 0x02 = Sound */
+ uint8_t reset_new_missed_calls; /*!< 0x01 = Reset */
+ uint8_t vcard_selector_operator; /*!< 0x00 = OR, 0x01 = AND */
+ uint16_t max_list_count; /*!< 0x0000 to 0xFFFF */
+ uint16_t list_start_offset; /*!< 0x0000 to 0xFFFF */
+ char *search_value; /*!< Text */
+ uint64_t vcard_selector; /*!< 64 bits mask */
+} esp_pbac_pull_vcard_listing_app_param_t;
+
+/**
+ * @brief PBA client pull vCard entry optional application parameter
+ */
+typedef struct {
+ uint8_t include_property_selector : 1; /*!< 1 if app param include property_selector */
+ uint8_t include_format : 1; /*!< 1 if app param include format */
+ uint8_t format; /*!< 0x00 = 2.1, 0x01 = 3.0 */
+ uint64_t property_selector; /*!< 64 bits mask */
+} esp_pbac_pull_vcard_entry_app_param_t;
+
+/**
+ * @brief PBA client callback parameters
+ */
+typedef union {
+ /**
+ * @brief ESP_PBAC_CONNECTION_STATE_EVT
+ */
+ struct pbac_conn_stat_param {
+ bool connected; /*!< whether pba client is connected to server */
+ esp_pbac_conn_hdl_t handle; /*!< connection handle, non zeros if exist */
+ uint8_t peer_supported_repo; /*!< peer supported repositories */
+ uint32_t peer_supported_feat; /*!< peer supported features */
+ esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
+ esp_pbac_status_t reason; /*!< reason if disconnect */
+ } conn_stat; /*!< PBA client connection status */
+
+ /**
+ * @brief ESP_PBAC_PULL_PHONE_BOOK_RESPONSE_EVT
+ */
+ struct pbac_pull_phone_book_rsp_param {
+ esp_pbac_conn_hdl_t handle; /*!< PBA client connection handle */
+ esp_pbac_status_t result; /*!< operation result, ESP_PBAC_SUCCESS if success */
+ bool final; /*!< whether this is the final response packet */
+ uint8_t *data; /*!< response data */
+ uint16_t data_len; /*!< response data len */
+ /* The following are the application parameters */
+ uint8_t include_phone_book_size : 1; /*!< 1 if app param include phone_book_size */
+ uint8_t include_new_missed_calls : 1; /*!< 1 if app param include new_missed_calls */
+ uint8_t include_primary_folder_version : 1; /*!< 1 if app param include primary_folder_version */
+ uint8_t include_secondary_folder_version : 1; /*!< 1 if app param include secondary_folder_version */
+ uint8_t include_database_identifier : 1; /*!< 1 if app param include database_identifier */
+ uint8_t new_missed_calls; /*!< 0x00 to 0xFF */
+ uint16_t phone_book_size; /*!< 0x0000 to 0xFFFF */
+ uint8_t *primary_folder_version; /*!< 0 to (2^128 -1) */
+ uint8_t *secondary_folder_version; /*!< 0 to (2^128 -1) */
+ uint8_t *database_identifier; /*!< 0 to (2^128 -1) */
+ } pull_phone_book_rsp; /*!< pull phone book response */
+
+ /**
+ * @brief ESP_PBAC_SET_PHONE_BOOK_RESPONSE_EVT
+ */
+ struct pbac_set_phone_book_rsp_param {
+ esp_pbac_conn_hdl_t handle; /*!< PBA client connection handle */
+ esp_pbac_status_t result; /*!< operation result, ESP_PBAC_SUCCESS if success */
+ } set_phone_book_rsp; /*!< set phone book response, always the final response */
+
+ /**
+ * @brief ESP_PBAC_PULL_VCARD_LISTING_RESPONSE_EVT
+ */
+ struct pbac_pull_vcard_listing_rsp_param {
+ esp_pbac_conn_hdl_t handle; /*!< PBA client connection handle */
+ esp_pbac_status_t result; /*!< operation result, ESP_PBAC_SUCCESS if success */
+ bool final; /*!< whether this is the final response packet */
+ uint8_t *data; /*!< response data */
+ uint16_t data_len; /*!< response data len */
+ /* The following are the application parameters */
+ uint8_t include_phone_book_size : 1; /*!< 1 if app param include phone_book_size */
+ uint8_t include_new_missed_calls : 1; /*!< 1 if app param include new_missed_calls */
+ uint8_t include_primary_folder_version : 1; /*!< 1 if app param include primary_folder_version */
+ uint8_t include_secondary_folder_version : 1; /*!< 1 if app param include secondary_folder_version */
+ uint8_t include_database_identifier : 1; /*!< 1 if app param include database_identifier */
+ uint8_t new_missed_calls; /*!< 0x00 to 0xFF */
+ uint16_t phone_book_size; /*!< 0x0000 to 0xFFFF */
+ uint8_t *primary_folder_version; /*!< 0 to (2^128 -1) */
+ uint8_t *secondary_folder_version; /*!< 0 to (2^128 -1) */
+ uint8_t *database_identifier; /*!< 0 to (2^128 -1) */
+ } pull_vcard_listing_rsp; /*!< pull vcard listing response */
+
+ /**
+ * @brief ESP_PBAC_PULL_VCARD_ENTRY_RESPONSE_EVT
+ */
+ struct pbac_pull_vcard_entry_rsp_param {
+ esp_pbac_conn_hdl_t handle; /*!< PBA client connection handle */
+ esp_pbac_status_t result; /*!< operation result, ESP_PBAC_SUCCESS if success */
+ bool final; /*!< whether this is the final response packet */
+ uint8_t *data; /*!< response data */
+ uint16_t data_len; /*!< response data len */
+ /* The following are the application parameters */
+ uint8_t include_database_identifier : 1; /*!< 1 if app param include database_identifier */
+ uint8_t *database_identifier; /*!< 0 to (2^128 -1) */
+ } pull_vcard_entry_rsp; /*!< pull vcard listing response */
+} esp_pbac_param_t;
+
+/**
+ * @brief PBA client callback function type
+ *
+ * @param event : Event type
+ *
+ * @param param : Pointer to callback parameter
+ */
+typedef void (*esp_pbac_callback_t)(esp_pbac_event_t event, esp_pbac_param_t *param);
+
+
+/**
+ * @brief This function is called to register a user callbacks in PBA client.
+ *
+ * @param[in] callback: pointer to the user callback function.
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_register_callback(esp_pbac_callback_t callback);
+
+/**
+ * @brief Initializes PBA client interface. This function should be called after bluedroid
+ * enable successfully, and should be called after esp_pbac_register_callback.
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_init(void);
+
+/**
+ * @brief De-initializes PBA client interface. This will close all PBA client connection.
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_deinit(void);
+
+/**
+ * @brief Start the process to establish a connection to PBA server.
+ *
+ * @param[in] bd_addr: peer bluetooth device address
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_connect(esp_bd_addr_t bd_addr);
+
+/**
+ * @brief Disconnects from the current connected PBA server.
+ *
+ * @param[in] handle: connection handle retrieved from ESP_PBAC_CONNECTION_STATE_EVT
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_disconnect(esp_pbac_conn_hdl_t handle);
+
+/**
+ * @brief Send a request to pull phone book.
+ *
+ * @param[in] handle: connection handle retrieved from ESP_PBAC_CONNECTION_STATE_EVT
+ *
+ * @param[in] name: phone book object path and name, shall contain the absolute path
+ * in the virtual folder architecture
+ *
+ * @param[in] app_param: optional application parameter
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_pull_phone_book(esp_pbac_conn_hdl_t handle, const char *name, esp_pbac_pull_phone_book_app_param_t *app_param);
+
+/**
+ * @brief Send a request to set the current folder in the virtual folder architecture.
+ *
+ * @param[in] handle: connection handle retrieved from ESP_PBAC_CONNECTION_STATE_EVT
+ *
+ * @param[in] flags: operation flags, one of ESP_PBAC_SET_PHONE_BOOK_FLAGS_XXX
+ *
+ * @param[in] name: folder name, if flags is set to ROOT, name should be empty string (""),
+ * if flags is set to UP, name is optional, if flags is set to DOWN, name
+ * is mandatory
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_set_phone_book(esp_pbac_conn_hdl_t handle, esp_pbac_set_phone_book_flags_t flags, const char *name);
+
+/**
+ * @brief Set the current folder in the virtual folder architecture, use absolute path.
+ *
+ * @param[in] handle: connection handle retrieved from ESP_PBAC_CONNECTION_STATE_EVT
+ *
+ * @param[in] path: absolute path of the folder intend to set. NULL or empty string will
+ * set to ROOT
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_set_phone_book2(esp_pbac_conn_hdl_t handle, const char *path);
+
+/**
+ * @brief Send a request to pull vCard listing.
+ *
+ * @param[in] handle: connection handle retrieved from ESP_PBAC_CONNECTION_STATE_EVT
+ *
+ * @param[in] name: specifies the name of the folder to be retrieved, uses relative paths,
+ * shall not include any path information. An empty name (empty string "")
+ * may be sent to retrieve the vCard Listing object of the current folder.
+ * However, it is illegal to issue a pull vCard listing request with an
+ * empty name header from the ‘telecom/’ folder
+ *
+ * @param[in] app_param: optional application parameter
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_pull_vcard_listing(esp_pbac_conn_hdl_t handle, const char *name, esp_pbac_pull_vcard_listing_app_param_t *app_param);
+
+/**
+ * @brief Send a request to pull vCard entry.
+ *
+ * @param[in] handle: connection handle retrieved from ESP_PBAC_CONNECTION_STATE_EVT
+ *
+ * @param[in] name: vCard name or, if supported, the X-BT-UID of the object to be retrieved.
+ * uses relative paths,shall not include any path information
+ *
+ * @param[in] app_param: optional application parameter
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_pbac_pull_vcard_entry(esp_pbac_conn_hdl_t handle, const char *name, esp_pbac_pull_vcard_entry_app_param_t *app_param);
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h b/lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h
index 14741e74..956af037 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_sdp_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,123 +14,173 @@
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 protocol status parameters
+ */
+typedef struct {
+ bool sdp_inited; /*!< SDP initialization */
+ uint8_t records_num; /*!< Number of created records */
+} esp_sdp_protocol_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 */
-
- // 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_types_t type; /*!< SDP type */
+ esp_bt_uuid_t uuid; /*!< UUID type, include uuid and uuid length, only needed to be set for RAW record creation */
+ uint32_t service_name_length; /*!< Service name length */
+ char *service_name; /*!< Service name */
+ int32_t rfcomm_channel_number; /*!< RFCOMM channel number, if not used set to -1*/
+ int32_t l2cap_psm; /*!< L2CAP psm, if not used set to -1 */
+ int32_t profile_version; /*!< Profile version */
+ int user1_ptr_len; /*!< User data1 length, only used for searching RAW record */
+ uint8_t *user1_ptr; /*!< User data1 pointer to the raw SDP response data, only used for searching RAW record */
+ int user2_ptr_len __attribute__((deprecated)); /*!< User data2 length, only used for searching RAW record */
+ uint8_t *user2_ptr __attribute__((deprecated)); /*!< User data2 pointer, only used for searching RAW record */
} esp_bluetooth_sdp_hdr_overlay_t;
/**
+ * @brief Raw SDP record
+ */
+typedef struct bluetooth_sdp_raw_record {
+ esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
+} esp_bluetooth_sdp_raw_record_t;
+
+/**
* @brief Message Access Profile - Server parameters
*/
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 */
+ 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 */
} 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 */
+ esp_bluetooth_sdp_hdr_overlay_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 */
+ esp_bluetooth_sdp_hdr_overlay_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 */
+ esp_bluetooth_sdp_hdr_overlay_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 */
+ 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 */
} 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 */
+ esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
} esp_bluetooth_sdp_sap_record_t;
/**
+ * @brief Vendor ID source
+ */
+typedef enum {
+ ESP_SDP_VENDOR_ID_SRC_BT = 1, /*!< Bluetooth assigned vendor id source */
+ ESP_SDP_VENDOR_ID_SRC_USB = 2, /*!< USB assigned vendor id source */
+} esp_sdp_vendor_id_source_t;
+
+/**
+ * @brief Device Identification Profile parameters
+ *
+ * @note Only one primary Device Identification service record can be added in the SDP database. If primary
+ * Device Identification service is created multiple times, only the last one will take effect.
+ */
+typedef struct bluetooth_sdp_dip_record {
+ esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
+ uint16_t vendor; /*!< Vendor ID */
+ uint16_t vendor_id_source; /*!< Vendor ID source, 0x0001 for Bluetooth, 0x0002 for USB, other values reserved, see `esp_sdp_vendor_id_source_t` */
+ uint16_t product; /*!< Product ID */
+ uint16_t version; /*!< Release version in format 0xJJMN(JJ – major number, M – minor number, N – sub-minor number) */
+ bool primary_record; /*!< Indicate if the record is primary, shall set to true if there is a only single device
+ record, others shall be set to false */
+} esp_bluetooth_sdp_dip_record_t;
+
+/**
* @brief SDP record parameters union
*/
typedef union {
- esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */
- esp_bluetooth_sdp_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_overlay_t hdr; /*!< General info */
+ esp_bluetooth_sdp_raw_record_t raw; /*!< Raw SDP search data for unknown UUIDs */
+ esp_bluetooth_sdp_mas_record_t mas; /*!< Message Access Profile - Server */
+ esp_bluetooth_sdp_mns_record_t mns; /*!< Message Access Profile - Client (Notification Server) */
+ esp_bluetooth_sdp_pse_record_t pse; /*!< Phone Book Profile - Server */
+ esp_bluetooth_sdp_pce_record_t pce; /*!< Phone Book Profile - Client */
+ esp_bluetooth_sdp_ops_record_t ops; /*!< Object Push Profile */
+ esp_bluetooth_sdp_sap_record_t sap; /*!< SIM Access Profile */
+ esp_bluetooth_sdp_dip_record_t dip; /*!< Device Identification Profile */
} esp_bluetooth_sdp_record_t;
/**
@@ -141,44 +191,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 */
+ struct sdp_create_record_evt_param {
+ esp_sdp_status_t status; /*!< Status */
+ int record_handle; /*!< SDP record handle */
+ } create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */
/**
* @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.
@@ -264,6 +313,17 @@ esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record);
*/
esp_err_t esp_sdp_remove_record(int record_handle);
+/**
+ * @brief This function is used to get the status of SDP
+ *
+ * @param[out] status - sdp status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_sdp_get_protocol_status(esp_sdp_protocol_status_t *status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/api/include/api/esp_spp_api.h b/lib/bt/host/bluedroid/api/include/api/esp_spp_api.h
index d2a0e090..40788667 100644
--- a/lib/bt/host/bluedroid/api/include/api/esp_spp_api.h
+++ b/lib/bt/host/bluedroid/api/include/api/esp_spp_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -102,6 +102,13 @@ typedef enum {
ESP_SPP_VFS_UNREGISTER_EVT = 37, /*!< When SPP VFS unregister, the event comes */
} esp_spp_cb_event_t;
+/**
+ * @brief SPP profile status parameters
+ */
+typedef struct {
+ bool spp_inited; /*!< spp initialization */
+ uint8_t conn_num; /*!< Number of connections */
+} esp_spp_profile_status_t;
/**
* @brief SPP callback parameters union
@@ -432,6 +439,17 @@ esp_err_t esp_spp_vfs_register(void);
*/
esp_err_t esp_spp_vfs_unregister(void);
+/**
+ * @brief This function is used to get the status of SPP
+ *
+ * @param[out] profile_status - SPP status
+ *
+ * @return
+ * - ESP_OK: success
+ * - other: failed
+ */
+esp_err_t esp_spp_get_profile_status(esp_spp_profile_status_t *profile_status);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/bta/av/bta_av_aact.c b/lib/bt/host/bluedroid/bta/av/bta_av_aact.c
index 26a23958..e75fe818 100644
--- a/lib/bt/host/bluedroid/bta/av/bta_av_aact.c
+++ b/lib/bt/host/bluedroid/bta/av/bta_av_aact.c
@@ -57,7 +57,7 @@
#define BTA_AV_CLOSE_REQ_TIME_VAL 4000
#endif
-/* number to retry on reconfigure failure - some headsets requirs this number to be more than 1 */
+/* number to retry on reconfigure failure - some headsets requires this number to be more than 1 */
#ifndef BTA_AV_RECONFIG_RETRY
#define BTA_AV_RECONFIG_RETRY 6
#endif
@@ -239,7 +239,7 @@ static UINT8 bta_av_get_scb_handle(tBTA_AV_SCB *p_scb, UINT8 local_sep)
return (p_scb->seps[xx].av_handle);
}
}
- APPL_TRACE_DEBUG(" bta_av_get_scb_handle appropiate sep_type not found")
+ APPL_TRACE_DEBUG(" bta_av_get_scb_handle appropriate sep_type not found")
return 0; /* return invalid handle */
}
@@ -260,7 +260,7 @@ static UINT8 bta_av_get_scb_sep_type(tBTA_AV_SCB *p_scb, UINT8 tavdt_handle)
return (p_scb->seps[xx].tsep);
}
}
- APPL_TRACE_DEBUG(" bta_av_get_scb_sep_type appropiate handle not found")
+ APPL_TRACE_DEBUG(" bta_av_get_scb_sep_type appropriate handle not found")
return 3; /* return invalid sep type */
}
@@ -586,9 +586,18 @@ void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UI
osi_free(p_pkt);
return;
}
+
+ if (p_pkt->offset >= 4) {
+ /* The offset of avdt packet will always greater than 4, it is safe to add timestamp here */
+ *((UINT32 *) (p_pkt + 1)) = time_stamp;
+ }
+ else {
+ APPL_TRACE_WARNING("bta_av_stream_data_cback avdt packet offset small than 4");
+ }
+
p_pkt->event = BTA_AV_MEDIA_DATA_EVT;
p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_DATA_EVT, (tBTA_AV_MEDIA *)p_pkt);
- osi_free(p_pkt); /* a copy of packet had been delivered, we free this buffer */
+ /* packet will be free by upper */
}
/*******************************************************************************
@@ -843,7 +852,7 @@ void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
bdcpy(av_open.bd_addr, p_scb->peer_addr);
av_open.chnl = p_scb->chnl;
av_open.hndl = p_scb->hndl;
- start.status = BTA_AV_FAIL_ROLE;
+ av_open.status = BTA_AV_FAIL_ROLE;
if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC ) {
av_open.sep = AVDT_TSEP_SNK;
} else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK ) {
@@ -1138,7 +1147,7 @@ void bta_av_config_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_info->media_type = p_scb->media_type;
p_info->seid = p_data->str_msg.msg.config_ind.int_seid;
- /* Sep type of Peer will be oppsite role to our local sep */
+ /* Sep type of Peer will be opposite role to our local sep */
if (local_sep == AVDT_TSEP_SRC) {
p_info->tsep = AVDT_TSEP_SNK;
} else if (local_sep == AVDT_TSEP_SNK) {
@@ -1271,7 +1280,7 @@ void bta_av_setconfig_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
if (AVDT_TSEP_SNK == local_sep) {
if ((p_data->ci_setconfig.err_code == AVDT_SUCCESS) &&
(p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL)) {
- p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT,
+ p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_CFG_EVT,
(tBTA_AV_MEDIA *)p_scb->cfg.codec_info);
}
if (p_scb->cur_psc_mask & AVDT_PSC_DELAY_RPT) {
@@ -1384,7 +1393,7 @@ void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
{
/* TODO check if other audio channel is open.
* If yes, check if reconfig is needed
- * Rigt now we do not do this kind of checking.
+ * Right now we do not do this kind of checking.
* BTA-AV is INT for 2nd audio connection.
* The application needs to make sure the current codec_info is proper.
* If one audio connection is open and another SNK attempts to connect to AV,
@@ -1397,6 +1406,7 @@ void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
open.status = BTA_AV_SUCCESS;
open.starting = bta_av_chk_start(p_scb);
open.edr = 0;
+ open.mtu = mtu;
if ( NULL != (p = BTM_ReadRemoteFeatures(p_scb->peer_addr))) {
if (HCI_EDR_ACL_2MPS_SUPPORTED(p)) {
open.edr |= BTA_AV_EDR_2MBPS;
@@ -1533,7 +1543,7 @@ void bta_av_do_close (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
AVDT_CloseReq(p_scb->avdt_handle);
- /* just in case that the link is congested, link is flow controled by peer or
+ /* just in case that the link is congested, link is flow controlled by peer or
* for whatever reason the the close request can not be sent in time.
* when this timer expires, AVDT_DisconnectReq will be called to disconnect the link
*/
@@ -1814,7 +1824,7 @@ void bta_av_open_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
}
- /* if there is already an active AV connnection with the same bd_addr,
+ /* if there is already an active AV connection with the same bd_addr,
don't send disconnect req, just report the open event with BTA_AV_FAIL_GET_CAP status */
if (is_av_opened == TRUE) {
bdcpy(open.bd_addr, p_scb->peer_addr);
@@ -1856,7 +1866,7 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
tAVDT_CFG cfg;
UINT8 media_type;
tAVDT_SEP_INFO *p_info = &p_scb->sep_info[p_scb->sep_info_idx];
- UINT16 uuid_int; /* UUID for which connection was initiatied */
+ UINT16 uuid_int; /* UUID for which connection was initiated */
tBTA_AV_SNK_PSC_CFG psc_cfg = {0};
memcpy(&cfg, &p_scb->cfg, sizeof(tAVDT_CFG));
@@ -1899,9 +1909,9 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_scb->cur_psc_mask = cfg.psc_mask;
if (uuid_int == UUID_SERVCLASS_AUDIO_SINK) {
- if (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL) {
+ if (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL) {
APPL_TRACE_DEBUG(" Configure Deoder for Sink Connection ");
- p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT,
+ p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_CFG_EVT,
(tBTA_AV_MEDIA *)p_scb->cfg.codec_info);
}
if (p_scb->cur_psc_mask & AVDT_PSC_DELAY_RPT) {
@@ -1909,6 +1919,13 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
}
(*bta_av_cb.p_cback)(BTA_AV_SNK_PSC_CFG_EVT, (tBTA_AV *)&psc_cfg);
}
+ else {
+ /* UUID_SERVCLASS_AUDIO_SOURCE */
+ if (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL) {
+ p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_CFG_EVT,
+ (tBTA_AV_MEDIA *)p_scb->cfg.codec_info);
+ }
+ }
/* open the stream */
AVDT_OpenReq(p_scb->seps[p_scb->sep_idx].av_handle, p_scb->peer_addr,
@@ -2387,7 +2404,7 @@ void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
{
/* If sink starts stream, disable sniff mode here */
if (!initiator) {
- /* If souce is the master role, disable role switch during streaming.
+ /* If source is the master role, disable role switch during streaming.
* Otherwise allow role switch, if source is slave.
* Because it would not hurt source, if the peer device wants source to be master */
if ((BTM_GetRole (p_scb->peer_addr, &cur_role) == BTM_SUCCESS) &&
@@ -2502,7 +2519,7 @@ void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
bta_av_str_stopped(p_scb, NULL);
}
- /* Update common mtu shared by remaining connectons */
+ /* Update common mtu shared by remaining connections */
mtu = bta_av_chk_mtu(p_scb, BTA_AV_MAX_A2DP_MTU);
{
diff --git a/lib/bt/host/bluedroid/bta/av/bta_av_act.c b/lib/bt/host/bluedroid/bta/av/bta_av_act.c
index 13a57507..1fd59a04 100644
--- a/lib/bt/host/bluedroid/bta/av/bta_av_act.c
+++ b/lib/bt/host/bluedroid/bta/av/bta_av_act.c
@@ -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;
diff --git a/lib/bt/host/bluedroid/bta/av/bta_av_api.c b/lib/bt/host/bluedroid/bta/av/bta_av_api.c
index 01993eec..f62d9efe 100644
--- a/lib/bt/host/bluedroid/bta/av/bta_av_api.c
+++ b/lib/bt/host/bluedroid/bta/av/bta_av_api.c
@@ -129,6 +129,23 @@ void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id,
}
}
+void BTA_AvRegSEP(tBTA_AV_CHNL chnl, UINT8 seid, UINT8 tsep, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, tBTA_AV_DATA_CBACK *p_data_cback)
+{
+ tBTA_AV_API_REG_SEP *p_buf;
+
+ if ((p_buf = (tBTA_AV_API_REG_SEP *) osi_malloc(sizeof(tBTA_AV_API_REG_SEP))) != NULL) {
+ p_buf->hdr.layer_specific = chnl;
+ p_buf->hdr.event = BTA_AV_API_REG_SEP_EVT;
+
+ p_buf->seid = seid;
+ p_buf->tsep = tsep;
+ p_buf->codec_type = codec_type;
+ memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
+ p_buf->p_data_cback = p_data_cback;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
/*******************************************************************************
**
** Function BTA_AvDeregister
@@ -613,4 +630,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 */
diff --git a/lib/bt/host/bluedroid/bta/av/bta_av_ca_act.c b/lib/bt/host/bluedroid/bta/av/bta_av_ca_act.c
new file mode 100644
index 00000000..d886f593
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/av/bta_av_ca_act.c
@@ -0,0 +1,496 @@
+/*
+ * 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);
+ osi_free(p_data->api_ca_get.image_descriptor);
+ }
+ /* 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 */
diff --git a/lib/bt/host/bluedroid/bta/av/bta_av_ca_sm.c b/lib/bt/host/bluedroid/bta/av/bta_av_ca_sm.c
new file mode 100644
index 00000000..4a9d4e7c
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/av/bta_av_ca_sm.c
@@ -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 */
diff --git a/lib/bt/host/bluedroid/bta/av/bta_av_main.c b/lib/bt/host/bluedroid/bta/av/bta_av_main.c
index 2fde06f6..7ccd3423 100644
--- a/lib/bt/host/bluedroid/bta/av/bta_av_main.c
+++ b/lib/bt/host/bluedroid/bta/av/bta_av_main.c
@@ -151,6 +151,7 @@ static const tBTA_AV_ST_TBL bta_av_st_tbl[] = {
typedef void (*tBTA_AV_NSM_ACT)(tBTA_AV_DATA *p_data);
static void bta_av_api_enable(tBTA_AV_DATA *p_data);
static void bta_av_api_register(tBTA_AV_DATA *p_data);
+static void bta_av_api_reg_sep(tBTA_AV_DATA *p_data);
#if (BTA_AV_SINK_INCLUDED == TRUE)
static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data);
static void bta_av_api_get_delay_value(tBTA_AV_DATA *p_data);
@@ -170,6 +171,7 @@ static void bta_av_sys_rs_cback (tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 ap
const tBTA_AV_NSM_ACT bta_av_nsm_act[] = {
bta_av_api_enable, /* BTA_AV_API_ENABLE_EVT */
bta_av_api_register, /* BTA_AV_API_REGISTER_EVT */
+ bta_av_api_reg_sep, /* BTA_AV_API_REG_SEP_EVT */
bta_av_api_deregister, /* BTA_AV_API_DEREGISTER_EVT */
bta_av_api_disconnect, /* BTA_AV_API_DISCONNECT_EVT */
bta_av_ci_data, /* BTA_AV_CI_SRC_DATA_READY_EVT */
@@ -461,7 +463,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
**
@@ -533,9 +535,11 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
tAVDT_REG reg;
tAVDT_CS cs;
char *p_service_name;
- tBTA_AV_CODEC codec_type;
tBTA_UTL_COD cod;
+#if (BTA_AV_EXT_CODEC == FALSE)
+ tBTA_AV_CODEC codec_type;
UINT8 index = 0;
+#endif
char p_avk_service_name[BTA_SERVICE_NAME_LEN + 1];
BCM_STRNCPY_S(p_avk_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
p_avk_service_name[BTA_SERVICE_NAME_LEN] = '\0';
@@ -593,7 +597,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;
@@ -658,6 +662,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
/* keep the configuration in the stream control block */
memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG));
+#if (BTA_AV_EXT_CODEC == FALSE)
while (index < BTA_AV_MAX_SEPS &&
(p_scb->p_cos->init)(&codec_type, cs.cfg.codec_info,
&cs.cfg.num_protect, cs.cfg.protect_info, p_data->api_reg.tsep) == TRUE) {
@@ -673,12 +678,13 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
#if (BTA_AV_SINK_INCLUDED == TRUE)
p_scb->seps[index].tsep = cs.tsep;
- if (cs.tsep == AVDT_TSEP_SNK) {
- p_scb->seps[index].p_app_data_cback = p_data->api_reg.p_app_data_cback;
- } else {
- p_scb->seps[index].p_app_data_cback = NULL; /* In case of A2DP SOURCE we don't need a callback to handle media packets */
- }
+ // if (cs.tsep == AVDT_TSEP_SNK) {
+ // p_scb->seps[index].p_app_data_cback = p_data->api_reg.p_app_data_cback;
+ // } else {
+ // p_scb->seps[index].p_app_data_cback = NULL; /* In case of A2DP SOURCE we don't need a callback to handle media packets */
+ // }
#endif
+ p_scb->seps[index].p_app_data_cback = p_data->api_reg.p_app_data_cback;
APPL_TRACE_DEBUG("audio[%d] av_handle: %d codec_type: %d\n",
index, p_scb->seps[index].av_handle, p_scb->seps[index].codec_type);
@@ -687,6 +693,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
break;
}
}
+#endif
if (!bta_av_cb.reg_audio) {
if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
@@ -744,6 +751,86 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
(*bta_av_cb.p_cback)(BTA_AV_REGISTER_EVT, (tBTA_AV *)&registr);
}
+static void bta_av_api_reg_sep(tBTA_AV_DATA *p_data)
+{
+ UNUSED(p_data);
+#if (BTA_AV_EXT_CODEC == TRUE)
+ tAVDT_CS cs;
+ tBTA_AV_CODEC codec_type;
+ UINT8 index = p_data->api_reg_sep.seid;
+ tBTA_AV_SEP_REG sep_reg;
+
+ sep_reg.seid = p_data->api_reg_sep.seid;
+ sep_reg.reg_state = BTA_AV_FAIL;
+
+ if (index > BTA_AV_MAX_SEPS || p_data->hdr.layer_specific != BTA_AV_CHNL_AUDIO) {
+ (*bta_av_cb.p_cback)(BTA_AV_SEP_REG_EVT, (tBTA_AV *)&sep_reg);
+ APPL_TRACE_WARNING("%s invalid parameter: seid %d, ch %d", __FUNCTION__, index, p_data->hdr.layer_specific);
+ return;
+ }
+
+ memset(&cs, 0, sizeof(tAVDT_CS));
+ cs.cfg.num_codec = 1;
+ cs.tsep = p_data->api_reg_sep.tsep;
+ cs.nsc_mask = AVDT_NSC_RECONFIG | ((bta_av_cb.features & BTA_AV_FEAT_PROTECT) ? 0 : AVDT_NSC_SECURITY);
+
+ for (int xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
+ if (bta_av_cb.p_scb[xx] != NULL && bta_av_cb.p_scb[xx]->chnl == BTA_AV_CHNL_AUDIO) {
+ tBTA_AV_SCB *p_scb = bta_av_cb.p_scb[xx];
+ cs.p_ctrl_cback = bta_av_dt_cback[p_scb->hdi];
+ cs.cfg.psc_mask = AVDT_PSC_TRANS;
+ cs.media_type = AVDT_MEDIA_AUDIO;
+ cs.mtu = p_bta_av_cfg->audio_mtu;
+ cs.flush_to = L2CAP_DEFAULT_FLUSH_TO;
+
+#if AVDT_REPORTING == TRUE
+ if (bta_av_cb.features & BTA_AV_FEAT_REPORT) {
+ cs.cfg.psc_mask |= AVDT_PSC_REPORT;
+ cs.p_report_cback = bta_av_a2dp_report_cback;
+#if AVDT_MULTIPLEXING == TRUE
+ cs.cfg.mux_tsid_report = 2;
+#endif
+ }
+#endif
+ if (bta_av_cb.features & BTA_AV_FEAT_DELAY_RPT) {
+ cs.cfg.psc_mask |= AVDT_PSC_DELAY_RPT;
+ }
+ /* todo: check whether this memcpy is necessary */
+ memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG));
+
+ codec_type = p_data->api_reg_sep.codec_type;
+ memcpy(cs.cfg.codec_info, p_data->api_reg_sep.codec_info, AVDT_CODEC_SIZE);
+ if ((p_scb->p_cos->init)(&codec_type, cs.cfg.codec_info,
+ &cs.cfg.num_protect, cs.cfg.protect_info, p_data->api_reg_sep.tsep) == TRUE) {
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+ if (p_data->api_reg_sep.tsep == AVDT_TSEP_SNK) {
+ cs.p_data_cback = bta_av_stream_data_cback;
+ }
+#endif
+ if ((p_scb->seps[index].av_handle != 0) && (AVDT_RemoveStream(p_scb->seps[index].av_handle) != AVDT_SUCCESS)) {
+ APPL_TRACE_WARNING("%s fail to remove exist sep", __FUNCTION__);
+ }
+ if (AVDT_CreateStream(&p_scb->seps[index].av_handle, &cs) == AVDT_SUCCESS) {
+ p_scb->seps[index].codec_type = codec_type;
+ p_scb->seps[index].tsep = cs.tsep;
+ p_scb->seps[index].p_app_data_cback = p_data->api_reg_sep.p_data_cback;
+ } else {
+ APPL_TRACE_WARNING("%s fail to create sep", __FUNCTION__);
+ break;
+ }
+ }
+ else {
+ APPL_TRACE_WARNING("%s invalid codec capability", __FUNCTION__);
+ }
+ }
+ }
+
+ sep_reg.reg_state = BTA_AV_SUCCESS;
+ (*bta_av_cb.p_cback)(BTA_AV_SEP_REG_EVT, (tBTA_AV *)&sep_reg);
+#endif
+}
+
/*******************************************************************************
**
** Function bta_av_api_deregister
@@ -1248,6 +1335,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);
@@ -1408,7 +1502,8 @@ char *bta_av_action_code(UINT16 action_code)
case 46: return "BTA_AV_DELAY_CO";
case 47: return "BTA_AV_OPEN_AT_INC";
case 48: return "BTA_AV_OPEN_FAIL_SDP";
- case 49: return "NULL";
+ case 49: return "BTA_AV_SET_DELAY_VALUE";
+ case 50: return "NULL";
default: return "unknown";
}
}
diff --git a/lib/bt/host/bluedroid/bta/av/bta_av_sbc.c b/lib/bt/host/bluedroid/bta/av/bta_av_sbc.c
index 4e034c42..3fd3d94b 100644
--- a/lib/bt/host/bluedroid/bta/av/bta_av_sbc.c
+++ b/lib/bt/host/bluedroid/bta/av/bta_av_sbc.c
@@ -583,6 +583,64 @@ UINT8 bta_av_sbc_cfg_in_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
/*******************************************************************************
**
+** Function bta_av_sbc_cfg_in_external_codec_cap
+**
+** Description This function checks whether an SBC codec configuration
+** is allowable for the given external codec capabilities.
+**
+** Returns 0 if ok, nonzero if error.
+**
+*******************************************************************************/
+UINT8 bta_av_sbc_cfg_in_external_codec_cap(UINT8 *p_cfg, UINT8 *p_cap)
+{
+ UINT8 status = 0;
+ tA2D_SBC_CIE cfg_cie;
+ tA2D_SBC_CIE cap_cie;
+
+ /* parse configuration */
+ if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, FALSE)) != 0) {
+ return status;
+ }
+ /* parse capability */
+ if ((status = A2D_ParsSbcInfo(&cap_cie, p_cap, TRUE)) != 0) {
+ return status;
+ }
+
+ /* verify that each parameter is in range */
+
+ /* sampling frequency */
+ if ((cfg_cie.samp_freq & cap_cie.samp_freq) == 0) {
+ status = A2D_NS_SAMP_FREQ;
+ }
+ /* channel mode */
+ else if ((cfg_cie.ch_mode & cap_cie.ch_mode) == 0) {
+ status = A2D_NS_CH_MODE;
+ }
+ /* block length */
+ else if ((cfg_cie.block_len & cap_cie.block_len) == 0) {
+ status = A2D_BAD_BLOCK_LEN;
+ }
+ /* subbands */
+ else if ((cfg_cie.num_subbands & cap_cie.num_subbands) == 0) {
+ status = A2D_NS_SUBBANDS;
+ }
+ /* allocation method */
+ else if ((cfg_cie.alloc_mthd & cap_cie.alloc_mthd) == 0) {
+ status = A2D_NS_ALLOC_MTHD;
+ }
+ /* max bitpool */
+ else if (cfg_cie.max_bitpool > cap_cie.max_bitpool) {
+ status = A2D_NS_MAX_BITPOOL;
+ }
+ /* min bitpool */
+ else if (cfg_cie.min_bitpool < cap_cie.min_bitpool) {
+ status = A2D_NS_MIN_BITPOOL;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
** Function bta_av_sbc_bld_hdr
**
** Description This function builds the packet header for MPF1.
diff --git a/lib/bt/host/bluedroid/bta/av/include/bta_av_int.h b/lib/bt/host/bluedroid/bta/av/include/bta_av_int.h
index 8c255456..9d8e6dfd 100644
--- a/lib/bt/host/bluedroid/bta/av/include/bta_av_int.h
+++ b/lib/bt/host/bluedroid/bta/av/include/bta_av_int.h
@@ -85,10 +85,20 @@ 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,
+ BTA_AV_API_REG_SEP_EVT,
BTA_AV_API_DEREGISTER_EVT,
BTA_AV_API_DISCONNECT_EVT,
BTA_AV_CI_SRC_DATA_READY_EVT,
@@ -115,6 +125,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
@@ -180,6 +196,15 @@ typedef struct {
tBTA_AVRC_CO_FUNCTS *bta_avrc_cos;
} tBTA_AV_API_REG;
+/* data type for BTA_AV_API_REG_SEP_EVT */
+typedef struct {
+ BT_HDR hdr;
+ UINT8 seid;
+ UINT8 tsep;
+ tBTA_AV_CODEC codec_type;
+ UINT8 codec_info[AVDT_CODEC_SIZE];
+ tBTA_AV_DATA_CBACK *p_data_cback;
+} tBTA_AV_API_REG_SEP;
enum {
BTA_AV_RS_NONE, /* straight API call */
@@ -348,6 +373,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 */
@@ -364,6 +435,7 @@ typedef union {
BT_HDR hdr;
tBTA_AV_API_ENABLE api_enable;
tBTA_AV_API_REG api_reg;
+ tBTA_AV_API_REG_SEP api_reg_sep;
tBTA_AV_API_OPEN api_open;
tBTA_AV_API_STOP api_stop;
tBTA_AV_API_DISCNT api_discnt;
@@ -382,6 +454,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 +485,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 +542,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 +551,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 +561,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 +578,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 +800,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 */
diff --git a/lib/bt/host/bluedroid/bta/dm/bta_dm_act.c b/lib/bt/host/bluedroid/bta/dm/bta_dm_act.c
index ba5e8f02..3ec7ae2a 100644
--- a/lib/bt/host/bluedroid/bta/dm/bta_dm_act.c
+++ b/lib/bt/host/bluedroid/bta/dm/bta_dm_act.c
@@ -616,8 +616,10 @@ void bta_dm_disable (tBTA_DM_MSG *p_data)
#endif
#if BLE_INCLUDED == TRUE
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
// btm_ble_multi_adv_init is called when the host is enabled, so btm_ble_multi_adv_cleanup is called when the host is disabled.
btm_ble_multi_adv_cleanup();
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
#endif
}
@@ -731,6 +733,7 @@ void bta_dm_cfg_coex_status (tBTA_DM_MSG *p_data)
}
#endif
+#if (BLE_VENDOR_HCI_EN == TRUE)
void bta_dm_send_vendor_hci(tBTA_DM_MSG *p_data)
{
BTM_VendorSpecificCommand(p_data->vendor_hci_cmd.opcode,
@@ -739,6 +742,28 @@ void bta_dm_send_vendor_hci(tBTA_DM_MSG *p_data)
p_data->vendor_hci_cmd.vendor_hci_cb);
}
+void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data)
+{
+ if (BTM_BleClearAdv(p_data->ble_clear_adv.p_clear_adv_cback) == FALSE) {
+ if (p_data->ble_clear_adv.p_clear_adv_cback) {
+ (*p_data->ble_clear_adv.p_clear_adv_cback)(BTA_FAILURE);
+ }
+ }
+}
+
+void bta_dm_ble_gap_set_csa_support(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s, csa_select = %d", __func__, p_data->ble_set_csa_support.csa_select);
+ BTM_BleSetCsaSupport(p_data->ble_set_csa_support.csa_select, p_data->ble_set_csa_support.p_cback);
+}
+
+void bta_dm_ble_gap_set_vendor_evt_mask(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s, evt_mask = %d", __func__, p_data->ble_set_vendor_evt_mask.evt_mask);
+ BTM_BleSetVendorEventMask(p_data->ble_set_vendor_evt_mask.evt_mask, p_data->ble_set_vendor_evt_mask.p_cback);
+}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+
/*******************************************************************************
**
** Function bta_dm_set_afh_channels
@@ -970,7 +995,7 @@ void bta_dm_clear_white_list(tBTA_DM_MSG *p_data)
BTM_BleClearWhitelist(p_data->white_list.update_wl_cb);
#endif
}
-
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data)
{
#if (BLE_INCLUDED == TRUE)
@@ -981,6 +1006,7 @@ void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data)
}
#endif ///BLE_INCLUDED == TRUE
}
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
void bta_dm_read_rssi(tBTA_DM_MSG *p_data)
{
@@ -991,6 +1017,7 @@ void bta_dm_read_rssi(tBTA_DM_MSG *p_data)
}
}
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function bta_dm_set_visibility
@@ -1080,6 +1107,7 @@ void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
}
}
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -1211,6 +1239,7 @@ void bta_dm_add_device (tBTA_DM_MSG *p_data)
}
}
+#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_close_acl
@@ -1256,7 +1285,9 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data)
/* otherwise, no action needed */
}
+#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
+#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_remove_all_acl
@@ -1285,7 +1316,7 @@ void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data)
}
}
}
-
+#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
/*******************************************************************************
**
@@ -2385,7 +2416,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 +2442,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
@@ -4589,6 +4630,7 @@ void bta_dm_eir_update_uuid(tBT_UUID uuid, BOOLEAN adding)
}
#endif
+#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_enable_test_mode
@@ -4620,7 +4662,9 @@ void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
UNUSED(p_data);
BTM_DeviceReset(NULL);
}
+#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
+#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_execute_callback
@@ -4640,6 +4684,7 @@ void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
}
+#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
/*******************************************************************************
**
@@ -4962,7 +5007,9 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
if (p_data->complt.reason != 0) {
sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
/* delete this device entry from Sec Dev DB */
- bta_dm_remove_sec_dev_entry (bda);
+ APPL_TRACE_WARNING("%s remove bond,rsn %d, BDA:0x%02X%02X%02X%02X%02X%02X", __func__, sec_event.auth_cmpl.fail_reason,
+ bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+ bta_dm_remove_sec_dev_entry(bda);
} else {
sec_event.auth_cmpl.success = TRUE;
if (!p_data->complt.smp_over_br) {
@@ -5162,6 +5209,7 @@ void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
p_data->ble_set_conn_params.slave_latency, p_data->ble_set_conn_params.supervision_tout);
}
+#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_set_conn_scan_params
@@ -5179,7 +5227,9 @@ void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
p_data->ble_set_scan_params.scan_mode,
p_data->ble_set_scan_params.scan_param_setup_cback);
}
+#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_set_scan_fil_params
@@ -5211,8 +5261,9 @@ void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data)
}
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
-
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_set_conn_scan_params
@@ -5227,6 +5278,8 @@ void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
p_data->ble_set_conn_scan_params.scan_window);
}
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
+
/*******************************************************************************
**
** Function bta_dm_ble_update_conn_params
@@ -5293,6 +5346,7 @@ void bta_dm_ble_clear_rand_address(tBTA_DM_MSG *p_data)
BTM_BleClearRandAddress();
}
+#if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_stop_advertising
@@ -5307,10 +5361,11 @@ void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) {
APPL_TRACE_ERROR("Invalid BTA event,can't stop the BLE adverting\n");
}
-
+#if (BLE_42_ADV_EN == TRUE)
btm_ble_stop_adv();
+#endif // #if (BLE_42_ADV_EN == TRUE)
}
-
+#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
#if BLE_PRIVACY_SPT == TRUE
@@ -5342,6 +5397,7 @@ void bta_dm_ble_config_local_icon (tBTA_DM_MSG *p_data)
BTM_BleConfigLocalIcon (p_data->ble_local_icon.icon);
}
+#if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_observe
@@ -5381,6 +5437,7 @@ void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
}
}
}
+#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
/*******************************************************************************
**
@@ -5419,26 +5476,14 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
p_data->ble_scan.p_stop_scan_cback(status);
}
- }
-}
-/*******************************************************************************
-**
-** Function bta_dm_ble_set_adv_params
-**
-** Description This function set the adv parameters.
-**
-** Parameters:
-**
-*******************************************************************************/
-void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
-{
- BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
- p_data->ble_set_adv_params.adv_int_max,
- p_data->ble_set_adv_params.p_dir_bda,
- BTA_DM_BLE_ADV_CHNL_MAP);
+ // reset BLE scan link state when stop scan
+ btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
+ btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
+ }
}
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_set_adv_params_all
@@ -5476,6 +5521,7 @@ void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
(*p_data->ble_set_adv_params_all.p_start_adv_cback)(status);
}
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
@@ -5493,6 +5539,7 @@ void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data)
p_data->ble_duplicate_exceptional_list.exceptional_list_cb);
}
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_set_adv_config
@@ -5518,29 +5565,6 @@ void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
/*******************************************************************************
**
-** Function bta_dm_ble_set_long_adv
-**
-** Description This function set the long ADV data
-**
-** Parameters:
-**
-*******************************************************************************/
-void bta_dm_ble_set_long_adv (tBTA_DM_MSG *p_data)
-{
- tBTA_STATUS status = BTA_FAILURE;
-
- if (BTM_BleWriteLongAdvData(p_data->ble_set_long_adv_data.adv_data,
- p_data->ble_set_long_adv_data.adv_data_len) == BTM_SUCCESS) {
- status = BTA_SUCCESS;
- }
-
- if (p_data->ble_set_adv_data.p_adv_data_cback) {
- (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
- }
-}
-
-/*******************************************************************************
-**
** Function bta_dm_ble_set_adv_config_raw
**
** Description This function set the customized ADV data configuration
@@ -5562,7 +5586,6 @@ void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data)
}
}
-
/*******************************************************************************
**
** Function bta_dm_ble_set_scan_rsp
@@ -5608,7 +5631,7 @@ void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data)
(*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
}
}
-
+#endif // #if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_set_data_length
@@ -5665,6 +5688,7 @@ void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
}
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_broadcast
@@ -5690,7 +5714,9 @@ void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
}
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_multi_adv_enb
@@ -5798,7 +5824,9 @@ void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
}
}
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
+#if (BLE_42_DTM_TEST_EN == TRUE)
void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data)
{
BTM_BleTransmitterTest(p_data->dtm_tx_start.tx_channel, p_data->dtm_tx_start.len_of_data, p_data->dtm_tx_start.pkt_payload, p_data->dtm_tx_start.p_dtm_cmpl_cback);
@@ -5808,20 +5836,14 @@ void bta_dm_ble_gap_dtm_rx_start(tBTA_DM_MSG *p_data)
{
BTM_BleReceiverTest(p_data->dtm_rx_start.rx_channel, p_data->dtm_rx_start.p_dtm_cmpl_cback);
}
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data)
{
BTM_BleTestEnd(p_data->dtm_stop.p_dtm_cmpl_cback);
}
-
-void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data)
-{
- if (BTM_BleClearAdv(p_data->ble_clear_adv.p_clear_adv_cback) == FALSE) {
- if (p_data->ble_clear_adv.p_clear_adv_cback) {
- (*p_data->ble_clear_adv.p_clear_adv_cback)(BTA_FAILURE);
- }
- }
-}
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
void bta_dm_ble_gap_set_rpa_timeout(tBTA_DM_MSG *p_data)
{
@@ -5845,7 +5867,14 @@ void bta_dm_ble_gap_set_privacy_mode(tBTA_DM_MSG *p_data)
p_data->ble_set_privacy_mode.privacy_mode, p_data->ble_set_privacy_mode.p_cback);
}
-#if (BLE_50_FEATURE_SUPPORT == TRUE)
+void bta_dm_read_ble_channel_map(tBTA_DM_MSG *p_data)
+{
+ if (p_data && p_data->ch_map.read_ch_map_cb) {
+ BTM_ReadChannelMap(p_data->ch_map.remote_addr, p_data->ch_map.read_ch_map_cb);
+ }
+}
+
+#if (BLE_50_DTM_TEST_EN == TRUE)
void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data)
{
BTM_BleEnhancedTransmitterTest(p_data->dtm_enh_tx_start.tx_channel, p_data->dtm_enh_tx_start.len_of_data,
@@ -5857,7 +5886,8 @@ void bta_dm_ble_gap_dtm_enhance_rx_start(tBTA_DM_MSG *p_data)
BTM_BleEnhancedReceiverTest(p_data->dtm_enh_rx_start.rx_channel, p_data->dtm_enh_rx_start.phy,
p_data->dtm_enh_rx_start.modulation_index, p_data->dtm_enh_rx_start.p_dtm_cmpl_cback);
}
-
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
void bta_dm_ble_gap_read_phy(tBTA_DM_MSG *p_data)
{
//tBTM_STATUS btm_status = 0;
@@ -5883,6 +5913,7 @@ void bta_dm_ble_gap_set_prefer_phy(tBTA_DM_MSG *p_data)
p_data->ble_set_per_phy.phy_options);
}
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
void bta_dm_ble_gap_ext_adv_set_rand_addr(tBTA_DM_MSG *p_data)
{
BTM_BleSetExtendedAdvRandaddr(p_data->ble_set_ext_adv_rand_addr.instance, p_data->ble_set_ext_adv_rand_addr.rand_addr);
@@ -5923,7 +5954,9 @@ void bta_dm_ble_gap_ext_adv_set_clear(tBTA_DM_MSG *p_data)
{
BTM_BleExtAdvSetClear();
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
void bta_dm_ble_gap_periodic_adv_set_params(tBTA_DM_MSG *p_data)
{
APPL_TRACE_API("%s, instance = %d", __func__, p_data->ble_set_periodic_adv_params.instance);
@@ -5950,7 +5983,9 @@ void bta_dm_ble_gap_periodic_adv_enable(tBTA_DM_MSG *p_data)
BTM_BlePeriodicAdvEnable(p_data->ble_enable_periodic_adv.instance,
p_data->ble_enable_periodic_adv.enable);
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
void bta_dm_ble_gap_periodic_adv_create_sync(tBTA_DM_MSG *p_data)
{
APPL_TRACE_API("%s", __func__);
@@ -5995,8 +6030,9 @@ void bta_dm_ble_gap_periodic_adv_clear_dev(tBTA_DM_MSG *p_data)
APPL_TRACE_API("%s", __func__);
BTM_BlePeriodicAdvClearDev();
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
-
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
void bta_dm_ble_gap_set_ext_scan_params(tBTA_DM_MSG *p_data)
{
APPL_TRACE_API("%s", __func__);
@@ -6010,14 +6046,14 @@ void bta_dm_ble_gap_ext_scan(tBTA_DM_MSG *p_data)
BTM_BleExtendedScan(p_data->ble_ext_scan.start, p_data->ble_ext_scan.duration,
p_data->ble_ext_scan.period);
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data)
{
tBTM_EXT_CONN_PARAMS conn_params;
conn_params.phy_mask = p_data->ble_set_per_ext_conn_params.phy_mask;
- APPL_TRACE_API("%s, start = %d, duration = %d, period = %d", __func__, p_data->ble_ext_scan.start, p_data->ble_ext_scan.duration,
- p_data->ble_ext_scan.period);
+ APPL_TRACE_API("%s, phy_mask %d", __func__, p_data->ble_set_per_ext_conn_params.phy_mask);
if (conn_params.phy_mask & BTA_PHY_1M_MASK) {
memcpy(&conn_params.phy_1m_conn_params, &p_data->ble_set_per_ext_conn_params.phy_1m_conn_params,
@@ -6029,7 +6065,7 @@ void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data)
sizeof(tBTA_DM_BLE_CONN_PARAMS));
}
- if (conn_params.phy_mask & BTAS_PHY_CODED_MASK) {
+ if (conn_params.phy_mask & BTA_PHY_CODED_MASK) {
memcpy(&conn_params.phy_coded_conn_params, &p_data->ble_set_per_ext_conn_params.phy_coded_conn_params,
sizeof(tBTA_DM_BLE_CONN_PARAMS));
}
@@ -6069,6 +6105,240 @@ void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data)
p_data->ble_set_past_params.params.cte_type);
}
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+void bta_dm_ble_big_create(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ tBTA_DM_BLE_BIG_CREATE_PARAMS param = p_data->big_creat.big_creat_param;
+ BTM_BleBigCreate(param.big_handle, param.adv_handle, param.num_bis,
+ param.sdu_interval, param.max_sdu, param.max_transport_latency,
+ param.rtn, param.phy, param.packing, param.framing,
+ param.encryption, &param.broadcast_code[0]);
+}
+
+void bta_dm_ble_big_create_test(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ tBTA_DM_BLE_BIG_CREATE_TEST_PARAMS param = p_data->big_creat_test.big_creat_test_param;
+ BTM_BleBigCreateTest(param.big_handle, param.adv_handle, param.num_bis,
+ param.sdu_interval, param.iso_interval, param.nse,
+ param.max_sdu, param.max_pdu, param.phy,
+ param.packing, param.framing, param.bn, param.irc,
+ param.pto, param.encryption, &param.broadcast_code[0]);
+}
+
+void bta_dm_ble_big_terminate(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ tBTA_DM_BLE_BIG_TERMINATE_PARAMS param = p_data->big_terminate.big_terminate_param;
+ BTM_BleBigTerminate(param.big_handle, param.reason);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+void bta_dm_ble_big_sync_create(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ tBTA_DM_BLE_BIG_SYNC_CREATE_PARAMS param = p_data->big_sync.big_sync_param;
+ BTM_BleBigSyncCreate(param.big_handle, param.sync_handle,
+ param.encryption, &param.bc_code[0],
+ param.mse, param.big_sync_timeout,
+ param.num_bis, &param.bis[0]);
+}
+
+void bta_dm_ble_big_sync_terminate(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ tBTA_DM_BLE_BIG_SYNC_TERMINATE_PARAMS param = p_data->big_sync_terminate.big_sync_terminate_param;
+ BTM_BleBigSyncTerminate(param.big_handle);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+void bta_dm_ble_iso_set_data_path(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ tBTA_DM_BLE_ISO_SET_DATA_PATH_PARAMS param = p_data->iso_set_data_path.iso_data_path_param;
+ BTM_BleIsoSetDataPath(param.conn_handle, param.data_path_dir, param.data_path_id, param.coding_fmt,
+ param.company_id, param.vs_codec_id, param.controller_delay, param.codec_len,
+ param.codec_cfg);
+}
+
+void bta_dm_ble_iso_remove_data_path(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ tBTA_DM_BLE_ISO_REMOVE_DATA_PATH_PARAMS param = p_data->iso_remove_data_path.iso_data_path_remove_param;
+ BTM_BleIsoRemoveDataPath(param.conn_handle, param.data_path_dir);
+}
+
+void bta_dm_ble_iso_read_tx_sync(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleIsoReadTxSync(p_data->iso_read_tx_sync.iso_hdl);
+}
+
+void bta_dm_ble_iso_read_link_quality(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleIsoReadLinkQuality(p_data->iso_read_link_quality.iso_hdl);
+}
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+void bta_dm_ble_set_cig_params(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleSetCigParams(p_data->api_cig_params.cig_id, p_data->api_cig_params.sdu_int_c_to_p, p_data->api_cig_params.sdu_int_p_to_c, p_data->api_cig_params.worse_case_SCA, p_data->api_cig_params.packing,
+ p_data->api_cig_params.framing, p_data->api_cig_params.mtl_c_to_p, p_data->api_cig_params.mtl_p_to_c, p_data->api_cig_params.cis_cnt, (uint8_t *)p_data->api_cig_params.cis_params);
+}
+
+void bta_dm_ble_set_cig_params_test(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleSetCigParamsTest(p_data->api_cig_params_test.cig_id, p_data->api_cig_params_test.sdu_int_c_to_p, p_data->api_cig_params_test.sdu_int_p_to_c,
+ p_data->api_cig_params_test.ft_c_to_p, p_data->api_cig_params_test.ft_p_to_c, p_data->api_cig_params_test.iso_interval,
+ p_data->api_cig_params_test.worse_case_SCA, p_data->api_cig_params_test.packing, p_data->api_cig_params_test.framing,
+ p_data->api_cig_params_test.cis_cnt, (uint8_t *)p_data->api_cig_params_test.cis_params_test);
+}
+
+void bta_dm_ble_create_cis(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleCreateCis(p_data->create_cis.cis_count, (uint8_t *)&p_data->create_cis.cis_hdls[0]);
+}
+
+void bta_dm_ble_remove_cig(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleRemoveCig(p_data->remove_cig.cig_id);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+void bta_dm_ble_accept_cis_req(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleAcceptCisReq(p_data->accept_cis_req.cis_handle);
+}
+
+void bta_dm_ble_reject_cis_req(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleRejectCisReq(p_data->reject_cis_req.cis_handle, p_data->reject_cis_req.reason);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+void bta_dm_ble_discon_cis(tBTA_DM_MSG *p_data)
+{
+ APPL_TRACE_API("%s", __func__);
+ BTM_BleDisconCis(p_data->discon_cis.cis_handle, p_data->discon_cis.reason);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+void bta_dm_ble_set_cte_trans_params(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSetCteTransParams(p_data->set_cte_trans_params.adv_handle, p_data->set_cte_trans_params.cte_len, p_data->set_cte_trans_params.cte_type,
+ p_data->set_cte_trans_params.cte_count, p_data->set_cte_trans_params.switching_pattern_len, p_data->set_cte_trans_params.antenna_ids);
+}
+
+void bta_dm_ble_set_cte_trans_enable(tBTA_DM_MSG *p_data)
+{
+ BTM_BleCteSetConnectionlessTransEnable(p_data->set_trans_en.adv_handle, p_data->set_trans_en.cte_enable);
+}
+
+void bta_dm_ble_set_iq_sampling_en(tBTA_DM_MSG *p_data)
+{
+ BTM_BleCteSetConnectionlessIqSamplingEnable(p_data->iq_samp_en.sync_handle, p_data->iq_samp_en.sampling_en, p_data->iq_samp_en.slot_dur,
+ p_data->iq_samp_en.max_sampled_ctes, p_data->iq_samp_en.switching_pattern_len, p_data->iq_samp_en.antenna_ids);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+void bta_dm_ble_set_conn_cte_recv_params(tBTA_DM_MSG *p_data)
+{
+ BTM_BleCteSetConnectionReceiveParams(p_data->recv_params.conn_handle, p_data->recv_params.sampling_en, p_data->recv_params.slot_dur,
+ p_data->recv_params.switching_pattern_len, p_data->recv_params.antenna_ids);
+}
+
+void bta_dm_ble_set_conn_trans_params(tBTA_DM_MSG *p_data)
+{
+ BTM_BleCteSetConnectionTransParams(p_data->conn_trans_params.conn_handle, p_data->conn_trans_params.cte_types,
+ p_data->conn_trans_params.switching_pattern_len, p_data->conn_trans_params.antenna_ids);
+}
+
+void bta_dm_ble_set_conn_cte_req_en(tBTA_DM_MSG *p_data)
+{
+ BTM_BleCteSetConnectionRequestEnable(p_data->conn_req_en.conn_handle, p_data->conn_req_en.enable, p_data->conn_req_en.cte_req_interval,
+ p_data->conn_req_en.req_cte_len, p_data->conn_req_en.req_cte_Type);
+}
+
+void bta_dm_ble_set_conn_cte_rsp_en(tBTA_DM_MSG *p_data)
+{
+ BTM_BleCteSetConnectionRspEnable(p_data->conn_rsp_en.conn_handle, p_data->conn_rsp_en.enable);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+void bta_dm_ble_read_cte_ant_infor(tBTA_DM_MSG *p_data)
+{
+ BTM_BleCteReadAntInfor();
+}
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void bta_dm_api_enh_read_trans_power_level(tBTA_DM_MSG *p_data)
+{
+ BTM_BleEnhReadTransPowerLevel(p_data->enh_read_trans_pwr_level.conn_handle, p_data->enh_read_trans_pwr_level.phy);
+}
+
+void bta_dm_api_read_rem_trans_power_level(tBTA_DM_MSG *p_data)
+{
+ BTM_BleReadRemoteTransPwrLevel(p_data->remote_trans_pwr_level.conn_handle, p_data->remote_trans_pwr_level.phy);
+}
+
+void bta_dm_api_set_path_loss_report_params(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSetPathLossRptParams(p_data->path_loss_rpt_params.conn_handle, p_data->path_loss_rpt_params.high_threshold, p_data->path_loss_rpt_params.high_hysteresis,
+ p_data->path_loss_rpt_params.low_threshold, p_data->path_loss_rpt_params.low_hysteresis, p_data->path_loss_rpt_params.min_time_spent);
+}
+
+void bta_dm_api_set_path_loss_reporting_en(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSetPathLossRptEnable(p_data->path_loss_rpt_en.conn_handle, p_data->path_loss_rpt_en.enable);
+}
+
+void bta_dm_api_set_trans_power_reporting_en(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSetTransPwrRptEnable(p_data->trans_pwr_rpt_en.conn_handle, p_data->trans_pwr_rpt_en.local_enable, p_data->trans_pwr_rpt_en.remote_enable);
+}
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void bta_dm_api_set_default_subrate(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSetDefaultSubrate(p_data->default_subrate.subrate_min, p_data->default_subrate.subrate_max, p_data->default_subrate.max_latency,
+ p_data->default_subrate.continuation_number, p_data->default_subrate.supervision_timeout);
+}
+
+void bta_dm_api_subrate_request(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSubrateRequest(p_data->subrate_request.conn_handle, p_data->subrate_request.subrate_min, p_data->subrate_request.subrate_max,
+ p_data->subrate_request.max_latency, p_data->subrate_request.continuation_number, p_data->subrate_request.supervision_timeout);
+}
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+void bta_dm_ble_set_host_feature(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSetHostFeature(p_data->set_host_feat.bit_num, p_data->set_host_feat.bit_val);
+}
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_setup_storage
@@ -6100,7 +6370,9 @@ void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
btm_status);
}
}
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_enable_batch_scan
@@ -6158,7 +6430,9 @@ void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
btm_status);
}
}
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_read_scan_reports
@@ -6185,7 +6459,9 @@ void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
btm_status);
}
}
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
** Function bta_dm_ble_track_advertiser
@@ -6218,6 +6494,7 @@ void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
}
}
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
@@ -6394,6 +6671,7 @@ void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
}
#endif
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
/*******************************************************************************
**
** Function bta_ble_enable_scan_cmpl
@@ -6441,6 +6719,7 @@ void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
}
}
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
@@ -6653,7 +6932,9 @@ void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
} else {
//TODO need to add addr_type in future
- BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, BLE_ADDR_UNKNOWN_TYPE, TRUE, BTA_GATT_TRANSPORT_LE, FALSE);
+ BTA_GATTC_Enh_Open(bta_dm_search_cb.client_if, bd_addr, BLE_ADDR_UNKNOWN_TYPE, TRUE,
+ BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, 0, NULL, NULL, NULL);
+
}
}
#endif /* #if (GATTC_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/bta/dm/bta_dm_api.c b/lib/bt/host/bluedroid/bta/dm/bta_dm_api.c
index a2282cd9..08510894 100644
--- a/lib/bt/host/bluedroid/bta/dm/bta_dm_api.c
+++ b/lib/bt/host/bluedroid/bta/dm/bta_dm_api.c
@@ -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"
@@ -109,7 +110,7 @@ tBTA_STATUS BTA_DisableBluetooth(void)
return BTA_SUCCESS;
}
-
+#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
/*******************************************************************************
**
** Function BTA_EnableTestMode
@@ -155,6 +156,7 @@ void BTA_DisableTestMode(void)
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
/*******************************************************************************
**
@@ -229,6 +231,7 @@ void BTA_DmCfgCoexStatus(UINT8 op, UINT8 type, UINT8 status)
}
#endif
+#if (BLE_VENDOR_HCI_EN == TRUE)
void BTA_DmsendVendorHciCmd(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf, tBTA_SEND_VENDOR_HCI_CMPL_CBACK p_vendor_cmd_complete_cback)
{
tBTA_DM_API_SEND_VENDOR_HCI_CMD *p_msg;
@@ -244,6 +247,57 @@ void BTA_DmsendVendorHciCmd(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf,
}
}
+/*******************************************************************************
+**
+** Function BTA_DmBleClearAdv
+**
+** Description This function is called to clear Advertising
+**
+** Parameters p_adv_data_cback : clear adv complete callback.
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_DmBleClearAdv (tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback)
+{
+ tBTA_DM_API_CLEAR_ADV *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_CLEAR_ADV *)
+ osi_malloc(sizeof(tBTA_DM_API_CLEAR_ADV))) != NULL) {
+ p_msg->hdr.event = BTA_DM_API_BLE_CLEAR_ADV_EVT;
+ p_msg->p_clear_adv_cback = p_clear_adv_cback;
+
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+void BTA_DmBleGapSetCsaSupport(uint8_t csa_select, tBTA_SET_CSA_SUPPORT_CMPL_CBACK *p_callback)
+{
+ tBTA_DM_API_BLE_SET_CSA_SUPPORT *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SET_CSA_SUPPORT *)osi_malloc(sizeof(tBTA_DM_API_BLE_SET_CSA_SUPPORT)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_BLE_SET_CSA_SUPPORT_EVT;
+ p_msg->csa_select = csa_select;
+ p_msg->p_cback = p_callback;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+void BTA_DmBleGapSetVendorEventMask(uint32_t evt_mask, tBTA_SET_VENDOR_EVT_MASK_CBACK *p_callback)
+{
+ tBTA_DM_API_BLE_SET_VENDOR_EVT_MASK *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SET_VENDOR_EVT_MASK *)osi_malloc(sizeof(tBTA_DM_API_BLE_SET_VENDOR_EVT_MASK)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_BLE_SET_VENDOR_EVT_MASK_EVT;
+ p_msg->evt_mask = evt_mask;
+ p_msg->p_cback = p_callback;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+
#if (CLASSIC_BT_INCLUDED == TRUE)
void BTA_DmConfigEir(tBTA_DM_EIR_CONF *eir_config)
@@ -486,6 +540,7 @@ void BTA_DmClearWhiteList(tBTA_UPDATE_WHITELIST_CBACK *update_wl_cb)
}
}
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb)
{
tBTA_DM_API_READ_ADV_TX_POWER *p_msg;
@@ -495,6 +550,22 @@ void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb)
bta_sys_sendmsg(p_msg);
}
}
+#endif // BLE_HOST_READ_TX_POWER_EN
+
+void BTA_DmBleReadChannelMap(BD_ADDR remote_device, tBTA_CMPL_CB *p_callback)
+{
+ if (!remote_device || !p_callback) {
+ return;
+ }
+ tBTA_DM_API_READ_CH_MAP *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_READ_CH_MAP *)osi_malloc(sizeof(tBTA_DM_API_READ_CH_MAP))) != NULL) {
+ p_msg->hdr.event = BTA_DM_API_BLE_READ_CH_MAP_EVT;
+ memcpy(p_msg->remote_addr, remote_device, sizeof(BD_ADDR));
+ p_msg->read_ch_map_cb = p_callback;
+ bta_sys_sendmsg(p_msg);
+ }
+}
#endif ///BLE_INCLUDED == TRUE
void BTA_DmReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb)
@@ -509,6 +580,7 @@ void BTA_DmReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB
}
}
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function BTA_DmSetVisibility
@@ -538,6 +610,7 @@ void BTA_DmSetVisibility(tBTA_DM_DISC disc_mode, tBTA_DM_CONN conn_mode, UINT8 p
}
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -1086,23 +1159,70 @@ 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
+
+#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
/*******************************************************************************
**
** Function bta_dmexecutecallback
@@ -1125,6 +1245,7 @@ void bta_dmexecutecallback (tBTA_DM_EXEC_CBACK *p_callback, void *p_param)
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
/*******************************************************************************
**
@@ -1335,6 +1456,7 @@ void BTA_DmSetBlePrefConnParams(BD_ADDR bd_addr,
#endif
}
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmSetBleConnScanParams
@@ -1359,7 +1481,9 @@ void BTA_DmSetBleConnScanParams(UINT32 scan_interval, UINT32 scan_window)
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
+#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
/*******************************************************************************
**
** Function BTA_DmSetBleScanParams
@@ -1393,8 +1517,9 @@ void BTA_DmSetBleScanParams(tGATT_IF client_if, UINT32 scan_interval,
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
-
+#if (BLE_42_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmSetBleScanFilterParams
@@ -1434,46 +1559,9 @@ void BTA_DmSetBleScanFilterParams(tGATT_IF client_if, UINT32 scan_interval,
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
-/*******************************************************************************
-**
-** Function BTA_DmSetBleAdvParams
-**
-** Description This function sets the advertising parameters BLE functionality.
-** It is to be called when device act in peripheral or broadcaster
-** role.
-**
-**
-** Returns void
-**
-*******************************************************************************/
-void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max,
- tBLE_BD_ADDR *p_dir_bda)
-{
-#if BLE_INCLUDED == TRUE
- tBTA_DM_API_BLE_ADV_PARAMS *p_msg;
-
- APPL_TRACE_API ("BTA_DmSetBleAdvParam: %d, %d\n", adv_int_min, adv_int_max);
-
- if ((p_msg = (tBTA_DM_API_BLE_ADV_PARAMS *) osi_malloc(sizeof(tBTA_DM_API_BLE_ADV_PARAMS)
- + sizeof(tBLE_BD_ADDR))) != NULL) {
- memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_ADV_PARAMS) + sizeof(tBLE_BD_ADDR));
-
- p_msg->hdr.event = BTA_DM_API_BLE_ADV_PARAM_EVT;
-
- p_msg->adv_int_min = adv_int_min;
- p_msg->adv_int_max = adv_int_max;
-
- if (p_dir_bda != NULL) {
- p_msg->p_dir_bda = (tBLE_BD_ADDR *)(p_msg + 1);
- memcpy(p_msg->p_dir_bda, p_dir_bda, sizeof(tBLE_BD_ADDR));
- }
-
- bta_sys_sendmsg(p_msg);
- }
-#endif
-}
-
+#if (BLE_42_ADV_EN == TRUE)
void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own,
tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol,
@@ -1507,6 +1595,8 @@ void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
}
#endif
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
+
#endif ///BLE_INCLUDED == TRUE
@@ -1515,6 +1605,7 @@ void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
********************************************************************************/
#if BLE_INCLUDED == TRUE
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleSetAdvConfig
@@ -1578,35 +1669,6 @@ void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len,
/*******************************************************************************
**
-** Function BTA_DmBleSetLongAdv
-**
-** Description This function is called to set long Advertising data
-**
-** Parameters adv_data : long advertising data.
-** adv_data_len : long advertising data length.
-** p_adv_data_cback : set long adv data complete callback.
-**
-** Returns None
-**
-*******************************************************************************/
-void BTA_DmBleSetLongAdv (UINT8 *adv_data, UINT32 adv_data_len,
- tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
-{
- tBTA_DM_API_SET_LONG_ADV *p_msg;
-
- if ((p_msg = (tBTA_DM_API_SET_LONG_ADV *)
- osi_malloc(sizeof(tBTA_DM_API_SET_LONG_ADV))) != NULL) {
- p_msg->hdr.event = BTA_DM_API_BLE_SET_LONG_ADV_EVT;
- p_msg->p_adv_data_cback = p_adv_data_cback;
- p_msg->adv_data = adv_data;
- p_msg->adv_data_len = adv_data_len;
-
- bta_sys_sendmsg(p_msg);
- }
-}
-
-/*******************************************************************************
-**
** Function BTA_DmBleSetScanRsp
**
** Description This function is called to override the BTA scan response.
@@ -1661,6 +1723,7 @@ void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len,
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
@@ -1689,7 +1752,7 @@ void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, BD_ADDR de
bta_sys_sendmsg(p_msg);
}
}
-
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleSetStorageParams
@@ -1730,7 +1793,9 @@ extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max,
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleEnableBatchScan
@@ -1789,7 +1854,9 @@ extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value)
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleReadScanReports
@@ -1815,7 +1882,9 @@ extern void BTA_DmBleReadScanReports(tBTA_BLE_BATCH_SCAN_MODE scan_type,
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleTrackAdvertiser
@@ -1841,6 +1910,7 @@ extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value,
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
#endif
@@ -1848,7 +1918,7 @@ extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value,
** BLE ADV data management API
********************************************************************************/
#if BLE_INCLUDED == TRUE
-
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleBroadcast
@@ -1878,30 +1948,8 @@ extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
-/*******************************************************************************
-**
-** Function BTA_DmBleClearAdv
-**
-** Description This function is called to clear Advertising
-**
-** Parameters p_adv_data_cback : clear adv complete callback.
-**
-** Returns None
-**
-*******************************************************************************/
-void BTA_DmBleClearAdv (tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback)
-{
- tBTA_DM_API_CLEAR_ADV *p_msg;
-
- if ((p_msg = (tBTA_DM_API_CLEAR_ADV *)
- osi_malloc(sizeof(tBTA_DM_API_CLEAR_ADV))) != NULL) {
- p_msg->hdr.event = BTA_DM_API_BLE_CLEAR_ADV_EVT;
- p_msg->p_clear_adv_cback = p_clear_adv_cback;
-
- bta_sys_sendmsg(p_msg);
- }
-}
#endif
/*******************************************************************************
**
@@ -2175,6 +2223,7 @@ void BTA_DmBleConfigLocalIcon(uint16_t icon)
}
}
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTA_BleEnableAdvInstance
@@ -2308,6 +2357,7 @@ void BTA_BleDisableAdvInstance (UINT8 inst_id) //this function just used fo
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
@@ -2490,6 +2540,7 @@ void BTA_DmBleScanFilterSetup(UINT8 action, tBTA_DM_BLE_PF_FILT_INDEX filt_index
#endif
}
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleGetEnergyInfo
@@ -2515,6 +2566,7 @@ void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback)
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
/*******************************************************************************
**
@@ -2636,6 +2688,7 @@ void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_S
}
}
+#if (BLE_42_DTM_TEST_EN == TRUE)
void BTA_DmBleDtmTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback)
{
tBTA_DM_API_BLE_DTM_TX_START *p_msg;
@@ -2665,7 +2718,9 @@ void BTA_DmBleDtmRxStart(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback)
{
tBTA_DM_API_BLE_DTM_STOP *p_msg;
@@ -2678,6 +2733,7 @@ void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback)
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
void BTA_DmBleSetPrivacyMode(uint8_t addr_type, BD_ADDR addr, uint8_t privacy_mode, tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback)
{
@@ -2740,6 +2796,7 @@ void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_DM_ENCR
}
#endif ///SMP_INCLUDED == TRUE
+#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmCloseACL
@@ -2771,8 +2828,10 @@ void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transpor
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
#if BLE_INCLUDED == TRUE
+#if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleObserve
@@ -2813,7 +2872,9 @@ extern void BTA_DmBleObserve(BOOLEAN start, UINT32 duration,
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleScan
@@ -2854,7 +2915,9 @@ extern void BTA_DmBleScan(BOOLEAN start, UINT32 duration,
bta_sys_sendmsg(p_msg);
}
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleStopAdvertising
@@ -2879,7 +2942,7 @@ extern void BTA_DmBleStopAdvertising(void)
bta_sys_sendmsg(p_msg);
}
}
-
+#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
/*******************************************************************************
**
@@ -2979,6 +3042,133 @@ void BTA_DmClearRandAddress(void)
}
}
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void BTA_DmBleGapEnhReadTransPwrLevel(uint16_t conn_handle, uint8_t phy)
+{
+ tBTA_DM_API_BLE_ENH_READ_TANS_PWR_LEVEL *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_ENH_READ_TANS_PWR_LEVEL *)osi_malloc(sizeof(tBTA_DM_API_BLE_ENH_READ_TANS_PWR_LEVEL)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_ENH_READ_TRANS_POWER_LEVEL;
+ p_msg->conn_handle = conn_handle;
+ p_msg->phy = phy;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+void BTA_DmBleGapReadRemoteTransPwrLevel(uint16_t conn_handle, uint8_t phy)
+{
+ tBTA_DM_API_BLE_READ_REMOTE_TANS_PWR_LEVEL *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_READ_REMOTE_TANS_PWR_LEVEL *)osi_malloc(sizeof(tBTA_DM_API_BLE_READ_REMOTE_TANS_PWR_LEVEL)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_READ_REM_TRANS_POWER_LEVEL;
+ p_msg->conn_handle = conn_handle;
+ p_msg->phy = phy;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+void BTA_DmBleGapSetPathLossRptParams(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis,
+ uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent)
+{
+ tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_PARAMS *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_PARAMS)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_SET_PATH_LOSS_REPORT_PARAMS;
+ p_msg->conn_handle = conn_handle;
+ p_msg->high_threshold = high_threshold;
+ p_msg->high_hysteresis = high_hysteresis;
+ p_msg->low_threshold = low_threshold;
+ p_msg->low_hysteresis = low_hysteresis;
+ p_msg->min_time_spent = min_time_spent;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+void BTA_DmBleGapSetPathLossRptEnable(uint16_t conn_handle, uint8_t enable)
+{
+ tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_ENABLE *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_ENABLE *)osi_malloc(sizeof(tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_ENABLE)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_SET_PATH_LOSS_REPORTING_EN;
+ p_msg->conn_handle = conn_handle;
+ p_msg->enable = enable;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+void BTA_DmBleGapSetTransPwrRptEnable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable)
+{
+ tBTA_DM_API_BLE_SET_TRANS_PWR_RPT_ENABLE *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SET_TRANS_PWR_RPT_ENABLE *)osi_malloc(sizeof(tBTA_DM_API_BLE_SET_TRANS_PWR_RPT_ENABLE)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_SET_TRANS_POWER_REPORTING_EN;
+ p_msg->conn_handle = conn_handle;
+ p_msg->local_enable = local_enable;
+ p_msg->remote_enable = remote_enable;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void BTA_DmBleGapSetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency, uint16_t continuation_number, uint16_t supervision_timeout)
+{
+ tBTA_DM_API_BLE_SET_DEFAULT_SUBRATE *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SET_DEFAULT_SUBRATE *)osi_malloc(sizeof(tBTA_DM_API_BLE_SET_DEFAULT_SUBRATE)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_SET_DEFALT_SUBRATE;
+ p_msg->subrate_min = subrate_min;
+ p_msg->subrate_max = subrate_max;
+ p_msg->max_latency = max_latency;
+ p_msg->continuation_number = continuation_number;
+ p_msg->supervision_timeout = supervision_timeout;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+void BTA_DmBleGapSubrateReqest(uint16_t conn_handle, uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency, uint16_t continuation_number, uint16_t supervision_timeout)
+{
+ tBTA_DM_API_BLE_SUBRATE_REQUEST *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SUBRATE_REQUEST *)osi_malloc(sizeof(tBTA_DM_API_BLE_SUBRATE_REQUEST)))
+ != NULL) {
+ p_msg->hdr.event = BTA_DM_API_SUBRATE_REQUEST;
+ p_msg->conn_handle = conn_handle;
+ p_msg->subrate_min = subrate_min;
+ p_msg->subrate_max = subrate_max;
+ p_msg->max_latency = max_latency;
+ p_msg->continuation_number = continuation_number;
+ p_msg->supervision_timeout = supervision_timeout;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+void BTA_DmBleGapSetHostFeature(uint16_t bit_num, uint8_t bit_val)
+{
+ tBTA_DM_API_SET_HOST_FEATURE *p_msg;
+ APPL_TRACE_API("%s", __func__);
+ if ((p_msg = (tBTA_DM_API_SET_HOST_FEATURE *) osi_malloc(sizeof(tBTA_DM_API_SET_HOST_FEATURE))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_SET_HOST_FEATURE));
+ p_msg->hdr.event = BTA_DM_API_SET_HOST_FEATURE_EVT;
+
+ p_msg->bit_num = bit_num;
+ p_msg->bit_val = bit_val;
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
/*******************************************************************************
**
** Function BTA_VendorInit
@@ -3082,7 +3272,7 @@ void BTA_DmBleGapSetPreferedPHY(BD_ADDR addr,
APPL_TRACE_ERROR("%s malloc failed", __func__);
}
}
-
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
void BTA_DmBleGapExtAdvSetRandaddr(UINT16 instance, BD_ADDR addr)
{
tBTA_DM_API_EXT_ADV_SET_RAND_ADDR *p_msg;
@@ -3188,7 +3378,9 @@ void BTA_DmBleGapExtAdvSetClear(void)
APPL_TRACE_ERROR("%s malloc failed", __func__);
}
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
void BTA_DmBleGapPeriodicAdvSetParams(UINT8 instance,
tBTA_DM_BLE_Periodic_Adv_Params *params)
{
@@ -3245,7 +3437,9 @@ void BTA_DmBleGapPeriodicAdvEnable(UINT8 enable, UINT8 instance)
}
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
void BTA_DmBleGapPeriodicAdvCreateSync(tBTA_DM_BLE_Periodic_Sync_Params *params)
{
tBTA_DM_API_PERIODIC_ADV_SYNC *p_msg;
@@ -3347,7 +3541,9 @@ void BTA_DmBleGapPeriodicAdvClearDev(void)
}
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
void BTA_DmBleGapSetExtScanParams(tBTA_DM_BLE_EXT_SCAN_PARAMS *params)
{
tBTA_DM_API_SET_EXT_SCAN_PARAMS *p_msg;
@@ -3381,6 +3577,7 @@ void BTA_DmBleGapExtScan(BOOLEAN start, UINT32 duration, UINT16 period)
}
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
void BTA_DmBleGapPreferExtConnectParamsSet(BD_ADDR bd_addr,
UINT8 phy_mask,
@@ -3434,7 +3631,9 @@ void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_add
}
}
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
void BTA_DmBleDtmEnhTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback)
{
tBTA_DM_API_BLE_DTM_ENH_TX_START *p_msg;
@@ -3467,8 +3666,7 @@ void BTA_DmBleDtmEnhRxStart(uint8_t rx_channel, uint8_t phy, uint8_t modulation_
bta_sys_sendmsg(p_msg);
}
}
-
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
void BTA_DmBleGapPeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable)
@@ -3538,4 +3736,500 @@ void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PA
}
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+void BTA_DmBleGapIsoBigCreate(tBTA_DM_BLE_BIG_CREATE_PARAMS *p_big_creat_param)
+{
+ tBTA_DM_API_BIG_CREATE *p_msg;
+ APPL_TRACE_API("%s.", __func__);
+ if ((p_msg = (tBTA_DM_API_BIG_CREATE *) osi_malloc(sizeof(tBTA_DM_API_BIG_CREATE))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BIG_CREATE));
+ p_msg->hdr.event = BTA_DM_API_ISO_BIG_CREATE_EVT;
+ p_msg->big_creat_param.big_handle = p_big_creat_param->big_handle;
+ p_msg->big_creat_param.adv_handle = p_big_creat_param->adv_handle;
+ p_msg->big_creat_param.num_bis = p_big_creat_param->num_bis;
+ p_msg->big_creat_param.sdu_interval = p_big_creat_param->sdu_interval;
+ p_msg->big_creat_param.max_sdu = p_big_creat_param->max_sdu;
+ p_msg->big_creat_param.max_transport_latency = p_big_creat_param->max_transport_latency;
+ p_msg->big_creat_param.rtn = p_big_creat_param->rtn;
+ p_msg->big_creat_param.phy = p_big_creat_param->phy;
+ p_msg->big_creat_param.packing = p_big_creat_param->packing;
+ p_msg->big_creat_param.framing = p_big_creat_param->framing;
+ p_msg->big_creat_param.encryption = p_big_creat_param->encryption;
+ memcpy(&p_msg->big_creat_param.broadcast_code[0], p_big_creat_param->broadcast_code, 16);
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+
+}
+
+void BTA_DmBleGapIsoBigCreateTest(tBTA_DM_BLE_BIG_CREATE_TEST_PARAMS *p_big_creat_test_param)
+{
+ tBTA_DM_API_BIG_CREATE_TEST *p_msg;
+ APPL_TRACE_API("%s.", __func__);
+ if ((p_msg = (tBTA_DM_API_BIG_CREATE_TEST *) osi_malloc(sizeof(tBTA_DM_API_BIG_CREATE_TEST))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BIG_CREATE_TEST));
+ p_msg->hdr.event = BTA_DM_API_ISO_BIG_CREATE_TEST_EVT;
+ p_msg->big_creat_test_param.big_handle = p_big_creat_test_param->big_handle;
+ p_msg->big_creat_test_param.adv_handle = p_big_creat_test_param->adv_handle;
+ p_msg->big_creat_test_param.num_bis = p_big_creat_test_param->num_bis;
+ p_msg->big_creat_test_param.sdu_interval = p_big_creat_test_param->sdu_interval;
+ p_msg->big_creat_test_param.iso_interval = p_big_creat_test_param->iso_interval;
+ p_msg->big_creat_test_param.nse = p_big_creat_test_param->nse;
+ p_msg->big_creat_test_param.max_sdu = p_big_creat_test_param->max_sdu;
+ p_msg->big_creat_test_param.max_pdu = p_big_creat_test_param->max_pdu;
+ p_msg->big_creat_test_param.phy = p_big_creat_test_param->phy;
+ p_msg->big_creat_test_param.packing = p_big_creat_test_param->packing;
+ p_msg->big_creat_test_param.framing = p_big_creat_test_param->framing;
+ p_msg->big_creat_test_param.bn = p_big_creat_test_param->bn;
+ p_msg->big_creat_test_param.irc = p_big_creat_test_param->irc;
+ p_msg->big_creat_test_param.pto = p_big_creat_test_param->pto;
+ p_msg->big_creat_test_param.encryption = p_big_creat_test_param->encryption;
+ memcpy(&p_msg->big_creat_test_param.broadcast_code[0], p_big_creat_test_param->broadcast_code, 16);
+
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleGapIsoBigTerminate(tBTA_DM_BLE_BIG_TERMINATE_PARAMS *p_big_terminate_param)
+{
+ tBTA_DM_API_BIG_TERMINATE *p_msg;
+ APPL_TRACE_API("%s.", __func__);
+ if ((p_msg = (tBTA_DM_API_BIG_TERMINATE *) osi_malloc(sizeof(tBTA_DM_API_BIG_TERMINATE))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BIG_TERMINATE));
+ p_msg->hdr.event = BTA_DM_API_ISO_BIG_TERMINATE_EVT;
+ p_msg->big_terminate_param.big_handle = p_big_terminate_param->big_handle;
+ p_msg->big_terminate_param.reason = p_big_terminate_param->reason;
+
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+void BTA_DmBleGapIsoBigSyncCreate(tBTA_DM_BLE_BIG_SYNC_CREATE_PARAMS *p_big_sync_param)
+{
+ tBTA_DM_API_BIG_SYNC_CREATE *p_msg;
+ APPL_TRACE_API("%s.", __func__);
+ if ((p_msg = (tBTA_DM_API_BIG_SYNC_CREATE *) osi_malloc(sizeof(tBTA_DM_API_BIG_SYNC_CREATE))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BIG_SYNC_CREATE));
+ p_msg->hdr.event = BTA_DM_API_ISO_BIG_SYNC_CREATE_EVT;
+
+ p_msg->big_sync_param.big_handle = p_big_sync_param->big_handle;
+ p_msg->big_sync_param.sync_handle = p_big_sync_param->sync_handle;
+ p_msg->big_sync_param.encryption = p_big_sync_param->encryption;
+ memcpy(&p_msg->big_sync_param.bc_code[0], &p_big_sync_param->bc_code[0], 16);
+ p_msg->big_sync_param.mse = p_big_sync_param->mse;
+ p_msg->big_sync_param.big_sync_timeout = p_big_sync_param->big_sync_timeout;
+ p_msg->big_sync_param.num_bis = p_big_sync_param->num_bis;
+ memcpy(&p_msg->big_sync_param.bis[0], &p_big_sync_param->bis[0], p_big_sync_param->num_bis);
+
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleGapIsoBigSyncTerminate(tBTA_DM_BLE_BIG_SYNC_TERMINATE_PARAMS *p_big_sync_terminate_param)
+{
+ tBTA_DM_API_BIG_SYNC_TERMINATE *p_msg;
+ APPL_TRACE_API("%s.", __func__);
+ if ((p_msg = (tBTA_DM_API_BIG_SYNC_TERMINATE *) osi_malloc(sizeof(tBTA_DM_API_BIG_SYNC_TERMINATE))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BIG_SYNC_TERMINATE));
+ p_msg->hdr.event = BTA_DM_API_ISO_BIG_SYNC_TERMINATE_EVT;
+
+ p_msg->big_sync_terminate_param.big_handle = p_big_sync_terminate_param->big_handle;
+
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+void BTA_DmBleGapIsoDataPathSet(tBTA_DM_BLE_ISO_SET_DATA_PATH_PARAMS *p_iso_data_path_param)
+{
+ tBTA_DM_API_ISO_DATA_PATH *p_msg;
+ uint8_t codec_cfg_len = p_iso_data_path_param->codec_len;
+ APPL_TRACE_API("%s", __func__);
+ if ((p_msg = (tBTA_DM_API_ISO_DATA_PATH *) osi_malloc(sizeof(tBTA_DM_API_ISO_DATA_PATH) + codec_cfg_len)) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_ISO_DATA_PATH));
+ p_msg->hdr.event = BTA_DM_API_ISO_SET_DATA_PATH_EVT;
+
+ p_msg->iso_data_path_param.conn_handle = p_iso_data_path_param->conn_handle;
+ p_msg->iso_data_path_param.data_path_dir = p_iso_data_path_param->data_path_dir;
+ p_msg->iso_data_path_param.data_path_id = p_iso_data_path_param->data_path_id;
+ p_msg->iso_data_path_param.coding_fmt = p_iso_data_path_param->coding_fmt;
+ p_msg->iso_data_path_param.company_id = p_iso_data_path_param->company_id;
+ p_msg->iso_data_path_param.vs_codec_id = p_iso_data_path_param->vs_codec_id;
+ p_msg->iso_data_path_param.controller_delay = p_iso_data_path_param->controller_delay;
+ p_msg->iso_data_path_param.codec_len = p_iso_data_path_param->codec_len;
+ p_msg->iso_data_path_param.codec_cfg = (codec_cfg_len != 0) ? (UINT8 *)(p_msg + 1) : NULL;
+ if (codec_cfg_len) {
+ memcpy(p_msg->iso_data_path_param.codec_cfg, p_iso_data_path_param->codec_cfg, p_iso_data_path_param->codec_len);
+ }
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleGapIsoDataPathRemove(tBTA_DM_BLE_ISO_REMOVE_DATA_PATH_PARAMS *p_iso_data_path_param)
+{
+ tBTA_DM_API_ISO_DATA_PATH_REMOVE *p_msg;
+ APPL_TRACE_API("%s", __func__);
+ if ((p_msg = (tBTA_DM_API_ISO_DATA_PATH_REMOVE *) osi_malloc(sizeof(tBTA_DM_API_ISO_DATA_PATH_REMOVE))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_ISO_DATA_PATH_REMOVE));
+ p_msg->hdr.event = BTA_DM_API_ISO_REMOVE_DATA_PATH_EVT;
+
+ p_msg->iso_data_path_remove_param.conn_handle = p_iso_data_path_param->conn_handle;
+ p_msg->iso_data_path_remove_param.data_path_dir = p_iso_data_path_param->data_path_dir;
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleGapIsoReadTxSync(uint16_t iso_handle)
+{
+ tBTA_DM_API_ISO_READ_TX_SYNC *p_msg;
+ APPL_TRACE_API("%s", __func__);
+ if ((p_msg = (tBTA_DM_API_ISO_READ_TX_SYNC *) osi_malloc(sizeof(tBTA_DM_API_ISO_READ_TX_SYNC))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_ISO_READ_TX_SYNC));
+ p_msg->hdr.event = BTA_DM_API_ISO_READ_TX_SYNC_EVT;
+
+ p_msg->iso_hdl= iso_handle;
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleGapIsoReadLinkQuality(uint16_t iso_handle)
+{
+ tBTA_DM_API_ISO_READ_LINK_QUALITY *p_msg;
+ APPL_TRACE_API("%s", __func__);
+ if ((p_msg = (tBTA_DM_API_ISO_READ_LINK_QUALITY *) osi_malloc(sizeof(tBTA_DM_API_ISO_READ_LINK_QUALITY))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_ISO_READ_LINK_QUALITY));
+ p_msg->hdr.event = BTA_DM_API_ISO_READ_LINK_QUALITY_EVT;
+
+ p_msg->iso_hdl= iso_handle;
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_msg);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+void BTA_DmBleIsoSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing,
+ uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, uint8_t *cis_params)
+{
+ tBTA_DM_API_SET_CIG_PARAM *p_buf;
+ if ((p_buf = (tBTA_DM_API_SET_CIG_PARAM *)osi_malloc(sizeof(tBTA_DM_API_SET_CIG_PARAM))) != NULL) {
+ p_buf->hdr.event = BTA_DM_API_SET_CIG_PARAMS_EVT;
+ p_buf->cig_id = cig_id;
+ p_buf->sdu_int_c_to_p = sdu_int_c_to_p;
+ p_buf->sdu_int_p_to_c = sdu_int_p_to_c;
+ p_buf->worse_case_SCA = worse_case_SCA;
+ p_buf->packing = packing;
+ p_buf->framing = framing;
+ p_buf->mtl_c_to_p = mtl_c_to_p;
+ p_buf->mtl_p_to_c = mtl_p_to_c;
+ p_buf->cis_cnt = cis_cnt;
+ memcpy(&p_buf->cis_params[0], cis_params, sizeof(struct bta_iso_cis_params) * cis_cnt);
+
+ bta_sys_sendmsg(p_buf);
+ }
+ return;
+}
+
+void BTA_DmBleIsoSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c,
+ uint16_t iso_interval, uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, uint8_t *cis_params_test)
+{
+ tBTA_DM_API_SET_CIG_PARAM_TEST *p_buf;
+ if ((p_buf = (tBTA_DM_API_SET_CIG_PARAM_TEST *)osi_malloc(sizeof(tBTA_DM_API_SET_CIG_PARAM_TEST))) != NULL) {
+ p_buf->hdr.event = BTA_DM_API_SET_CIG_PARAMS_TEST_EVT;
+ p_buf->cig_id = cig_id;
+ p_buf->sdu_int_c_to_p = sdu_int_c_to_p;
+ p_buf->sdu_int_p_to_c = sdu_int_p_to_c;
+ p_buf->ft_c_to_p = ft_c_to_p;
+ p_buf->ft_p_to_c = ft_p_to_c;
+ p_buf->iso_interval = iso_interval;
+ p_buf->worse_case_SCA = worse_case_SCA;
+ p_buf->packing = packing;
+ p_buf->framing = framing;
+ p_buf->cis_cnt = cis_cnt;
+ memcpy(&p_buf->cis_params_test[0], cis_params_test, sizeof(struct bta_iso_cis_params_test) * cis_cnt);
+
+ bta_sys_sendmsg(p_buf);
+ }
+ return;
+}
+
+void BTA_DmBleIsoCreateCis(uint8_t cig_count, uint8_t *cis_hdl_info)
+{
+ tBTA_DM_API_CREATE_CIS_PARAM *p_buf;
+ if ((p_buf = (tBTA_DM_API_CREATE_CIS_PARAM *)osi_malloc(sizeof(tBTA_DM_API_CREATE_CIS_PARAM))) != NULL) {
+ p_buf->hdr.event = BTA_DM_API_CREATE_CIS_EVT;
+ p_buf->cis_count = cig_count;
+
+ struct bta_iso_cis_hdls *hdls = (struct bta_iso_cis_hdls *)cis_hdl_info;
+
+ for (uint8_t i = 0; i < cig_count; i++)
+ {
+ p_buf->cis_hdls[i].cis_hdl = hdls[i].cis_hdl;
+ p_buf->cis_hdls[i].acl_hdl = hdls[i].acl_hdl;
+ }
+
+ bta_sys_sendmsg(p_buf);
+ }
+ return;
+}
+
+void BTA_DmBleIsoRemoveCig(uint8_t cig_id)
+{
+ tBTA_DM_API_REMOVE_CIG_PARAM *p_buf;
+ if ((p_buf = (tBTA_DM_API_REMOVE_CIG_PARAM *)osi_malloc(sizeof(tBTA_DM_API_REMOVE_CIG_PARAM))) != NULL) {
+ p_buf->hdr.event = BTA_DM_API_REMOVE_CIG_PARAMS_EVT;
+ p_buf->cig_id = cig_id;
+ bta_sys_sendmsg(p_buf);
+ }
+ return;
+}
+
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+void BTA_DmBleIsoAcceptCisReq(uint16_t cis_handle)
+{
+ tBTA_DM_API_ACCEPT_CIS_REQ_PARAM *p_buf;
+ if ((p_buf = (tBTA_DM_API_ACCEPT_CIS_REQ_PARAM *)osi_malloc(sizeof(tBTA_DM_API_ACCEPT_CIS_REQ_PARAM))) != NULL) {
+ p_buf->hdr.event = BTA_DM_API_ACCEPT_CIS_REQ_PARAMS_EVT;
+ p_buf->cis_handle = cis_handle;
+ bta_sys_sendmsg(p_buf);
+ }
+ return;
+}
+
+void BTA_DmBleIsoRejectCisReq(uint16_t cis_handle, uint8_t reason)
+{
+ tBTA_DM_API_REJECT_CIS_REQ_PARAM *p_buf;
+ if ((p_buf = (tBTA_DM_API_REJECT_CIS_REQ_PARAM *)osi_malloc(sizeof(tBTA_DM_API_REJECT_CIS_REQ_PARAM))) != NULL) {
+ p_buf->hdr.event = BTA_DM_API_REJECT_CIS_REQ_PARAMS_EVT;
+ p_buf->cis_handle = cis_handle;
+ p_buf->reason = reason;
+ bta_sys_sendmsg(p_buf);
+ }
+ return;
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+void BTA_DmBleIsoDisconCis(uint16_t cis_handle, uint8_t reason)
+{
+ tBTA_DM_API_DISCON_CIS_PARAM *p_buf;
+ if ((p_buf = (tBTA_DM_API_DISCON_CIS_PARAM *)osi_malloc(sizeof(tBTA_DM_API_DISCON_CIS_PARAM))) != NULL) {
+ p_buf->hdr.event = BTA_DM_API_DISCON_CIS_EVT;
+ p_buf->cis_handle = cis_handle;
+ p_buf->reason = reason;
+ bta_sys_sendmsg(p_buf);
+ }
+ return;
+}
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+void BTA_DmBleCteSetConnectionlessTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type,
+ uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_CTE_SET_TRANS_PARAMS *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_CTE_SET_TRANS_PARAMS *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_SET_TRANS_PARAMS) + switching_pattern_len)) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_SET_TRANS_PARAMS) + switching_pattern_len);
+ p_buf->hdr.event = BTA_DM_API_CTE_SET_TRANS_PARAMS;
+
+ p_buf->adv_handle = adv_handle;
+ p_buf->cte_len = cte_len;
+ p_buf->cte_type = cte_type;
+ p_buf->cte_count = cte_count;
+ p_buf->switching_pattern_len = switching_pattern_len;
+ p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL;
+ if (switching_pattern_len) {
+ memcpy(p_buf->antenna_ids, antenna_ids, switching_pattern_len);
+ }
+ //start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_CTE_SET_TRANS_ENABLE *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_CTE_SET_TRANS_ENABLE *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_SET_TRANS_ENABLE))) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_SET_TRANS_ENABLE));
+ p_buf->hdr.event = BTA_DM_API_CTE_SET_TRANS_ENABLE;
+
+ p_buf->adv_handle = adv_handle;
+ p_buf->cte_enable = cte_en;
+ // start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_CTE_IQ_SAMP_EN *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_CTE_IQ_SAMP_EN *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_IQ_SAMP_EN) + switching_pattern_len)) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_IQ_SAMP_EN) + switching_pattern_len);
+ p_buf->hdr.event = BTA_DM_API_CTE_SET_IQ_SAMPLING_EN;
+
+ p_buf->sync_handle = sync_handle;
+ p_buf->sampling_en = sampling_en;
+ p_buf->slot_dur = slot_dur;
+ p_buf->max_sampled_ctes = max_sampled_ctes;
+ p_buf->switching_pattern_len = switching_pattern_len;
+ p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL;
+ if (switching_pattern_len) {
+ memcpy(p_buf->antenna_ids, ant_ids, switching_pattern_len);
+ }
+ // start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+void BTA_DmBleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t switching_pattern_len, uint8_t *ant_ids)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_CTE_RECV_PARAMS *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_CTE_RECV_PARAMS *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_RECV_PARAMS) + switching_pattern_len)) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_RECV_PARAMS) + switching_pattern_len);
+ p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_RECV_PARAMS;
+
+ p_buf->conn_handle = conn_handle;
+ p_buf->sampling_en = sampling_en;
+ p_buf->slot_dur = slot_dur;
+ p_buf->switching_pattern_len = switching_pattern_len;
+ p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL;
+ if (switching_pattern_len) {
+ memcpy(p_buf->antenna_ids, ant_ids, switching_pattern_len);
+ }
+ // start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS *) osi_malloc(sizeof(tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS) + switching_pattern_len)) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS) + switching_pattern_len);
+ p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_TRANS_PARAMS;
+
+ p_buf->conn_handle = conn_handle;
+ p_buf->cte_types = cte_types;
+ p_buf->switching_pattern_len = switching_pattern_len;
+ p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL;
+ if (switching_pattern_len) {
+ memcpy(p_buf->antenna_ids, ant_ids, switching_pattern_len);
+ }
+ // start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_interval,
+ uint8_t req_cte_len, uint8_t req_cte_Type)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_CONN_CTE_REQ_EN *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_CONN_CTE_REQ_EN *) osi_malloc(sizeof(tBTA_DM_BLE_CONN_CTE_REQ_EN))) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_CONN_CTE_REQ_EN));
+ p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_REQUEST_EN;
+
+ p_buf->conn_handle = conn_handle;
+ p_buf->enable = enable;
+ p_buf->cte_req_interval = cte_req_interval;
+ p_buf->req_cte_len = req_cte_len;
+ p_buf->req_cte_Type = req_cte_Type;
+ // start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+void BTA_DmBleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_CONN_CTE_RSP_EN *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_CONN_CTE_RSP_EN *) osi_malloc(sizeof(tBTA_DM_BLE_CONN_CTE_RSP_EN))) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_CONN_CTE_RSP_EN));
+ p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_RESPONSE_EN;
+
+ p_buf->conn_handle = conn_handle;
+ p_buf->enable = enable;
+ // start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+void BTA_DmBleCteReadAntInfor(void)
+{
+ APPL_TRACE_API("%s", __func__);
+
+ tBTA_DM_BLE_READ_ANT_INFOR *p_buf;
+ if ((p_buf = (tBTA_DM_BLE_READ_ANT_INFOR *) osi_malloc(sizeof(tBTA_DM_BLE_READ_ANT_INFOR))) != NULL) {
+ memset(p_buf, 0, sizeof(tBTA_DM_BLE_READ_ANT_INFOR));
+ p_buf->hdr.event = BTA_DM_API_CTE_READ_ANTENNA_INFOR;
+ // start sent the msg to the bta system control module
+ bta_sys_sendmsg(p_buf);
+ } else {
+ APPL_TRACE_ERROR("%s malloc failed", __func__);
+ }
+}
+
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
#endif
diff --git a/lib/bt/host/bluedroid/bta/dm/bta_dm_cfg.c b/lib/bt/host/bluedroid/bta/dm/bta_dm_cfg.c
index a4792ce8..81bbd466 100644
--- a/lib/bt/host/bluedroid/bta/dm/bta_dm_cfg.c
+++ b/lib/bt/host/bluedroid/bta/dm/bta_dm_cfg.c
@@ -151,13 +151,13 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
+ {{BTA_DM_PM_SNIFF_AG_OPEN_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_SNIFF_SCO_OPEN_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
+ {{BTA_DM_PM_SNIFF_SCO_CLOSE_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
+ {{BTA_DM_PM_SNIFF_AG_IDLE_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_RETRY, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@@ -231,9 +231,9 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
+ {{BTA_DM_PM_SNIFF3, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
+ {{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
+ {{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_RETRY, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@@ -409,7 +409,7 @@ tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] = {
/*max_lat, min_rmt_to, min_loc_to*/
{0, 0, 0}, /* BTA_DM_PM_SSR0 - do not use SSR */
{0, 0, 2}, /* BTA_DM_PM_SSR1 - HH, can NOT share entry with any other profile,
- seting default max latency and min remote timeout as 0,
+ setting default max latency and min remote timeout as 0,
and always read individual device preference from HH module */
{1200, 2, 2}, /* BTA_DM_PM_SSR2 - others (as long as sniff is allowed)*/
{360, 160, 1600} /* BTA_DM_PM_SSR3 - HD */
@@ -466,7 +466,7 @@ tBTA_DM_EIR_CONF bta_dm_eir_cfg = {
{ /* mask of UUID list in EIR */
0xFFFFFFFF, /* LSB is the first UUID of the first 32 UUIDs in BTM_EIR_UUID_LKUP_TBL */
0xFFFFFFFF /* LSB is the first UUID of the next 32 UUIDs in BTM_EIR_UUID_LKUP_TBL */
- /* BTM_EIR_UUID_LKUP_TBL can be overrided */
+ /* BTM_EIR_UUID_LKUP_TBL can be overridden */
},
#endif // BTA_EIR_CANNED_UUID_LIST
FALSE, /* Not included TX power*/
diff --git a/lib/bt/host/bluedroid/bta/dm/bta_dm_co.c b/lib/bt/host/bluedroid/bta/dm/bta_dm_co.c
index c6b62f3a..5c7ee9bd 100644
--- a/lib/bt/host/bluedroid/bta/dm/bta_dm_co.c
+++ b/lib/bt/host/bluedroid/bta/dm/bta_dm_co.c
@@ -52,6 +52,18 @@ tBTE_APPL_CFG bte_appl_cfg = {
BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE,
BTM_BLE_OOB_DISABLE,
};
+
+void bta_dm_co_security_param_init(void)
+{
+ bte_appl_cfg.ble_auth_req = BTA_LE_AUTH_REQ_SC_MITM_BOND;
+ bte_appl_cfg.ble_io_cap = BTM_LOCAL_IO_CAPS_BLE;
+ bte_appl_cfg.ble_init_key = BTM_BLE_INITIATOR_KEY_SIZE;
+ bte_appl_cfg.ble_resp_key = BTM_BLE_RESPONDER_KEY_SIZE;
+ bte_appl_cfg.ble_max_key_size = BTM_BLE_MAX_KEY_SIZE;
+ bte_appl_cfg.ble_min_key_size = BTM_BLE_MIN_KEY_SIZE;
+ bte_appl_cfg.ble_accept_auth_enable = BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE;
+ bte_appl_cfg.oob_support = BTM_BLE_OOB_DISABLE;
+};
#endif
#if (defined CLASSIC_BT_INCLUDED && CLASSIC_BT_INCLUDED == TRUE)
diff --git a/lib/bt/host/bluedroid/bta/dm/bta_dm_main.c b/lib/bt/host/bluedroid/bta/dm/bta_dm_main.c
index 99736d8e..9fe5e769 100644
--- a/lib/bt/host/bluedroid/bta/dm/bta_dm_main.c
+++ b/lib/bt/host/bluedroid/bta/dm/bta_dm_main.c
@@ -67,7 +67,12 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
#if (ESP_COEX_VSC_INCLUDED == TRUE)
bta_dm_cfg_coex_status, /* BTA_DM_API_CFG_COEX_ST_EVT */
#endif
+#if (BLE_VENDOR_HCI_EN == TRUE)
bta_dm_send_vendor_hci, /* BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT */
+ bta_dm_ble_gap_clear_adv, /* BTA_DM_API_BLE_CLEAR_ADV_EVT */
+ bta_dm_ble_gap_set_csa_support, /* BTA_DM_API_BLE_SET_CSA_SUPPORT_EVT */
+ bta_dm_ble_gap_set_vendor_evt_mask, /* BTA_DM_API_BLE_SET_VENDOR_EVT_MASK_EVT */
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
#if (CLASSIC_BT_INCLUDED == TRUE)
bta_dm_config_eir, /* BTA_DM_API_CONFIG_EIR_EVT */
bta_dm_set_page_timeout, /* BTA_DM_API_PAGE_TO_SET_EVT */
@@ -76,15 +81,18 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
#if (ENC_KEY_SIZE_CTRL_MODE != ENC_KEY_SIZE_CTRL_MODE_NONE)
bta_dm_set_min_enc_key_size, /* BTA_DM_API_SET_MIN_ENC_KEY_SIZE_EVT */
#endif
-#endif
+
bta_dm_set_afh_channels, /* BTA_DM_API_SET_AFH_CHANNELS_EVT */
#if (SDP_INCLUDED == TRUE)
bta_dm_read_rmt_name, /* BTA_DM_API_GET_REMOTE_NAME_EVT*/
#endif
bta_dm_set_visibility, /* BTA_DM_API_SET_VISIBILITY_EVT */
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
bta_dm_acl_change, /* BTA_DM_ACL_CHANGE_EVT */
bta_dm_add_device, /* BTA_DM_API_ADD_DEVICE_EVT */
+#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
bta_dm_close_acl, /* BTA_DM_API_REMOVE_ACL_EVT */
+#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
#if (SMP_INCLUDED == TRUE)
/* security API events */
bta_dm_bond, /* BTA_DM_API_BOND_EVT */
@@ -130,11 +138,21 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
#endif ///SMP_INCLUDED == TRUE
bta_dm_ble_set_bg_conn_type,
bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
bta_dm_ble_set_conn_scan_params, /* BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT */
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
+#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
+#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
bta_dm_ble_observe, /* BTA_DM_API_BLE_OBSERVE_EVT */
+#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
bta_dm_ble_scan, /* BTA_DM_API_BLE_SCAN_EVT */
+#endif // #if (BLE_42_SCAN_EN == TRUE)
bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */
/* This handler function added by
Yulong at 2016/9/9 to support the
@@ -145,12 +163,14 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
Yulong at 2016/10/19 to support
stop the ble advertising setting
by the APP */
+#if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
bta_dm_ble_stop_advertising, /* BTA_DM_API_BLE_STOP_ADV_EVT */
+#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
#if BLE_PRIVACY_SPT == TRUE
bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */
#endif
bta_dm_ble_config_local_icon, /* BTA_DM_API_LOCAL_ICON_EVT */
- bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_ADV_PARAM_EVT */
+#if (BLE_42_ADV_EN == TRUE)
bta_dm_ble_set_adv_params_all, /* BTA_DM_API_BLE_ADV_PARAM_All_EVT */
bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */
/* New function to allow set raw adv
@@ -161,36 +181,54 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
response data to HCI */
bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */
bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */
+#endif // #if (BLE_42_ADV_EN == TRUE)
bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */
- bta_dm_ble_set_long_adv, /* BTA_DM_API_BLE_SET_LONG_ADV_EVT */
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */
bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */
bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */
#endif
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT */
bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */
bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */
btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */
+#endif // BLE_HOST_BLE_MULTI_ADV_EN
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */
bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
bta_dm_ble_track_advertiser, /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_EVT */
#endif
-
+#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
bta_dm_enable_test_mode, /* BTA_DM_API_ENABLE_TEST_MODE_EVT */
bta_dm_disable_test_mode, /* BTA_DM_API_DISABLE_TEST_MODE_EVT */
+#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
+#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
bta_dm_execute_callback, /* BTA_DM_API_EXECUTE_CBACK_EVT */
-
+#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
+#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
bta_dm_remove_all_acl, /* BTA_DM_API_REMOVE_ALL_ACL_EVT */
+#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
bta_dm_remove_device, /* BTA_DM_API_REMOVE_DEVICE_EVT */
bta_dm_ble_set_channels, /* BTA_DM_API_BLE_SET_CHANNELS_EVT */
bta_dm_update_white_list, /* BTA_DM_API_UPDATE_WHITE_LIST_EVT */
bta_dm_clear_white_list, /* BTA_DM_API_CLEAR_WHITE_LIST_EVT */
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
bta_dm_ble_read_adv_tx_power, /* BTA_DM_API_BLE_READ_ADV_TX_POWER_EVT */
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
bta_dm_read_rssi, /* BTA_DM_API_READ_RSSI_EVT */
#if BLE_INCLUDED == TRUE
bta_dm_ble_update_duplicate_exceptional_list,/* BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT */
@@ -199,28 +237,38 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
bta_dm_ble_gap_read_phy, /* BTA_DM_API_READ_PHY_EVT */
bta_dm_ble_gap_set_prefer_default_phy, /* BTA_DM_API_SET_PER_DEF_PHY_EVT */
bta_dm_ble_gap_set_prefer_phy, /* BTA_DM_API_SET_PER_PHY_EVT */
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
bta_dm_ble_gap_ext_adv_set_rand_addr, /* BTA_DM_API_SET_EXT_ADV_RAND_ADDR_EVT */
bta_dm_ble_gap_ext_adv_set_params, /* BTA_DM_API_SET_EXT_ADV_PARAMS_EVT */
bta_dm_ble_gap_config_ext_adv_data_raw, /* BTA_DM_API_CFG_ADV_DATA_RAW_EVT */
bta_dm_ble_gap_start_ext_adv, /* BTA_DM_API_EXT_ADV_ENABLE_EVT */
bta_dm_ble_gap_ext_adv_set_remove, /* BTA_DM_API_EXT_ADV_SET_REMOVE_EVT */
bta_dm_ble_gap_ext_adv_set_clear, /* BTA_DM_API_EXT_ADV_SET_CLEAR_EVT */
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
bta_dm_ble_gap_periodic_adv_set_params, /* BTA_DM_API_PERIODIC_ADV_SET_PARAMS_EVT */
bta_dm_ble_gap_periodic_adv_cfg_data_raw, /* BTA_DM_API_PERIODIC_ADV_CFG_DATA_EVT */
bta_dm_ble_gap_periodic_adv_enable, /* BTA_DM_API_PERIODIC_ADV_ENABLE_EVT */
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
bta_dm_ble_gap_periodic_adv_create_sync, /* BTA_DM_API_PERIODIC_ADV_SYNC_EVT */
bta_dm_ble_gap_periodic_adv_sync_cancel, /* BTA_DM_API_PERIODIC_ADV_SYNC_CANCEL_EVT */
bta_dm_ble_gap_periodic_adv_sync_terminate, /* BTA_DM_API_PERIODIC_ADV_SYNC_TERMINATE_EVT */
bta_dm_ble_gap_periodic_adv_add_dev_to_list, /* BTA_DM_API_PERIODIC_ADV_ADD_DEV_TO_LSIT_EVT */
bta_dm_ble_gap_periodic_adv_remove_dev_from_list, /* BTA_DM_API_PERIODIC_ADV_REMOVE_DEV_FROM_LSIT_EVT */
bta_dm_ble_gap_periodic_adv_clear_dev, /* BTA_DM_API_PERIODIC_ADV_CLEAR_DEV_EVT */
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
bta_dm_ble_gap_set_ext_scan_params, /* BTA_DM_API_SET_EXT_SCAN_PARAMS_EVT */
bta_dm_ble_gap_ext_scan, /* BTA_DM_API_START_EXT_SCAN_EVT */
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
bta_dm_ble_gap_set_prefer_ext_conn_params, /* BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT */
NULL, /* BTA_DM_API_EXT_CONN_EVT */
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
bta_dm_ble_gap_dtm_enhance_tx_start, /* BTA_DM_API_DTM_ENH_TX_START_EVT */
bta_dm_ble_gap_dtm_enhance_rx_start, /* BTA_DM_API_DTM_ENH_RX_START_EVT */
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
bta_dm_ble_gap_periodic_adv_recv_enable, /* BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT */
bta_dm_ble_gap_periodic_adv_sync_trans, /* BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT */
@@ -228,14 +276,74 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
bta_dm_ble_gap_set_periodic_adv_sync_trans_params, /* BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT */
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#if BLE_INCLUDED == TRUE
+#if (BLE_42_DTM_TEST_EN == TRUE)
bta_dm_ble_gap_dtm_tx_start, /* BTA_DM_API_DTM_TX_START_EVT */
bta_dm_ble_gap_dtm_rx_start, /* BTA_DM_API_DTM_RX_START_EVT */
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
bta_dm_ble_gap_dtm_stop, /* BTA_DM_API_DTM_STOP_EVT */
- bta_dm_ble_gap_clear_adv, /* BTA_DM_API_BLE_CLEAR_ADV_EVT */
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
bta_dm_ble_gap_set_rpa_timeout, /* BTA_DM_API_SET_RPA_TIMEOUT_EVT */
bta_dm_ble_gap_add_dev_to_resolving_list, /* BTA_DM_API_ADD_DEV_TO_RESOLVING_LIST_EVT */
bta_dm_ble_gap_set_privacy_mode, /* BTA_DM_API_SET_PRIVACY_MODE_EVT */
+ bta_dm_read_ble_channel_map, /* BTA_DM_API_BLE_READ_CH_MAP_EVT */
#endif
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ bta_dm_ble_big_create, /* BTA_DM_API_ISO_BIG_CREATE_EVT */
+ bta_dm_ble_big_create_test, /* BTA_DM_API_ISO_BIG_CREATE_TEST_EVT */
+ bta_dm_ble_big_terminate, /* BTA_DM_API_ISO_BIG_TERMINATE_EVT */
+#endif// #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ bta_dm_ble_big_sync_create, /* BTA_DM_API_ISO_BIG_SYNC_CREATE_EVT */
+ bta_dm_ble_big_sync_terminate, /* BTA_DM_API_ISO_BIG_SYNC_TERMINATE_EVT */
+#endif// #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ bta_dm_ble_iso_set_data_path, /* BTA_DM_API_ISO_SET_DATA_PATH_EVT */
+ bta_dm_ble_iso_remove_data_path, /* BTA_DM_API_ISO_REMOVE_DATA_PATH_EVT */
+ bta_dm_ble_iso_read_tx_sync, /* BTA_DM_API_ISO_READ_TX_SYNC_EVT */
+ bta_dm_ble_iso_read_link_quality, /* BTA_DM_API_ISO_READ_LINK_QUALITY_EVT */
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ bta_dm_ble_set_cig_params, /* BTA_DM_API_SET_CIG_PARAMS_EVT */
+ bta_dm_ble_set_cig_params_test, /* BTA_DM_API_SET_CIG_PARAMS_TEST_EVT */
+ bta_dm_ble_create_cis, /* BTA_DM_API_CREATE_CIS_EVT */
+ bta_dm_ble_remove_cig, /* BTA_DM_API_REMOVE_CIG_PARAMS_EVT*/
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ bta_dm_ble_accept_cis_req, /* BTA_DM_API_ACCEPT_CIS_REQ_PARAMS_EVT */
+ bta_dm_ble_reject_cis_req, /* BTA_DM_API_REJECT_CIS_REQ_PARAMS_EVT */
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ bta_dm_ble_discon_cis, /* BTA_DM_API_DISCON_CIS_EVT */
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ bta_dm_ble_set_cte_trans_params, /* BTA_DM_API_CTE_SET_TRANS_PARAMS */
+ bta_dm_ble_set_cte_trans_enable, /* BTA_DM_API_CTE_SET_TRANS_ENABLE */
+ bta_dm_ble_set_iq_sampling_en, /* BTA_DM_API_CTE_SET_IQ_SAMPLING_EN */
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ bta_dm_ble_set_conn_cte_recv_params, /* BTA_DM_API_CTE_SET_CONN_CTE_RECV_PARAMS */
+ bta_dm_ble_set_conn_trans_params, /* BTA_DM_API_CTE_SET_CONN_CTE_TRANS_PARAMS */
+ bta_dm_ble_set_conn_cte_req_en, /* BTA_DM_API_CTE_SET_CONN_CTE_REQUEST_EN */
+ bta_dm_ble_set_conn_cte_rsp_en, /* BTA_DM_API_CTE_SET_CONN_CTE_RESPONSE_EN */
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ bta_dm_ble_read_cte_ant_infor, /* BTA_DM_API_CTE_READ_ANTENNA_INFOR */
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ bta_dm_api_enh_read_trans_power_level, /* BTA_DM_API_ENH_READ_TRANS_POWER_LEVEL */
+ bta_dm_api_read_rem_trans_power_level, /* BTA_DM_API_READ_REM_TRANS_POWER_LEVEL */
+ bta_dm_api_set_path_loss_report_params, /* BTA_DM_API_SET_PATH_LOSS_REPORT_PARAMS */
+ bta_dm_api_set_path_loss_reporting_en, /* BTA_DM_API_SET_PATH_LOSS_REPORTING_EN */
+ bta_dm_api_set_trans_power_reporting_en, /* BTA_DM_API_SET_TRANS_POWER_REPORTING_EN */
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ bta_dm_api_set_default_subrate, /* BTA_DM_API_SET_DEFALT_SUBRATE */
+ bta_dm_api_subrate_request, /* BTA_DM_API_SUBRATE_REQUEST */
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ bta_dm_ble_set_host_feature, /* BTA_DM_API_SET_HOST_FEATURE_EVT */
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
};
diff --git a/lib/bt/host/bluedroid/bta/dm/bta_dm_pm.c b/lib/bt/host/bluedroid/bta/dm/bta_dm_pm.c
index 149b4fac..8167ddf9 100644
--- a/lib/bt/host/bluedroid/bta/dm/bta_dm_pm.c
+++ b/lib/bt/host/bluedroid/bta/dm/bta_dm_pm.c
@@ -75,7 +75,7 @@ void bta_dm_init_pm(void)
{
memset(&bta_dm_conn_srvcs, 0x00, sizeof(bta_dm_conn_srvcs));
- /* if there are no power manger entries, so not register */
+ /* if there are no power manager entries, so not register */
if (p_bta_dm_pm_cfg[0].app_id != 0) {
bta_sys_pm_register((tBTA_SYS_CONN_CBACK *)bta_dm_pm_cback);
@@ -694,9 +694,9 @@ static BOOLEAN bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE *p_peer_dev, UINT8 index)
#endif
{
#if (BTM_SSR_INCLUDED == TRUE)
- /* Dont initiate Sniff if controller has alreay accepted
+ /* Dont initiate Sniff if controller has already accepted
* remote sniff params. This avoid sniff loop issue with
- * some agrresive headsets who use sniff latencies more than
+ * some aggressive headsets who use sniff latencies more than
* DUT supported range of Sniff intervals.*/
if ((mode == BTM_PM_MD_SNIFF) && (p_peer_dev->info & BTA_DM_DI_ACP_SNIFF)) {
APPL_TRACE_DEBUG("%s: already in remote initiate sniff", __func__);
@@ -917,7 +917,7 @@ void bta_dm_pm_btm_status(tBTA_DM_MSG *p_data)
} else {
#if (BTM_SSR_INCLUDED == TRUE)
if (p_dev->prev_low) {
- /* need to send the SSR paramaters to controller again */
+ /* need to send the SSR parameters to controller again */
bta_dm_pm_ssr(p_dev->peer_bdaddr);
}
p_dev->prev_low = BTM_PM_STS_ACTIVE;
@@ -980,6 +980,7 @@ void bta_dm_pm_btm_status(tBTA_DM_MSG *p_data)
) {
tBTA_DM_SEC conn;
conn.mode_chg.mode = p_data->pm_status.status;
+ conn.mode_chg.interval = p_data->pm_status.value;
bdcpy(conn.mode_chg.bd_addr, p_data->pm_status.bd_addr);
bta_dm_cb.p_sec_cback(BTA_DM_PM_MODE_CHG_EVT, (tBTA_DM_SEC *)&conn);
}
diff --git a/lib/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/lib/bt/host/bluedroid/bta/dm/include/bta_dm_int.h
index 8adc430b..e724b37c 100644
--- a/lib/bt/host/bluedroid/bta/dm/include/bta_dm_int.h
+++ b/lib/bt/host/bluedroid/bta/dm/include/bta_dm_int.h
@@ -57,7 +57,12 @@ enum {
#if (ESP_COEX_VSC_INCLUDED == TRUE)
BTA_DM_API_CFG_COEX_ST_EVT,
#endif
+#if (BLE_VENDOR_HCI_EN == TRUE)
BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT,
+ BTA_DM_API_BLE_CLEAR_ADV_EVT,
+ BTA_DM_API_BLE_SET_CSA_SUPPORT_EVT,
+ BTA_DM_API_BLE_SET_VENDOR_EVT_MASK_EVT,
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
#if (CLASSIC_BT_INCLUDED == TRUE)
BTA_DM_API_CONFIG_EIR_EVT,
BTA_DM_API_PAGE_TO_SET_EVT,
@@ -66,16 +71,18 @@ enum {
#if (ENC_KEY_SIZE_CTRL_MODE != ENC_KEY_SIZE_CTRL_MODE_NONE)
BTA_DM_API_SET_MIN_ENC_KEY_SIZE_EVT,
#endif
-#endif
BTA_DM_API_SET_AFH_CHANNELS_EVT,
#if (SDP_INCLUDED == TRUE)
BTA_DM_API_GET_REMOTE_NAME_EVT,
#endif
BTA_DM_API_SET_VISIBILITY_EVT,
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
BTA_DM_ACL_CHANGE_EVT,
BTA_DM_API_ADD_DEVICE_EVT,
+#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
BTA_DM_API_REMOVE_ACL_EVT,
+#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
#if (SMP_INCLUDED == TRUE)
/* security API events */
BTA_DM_API_BOND_EVT,
@@ -121,13 +128,23 @@ enum {
#endif ///SMP_INCLUDED == TRUE
BTA_DM_API_BLE_SET_BG_CONN_TYPE,
BTA_DM_API_BLE_CONN_PARAM_EVT,
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT,
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
+#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
BTA_DM_API_BLE_SCAN_PARAM_EVT,
+#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
/*******This event added by Yulong at 2016/10/25 to
support the scan filter setting for the APP******/
+#if (BLE_42_SCAN_EN == TRUE)
BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT,
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
BTA_DM_API_BLE_OBSERVE_EVT,
+#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
BTA_DM_API_BLE_SCAN_EVT,
+#endif // #if (BLE_42_SCAN_EN == TRUE)
BTA_DM_API_UPDATE_CONN_PARAM_EVT,
/*******This event added by Yulong at 2016/9/9 to
support the random address setting for the APP******/
@@ -135,15 +152,17 @@ enum {
BTA_DM_API_CLEAR_RAND_ADDR_EVT,
/*******This event added by Yulong at 2016/10/19 to
support stop the ble advertising setting by the APP******/
+#if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
BTA_DM_API_BLE_STOP_ADV_EVT,
+#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
#if BLE_PRIVACY_SPT == TRUE
BTA_DM_API_LOCAL_PRIVACY_EVT,
#endif
BTA_DM_API_LOCAL_ICON_EVT,
- BTA_DM_API_BLE_ADV_PARAM_EVT,
/*******This event added by Yulong at 2016/10/20 to
support setting the ble advertising param by the APP******/
+#if (BLE_42_ADV_EN == TRUE)
BTA_DM_API_BLE_ADV_PARAM_All_EVT,
BTA_DM_API_BLE_SET_ADV_CONFIG_EVT,
/* Add for set raw advertising data */
@@ -152,36 +171,55 @@ enum {
/* Add for set raw scan response data */
BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT,
BTA_DM_API_BLE_BROADCAST_EVT,
+#endif // #if (BLE_42_ADV_EN == TRUE)
BTA_DM_API_SET_DATA_LENGTH_EVT,
- BTA_DM_API_BLE_SET_LONG_ADV_EVT,
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
BTA_DM_API_CFG_FILTER_COND_EVT,
BTA_DM_API_SCAN_FILTER_SETUP_EVT,
BTA_DM_API_SCAN_FILTER_ENABLE_EVT,
#endif
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
BTA_DM_API_BLE_MULTI_ADV_ENB_EVT,
BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT,
BTA_DM_API_BLE_MULTI_ADV_DATA_EVT,
BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT,
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
BTA_DM_API_BLE_SETUP_STORAGE_EVT,
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT,
BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT,
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT,
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
BTA_DM_API_BLE_TRACK_ADVERTISER_EVT,
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
BTA_DM_API_BLE_ENERGY_INFO_EVT,
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
BTA_DM_API_BLE_DISCONNECT_EVT,
#endif
-
+#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
BTA_DM_API_ENABLE_TEST_MODE_EVT,
BTA_DM_API_DISABLE_TEST_MODE_EVT,
+#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
+#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
BTA_DM_API_EXECUTE_CBACK_EVT,
+#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
+#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
BTA_DM_API_REMOVE_ALL_ACL_EVT,
+#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
BTA_DM_API_REMOVE_DEVICE_EVT,
BTA_DM_API_BLE_SET_CHANNELS_EVT,
BTA_DM_API_UPDATE_WHITE_LIST_EVT,
BTA_DM_API_CLEAR_WHITE_LIST_EVT,
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
BTA_DM_API_BLE_READ_ADV_TX_POWER_EVT,
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
BTA_DM_API_READ_RSSI_EVT,
#if BLE_INCLUDED == TRUE
BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT,
@@ -190,28 +228,38 @@ enum {
BTA_DM_API_READ_PHY_EVT,
BTA_DM_API_SET_PER_DEF_PHY_EVT,
BTA_DM_API_SET_PER_PHY_EVT,
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
BTA_DM_API_SET_EXT_ADV_RAND_ADDR_EVT,
BTA_DM_API_SET_EXT_ADV_PARAMS_EVT,
BTA_DM_API_CFG_ADV_DATA_RAW_EVT,
BTA_DM_API_EXT_ADV_ENABLE_EVT,
BTA_DM_API_EXT_ADV_SET_REMOVE_EVT,
BTA_DM_API_EXT_ADV_SET_CLEAR_EVT,
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
BTA_DM_API_PERIODIC_ADV_SET_PARAMS_EVT,
BTA_DM_API_PERIODIC_ADV_CFG_DATA_EVT,
BTA_DM_API_PERIODIC_ADV_ENABLE_EVT,
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
BTA_DM_API_PERIODIC_ADV_SYNC_EVT,
BTA_DM_API_PERIODIC_ADV_SYNC_CANCEL_EVT,
BTA_DM_API_PERIODIC_ADV_SYNC_TERMINATE_EVT,
BTA_DM_API_PERIODIC_ADV_ADD_DEV_TO_LSIT_EVT,
BTA_DM_API_PERIODIC_ADV_REMOVE_DEV_FROM_LSIT_EVT,
BTA_DM_API_PERIODIC_ADV_CLEAR_DEV_EVT,
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
BTA_DM_API_SET_EXT_SCAN_PARAMS_EVT,
BTA_DM_API_START_EXT_SCAN_EVT,
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT,
BTA_DM_API_EXT_CONN_EVT,
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
BTA_DM_API_DTM_ENH_TX_START_EVT,
BTA_DM_API_DTM_ENH_RX_START_EVT,
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT,
BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT,
@@ -219,14 +267,74 @@ enum {
BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT,
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#if BLE_INCLUDED == TRUE
+#if (BLE_42_DTM_TEST_EN == TRUE)
BTA_DM_API_DTM_TX_START_EVT,
BTA_DM_API_DTM_RX_START_EVT,
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
BTA_DM_API_DTM_STOP_EVT,
- BTA_DM_API_BLE_CLEAR_ADV_EVT,
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
BTA_DM_API_SET_RPA_TIMEOUT_EVT,
BTA_DM_API_ADD_DEV_TO_RESOLVING_LIST_EVT,
BTA_DM_API_SET_PRIVACY_MODE_EVT,
+ BTA_DM_API_BLE_READ_CH_MAP_EVT,
#endif
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ BTA_DM_API_ISO_BIG_CREATE_EVT,
+ BTA_DM_API_ISO_BIG_CREATE_TEST_EVT,
+ BTA_DM_API_ISO_BIG_TERMINATE_EVT,
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ BTA_DM_API_ISO_BIG_SYNC_CREATE_EVT,
+ BTA_DM_API_ISO_BIG_SYNC_TERMINATE_EVT,
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ BTA_DM_API_ISO_SET_DATA_PATH_EVT,
+ BTA_DM_API_ISO_REMOVE_DATA_PATH_EVT,
+ BTA_DM_API_ISO_READ_TX_SYNC_EVT,
+ BTA_DM_API_ISO_READ_LINK_QUALITY_EVT,
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ BTA_DM_API_SET_CIG_PARAMS_EVT,
+ BTA_DM_API_SET_CIG_PARAMS_TEST_EVT,
+ BTA_DM_API_CREATE_CIS_EVT,
+ BTA_DM_API_REMOVE_CIG_PARAMS_EVT,
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ BTA_DM_API_ACCEPT_CIS_REQ_PARAMS_EVT,
+ BTA_DM_API_REJECT_CIS_REQ_PARAMS_EVT,
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ BTA_DM_API_DISCON_CIS_EVT,
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ BTA_DM_API_CTE_SET_TRANS_PARAMS,
+ BTA_DM_API_CTE_SET_TRANS_ENABLE,
+ BTA_DM_API_CTE_SET_IQ_SAMPLING_EN,
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ BTA_DM_API_CTE_SET_CONN_CTE_RECV_PARAMS,
+ BTA_DM_API_CTE_SET_CONN_CTE_TRANS_PARAMS,
+ BTA_DM_API_CTE_SET_CONN_CTE_REQUEST_EN,
+ BTA_DM_API_CTE_SET_CONN_CTE_RESPONSE_EN,
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ BTA_DM_API_CTE_READ_ANTENNA_INFOR,
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ BTA_DM_API_ENH_READ_TRANS_POWER_LEVEL,
+ BTA_DM_API_READ_REM_TRANS_POWER_LEVEL,
+ BTA_DM_API_SET_PATH_LOSS_REPORT_PARAMS,
+ BTA_DM_API_SET_PATH_LOSS_REPORTING_EN,
+ BTA_DM_API_SET_TRANS_POWER_REPORTING_EN,
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ BTA_DM_API_SET_DEFALT_SUBRATE,
+ BTA_DM_API_SUBRATE_REQUEST,
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ BTA_DM_API_SET_HOST_FEATURE_EVT,
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
BTA_DM_MAX_EVT
};
@@ -367,10 +475,13 @@ typedef struct {
tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *exceptional_list_cb;
}tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST;
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
typedef struct {
BT_HDR hdr;
tBTA_CMPL_CB *read_tx_power_cb;
}tBTA_DM_API_READ_ADV_TX_POWER;
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
+
#endif ///BLE_INCLUDED == TRUE
typedef struct {
@@ -380,6 +491,12 @@ typedef struct {
tBTA_CMPL_CB *read_rssi_cb;
}tBTA_DM_API_READ_RSSI;
+typedef struct {
+ BT_HDR hdr;
+ BD_ADDR remote_addr;
+ tBTA_CMPL_CB *read_ch_map_cb;
+} tBTA_DM_API_READ_CH_MAP;
+
/* data type for BTA_DM_API_SET_VISIBILITY_EVT */
typedef struct {
BT_HDR hdr;
@@ -626,12 +743,14 @@ typedef struct {
UINT8 transport;
} tBTA_DM_API_REMOVE_DEVICE;
+#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
/* data type for BTA_DM_API_EXECUTE_CBACK_EVT */
typedef struct {
BT_HDR hdr;
void *p_param;
tBTA_DM_EXEC_CBACK *p_exec_cback;
} tBTA_DM_API_EXECUTE_CBACK;
+#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
/* data type for tBTA_DM_API_SET_ENCRYPTION */
typedef struct {
@@ -737,13 +856,14 @@ typedef struct {
tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback;
} tBTA_DM_API_BLE_SCAN_FILTER_PARAMS;
-
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
/* set scan parameter for BLE connections */
typedef struct {
BT_HDR hdr;
UINT16 scan_int;
UINT16 scan_window;
} tBTA_DM_API_BLE_CONN_SCAN_PARAMS;
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
/* Data type for start/stop observe */
typedef struct {
@@ -806,14 +926,6 @@ typedef struct {
BT_HDR hdr;
UINT16 adv_int_min;
UINT16 adv_int_max;
- tBLE_BD_ADDR *p_dir_bda;
-} tBTA_DM_API_BLE_ADV_PARAMS;
-
-/* set adv parameter for BLE advertising */
-typedef struct {
- BT_HDR hdr;
- UINT16 adv_int_min;
- UINT16 adv_int_max;
UINT8 adv_type;
tBLE_ADDR_TYPE addr_type_own;
tBTM_BLE_ADV_CHNL_MAP channel_map;
@@ -829,6 +941,7 @@ typedef struct {
} tBTA_DM_API_BLE_FEATURE;
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/* multi adv data structure */
typedef struct {
BT_HDR hdr;
@@ -855,6 +968,7 @@ typedef struct {
BT_HDR hdr;
UINT8 inst_id;
} tBTA_DM_API_BLE_MULTI_ADV_DISABLE;
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
typedef struct {
BT_HDR hdr;
@@ -872,13 +986,7 @@ typedef struct {
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback;
} tBTA_DM_API_SET_ADV_CONFIG_RAW;
-typedef struct {
- BT_HDR hdr;
- UINT8 *adv_data;
- UINT8 adv_data_len;
- tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback;
-} tBTA_DM_API_SET_LONG_ADV;
-
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
typedef struct {
BT_HDR hdr;
UINT8 batch_scan_full_max;
@@ -889,7 +997,9 @@ typedef struct {
tBTA_BLE_SCAN_REP_CBACK *p_read_rep_cback;
tBTA_DM_BLE_REF_VALUE ref_value;
} tBTA_DM_API_SET_STORAGE_CONFIG;
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
typedef struct {
BT_HDR hdr;
tBTA_BLE_BATCH_SCAN_MODE scan_mode;
@@ -904,29 +1014,37 @@ typedef struct {
BT_HDR hdr;
tBTA_DM_BLE_REF_VALUE ref_value;
} tBTA_DM_API_DISABLE_SCAN;
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
typedef struct {
BT_HDR hdr;
tBTA_BLE_BATCH_SCAN_MODE scan_type;
tBTA_DM_BLE_REF_VALUE ref_value;
} tBTA_DM_API_READ_SCAN_REPORTS;
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
typedef struct {
BT_HDR hdr;
tBTA_DM_BLE_REF_VALUE ref_value;
tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback;
} tBTA_DM_API_TRACK_ADVERTISER;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
typedef struct {
BT_HDR hdr;
tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback;
} tBTA_DM_API_ENERGY_INFO;
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
typedef struct {
BT_HDR hdr;
BD_ADDR remote_bda;
} tBTA_DM_API_BLE_DISCONNECT;
+#if (BLE_42_DTM_TEST_EN == TRUE)
typedef struct {
BT_HDR hdr;
UINT8 tx_channel;
@@ -940,6 +1058,7 @@ typedef struct {
UINT8 rx_channel;
tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback;
} tBTA_DM_API_BLE_DTM_RX_START;
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
typedef struct {
BT_HDR hdr;
@@ -959,8 +1078,87 @@ typedef struct {
tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback;
} tBTA_DM_API_SET_PRIVACY_MODE;
+typedef struct {
+ BT_HDR hdr;
+ UINT8 csa_select;
+ tBTA_SET_CSA_SUPPORT_CMPL_CBACK *p_cback;
+} tBTA_DM_API_BLE_SET_CSA_SUPPORT;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT32 evt_mask;
+ tBTA_SET_VENDOR_EVT_MASK_CBACK *p_cback;
+} tBTA_DM_API_BLE_SET_VENDOR_EVT_MASK;
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 phy;
+} tBTA_DM_API_BLE_ENH_READ_TANS_PWR_LEVEL;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 phy;
+} tBTA_DM_API_BLE_READ_REMOTE_TANS_PWR_LEVEL;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 high_threshold;
+ UINT8 high_hysteresis;
+ UINT8 low_threshold;
+ UINT8 low_hysteresis;
+ UINT16 min_time_spent;
+} tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_PARAMS;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 enable;
+} tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_ENABLE;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 local_enable;
+ UINT8 remote_enable;
+} tBTA_DM_API_BLE_SET_TRANS_PWR_RPT_ENABLE;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ UINT16 subrate_min;
+ UINT16 subrate_max;
+ UINT16 max_latency;
+ UINT16 continuation_number;
+ UINT16 supervision_timeout;
+} tBTA_DM_API_BLE_SET_DEFAULT_SUBRATE;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT16 subrate_min;
+ UINT16 subrate_max;
+ UINT16 max_latency;
+ UINT16 continuation_number;
+ UINT16 supervision_timeout;
+} tBTA_DM_API_BLE_SUBRATE_REQUEST;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ uint16_t bit_num;
+ uint8_t bit_val;
+} tBTA_DM_API_SET_HOST_FEATURE;
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
#endif /* BLE_INCLUDED */
+#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
/* data type for BTA_DM_API_REMOVE_ACL_EVT */
typedef struct {
BT_HDR hdr;
@@ -969,13 +1167,17 @@ typedef struct {
tBTA_TRANSPORT transport;
} tBTA_DM_API_REMOVE_ACL;
+#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
+#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
/* data type for BTA_DM_API_REMOVE_ALL_ACL_EVT */
typedef struct {
BT_HDR hdr;
tBTA_DM_LINK_TYPE link_type;
} tBTA_DM_API_REMOVE_ALL_ACL;
+#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
+
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
@@ -1013,8 +1215,8 @@ typedef struct {
tBTA_DM_BLE_REF_VALUE ref_value;
} tBTA_DM_API_SCAN_FILTER_PARAM_SETUP;
#endif
-#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
typedef struct {
BT_HDR hdr;
UINT8 tx_channel;
@@ -1030,10 +1232,12 @@ typedef struct {
UINT8 modulation_index;
tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback;
} tBTA_DM_API_BLE_DTM_ENH_RX_START;
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
#define BTA_PHY_1M_MASK (1 << 0)
#define BTA_PHY_2M_MASK (1 << 1)
-#define BTAS_PHY_CODED_MASK (1 << 2)
+#define BTA_PHY_CODED_MASK (1 << 2)
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
@@ -1199,6 +1403,215 @@ typedef struct {
} tBTA_DM_API_SET_PAST_PARAMS;
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ tBTA_DM_BLE_BIG_CREATE_PARAMS big_creat_param;
+} tBTA_DM_API_BIG_CREATE;
+typedef struct {
+ BT_HDR hdr;
+ tBTA_DM_BLE_BIG_CREATE_TEST_PARAMS big_creat_test_param;
+} tBTA_DM_API_BIG_CREATE_TEST;
+typedef struct {
+ BT_HDR hdr;
+ tBTA_DM_BLE_BIG_TERMINATE_PARAMS big_terminate_param;
+} tBTA_DM_API_BIG_TERMINATE;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ tBTA_DM_BLE_BIG_SYNC_CREATE_PARAMS big_sync_param;
+} tBTA_DM_API_BIG_SYNC_CREATE;
+
+typedef struct {
+ BT_HDR hdr;
+ tBTA_DM_BLE_BIG_SYNC_TERMINATE_PARAMS big_sync_terminate_param;
+} tBTA_DM_API_BIG_SYNC_TERMINATE;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ tBTA_DM_BLE_ISO_SET_DATA_PATH_PARAMS iso_data_path_param;
+} tBTA_DM_API_ISO_DATA_PATH;
+
+typedef struct {
+ BT_HDR hdr;
+ tBTA_DM_BLE_ISO_REMOVE_DATA_PATH_PARAMS iso_data_path_remove_param;
+} tBTA_DM_API_ISO_DATA_PATH_REMOVE;
+
+typedef struct {
+ BT_HDR hdr;
+ uint16_t iso_hdl;
+} tBTA_DM_API_ISO_READ_TX_SYNC;
+
+typedef struct {
+ BT_HDR hdr;
+ uint16_t iso_hdl;
+} tBTA_DM_API_ISO_READ_LINK_QUALITY;
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+struct bta_iso_cis_params {
+ UINT8 cis_id;
+ UINT16 max_sdu_c_to_p;
+ UINT16 max_sdu_p_to_c;
+ UINT8 phy_c_to_p;
+ UINT8 phy_p_to_c;
+ UINT8 rtn_c_to_p;
+ UINT8 rtn_p_to_c;
+} __attribute__((packed));
+
+struct bta_iso_cis_params_test {
+ UINT8 cis_id;
+ UINT8 nse;
+ UINT16 max_sdu_c_to_p;
+ UINT16 max_sdu_p_to_c;
+ UINT16 max_pdu_c_to_p;
+ UINT16 max_pdu_p_to_c;
+ UINT8 phy_c_to_p;
+ UINT8 phy_p_to_c;
+ UINT8 bn_c_to_p;
+ UINT8 bn_p_to_c;
+} __attribute__((packed));
+
+typedef struct {
+ BT_HDR hdr;
+ UINT8 cig_id;
+ UINT32 sdu_int_c_to_p;
+ UINT32 sdu_int_p_to_c;
+ UINT8 worse_case_SCA;
+ UINT8 packing;
+ UINT8 framing;
+ UINT16 mtl_c_to_p; // max_transport_latency_c_to_p
+ UINT16 mtl_p_to_c; // max_transport_latency_p_to_c
+ UINT8 cis_cnt;
+ struct bta_iso_cis_params cis_params[BLE_ISO_CIS_MAX_COUNT];
+} tBTA_DM_API_SET_CIG_PARAM;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT8 cig_id;
+ UINT32 sdu_int_c_to_p;
+ UINT32 sdu_int_p_to_c;
+ UINT8 ft_c_to_p;
+ UINT8 ft_p_to_c;
+ UINT16 iso_interval;
+ UINT8 worse_case_SCA;
+ UINT8 packing;
+ UINT8 framing;
+ UINT8 cis_cnt;
+ struct bta_iso_cis_params_test cis_params_test[BLE_ISO_CIS_MAX_COUNT];
+} tBTA_DM_API_SET_CIG_PARAM_TEST;
+
+struct bta_iso_cis_hdls {
+ uint16_t cis_hdl;
+ uint16_t acl_hdl;
+}__attribute__((packed));
+
+typedef struct {
+ BT_HDR hdr;
+ uint8_t cis_count;
+ struct bta_iso_cis_hdls cis_hdls[BLE_ISO_CIS_MAX_COUNT];
+} tBTA_DM_API_CREATE_CIS_PARAM;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT8 cig_id;
+} tBTA_DM_API_REMOVE_CIG_PARAM;
+
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ UINT16 cis_handle;
+} tBTA_DM_API_ACCEPT_CIS_REQ_PARAM;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 cis_handle;
+ UINT8 reason;
+} tBTA_DM_API_REJECT_CIS_REQ_PARAM;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ UINT16 cis_handle;
+ UINT8 reason;
+} tBTA_DM_API_DISCON_CIS_PARAM;
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ UINT8 adv_handle;
+ UINT8 cte_len;
+ UINT8 cte_type;
+ UINT8 cte_count;
+ UINT8 switching_pattern_len;
+ UINT8 *antenna_ids;
+} tBTA_DM_BLE_CTE_SET_TRANS_PARAMS;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT8 adv_handle;
+ UINT8 cte_enable;
+} tBTA_DM_BLE_CTE_SET_TRANS_ENABLE;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 sync_handle;
+ UINT8 sampling_en;
+ UINT8 slot_dur;
+ UINT8 max_sampled_ctes;
+ UINT8 switching_pattern_len;
+ UINT8 *antenna_ids;
+} tBTA_DM_BLE_CTE_IQ_SAMP_EN;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 sampling_en;
+ UINT8 slot_dur;
+ UINT8 switching_pattern_len;
+ UINT8 *antenna_ids;
+} tBTA_DM_BLE_CTE_RECV_PARAMS;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 cte_types;
+ UINT8 switching_pattern_len;
+ UINT8 *antenna_ids;
+} tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 enable;
+ UINT16 cte_req_interval;
+ UINT8 req_cte_len;
+ UINT8 req_cte_Type;
+} tBTA_DM_BLE_CONN_CTE_REQ_EN;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 conn_handle;
+ UINT8 enable;
+} tBTA_DM_BLE_CONN_CTE_RSP_EN;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+typedef struct {
+ BT_HDR hdr;
+} tBTA_DM_BLE_READ_ANT_INFOR;
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
/* union of all data types */
typedef union {
/* event buffer header */
@@ -1227,10 +1640,14 @@ typedef union {
#if (BLE_INCLUDED == TRUE)
tBTA_DM_API_BLE_SET_CHANNELS ble_set_channels;
tBTA_DM_API_UPDATE_WHITE_LIST white_list;
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
tBTA_DM_API_READ_ADV_TX_POWER read_tx_power;
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
#endif ///BLE_INCLUDED == TRUE
tBTA_DM_API_READ_RSSI rssi;
+ tBTA_DM_API_READ_CH_MAP ch_map;
+
tBTA_DM_API_SET_VISIBILITY set_visibility;
tBTA_DM_API_ADD_DEVICE add_dev;
@@ -1278,9 +1695,9 @@ typedef union {
#endif /* #if (BTA_DM_QOS_INCLUDED == TRUE) */
tBTA_DM_API_DI_DISC di_disc;
-
+#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
tBTA_DM_API_EXECUTE_CBACK exec_cback;
-
+#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE)
tBTA_DM_API_SET_ENCRYPTION set_encryption;
#if BLE_INCLUDED == TRUE
@@ -1291,19 +1708,21 @@ typedef union {
tBTA_DM_API_BLE_SEC_GRANT ble_sec_grant;
tBTA_DM_API_BLE_SET_BG_CONN_TYPE ble_set_bd_conn_type;
tBTA_DM_API_BLE_CONN_PARAMS ble_set_conn_params;
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
tBTA_DM_API_BLE_CONN_SCAN_PARAMS ble_set_conn_scan_params;
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
+#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
tBTA_DM_API_BLE_SCAN_PARAMS ble_set_scan_params;
+#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
tBTA_DM_API_BLE_SCAN_FILTER_PARAMS ble_set_scan_fil_params;
tBTA_DM_API_BLE_OBSERVE ble_observe;
tBTA_DM_API_BLE_SCAN ble_scan;
tBTA_DM_API_ENABLE_PRIVACY ble_remote_privacy;
tBTA_DM_API_LOCAL_PRIVACY ble_local_privacy;
tBTA_DM_API_LOCAL_ICON ble_local_icon;
- tBTA_DM_API_BLE_ADV_PARAMS ble_set_adv_params;
tBTA_DM_API_BLE_ADV_PARAMS_ALL ble_set_adv_params_all;
tBTA_DM_API_SET_ADV_CONFIG ble_set_adv_data;
tBTA_DM_API_SET_ADV_CONFIG_RAW ble_set_adv_data_raw;
- tBTA_DM_API_SET_LONG_ADV ble_set_long_adv_data;
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
tBTA_DM_API_SCAN_FILTER_PARAM_SETUP ble_scan_filt_param_setup;
tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond;
@@ -1315,61 +1734,148 @@ typedef union {
tBTA_DM_APT_CLEAR_ADDR clear_addr;
tBTA_DM_API_SET_RPA_TIMEOUT set_rpa_timeout;
tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST add_dev_to_resolving_list;
+
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
tBTA_DM_API_BLE_MULTI_ADV_ENB ble_multi_adv_enb;
tBTA_DM_API_BLE_MULTI_ADV_PARAM ble_multi_adv_param;
tBTA_DM_API_BLE_MULTI_ADV_DATA ble_multi_adv_data;
tBTA_DM_API_BLE_MULTI_ADV_DISABLE ble_multi_adv_disable;
-
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
tBTA_DM_API_SET_STORAGE_CONFIG ble_set_storage;
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
tBTA_DM_API_ENABLE_SCAN ble_enable_scan;
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
tBTA_DM_API_READ_SCAN_REPORTS ble_read_reports;
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
tBTA_DM_API_DISABLE_SCAN ble_disable_scan;
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
tBTA_DM_API_TRACK_ADVERTISER ble_track_advert;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
tBTA_DM_API_ENERGY_INFO ble_energy_info;
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
tBTA_DM_API_BLE_DISCONNECT ble_disconnect;
tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST ble_duplicate_exceptional_list;
#if (BLE_50_FEATURE_SUPPORT == TRUE)
tBTA_DM_API_READ_PHY ble_read_phy;
tBTA_DM_API_SET_PER_DEF_PHY ble_set_per_def_phy;
tBTA_DM_API_SET_PER_PHY ble_set_per_phy;
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
tBTA_DM_API_EXT_ADV_SET_RAND_ADDR ble_set_ext_adv_rand_addr;
tBTA_DM_API_EXT_ADV_SET_PARAMS ble_set_ext_adv_params;
tBTA_DM_API_CFG_EXT_ADV_DATA ble_cfg_ext_adv_data;
tBTA_DM_API_BLE_EXT_ADV ble_start_ext_adv;
tBTA_DM_API_BLE_EXT_ADV_SET_REMOVE ble_ext_adv_set_remove;
tBTA_DM_API_BLE_EXT_ADV_SET_CLEAR ble_ext_adv_set_clear;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
tBTA_DM_API_BLE_PERIODIC_ADV_SET_PARAMS ble_set_periodic_adv_params;
tBTA_DM_API_CFG_PERIODIC_ADV_DATA ble_cfg_periodic_adv_data;
tBTA_DM_API_ENABLE_PERIODIC_ADV ble_enable_periodic_adv;
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
tBTA_DM_API_PERIODIC_ADV_SYNC ble_periodic_adv_sync;
tBTA_DM_API_PERIODIC_ADV_SYNC_CANCEL ble_periodic_adv_sync_cancel;
tBTA_DM_API_PERIODIC_ADV_SYNC_TERM ble_periodic_adv_sync_term;
tBTA_DM_API_PERIODIC_ADV_ADD_DEV_TO_LIST ble_periodic_adv_add_dev_to_list;
tBTA_DM_API_PERIODIC_ADV_REMOVE_DEV_FROM_LIST ble_periodic_adv_remove_dev_from_list;
tBTA_DM_API_PERIODIC_ADV_DEV_CLEAR ble_periodic_adv_clear_dev;
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
tBTA_DM_API_SET_EXT_SCAN_PARAMS ble_set_ext_scan_params;
tBTA_DM_API_EXT_SCAN ble_ext_scan;
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
tBTA_DM_API_SET_PER_EXT_CONN_PARAMS ble_set_per_ext_conn_params;
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
tBTA_DM_API_BLE_DTM_ENH_TX_START dtm_enh_tx_start;
tBTA_DM_API_BLE_DTM_ENH_RX_START dtm_enh_rx_start;
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE ble_periodic_adv_recv_enable;
tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS ble_periodic_adv_sync_trans;
tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS ble_periodic_adv_set_info_trans;
tBTA_DM_API_SET_PAST_PARAMS ble_set_past_params;
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
-
+#if (BLE_42_DTM_TEST_EN == TRUE)
tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start;
tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start;
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
tBTA_DM_API_BLE_DTM_STOP dtm_stop;
tBTA_DM_API_CLEAR_ADV ble_clear_adv;
tBTA_DM_API_SET_PRIVACY_MODE ble_set_privacy_mode;
+ tBTA_DM_API_BLE_SET_CSA_SUPPORT ble_set_csa_support;
+ tBTA_DM_API_BLE_SET_VENDOR_EVT_MASK ble_set_vendor_evt_mask;
#endif
-
+#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
tBTA_DM_API_REMOVE_ACL remove_acl;
+#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE)
+#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
tBTA_DM_API_REMOVE_ALL_ACL remove_all_acl;
-
+#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ tBTA_DM_API_BIG_CREATE big_creat;
+ tBTA_DM_API_BIG_CREATE_TEST big_creat_test;
+ tBTA_DM_API_BIG_TERMINATE big_terminate;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ tBTA_DM_API_BIG_SYNC_CREATE big_sync;
+ tBTA_DM_API_BIG_SYNC_TERMINATE big_sync_terminate;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ tBTA_DM_API_ISO_DATA_PATH iso_set_data_path;
+ tBTA_DM_API_ISO_DATA_PATH_REMOVE iso_remove_data_path;
+ tBTA_DM_API_ISO_READ_TX_SYNC iso_read_tx_sync;
+ tBTA_DM_API_ISO_READ_LINK_QUALITY iso_read_link_quality;
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ tBTA_DM_API_SET_CIG_PARAM api_cig_params;
+ tBTA_DM_API_SET_CIG_PARAM_TEST api_cig_params_test;
+ tBTA_DM_API_CREATE_CIS_PARAM create_cis;
+ tBTA_DM_API_REMOVE_CIG_PARAM remove_cig;
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ tBTA_DM_API_ACCEPT_CIS_REQ_PARAM accept_cis_req;
+ tBTA_DM_API_REJECT_CIS_REQ_PARAM reject_cis_req;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ tBTA_DM_API_DISCON_CIS_PARAM discon_cis;
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ tBTA_DM_BLE_CTE_SET_TRANS_PARAMS set_cte_trans_params;
+ tBTA_DM_BLE_CTE_SET_TRANS_ENABLE set_trans_en;
+ tBTA_DM_BLE_CTE_IQ_SAMP_EN iq_samp_en;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ tBTA_DM_BLE_CTE_RECV_PARAMS recv_params;
+ tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS conn_trans_params;
+ tBTA_DM_BLE_CONN_CTE_REQ_EN conn_req_en;
+ tBTA_DM_BLE_CONN_CTE_RSP_EN conn_rsp_en;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ tBTA_DM_BLE_READ_ANT_INFOR read_ant_infor;
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ tBTA_DM_API_BLE_ENH_READ_TANS_PWR_LEVEL enh_read_trans_pwr_level;
+ tBTA_DM_API_BLE_READ_REMOTE_TANS_PWR_LEVEL remote_trans_pwr_level;
+ tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_PARAMS path_loss_rpt_params;
+ tBTA_DM_API_BLE_SET_PATH_LOSS_RPT_ENABLE path_loss_rpt_en;
+ tBTA_DM_API_BLE_SET_TRANS_PWR_RPT_ENABLE trans_pwr_rpt_en;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ tBTA_DM_API_BLE_SET_DEFAULT_SUBRATE default_subrate;
+ tBTA_DM_API_BLE_SUBRATE_REQUEST subrate_request;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ tBTA_DM_API_SET_HOST_FEATURE set_host_feat;
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
} tBTA_DM_MSG;
@@ -1483,8 +1989,12 @@ typedef struct {
tBTA_DM_BLE_PF_CFG_CBACK *p_scan_filt_cfg_cback;
tBTA_DM_BLE_PF_STATUS_CBACK *p_scan_filt_status_cback;
tBTA_DM_BLE_PF_PARAM_CBACK *p_scan_filt_param_cback;
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
tBTA_BLE_MULTI_ADV_CBACK *p_multi_adv_cback;
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback;
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
#endif
UINT16 state;
BOOLEAN disabling;
@@ -1590,6 +2100,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;
@@ -1748,7 +2259,10 @@ extern void bta_dm_update_white_list(tBTA_DM_MSG *p_data);
extern void bta_dm_clear_white_list(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data);
extern void bta_dm_read_rssi(tBTA_DM_MSG *p_data);
+extern void bta_dm_read_ble_channel_map(tBTA_DM_MSG *p_data);
+#if (CLASSIC_BT_INCLUDED == TRUE)
extern void bta_dm_set_visibility (tBTA_DM_MSG *p_data);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
extern void bta_dm_set_scan_config(tBTA_DM_MSG *p_data);
extern void bta_dm_vendor_spec_command(tBTA_DM_MSG *p_data);
@@ -1774,7 +2288,9 @@ extern void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data);
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
extern void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data);
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data);
#endif /* ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE) */
@@ -1784,19 +2300,22 @@ extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_clear_rand_address(tBTA_DM_MSG *p_data);
+#if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
extern void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_config_local_icon (tBTA_DM_MSG *p_data);
-extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_adv_params_all(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data);
-extern void bta_dm_ble_set_long_adv (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data);
+#if SMP_INCLUDED == TRUE
+extern void bta_dm_co_security_param_init(void);
+#endif
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data);
extern void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data);
@@ -1806,16 +2325,22 @@ extern void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data);
+#if (BLE_42_DTM_TEST_EN == TRUE)
extern void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_dtm_rx_start(tBTA_DM_MSG *p_data);
+#endif// #if (BLE_42_DTM_TEST_EN == TRUE)
extern void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_set_rpa_timeout(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_add_dev_to_resolving_list(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_set_privacy_mode(tBTA_DM_MSG *p_data);
-#if (BLE_50_FEATURE_SUPPORT == TRUE)
+extern void bta_dm_ble_gap_set_csa_support(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_gap_set_vendor_evt_mask(tBTA_DM_MSG *p_data);
+#if (BLE_50_DTM_TEST_EN == TRUE)
extern void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_dtm_enhance_rx_start(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
extern void bta_dm_ble_gap_read_phy(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_set_prefer_default_phy(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_set_prefer_phy(tBTA_DM_MSG *p_data);
@@ -1826,12 +2351,20 @@ extern void bta_dm_ble_gap_set_ext_scan_params(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_ext_scan(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data);
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
extern void bta_dm_ble_setup_storage(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data);
+
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
extern void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
#endif
extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
@@ -1950,4 +2483,64 @@ extern void bta_dm_ble_gap_periodic_adv_set_info_trans(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data);
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+extern void bta_dm_ble_big_create(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_big_create_test(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_big_terminate(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+extern void bta_dm_ble_big_sync_create(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_big_sync_terminate(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+extern void bta_dm_ble_iso_set_data_path(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_iso_remove_data_path(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_iso_read_tx_sync(tBTA_DM_MSG *p_data);
+void bta_dm_ble_iso_read_link_quality(tBTA_DM_MSG *p_data);
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+void bta_dm_ble_set_cig_params(tBTA_DM_MSG *p_data);
+void bta_dm_ble_set_cig_params_test(tBTA_DM_MSG *p_data);
+void bta_dm_ble_create_cis(tBTA_DM_MSG *p_data);
+void bta_dm_ble_remove_cig(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+void bta_dm_ble_accept_cis_req(tBTA_DM_MSG *p_data);
+void bta_dm_ble_reject_cis_req(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+void bta_dm_ble_discon_cis(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+void bta_dm_ble_set_cte_trans_params(tBTA_DM_MSG *p_data);
+void bta_dm_ble_set_cte_trans_enable(tBTA_DM_MSG *p_data);
+void bta_dm_ble_set_iq_sampling_en(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+void bta_dm_ble_set_conn_cte_recv_params(tBTA_DM_MSG *p_data);
+void bta_dm_ble_set_conn_trans_params(tBTA_DM_MSG *p_data);
+void bta_dm_ble_set_conn_cte_req_en(tBTA_DM_MSG *p_data);
+void bta_dm_ble_set_conn_cte_rsp_en(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+void bta_dm_ble_read_cte_ant_infor(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void bta_dm_api_enh_read_trans_power_level(tBTA_DM_MSG *p_data);
+void bta_dm_api_read_rem_trans_power_level(tBTA_DM_MSG *p_data);
+void bta_dm_api_set_path_loss_report_params(tBTA_DM_MSG *p_data);
+void bta_dm_api_set_path_loss_reporting_en(tBTA_DM_MSG *p_data);
+void bta_dm_api_set_trans_power_reporting_en(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void bta_dm_api_set_default_subrate(tBTA_DM_MSG *p_data);
+void bta_dm_api_subrate_request(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+extern void bta_dm_ble_set_host_feature(tBTA_DM_MSG *p_data);
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#endif /* BTA_DM_INT_H */
diff --git a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_act.c
index b2302fa4..eb2b091e 100644
--- a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_act.c
+++ b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_act.c
@@ -36,6 +36,7 @@
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "bta_hh_int.h"
+#include "btm_int.h"
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
#include "bta_hh_int.h"
@@ -63,13 +64,14 @@ static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
tGATT_CL_COMPLETE *p_data);
static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb);
-static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
+void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
static tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda);
extern void btc_gattc_congest_callback(tBTA_GATTC *param);
+extern uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
static const tGATT_CBACK bta_gattc_cl_cback = {
bta_gattc_conn_cback,
@@ -154,7 +156,7 @@ void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
APPL_TRACE_DEBUG("bta_gattc_disable");
if (p_cb->state != BTA_GATTC_STATE_ENABLED) {
- APPL_TRACE_ERROR("not enabled or disable in pogress");
+ APPL_TRACE_ERROR("not enabled or disable in progress");
return;
}
@@ -227,7 +229,7 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) {
p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
p_buf->client_if = p_cb->cl_rcb[i].client_if;
- APPL_TRACE_DEBUG("GATTC getbuf sucess.\n");
+ APPL_TRACE_DEBUG("GATTC getbuf success.\n");
bta_sys_sendmsg(p_buf);
status = BTA_GATT_OK;
} else {
@@ -336,6 +338,10 @@ void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
UNUSED(p_cb);
if (p_clreg != NULL) {
+ if (p_msg->api_conn.own_addr_type <= BLE_ADDR_TYPE_MAX) {
+ // update own address type for creating connection
+ BTM_BleUpdateOwnType(&p_msg->api_conn.own_addr_type, NULL);
+ }
if (p_msg->api_conn.is_direct) {
if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
p_msg->api_conn.remote_bda,
@@ -503,6 +509,7 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
tBTA_GATTC_DATA gattc_data;
BOOLEAN found_app = FALSE;
tGATT_TCB *p_tcb;
+ tBTM_SEC_DEV_REC *p_dev_rec = NULL;
if (!p_clcb || !p_data) {
return;
@@ -512,6 +519,33 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
if(p_tcb) {
found_app = gatt_find_specific_app_in_hold_link(p_tcb, p_clcb->p_rcb->client_if);
}
+
+ if (p_data->api_conn.phy_mask) {
+ p_dev_rec = btm_find_or_alloc_dev(p_data->api_conn.remote_bda);
+ if (p_dev_rec) {
+ if (p_data->api_conn.is_aux) {
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ p_dev_rec->ext_conn_params.phy_mask = p_data->api_conn.phy_mask;
+ if (p_data->api_conn.phy_mask & BTA_BLE_PHY_1M_MASK) {
+ memcpy(&p_dev_rec->ext_conn_params.phy_1m_conn_params, &p_data->api_conn.phy_1m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
+ }
+ if (p_data->api_conn.phy_mask & BTA_BLE_PHY_2M_MASK) {
+ memcpy(&p_dev_rec->ext_conn_params.phy_2m_conn_params, &p_data->api_conn.phy_2m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
+ }
+ if (p_data->api_conn.phy_mask & BTA_BLE_PHY_CODED_MASK) {
+ memcpy(&p_dev_rec->ext_conn_params.phy_coded_conn_params, &p_data->api_conn.phy_coded_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
+ }
+#endif
+ } else {
+ if (p_data->api_conn.phy_mask & BTA_BLE_PHY_1M_MASK) {
+ memcpy(&p_dev_rec->conn_params, &p_data->api_conn.phy_1m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
+ }
+ }
+ } else {
+ APPL_TRACE_ERROR("Unknown Device, setting rejected");
+ }
+ }
+
/* open/hold a connection */
if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, p_data->api_conn.remote_addr_type,
TRUE, p_data->api_conn.transport, p_data->api_conn.is_aux)) {
@@ -841,6 +875,9 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
(* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
}
+ // Please note that BTA_GATTC_CLOSE_EVT will run in the BTC task.
+ // because bta_gattc_deregister_cmpl did not execute as expected(this is a known issue),
+ // we will run it again in bta_gattc_clcb_dealloc_by_conn_id.
if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
bta_gattc_deregister_cmpl(p_clreg);
}
@@ -1672,7 +1709,7 @@ void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
** Returns void
**
*******************************************************************************/
-static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
+void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
{
tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
tBTA_GATTC_IF client_if = p_clreg->client_if;
@@ -1804,8 +1841,8 @@ static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
*******************************************************************************/
void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
{
- tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
- tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
+ tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_refresh.remote_bda);
+ tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
BOOLEAN found = FALSE;
UINT8 i;
UNUSED(p_cb);
@@ -1925,7 +1962,7 @@ void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_D
*******************************************************************************/
void bta_gattc_process_api_cache_clean(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
{
- tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
+ tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_clean.remote_bda);
UNUSED(p_cb);
if (p_srvc_cb != NULL && p_srvc_cb->p_srvc_cache != NULL) {
@@ -2118,7 +2155,7 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL
bta_gattc_proc_other_indication(p_clcb, op, p_data, &notify);
}
} else if (op == GATTC_OPTYPE_INDICATION) {
- /* no one intersted and need ack? */
+ /* no one interested and need ack? */
APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
GATTC_SendHandleValueConfirm(conn_id, handle);
}
@@ -2235,7 +2272,7 @@ static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYP
**
** Function bta_gattc_init_clcb_conn
**
-** Description Initaite a BTA CLCB connection
+** Description Initiate a BTA CLCB connection
**
** Returns void
**
@@ -2252,7 +2289,7 @@ void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
return;
}
- /* initaite a new connection here */
+ /* initiate a new connection here */
if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) {
gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
@@ -2289,92 +2326,6 @@ void bta_gattc_process_listen_all(UINT8 cif)
}
}
}
-/*******************************************************************************
-**
-** Function bta_gattc_listen
-**
-** Description Start or stop a listen for connection
-**
-** Returns void
-**
-********************************************************************************/
-void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
-{
- tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
- tBTA_GATTC cb_data;
- UNUSED(p_cb);
-
- cb_data.reg_oper.status = BTA_GATT_ERROR;
- cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
-
- if (p_clreg == NULL) {
- APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
- p_msg->api_listen.client_if);
- return;
- }
- /* mark bg conn record */
- if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
- (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
- p_msg->api_listen.start,
- TRUE)) {
- if (!GATT_Listen(p_msg->api_listen.client_if,
- p_msg->api_listen.start,
- p_msg->api_listen.remote_bda)) {
- APPL_TRACE_ERROR("Listen failure");
- (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
- } else {
- cb_data.status = BTA_GATT_OK;
-
- (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
-
- if (p_msg->api_listen.start) {
- /* if listen to a specific target */
- if (p_msg->api_listen.remote_bda != NULL) {
-
- /* if is a connected remote device */
- if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
- bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
- p_msg->api_listen.remote_bda,
- BTA_GATT_TRANSPORT_LE) == NULL) {
-
- bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
- p_msg->api_listen.remote_bda);
- }
- }
- /* if listen to all */
- else {
- APPL_TRACE_DEBUG("Listen For All now");
- /* go through all connected device and send
- callback for all connected slave connection */
- bta_gattc_process_listen_all(p_msg->api_listen.client_if);
- }
- }
- }
- }
-}
-
-/*******************************************************************************
-**
-** Function bta_gattc_broadcast
-**
-** Description Start or stop broadcasting
-**
-** Returns void
-**
-********************************************************************************/
-void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
-{
- tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
- tBTA_GATTC cb_data;
- UNUSED(p_cb);
-
- cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
- cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL);
- //TODO need modify callback if used
- if (p_clreg && p_clreg->p_cback) {
- (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
- }
-}
/*******************************************************************************
**
diff --git a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_api.c b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_api.c
index 6e2586d6..8ac0ec4c 100644
--- a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_api.c
+++ b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_api.c
@@ -128,7 +128,7 @@ void BTA_GATTC_AppDeregister(tBTA_GATTC_IF client_if)
/*******************************************************************************
**
-** Function BTA_GATTC_Open
+** Function BTA_GATTC_Enh_Open
**
** Description Open a direct connection or add a background auto connection
** bd address
@@ -142,8 +142,10 @@ void BTA_GATTC_AppDeregister(tBTA_GATTC_IF client_if)
** Returns void
**
*******************************************************************************/
-void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE remote_addr_type,
- BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport, BOOLEAN is_aux)
+void BTA_GATTC_Enh_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE remote_addr_type,
+ BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport, BOOLEAN is_aux, tBTA_ADDR_TYPE own_addr_type,
+ UINT8 phy_mask, tBTA_BLE_CONN_PARAMS *phy_1m_conn_params, tBTA_BLE_CONN_PARAMS *phy_2m_conn_params,
+ tBTA_BLE_CONN_PARAMS *phy_coded_conn_params)
{
tBTA_GATTC_API_OPEN *p_buf;
@@ -155,8 +157,18 @@ void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE
p_buf->transport = transport;
p_buf->is_aux = is_aux;
p_buf->remote_addr_type = remote_addr_type;
+ p_buf->own_addr_type = own_addr_type;
+ p_buf->phy_mask = phy_mask;
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
-
+ if ((phy_mask & BTA_BLE_PHY_1M_MASK) && phy_1m_conn_params) {
+ memcpy(&p_buf->phy_1m_conn_params, phy_1m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
+ }
+ if ((phy_mask & BTA_BLE_PHY_2M_MASK) && phy_2m_conn_params) {
+ memcpy(&p_buf->phy_2m_conn_params, phy_2m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
+ }
+ if ((phy_mask & BTA_BLE_PHY_CODED_MASK) && phy_coded_conn_params) {
+ memcpy(&p_buf->phy_coded_conn_params, phy_coded_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
+ }
bta_sys_sendmsg(p_buf);
}
@@ -472,7 +484,7 @@ void BTA_GATTC_GetGattDb(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle
** Description This function is called to read a characteristics value
**
** Parameters conn_id - connection ID.
-** handle - characteritic handle to read.
+** handle - characteristic handle to read.
**
** Returns None
**
@@ -607,7 +619,7 @@ void BTA_GATTC_ReadMultipleVariable(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_mul
**
** Parameters conn_id - connection ID.
** s_handle - start handle.
-** e_handle - end hanle
+** e_handle - end handle
** uuid - The attribute UUID.
**
** Returns None
@@ -687,7 +699,7 @@ void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
** Description This function is called to write descriptor value.
**
** Parameters conn_id - connection ID
-** handle - descriptor hadle to write.
+** handle - descriptor handle to write.
** write_type - write type.
** p_value - the value to be written.
**
@@ -738,7 +750,7 @@ void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
** Description This function is called to prepare write a characteristic value.
**
** Parameters conn_id - connection ID.
-** p_char_id - GATT characteritic ID of the service.
+** p_char_id - GATT characteristic ID of the service.
** offset - offset of the write value.
** len: length of the data to be written.
** p_value - the value to be written.
@@ -781,7 +793,7 @@ void BTA_GATTC_PrepareWrite (UINT16 conn_id, UINT16 handle,
** Description This function is called to prepare write a characteristic descriptor value.
**
** Parameters conn_id - connection ID.
-** p_char_descr_id - GATT characteritic descriptor ID of the service.
+** p_char_descr_id - GATT characteristic descriptor ID of the service.
** offset - offset of the write value.
** len: length of the data to be written.
** p_value - the value to be written.
@@ -1010,9 +1022,9 @@ void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash)
if(bta_sys_is_register(BTA_ID_GATTC) == FALSE) {
return;
}
- tBTA_GATTC_API_OPEN *p_buf;
+ tBTA_GATTC_API_CACHE_REFRESH *p_buf;
- if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) {
+ if ((p_buf = (tBTA_GATTC_API_CACHE_REFRESH *) osi_malloc(sizeof(tBTA_GATTC_API_CACHE_REFRESH))) != NULL) {
p_buf->hdr.event = BTA_GATTC_API_REFRESH_EVT;
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
@@ -1068,9 +1080,9 @@ void BTA_GATTC_Clean(BD_ADDR remote_bda)
bta_gattc_cache_reset(remote_bda);
#endif
- tBTA_GATTC_API_OPEN *p_buf;
+ tBTA_GATTC_API_CACHE_CLEAN *p_buf;
- if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) {
+ if ((p_buf = (tBTA_GATTC_API_CACHE_CLEAN *) osi_malloc(sizeof(tBTA_GATTC_API_CACHE_CLEAN))) != NULL) {
p_buf->hdr.event = BTA_GATTC_API_CACHE_CLEAN_EVT;
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
@@ -1078,66 +1090,6 @@ void BTA_GATTC_Clean(BD_ADDR remote_bda)
}
return;
}
-/*******************************************************************************
-**
-** Function BTA_GATTC_Listen
-**
-** Description Start advertisement to listen for connection request for a GATT
-** client application.
-**
-** Parameters client_if: server interface.
-** start: to start or stop listening for connection
-** remote_bda: remote device BD address, if listen to all device
-** use NULL.
-**
-** Returns void
-**
-*******************************************************************************/
-void BTA_GATTC_Listen(tBTA_GATTC_IF client_if, BOOLEAN start, BD_ADDR_PTR target_bda)
-{
- tBTA_GATTC_API_LISTEN *p_buf;
-
- if ((p_buf = (tBTA_GATTC_API_LISTEN *) osi_malloc((UINT16)(sizeof(tBTA_GATTC_API_LISTEN) + BD_ADDR_LEN))) != NULL) {
- p_buf->hdr.event = BTA_GATTC_API_LISTEN_EVT;
-
- p_buf->client_if = client_if;
- p_buf->start = start;
- if (target_bda) {
- p_buf->remote_bda = (UINT8 *)(p_buf + 1);
- memcpy(p_buf->remote_bda, target_bda, BD_ADDR_LEN);
- } else {
- p_buf->remote_bda = NULL;
- }
-
- bta_sys_sendmsg(p_buf);
- }
- return;
-}
-
-/*******************************************************************************
-**
-** Function BTA_GATTC_Broadcast
-**
-** Description Start broadcasting (non-connectable advertisements)
-**
-** Parameters client_if: client interface.
-** start: to start or stop listening for connection
-**
-** Returns void
-**
-*******************************************************************************/
-void BTA_GATTC_Broadcast(tBTA_GATTC_IF client_if, BOOLEAN start)
-{
- tBTA_GATTC_API_LISTEN *p_buf;
-
- if ((p_buf = (tBTA_GATTC_API_LISTEN *) osi_malloc((UINT16)(sizeof(tBTA_GATTC_API_LISTEN) + BD_ADDR_LEN))) != NULL) {
- p_buf->hdr.event = BTA_GATTC_API_BROADCAST_EVT;
- p_buf->client_if = client_if;
- p_buf->start = start;
- bta_sys_sendmsg(p_buf);
- }
- return;
-}
/* Add For BLE PTS */
uint8_t BTA_GATTC_AutoDiscoverEnable(uint8_t enable)
diff --git a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_main.c b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_main.c
index 0cc55995..c1d1e720 100644
--- a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_main.c
+++ b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_main.c
@@ -381,15 +381,6 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
case BTA_GATTC_API_CACHE_CLEAN_EVT:
bta_gattc_process_api_cache_clean(p_cb, (tBTA_GATTC_DATA *) p_msg);
break;
-#if BLE_INCLUDED == TRUE
- case BTA_GATTC_API_LISTEN_EVT:
- bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
- break;
- case BTA_GATTC_API_BROADCAST_EVT:
- bta_gattc_broadcast(p_cb, (tBTA_GATTC_DATA *) p_msg);
- break;
-#endif
-
case BTA_GATTC_ENC_CMPL_EVT:
bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
break;
@@ -485,8 +476,6 @@ static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code)
return "BTA_GATTC_API_REFRESH_EVT";
case BTA_GATTC_API_CACHE_CLEAN_EVT:
return "BTA_GATTC_API_CACHE_CLEAN_EVT";
- case BTA_GATTC_API_LISTEN_EVT:
- return "BTA_GATTC_API_LISTEN_EVT";
case BTA_GATTC_API_DISABLE_EVT:
return "BTA_GATTC_API_DISABLE_EVT";
case BTA_GATTC_API_CFG_MTU_EVT:
@@ -538,9 +527,14 @@ void bta_gattc_deinit(void)
uint8_t bta_gattc_cl_rcb_active_count(void)
{
uint8_t count = 0;
+ uint8_t dm_gattc_uuid[16];
+
+ // When SDP is included, Bluedroid stack will register the DM GATTC application
+ memset(dm_gattc_uuid, 0x87, 16);
for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i ++) {
- if (bta_gattc_cb.cl_rcb[i].in_use) {
+ if (bta_gattc_cb.cl_rcb[i].in_use &&
+ memcmp(bta_gattc_cb.cl_rcb[i].app_uuid.uu.uuid128, dm_gattc_uuid, 16)) {
count++;
}
}
diff --git a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c
index 2265e282..b47a9d97 100644
--- a/lib/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c
+++ b/lib/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c
@@ -160,7 +160,7 @@ UINT8 bta_gattc_num_reg_app(void)
**
** Function bta_gattc_find_clcb_by_cif
**
-** Description get clcb by client interface and remote bd adddress
+** Description get clcb by client interface and remote bd address
**
** Returns pointer to the clcb
**
@@ -322,12 +322,18 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
}
}
+extern void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id)
{
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
if (p_clcb) {
+ tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
bta_gattc_clcb_dealloc(p_clcb);
+ // there is a workaround: if there is no connect, we will reset it.
+ if (p_clreg && p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
+ bta_gattc_deregister_cmpl(p_clreg);
+ }
}
}
@@ -517,7 +523,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1);
memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len);
} else {
- APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__);
+ APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__);
return FALSE;
}
} else {
@@ -525,7 +531,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA));
memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA));
} else {
- APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__);
+ APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__);
return FALSE;
}
}
@@ -919,7 +925,7 @@ BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
**
** Function bta_gattc_find_int_conn_clcb
**
-** Description try to locate a clcb when an internal connecion event arrives.
+** Description try to locate a clcb when an internal connection event arrives.
**
** Returns pointer to the clcb
**
diff --git a/lib/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/lib/bt/host/bluedroid/bta/gatt/bta_gatts_act.c
index d09eaa96..692c59c6 100644
--- a/lib/bt/host/bluedroid/bta/gatt/bta_gatts_act.c
+++ b/lib/bt/host/bluedroid/bta/gatt/bta_gatts_act.c
@@ -723,8 +723,6 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
} else {
APPL_TRACE_ERROR("%s, malloc failed", __func__);
}
- } else {
- APPL_TRACE_ERROR("%s, incorrect length", __func__);
}
(*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
if (cb_data.req_data.value != NULL) {
@@ -733,7 +731,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
}
}
} else {
- APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
+ APPL_TRACE_ERROR("Not a registered service attribute ID: 0x%04x",
p_msg->api_indicate.attr_id);
}
}
@@ -886,44 +884,9 @@ void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg)
/*******************************************************************************
**
-** Function bta_gatts_listen
-**
-** Description Start or stop listening for LE connection on a GATT server
-**
-** Returns none.
-**
-*******************************************************************************/
-void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
-{
- tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
- tBTA_GATTS cb_data;
- UNUSED(p_cb);
-
- cb_data.reg_oper.status = BTA_GATT_OK;
- cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
-
- if (p_rcb == NULL) {
- APPL_TRACE_ERROR("Unknown GATTS application");
- return;
- }
-
- if (!GATT_Listen(p_msg->api_listen.server_if,
- p_msg->api_listen.start,
- p_msg->api_listen.remote_bda)) {
- cb_data.status = BTA_GATT_ERROR;
- APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
- }
-
- if (p_rcb->p_cback) {
- (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
- }
-}
-
-/*******************************************************************************
-**
** Function bta_gatts_show_local_database
**
-** Description print loacl service database
+** Description print local service database
**
** Returns none.
**
diff --git a/lib/bt/host/bluedroid/bta/gatt/bta_gatts_api.c b/lib/bt/host/bluedroid/bta/gatt/bta_gatts_api.c
index ffe3abec..4e1f76f6 100644
--- a/lib/bt/host/bluedroid/bta/gatt/bta_gatts_api.c
+++ b/lib/bt/host/bluedroid/bta/gatt/bta_gatts_api.c
@@ -603,43 +603,6 @@ void BTA_GATTS_SendServiceChangeIndication(tBTA_GATTS_IF server_if, BD_ADDR remo
}
-/*******************************************************************************
-**
-** Function BTA_GATTS_Listen
-**
-** Description Start advertisement to listen for connection request for a
-** GATT server
-**
-** Parameters server_if: server interface.
-** start: to start or stop listening for connection
-** remote_bda: remote device BD address, if listen to all device
-** use NULL.
-**
-** Returns void
-**
-*******************************************************************************/
-void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target_bda)
-{
- tBTA_GATTS_API_LISTEN *p_buf;
-
- if ((p_buf = (tBTA_GATTS_API_LISTEN *) osi_malloc((UINT16)(sizeof(tBTA_GATTS_API_LISTEN) + BD_ADDR_LEN))) != NULL) {
- p_buf->hdr.event = BTA_GATTS_API_LISTEN_EVT;
-
- p_buf->server_if = server_if;
- p_buf->start = start;
-
- if (target_bda) {
- p_buf->remote_bda = (UINT8 *)(p_buf + 1);
- memcpy(p_buf->remote_bda, target_bda, BD_ADDR_LEN);
- } else {
- p_buf->remote_bda = NULL;
- }
-
- bta_sys_sendmsg(p_buf);
- }
- return;
-}
-
uint8_t BTA_GATTS_SetServiceChangeMode(uint8_t mode)
{
tGATT_STATUS status;
diff --git a/lib/bt/host/bluedroid/bta/gatt/bta_gatts_main.c b/lib/bt/host/bluedroid/bta/gatt/bta_gatts_main.c
index fe83d151..bf1174c5 100644
--- a/lib/bt/host/bluedroid/bta/gatt/bta_gatts_main.c
+++ b/lib/bt/host/bluedroid/bta/gatt/bta_gatts_main.c
@@ -112,9 +112,6 @@ BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg)
bta_gatts_set_attr_value(p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
break;
}
- case BTA_GATTS_API_LISTEN_EVT:
- bta_gatts_listen(p_cb, (tBTA_GATTS_DATA *) p_msg);
- break;
case BTA_GATTS_API_ADD_INCL_SRVC_EVT:
case BTA_GATTS_API_ADD_CHAR_EVT:
case BTA_GATTS_API_ADD_DESCR_EVT:
diff --git a/lib/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h b/lib/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h
index 108358ca..cb877fcf 100644
--- a/lib/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h
+++ b/lib/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h
@@ -66,8 +66,6 @@ enum {
BTA_GATTC_INT_START_IF_EVT,
BTA_GATTC_API_REG_EVT,
BTA_GATTC_API_DEREG_EVT,
- BTA_GATTC_API_LISTEN_EVT,
- BTA_GATTC_API_BROADCAST_EVT,
BTA_GATTC_API_DISABLE_EVT,
BTA_GATTC_ENC_CMPL_EVT,
BTA_GATTC_API_CACHE_ASSOC_EVT,
@@ -110,7 +108,7 @@ typedef enum {
#define BTA_GATTC_WRITE_PREPARE GATT_WRITE_PREPARE
#define BTA_GATTC_INVALID_HANDLE 0
-/* internal strucutre for GATTC register API */
+/* internal structure for GATTC register API */
typedef struct {
BT_HDR hdr;
tBT_UUID app_uuid;
@@ -133,9 +131,20 @@ typedef struct {
BOOLEAN is_direct;
BOOLEAN is_aux;
tBTA_TRANSPORT transport;
+ tBTA_ADDR_TYPE own_addr_type;
+ UINT8 phy_mask;
+ tBTA_BLE_CONN_PARAMS phy_1m_conn_params;
+ tBTA_BLE_CONN_PARAMS phy_2m_conn_params;
+ tBTA_BLE_CONN_PARAMS phy_coded_conn_params;
} tBTA_GATTC_API_OPEN;
-typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
+typedef struct {
+ BT_HDR hdr;
+ BD_ADDR remote_bda;
+ tBTA_ADDR_TYPE remote_addr_type;
+ tBTA_GATTC_IF client_if;
+ BOOLEAN is_direct;
+} tBTA_GATTC_API_CANCEL_OPEN;
typedef struct {
BT_HDR hdr;
@@ -191,19 +200,16 @@ typedef struct {
}tBTA_GATTC_API_READ_MULTI;
typedef struct {
- BT_HDR hdr;
- BD_ADDR_PTR remote_bda;
- tBTA_GATTC_IF client_if;
- BOOLEAN start;
-} tBTA_GATTC_API_LISTEN;
-
-
-typedef struct {
BT_HDR hdr;
} tBTA_GATTC_API_CFG_MTU;
typedef struct {
BT_HDR hdr;
+ BD_ADDR remote_bda;
+} tBTA_GATTC_API_CACHE_REFRESH;
+
+typedef struct {
+ BT_HDR hdr;
tBTA_GATTC_IF client_if;
BD_ADDR src_addr;
BD_ADDR assoc_addr;
@@ -216,6 +222,11 @@ typedef struct {
} tBTA_GATTC_API_GET_ADDR;
typedef struct {
+ BT_HDR hdr;
+ BD_ADDR remote_bda;
+} tBTA_GATTC_API_CACHE_CLEAN;
+
+typedef struct {
BT_HDR hdr;
BD_ADDR remote_bda;
tBTA_GATTC_IF client_if;
@@ -247,16 +258,16 @@ typedef union {
tBTA_GATTC_API_EXEC api_exec;
tBTA_GATTC_API_READ_MULTI api_read_multi;
tBTA_GATTC_API_CFG_MTU api_mtu;
+ tBTA_GATTC_API_CACHE_REFRESH api_refresh;
tBTA_GATTC_API_CACHE_ASSOC api_assoc;
tBTA_GATTC_API_GET_ADDR api_get_addr;
+ tBTA_GATTC_API_CACHE_CLEAN api_clean;
tBTA_GATTC_OP_CMPL op_cmpl;
tBTA_GATTC_INT_CONN int_conn;
tBTA_GATTC_ENC_CMPL enc_cmpl;
tBTA_GATTC_INT_START_IF int_start_if;
tBTA_GATTC_INT_DEREG int_dereg;
- /* if peripheral role is supported */
- tBTA_GATTC_API_LISTEN api_listen;
} tBTA_GATTC_DATA;
@@ -313,7 +324,7 @@ typedef struct {
UINT16 total_char;
UINT16 total_attr;
UINT8 srvc_hdl_chg; /* service handle change indication pending */
- UINT16 attr_index; /* cahce NV saving/loading attribute index */
+ UINT16 attr_index; /* cache NV saving/loading attribute index */
UINT16 mtu;
bool update_incl_srvc;
@@ -484,10 +495,6 @@ extern void bta_gattc_process_api_cache_clean(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DA
extern void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
extern void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
-#if BLE_INCLUDED == TRUE
-extern void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
-extern void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
-#endif
/* utility functions */
extern tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
extern tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_conn_id (UINT16 conn_id);
diff --git a/lib/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h b/lib/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h
index 51d6fd4e..854a28a2 100644
--- a/lib/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h
+++ b/lib/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h
@@ -51,7 +51,6 @@ enum {
BTA_GATTS_API_OPEN_EVT,
BTA_GATTS_API_CANCEL_OPEN_EVT,
BTA_GATTS_API_CLOSE_EVT,
- BTA_GATTS_API_LISTEN_EVT,
BTA_GATTS_API_DISABLE_EVT,
BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT,
BTA_GATTS_API_SHOW_LOCAL_DATABASE_EVT
@@ -64,7 +63,7 @@ typedef UINT16 tBTA_GATTS_INT_EVT;
/* max number of services allowed in the device */
#define BTA_GATTS_MAX_SRVC_NUM GATT_MAX_SR_PROFILES
-/* internal strucutre for GATTC register API */
+/* internal structure for GATTC register API */
typedef struct {
BT_HDR hdr;
tBT_UUID app_uuid;
@@ -150,13 +149,6 @@ typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN;
typedef struct {
BT_HDR hdr;
- BD_ADDR_PTR remote_bda;
- tBTA_GATTS_IF server_if;
- BOOLEAN start;
-} tBTA_GATTS_API_LISTEN;
-
-typedef struct {
- BT_HDR hdr;
tBTA_GATTS_IF server_if;
BD_ADDR remote_bda;
} tBTA_GATTS_API_SEND_SERVICE_CHANGE;
@@ -177,8 +169,6 @@ typedef union {
tBTA_GATTS_API_CANCEL_OPEN api_cancel_open;
tBTA_GATTS_INT_START_IF int_start_if;
- /* if peripheral role is supported */
- tBTA_GATTS_API_LISTEN api_listen;
tBTA_GATTS_API_SEND_SERVICE_CHANGE api_send_service_change;
} tBTA_GATTS_DATA;
@@ -250,7 +240,6 @@ extern void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_m
extern void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
-extern void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_show_local_database (void);
diff --git a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c
index 4b1d91ee..331f6595 100644
--- a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c
+++ b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c
@@ -339,6 +339,73 @@ void BTA_AgCiData(UINT16 handle)
bta_sys_sendmsg(p_buf);
}
}
+
+/*******************************************************************************
+**
+** Function BTA_AgAudioBuffAlloc
+**
+** Description Allocate an audio buffer with specific size, reserve enough
+** space and offset for lower layer to send the buffer directly.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_AgAudioBuffAlloc(UINT16 size, UINT8 **pp_buff, UINT8 **pp_data)
+{
+ /* reserve 1 byte at last, when the size is mSBC frame size (57), then we got a buffer that can hold 60 bytes data */
+ BT_HDR *p_buf= (BT_HDR *)osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + BTA_AG_H2_HEADER_LEN + size + 1);
+ if (p_buf != NULL) {
+ /* mSBC offset is large than CVSD, so this is also work in CVSD air mode */
+ p_buf->offset = BTA_AG_BUFF_OFFSET_MIN + BTA_AG_H2_HEADER_LEN;
+ *pp_buff = (UINT8 *)p_buf;
+ *pp_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_AgAudioBuffFree
+**
+** Description Free an audio buffer.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_AgAudioBuffFree(UINT8 *p_buf)
+{
+ osi_free(p_buf);
+}
+
+/*******************************************************************************
+**
+** Function BTA_AgAudioDataSend
+**
+** Description Send audio data to lower level, whether success or not, buffer
+** is consumed.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_AgAudioDataSend(UINT16 handle, UINT8 *p_buff_start, UINT8 *p_data, UINT16 data_len)
+{
+ BT_HDR *p_buf = (BT_HDR *)p_buff_start;
+ tBTA_AG_SCB *p_scb;
+ assert(p_data - (UINT8 *)(p_buf + 1) >= 0);
+ if ((p_scb = bta_ag_scb_by_idx(handle)) != NULL) {
+ p_buf->event = BTA_AG_API_SCO_DATA_SEND_EVT;
+ p_buf->layer_specific = handle;
+ p_buf->offset = p_data - (UINT8 *)(p_buf + 1);
+ p_buf->len = data_len;
+ bta_sys_sendmsg(p_buf);
+ }
+ else {
+ osi_free(p_buf);
+ }
+}
+
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
#endif /* #if (BTA_AG_INCLUDED == TRUE)*/
diff --git a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c
index 6bccfe1b..2cf985c7 100644
--- a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c
+++ b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c
@@ -358,7 +358,7 @@ void bta_hf_ag_bqb_brsf_ctrl(BOOLEAN enable)
#endif /* BT_HF_AG_BQB_INCLUDED */
/*******************************************
-* Funcitons Result
+* Function Results
********************************************/
/*******************************************************************************
**
diff --git a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c
index bcf3cc6e..39daa0de 100644
--- a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c
+++ b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c
@@ -89,6 +89,8 @@ enum
BTA_AG_SETCODEC,
BTA_AG_SEND_RING,
BTA_AG_CI_SCO_DATA,
+ BTA_AG_SCO_DATA_SEND,
+ BTA_AG_SCO_DATA_FREE,
BTA_AG_CI_RX_DATA,
BTA_AG_RCVD_SLC_READY,
BTA_AG_PKT_STAT_NUMS,
@@ -133,6 +135,8 @@ const tBTA_AG_ACTION bta_ag_action[] =
bta_ag_setcodec,
bta_ag_send_ring,
bta_ag_ci_sco_data,
+ bta_ag_sco_data_send,
+ bta_ag_sco_data_free,
bta_ag_ci_rx_data,
bta_ag_rcvd_slc_ready,
bta_ag_pkt_stat_nums
@@ -155,6 +159,7 @@ const UINT8 bta_ag_st_init[][BTA_AG_NUM_COLS] =
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
/* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
/* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
+/* API_SCO_DATA_SEND_EVT */ {BTA_AG_SCO_DATA_FREE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
/* RFC_OPEN_EVT */ {BTA_AG_RFC_ACP_OPEN, BTA_AG_SCO_LISTEN, BTA_AG_OPEN_ST},
/* RFC_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
@@ -185,6 +190,7 @@ const UINT8 bta_ag_st_opening[][BTA_AG_NUM_COLS] =
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
/* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
/* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
+/* API_SCO_DATA_SEND_EVT */ {BTA_AG_SCO_DATA_FREE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
/* RFC_OPEN_EVT */ {BTA_AG_RFC_OPEN, BTA_AG_SCO_LISTEN, BTA_AG_OPEN_ST},
/* RFC_CLOSE_EVT */ {BTA_AG_RFC_FAIL, BTA_AG_IGNORE, BTA_AG_INIT_ST},
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
@@ -215,6 +221,7 @@ const UINT8 bta_ag_st_open[][BTA_AG_NUM_COLS] =
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_SCO_CLOSE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
/* API_RESULT_EVT */ {BTA_AG_RESULT, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
/* API_SETCODEC_EVT */ {BTA_AG_SETCODEC, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
+/* API_SCO_DATA_SEND_EVT */ {BTA_AG_SCO_DATA_SEND, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
/* RFC_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
/* RFC_CLOSE_EVT */ {BTA_AG_RFC_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
@@ -245,6 +252,7 @@ const UINT8 bta_ag_st_closing[][BTA_AG_NUM_COLS] =
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
/* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
/* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
+/* API_SCO_DATA_SEND_EVT */ {BTA_AG_SCO_DATA_FREE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
/* RFC_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
/* RFC_CLOSE_EVT */ {BTA_AG_RFC_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
@@ -360,9 +368,9 @@ static char *bta_ag_evt_str(UINT16 event, tBTA_AG_RES result)
case BTA_AG_API_DISABLE_EVT:
return "Disable AG";
case BTA_AG_CI_SCO_DATA_EVT:
- return "SCO data Callin";
+ return "SCO data Call In";
case BTA_AG_CI_SLC_READY_EVT:
- return "SLC Ready Callin";
+ return "SLC Ready Call In";
case BTA_AG_PKT_STAT_NUMS_GET_EVT:
return "Get Packet Nums";
default:
@@ -433,6 +441,7 @@ static tBTA_AG_SCB *bta_ag_scb_alloc(void)
#if (BTM_WBS_INCLUDED == TRUE)
p_scb->codec_updated = FALSE;
#endif
+ p_scb->p_sco_data = NULL;
/* set up timers */
p_scb->act_timer.param = (UINT32) p_scb;
p_scb->act_timer.p_cback = bta_ag_timer_cback;
@@ -473,6 +482,10 @@ void bta_ag_scb_dealloc(tBTA_AG_SCB *p_scb)
#if (BTM_WBS_INCLUDED == TRUE)
bta_sys_free_timer(&p_scb->cn_timer);
#endif
+ if (p_scb->p_sco_data != NULL) {
+ osi_free(p_scb->p_sco_data);
+ p_scb->p_sco_data = NULL;
+ }
bta_sys_free_timer(&p_scb->colli_timer);
/* initialize control block */
@@ -774,7 +787,7 @@ static void bta_ag_api_enable(tBTA_AG_DATA *p_data)
bta_ag_cb.scb->negotiated_codec = BTM_SCO_CODEC_CVSD;
}
- /* set deault setting for eSCO/SCO */
+ /* set default setting for eSCO/SCO */
BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
bta_sys_collision_register (BTA_ID_AG, bta_ag_collision_cback);
/* call callback with enable event */
@@ -943,6 +956,7 @@ void bta_ag_sm_execute(tBTA_AG_SCB *p_scb, UINT16 event, tBTA_AG_DATA *p_data)
BOOLEAN bta_ag_hdl_event(BT_HDR *p_msg)
{
tBTA_AG_SCB *p_scb;
+ BOOLEAN free_msg = TRUE;
APPL_TRACE_DEBUG("bta_ag_hdl_event: Event 0x%04x ", p_msg->event);
switch (p_msg->event) {
@@ -966,15 +980,22 @@ BOOLEAN bta_ag_hdl_event(BT_HDR *p_msg)
bta_ag_api_result((tBTA_AG_DATA *) p_msg);
break;
- /* all others reference scb by handle */
+ case BTA_AG_API_SCO_DATA_SEND_EVT:
+ free_msg = FALSE;
+ /* fall through */
default:
+ /* all others reference scb by handle */
if ((p_scb = bta_ag_scb_by_idx(p_msg->layer_specific)) != NULL) {
APPL_TRACE_DEBUG("bta_ag_hdl_event: p_scb 0x%08x ", (unsigned int)p_scb);
bta_ag_sm_execute(p_scb, p_msg->event, (tBTA_AG_DATA *) p_msg);
}
+ else {
+ /* free message if p_scb not found */
+ free_msg = TRUE;
+ }
break;
}
- return TRUE;
+ return free_msg;
}
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c
index 661d2372..f2196c6b 100644
--- a/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c
+++ b/lib/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c
@@ -345,9 +345,10 @@ static void bta_ag_sco_read_cback(UINT16 sco_inx, BT_HDR *p_data, tBTM_SCO_DATA_
APPL_TRACE_DEBUG("bta_ag_sco_read_cback: status(%d)", status);
}
+#if (BTA_HFP_EXT_CODEC == FALSE)
/* Callout function must free the data. */
bta_ag_sco_co_in_data(p_data, status);
- osi_free(p_data);
+#endif
}
#endif
/*******************************************************************************
@@ -459,6 +460,37 @@ static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *p
}
}
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+
+/*******************************************************************************
+**
+** Function bta_ag_sco_get_frame_size
+**
+** Description Get SCO frame size.
+**
+**
+** Returns SCO frame size
+**
+*******************************************************************************/
+static UINT16 bta_ag_sco_get_frame_size(tBTA_AG_SCB *p_scb)
+{
+ UINT16 frame_size = 0;
+ switch (p_scb->air_mode)
+ {
+ case BTM_SCO_AIR_MODE_CVSD:
+ frame_size = p_scb->out_pkt_len;
+ break;
+ case BTM_SCO_AIR_MODE_TRANSPNT:
+ frame_size = BTA_AG_MSBC_FRAME_SIZE;
+ break;
+ default:
+ break;
+ }
+ return frame_size;
+}
+
+#endif
+
/*******************************************************************************
**
** Function bta_ag_cback_sco
@@ -471,14 +503,19 @@ static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *p
*******************************************************************************/
static void bta_ag_cback_sco(tBTA_AG_SCB *p_scb, UINT8 event)
{
- tBTA_AG_HDR sco;
-
- sco.handle = bta_ag_scb_to_idx(p_scb);
- sco.app_id = p_scb->app_id;
- sco.sync_conn_handle = BTM_ReadScoHandle(p_scb->sco_idx);
+ tBTA_AG_AUDIO_STAT audio_stat = {0};
+
+ audio_stat.hdr.handle = bta_ag_scb_to_idx(p_scb);
+ audio_stat.hdr.app_id = p_scb->app_id;
+ audio_stat.hdr.sync_conn_handle = BTM_ReadScoHandle(p_scb->sco_idx);
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+ if (event != BTA_AG_AUDIO_CLOSE_EVT) {
+ audio_stat.preferred_frame_size = bta_ag_sco_get_frame_size(p_scb);
+ }
+#endif
/* call close cback */
- (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &sco);
+ (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &audio_stat);
}
/*******************************************************************************
@@ -784,7 +821,7 @@ static void bta_ag_sco_event(tBTA_AG_SCB *p_scb, UINT8 event)
p_scb->sco_idx, p_sco->state,
bta_ag_sco_state_str(p_sco->state), event, bta_ag_sco_evt_str(event));
-#if (BTM_SCO_HCI_INCLUDED == TRUE)
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == FALSE)
BT_HDR *p_buf;
if (event == BTA_AG_SCO_CI_DATA_E)
{
@@ -1633,6 +1670,11 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
}
+ if (p_scb->p_sco_data != NULL) {
+ osi_free(p_scb->p_sco_data);
+ p_scb->p_sco_data = NULL;
+ }
+
/* call app callback */
bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
#if (BTM_WBS_INCLUDED == TRUE)
@@ -1665,7 +1707,7 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data
bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST)
{
- /* If script overrided sco parameter by BTA_CMD_SET_ESCO_PARAM */
+ /* If script override sco parameter by BTA_CMD_SET_ESCO_PARAM */
if (bta_ag_cb.sco.param_updated)
{
resp = bta_ag_cb.sco.params;
@@ -1736,7 +1778,7 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data
**
** Function bta_ag_ci_sco_data
**
-** Description Process the SCO data ready callin event
+** Description Process the SCO data ready call in event
**
**
** Returns void
@@ -1752,6 +1794,288 @@ void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
#endif
}
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+
+/*******************************************************************************
+**
+** Function bta_ag_write_sco_data
+**
+** Description Write two SCO data buffers to specified instance
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_ag_write_sco_data(tBTA_AG_SCB *p_scb, BT_HDR *p_buf1, BT_HDR *p_buf2)
+{
+ BTM_WriteScoData(p_scb->sco_idx, p_buf1);
+ if (p_buf2 != NULL) {
+ BTM_WriteScoData(p_scb->sco_idx, p_buf2);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_ag_sco_data_send_cvsd
+**
+** Description Process SCO data of CVSD air mode
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_ag_sco_data_send_cvsd(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
+{
+ UINT16 out_pkt_len = p_scb->out_pkt_len;
+
+ if (p_scb->p_sco_data != NULL) {
+ /* the remaining data of last sending operation */
+ BT_HDR *p_buf_last = p_scb->p_sco_data;
+ /* remaining data len should small than out_pkt_len */
+ assert(p_buf_last->len < out_pkt_len);
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + out_pkt_len);
+ if (p_buf2 == NULL) {
+ osi_free(p_buf);
+ osi_free(p_buf_last);
+ p_scb->p_sco_data = NULL;
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ return;
+ }
+ p_buf2->offset = BTA_AG_BUFF_OFFSET_MIN;
+ UINT8 *p_data = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ memcpy(p_data, (UINT8 *)(p_buf_last + 1) + p_buf_last->offset, p_buf_last->len);
+
+ if (p_buf->len + p_buf_last->len < out_pkt_len) {
+ memcpy(p_data + p_buf_last->len, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
+ p_buf2->len = p_buf->len + p_buf_last->len;
+ osi_free(p_buf);
+ osi_free(p_buf_last);
+ p_scb->p_sco_data = p_buf2;
+ }
+ else {
+ UINT16 copy_len = out_pkt_len - p_buf_last->len;
+ memcpy(p_data + p_buf_last->len, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len);
+ p_buf2->len = out_pkt_len;
+ p_buf->offset += copy_len;
+ p_buf->len -= copy_len;
+ osi_free(p_buf_last);
+ p_scb->p_sco_data = NULL;
+ bta_ag_write_sco_data(p_scb, p_buf2, NULL);
+
+ if (p_buf->len == 0) {
+ osi_free(p_buf);
+ }
+ else {
+ /* recursive call, this will only called once */
+ bta_ag_sco_data_send_cvsd(p_scb, p_buf);
+ }
+ }
+ }
+ else if (p_buf->len < out_pkt_len) {
+ p_scb->p_sco_data = p_buf;
+ }
+ else {
+ /* p_scb->p_sco_data != NULL && p_buf->len >= out_pkt_len */
+ while (1) {
+ if (p_buf->len == out_pkt_len) {
+ bta_ag_write_sco_data(p_scb, p_buf, NULL);
+ break;
+ }
+ else {
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + out_pkt_len);
+ if (p_buf2 == NULL) {
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ return;
+ }
+ p_buf2->offset = BTA_AG_BUFF_OFFSET_MIN;
+ UINT8 *p_data = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ memcpy(p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, out_pkt_len);
+ p_buf2->len = out_pkt_len;
+ p_buf->offset += out_pkt_len;
+ p_buf->len -= out_pkt_len;
+ bta_ag_write_sco_data(p_scb, p_buf2, NULL);
+ }
+ if (p_buf->len < out_pkt_len) {
+ p_scb->p_sco_data = p_buf;
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_ag_sco_data_send_msbc
+**
+** Description Process SCO data of mSBC air mode
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_ag_sco_data_send_msbc(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
+{
+ UINT16 out_pkt_len = p_scb->out_pkt_len;
+ if (p_buf->len == BTA_AG_MSBC_FRAME_SIZE && p_buf->offset >= BTA_AG_BUFF_OFFSET_MIN + BTA_AG_H2_HEADER_LEN) {
+ /* add H2 header */
+ p_buf->offset -= BTA_AG_H2_HEADER_LEN;
+ UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ bta_ag_h2_header((UINT16 *)p_data);
+ /* add header len, add addition one bytes, the len is BTA_AG_SCO_OUT_PKT_LEN_2EV3 now */
+ p_buf->len += BTA_AG_H2_HEADER_LEN + 1;
+
+ if (out_pkt_len == BTA_AG_SCO_OUT_PKT_LEN_2EV3) {
+ /* mSBC frame can be send directly */
+ bta_ag_write_sco_data(p_scb, p_buf, NULL);
+ }
+ else if (out_pkt_len == BTA_AG_SCO_OUT_PKT_LEN_EV3) {
+ /* need to split into 2 sco packages for sending */
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + BTA_AG_SCO_OUT_PKT_LEN_EV3);
+ if (p_buf2 == NULL) {
+ /* free the first buff too */
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ return;
+ }
+ p_buf2->offset = BTA_AG_BUFF_OFFSET_MIN;
+ p_buf2->len = BTA_AG_SCO_OUT_PKT_LEN_EV3;
+ UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ memcpy(p_data2, p_data + BTA_AG_SCO_OUT_PKT_LEN_EV3, BTA_AG_SCO_OUT_PKT_LEN_EV3);
+ /* update the first packet len */
+ p_buf->len = BTA_AG_SCO_OUT_PKT_LEN_EV3;
+ bta_ag_write_sco_data(p_scb, p_buf, p_buf2);
+ }
+ else {
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s, invalid out pkt len: %d", __FUNCTION__, out_pkt_len);
+ }
+ }
+ else if (p_buf->len != 0 && p_buf->len % BTA_AG_MSBC_FRAME_SIZE == 0) {
+ /* multiple mSBC frame in the buffer, or just one but offset is too small */
+ UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ UINT16 total_len = p_buf->len;
+ if (out_pkt_len == BTA_AG_SCO_OUT_PKT_LEN_2EV3) {
+ while (total_len != 0) {
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + BTA_AG_SCO_OUT_PKT_LEN_2EV3);
+ if (p_buf2 == NULL) {
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ break;
+ }
+ p_buf2->offset = BTA_AG_BUFF_OFFSET_MIN;
+ p_buf2->len = BTA_AG_SCO_OUT_PKT_LEN_2EV3;
+ UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ bta_ag_h2_header((UINT16 *)p_data2);
+ p_data2 += BTA_AG_H2_HEADER_LEN;
+ memcpy(p_data2, p_data, BTA_AG_MSBC_FRAME_SIZE);
+ p_data += BTA_AG_MSBC_FRAME_SIZE;
+ total_len -= BTA_AG_MSBC_FRAME_SIZE;
+ bta_ag_write_sco_data(p_scb, p_buf2, NULL);
+ }
+ }
+ else if (out_pkt_len == BTA_AG_SCO_OUT_PKT_LEN_EV3) {
+ while (total_len != 0) {
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + BTA_AG_SCO_OUT_PKT_LEN_EV3);
+ if (p_buf2 == NULL) {
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ break;
+ }
+ BT_HDR *p_buf3 = osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + BTA_AG_SCO_OUT_PKT_LEN_EV3);
+ if (p_buf3 == NULL) {
+ /* free the first buff too */
+ osi_free(p_buf2);
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ break;
+ }
+
+ /* build first packet, include H2 header */
+ p_buf2->offset = BTA_AG_BUFF_OFFSET_MIN;
+ p_buf2->len = BTA_AG_SCO_OUT_PKT_LEN_EV3;
+ UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ bta_ag_h2_header((UINT16 *)p_data2);
+ p_data2 += BTA_AG_H2_HEADER_LEN;
+ memcpy(p_data2, p_data, BTA_AG_SCO_OUT_PKT_LEN_EV3 - BTA_AG_H2_HEADER_LEN);
+ p_data += BTA_AG_SCO_OUT_PKT_LEN_EV3 - BTA_AG_H2_HEADER_LEN;
+ total_len -= BTA_AG_SCO_OUT_PKT_LEN_EV3 - BTA_AG_H2_HEADER_LEN;
+
+ /* build second packet, not include header */
+ p_buf3->offset = BTA_AG_BUFF_OFFSET_MIN;
+ p_buf3->len = BTA_AG_SCO_OUT_PKT_LEN_EV3;
+ UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
+ memcpy(p_data3, p_data, BTA_AG_MSBC_FRAME_SIZE - BTA_AG_H2_HEADER_LEN - BTA_AG_SCO_OUT_PKT_LEN_EV3);
+ p_data += BTA_AG_MSBC_FRAME_SIZE - BTA_AG_H2_HEADER_LEN - BTA_AG_SCO_OUT_PKT_LEN_EV3;
+ total_len -= BTA_AG_MSBC_FRAME_SIZE - BTA_AG_H2_HEADER_LEN - BTA_AG_SCO_OUT_PKT_LEN_EV3;
+ bta_ag_write_sco_data(p_scb, p_buf2, p_buf3);
+ }
+ }
+ else {
+ APPL_TRACE_WARNING("%s, invalid out pkt len: %d", __FUNCTION__, out_pkt_len);
+ }
+ osi_free(p_buf);
+ }
+ else {
+ APPL_TRACE_WARNING("%s, unaccepted data len: %d", __FUNCTION__, p_buf->len);
+ osi_free(p_buf);
+ }
+}
+
+#endif
+
+/*******************************************************************************
+**
+** Function bta_ag_sco_data_send
+**
+** Description Route SCO data to specific processing function based on air mode
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_ag_sco_data_send(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
+{
+ BT_HDR *p_buf = (BT_HDR *) p_data;
+
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+ if (bta_ag_cb.sco.state != BTA_AG_SCO_OPEN_ST || bta_ag_cb.sco.cur_idx != p_scb->sco_idx) {
+ osi_free(p_data);
+ APPL_TRACE_WARNING("%s: SCO invalid state", __FUNCTION__);
+ return;
+ }
+
+ switch (p_scb->air_mode)
+ {
+ case BTM_SCO_AIR_MODE_CVSD:
+ bta_ag_sco_data_send_cvsd(p_scb, p_buf);
+ break;
+ case BTM_SCO_AIR_MODE_TRANSPNT:
+ bta_ag_sco_data_send_msbc(p_scb, p_buf);
+ break;
+ default:
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s: unsupported air mode: %d", __FUNCTION__, p_scb->air_mode);
+ break;
+ }
+#else
+ osi_free(p_buf);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function bta_ag_sco_data_free
+**
+** Description Free SCO data
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_ag_sco_data_free(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
+{
+ UNUSED(p_scb);
+ osi_free(p_data);
+}
+
/*******************************************************************************
**
** Function bta_ag_set_esco_param
diff --git a/lib/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h b/lib/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h
index 9ced8b36..c8b7be36 100644
--- a/lib/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h
+++ b/lib/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h
@@ -96,6 +96,19 @@
BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \
BTA_AG_FEAT_VTAG)
+#if (BTM_SCO_HCI_INCLUDED == TRUE)
+/* 1 (offset can not be 0) + HCI_SCO_PREAMBLE */
+#define BTA_AG_BUFF_OFFSET_MIN (1 + HCI_SCO_PREAMBLE_SIZE)
+/* mSBC H2 header length */
+#define BTA_AG_H2_HEADER_LEN 2
+/* mSBC frame size not include H1/H2 header */
+#define BTA_AG_MSBC_FRAME_SIZE 57
+/* max user data len of sco packet type EV3 */
+#define BTA_AG_SCO_OUT_PKT_LEN_EV3 30
+/* max user data len of sco packet type 2-EV3 */
+#define BTA_AG_SCO_OUT_PKT_LEN_2EV3 60
+#endif
+
enum
{
/* these events are handled by the state machine */
@@ -107,6 +120,7 @@ enum
BTA_AG_API_AUDIO_CLOSE_EVT,
BTA_AG_API_RESULT_EVT,
BTA_AG_API_SETCODEC_EVT,
+ BTA_AG_API_SCO_DATA_SEND_EVT,
BTA_AG_RFC_OPEN_EVT,
BTA_AG_RFC_CLOSE_EVT,
BTA_AG_RFC_SRV_CLOSE_EVT,
@@ -295,6 +309,7 @@ typedef struct
TIMER_LIST_ENT cn_timer; /* codec negotiation timer */
#endif
UINT16 sco_idx; /* SCO connection index */
+ BT_HDR *p_sco_data; /* remaining SCO data of last sending operation */
BOOLEAN in_use; /* scb in use */
BOOLEAN dealloc; /* TRUE if service shutting down */
BOOLEAN clip_enabled; /* set to TRUE if HF enables CLIP reporting */
@@ -452,10 +467,13 @@ extern void bta_ag_result(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
extern void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
extern void bta_ag_send_ring(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
extern void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
+extern void bta_ag_sco_data_send(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
+extern void bta_ag_sco_data_free(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
extern void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param);
extern void bta_ag_ci_rx_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
extern void bta_ag_rcvd_slc_ready(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
extern void bta_ag_pkt_stat_nums(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
+extern void bta_ag_h2_header(UINT16 *p_buf);
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c
index 0e0c43ad..930f30a5 100644
--- a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c
+++ b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c
@@ -511,7 +511,9 @@ void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data)
break;
}
+ bta_sys_busy(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
bta_hf_client_at_parse(buf, len);
+ bta_sys_idle(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
/* no more data to read, we're done */
if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
diff --git a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c
index 6149d8c4..748d62db 100644
--- a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c
+++ b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c
@@ -44,9 +44,9 @@ static const uint8_t bta_hf_client_cb_data_size[] = {
sizeof(tBTA_HF_CLIENT_OPEN), // #define BTA_HF_CLIENT_OPEN_EVT 2
0, // #define BTA_HF_CLIENT_CLOSE_EVT 3
sizeof(tBTA_HF_CLIENT_CONN), // #define BTA_HF_CLIENT_CONN_EVT 4
- sizeof(tBTA_HF_CLIENT_HDR), // #define BTA_HF_CLIENT_AUDIO_OPEN_EVT 5
- sizeof(tBTA_HF_CLIENT_HDR), //#define BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT 6
- sizeof(tBTA_HF_CLIENT_HDR), // #define BTA_HF_CLIENT_AUDIO_CLOSE_EVT 7
+ sizeof(tBTA_HF_CLIENT_AUDIO_STAT), // #define BTA_HF_CLIENT_AUDIO_OPEN_EVT 5
+ sizeof(tBTA_HF_CLIENT_AUDIO_STAT), // #define BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT 6
+ sizeof(tBTA_HF_CLIENT_AUDIO_STAT), // #define BTA_HF_CLIENT_AUDIO_CLOSE_EVT 7
sizeof(tBTA_HF_CLIENT_VAL), // #define BTA_HF_CLIENT_SPK_EVT 8
sizeof(tBTA_HF_CLIENT_VAL), // #define BTA_HF_CLIENT_MIC_EVT 9
sizeof(tBTA_HF_CLIENT_IND), //#define BTA_HF_CLIENT_IND_EVT 10
@@ -322,6 +322,16 @@ void BTA_HfClientPktStatsNumsGet(UINT16 sync_conn_handle)
}
}
+/*******************************************************************************
+**
+** Function BTA_HfClientCiData
+**
+** Description Send SCO outgoing data ready event
+**
+**
+** Returns void
+**
+*******************************************************************************/
void BTA_HfClientCiData(void)
{
BT_HDR *p_buf;
@@ -330,8 +340,79 @@ void BTA_HfClientCiData(void)
bta_sys_sendmsg(p_buf);
}
}
+
+/*******************************************************************************
+**
+** Function BTA_HfClientAudioBuffAlloc
+**
+** Description Allocate an audio buffer with specific size, reserve enough
+** space and offset for lower layer to send the buffer directly.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_HfClientAudioBuffAlloc(UINT16 size, UINT8 **pp_buff, UINT8 **pp_data)
+{
+ /* reserve 1 byte at last, when the size is mSBC frame size (57), then we got a buffer that can hold 60 bytes data */
+ BT_HDR *p_buf= (BT_HDR *)osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_H2_HEADER_LEN + size + 1);
+ if (p_buf != NULL) {
+ /* mSBC offset is large than CVSD, so this is work in CVSD air mode */
+ p_buf->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_H2_HEADER_LEN;
+ *pp_buff = (UINT8 *)p_buf;
+ *pp_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_HfClientAudioBuffFree
+**
+** Description Free an audio buffer.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_HfClientAudioBuffFree(UINT8 *p_buf)
+{
+ osi_free(p_buf);
+}
+
+/*******************************************************************************
+**
+** Function BTA_HfClientAudioDataSend
+**
+** Description Send audio data to lower layer, whether success or not, buffer
+** is consumed.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_HfClientAudioDataSend(UINT16 sync_conn_hdl, UINT8 *p_buff_start, UINT8 *p_data, UINT16 data_len)
+{
+ /* currently, sync_conn_hdl is not used */
+ BT_HDR *p_buf = (BT_HDR *)p_buff_start;
+ assert(p_data - (UINT8 *)(p_buf + 1) >= 0);
+ p_buf->event = BTA_HF_CLIENT_SCO_DATA_SEND_EVT;
+ p_buf->offset = p_data - (UINT8 *)(p_buf + 1);
+ p_buf->len = data_len;
+ bta_sys_sendmsg(p_buf);
+}
+
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */
+/*******************************************************************************
+**
+** Function BTA_HfClientGetCbDataSize
+**
+** Description Get callback data size of specific event
+**
+**
+** Returns void
+**
+*******************************************************************************/
int BTA_HfClientGetCbDataSize(tBTA_HF_CLIENT_EVT event)
{
return bta_hf_client_cb_data_size[event];
diff --git a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c
index 4124a10f..b87c4869 100644
--- a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c
+++ b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c
@@ -24,6 +24,7 @@
#include "bta/bta_sys.h"
#include "bta/bta_hf_client_api.h"
#include "bta_hf_client_int.h"
+#include "osi/allocator.h"
#if BT_HF_CLIENT_BQB_INCLUDED
static BOOLEAN s_bta_hf_client_bqb_clip_flag = TRUE;
@@ -79,6 +80,8 @@ enum {
BTA_HF_CLIENT_SEND_AT_CMD,
#if (BTM_SCO_HCI_INCLUDED == TRUE)
BTA_HF_CLIENT_CI_SCO_DATA,
+ BTA_HF_CLIENT_SCO_DATA_SEND,
+ BTA_HF_CLIENT_SCO_DATA_FREE,
BTA_HF_CLIENT_PKT_STAT_NUMS,
#endif
BTA_HF_CLIENT_NUM_ACTIONS,
@@ -118,6 +121,8 @@ const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
/* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
#if (BTM_SCO_HCI_INCLUDED == TRUE)
/* BTA_HF_CLIENT_CI_SCO_DATA */ bta_hf_client_ci_sco_data,
+ /* BTA_HF_CLIENT_SCO_DATA_SEND */ bta_hf_client_sco_data_send,
+ /* BTA_HF_CLIENT_SCO_DATA_FREE */ bta_hf_client_sco_data_free,
/* BTA_HF_CLIENT_PKT_STAT_NUMS */ bta_hf_client_pkt_stat_nums,
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
};
@@ -149,6 +154,7 @@ const UINT8 bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
/* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
#if (BTM_SCO_HCI_INCLUDED == TRUE )
/* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
+ /* SCO_DATA_SEND_EVT */ {BTA_HF_CLIENT_SCO_DATA_FREE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
/* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
};
@@ -175,6 +181,7 @@ const UINT8 bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
/* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
#if (BTM_SCO_HCI_INCLUDED == TRUE)
/* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
+ /* SCO_DATA_SEND_EVT */ {BTA_HF_CLIENT_SCO_DATA_FREE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
/* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
};
@@ -201,6 +208,7 @@ const UINT8 bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = {
/* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
#if (BTM_SCO_HCI_INCLUDED == TRUE )
/* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_CI_SCO_DATA, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
+ /* SCO_DATA_SEND_EVT */ {BTA_HF_CLIENT_SCO_DATA_SEND, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
/* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
};
@@ -227,6 +235,7 @@ const UINT8 bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
/* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
#if (BTM_SCO_HCI_INCLUDED == TRUE )
/* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
+ /* SCO_DATA_SEND_EVT */ {BTA_HF_CLIENT_SCO_DATA_FREE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
/* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
};
@@ -284,6 +293,7 @@ void bta_hf_client_scb_init(void)
memset(&bta_hf_client_cb.scb, 0, sizeof(tBTA_HF_CLIENT_SCB));
bta_hf_client_cb.scb.sco_idx = BTM_INVALID_SCO_INDEX;
bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
+ bta_hf_client_cb.scb.p_sco_data = NULL;
}
/*******************************************************************************
@@ -299,6 +309,10 @@ void bta_hf_client_scb_init(void)
void bta_hf_client_scb_disable(void)
{
APPL_TRACE_DEBUG("%s", __FUNCTION__);
+ if (bta_hf_client_cb.scb.p_sco_data != NULL) {
+ osi_free(bta_hf_client_cb.scb.p_sco_data);
+ bta_hf_client_cb.scb.p_sco_data = NULL;
+ }
bta_hf_client_scb_init();
@@ -413,7 +427,11 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
/* check if mSBC support enabled */
if (bta_hf_client_version >= HFP_HF_VERSION_1_6) {
+#if (BTM_WBS_INCLUDED == TRUE)
bta_hf_client_cb.msbc_enabled = TRUE;
+#else
+ bta_hf_client_cb.msbc_enabled = FALSE;
+#endif
} else{
bta_hf_client_cb.msbc_enabled = FALSE;
}
@@ -466,6 +484,7 @@ static void bta_hf_client_api_disable(tBTA_HF_CLIENT_DATA *p_data)
*******************************************************************************/
BOOLEAN bta_hf_client_hdl_event(BT_HDR *p_msg)
{
+ BOOLEAN free_msg = TRUE;
#if BTA_HF_CLIENT_DEBUG == TRUE
APPL_TRACE_DEBUG("bta_hf_client_hdl_event %s (0x%x)", bta_hf_client_evt_str(p_msg->event), p_msg->event);
#endif
@@ -480,12 +499,16 @@ BOOLEAN bta_hf_client_hdl_event(BT_HDR *p_msg)
case BTA_HF_CLIENT_API_DISABLE_EVT:
bta_hf_client_api_disable((tBTA_HF_CLIENT_DATA *) p_msg);
break;
-
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+ case BTA_HF_CLIENT_SCO_DATA_SEND_EVT:
+ free_msg = false;
+ /* fall through */
+#endif
default:
bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA *) p_msg);
break;
}
- return TRUE;
+ return free_msg;
}
/*******************************************************************************
diff --git a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c
index d464a889..11437fb9 100644
--- a/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c
+++ b/lib/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c
@@ -177,6 +177,36 @@ static BOOLEAN bta_hf_client_sco_remove(BOOLEAN only_active)
return removed_started;
}
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+
+/*******************************************************************************
+**
+** Function bta_hf_client_sco_get_frame_size
+**
+** Description Get SCO frame size
+**
+** Returns frame size
+**
+*******************************************************************************/
+static UINT16 bta_hf_client_sco_get_frame_size(void)
+{
+ UINT16 frame_size = 0;
+ switch (bta_hf_client_cb.scb.air_mode)
+ {
+ case BTM_SCO_AIR_MODE_CVSD:
+ frame_size = bta_hf_client_cb.scb.out_pkt_len;
+ break;
+ case BTM_SCO_AIR_MODE_TRANSPNT:
+ frame_size = BTA_HF_CLIENT_MSBC_FRAME_SIZE;
+ break;
+ default:
+ break;
+ }
+ return frame_size;
+}
+
+#endif
+
/*******************************************************************************
**
** Function bta_hf_client_cback_sco
@@ -189,13 +219,17 @@ static BOOLEAN bta_hf_client_sco_remove(BOOLEAN only_active)
*******************************************************************************/
void bta_hf_client_cback_sco(UINT8 event)
{
- tBTA_HF_CLIENT_HDR evt;
-
- memset(&evt, 0, sizeof(evt));
- evt.sync_conn_handle = BTM_ReadScoHandle(bta_hf_client_cb.scb.sco_idx);
+ tBTA_HF_CLIENT_AUDIO_STAT audio_stat;
+ memset(&audio_stat, 0, sizeof(audio_stat));
+ audio_stat.hdr.sync_conn_handle = BTM_ReadScoHandle(bta_hf_client_cb.scb.sco_idx);
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+ if (event != BTA_HF_CLIENT_AUDIO_CLOSE_EVT) {
+ audio_stat.preferred_frame_size = bta_hf_client_sco_get_frame_size();
+ }
+#endif
/* call app cback */
- (*bta_hf_client_cb.p_cback)(event, (tBTA_HF_CLIENT_HDR *) &evt);
+ (*bta_hf_client_cb.p_cback)(event, &audio_stat);
}
#if (BTM_SCO_HCI_INCLUDED == TRUE )
@@ -217,7 +251,6 @@ static void bta_hf_client_sco_read_cback (UINT16 sco_idx, BT_HDR *p_data, tBTM_S
}
bta_hf_client_sco_co_in_data (p_data, status);
- osi_free(p_data);
}
#endif /* BTM_SCO_HCI_INCLUDED */
@@ -307,7 +340,7 @@ void bta_hf_client_pkt_stat_nums(tBTA_HF_CLIENT_DATA *p_data)
**
** Function bta_hf_client_ci_sco_data
**
-** Description Process the SCO data ready callin event
+** Description Process the SCO data ready call in event
**
**
** Returns void
@@ -318,6 +351,281 @@ void bta_hf_client_ci_sco_data(tBTA_HF_CLIENT_DATA *p_data)
UNUSED(p_data);
bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_CI_DATA_E);
}
+
+/*******************************************************************************
+**
+** Function bta_hf_client_write_sco_data
+**
+** Description Write two SCO data buffers to specified instance
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_hf_client_write_sco_data(BT_HDR *p_buf1, BT_HDR *p_buf2)
+{
+ BTM_WriteScoData(bta_hf_client_cb.scb.sco_idx, p_buf1);
+ if (p_buf2 != NULL) {
+ BTM_WriteScoData(bta_hf_client_cb.scb.sco_idx, p_buf2);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hf_client_sco_data_send_cvsd
+**
+** Description Process SCO data of CVSD air mode
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_hf_client_sco_data_send_cvsd(BT_HDR *p_buf, UINT8 out_pkt_len)
+{
+ if (bta_hf_client_cb.scb.p_sco_data != NULL) {
+ /* the remaining data of last sending operation */
+ BT_HDR *p_buf_last = bta_hf_client_cb.scb.p_sco_data;
+ /* remaining data len should small than out_pkt_len */
+ assert(p_buf_last->len < out_pkt_len);
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + out_pkt_len);
+ if (p_buf2 == NULL) {
+ osi_free(p_buf);
+ osi_free(p_buf_last);
+ bta_hf_client_cb.scb.p_sco_data = NULL;
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ return;
+ }
+ p_buf2->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
+
+ UINT8 *p_data = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ memcpy(p_data, (UINT8 *)(p_buf_last + 1) + p_buf_last->offset, p_buf_last->len);
+
+ if (p_buf->len + p_buf_last->len < out_pkt_len) {
+ memcpy(p_data + p_buf_last->len, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
+ p_buf2->len = p_buf->len + p_buf_last->len;
+ osi_free(p_buf);
+ osi_free(p_buf_last);
+ bta_hf_client_cb.scb.p_sco_data = p_buf2;
+ }
+ else {
+ UINT16 copy_len = out_pkt_len - p_buf_last->len;
+ memcpy(p_data + p_buf_last->len, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len);
+ p_buf2->len = out_pkt_len;
+ p_buf->offset += copy_len;
+ p_buf->len -= copy_len;
+ osi_free(p_buf_last);
+ bta_hf_client_cb.scb.p_sco_data = NULL;
+ bta_hf_client_write_sco_data(p_buf2, NULL);
+ if (p_buf->len == 0) {
+ osi_free(p_buf);
+ }
+ else {
+ /* Recursive call, this will only called once */
+ bta_hf_client_sco_data_send_cvsd(p_buf, out_pkt_len);
+ }
+ }
+ }
+ else if (p_buf->len < out_pkt_len) {
+ bta_hf_client_cb.scb.p_sco_data = p_buf;
+ }
+ else {
+ /* bta_hf_client_cb.scb.p_sco_data == NULL && p_buf->len >= out_pkt_len */
+ while (1) {
+ if (p_buf->len == out_pkt_len) {
+ bta_hf_client_write_sco_data(p_buf, NULL);
+ break;
+ }
+ else {
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + out_pkt_len);
+ if (p_buf2 == NULL) {
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ return;
+ }
+ p_buf2->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
+ UINT8 *p_data = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ memcpy(p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, out_pkt_len);
+ p_buf2->len = out_pkt_len;
+ p_buf->offset += out_pkt_len;
+ p_buf->len -= out_pkt_len;
+ bta_hf_client_write_sco_data(p_buf2, NULL);
+ }
+ if (p_buf->len < out_pkt_len) {
+ bta_hf_client_cb.scb.p_sco_data = p_buf;
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hf_client_sco_data_send_msbc
+**
+** Description Process SCO data of mSBC air mode
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_hf_client_sco_data_send_msbc(BT_HDR *p_buf, UINT8 out_pkt_len)
+{
+ if (p_buf->len == BTA_HF_CLIENT_MSBC_FRAME_SIZE && p_buf->offset >= BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_H2_HEADER_LEN) {
+ /* add H2 header */
+ p_buf->offset -= BTA_HF_CLIENT_H2_HEADER_LEN;
+ UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ bta_hf_client_h2_header((UINT16 *)p_data);
+ /* add header len, add addition one bytes, the len is BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3 now */
+ p_buf->len += BTA_HF_CLIENT_H2_HEADER_LEN + 1;
+
+ if (out_pkt_len == BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3) {
+ /* mSBC frame can be send directly */
+ bta_hf_client_write_sco_data(p_buf, NULL);
+ }
+ else if (out_pkt_len == BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3) {
+ /* need to split into 2 sco packages for sending */
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3);
+ if (p_buf2 == NULL) {
+ /* free the first buff too */
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ return;
+ }
+ p_buf2->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
+ p_buf2->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
+ UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ memcpy(p_data2, p_data + BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3, BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3);
+ /* update the first packet len */
+ p_buf->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
+ bta_hf_client_write_sco_data(p_buf, p_buf2);
+ }
+ else {
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s, invalid out pkt len: %d", __FUNCTION__, out_pkt_len);
+ }
+ }
+ else if (p_buf->len != 0 && p_buf->len % BTA_HF_CLIENT_MSBC_FRAME_SIZE == 0) {
+ /* multiple mSBC frame in the buffer, or just one but offset is too small */
+ UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ UINT16 total_len = p_buf->len;
+ if (out_pkt_len == BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3) {
+ while (total_len != 0) {
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3);
+ if (p_buf2 == NULL) {
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ break;
+ }
+ p_buf2->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
+ p_buf2->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3;
+ UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ bta_hf_client_h2_header((UINT16 *)p_data2);
+ p_data2 += BTA_HF_CLIENT_H2_HEADER_LEN;
+ memcpy(p_data2, p_data, BTA_HF_CLIENT_MSBC_FRAME_SIZE);
+ p_data += BTA_HF_CLIENT_MSBC_FRAME_SIZE;
+ total_len -= BTA_HF_CLIENT_MSBC_FRAME_SIZE;
+ bta_hf_client_write_sco_data(p_buf2, NULL);
+ }
+ }
+ else if (out_pkt_len == BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3) {
+ while (total_len != 0) {
+ BT_HDR *p_buf2 = osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3);
+ if (p_buf2 == NULL) {
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ break;
+ }
+ BT_HDR *p_buf3 = osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3);
+ if (p_buf3 == NULL) {
+ /* free the first buff too */
+ osi_free(p_buf2);
+ APPL_TRACE_WARNING("%s, no memory", __FUNCTION__);
+ break;
+ }
+
+ /* build first packet, include H2 header */
+ p_buf2->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
+ p_buf2->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
+ UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
+ bta_hf_client_h2_header((UINT16 *)p_data2);
+ p_data2 += BTA_HF_CLIENT_H2_HEADER_LEN;
+ memcpy(p_data2, p_data, BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 - BTA_HF_CLIENT_H2_HEADER_LEN);
+ p_data += BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 - BTA_HF_CLIENT_H2_HEADER_LEN;
+ total_len -= BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 - BTA_HF_CLIENT_H2_HEADER_LEN;
+
+ /* build second packet, not include header */
+ p_buf3->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
+ p_buf3->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
+ UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
+ memcpy(p_data3, p_data, BTA_HF_CLIENT_MSBC_FRAME_SIZE - BTA_HF_CLIENT_H2_HEADER_LEN - BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3);
+ p_data += BTA_HF_CLIENT_MSBC_FRAME_SIZE - BTA_HF_CLIENT_H2_HEADER_LEN - BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
+ total_len -= BTA_HF_CLIENT_MSBC_FRAME_SIZE - BTA_HF_CLIENT_H2_HEADER_LEN - BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
+ bta_hf_client_write_sco_data(p_buf2, p_buf3);
+ }
+ }
+ else {
+ APPL_TRACE_WARNING("%s, invalid out pkt len: %d", __FUNCTION__, out_pkt_len);
+ }
+ osi_free(p_buf);
+ }
+ else {
+ APPL_TRACE_WARNING("%s, unaccepted data len: %d", __FUNCTION__, p_buf->len);
+ osi_free(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hf_client_sco_data_send
+**
+** Description Route SCO data to specific processing function based on air mode
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hf_client_sco_data_send(tBTA_HF_CLIENT_DATA *p_data)
+{
+ BT_HDR *p_buf = (BT_HDR *) p_data;
+
+ if (bta_hf_client_cb.scb.sco_state != BTA_HF_CLIENT_SCO_OPEN_ST) {
+ osi_free(p_data);
+ APPL_TRACE_WARNING("%s: SCO not open", __FUNCTION__);
+ return;
+ }
+
+ UINT8 out_pkt_len = bta_hf_client_cb.scb.out_pkt_len;
+ UINT8 air_mode = bta_hf_client_cb.scb.air_mode;
+
+ switch (air_mode)
+ {
+ case BTM_SCO_AIR_MODE_CVSD:
+ bta_hf_client_sco_data_send_cvsd(p_buf, out_pkt_len);
+ break;
+ case BTM_SCO_AIR_MODE_TRANSPNT:
+ bta_hf_client_sco_data_send_msbc(p_buf, out_pkt_len);
+ break;
+ default:
+ osi_free(p_buf);
+ APPL_TRACE_WARNING("%s: unsupported air mode: %d", __FUNCTION__, air_mode);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hf_client_sco_data_free
+**
+** Description Free SCO data buffer
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hf_client_sco_data_free(tBTA_HF_CLIENT_DATA *p_data)
+{
+ /* just free the sco data buffer */
+ osi_free(p_data);
+}
+
#endif
/*******************************************************************************
@@ -539,12 +847,9 @@ static void bta_hf_client_sco_event(UINT8 event)
APPL_TRACE_DEBUG("%s state: %d event: %d", __FUNCTION__,
bta_hf_client_cb.scb.sco_state, event);
-#if (BTM_SCO_HCI_INCLUDED == TRUE )
- tBTA_HF_CLIENT_SCB *p_scb = &bta_hf_client_cb.scb;
+#if (BTM_SCO_HCI_INCLUDED == TRUE ) && (BTA_HFP_EXT_CODEC == FALSE)
BT_HDR *p_buf;
-#endif
-
-#if (BTM_SCO_HCI_INCLUDED == TRUE )
+ tBTA_HF_CLIENT_SCB *p_scb = &bta_hf_client_cb.scb;
if (event == BTA_HF_CLIENT_SCO_CI_DATA_E) {
UINT16 pkt_offset = 1 + HCI_SCO_PREAMBLE_SIZE;
UINT16 len_to_send = 0;
@@ -890,6 +1195,11 @@ void bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA *p_data)
bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
+ if (bta_hf_client_cb.scb.p_sco_data != NULL) {
+ osi_free(bta_hf_client_cb.scb.p_sco_data);
+ bta_hf_client_cb.scb.p_sco_data = NULL;
+ }
+
/* call app callback */
bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
diff --git a/lib/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h b/lib/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h
index 0732a96c..d2b34518 100644
--- a/lib/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h
+++ b/lib/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h
@@ -44,6 +44,19 @@
#define BTA_HF_CLIENT_COLLISION_TIMER 2411
#endif
+#if (BTM_SCO_HCI_INCLUDED == TRUE )
+/* 1 (offset can not be 0) + HCI_SCO_PREAMBLE */
+#define BTA_HF_CLIENT_BUFF_OFFSET_MIN (1 + HCI_SCO_PREAMBLE_SIZE)
+/* mSBC H2 header length */
+#define BTA_HF_CLIENT_H2_HEADER_LEN 2
+/* mSBC frame size not include H1/H2 header */
+#define BTA_HF_CLIENT_MSBC_FRAME_SIZE 57
+/* max user data len of sco packet type EV3 */
+#define BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 30
+/* max user data len of sco packet type 2-EV3 */
+#define BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3 60
+#endif
+
enum {
/* these events are handled by the state machine */
BTA_HF_CLIENT_API_REGISTER_EVT = BTA_SYS_EVT_START(BTA_ID_HS),
@@ -65,6 +78,7 @@ enum {
BTA_HF_CLIENT_SEND_AT_CMD_EVT,
#if (BTM_SCO_HCI_INCLUDED == TRUE )
BTA_HF_CLIENT_CI_SCO_DATA_EVT,
+ BTA_HF_CLIENT_SCO_DATA_SEND_EVT,
BTA_HF_CLIENT_PKT_NUMS_GET_EVT,
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
BTA_HF_CLIENT_MAX_EVT,
@@ -138,7 +152,6 @@ typedef union {
tBTA_HF_CLIENT_RFC rfc;
tBTA_HF_CLIENT_DATA_VAL val;
tBTA_HF_CLIENT_PKT_STAT_GET pkt_stat;
-
} tBTA_HF_CLIENT_DATA;
/* type for each service control block */
@@ -158,6 +171,7 @@ typedef struct {
UINT16 sco_idx; /* SCO handle */
UINT8 sco_state; /* SCO state variable */
BOOLEAN sco_close_rfc; /* TRUE if also close RFCOMM after SCO */
+ BT_HDR *p_sco_data; /* remaining SCO data of last sending operation */
BOOLEAN retry_with_sco_only;
BOOLEAN deregister; /* TRUE if service shutting down */
BOOLEAN svc_conn; /* set to TRUE when service level connection is up */
@@ -312,5 +326,8 @@ extern void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA *p_data);
#if (BTM_SCO_HCI_INCLUDED == TRUE )
extern void bta_hf_client_pkt_stat_nums(tBTA_HF_CLIENT_DATA *p_data);
extern void bta_hf_client_ci_sco_data(tBTA_HF_CLIENT_DATA *p_data);
+extern void bta_hf_client_h2_header(UINT16 *p_buf);
+extern void bta_hf_client_sco_data_send(tBTA_HF_CLIENT_DATA *p_data);
+extern void bta_hf_client_sco_data_free(tBTA_HF_CLIENT_DATA *p_data);
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
#endif /* #if (BTA_HF_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/bta/hh/bta_hh_le.c b/lib/bt/host/bluedroid/bta/hh/bta_hh_le.c
index a80314ef..f5697dff 100644
--- a/lib/bt/host/bluedroid/bta/hh/bta_hh_le.c
+++ b/lib/bt/host/bluedroid/bta/hh/bta_hh_le.c
@@ -117,7 +117,7 @@ static void bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB *p_cb)
if (p_cb->hid_srvc[i].in_use) {
p_rpt = &p_cb->hid_srvc[i].report[0];
- APPL_TRACE_DEBUG("\t HID serivce inst: %d", i);
+ APPL_TRACE_DEBUG("\t HID service inst: %d", i);
for (j = 0; j < BTA_HH_LE_RPT_MAX; j ++, p_rpt++) {
rpt_name = "Unknown";
@@ -334,14 +334,15 @@ void bta_hh_le_open_conn(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda)
bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
p_cb->in_use = TRUE;
- BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, BLE_ADDR_UNKNOWN_TYPE, TRUE, BTA_GATT_TRANSPORT_LE, FALSE);
+ BTA_GATTC_Enh_Open(bta_hh_cb.gatt_if, remote_bda, BLE_ADDR_UNKNOWN_TYPE, TRUE,
+ BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, 0, NULL, NULL, NULL);
}
/*******************************************************************************
**
** Function bta_hh_le_fill_16bits_gatt_id
**
-** Description Utility function to fill a GATT ID strucure
+** Description Utility function to fill a GATT ID structure
**
*******************************************************************************/
void bta_hh_le_fill_16bits_gatt_id(UINT8 inst_id, UINT16 uuid, tBTA_GATT_ID *p_output)
@@ -355,7 +356,7 @@ void bta_hh_le_fill_16bits_gatt_id(UINT8 inst_id, UINT16 uuid, tBTA_GATT_ID *p_
**
** Function bta_hh_le_fill_16bits_srvc_id
**
-** Description Utility function to fill a service ID strucure with a 16 bits
+** Description Utility function to fill a service ID structure with a 16 bits
** service UUID.
**
*******************************************************************************/
@@ -372,7 +373,7 @@ void bta_hh_le_fill_16bits_srvc_id(BOOLEAN is_pri, UINT8 inst_id, UINT16 srvc_uu
**
** Function bta_hh_le_fill_16bits_char_id
**
-** Description Utility function to fill a char ID strucure with a 16 bits
+** Description Utility function to fill a char ID structure with a 16 bits
** char UUID.
**
*******************************************************************************/
@@ -624,7 +625,7 @@ tBTA_HH_STATUS bta_hh_le_read_char_dscrpt(tBTA_HH_DEV_CB *p_cb, UINT16 srvc_uuid
**
** Function bta_hh_le_read_rpt_ref_descr
**
-** Description read report refernece descriptors in service discovery process
+** Description read report reference descriptors in service discovery process
**
*******************************************************************************/
void bta_hh_le_read_rpt_ref_descr(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_LE_RPT *p_rpt)
@@ -841,7 +842,7 @@ void bta_hh_le_register_input_notif(tBTA_HH_DEV_CB *p_dev_cb, UINT8 srvc_inst,
}
}
/*
- else unknow protocol mode */
+ else unknown protocol mode */
}
}
}
@@ -1486,7 +1487,7 @@ void bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_STATUS status)
{
APPL_TRACE_DEBUG("bta_hh_le_gatt_disc_cmpl ");
- /* if open sucessful or protocol mode not desired, keep the connection open but inform app */
+ /* if open successful or protocol mode not desired, keep the connection open but inform app */
if (status == BTA_HH_OK || status == BTA_HH_ERR_PROTO) {
/* assign a special APP ID temp, since device type unknown */
p_cb->app_id = BTA_HH_APP_ID_LE;
@@ -1504,7 +1505,7 @@ void bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_STATUS status)
**
** Function bta_hh_le_srvc_expl_srvc
**
-** Description This function discover the next avaible HID service.
+** Description This function discover the next available HID service.
**
** Parameters:
**
@@ -2076,7 +2077,7 @@ void bta_hh_w4_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf)
**
** Function bta_hh_w4_le_write_cmpl
**
-** Description Write charactersitic complete event at W4_CONN st.
+** Description Write characteristic complete event at W4_CONN st.
**
** Parameters:
**
@@ -2104,7 +2105,7 @@ void bta_hh_w4_le_write_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf)
**
** Function bta_hh_le_write_cmpl
**
-** Description Write charactersitic complete event at CONN st.
+** Description Write characteristic complete event at CONN st.
**
** Parameters:
**
@@ -2162,7 +2163,7 @@ void bta_hh_le_write_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf)
**
** Function bta_hh_le_write_char_descr_cmpl
**
-** Description Write charactersitic descriptor complete event
+** Description Write characteristic descriptor complete event
**
** Parameters:
**
@@ -2216,7 +2217,7 @@ void bta_hh_le_write_char_descr_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_b
**
** Function bta_hh_le_input_rpt_notify
**
-** Description process the notificaton event, most likely for input report.
+** Description process the notification event, most likely for input report.
**
** Parameters:
**
@@ -2357,7 +2358,7 @@ void bta_hh_gatt_close(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
**
** Function bta_hh_le_api_disc_act
**
-** Description initaite a Close API to a remote HID device
+** Description initiate a Close API to a remote HID device
**
** Returns void
**
@@ -2601,7 +2602,8 @@ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond)
if (/*p_cb->dscp_info.flag & BTA_HH_LE_NORMAL_CONN &&*/
!p_cb->in_bg_conn && to_add) {
/* add device into BG connection to accept remote initiated connection */
- BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, BLE_ADDR_UNKNOWN_TYPE, FALSE, BTA_GATT_TRANSPORT_LE, FALSE);
+ BTA_GATTC_Enh_Open(bta_hh_cb.gatt_if, p_cb->addr, BLE_ADDR_UNKNOWN_TYPE, FALSE,
+ BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, 0, NULL, NULL);
p_cb->in_bg_conn = TRUE;
BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL);
@@ -2682,7 +2684,7 @@ void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf)
if (!p_dev_cb->is_le_device ||
p_dev_cb->mode != BTA_HH_PROTO_RPT_MODE ||
p_dev_cb->scps_supported == FALSE) {
- APPL_TRACE_ERROR("Can not set ScPP scan paramter as boot host, or remote does not support ScPP ");
+ APPL_TRACE_ERROR("Can not set ScPP scan parameter as boot host, or remote does not support ScPP ");
cback_data.handle = p_dev_cb->hid_handle;
cback_data.status = BTA_HH_ERR;
@@ -2908,7 +2910,7 @@ static void bta_hh_le_search_scps_chars(tBTA_HH_DEV_CB *p_cb)
**
** Function bta_hh_le_register_scpp_notif
**
-** Description register scan parameter refresh notitication complete
+** Description register scan parameter refresh notification complete
**
**
** Parameters:
@@ -2919,7 +2921,7 @@ static void bta_hh_le_register_scpp_notif(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATT_ST
UINT8 sec_flag = 0;
tBTA_GATTC_CHAR_ID char_id;
- /* if write scan parameter sucessful */
+ /* if write scan parameter successful */
/* if bonded and notification is not enabled, configure the client configuration */
if (status == BTA_GATT_OK &&
(p_dev_cb->scps_notify & BTA_HH_LE_SCPS_NOTIFY_SPT) != 0 &&
@@ -2949,7 +2951,7 @@ static void bta_hh_le_register_scpp_notif(tBTA_HH_DEV_CB *p_dev_cb, tBTA_GATT_ST
**
** Function bta_hh_le_register_scpp_notif_cmpl
**
-** Description action function to register scan parameter refresh notitication
+** Description action function to register scan parameter refresh notification
**
** Parameters:
**
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_ag_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_ag_api.h
index 35bb6ab5..ac714d85 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_ag_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_ag_api.h
@@ -112,7 +112,7 @@ typedef UINT8 tBTA_AG_STATUS;
/* It is safe to use the same value as BTA_AG_HANDLE_ALL
* HANDLE_ALL is used for delivering indication
* SCO_NO_CHANGE is used for changing sco behavior
- * They donot interfere with each other
+ * They do not interfere with each other
*/
#define BTA_AG_HANDLE_SCO_NO_CHANGE 0xFFFF
@@ -363,6 +363,13 @@ typedef struct
tBTA_AG_CHLD_FEAT chld_feat;
} tBTA_AG_CONN;
+/* data associated with BTA_AG_AUDIO_OPEN_EVT, BTA_AG_AUDIO_CLOSE_EVT or BTA_AG_AUDIO_MSBC_OPEN_EVT */
+typedef struct
+{
+ tBTA_AG_HDR hdr;
+ UINT16 preferred_frame_size;
+} tBTA_AG_AUDIO_STAT;
+
/* data associated with AT command event */
typedef struct
{
@@ -427,6 +434,7 @@ typedef union
tBTA_AG_OPEN open;
tBTA_AG_CLOSE close;
tBTA_AG_CONN conn;
+ tBTA_AG_AUDIO_STAT audio_stat;
tBTA_AG_IND ind;
tBTA_AG_VAL val;
//add
@@ -619,6 +627,45 @@ void BTA_AgPktStatsNumsGet(UINT16 handle, UINT16 sync_conn_handle);
**
*******************************************************************************/
void BTA_AgCiData(UINT16 handle);
+
+/*******************************************************************************
+**
+** Function BTA_AgAudioBuffAlloc
+**
+** Description Allocate an audio buffer with specific size, reserve enough
+** space and offset for lower layer to send the buffer directly.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_AgAudioBuffAlloc(UINT16 size, UINT8 **pp_buff, UINT8 **pp_data);
+
+/*******************************************************************************
+**
+** Function BTA_AgAudioBuffFree
+**
+** Description Free an audio buffer.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_AgAudioBuffFree(UINT8 *p_buf);
+
+/*******************************************************************************
+**
+** Function BTA_AgAudioDataSend
+**
+** Description Send audio data to lower layer, whether success or not, buffer
+** is consumed.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_AgAudioDataSend(UINT16 handle, UINT8 *p_buff_start, UINT8 *p_data, UINT16 data_len);
+
#endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE ) */
#ifdef __cplusplus
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_api.h
index 75a81994..aa1b632a 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_api.h
@@ -439,6 +439,10 @@ typedef tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK tBTA_ADD_DEV_TO_RESOLVING_LIST
typedef tBTM_SET_PRIVACY_MODE_CMPL_CBACK tBTA_SET_PRIVACY_MODE_CMPL_CBACK;
+typedef tBTM_SET_CSA_SUPPORT_CMPL_CBACK tBTA_SET_CSA_SUPPORT_CMPL_CBACK;
+
+typedef tBTM_SET_VENDOR_EVT_MASK_CBACK tBTA_SET_VENDOR_EVT_MASK_CBACK;
+
typedef tBTM_CMPL_CB tBTA_CMPL_CB;
typedef tBTM_VSC_CMPL tBTA_VSC_CMPL;
@@ -447,6 +451,8 @@ typedef tBTM_TX_POWER_RESULTS tBTA_TX_POWER_RESULTS;
typedef tBTM_RSSI_RESULTS tBTA_RSSI_RESULTS;
+typedef tBTM_BLE_CH_MAP_RESULTS tBTA_BLE_CH_MAP_RESULTS;
+
typedef tBTM_SET_AFH_CHANNELS_RESULTS tBTA_SET_AFH_CHANNELS_RESULTS;
typedef tBTM_BLE_SET_CHANNELS_RESULTS tBTA_BLE_SET_CHANNELS_RESULTS;
@@ -537,7 +543,9 @@ enum {
};
typedef tBTM_BLE_BATCH_SCAN_EVT tBTA_BLE_BATCH_SCAN_EVT;
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
typedef tBTM_BLE_TRACK_ADV_ACTION tBTA_BLE_TRACK_ADV_ACTION;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
// #endif
/* BLE customer specific feature function type definitions */
@@ -1001,6 +1009,7 @@ typedef struct {
typedef struct {
BD_ADDR bd_addr; /* BD address peer device. */
tBTA_PM_MODE mode; /* the new connection role */
+ UINT16 interval; /* Number of baseband slots */
} tBTA_DM_MODE_CHG;
typedef struct {
@@ -1044,6 +1053,7 @@ typedef union {
/* Security callback */
typedef void (tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data);
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
#define BTA_BLE_MULTI_ADV_ILLEGAL 0
/* multi adv callback event */
@@ -1057,6 +1067,8 @@ typedef UINT8 tBTA_BLE_MULTI_ADV_EVT;
/* multi adv callback */
typedef void (tBTA_BLE_MULTI_ADV_CBACK)(tBTA_BLE_MULTI_ADV_EVT event,
UINT8 inst_id, void *p_ref, tBTA_STATUS status);
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
+
typedef UINT32 tBTA_DM_BLE_REF_VALUE;
#define BTA_DM_BLE_PF_ENABLE_EVT BTM_BLE_PF_ENABLE
@@ -1249,8 +1261,9 @@ typedef UINT8 tBTA_DM_BLE_ADV_STATE;
typedef UINT8 tBTA_DM_BLE_ADV_INFO_PRESENT;
typedef UINT8 tBTA_DM_BLE_RSSI_VALUE;
typedef UINT16 tBTA_DM_BLE_ADV_INFO_TIMESTAMP;
-
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
typedef tBTM_BLE_TRACK_ADV_DATA tBTA_DM_BLE_TRACK_ADV_DATA;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
typedef void (tBTA_BLE_SCAN_THRESHOLD_CBACK)(tBTA_DM_BLE_REF_VALUE ref_value);
@@ -1268,18 +1281,22 @@ typedef void (tBTA_START_STOP_ADV_CMPL_CBACK) (tBTA_STATUS status);
typedef void (tBTA_CLEAR_ADV_CMPL_CBACK) (tBTA_STATUS status);
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status,
tBTA_DM_BLE_PF_AVBL_SPACE avbl_space,
tBTA_DM_BLE_REF_VALUE ref_value);
typedef void (tBTA_BLE_TRACK_ADV_CBACK)(tBTA_DM_BLE_TRACK_ADV_DATA *p_adv_data);
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
typedef void (tBTA_BLE_ENERGY_INFO_CBACK)(tBTA_DM_BLE_TX_TIME_MS tx_time,
tBTA_DM_BLE_RX_TIME_MS rx_time,
tBTA_DM_BLE_IDLE_TIME_MS idle_time,
tBTA_DM_BLE_ENERGY_USED energy_used,
tBTA_DM_CONTRL_STATE ctrl_state,
tBTA_STATUS status);
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
#else
typedef UINT8 tBTA_DM_BLE_SEC_ACT;
@@ -1350,10 +1367,22 @@ typedef UINT8 tBTA_DM_PM_ACTION;
#define BTA_DM_PM_SNIFF_HD_IDLE_IDX BTA_DM_PM_SNIFF4
#endif
+#ifndef BTA_DM_PM_SNIFF_AG_OPEN_IDX
+#define BTA_DM_PM_SNIFF_AG_OPEN_IDX BTA_DM_PM_SNIFF
+#endif
+
+#ifndef BTA_DM_PM_SNIFF_AG_IDLE_IDX
+#define BTA_DM_PM_SNIFF_AG_IDLE_IDX BTA_DM_PM_SNIFF
+#endif
+
#ifndef BTA_DM_PM_SNIFF_SCO_OPEN_IDX
#define BTA_DM_PM_SNIFF_SCO_OPEN_IDX BTA_DM_PM_SNIFF3
#endif
+#ifndef BTA_DM_PM_SNIFF_SCO_CLOSE_IDX
+#define BTA_DM_PM_SNIFF_SCO_CLOSE_IDX BTA_DM_PM_SNIFF
+#endif
+
#ifndef BTA_DM_PM_SNIFF_HD_ACTIVE_IDX
#define BTA_DM_PM_SNIFF_HD_ACTIVE_IDX BTA_DM_PM_SNIFF5
#endif
@@ -1497,18 +1526,18 @@ typedef UINT8 tBTA_DM_LINK_TYPE;
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_INCLUDE_TX_PWR (1 << 6)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_MASK (0x7F)
-#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
- ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
- ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
-#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_LD_DIR (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
- ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
- ESP_BLE_GAP_SET_EXT_ADV_PROP_DIRECTED)
-#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_HD_DIR (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
- ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
- ESP_BLE_GAP_SET_EXT_ADV_PROP_HD_DIRECTED)
-#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_SCAN (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
- ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
-#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY)
+#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
+ BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
+ BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
+#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_LD_DIR (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
+ BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
+ BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_DIRECTED)
+#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_HD_DIR (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
+ BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
+ BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_HD_DIRECTED)
+#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_SCAN (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
+ BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
+#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY)
typedef UINT16 tBTA_DM_BLE_EXT_ADV_TYPE_MASK;
@@ -1560,15 +1589,16 @@ typedef struct {
typedef struct {
UINT8 filter_policy;
- #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
+#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
UINT8 reports_disabled;
UINT8 filter_duplicates;
- #endif
+#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
UINT8 sid;
tBLE_ADDR_TYPE addr_type;
BD_ADDR addr;
UINT16 skip;
UINT16 sync_timeout;
+ UINT8 sync_cte_type;
} tBTA_DM_BLE_Periodic_Sync_Params;
typedef struct {
@@ -1600,6 +1630,7 @@ typedef struct {
#define BTA_DM_BLE_5_GAP_READ_PHY_COMPLETE_EVT BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
#define BTA_DM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT
@@ -1608,29 +1639,42 @@ typedef struct {
#define BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT BTM_BLE_5_GAP_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
#define BTA_DM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT BTM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT BTM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
#define BTA_DM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT BTM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT
#define BTA_DM_BLE_5_GAP_PHY_UPDATE_COMPLETE_EVT BTM_BLE_5_GAP_PHY_UPDATE_COMPLETE_EVT
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
#define BTA_DM_BLE_5_GAP_EXT_ADV_REPORT_EVT BTM_BLE_5_GAP_EXT_ADV_REPORT_EVT
#define BTA_DM_BLE_5_GAP_SCAN_TIMEOUT_EVT BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
#define BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT BTM_BLE_5_GAP_ADV_TERMINATED_EVT
#define BTA_DM_BLE_5_GAP_SCAN_REQ_RECEIVED_EVT BTM_BLE_5_GAP_SCAN_REQ_RECEIVED_EVT
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#define BTA_DM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT BTM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT
#define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#define BTA_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT
#define BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT
@@ -1638,6 +1682,25 @@ typedef struct {
#define BTA_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT
#define BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#define BTA_BLE_GAP_ENH_READ_TRANS_POWER_LEVEL_EVT BTM_BLE_GAP_ENH_READ_TRANS_POWER_LEVEL_EVT
+#define BTA_BLE_GAP_READ_REMOTE_TRANS_POWER_LEVEL_EVT BTM_BLE_GAP_READ_REMOTE_TRANS_POWER_LEVEL_EVT
+#define BTA_BLE_GAP_SET_PATH_LOSS_REPORTING_PARAMS_EVT BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_PARAMS_EVT
+#define BTA_BLE_GAP_SET_PATH_LOSS_REPORTING_ENABLE_EVT BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_ENABLE_EVT
+#define BTA_BLE_GAP_SET_TRANS_POWER_REPORTING_ENABLE_EVT BTM_BLE_GAP_SET_TRANS_POWER_REPORTING_ENABLE_EVT
+#define BTA_BLE_GAP_PATH_LOSS_THRESHOLD_EVT BTM_BLE_GAP_PATH_LOSS_THRESHOLD_EVT
+#define BTA_BLE_GAP_TRANMIT_POWER_REPORTING_EVT BTM_BLE_GAP_TRANMIT_POWER_REPORTING_EVT
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#define BTA_BLE_GAP_SET_DEFAULT_SUBRATE_EVT BTM_BLE_GAP_SET_DEFAULT_SUBRATE_EVT
+#define BTA_BLE_GAP_SUBRATE_REQUEST_EVT BTM_BLE_GAP_SUBRATE_REQUEST_EVT
+#define BTA_BLE_GAP_SUBRATE_CHANGE_EVT BTM_BLE_GAP_SUBRATE_CHANGE_EVT
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#define BTA_BLE_GAP_SET_HOST_FEATURE_EVT BTM_BLE_GAP_SET_HOST_FEATURE_EVT
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
#define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT
typedef tBTM_BLE_5_GAP_EVENT tBTA_DM_BLE_5_GAP_EVENT;
@@ -1648,6 +1711,62 @@ extern tBTM_BLE_5_HCI_CBACK ble_5_hci_cb;
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#define BTA_BLE_ISO_BIG_CREATE_COMPLETE_EVT BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT
+#define BTA_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define BTA_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT
+#define BTA_BLE_ISO_BIG_SYNC_LOST_EVT BTM_BLE_ISO_BIG_SYNC_LOST_EVT
+#define BTA_BLE_ISO_BIG_SYNC_TERMINATE_COMPLETE_EVT BTM_BLE_ISO_BIG_SYNC_TERMINATE_COMPLETE_EVT
+#define BTA_BLE_ISO_BIGINFO_ADV_REPORT_EVT BTM_BLE_ISO_BIGINFO_ADV_REPORT_EVT
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define BTA_BLE_ISO_DATA_PATH_UPFATE_EVT BTM_BLE_ISO_DATA_PATH_UPFATE_EVT
+#define BTA_BLE_ISO_READ_TX_SYNC_EVT BTM_BLE_ISO_READ_TX_SYNC_EVT
+#define BTA_BLE_ISO_READ_LINK_QUALITY_EVT BTM_BLE_ISO_READ_LINK_QUALITY_EVT
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#define BTA_BLE_ISO_SET_CIG_PARAMS_EVT BTM_BLE_ISO_SET_CIG_PARAMS_EVT
+#define BTA_BLE_ISO_CREATE_CIS_EVT BTM_BLE_ISO_CREATE_CIS_EVT
+#define BTA_BLE_ISO_REMOVE_CIG_EVT BTM_BLE_ISO_REMOVE_CIG_EVT
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#define BTA_BLE_ISO_ACCEPT_CIS_REQ_EVT BTM_BLE_ISO_ACCEPT_CIS_REQ_EVT
+#define BTA_BLE_ISO_REJECT_CIS_REQ_EVT BTM_BLE_ISO_REJECT_CIS_REQ_EVT
+#define BTA_BLE_ISO_CIS_REQUEST_EVT BTM_BLE_ISO_CIS_REQUEST_EVT
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#define BTA_BLE_ISO_CIS_ESTABLISHED_EVT BTM_BLE_ISO_CIS_ESTABLISHED_EVT
+#define BTA_BLE_ISO_CIS_DISCONNECTED_EVT BTM_BLE_ISO_CIS_DISCONNECTED_EVT
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#define BTA_DM_BLE_ISO_UNKNOWN_EVT BTM_BLE_ISO_UNKNOWN_EVT
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#define BTA_BLE_CTE_SET_TRANS_PARAMS_EVT BTM_BLE_CTE_SET_TRANS_PARAMS_EVT
+#define BTA_BLE_CTE_SET_TRANS_ENABLE_EVT BTM_BLE_CTE_SET_TRANS_ENABLE_EVT
+#define BTA_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define BTA_BLE_CTE_SET_CONN_RECV_PARAMS_EVT BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT
+#define BTA_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT
+#define BTA_BLE_CTE_SET_CONN_REQ_ENABLE_EVT BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT
+#define BTA_BLE_CTE_SET_CONN_RSP_ENABLE_EVT BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define BTA_BLE_CTE_READ_ANT_INFOR_EVT BTM_BLE_CTE_READ_ANT_INFOR_EVT
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#define BTA_BLE_CTE_CONNLESS_IQ_REPORT_EVT BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define BTA_BLE_CTE_CONN_IQ_REPORT_EVT BTM_BLE_CTE_CONN_IQ_REPORT_EVT
+#define BTA_BLE_CTE_REQUEST_FAILED_EVT BTM_BLE_CTE_REQUEST_FAILED_EVT
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
typedef struct {
UINT8 mode;
@@ -1657,6 +1776,77 @@ typedef struct {
} tBTA_DM_BLE_PAST_PARAMS;
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+typedef struct {
+ UINT8 big_handle;
+ UINT8 adv_handle;
+ UINT8 num_bis;
+ UINT32 sdu_interval;
+ UINT16 max_sdu;
+ UINT16 max_transport_latency;
+ UINT8 rtn;
+ UINT8 phy;
+ UINT8 packing;
+ UINT8 framing;
+ UINT8 encryption;
+ UINT8 broadcast_code[16];
+} tBTA_DM_BLE_BIG_CREATE_PARAMS;
+
+typedef struct {
+ UINT8 big_handle;
+ UINT8 adv_handle;
+ UINT8 num_bis;
+ UINT32 sdu_interval;
+ UINT16 iso_interval;
+ UINT8 nse;
+ UINT16 max_sdu;
+ UINT16 max_pdu;
+ UINT8 phy;
+ UINT8 packing;
+ UINT8 framing;
+ UINT8 bn;
+ UINT8 irc;
+ UINT8 pto;
+ UINT8 encryption;
+ UINT8 broadcast_code[16];
+} tBTA_DM_BLE_BIG_CREATE_TEST_PARAMS;
+typedef struct {
+ UINT8 big_handle;
+ UINT8 reason;
+} tBTA_DM_BLE_BIG_TERMINATE_PARAMS;
+typedef struct {
+ UINT8 big_handle;
+ UINT16 sync_handle;
+ UINT8 encryption;
+ UINT8 bc_code[16];
+ UINT8 mse;
+ UINT16 big_sync_timeout;
+ UINT8 num_bis;
+ UINT8 bis[BLE_ISO_BIS_MAX_COUNT];
+} tBTA_DM_BLE_BIG_SYNC_CREATE_PARAMS;
+typedef struct {
+ UINT8 big_handle;
+} tBTA_DM_BLE_BIG_SYNC_TERMINATE_PARAMS;
+
+typedef struct {
+ uint16_t conn_handle;
+ uint8_t data_path_dir;
+ uint8_t data_path_id;
+ uint8_t coding_fmt;
+ uint16_t company_id;
+ uint16_t vs_codec_id;
+ uint32_t controller_delay;
+ uint8_t codec_len;
+ uint8_t *codec_cfg;
+} tBTA_DM_BLE_ISO_SET_DATA_PATH_PARAMS;
+
+typedef struct {
+ uint16_t conn_handle;
+ uint8_t data_path_dir;
+} tBTA_DM_BLE_ISO_REMOVE_DATA_PATH_PARAMS;
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+
/*****************************************************************************
** External Function Declarations
*****************************************************************************/
@@ -1880,6 +2070,7 @@ extern void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb);
#endif ///BLE_INCLUDED == TRUE
extern void BTA_DmReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb);
+extern void BTA_DmBleReadChannelMap(BD_ADDR remote_device, tBTA_CMPL_CB *p_callback);
/*******************************************************************************
**
@@ -2190,6 +2381,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
/*******************************************************************************
**
@@ -2466,24 +2668,6 @@ extern void BTA_DmSetBleScanFilterParams(tGATT_IF client_if, UINT32 scan_interva
UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback);
-/*******************************************************************************
-**
-** Function BTA_DmSetBleAdvParams
-**
-** Description This function sets the advertising parameters BLE functionality.
-** It is to be called when device act in peripheral or broadcaster
-** role.
-**
-** Parameters: adv_int_min - adv interval minimum
-** adv_int_max - adv interval max
-** p_dir_bda - directed adv initiator address
-**
-** Returns void
-**
-*******************************************************************************/
-extern void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max,
- tBLE_BD_ADDR *p_dir_bda);
-
extern void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own,
tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol,
@@ -2614,7 +2798,9 @@ extern void BTA_DmBleScan(BOOLEAN start, UINT32 duration,
tBTA_DM_SEARCH_CBACK *p_results_cb,
tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb);
+#if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
extern void BTA_DmBleStopAdvertising(void);
+#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE)
extern void BTA_DmSetRandAddress(BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK *p_set_rand_addr_cback);
extern void BTA_DmClearRandAddress(void);
@@ -2699,21 +2885,6 @@ extern void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask,
extern void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len,
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback);
-/*******************************************************************************
-**
-** Function BTA_DmBleSetLongAdv
-**
-** Description This function is called to set long Advertising data
-**
-** Parameters adv_data : long advertising data.
-** adv_data_len : long advertising data length.
-** p_adv_data_cback : set long adv data complete callback.
-**
-** Returns None
-**
-*******************************************************************************/
-void BTA_DmBleSetLongAdv (UINT8 *adv_data, UINT32 adv_data_len,
- tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback);
/*******************************************************************************
**
@@ -2791,7 +2962,7 @@ extern void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type,
*******************************************************************************/
extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_start_stop_adv_cb);
-
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTA_BleEnableAdvInstance
@@ -2850,6 +3021,7 @@ extern void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
**
*******************************************************************************/
extern void BTA_BleDisableAdvInstance(UINT8 inst_id);
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
@@ -2890,13 +3062,38 @@ extern void BTA_DmBleDisconnect(BD_ADDR bd_addr);
**
*******************************************************************************/
extern void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback);
-
+#if (BLE_42_DTM_TEST_EN == TRUE)
extern void BTA_DmBleDtmTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback);
extern void BTA_DmBleDtmRxStart(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback);
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
+
extern void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback);
extern void BTA_DmBleSetPrivacyMode(uint8_t addr_type, BD_ADDR addr, uint8_t privacy_mode, tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback);
+extern void BTA_DmBleGapSetCsaSupport(uint8_t csa_select, tBTM_SET_CSA_SUPPORT_CMPL_CBACK *p_callback);
+
+extern void BTA_DmBleGapSetVendorEventMask(uint32_t evt_mask, tBTA_SET_VENDOR_EVT_MASK_CBACK *p_callback);
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void BTA_DmBleGapEnhReadTransPwrLevel(uint16_t conn_handle, uint8_t phy);
+void BTA_DmBleGapReadRemoteTransPwrLevel(uint16_t conn_handle, uint8_t phy);
+void BTA_DmBleGapSetPathLossRptParams(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis,
+ uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent);
+void BTA_DmBleGapSetPathLossRptEnable(uint16_t conn_handle, uint8_t enable);
+void BTA_DmBleGapSetTransPwrRptEnable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable);
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void BTA_DmBleGapSetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency,
+ uint16_t continuation_number, uint16_t supervision_timeout);
+void BTA_DmBleGapSubrateReqest(uint16_t conn_handle, uint16_t subrate_min, uint16_t subrate_max,
+ uint16_t max_latency, uint16_t continuation_number, uint16_t supervision_timeout);
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+extern void BTA_DmBleGapSetHostFeature(uint16_t bit_num, uint8_t bit_val);
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
/*******************************************************************************
**
** Function BTA_DmBleSetStorageParams
@@ -3037,7 +3234,7 @@ extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action,
tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback,
tBTA_DM_BLE_REF_VALUE ref_value);
-
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleTrackAdvertiser
@@ -3052,7 +3249,9 @@ extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action,
*******************************************************************************/
extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value,
tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback);
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
/*******************************************************************************
**
** Function BTA_DmBleGetEnergyInfo
@@ -3065,6 +3264,7 @@ extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value,
**
*******************************************************************************/
extern void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback);
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
/*******************************************************************************
**
@@ -3151,11 +3351,13 @@ extern void BTA_DmBleGapPreferExtConnectParamsSet(BD_ADDR bd_addr,
const tBTA_DM_BLE_CONN_PARAMS *phy_coded_conn_params);
extern void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_addr);
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
extern void BTA_DmBleDtmEnhTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback);
extern void BTA_DmBleDtmEnhRxStart(uint8_t rx_channel, uint8_t phy, uint8_t modulation_index, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback);
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
extern void BTA_DmBleGapPeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable);
@@ -3167,6 +3369,57 @@ extern void BTA_DmBleGapPeriodicAdvSetInfoTrans(BD_ADDR peer_addr, UINT16 servic
extern void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PAST_PARAMS *params);
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+extern void BTA_DmBleGapIsoBigCreate(tBTA_DM_BLE_BIG_CREATE_PARAMS *p_big_creat_param);
+extern void BTA_DmBleGapIsoBigCreateTest(tBTA_DM_BLE_BIG_CREATE_TEST_PARAMS *p_big_creat_test_param);
+extern void BTA_DmBleGapIsoBigTerminate(tBTA_DM_BLE_BIG_TERMINATE_PARAMS *p_big_terminate_param);
+#endif// #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+extern void BTA_DmBleGapIsoBigSyncCreate(tBTA_DM_BLE_BIG_SYNC_CREATE_PARAMS *p_big_sync_param);
+extern void BTA_DmBleGapIsoBigSyncTerminate(tBTA_DM_BLE_BIG_SYNC_TERMINATE_PARAMS *p_big_sync_terminate_param);
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+extern void BTA_DmBleGapIsoDataPathSet(tBTA_DM_BLE_ISO_SET_DATA_PATH_PARAMS *p_iso_data_path_param);
+extern void BTA_DmBleGapIsoDataPathRemove(tBTA_DM_BLE_ISO_REMOVE_DATA_PATH_PARAMS *p_iso_data_path_param);
+extern void BTA_DmBleGapIsoReadTxSync(uint16_t iso_handle);
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+extern void BTA_DmBleIsoSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing,
+ uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, uint8_t *cis_params);
+void BTA_DmBleIsoSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c,
+ uint16_t iso_interval, uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, uint8_t *cis_params_test);
+extern void BTA_DmBleIsoCreateCis(uint8_t cig_count, uint8_t *cis_hdl_info);
+extern void BTA_DmBleIsoRemoveCig(uint8_t cig_id);
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+extern void BTA_DmBleIsoAcceptCisReq(uint16_t cis_handle);
+extern void BTA_DmBleIsoRejectCisReq(uint16_t cis_handle, uint8_t reason);
+#endif // BLE_FEAT_ISO_CIG_PERIPHERAL_EN
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+extern void BTA_DmBleIsoDisconCis(uint16_t cis_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#endif // if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+void BTA_DmBleCteSetConnectionlessTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type,
+ uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids);
+void BTA_DmBleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en);
+void BTA_DmBleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids);
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+void BTA_DmBleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t switching_pattern_len, uint8_t *ant_ids);
+
+void BTA_DmBleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids);
+void BTA_DmBleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_interval,
+ uint8_t req_cte_len, uint8_t req_cte_Type);
+void BTA_DmBleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable);
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+void BTA_DmBleCteReadAntInfor(void);
+#endif // if (BLE_FEAT_CTE_EN == TRUE)
+
#endif
enum {
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_ar_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_ar_api.h
index 2823d674..20f11281 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_ar_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_ar_api.h
@@ -18,7 +18,7 @@
/******************************************************************************
*
- * This is the public interface file for the simulatenous advanced
+ * This is the public interface file for the simultaneous advanced
* audio/video streaming (AV) source and sink of BTA, Broadcom's Bluetooth
* application layer for mobile phones.
*
@@ -35,6 +35,10 @@
#if (BTA_AR_INCLUDED == TRUE)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*****************************************************************************
** Constants and data types
*****************************************************************************/
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_av_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_av_api.h
index ddf72b96..5a670bd0 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_av_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_av_api.h
@@ -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 */
@@ -248,13 +256,19 @@ typedef UINT8 tBTA_AV_ERR;
#define BTA_AV_META_MSG_EVT 17 /* metadata messages */
#define BTA_AV_REJECT_EVT 18 /* incoming connection rejected */
#define BTA_AV_RC_FEAT_EVT 19 /* remote control channel peer supported features update */
-#define BTA_AV_MEDIA_SINK_CFG_EVT 20 /* command to configure codec */
+#define BTA_AV_MEDIA_CFG_EVT 20 /* command to configure codec */
#define BTA_AV_MEDIA_DATA_EVT 21 /* sending data to Media Task */
#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. */
+#define BTA_AV_SEP_REG_EVT 25 /* stream endpoint registered */
+
+/* still keep Cover Art event here if Cover Art feature not enabled */
+#define BTA_AV_CA_STATUS_EVT 26 /* Cover Art Client status event */
+#define BTA_AV_CA_DATA_EVT 27 /* Cover Art response body data */
+
/* Max BTA event */
-#define BTA_AV_MAX_EVT 25
+#define BTA_AV_MAX_EVT 28
/* function types for call-out functions */
@@ -328,6 +342,12 @@ typedef struct {
tBTA_AVRC_CO_FUNCTS *p_bta_avrc_cos;
} tBTA_AV_REGISTER;
+/* Event associated with BTA_AV_SEP_REG_EVT */
+typedef struct {
+ UINT8 seid;
+ tBTA_AV_STATUS reg_state;
+} tBTA_AV_SEP_REG;
+
/* data associated with BTA_AV_OPEN_EVT */
#define BTA_AV_EDR_2MBPS 0x01
#define BTA_AV_EDR_3MBPS 0x02
@@ -341,6 +361,7 @@ typedef struct {
BOOLEAN starting;
tBTA_AV_EDR edr; /* 0, if peer device does not support EDR */
UINT8 sep; /* sep type of peer device */
+ UINT16 mtu;
} tBTA_AV_OPEN;
/* data associated with BTA_AV_CLOSE_EVT */
@@ -482,11 +503,31 @@ 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;
tBTA_AV_ENABLE enable;
tBTA_AV_REGISTER registr;
+ tBTA_AV_SEP_REG sep_reg;
tBTA_AV_OPEN open;
tBTA_AV_CLOSE close;
tBTA_AV_START start;
@@ -506,6 +547,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 */
@@ -621,6 +666,8 @@ void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name,
tBTA_AV_CO_FUNCTS *bta_av_cos, tBTA_AVRC_CO_FUNCTS *bta_avrc_cos,
UINT8 tsep);
+void BTA_AvRegSEP(tBTA_AV_CHNL chnl, UINT8 idx, UINT8 tsep, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, tBTA_AV_DATA_CBACK *p_data_cback);
+
/*******************************************************************************
**
** Function BTA_AvDeregister
@@ -865,6 +912,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
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_av_sbc.h b/lib/bt/host/bluedroid/bta/include/bta/bta_av_sbc.h
index fccc02fa..751c6488 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_av_sbc.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_av_sbc.h
@@ -196,6 +196,18 @@ extern UINT8 bta_av_sbc_cfg_in_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap);
/*******************************************************************************
**
+** Function bta_av_sbc_cfg_in_external_codec_cap
+**
+** Description This function checks whether an SBC codec configuration
+** is allowable for the given external codec capabilities.
+**
+** Returns 0 if ok, nonzero if error.
+**
+*******************************************************************************/
+extern UINT8 bta_av_sbc_cfg_in_external_codec_cap(UINT8 *p_cfg, UINT8 *p_cap);
+
+/*******************************************************************************
+**
** Function bta_av_sbc_cfg_matches_cap
**
** Description This function checks whether an SBC codec configuration
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h
index 183e3acc..a42d1408 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h
@@ -180,7 +180,7 @@ typedef UINT8 tBTA_GATT_STATUS;
#define BTA_GATTC_ADV_VSC_EVT 34 /* ADV VSC event */
#define BTA_GATTC_CONNECT_EVT 35 /* GATTC CONNECT event */
#define BTA_GATTC_DISCONNECT_EVT 36 /* GATTC DISCONNECT event */
-#define BTA_GATTC_READ_MULTIPLE_EVT 37 /* GATTC Read mutiple event */
+#define BTA_GATTC_READ_MULTIPLE_EVT 37 /* GATTC Read multiple event */
#define BTA_GATTC_QUEUE_FULL_EVT 38 /* GATTC queue full event */
#define BTA_GATTC_ASSOC_EVT 39 /* GATTC association address event */
#define BTA_GATTC_GET_ADDR_LIST_EVT 40 /* GATTC get address list in the cache event */
@@ -728,6 +728,21 @@ typedef struct
tBTA_GATTC_SERVICE *included_service;
} __attribute__((packed)) tBTA_GATTC_INCLUDED_SVC;
+typedef struct {
+ UINT16 scan_interval;
+ UINT16 scan_window;
+ UINT16 interval_min;
+ UINT16 interval_max;
+ UINT16 latency;
+ UINT16 supervision_timeout;
+ UINT16 min_ce_len;
+ UINT16 max_ce_len;
+} tBTA_BLE_CONN_PARAMS;
+
+#define BTA_BLE_PHY_1M_MASK (1 << 0)
+#define BTA_BLE_PHY_2M_MASK (1 << 1)
+#define BTA_BLE_PHY_CODED_MASK (1 << 2)
+
/*****************************************************************************
** External Function Declarations
*****************************************************************************/
@@ -783,9 +798,10 @@ extern void BTA_GATTC_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTC_CBACK *p_clie
*******************************************************************************/
extern void BTA_GATTC_AppDeregister (tBTA_GATTC_IF client_if);
+
/*******************************************************************************
**
-** Function BTA_GATTC_Open
+** Function BTA_GATTC_Enh_Open
**
** Description Open a direct connection or add a background auto connection
** bd address
@@ -793,13 +809,16 @@ extern void BTA_GATTC_AppDeregister (tBTA_GATTC_IF client_if);
** Parameters client_if: server interface.
** remote_bda: remote device BD address.
** remote_addr_type: remote device BD address type.
-** is_direct: direct connection or background auto connection
+** is_direct: direct connection or background auto connection.
+** own_addr_type: own address type.
**
** Returns void
**
*******************************************************************************/
-extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE remote_addr_type,
- BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport, BOOLEAN is_aux);
+extern void BTA_GATTC_Enh_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE remote_addr_type,
+ BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport, BOOLEAN is_aux, tBTA_ADDR_TYPE own_addr_type,
+ UINT8 phy_mask, tBTA_BLE_CONN_PARAMS *phy_1m_conn_params, tBTA_BLE_CONN_PARAMS *phy_2m_conn_params,
+ tBTA_BLE_CONN_PARAMS *phy_coded_conn_params);
/*******************************************************************************
**
@@ -937,8 +956,8 @@ extern void BTA_GATTC_GetGattDb(UINT16 conn_id, UINT16 start_handle, UINT16 end_
**
** Description This function is called to read a characteristics value
**
-** Parameters conn_id - connectino ID.
-** handle - characteritic handle to read.
+** Parameters conn_id - connection ID.
+** handle - characteristic handle to read.
**
** Returns None
**
@@ -953,7 +972,7 @@ void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, UINT16 handle, tBTA_GATT_AUTH_
**
** Parameters conn_id - connection ID.
** s_handle - start handle.
-** e_handle - end hanle
+** e_handle - end handle
** uuid - The attribute UUID.
**
** Returns None
@@ -1072,7 +1091,7 @@ extern tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF
** Description This function is called to prepare write a characteristic value.
**
** Parameters conn_id - connection ID.
-** handle - GATT characteritic handle.
+** handle - GATT characteristic handle.
** offset - offset of the write value.
** len - length of the data to be written.
** p_value - the value to be written.
@@ -1094,7 +1113,7 @@ extern void BTA_GATTC_PrepareWrite (UINT16 conn_id,
** Description This function is called to prepare write a characteristic descriptor value.
**
** Parameters conn_id - connection ID.
-** p_char_descr_id - GATT characteritic descriptor ID of the service.
+** p_char_descr_id - GATT characteristic descriptor ID of the service.
** offset - offset of the write value.
** len: length of the data to be written.
** p_value - the value to be written.
@@ -1186,37 +1205,6 @@ extern void BTA_GATTC_Clean(BD_ADDR remote_bda);
/*******************************************************************************
**
-** Function BTA_GATTC_Listen
-**
-** Description Start advertisement to listen for connection request.
-**
-** Parameters client_if: server interface.
-** start: to start or stop listening for connection
-** remote_bda: remote device BD address, if listen to all device
-** use NULL.
-**
-** Returns void
-**
-*******************************************************************************/
-extern void BTA_GATTC_Listen(tBTA_GATTC_IF client_if, BOOLEAN start, BD_ADDR_PTR target_bda);
-
-/*******************************************************************************
-**
-** Function BTA_GATTC_Broadcast
-**
-** Description Start broadcasting (non-connectable advertisements)
-**
-** Parameters client_if: client interface.
-** start: to start or stop listening for connection
-**
-** Returns void
-**
-*******************************************************************************/
-extern void BTA_GATTC_Broadcast(tBTA_GATTC_IF client_if, BOOLEAN start);
-
-
-/*******************************************************************************
-**
** Function BTA_GATTC_ConfigureMTU
**
** Description Configure the MTU size in the GATT channel. This can be done
@@ -1238,7 +1226,7 @@ extern void BTA_GATTC_ConfigureMTU (UINT16 conn_id);
**
** Function BTA_GATTS_Init
**
-** Description This function is called to initalize GATTS module
+** Description This function is called to initialize GATTS module
**
** Parameters None
**
@@ -1542,24 +1530,6 @@ void BTA_GATTS_SendServiceChangeIndication(tBTA_GATTS_IF server_if, BD_ADDR remo
/*******************************************************************************
**
-** Function BTA_GATTS_Listen
-**
-** Description Start advertisement to listen for connection request for a
-** GATT server
-**
-** Parameters server_if: server interface.
-** start: to start or stop listening for connection
-** remote_bda: remote device BD address, if listen to all device
-** use NULL.
-**
-** Returns void
-**
-*******************************************************************************/
-extern void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start,
- BD_ADDR_PTR target_bda);
-
-/*******************************************************************************
-**
** Function BTA_GATTS_ShowLocalDatabase
**
** Description print local service database.
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h
index ac834c7b..d2731d28 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h
@@ -188,6 +188,12 @@ typedef struct {
tBTA_HF_CLIENT_CHLD_FEAT chld_feat;
} tBTA_HF_CLIENT_CONN;
+/* data associated with BTA_HF_CLIENT_AUDIO_XXX_EVT */
+typedef struct {
+ tBTA_HF_CLIENT_HDR hdr;
+ UINT16 preferred_frame_size;
+} tBTA_HF_CLIENT_AUDIO_STAT;
+
/* data associated with BTA_HF_CLIENT_IND_EVT event */
typedef struct {
tBTA_HF_CLIENT_HDR hdr;
@@ -251,6 +257,7 @@ typedef union {
tBTA_HF_CLIENT_REGISTER reg;
tBTA_HF_CLIENT_OPEN open;
tBTA_HF_CLIENT_CONN conn;
+ tBTA_HF_CLIENT_AUDIO_STAT audio_stat;
tBTA_HF_CLIENT_IND ind;
tBTA_HF_CLIENT_VAL val;
tBTA_HF_CLIENT_OPERATOR_NAME operator;
@@ -406,9 +413,68 @@ void BTA_HfClientSendAT(UINT16 handle, tBTA_HF_CLIENT_AT_CMD_TYPE at, UINT32 val
*******************************************************************************/
void BTA_HfClientPktStatsNumsGet(UINT16 sync_conn_handle);
+/*******************************************************************************
+**
+** Function BTA_HfClientCiData
+**
+** Description Send SCO outgoing data ready event
+**
+**
+** Returns void
+**
+*******************************************************************************/
void BTA_HfClientCiData(void);
+
+/*******************************************************************************
+**
+** Function BTA_HfClientAudioBuffAlloc
+**
+** Description Allocate an audio buffer with specific size, reserve enough
+** space and offset for lower layer to send the buffer directly.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_HfClientAudioBuffAlloc(UINT16 size, UINT8 **pp_buff, UINT8 **pp_data);
+
+/*******************************************************************************
+**
+** Function BTA_HfClientAudioBuffFree
+**
+** Description Free an audio buffer.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_HfClientAudioBuffFree(UINT8 *p_buf);
+
+/*******************************************************************************
+**
+** Function BTA_HfClientAudioDataSend
+**
+** Description Send audio data to lower layer, whether success or not, buffer
+** is consumed.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_HfClientAudioDataSend(UINT16 sync_conn_hdl, UINT8 *p_buff_start, UINT8 *p_data, UINT16 data_len);
+
#endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE ) */
+/*******************************************************************************
+**
+** Function BTA_HfClientGetCbDataSize
+**
+** Description Get callback data size of specific event
+**
+**
+** Returns void
+**
+*******************************************************************************/
int BTA_HfClientGetCbDataSize(tBTA_HF_CLIENT_EVT event);
#ifdef __cplusplus
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_jv_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_jv_api.h
index 660ce5cf..20c533a5 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_jv_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_jv_api.h
@@ -315,7 +315,7 @@ typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT8 sec_id; /* security ID used by this server */
- UINT8 scn; /* Server channe number */
+ UINT8 scn; /* Server channel number */
BOOLEAN use_co; /* TRUE to use co_rfc_data */
} tBTA_JV_RFCOMM_START;
@@ -378,6 +378,7 @@ typedef struct {
typedef enum {
BTA_JV_SERVER_START_FAILED,
BTA_JV_SERVER_RUNNING,
+ BTA_JV_SERVER_CONNECTED,
BTA_JV_SERVER_STATUS_MAX,
} tBTA_JV_SERVER_STATUS;
@@ -390,7 +391,7 @@ typedef struct {
typedef struct {
tBTA_JV_STATUS status; /* Status of the operation */
tBTA_JV_SERVER_STATUS server_status; /* Server status */
- UINT8 scn; /* Server channe number */
+ UINT16 scn; /* Server channel number */
} tBTA_JV_FREE_SCN;
@@ -822,7 +823,7 @@ extern tBTA_JV_STATUS BTA_JvRfcommConfig(BOOLEAN enable_l2cap_ertm);
**
** Function BTA_JvRfcommConnect
**
-** Description This function makes an RFCOMM conection to a remote BD
+** Description This function makes an RFCOMM connection to a remote BD
** Address.
** When the connection is initiated or failed to initiate,
** tBTA_JV_RFCOMM_CBACK is called with BTA_JV_RFCOMM_CL_INIT_EVT
@@ -956,7 +957,7 @@ UINT16 BTA_JvRfcommGetPortHdl(UINT32 handle);
** Parameters: handle, JV handle from RFCOMM or L2CAP
** app_id: app specific pm ID, can be BTA_JV_PM_ALL, see bta_dm_cfg.c for details
** BTA_JV_PM_ID_CLEAR: removes pm management on the handle. init_st is ignored and
- ** BTA_JV_CONN_CLOSE is called implicitely
+ ** BTA_JV_CONN_CLOSE is called implicitly
** init_st: state after calling this API. typically it should be BTA_JV_CONN_OPEN
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_pba_client_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_pba_client_api.h
new file mode 100644
index 00000000..404f8ffd
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_pba_client_api.h
@@ -0,0 +1,92 @@
+/*
+ * 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 "bta/bta_pba_defs.h"
+
+#if BTA_PBA_CLIENT_INCLUDED
+
+/* Phone Book Access Profile (client) version */
+#define PBAP_PCE_VERSION 0x102 /* v1.2 */
+#define PBAP_PCE_SUPPORTED_FEATURES 0x0000003F /* support all features */
+
+/* PBA Client callback events */
+#define BTA_PBA_CLIENT_ENABLE_EVT 0 /* PBA Client enabled */
+#define BTA_PBA_CLIENT_DISABLE_EVT 1 /* PBA Client disabled */
+#define BTA_PBA_CLIENT_REGISTER_EVT 2 /* PBA Client registered */
+#define BTA_PBA_CLIENT_DEREGISTER_EVT 3 /* PBA Client deregistered */
+#define BTA_PBA_CLIENT_CONN_OPEN_EVT 4 /* PBA Client connection opened */
+#define BTA_PBA_CLIENT_CONN_CLOSE_EVT 5 /* PBA Client connection closed */
+#define BTA_PBA_CLIENT_PULL_PHONE_BOOK_RSP_EVT 6 /* PBA Client pull phone book response */
+#define BTA_PBA_CLIENT_SET_PHONE_BOOK_RSP_EVT 7 /* PBA Client set phone book response */
+#define BTA_PBA_CLIENT_PULL_VCARD_LISTING_RSP_EVT 8 /* PBA Client pull vCard listing response */
+#define BTA_PBA_CLIENT_PULL_VCARD_ENTRY_RSP_EVT 9 /* PBA Client pull vCard entry response */
+
+typedef enum {
+ BTA_PBA_CLIENT_NO_ERROR, /* operation success */
+ BTA_PBA_CLIENT_FAIL, /* general fail */
+ BTA_PBA_CLIENT_ALREADY_CONN, /* connection to peer device already exist */
+ BTA_PBA_CLIENT_NO_RESOURCE, /* no resource */
+ BTA_PBA_CLIENT_SDP_ERROR, /* error in sdp */
+ BTA_PBA_CLIENT_GOEP_ERROR, /* error in goep */
+ BTA_PBA_CLIENT_AUTH_FAIL, /* authenticate failed */
+ BTA_PBA_CLIENT_DISABLE, /* operation failed due to pba client is disable */
+
+ /* these error code is related to OBEX */
+ BTA_PBA_CLIENT_BAD_REQUEST = 0xC0, /* Server couldn't understand request */
+ BTA_PBA_CLIENT_UNAUTHORIZED = 0xC1, /* Unauthorized */
+ BTA_PBA_CLIENT_FORBIDDEN = 0xC3, /* Operation is understood but refused > */
+ BTA_PBA_CLIENT_NOT_FOUND = 0xC4, /* Not found */
+ BTA_PBA_CLIENT_NOT_ACCEPTABLE = 0xC6, /* Not Acceptable */
+ BTA_PBA_CLIENT_PRECONDITION_FAILED = 0xCC, /* Precondition failed */
+ BTA_PBA_CLIENT_NOT_IMPLEMENTED = 0xD1, /* Not implemented */
+ BTA_PBA_CLIENT_SERVICE_UNAVAILABLE = 0xD3, /* Service unavailable */
+} tBTA_PBA_CLIENT_ERR;
+
+typedef struct {
+ UINT16 handle; /* connection handle */
+ tBTA_PBA_CLIENT_ERR error; /* error code */
+ BD_ADDR bd_addr; /* peer BD addr */
+ UINT8 peer_supported_repo; /* peer supported repositories */
+ UINT32 peer_supported_feat; /* peer supported feature */
+} tBTA_PBA_CLIENT_CONN;
+
+typedef struct {
+ tBTA_PBA_CLIENT_ERR status;
+ UINT16 handle; /* connection handle */
+ BOOLEAN final; /* final data event */
+ UINT8 *data; /* body data in response packet */
+ UINT16 data_len; /* body data length */
+ UINT8 *app_param; /* application parameters */
+ UINT16 app_param_len; /* application parameters length */
+ BT_HDR *pkt; /* raw buff that store all data, should be freed before return */
+} tBTA_PBA_CLIENT_RESPONSE;
+
+/* union of data associated with PBA Client callback */
+typedef union {
+ tBTA_PBA_CLIENT_CONN conn; /* CONN_OPEN_EVT, CONN_CLOSE_EVT */
+ tBTA_PBA_CLIENT_RESPONSE response; /* XXX_RSP_EVT */
+} tBTA_PBA_CLIENT;
+
+typedef UINT8 tBTA_PBA_CLIENT_EVT;
+
+typedef void (tBTA_PBA_CLIENT_CBACK)(tBTA_PBA_CLIENT_EVT event, tBTA_PBA_CLIENT *p_data);
+
+void BTA_PbaClientEnable(tBTA_PBA_CLIENT_CBACK *p_cback);
+void BTA_PbaClientDisable(void);
+void BTA_PbaClientRegister(const char *server_name);
+void BTA_PbaClientDeregister(void);
+void BTA_PbaClientOpen(BD_ADDR bd_addr, tBTA_SEC sec_mask, UINT32 supported_feat, UINT16 mtu);
+void BTA_PbaClientClose(UINT16 handle);
+void BTA_PbaClientPullPhoneBook(UINT16 handle, char *name, UINT8 *app_param, UINT16 app_param_len);
+void BTA_PbaClientSetPhoneBook(UINT16 handle, UINT8 flags, char *name);
+void BTA_PbaClientPullvCardListing(UINT16 handle, char *name, UINT8 *app_param, UINT16 app_param_len);
+void BTA_PbaClientPullvCardEntry(UINT16 handle, char *name, UINT8 *app_param, UINT16 app_param_len);
+
+#endif
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_pba_defs.h b/lib/bt/host/bluedroid/bta/include/bta/bta_pba_defs.h
new file mode 100644
index 00000000..ce92f9cd
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_pba_defs.h
@@ -0,0 +1,93 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+/* PBAP supported repositories */
+#define BTA_PBAP_REPO_LOCAL_PHONEBOOK 0x01
+#define BTA_PBAP_REPO_SIM_CARD 0x02
+#define BTA_PBAP_REPO_SPEED_DIAL 0x04
+#define BTA_PBAP_REPO_FAVORITES 0x08
+
+/* PBAP supported features */
+#define BTA_PBAP_FEAT_DOWNLOAD 0x0001
+#define BTA_PBAP_FEAT_BROWSING 0x0002
+#define BTA_PBAP_FEAT_DATABASE_IDENTIFIER 0x0004
+#define BTA_PBAP_FEAT_FLODER_VERSION_COUNTER 0x0008
+#define BTA_PBAP_FEAT_VCARD_SELECTING 0x0010
+#define BTA_PBAP_FEAT_ENHANCED_MISSED_CALLS 0x0020
+#define BTA_PBAP_FEAT_X_BT_UCI_VCARD_PROPERTY 0x0040
+#define BTA_PBAP_FEAT_X_BT_UID_VCARD_PROPERTY 0x0080
+#define BTA_PBAP_FEAT_CONTACT_REFERENCING 0x0100
+#define BTA_PBAP_FEAT_DEFAULT_CONTACT_IMAGE_FORMAT 0x0200
+
+/* PBAP default supported features */
+#define BTA_PBAP_DEFAULT_SUPPORTED_FEATURES 0x0003
+
+/* Application parameters tag id */
+#define BTA_PBAP_APP_PARAM_ORDER 0x01
+#define BTA_PBAP_APP_PARAM_SEARCH_VALUE 0x02
+#define BTA_PBAP_APP_PARAM_SEARCH_PROPERTY 0x03
+#define BTA_PBAP_APP_PARAM_MAX_LIST_COUNT 0x04
+#define BTA_PBAP_APP_PARAM_LIST_START_OFFSET 0x05
+#define BTA_PBAP_APP_PARAM_PROPERTY_SELECTOR 0x06
+#define BTA_PBAP_APP_PARAM_FORMAT 0x07
+#define BTA_PBAP_APP_PARAM_PHONE_BOOK_SIZE 0x08
+#define BTA_PBAP_APP_PARAM_NEW_MISSED_CALLS 0x09
+#define BTA_PBAP_APP_PARAM_PRIMARY_FOLDER_VERSION 0x0A
+#define BTA_PBAP_APP_PARAM_SECONDARY_FOLDER_VERSION 0x0B
+#define BTA_PBAP_APP_PARAM_VCARD_SELECTOR 0x0C
+#define BTA_PBAP_APP_PARAM_DATABASE_IDENTIFIER 0x0D
+#define BTA_PBAP_APP_PARAM_VCARD_SELECTOR_OPERATOR 0x0E
+#define BTA_PBAP_APP_PARAM_RESET_NEW_MISSED_CALLS 0x0F
+#define BTA_PBAP_APP_PARAM_PBAP_SUPPORTED_FEATURES 0x10
+
+/* Application parameters length (except SearchValue) */
+#define BTA_PBAP_APP_PARAM_LENGTH_ORDER 1
+#define BTA_PBAP_APP_PARAM_LENGTH_SEARCH_PROPERTY 1
+#define BTA_PBAP_APP_PARAM_LENGTH_MAX_LIST_COUNT 2
+#define BTA_PBAP_APP_PARAM_LENGTH_LIST_START_OFFSET 2
+#define BTA_PBAP_APP_PARAM_LENGTH_PROPERTY_SELECTOR 8
+#define BTA_PBAP_APP_PARAM_LENGTH_FORMAT 1
+#define BTA_PBAP_APP_PARAM_LENGTH_PHONE_BOOK_SIZE 2
+#define BTA_PBAP_APP_PARAM_LENGTH_NEW_MISSED_CALLS 1
+#define BTA_PBAP_APP_PARAM_LENGTH_PRIMARY_FOLDER_VERSION 16
+#define BTA_PBAP_APP_PARAM_LENGTH_SECONDARY_FOLDER_VERSION 16
+#define BTA_PBAP_APP_PARAM_LENGTH_VCARD_SELECTOR 8
+#define BTA_PBAP_APP_PARAM_LENGTH_DATABASE_IDENTIFIER 16
+#define BTA_PBAP_APP_PARAM_LENGTH_VCARD_SELECTOR_OPERATOR 1
+#define BTA_PBAP_APP_PARAM_LENGTH_RESET_NEW_MISSED_CALLS 1
+#define BTA_PBAP_APP_PARAM_LENGTH_PBAP_SUPPORTED_FEATURES 4
+
+/* Application parameter tag (1 byte) + Application parameter length (1 byte) */
+#define BTA_PBAP_APP_PARAM_HEADER_LENGTH 2
+
+/* The minimal buff size that can hold all pull phone book application parameters */
+#define BTA_PBAP_PULL_PHONE_BOOK_APP_PARAM_BUFF_SIZE_MIN 37
+
+/* The minimal buff size that can hold pull vCard listing application parameters, except the value of SearchValue */
+#define BTA_PBAP_PULL_VCARD_LISTING_APP_PARAM_BUFF_SIZE_MIN 34
+
+/* The minimal buff size that can hold all pull vCard entry application parameters */
+#define BTA_PBAP_PULL_VCARD_ENTRY_APP_PARAM_BUFF_SIZE_MIN 13
+
+/* Application parameters bit mask */
+#define PBAP_APP_PARAM_BIT_MASK_ORDER 0x0001
+#define PBAP_APP_PARAM_BIT_MASK_SEARCH_VALUE 0x0002
+#define PBAP_APP_PARAM_BIT_MASK_SEARCH_PROPERTY 0x0004
+#define PBAP_APP_PARAM_BIT_MASK_MAX_LIST_COUNT 0x0008
+#define PBAP_APP_PARAM_BIT_MASK_LIST_START_OFFSET 0x0010
+#define PBAP_APP_PARAM_BIT_MASK_PROPERTY_SELECTOR 0x0020
+#define PBAP_APP_PARAM_BIT_MASK_FORMAT 0x0040
+#define PBAP_APP_PARAM_BIT_MASK_PHONE_BOOK_SIZE 0x0080
+#define PBAP_APP_PARAM_BIT_MASK_NEW_MISSED_CALLS 0x0100
+#define PBAP_APP_PARAM_BIT_MASK_PRIMARY_FOLDER_VERSION 0x0200
+#define PBAP_APP_PARAM_BIT_MASK_SECONDARY_FOLDER_VERSION 0x0400
+#define PBAP_APP_PARAM_BIT_MASK_VCARD_SELECTOR 0x0800
+#define PBAP_APP_PARAM_BIT_MASK_DATABASE_IDENTIFIER 0x1000
+#define PBAP_APP_PARAM_BIT_MASK_VCARD_SELECTOR_OPERATOR 0x2000
+#define PBAP_APP_PARAM_BIT_MASK_RESET_NEW_MISSED_CALLS 0x4000
+#define PBAP_APP_PARAM_BIT_MASK_PBAP_SUPPORTED_FEATURES 0x8000
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h b/lib/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h
index 62b5228a..fadc8183 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h
@@ -41,7 +41,7 @@ typedef UINT8 tBTA_SDP_STATUS;
/* SDP I/F callback events */
/* events received by tBTA_SDP_DM_CBACK */
#define BTA_SDP_ENABLE_EVT 0 /* SDP service enabled */
-#define BTA_SDP_DISENABLE_EVT 1 /* SDP service disenabled */
+#define BTA_SDP_DISABLE_EVT 1 /* SDP service disenabled */
#define BTA_SDP_SEARCH_EVT 2 /* SDP search started */
#define BTA_SDP_SEARCH_COMP_EVT 3 /* SDP search complete */
#define BTA_SDP_CREATE_RECORD_USER_EVT 4 /* SDP create record complete */
@@ -67,10 +67,17 @@ typedef struct {
int handle;
} tBTA_SDP_CREATE_RECORD_USER;
+/* data associated with BTA_SDP_REMOVE_RECORD_USER_EVT */
+typedef struct {
+ tBTA_SDP_STATUS status;
+ int handle;
+} tBTA_SDP_REMOVE_RECORD_USER;
+
typedef union {
tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */
tBTA_SDP_SEARCH_COMP sdp_search_comp; /* BTA_SDP_SEARCH_COMP_EVT */
tBTA_SDP_CREATE_RECORD_USER sdp_create_record; /* BTA_SDP_CREATE_RECORD_USER_EVT */
+ tBTA_SDP_REMOVE_RECORD_USER sdp_remove_record; /* BTA_SDP_REMOVE_RECORD_USER_EVT */
} tBTA_SDP;
/* SDP DM Interface callback */
@@ -78,9 +85,11 @@ typedef void (tBTA_SDP_DM_CBACK)(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *use
/* MCE configuration structure */
typedef struct {
- UINT16 sdp_db_size; /* The size of p_sdp_db */
+ UINT16 sdp_raw_size; /* The size of p_sdp_raw_data */
+ UINT16 sdp_db_size; /* The size of p_sdp_db */
#if (SDP_INCLUDED == TRUE)
- tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */
+ UINT8 *p_sdp_raw_data; /* The data buffer to keep raw data */
+ tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */
#endif ///SDP_INCLUDED == TRUE
} tBTA_SDP_CFG;
@@ -108,14 +117,28 @@ extern tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback);
**
** Function BTA_SdpDisable
**
-** Description Disable the SDP search I/F service.
+** Description This function is used to request a callback to perform disable
+** operation. The registered callback will be called with event
+** BTA_SDP_DISABLE_EVT.
+**
+** Returns BTA_SDP_SUCCESS, if the request is being processed.
+** BTA_SDP_FAILURE, otherwise.
+**
+*******************************************************************************/
+extern tBTA_SDP_STATUS BTA_SdpDisable(void);
+
+/*******************************************************************************
+**
+** Function BTA_SdpCleanup
+**
+** Description Cleanup the SDP search I/F service.
** Free buffer for SDP configuration structure.
**
** Returns BTA_SDP_SUCCESS if successful.
** BTA_SDP_FAIL if internal failure.
**
*******************************************************************************/
-extern tBTA_SDP_STATUS BTA_SdpDisable(void);
+extern tBTA_SDP_STATUS BTA_SdpCleanup(void);
/*******************************************************************************
**
diff --git a/lib/bt/host/bluedroid/bta/include/bta/bta_sys.h b/lib/bt/host/bluedroid/bta/include/bta/bta_sys.h
index 54376de6..ecf47919 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/bta_sys.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/bta_sys.h
@@ -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
diff --git a/lib/bt/host/bluedroid/bta/include/bta/utl.h b/lib/bt/host/bluedroid/bta/include/bta/utl.h
index a140832f..9dd46a75 100644
--- a/lib/bt/host/bluedroid/bta/include/bta/utl.h
+++ b/lib/bt/host/bluedroid/bta/include/bta/utl.h
@@ -36,6 +36,7 @@
#define BTA_UTL_CLR_COD_SERVICE_CLASS 0x04
#define BTA_UTL_SET_COD_ALL 0x08 /* take service class as the input (may clear some set bits!!) */
#define BTA_UTL_INIT_COD 0x0a
+#define BTA_UTL_SET_COD_RESERVED_2 0x10 /* overwrite the two least significant bits reserved_2 */
/*****************************************************************************
** Type Definitions
@@ -43,6 +44,7 @@
/** for utl_set_device_class() **/
typedef struct {
+ UINT8 reserved_2;
UINT8 minor;
UINT8 major;
UINT16 service;
@@ -125,11 +127,12 @@ extern void utl_freebuf(void **p);
** p_cod - Pointer to the device class to set to
**
** cmd - the fields of the device class to update.
+** BTA_UTL_SET_COD_RESERVED_2 - overwrite the two least significant bits reserved_2
** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class
** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input
** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input
-** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class
-** BTA_UTL_INIT_COD - overwrite major, minor, and service class
+** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class, reserved_2 remain unchanged
+** BTA_UTL_INIT_COD - overwrite major, minor, and service class, reserved_2 remain unchanged
**
** Returns TRUE if successful, Otherwise FALSE
**
diff --git a/lib/bt/host/bluedroid/bta/jv/bta_jv_act.c b/lib/bt/host/bluedroid/bta/jv/bta_jv_act.c
index 214ef746..17eba5ed 100644
--- a/lib/bt/host/bluedroid/bta/jv/bta_jv_act.c
+++ b/lib/bt/host/bluedroid/bta/jv/bta_jv_act.c
@@ -899,6 +899,7 @@ void bta_jv_free_scn(tBTA_JV_MSG *p_data)
}
case BTA_JV_CONN_TYPE_L2CAP:
bta_jv_set_free_psm(scn);
+ user_data = (tBTA_JV_FREE_SCN_USER_DATA *)fc->user_data;
if (fc->p_cback) {
fc->p_cback(BTA_JV_FREE_SCN_EVT, (tBTA_JV *)&evt_data, (void *)user_data);
}
@@ -1058,7 +1059,7 @@ void sdp_bqb_add_language_attr_ctrl(BOOLEAN enable)
/**
* @brief Adds a protocol list and service name (if provided) to an SDP record given by
- * sdp_handle, and marks it as browseable. This is a shortcut for defining a
+ * sdp_handle, and marks it as browsable. This is a shortcut for defining a
* set of protocols that includes L2CAP, RFCOMM, and optionally OBEX.
*
* @param[in] sdp_handle: SDP handle
@@ -1133,9 +1134,9 @@ static bool create_base_record(const uint32_t sdp_handle, const char *name, cons
}
}
- // Mark the service as browseable.
+ // Mark the service as browsable.
uint16_t list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
- stage = "browseable";
+ stage = "browsable";
if (!SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list)){
APPL_TRACE_ERROR("create_base_record: failed to create base service "
"record, stage: %s, scn: %d, name: %s, with_obex: %d",
@@ -1389,6 +1390,7 @@ void bta_jv_l2cap_close(tBTA_JV_MSG *p_data)
evt_data.handle = cc->handle;
evt_data.status = bta_jv_free_l2c_cb(cc->p_cb);
evt_data.async = FALSE;
+ evt_data.user_data = (void *)cc->user_data;
if (cc->p_cback) {
cc->p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
@@ -1542,19 +1544,13 @@ void bta_jv_l2cap_start_server(tBTA_JV_MSG *p_data)
void bta_jv_l2cap_stop_server(tBTA_JV_MSG *p_data)
{
tBTA_JV_L2C_CB *p_cb;
- tBTA_JV_L2CAP_CLOSE evt_data;
tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
- tBTA_JV_L2CAP_CBACK *p_cback;
- void *user_data;
+
for (int i = 0; i < BTA_JV_MAX_L2C_CONN; i++) {
if (bta_jv_cb.l2c_cb[i].psm == ls->local_psm) {
p_cb = &bta_jv_cb.l2c_cb[i];
- p_cback = p_cb->p_cback;
- user_data = p_cb->user_data;
- evt_data.handle = p_cb->handle;
- evt_data.status = bta_jv_free_l2c_cb(p_cb);
- evt_data.async = FALSE;
- p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
+ bta_jv_free_l2c_cb(p_cb);
+ // Report event when free psm
break;
}
}
@@ -1754,6 +1750,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat
evt_data.rfc_close.status = BTA_JV_FAILURE;
evt_data.rfc_close.port_status = code;
evt_data.rfc_close.async = TRUE;
+ evt_data.rfc_close.user_data = p_pcb->user_data;
if (p_pcb->state == BTA_JV_ST_CL_CLOSING) {
evt_data.rfc_close.async = FALSE;
evt_data.rfc_close.status = BTA_JV_SUCCESS;
@@ -2082,6 +2079,7 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat
evt_data.rfc_close.status = BTA_JV_FAILURE;
evt_data.rfc_close.async = TRUE;
evt_data.rfc_close.port_status = code;
+ evt_data.rfc_close.user_data = user_data;
p_pcb->cong = FALSE;
tBTA_JV_RFCOMM_CBACK *p_cback = p_cb->p_cback;
diff --git a/lib/bt/host/bluedroid/bta/pba/bta_pba_client_act.c b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_act.c
new file mode 100644
index 00000000..7ed5aaa8
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_act.c
@@ -0,0 +1,702 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+
+#include "osi/allocator.h"
+#include "common/bt_target.h"
+#include "stack/bt_types.h"
+#include "stack/obex_api.h"
+#include "stack/goep_common.h"
+#include "stack/goepc_api.h"
+#include "bta_pba_client_int.h"
+
+#if BTA_PBA_CLIENT_INCLUDED
+
+static const UINT8 pbap_target_uuid[16] = {0x79, 0x61, 0x35, 0xf0, 0xf0, 0xc5, 0x11, 0xd8, 0x09, 0x66, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66};
+static const char *type_pull_phone_book = "x-bt/phonebook";
+static const char *type_pull_vcard_listing = "x-bt/vcard-listing";
+static const char *type_pull_vcard_entry = "x-bt/vcard";
+
+#define TYPE_LEN_PULL_PHONE_BOOK 15
+#define TYPE_LEN_PULL_VCARD_LISTING 19
+#define TYPE_LEN_PULL_VCARD_ENTRY 11
+
+static void free_ccb(tBTA_PBA_CLIENT_CCB *p_ccb)
+{
+ /* free sdp db */
+ bta_pba_client_free_db(p_ccb);
+
+ /* clear all field, set allocated to 0 */
+ memset(p_ccb, 0, sizeof(tBTA_PBA_CLIENT_CCB));
+}
+
+static void close_goepc_and_report(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_ERR reason)
+{
+ /* remove goep connection */
+ if (p_ccb->goep_handle != 0) {
+ GOEPC_Close(p_ccb->goep_handle);
+ p_ccb->goep_handle = 0;
+ }
+
+ /* report connection closed event */
+ tBTA_PBA_CLIENT_CONN conn;
+ conn.handle = p_ccb->allocated;
+ conn.error = reason;
+ bdcpy(conn.bd_addr, p_ccb->bd_addr);
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_CONN_CLOSE_EVT, (tBTA_PBA_CLIENT *)&conn);
+
+ /* free ccb */
+ free_ccb(p_ccb);
+}
+
+static void build_and_send_empty_get_req(tBTA_PBA_CLIENT_CCB *p_ccb)
+{
+ tOBEX_PARSE_INFO info = {0};
+ info.opcode = OBEX_OPCODE_GET_FINAL;
+ /* empty get request, try to use a smaller buff size */
+ UINT16 tx_buff_size = BT_SMALL_BUFFER_SIZE < p_ccb->max_tx ? BT_SMALL_BUFFER_SIZE : p_ccb->max_tx;
+ UINT16 ret = GOEPC_PrepareRequest(p_ccb->goep_handle, &info, tx_buff_size);
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_CONNECTION_ID, (UINT8 *)(&p_ccb->goep_cid), 4);
+ ret |= GOEPC_SendRequest(p_ccb->goep_handle);
+ if (ret != GOEP_SUCCESS) {
+ close_goepc_and_report(p_ccb, BTA_PBA_CLIENT_GOEP_ERROR);
+ }
+}
+
+static uint8_t get_operation_response_event(tBTA_PBA_CLIENT_OP operation)
+{
+ uint8_t event = 0;
+ switch (operation)
+ {
+ case BTA_PBA_CLIENT_OP_PULL_PHONE_BOOK:
+ event = BTA_PBA_CLIENT_PULL_PHONE_BOOK_RSP_EVT;
+ break;
+ case BTA_PBA_CLIENT_OP_SET_PHONE_BOOK:
+ event = BTA_PBA_CLIENT_SET_PHONE_BOOK_RSP_EVT;
+ break;
+ case BTA_PBA_CLIENT_OP_PULL_VCARD_LISTING:
+ event = BTA_PBA_CLIENT_PULL_VCARD_LISTING_RSP_EVT;
+ break;
+ case BTA_PBA_CLIENT_OP_PULL_VCARD_ENTRY:
+ event = BTA_PBA_CLIENT_PULL_VCARD_ENTRY_RSP_EVT;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return event;
+}
+
+static tBTA_PBA_CLIENT_ERR calculate_response_error(uint8_t response_code)
+{
+ tBTA_PBA_CLIENT_ERR error = BTA_PBA_CLIENT_FAIL;
+ /* always treat error response code as final response */
+ response_code |= OBEX_FINAL_BIT_MASK;
+ switch (response_code)
+ {
+ case (OBEX_RESPONSE_CODE_BAD_REQUEST | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_BAD_REQUEST;
+ break;
+ case (OBEX_RESPONSE_CODE_UNAUTHORIZED | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_UNAUTHORIZED;
+ break;
+ case (OBEX_RESPONSE_CODE_FORBIDDEN | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_FORBIDDEN;
+ break;
+ case (OBEX_RESPONSE_CODE_NOT_FOUND | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_NOT_FOUND;
+ break;
+ case (OBEX_RESPONSE_CODE_NOT_ACCEPTABLE | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_NOT_ACCEPTABLE;
+ break;
+ case (OBEX_RESPONSE_CODE_PRECONDITION_FAILED | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_PRECONDITION_FAILED;
+ break;
+ case (OBEX_RESPONSE_CODE_NOT_IMPLEMENTED | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_NOT_IMPLEMENTED;
+ break;
+ case (OBEX_RESPONSE_CODE_SERVICE_UNAVAILABLE | OBEX_FINAL_BIT_MASK):
+ error = BTA_PBA_CLIENT_SERVICE_UNAVAILABLE;
+ break;
+ default:
+ break;
+ }
+ return error;
+}
+
+static void report_data_event(tBTA_PBA_CLIENT_CCB *p_ccb, UINT8 *data, UINT16 data_len, UINT8 *app_param,
+ UINT16 app_param_len, BOOLEAN final, BT_HDR *pkt)
+{
+ uint8_t event = get_operation_response_event(p_ccb->operation);
+ tBTA_PBA_CLIENT_RESPONSE response;
+ response.status = BTA_PBA_CLIENT_NO_ERROR;
+ response.handle = p_ccb->allocated;
+ response.final = final;
+ response.data_len = data_len;
+ response.data = data;
+ response.app_param_len = app_param_len;
+ response.app_param = app_param;
+ response.pkt = pkt;
+ bta_pba_client_cb.p_cback(event, (tBTA_PBA_CLIENT *)&response);
+}
+
+static void report_error_data_event(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_ERR status)
+{
+ uint8_t event = get_operation_response_event(p_ccb->operation);
+ tBTA_PBA_CLIENT_RESPONSE response;
+ memset(&response, 0, sizeof(tBTA_PBA_CLIENT_RESPONSE));
+ response.status = status;
+ response.handle = p_ccb->allocated;
+ response.final = TRUE;
+ bta_pba_client_cb.p_cback(event, (tBTA_PBA_CLIENT *)&response);
+}
+
+static void ascii_to_utf16(const UINT8 *src, UINT16 len, UINT8 *dst)
+{
+ UINT16 pos = 0;
+ for (int i = 0 ; i < len ; i++){
+ dst[pos++] = 0;
+ dst[pos++] = src[i];
+ }
+}
+
+void bta_pba_client_api_enable(tBTA_PBA_CLIENT_DATA *p_data)
+{
+ /* initialize control block */
+ memset(&bta_pba_client_cb, 0, sizeof(tBTA_PBA_CLIENT_CB));
+
+ /* store callback function */
+ bta_pba_client_cb.p_cback = p_data->api_enable.p_cback;
+
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_ENABLE_EVT, NULL);
+}
+
+void bta_pba_client_api_disable(tBTA_PBA_CLIENT_DATA *p_data)
+{
+ if (!bta_sys_is_register(BTA_ID_PBC)) {
+ return;
+ }
+ /* deregister with BTA system manager */
+ bta_sys_deregister(BTA_ID_PBC);
+
+ /* close all connections */
+ for (int i = 0; i < PBA_CLIENT_MAX_CONNECTION; ++i) {
+ if (bta_pba_client_cb.ccb[i].allocated) {
+ close_goepc_and_report(&bta_pba_client_cb.ccb[i], BTA_PBA_CLIENT_DISABLE);
+ }
+ }
+
+ /* store and clear callback function */
+ tBTA_PBA_CLIENT_CBACK *p_cback = bta_pba_client_cb.p_cback;
+ bta_pba_client_cb.p_cback = NULL;
+
+ if(p_cback) {
+ p_cback(BTA_PBA_CLIENT_DISABLE_EVT, NULL);
+ }
+}
+
+void bta_pba_client_api_register(tBTA_PBA_CLIENT_DATA *p_data)
+{
+ /* create SDP records */
+ bta_pba_client_create_record(p_data->api_register.name);
+
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_REGISTER_EVT, NULL);
+}
+
+void bta_pba_client_api_deregister(tBTA_PBA_CLIENT_DATA *p_data)
+{
+ /* delete SDP records */
+ bta_pba_client_del_record();
+
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_DEREGISTER_EVT, NULL);
+}
+
+void bta_pba_client_api_open(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ p_ccb->sec_mask = p_data->api_open.sec_mask;
+ if (p_data->api_open.mtu < PBA_CLIENT_MIN_MTU || p_data->api_open.mtu > PBA_CLIENT_MAX_MTU) {
+ p_ccb->max_rx = PBA_CLIENT_MAX_MTU;
+ p_ccb->max_tx = PBA_CLIENT_MAX_MTU;
+ }
+ else {
+ p_ccb->max_rx = p_data->api_open.mtu;
+ p_ccb->max_tx = p_data->api_open.mtu;
+ }
+ bdcpy(p_ccb->bd_addr, p_data->api_open.bd_addr);
+ p_ccb->our_supported_feat = p_data->api_open.supported_feat;
+ if (!bta_pba_client_do_disc(p_ccb)) {
+ close_goepc_and_report(p_ccb, BTA_PBA_CLIENT_SDP_ERROR);
+ }
+}
+
+void bta_pba_client_api_close(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ UNUSED(p_data);
+ tOBEX_PARSE_INFO info = {0};
+
+ info.opcode = OBEX_OPCODE_DISCONNECT;
+ UINT16 tx_buff_size = BT_SMALL_BUFFER_SIZE < p_ccb->max_tx ? BT_SMALL_BUFFER_SIZE : p_ccb->max_tx;
+ UINT16 ret = GOEPC_PrepareRequest(p_ccb->goep_handle, &info, tx_buff_size);
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_CONNECTION_ID, (UINT8 *)(&p_ccb->goep_cid), 4);
+ ret |= GOEPC_SendRequest(p_ccb->goep_handle);
+
+ if (ret != GOEP_SUCCESS) {
+ /* anyway, this close operation is requested by upper, set reason to success */
+ close_goepc_and_report(p_ccb, BTA_PBA_CLIENT_NO_ERROR);
+ }
+}
+
+void bta_pba_client_api_req(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ tOBEX_PARSE_INFO info = {0};
+ UINT16 ret;
+
+ if (p_data->api_req.operation == BTA_PBA_CLIENT_OP_SET_PHONE_BOOK) {
+ info.opcode = OBEX_OPCODE_SETPATH;
+ info.flags = p_data->api_req.flags;
+ }
+ else {
+ info.opcode = OBEX_OPCODE_GET_FINAL;
+ }
+ ret = GOEPC_PrepareRequest(p_ccb->goep_handle, &info, p_ccb->max_tx);
+ if (ret != GOEP_SUCCESS) {
+ goto error;
+ }
+
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_CONNECTION_ID, (UINT8 *)(&p_ccb->goep_cid), 4);
+
+ if (p_data->api_req.operation != BTA_PBA_CLIENT_OP_SET_PHONE_BOOK) {
+ ret |= GOEPC_RequestSetSRM(p_ccb->goep_handle, TRUE, FALSE);
+ }
+
+ if (p_data->api_req.name) {
+ UINT16 name_len = strlen(p_data->api_req.name) + 1;
+ if (name_len == 1) {
+ /* empty string, add empty name header */
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_NAME, NULL, 0);
+ }
+ else {
+ UINT8 *utf16_name = osi_malloc(2 * name_len);
+ assert(utf16_name != NULL);
+ ascii_to_utf16((UINT8 *)p_data->api_req.name, name_len, utf16_name);
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_NAME, utf16_name, 2 * name_len);
+ osi_free(utf16_name);
+ }
+ osi_free(p_data->api_req.name);
+ p_data->api_req.name = NULL;
+ }
+
+ switch (p_data->api_req.operation)
+ {
+ case BTA_PBA_CLIENT_OP_PULL_PHONE_BOOK:
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_TYPE, (const UINT8 *)type_pull_phone_book, TYPE_LEN_PULL_PHONE_BOOK);
+ break;
+ case BTA_PBA_CLIENT_OP_PULL_VCARD_LISTING:
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_TYPE, (const UINT8 *)type_pull_vcard_listing, TYPE_LEN_PULL_VCARD_LISTING);
+ break;
+ case BTA_PBA_CLIENT_OP_PULL_VCARD_ENTRY:
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_TYPE, (const UINT8 *)type_pull_vcard_entry, TYPE_LEN_PULL_VCARD_ENTRY);
+ break;
+ default:
+ break;
+ }
+
+ if (p_data->api_req.app_param) {
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_APP_PARAM, p_data->api_req.app_param, p_data->api_req.app_param_len);
+ osi_free(p_data->api_req.app_param);
+ }
+
+ ret |= GOEPC_SendRequest(p_ccb->goep_handle);
+ p_ccb->operation = p_data->api_req.operation;
+ if (ret != GOEP_SUCCESS) {
+ goto error;
+ }
+ return;
+
+error:
+ if (p_data->api_req.name) {
+ osi_free(p_data->api_req.name);
+ }
+ if (p_data->api_req.app_param) {
+ osi_free(p_data->api_req.app_param);
+ }
+ close_goepc_and_report(p_ccb, BTA_PBA_CLIENT_GOEP_ERROR);
+}
+
+static void goep_event_callback(UINT16 handle, UINT8 event, tGOEPC_MSG *p_msg)
+{
+ tBTA_PBA_CLIENT_DATA *p_data = NULL;
+
+ switch (event)
+ {
+ case GOEPC_OPENED_EVT:
+ p_data = (tBTA_PBA_CLIENT_DATA *)osi_malloc(sizeof(tBTA_PBA_CLIENT_DATA));
+ assert(p_data != NULL);
+ p_data->goep_connect.hdr.event = BTA_PBA_CLIENT_GOEP_CONNECT_EVT;
+ p_data->goep_connect.hdr.layer_specific = handle;
+ p_data->goep_connect.our_mtu = p_msg->opened.our_mtu;
+ p_data->goep_connect.peer_mtu = p_msg->opened.peer_mtu;
+ break;
+ case GOEPC_CLOSED_EVT:
+ p_data = (tBTA_PBA_CLIENT_DATA *)osi_malloc(sizeof(tBTA_PBA_CLIENT_DATA));
+ assert(p_data != NULL);
+ p_data->goep_disconnect.hdr.event = BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT;
+ p_data->goep_disconnect.hdr.layer_specific = handle;
+ p_data->goep_disconnect.reason = p_msg->closed.reason;
+ break;
+ case GOEPC_RESPONSE_EVT:
+ p_data = (tBTA_PBA_CLIENT_DATA *)osi_malloc(sizeof(tBTA_PBA_CLIENT_DATA));
+ assert(p_data != NULL);
+ p_data->goep_response.hdr.layer_specific = handle;
+ p_data->goep_response.pkt = p_msg->response.pkt;
+ p_data->goep_response.opcode = p_msg->response.opcode;
+ p_data->goep_response.srm_en = p_msg->response.srm_en;
+ p_data->goep_response.srm_wait = p_msg->response.srm_wait;
+ if (p_msg->response.final) {
+ p_data->goep_response.hdr.event = BTA_PBA_CLIENT_RESPONSE_FINAL_EVT;
+ }
+ else {
+ p_data->hdr.event = BTA_PBA_CLIENT_RESPONSE_EVT;
+ }
+ break;
+ case GOEPC_MTU_CHANGED_EVT:
+ case GOEPC_CONGEST_EVT:
+ case GOEPC_UNCONGEST_EVT:
+ /* ignore these event */
+ break;
+ default:
+ APPL_TRACE_WARNING("%s, unknown goep event: %d", __FUNCTION__, event);
+ break;
+ }
+ if (p_data != NULL) {
+ bta_sys_sendmsg(p_data);
+ }
+}
+
+void bta_pba_client_do_connect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ tBTA_PBA_CLIENT_ERR reason = BTA_PBA_CLIENT_FAIL;
+
+ /* find attr in sdp discovery result */
+ BOOLEAN found = bta_pba_client_sdp_find_attr(p_ccb);
+ if (found) {
+ tOBEX_SVR_INFO svr = {0};
+ if (p_ccb->peer_l2cap_psm != 0) {
+ /* peer support obex over l2cap, use it */
+ svr.tl = OBEX_OVER_L2CAP;
+ svr.l2cap.psm = p_ccb->peer_l2cap_psm;
+ svr.l2cap.sec_mask = p_ccb->sec_mask;
+ svr.l2cap.pref_mtu = 0;
+ bdcpy(svr.l2cap.addr, p_ccb->bd_addr);
+ }
+ else {
+ /* otherwise, use obex over rfcomm */
+ svr.tl = OBEX_OVER_RFCOMM;
+ svr.rfcomm.scn = p_ccb->peer_rfcomm_scn;
+ svr.rfcomm.sec_mask = p_ccb->sec_mask;
+ svr.rfcomm.pref_mtu = 0;
+ bdcpy(svr.rfcomm.addr, p_ccb->bd_addr);
+ }
+
+ if (GOEPC_Open(&svr, goep_event_callback, &p_ccb->goep_handle) == GOEP_SUCCESS) {
+ /* start connection success */
+ return;
+ }
+ else {
+ reason = BTA_PBA_CLIENT_GOEP_ERROR;
+ }
+ }
+ else {
+ reason = BTA_PBA_CLIENT_SDP_ERROR;
+ }
+
+ /* critical sdp attribute not found or start goep connection failed */
+ tBTA_PBA_CLIENT_CONN conn;
+ conn.handle = 0;
+ conn.error = reason;
+ bdcpy(conn.bd_addr, p_ccb->bd_addr);
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_CONN_CLOSE_EVT, (tBTA_PBA_CLIENT *)&conn);
+
+ /* free ccb */
+ free_ccb(p_ccb);
+}
+
+void bta_pba_client_authenticate(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ /* [todo]: support authenticate */
+}
+
+void bta_pba_client_connect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ tBTA_PBA_CLIENT_CONN conn;
+ conn.handle = p_ccb->allocated;
+ conn.peer_supported_repo = p_ccb->peer_supported_repo;
+ conn.peer_supported_feat = p_ccb->peer_supported_feat;
+ conn.error = BTA_PBA_CLIENT_NO_ERROR;
+ bdcpy(conn.bd_addr, p_ccb->bd_addr);
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_CONN_OPEN_EVT, (tBTA_PBA_CLIENT *)&conn);
+}
+
+void bta_pba_client_force_disconnect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ UNUSED(p_data);
+
+ /* force disconnect is requested by upper, set reason to success */
+ close_goepc_and_report(p_ccb, BTA_PBA_CLIENT_NO_ERROR);
+}
+
+void bta_pba_client_response(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ tOBEX_PARSE_INFO info;
+ tBTA_PBA_CLIENT_ERR reason = BTA_PBA_CLIENT_GOEP_ERROR;
+
+ OBEX_ParseResponse(p_data->goep_response.pkt, p_data->goep_response.opcode, &info);
+ if (p_data->goep_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;
+ UINT8 *app_param = NULL;
+ UINT16 app_param_len = 0;
+ while((header = OBEX_GetNextHeader(p_data->goep_response.pkt, &info)) != NULL) {
+ switch (*header)
+ {
+ 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(p_ccb, body_data, body_data_len, NULL, 0, FALSE, NULL);
+ body_data = header + 3; /* skip opcode, length */
+ body_data_len = OBEX_GetHeaderLength(header) - 3;
+ }
+ break;
+ case OBEX_HEADER_ID_APP_PARAM:
+ app_param = header + 3;
+ app_param_len = OBEX_GetHeaderLength(header) - 3;
+ break;
+ default:
+ break;
+ }
+ }
+ if (body_data != NULL || app_param != NULL) {
+ /* report body data and app param, dont free packet here */
+ report_data_event(p_ccb, body_data, body_data_len, app_param, app_param_len, FALSE, p_data->goep_response.pkt);
+ }
+ else {
+ /* not any body data or app param */
+ osi_free(p_data->goep_response.pkt);
+ }
+
+ /* if SRM not enable, we need to send a empty get request */
+ if (!p_data->goep_response.srm_en || p_data->goep_response.srm_wait) {
+ build_and_send_empty_get_req(p_ccb);
+ }
+ }
+ else {
+ /* unexpected opcode or response code */
+ reason = calculate_response_error(info.response_code);
+ goto error;
+ }
+ return;
+
+error:
+ if (p_data->goep_response.pkt != NULL) {
+ osi_free(p_data->goep_response.pkt);
+ }
+ close_goepc_and_report(p_ccb, reason);
+}
+
+void bta_pba_client_response_final(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ tOBEX_PARSE_INFO info;
+ UINT8 *header = NULL;
+ tBTA_PBA_CLIENT_ERR reason = BTA_PBA_CLIENT_FAIL;
+
+ OBEX_ParseResponse(p_data->goep_response.pkt, p_data->goep_response.opcode, &info);
+ if (p_data->goep_response.opcode == OBEX_OPCODE_CONNECT) {
+ if (info.response_code == (OBEX_RESPONSE_CODE_OK | OBEX_FINAL_BIT_MASK)) {
+ /* obex connect success */
+ if (info.max_packet_length < 255) {
+ p_ccb->max_tx = 255;
+ }
+ else if (p_ccb->max_tx > info.max_packet_length) {
+ p_ccb->max_tx = info.max_packet_length;
+ }
+ BOOLEAN cid_found = false;
+ while((header = OBEX_GetNextHeader(p_data->goep_response.pkt, &info)) != NULL) {
+ if (*header == OBEX_HEADER_ID_CONNECTION_ID) {
+ cid_found = true;
+ memcpy((UINT8 *)(&p_ccb->goep_cid), header + 1, 4);
+ break;
+ }
+ }
+ if (!cid_found) {
+ goto error;
+ }
+
+ BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
+ assert(p_buf != NULL);
+ p_buf->event = BTA_PBA_CLIENT_CONNECT_EVT;
+ p_buf->layer_specific = p_ccb->allocated;
+ bta_sys_sendmsg(p_buf);
+ }
+ else if (info.response_code == (OBEX_RESPONSE_CODE_UNAUTHORIZED | OBEX_FINAL_BIT_MASK)){
+ /* need to authenticate */
+ if (p_ccb->authenticate) {
+ /* already try to authenticate, but failed */
+ reason = BTA_PBA_CLIENT_AUTH_FAIL;
+ goto error;
+ }
+
+ p_ccb->authenticate = TRUE;
+ /* [todo]: we don't support authenticate currently */
+ goto error;
+ }
+ else {
+ /* other unexpected response code */
+ goto error;
+ }
+ osi_free(p_data->goep_response.pkt);
+ }
+ else if (p_data->goep_response.opcode == OBEX_OPCODE_GET_FINAL) {
+ /* check response code is success */
+ if (info.response_code == (OBEX_RESPONSE_CODE_OK | OBEX_FINAL_BIT_MASK)) {
+ UINT8 *body_data = NULL;
+ UINT16 body_data_len = 0;
+ UINT8 *app_param = NULL;
+ UINT16 app_param_len = 0;
+ while((header = OBEX_GetNextHeader(p_data->goep_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(p_ccb, body_data, body_data_len, NULL, 0, FALSE, NULL);
+ body_data = header + 3; /* skip opcode, length */
+ body_data_len = OBEX_GetHeaderLength(header) - 3;
+ }
+ break;
+ case OBEX_HEADER_ID_APP_PARAM:
+ app_param = header + 3;
+ app_param_len = OBEX_GetHeaderLength(header) - 3;
+ break;
+ default:
+ break;
+ }
+ }
+ if (body_data != NULL || app_param != NULL) {
+ /* report body data and app param, dont free packet here */
+ report_data_event(p_ccb, body_data, body_data_len, app_param, app_param_len, TRUE, p_data->goep_response.pkt);
+ /* done, return */
+ return;
+ }
+ }
+ /* unexpected response code or body data not found */
+ reason = calculate_response_error(info.response_code);
+ report_error_data_event(p_ccb, reason);
+ osi_free(p_data->goep_response.pkt);
+
+ /* state machine is good, don't goto error */
+ }
+ else if (p_data->goep_response.opcode == OBEX_OPCODE_SETPATH) {
+ if (info.response_code == (OBEX_RESPONSE_CODE_OK | OBEX_FINAL_BIT_MASK)) {
+ report_data_event(p_ccb, NULL, 0, NULL, 0, TRUE, NULL);
+ }
+ else {
+ reason = calculate_response_error(info.response_code);
+ report_error_data_event(p_ccb, reason);
+ }
+ osi_free(p_data->goep_response.pkt);
+ }
+ else if (p_data->goep_response.opcode == OBEX_OPCODE_DISCONNECT) {
+ /* received disconnect response, close goep connection now */
+ reason = BTA_PBA_CLIENT_NO_ERROR;
+ close_goepc_and_report(p_ccb, reason);
+ osi_free(p_data->goep_response.pkt);
+ }
+ else {
+ /* unexpected opcode or response code */
+ reason = calculate_response_error(info.response_code);
+ goto error;
+ }
+ return;
+
+error:
+ if (p_data->goep_response.pkt != NULL) {
+ osi_free(p_data->goep_response.pkt);
+ }
+ close_goepc_and_report(p_ccb, reason);
+}
+
+void bta_pba_client_goep_connect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ /* limit max rx to our goep mtu */
+ if (p_ccb->max_rx > p_data->goep_connect.our_mtu) {
+ p_ccb->max_rx = p_data->goep_connect.our_mtu;
+ }
+ /* limit max tx to peer goep mtu */
+ if (p_ccb->max_tx > p_data->goep_connect.peer_mtu) {
+ p_ccb->max_tx = p_data->goep_connect.peer_mtu;
+ }
+
+ /* build and send obex connect request */
+ tOBEX_PARSE_INFO info = {0};
+ info.opcode = OBEX_OPCODE_CONNECT;
+ info.obex_version_number = OBEX_VERSION_NUMBER;
+ info.max_packet_length = p_ccb->max_rx;
+ /* before obex connect response, we dont know the real max_tx, use BT_SMALL_BUFFER_SIZE as tx buff size */
+ UINT16 ret = GOEPC_PrepareRequest(p_ccb->goep_handle, &info, BT_SMALL_BUFFER_SIZE);
+ /* add target header */
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_TARGET, pbap_target_uuid, 16);
+ if (p_ccb->send_supported_feat) {
+ /* add application parameters with supported features */
+ UINT8 app_param[6];
+ app_param[0] = BTA_PBAP_APP_PARAM_PBAP_SUPPORTED_FEATURES;
+ app_param[1] = BTA_PBAP_APP_PARAM_LENGTH_PBAP_SUPPORTED_FEATURES;
+ UINT32_TO_FIELD(&app_param[2], p_ccb->our_supported_feat);
+ ret |= GOEPC_RequestAddHeader(p_ccb->goep_handle, OBEX_HEADER_ID_APP_PARAM, app_param, 6);
+ }
+ ret |= GOEPC_SendRequest(p_ccb->goep_handle);
+ if (ret != GOEP_SUCCESS) {
+ close_goepc_and_report(p_ccb, BTA_PBA_CLIENT_GOEP_ERROR);
+ }
+}
+
+void bta_pba_client_goep_disconnect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ p_ccb->goep_handle = 0;
+
+ /* report connection closed event */
+ tBTA_PBA_CLIENT_CONN conn;
+ conn.handle = p_ccb->allocated;
+ bdcpy(conn.bd_addr, p_ccb->bd_addr);
+ conn.error = BTA_PBA_CLIENT_GOEP_ERROR;
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_CONN_CLOSE_EVT, (tBTA_PBA_CLIENT *)&conn);
+ free_ccb(p_ccb);
+}
+
+void bta_pba_client_free_response(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ if (p_data->goep_response.pkt != NULL) {
+ osi_free(p_data->goep_response.pkt);
+ }
+ close_goepc_and_report(p_ccb, BTA_PBA_CLIENT_GOEP_ERROR);
+}
+
+#endif
diff --git a/lib/bt/host/bluedroid/bta/pba/bta_pba_client_api.c b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_api.c
new file mode 100644
index 00000000..8169a7d6
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_api.c
@@ -0,0 +1,162 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include <stdio.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 "bta/bta_sys.h"
+#include "bta/bta_api.h"
+#include "bta_pba_client_int.h"
+
+#if BTA_PBA_CLIENT_INCLUDED
+
+static const tBTA_SYS_REG bta_pba_client_reg = {
+ bta_pba_client_hdl_event,
+ BTA_PbaClientDisable
+};
+
+void BTA_PbaClientEnable(tBTA_PBA_CLIENT_CBACK *p_cback)
+{
+ tBTA_PBA_CLIENT_API_ENABLE *p_buf;
+
+ if (bta_sys_is_register(BTA_ID_PBC)) {
+ APPL_TRACE_ERROR("BTA PBA Client already enabled");
+ return;
+ }
+
+ /* register with BTA system manager */
+ bta_sys_register(BTA_ID_PBC, &bta_pba_client_reg);
+
+ if ((p_buf = (tBTA_PBA_CLIENT_API_ENABLE *)osi_malloc(sizeof(tBTA_PBA_CLIENT_API_ENABLE))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_API_ENABLE_EVT;
+ p_buf->p_cback = p_cback;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientDisable(void)
+{
+ BT_HDR *p_buf;
+
+ if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+ p_buf->event = BTA_PBA_CLIENT_API_DISABLE_EVT;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientRegister(const char *server_name)
+{
+ tBTA_PBA_CLIENT_API_REGISTER *p_buf;
+
+ if ((p_buf = (tBTA_PBA_CLIENT_API_REGISTER *) osi_malloc(sizeof(tBTA_PBA_CLIENT_API_REGISTER))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_API_REGISTER_EVT;
+ memcpy(p_buf->name, server_name, strlen(server_name) + 1);
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientDeregister(void)
+{
+ BT_HDR *p_buf;
+
+ if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+ p_buf->event = BTA_PBA_CLIENT_API_DEREGISTER_EVT;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientOpen(BD_ADDR bd_addr, tBTA_SEC sec_mask, UINT32 supported_feat, UINT16 mtu)
+{
+ tBTA_PBA_CLIENT_API_OPEN *p_buf;
+
+ if ((p_buf = (tBTA_PBA_CLIENT_API_OPEN *)osi_malloc(sizeof(tBTA_PBA_CLIENT_API_OPEN))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_API_OPEN_EVT;
+ p_buf->sec_mask = sec_mask;
+ p_buf->supported_feat = supported_feat;
+ p_buf->mtu = mtu;
+ bdcpy(p_buf->bd_addr, bd_addr);
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientClose(UINT16 handle)
+{
+ BT_HDR *p_buf;
+
+ if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+ p_buf->event = BTA_PBA_CLIENT_API_CLOSE_EVT;
+ p_buf->layer_specific = handle;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientPullPhoneBook(UINT16 handle, char *name, UINT8 *app_param, UINT16 app_param_len)
+{
+ tBTA_PBA_CLIENT_API_REQ *p_buf;
+
+ if ((p_buf = (tBTA_PBA_CLIENT_API_REQ *) osi_malloc(sizeof(tBTA_PBA_CLIENT_API_REQ))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_API_REQ_EVT;
+ p_buf->hdr.layer_specific = handle;
+ p_buf->operation = BTA_PBA_CLIENT_OP_PULL_PHONE_BOOK;
+ p_buf->name = name;
+ p_buf->app_param = app_param;
+ p_buf->app_param_len = app_param_len;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientSetPhoneBook(UINT16 handle, UINT8 flags, char *name)
+{
+ tBTA_PBA_CLIENT_API_REQ *p_buf;
+
+ if ((p_buf = (tBTA_PBA_CLIENT_API_REQ *) osi_malloc(sizeof(tBTA_PBA_CLIENT_API_REQ))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_API_REQ_EVT;
+ p_buf->hdr.layer_specific = handle;
+ p_buf->operation = BTA_PBA_CLIENT_OP_SET_PHONE_BOOK;
+ p_buf->flags = flags;
+ p_buf->name = name;
+ p_buf->app_param = NULL;
+ p_buf->app_param_len = 0;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientPullvCardListing(UINT16 handle, char *name, UINT8 *app_param, UINT16 app_param_len)
+{
+ tBTA_PBA_CLIENT_API_REQ *p_buf;
+
+ if ((p_buf = (tBTA_PBA_CLIENT_API_REQ *) osi_malloc(sizeof(tBTA_PBA_CLIENT_API_REQ))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_API_REQ_EVT;
+ p_buf->hdr.layer_specific = handle;
+ p_buf->operation = BTA_PBA_CLIENT_OP_PULL_VCARD_LISTING;
+ p_buf->name = name;
+ p_buf->app_param = app_param;
+ p_buf->app_param_len = app_param_len;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+void BTA_PbaClientPullvCardEntry(UINT16 handle, char *name, UINT8 *app_param, UINT16 app_param_len)
+{
+ tBTA_PBA_CLIENT_API_REQ *p_buf;
+
+ if ((p_buf = (tBTA_PBA_CLIENT_API_REQ *) osi_malloc(sizeof(tBTA_PBA_CLIENT_API_REQ))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_API_REQ_EVT;
+ p_buf->hdr.layer_specific = handle;
+ p_buf->operation = BTA_PBA_CLIENT_OP_PULL_VCARD_ENTRY;
+ p_buf->name = name;
+ p_buf->app_param = app_param;
+ p_buf->app_param_len = app_param_len;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+#endif
diff --git a/lib/bt/host/bluedroid/bta/pba/bta_pba_client_main.c b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_main.c
new file mode 100644
index 00000000..81c389bb
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_main.c
@@ -0,0 +1,293 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.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 "bta_pba_client_int.h"
+
+#if BTA_PBA_CLIENT_INCLUDED
+
+/* state machine states */
+enum {
+ BTA_PBA_CLIENT_INIT_ST,
+ BTA_PBA_CLIENT_OPENING_ST,
+ BTA_PBA_CLIENT_OPENED_ST,
+ BTA_PBA_CLIENT_REQUESTING_ST,
+ BTA_PBA_CLIENT_CLOSING_ST
+};
+
+/* state machine action enumeration list */
+enum {
+ BTA_PBA_CLIENT_API_OPEN,
+ BTA_PBA_CLIENT_API_CLOSE,
+ BTA_PBA_CLIENT_API_REQ,
+ BTA_PBA_CLIENT_DO_CONNECT,
+ BTA_PBA_CLIENT_AUTHENTICATE,
+ BTA_PBA_CLIENT_CONNECT,
+ BTA_PBA_CLIENT_RESPONSE,
+ BTA_PBA_CLIENT_RESPONSE_FINAL,
+ BTA_PBA_CLIENT_GOEP_CONNECT,
+ BTA_PBA_CLIENT_GOEP_DISCONNECT,
+ BTA_PBA_CLIENT_FORCE_DISCONNECT,
+ BTA_PBA_CLIENT_FREE_RESPONSE,
+ BTA_PBA_CLIENT_NUM_ACTIONS
+};
+
+#define BTA_PBA_CLIENT_IGNORE BTA_PBA_CLIENT_NUM_ACTIONS
+
+/* type for action functions */
+typedef void (*tBTA_PBA_CLIENT_ACTION)(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+
+/* action functions table, indexed with action enum */
+const tBTA_PBA_CLIENT_ACTION bta_pba_client_action[] = {
+ /* BTA_PBA_CLIENT_API_OPEN */ bta_pba_client_api_open,
+ /* BTA_PBA_CLIENT_API_CLOSE */ bta_pba_client_api_close,
+ /* BTA_PBA_CLIENT_API_REQ */ bta_pba_client_api_req,
+ /* BTA_PBA_CLIENT_DO_CONNECT */ bta_pba_client_do_connect,
+ /* BTA_PBA_CLIENT_AUTHENTICATE */ bta_pba_client_authenticate,
+ /* BTA_PBA_CLIENT_CONNECT */ bta_pba_client_connect,
+ /* BTA_PBA_CLIENT_RESPONSE */ bta_pba_client_response,
+ /* BTA_PBA_CLIENT_RESPONSE_FINAL */ bta_pba_client_response_final,
+ /* BTA_PBA_CLIENT_GOEP_CONNECT */ bta_pba_client_goep_connect,
+ /* BTA_PBA_CLIENT_GOEP_DISCONNECT*/ bta_pba_client_goep_disconnect,
+ /* BTA_PBA_CLIENT_FORCE_DISCONNECT */ bta_pba_client_force_disconnect,
+ /* BTA_PBA_CLIENT_FREE_RESPONSE */ bta_pba_client_free_response,
+};
+
+/* state table information */
+#define BTA_PBA_CLIENT_ACTION 0 /* position of action */
+#define BTA_PBA_CLIENT_NEXT_STATE 1 /* position of next state */
+#define BTA_PBA_CLIENT_NUM_COLS 2 /* number of columns */
+
+const uint8_t bta_pba_client_st_init[][BTA_PBA_CLIENT_NUM_COLS] = {
+ /* Event Action Next state */
+ /* BTA_PBA_CLIENT_API_OPEN_EVT */ {BTA_PBA_CLIENT_API_OPEN, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_API_CLOSE_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_API_REQ_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_DISC_RES_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_AUTHENTICATE_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_FINAL_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_GOEP_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_INIT_ST},
+};
+
+const uint8_t bta_pba_client_st_opening[][BTA_PBA_CLIENT_NUM_COLS] = {
+ /* Event Action Next state */
+ /* BTA_PBA_CLIENT_API_OPEN_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_API_CLOSE_EVT */ {BTA_PBA_CLIENT_FORCE_DISCONNECT, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_API_REQ_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_DISC_RES_EVT */ {BTA_PBA_CLIENT_DO_CONNECT, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_AUTHENTICATE_EVT */ {BTA_PBA_CLIENT_AUTHENTICATE, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_CONNECT_EVT */ {BTA_PBA_CLIENT_CONNECT, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_EVT */ {BTA_PBA_CLIENT_FREE_RESPONSE, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_FINAL_EVT */ {BTA_PBA_CLIENT_RESPONSE_FINAL, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_GOEP_CONNECT_EVT */ {BTA_PBA_CLIENT_GOEP_CONNECT, BTA_PBA_CLIENT_OPENING_ST},
+ /* BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT */ {BTA_PBA_CLIENT_GOEP_DISCONNECT, BTA_PBA_CLIENT_INIT_ST},
+};
+
+const uint8_t bta_pba_client_st_opened[][BTA_PBA_CLIENT_NUM_COLS] = {
+ /* Event Action Next state */
+ /* BTA_PBA_CLIENT_API_OPEN_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_API_CLOSE_EVT */ {BTA_PBA_CLIENT_API_CLOSE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_API_REQ_EVT */ {BTA_PBA_CLIENT_API_REQ, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_DISC_RES_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_AUTHENTICATE_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_EVT */ {BTA_PBA_CLIENT_FREE_RESPONSE, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_FINAL_EVT */ {BTA_PBA_CLIENT_FREE_RESPONSE, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_GOEP_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT */ {BTA_PBA_CLIENT_GOEP_DISCONNECT, BTA_PBA_CLIENT_INIT_ST},
+};
+
+const uint8_t bta_pba_client_st_getting[][BTA_PBA_CLIENT_NUM_COLS] = {
+ /* Event Action Next state */
+ /* BTA_PBA_CLIENT_API_OPEN_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_API_CLOSE_EVT */ {BTA_PBA_CLIENT_FORCE_DISCONNECT, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_API_REQ_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_DISC_RES_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_AUTHENTICATE_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_EVT */ {BTA_PBA_CLIENT_RESPONSE, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_FINAL_EVT */ {BTA_PBA_CLIENT_RESPONSE_FINAL, BTA_PBA_CLIENT_OPENED_ST},
+ /* BTA_PBA_CLIENT_GOEP_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_REQUESTING_ST},
+ /* BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT */ {BTA_PBA_CLIENT_GOEP_DISCONNECT, BTA_PBA_CLIENT_INIT_ST},
+};
+
+const uint8_t bta_pba_client_st_closing[][BTA_PBA_CLIENT_NUM_COLS] = {
+ /* Event Action Next state */
+ /* BTA_PBA_CLIENT_API_OPEN_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_API_CLOSE_EVT */ {BTA_PBA_CLIENT_FORCE_DISCONNECT, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_API_REQ_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_DISC_RES_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_AUTHENTICATE_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_RESPONSE_FINAL_EVT */ {BTA_PBA_CLIENT_RESPONSE_FINAL, BTA_PBA_CLIENT_INIT_ST},
+ /* BTA_PBA_CLIENT_GOEP_CONNECT_EVT */ {BTA_PBA_CLIENT_IGNORE, BTA_PBA_CLIENT_CLOSING_ST},
+ /* BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT */ {BTA_PBA_CLIENT_GOEP_DISCONNECT, BTA_PBA_CLIENT_INIT_ST},
+};
+
+/* type for state table */
+typedef const UINT8 (*tBTA_PBA_CLIENT_ST_TBL)[BTA_PBA_CLIENT_NUM_COLS];
+
+/* state table */
+const tBTA_PBA_CLIENT_ST_TBL bta_pba_client_st_tbl[] = {
+ bta_pba_client_st_init,
+ bta_pba_client_st_opening,
+ bta_pba_client_st_opened,
+ bta_pba_client_st_getting,
+ bta_pba_client_st_closing
+};
+
+/* PBA Client control block */
+#if BTA_DYNAMIC_MEMORY == FALSE
+tBTA_PBA_CLIENT_CB bta_pba_client_cb;
+#else
+tBTA_PBA_CLIENT_CB *bta_pba_client_cb_ptr;
+#endif
+
+static tBTA_PBA_CLIENT_CCB *allocate_ccb(void)
+{
+ tBTA_PBA_CLIENT_CCB *p_ccb = NULL;
+ for (int i = 0; i < PBA_CLIENT_MAX_CONNECTION; ++i) {
+ if (bta_pba_client_cb.ccb[i].allocated == 0) {
+ bta_pba_client_cb.ccb[i].allocated = i + 1;
+ p_ccb = &bta_pba_client_cb.ccb[i];
+ break;
+ }
+ }
+ return p_ccb;
+}
+
+static tBTA_PBA_CLIENT_CCB *find_ccb_by_handle(UINT16 handle)
+{
+ tBTA_PBA_CLIENT_CCB *p_ccb = NULL;
+ for (int i = 0; i < PBA_CLIENT_MAX_CONNECTION; ++i) {
+ if (bta_pba_client_cb.ccb[i].allocated != 0 && bta_pba_client_cb.ccb[i].allocated == handle) {
+ p_ccb = &bta_pba_client_cb.ccb[i];
+ }
+ }
+ return p_ccb;
+}
+
+static tBTA_PBA_CLIENT_CCB *find_ccb_by_goep_handle(UINT16 goep_handle)
+{
+ tBTA_PBA_CLIENT_CCB *p_ccb = NULL;
+ for (int i = 0; i < PBA_CLIENT_MAX_CONNECTION; ++i) {
+ if (bta_pba_client_cb.ccb[i].allocated != 0 && bta_pba_client_cb.ccb[i].goep_handle == goep_handle) {
+ p_ccb = &bta_pba_client_cb.ccb[i];
+ }
+ }
+ return p_ccb;
+}
+
+static tBTA_PBA_CLIENT_CCB *find_ccb_by_bd_addr(BD_ADDR bd_addr)
+{
+ tBTA_PBA_CLIENT_CCB *p_ccb = NULL;
+ for (int i = 0; i < PBA_CLIENT_MAX_CONNECTION; ++i) {
+ if (bta_pba_client_cb.ccb[i].allocated != 0 && bdcmp(bta_pba_client_cb.ccb[i].bd_addr, bd_addr) == 0) {
+ p_ccb = &bta_pba_client_cb.ccb[i];
+ }
+ }
+ return p_ccb;
+}
+
+void bta_pba_client_sm_execute(tBTA_PBA_CLIENT_CCB *p_ccb, UINT16 event, tBTA_PBA_CLIENT_DATA *p_data)
+{
+ tBTA_PBA_CLIENT_ST_TBL state_table;
+ UINT8 action;
+
+ state_table = bta_pba_client_st_tbl[p_ccb->state];
+
+ event &= 0xff;
+
+ p_ccb->state = state_table[event][BTA_PBA_CLIENT_NEXT_STATE];
+
+ if ((action = state_table[event][BTA_PBA_CLIENT_ACTION]) != BTA_PBA_CLIENT_IGNORE) {
+ (*bta_pba_client_action[action])(p_ccb, p_data);
+ }
+
+ return;
+}
+
+BOOLEAN bta_pba_client_hdl_event(BT_HDR *p_msg)
+{
+ tBTA_PBA_CLIENT_CCB *p_ccb = NULL;
+ BOOLEAN execute_sm = FALSE;
+ tBTA_PBA_CLIENT_CONN conn = {0};
+ tBTA_PBA_CLIENT_DATA *p_data = (tBTA_PBA_CLIENT_DATA *)p_msg;
+
+ switch (p_msg->event) {
+ case BTA_PBA_CLIENT_API_ENABLE_EVT:
+ bta_pba_client_api_enable(p_data);
+ break;
+ case BTA_PBA_CLIENT_API_DISABLE_EVT:
+ bta_pba_client_api_disable(p_data);
+ break;
+ case BTA_PBA_CLIENT_API_REGISTER_EVT:
+ bta_pba_client_api_register(p_data);
+ break;
+ case BTA_PBA_CLIENT_API_DEREGISTER_EVT:
+ bta_pba_client_api_deregister(p_data);
+ break;
+ case BTA_PBA_CLIENT_API_OPEN_EVT:
+ if (find_ccb_by_bd_addr(p_data->api_open.bd_addr) != NULL) {
+ /* already connected */
+ conn.handle = 0;
+ conn.error = BTA_PBA_CLIENT_ALREADY_CONN;
+ bdcpy(conn.bd_addr, p_data->api_open.bd_addr);
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_CONN_OPEN_EVT, (tBTA_PBA_CLIENT *)&conn);
+ /* break, don't execute sm */
+ break;
+ }
+ p_ccb = allocate_ccb();
+ if (p_ccb == NULL) {
+ /* no resource to allocate ccb */
+ conn.handle = 0;
+ conn.error = BTA_PBA_CLIENT_NO_RESOURCE;
+ bdcpy(conn.bd_addr, p_data->api_open.bd_addr);
+ bta_pba_client_cb.p_cback(BTA_PBA_CLIENT_CONN_OPEN_EVT, (tBTA_PBA_CLIENT *)&conn);
+ /* break, don't execute sm */
+ break;
+ }
+ execute_sm = TRUE;
+ break;
+ case BTA_PBA_CLIENT_GOEP_CONNECT_EVT:
+ case BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT:
+ case BTA_PBA_CLIENT_RESPONSE_EVT:
+ case BTA_PBA_CLIENT_RESPONSE_FINAL_EVT:
+ p_ccb = find_ccb_by_goep_handle(p_msg->layer_specific);
+ if (p_ccb == NULL) {
+ /* ignore event with invalid goep handle */
+ break;
+ }
+ execute_sm = TRUE;
+ break;
+ default:
+ p_ccb = find_ccb_by_handle(p_msg->layer_specific);
+ if (p_ccb == NULL) {
+ /* ignore event with invalid handle */
+ break;
+ }
+ execute_sm = TRUE;
+ }
+
+ if (execute_sm) {
+ bta_pba_client_sm_execute(p_ccb, p_msg->event, (tBTA_PBA_CLIENT_DATA *) p_msg);
+ }
+
+ return TRUE;
+}
+
+#endif
diff --git a/lib/bt/host/bluedroid/bta/pba/bta_pba_client_sdp.c b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_sdp.c
new file mode 100644
index 00000000..030ddad6
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/pba/bta_pba_client_sdp.c
@@ -0,0 +1,279 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "osi/allocator.h"
+#include "common/bt_defs.h"
+#include "stack/sdp_api.h"
+#include "bta/bta_api.h"
+#include "bta/bta_pba_defs.h"
+#include "bta/bta_pba_client_api.h"
+#include "bta_pba_client_int.h"
+
+#if BTA_PBA_CLIENT_INCLUDED
+
+/* Number of elements in service class id list. */
+#define BTA_PBA_CLIENT_NUM_SVC_ELEMS 1
+
+/*******************************************************************************
+**
+** Function bta_pba_client_sdp_cback
+**
+** Description SDP callback function.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_pba_client_sdp_cback(UINT16 status, void *user_data)
+{
+ tBTA_PBA_CLIENT_DISC_RESULT *p_buf;
+ tBTA_PBA_CLIENT_CCB *p_ccb = (tBTA_PBA_CLIENT_CCB *)user_data;
+
+ APPL_TRACE_DEBUG("bta_pba_client_sdp_cback status:0x%x", status);
+
+ if ((p_buf = (tBTA_PBA_CLIENT_DISC_RESULT *) osi_malloc(sizeof(tBTA_PBA_CLIENT_DISC_RESULT))) != NULL) {
+ p_buf->hdr.event = BTA_PBA_CLIENT_DISC_RES_EVT;
+ p_buf->hdr.layer_specific = p_ccb->allocated;
+ p_buf->status = status;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/******************************************************************************
+**
+** Function bta_pba_client_add_record
+**
+** Description Add PBA Client information to an SDP record. Prior to
+** calling this function the application must call
+** SDP_CreateRecord() to create an SDP record.
+**
+** Returns TRUE if function execution succeeded,
+** FALSE if function execution failed.
+**
+******************************************************************************/
+static BOOLEAN bta_pba_client_add_record(const char *p_service_name, UINT32 sdp_handle)
+{
+ UINT16 svc_class_id_list[BTA_PBA_CLIENT_NUM_SVC_ELEMS];
+ UINT16 version;
+ UINT16 profile_uuid;
+ BOOLEAN result = TRUE;
+
+ APPL_TRACE_DEBUG("bta_pba_client_add_record");
+
+ /* add service class id list */
+ svc_class_id_list[0] = UUID_SERVCLASS_PBAP_PCE;
+ result &= SDP_AddServiceClassIdList(sdp_handle, BTA_PBA_CLIENT_NUM_SVC_ELEMS, svc_class_id_list);
+
+ /* add service name */
+ if (p_service_name != NULL && p_service_name[0] != 0) {
+ result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
+ (UINT32)(strlen(p_service_name) + 1), (UINT8 *) p_service_name);
+ }
+
+ /* add profile descriptor list */
+ profile_uuid = UUID_SERVCLASS_PHONE_ACCESS;
+ version = PBAP_PCE_VERSION;
+ result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function bta_pba_client_create_record
+**
+** Description Create SDP record for registered service.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pba_client_create_record(const char *p_service_name)
+{
+ /* add sdp record if not already registered */
+ if (bta_pba_client_cb.sdp_handle == 0) {
+ bta_pba_client_cb.sdp_handle = SDP_CreateRecord();
+ bta_pba_client_add_record(p_service_name, bta_pba_client_cb.sdp_handle);
+ bta_sys_add_uuid(UUID_SERVCLASS_PBAP_PCE);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function bta_pba_client_del_record
+**
+** Description Delete SDP record for registered service.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pba_client_del_record(void)
+{
+ APPL_TRACE_DEBUG("bta_pba_client_del_record");
+
+ if (bta_pba_client_cb.sdp_handle != 0) {
+ SDP_DeleteRecord(bta_pba_client_cb.sdp_handle);
+ bta_pba_client_cb.sdp_handle = 0;
+ bta_sys_remove_uuid(UUID_SERVCLASS_PBAP_PCE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_pba_client_sdp_find_attr
+**
+** Description Process SDP discovery results to find requested attribute
+**
+**
+** Returns TRUE if results found, FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN bta_pba_client_sdp_find_attr(tBTA_PBA_CLIENT_CCB *p_ccb)
+{
+ tSDP_DISC_REC *p_rec = NULL;
+ tSDP_DISC_ATTR *p_attr;
+ tSDP_PROTOCOL_ELEM pe;
+ BOOLEAN result = FALSE;
+
+ /* loop through all records we found */
+ while (TRUE) {
+ /* get next record; if none found, we're done */
+ if ((p_rec = SDP_FindServiceInDb(p_ccb->p_disc_db, UUID_SERVCLASS_PBAP_PSE, p_rec)) == NULL) {
+ break;
+ }
+
+ /* get rfcomm scn from proto desc list */
+ if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+ p_ccb->peer_rfcomm_scn = (UINT8) pe.params[0];
+ }
+ else {
+ /* not found, go to next record */
+ continue;
+ }
+
+ /* get supported repositories */
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES)) != NULL) {
+ /* Found attribute, get value */
+ p_ccb->peer_supported_repo = p_attr->attr_value.v.u8;
+ }
+ else {
+ /* not found, clear rfcomm scn and go to next record */
+ p_ccb->peer_rfcomm_scn = 0;
+ continue;
+ }
+
+ /* get profile version */
+ SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS, &p_ccb->peer_version);
+
+ /* get GOEP L2CAP PSM */
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
+ /* Found attribute, get value */
+ p_ccb->peer_l2cap_psm = p_attr->attr_value.v.u16;
+ }
+
+ /* try to get supported features */
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES)) != NULL) {
+ /* found attribute, get value */
+ p_ccb->peer_supported_feat = p_attr->attr_value.v.u32;
+ p_ccb->send_supported_feat = TRUE;
+ }
+ else {
+ /* assume as default value if not found in sdp record */
+ p_ccb->peer_supported_feat = BTA_PBAP_DEFAULT_SUPPORTED_FEATURES;
+ p_ccb->send_supported_feat = FALSE;
+ }
+
+ /* found what we needed */
+ result = TRUE;
+ break;
+ }
+
+ APPL_TRACE_DEBUG("%s peer_version:0x%x, supported repositories:0x%x, supported features:0x%x",
+ __FUNCTION__, p_ccb->peer_version, p_ccb->peer_supported_repo, p_ccb->peer_supported_feat);
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function bta_pba_client_do_disc
+**
+** Description Do service discovery.
+**
+**
+** Returns TRUE if start service discovery successfully
+**
+*******************************************************************************/
+BOOLEAN bta_pba_client_do_disc(tBTA_PBA_CLIENT_CCB *p_ccb)
+{
+ tSDP_UUID uuid_list[1];
+ UINT16 num_uuid = 1;
+ UINT16 attr_list[6];
+ UINT8 num_attr = 6;
+ BOOLEAN db_inited = FALSE;
+
+ /* get proto list and features */
+ attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
+ attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
+ attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
+ attr_list[3] = ATTR_ID_GOEP_L2CAP_PSM;
+ attr_list[4] = ATTR_ID_SUPPORTED_REPOSITORIES;
+ attr_list[5] = ATTR_ID_PBAP_SUPPORTED_FEATURES;
+ uuid_list[0].uu.uuid16 = UUID_SERVCLASS_PBAP_PSE;
+ uuid_list[0].len = LEN_UUID_16;
+
+ if (p_ccb->p_disc_db != NULL) {
+ APPL_TRACE_WARNING("%s service discovery already in progress", __FUNCTION__);
+ return FALSE;
+ }
+
+ /* allocate buffer for sdp database */
+ p_ccb->p_disc_db = (tSDP_DISCOVERY_DB *) osi_malloc(BT_DEFAULT_BUFFER_SIZE);
+
+ if (p_ccb->p_disc_db) {
+ /* set up service discovery database; attr happens to be attr_list len */
+ db_inited = SDP_InitDiscoveryDb(p_ccb->p_disc_db, BT_DEFAULT_BUFFER_SIZE, num_uuid,
+ uuid_list, num_attr, attr_list);
+ }
+
+ if (db_inited) {
+ /*start service discovery */
+ /* todo: avoid p_ccb being free during sdp */
+ db_inited = SDP_ServiceSearchAttributeRequest2(p_ccb->bd_addr, p_ccb->p_disc_db,
+ bta_pba_client_sdp_cback, p_ccb);
+ }
+
+ if (!db_inited) {
+ /*free discover db */
+ bta_pba_client_free_db(p_ccb);
+ APPL_TRACE_ERROR("%s start service discovery failed", __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function bta_hf_client_free_db
+**
+** Description Free discovery database.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_pba_client_free_db(tBTA_PBA_CLIENT_CCB *p_ccb)
+{
+ if (p_ccb->p_disc_db != NULL) {
+ osi_free(p_ccb->p_disc_db);
+ p_ccb->p_disc_db = NULL;
+ }
+}
+
+#endif
diff --git a/lib/bt/host/bluedroid/bta/pba/include/bta_pba_client_int.h b/lib/bt/host/bluedroid/bta/pba/include/bta_pba_client_int.h
new file mode 100644
index 00000000..5d48eab9
--- /dev/null
+++ b/lib/bt/host/bluedroid/bta/pba/include/bta_pba_client_int.h
@@ -0,0 +1,177 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "osi/list.h"
+#include "common/bt_target.h"
+#include "stack/sdp_api.h"
+#include "stack/obex_api.h"
+#include "bta/bta_sys.h"
+#include "bta/bta_api.h"
+#include "bta/bta_pba_client_api.h"
+
+#if BTA_PBA_CLIENT_INCLUDED
+
+#define PBA_CLIENT_MAX_CONNECTION 2
+
+#define PBA_CLIENT_MAX_MTU L2CAP_MTU_SIZE /* RFCOMM is base on L2CAP, its MTU will smaller than this */
+#define PBA_CLIENT_MIN_MTU 255
+
+enum {
+ /* these events are handled by the state machine */
+ BTA_PBA_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_PBC),
+ BTA_PBA_CLIENT_API_CLOSE_EVT,
+ BTA_PBA_CLIENT_API_REQ_EVT,
+ BTA_PBA_CLIENT_DISC_RES_EVT,
+ BTA_PBA_CLIENT_AUTHENTICATE_EVT,
+ BTA_PBA_CLIENT_CONNECT_EVT,
+ BTA_PBA_CLIENT_RESPONSE_EVT,
+ BTA_PBA_CLIENT_RESPONSE_FINAL_EVT,
+ BTA_PBA_CLIENT_GOEP_CONNECT_EVT,
+ BTA_PBA_CLIENT_GOEP_DISCONNECT_EVT,
+
+ /* these events are handled outside of the state machine */
+ BTA_PBA_CLIENT_API_ENABLE_EVT,
+ BTA_PBA_CLIENT_API_DISABLE_EVT,
+ BTA_PBA_CLIENT_API_REGISTER_EVT,
+ BTA_PBA_CLIENT_API_DEREGISTER_EVT,
+};
+
+typedef enum {
+ BTA_PBA_CLIENT_OP_PULL_PHONE_BOOK,
+ BTA_PBA_CLIENT_OP_SET_PHONE_BOOK,
+ BTA_PBA_CLIENT_OP_PULL_VCARD_LISTING,
+ BTA_PBA_CLIENT_OP_PULL_VCARD_ENTRY,
+} tBTA_PBA_CLIENT_OP;
+
+typedef struct {
+ BT_HDR hdr;
+ tBTA_PBA_CLIENT_CBACK *p_cback;
+} tBTA_PBA_CLIENT_API_ENABLE;
+
+typedef struct {
+ BT_HDR hdr;
+ char name[BTA_SERVICE_NAME_LEN + 1];
+} tBTA_PBA_CLIENT_API_REGISTER;
+
+typedef struct {
+ BT_HDR hdr;
+ BD_ADDR bd_addr;
+ tBTA_SEC sec_mask;
+ UINT16 mtu;
+ UINT32 supported_feat;
+} tBTA_PBA_CLIENT_API_OPEN;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT8 operation;
+ UINT8 flags;
+ char *name;
+ UINT16 app_param_len;
+ UINT8 *app_param;
+} tBTA_PBA_CLIENT_API_REQ;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 status;
+} tBTA_PBA_CLIENT_DISC_RESULT;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 our_mtu;
+ UINT16 peer_mtu;
+} tBTA_PBA_CLIENT_GOEP_CONNECT;
+
+typedef struct {
+ BT_HDR hdr;
+ UINT16 reason;
+} tBTA_PBA_CLIENT_GOEP_DISCONNECT;
+
+typedef struct {
+ BT_HDR hdr;
+ BT_HDR *pkt;
+ UINT8 opcode;
+ BOOLEAN srm_en;
+ BOOLEAN srm_wait;
+} tBTA_PBA_CLIENT_GOEP_RESPONSE;
+
+typedef union {
+ BT_HDR hdr;
+ tBTA_PBA_CLIENT_API_ENABLE api_enable;
+ tBTA_PBA_CLIENT_API_REGISTER api_register;
+ tBTA_PBA_CLIENT_API_OPEN api_open;
+ tBTA_PBA_CLIENT_API_REQ api_req;
+ tBTA_PBA_CLIENT_DISC_RESULT disc_result;
+ tBTA_PBA_CLIENT_GOEP_CONNECT goep_connect;
+ tBTA_PBA_CLIENT_GOEP_DISCONNECT goep_disconnect;
+ tBTA_PBA_CLIENT_GOEP_RESPONSE goep_response;
+} tBTA_PBA_CLIENT_DATA;
+
+typedef struct {
+ BD_ADDR bd_addr; /* peer BD address */
+ tSDP_DISCOVERY_DB *p_disc_db; /* pointer to discovery database */
+ tBTA_SEC sec_mask; /* security mask */
+ UINT16 peer_version; /* peer profile version */
+ UINT16 peer_l2cap_psm; /* peer l2cap psm */
+ UINT8 peer_rfcomm_scn; /* peer rfcomm scn */
+ UINT8 peer_supported_repo; /* peer supported repositories */
+ UINT32 peer_supported_feat; /* peer supported features */
+ UINT32 our_supported_feat; /* we supported features */
+ BOOLEAN send_supported_feat; /* whether we should send supported features in connect request */
+ UINT16 goep_handle; /* goep connection handle */
+ UINT32 goep_cid; /* goep connection id */
+ UINT16 max_rx; /* max rx bytes */
+ UINT16 max_tx; /* max tx bytes */
+ BOOLEAN authenticate; /* whether we are authenticated */
+ tBTA_PBA_CLIENT_OP operation; /* ongoing or last operations */
+ UINT8 state; /* main state machine */
+ UINT8 allocated; /* index + 1 if allocated, otherwise 0 */
+} tBTA_PBA_CLIENT_CCB;
+
+typedef struct {
+ tBTA_PBA_CLIENT_CCB ccb[PBA_CLIENT_MAX_CONNECTION]; /* connection control block */
+ tBTA_PBA_CLIENT_CBACK *p_cback; /* message callback to upper */
+ UINT32 sdp_handle; /* sdp record handle */
+ UINT8 trace_level; /* debug trace level */
+} tBTA_PBA_CLIENT_CB;
+
+#if BTA_DYNAMIC_MEMORY == FALSE
+extern tBTA_PBA_CLIENT_CB bta_pba_client_cb;
+#else
+extern tBTA_PBA_CLIENT_CB *bta_pba_client_cb_ptr;
+#define bta_pba_client_cb (*bta_pba_client_cb_ptr)
+#endif
+
+extern void bta_pba_client_api_enable(tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_api_disable(tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_api_register(tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_api_deregister(tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_api_open(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_api_close(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_api_req(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_do_connect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_authenticate(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_force_disconnect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+
+extern void bta_pba_client_connect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_response(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+extern void bta_pba_client_response_final(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+void bta_pba_client_goep_connect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+void bta_pba_client_goep_disconnect(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+void bta_pba_client_free_response(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+void bta_pba_client_free_sdp_db(tBTA_PBA_CLIENT_CCB *p_ccb, tBTA_PBA_CLIENT_DATA *p_data);
+
+extern void bta_pba_client_create_record(const char *p_service_name);
+extern void bta_pba_client_del_record(void);
+extern BOOLEAN bta_pba_client_sdp_find_attr(tBTA_PBA_CLIENT_CCB *p_ccb);
+extern BOOLEAN bta_pba_client_do_disc(tBTA_PBA_CLIENT_CCB *p_ccb);
+extern void bta_pba_client_free_db(tBTA_PBA_CLIENT_CCB *p_ccb);
+
+extern void bta_pba_client_sm_execute(tBTA_PBA_CLIENT_CCB *p_ccb, UINT16 event, tBTA_PBA_CLIENT_DATA *p_data);
+extern BOOLEAN bta_pba_client_hdl_event(BT_HDR *p_msg);
+
+#endif
diff --git a/lib/bt/host/bluedroid/bta/sdp/bta_sdp.c b/lib/bt/host/bluedroid/bta/sdp/bta_sdp.c
index 4deabe9a..71773d98 100644
--- a/lib/bt/host/bluedroid/bta/sdp/bta_sdp.c
+++ b/lib/bt/host/bluedroid/bta/sdp/bta_sdp.c
@@ -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 */
};
/*******************************************************************************
diff --git a/lib/bt/host/bluedroid/bta/sdp/bta_sdp_act.c b/lib/bt/host/bluedroid/bta/sdp/bta_sdp_act.c
index 70aa00ba..045672f0 100644
--- a/lib/bt/host/bluedroid/bta/sdp/bta_sdp_act.c
+++ b/lib/bt/host/bluedroid/bta/sdp/bta_sdp_act.c
@@ -40,31 +40,6 @@
#if (SDP_INCLUDED == TRUE)
-/*****************************************************************************
-** Constants
-*****************************************************************************/
-
-static const uint8_t UUID_OBEX_OBJECT_PUSH[] = {0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
- };
-static const uint8_t UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
- };
-static const uint8_t UUID_PBAP_PCE[] = {0x00, 0x00, 0x11, 0x2E, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
- };
-static const uint8_t UUID_MAP_MAS[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
- };
-static const uint8_t UUID_MAP_MNS[] = {0x00, 0x00, 0x11, 0x33, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
- };
-static const uint8_t UUID_SPP[] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
- };
-static const uint8_t UUID_SAP[] = {0x00, 0x00, 0x11, 0x2D, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
- };
// TODO:
// Both the fact that the UUIDs are declared in multiple places, plus the fact
// that there is a mess of UUID comparison and shortening methods will have to
@@ -140,6 +115,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;
@@ -328,7 +344,7 @@ static void bta_create_sap_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
tSDP_PROTOCOL_ELEM pe;
UINT16 pversion = -1;
- record->sap.hdr.type = SDP_TYPE_MAP_MAS;
+ record->sap.hdr.type = SDP_TYPE_SAP_SERVER;
record->sap.hdr.service_name_length = 0;
record->sap.hdr.service_name = NULL;
record->sap.hdr.rfcomm_channel_number = 0;
@@ -354,31 +370,40 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
tSDP_DISC_ATTR *p_attr;
tSDP_PROTOCOL_ELEM pe;
- record->hdr.type = SDP_TYPE_RAW;
- record->hdr.service_name_length = 0;
- record->hdr.service_name = NULL;
- record->hdr.rfcomm_channel_number = -1;
- record->hdr.l2cap_psm = -1;
- record->hdr.profile_version = -1;
+ record->raw.hdr.type = SDP_TYPE_RAW;
+ record->raw.hdr.service_name_length = 0;
+ record->raw.hdr.service_name = NULL;
+ record->raw.hdr.rfcomm_channel_number = -1;
+ record->raw.hdr.l2cap_psm = -1;
+ record->raw.hdr.profile_version = -1;
/* Try to extract a service name */
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
- record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
- record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
+ record->raw.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+ record->raw.hdr.service_name = (char *)p_attr->attr_value.v.array;
}
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
- record->hdr.l2cap_psm = p_attr->attr_value.v.u16;
+ record->raw.hdr.l2cap_psm = p_attr->attr_value.v.u16;
}
/* Try to extract an RFCOMM channel */
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
- record->pse.hdr.rfcomm_channel_number = pe.params[0];
+ record->raw.hdr.rfcomm_channel_number = pe.params[0];
}
- record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
- record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
+ record->raw.hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_used;
+ record->raw.hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
}
+static bool check_if_uuid16_match(UINT16 uuid16, tBT_UUID *uuid)
+{
+ // Because it is converted to a short UUID, only uuid16 needs to be checked.
+ if (uuid->len == 2 && uuid->uu.uuid16 == uuid16) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
/*******************************************************************************
**
@@ -415,22 +440,25 @@ 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 (check_if_uuid16_match(UUID_SERVCLASS_PNP_INFORMATION, &su)) {
+ APPL_TRACE_DEBUG("%s() - found DIP uuid\n", __func__);
+ bta_create_dip_sdp_record(&evt_data.records[count], p_rec);
+ } else if (check_if_uuid16_match(UUID_SERVCLASS_MESSAGE_ACCESS, &su)) {
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)) {
+ } else if (check_if_uuid16_match(UUID_SERVCLASS_MESSAGE_NOTIFICATION, &su)) {
APPL_TRACE_DEBUG("%s() - found MAP (MNS) uuid\n", __func__);
bta_create_mns_sdp_record(&evt_data.records[count], p_rec);
- } else if (IS_UUID(UUID_PBAP_PSE, uuid->uu.uuid128)) {
+ } else if (check_if_uuid16_match(UUID_SERVCLASS_PBAP_PSE, &su)) {
APPL_TRACE_DEBUG("%s() - found PBAP (PSE) uuid\n", __func__);
bta_create_pse_sdp_record(&evt_data.records[count], p_rec);
- } else if (IS_UUID(UUID_PBAP_PCE, uuid->uu.uuid128)) {
+ } else if (check_if_uuid16_match(UUID_SERVCLASS_PBAP_PCE, &su)) {
APPL_TRACE_DEBUG("%s() - found PBAP (PCE) uuid\n", __func__);
bta_create_pce_sdp_record(&evt_data.records[count], p_rec);
- } else if (IS_UUID(UUID_OBEX_OBJECT_PUSH, uuid->uu.uuid128)) {
+ } else if (check_if_uuid16_match(UUID_SERVCLASS_OBEX_OBJECT_PUSH, &su)) {
APPL_TRACE_DEBUG("%s() - found Object Push Server (OPS) uuid\n", __func__);
bta_create_ops_sdp_record(&evt_data.records[count], p_rec);
- } else if (IS_UUID(UUID_SAP, uuid->uu.uuid128)) {
+ } else if (check_if_uuid16_match(UUID_SERVCLASS_SAP, &su)) {
APPL_TRACE_DEBUG("%s() - found SAP uuid\n", __func__);
bta_create_sap_sdp_record(&evt_data.records[count], p_rec);
} else {
@@ -526,6 +554,10 @@ void bta_sdp_search(tBTA_SDP_MSG *p_data)
SDP_InitDiscoveryDb (p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
bta_sdp_search_uuid, 0, NULL);
+ /* tell SDP to keep the raw data */
+ p_bta_sdp_cfg->p_sdp_db->raw_size = p_bta_sdp_cfg->sdp_raw_size;
+ p_bta_sdp_cfg->p_sdp_db->raw_data = p_bta_sdp_cfg->p_sdp_raw_data;
+
if (!SDP_ServiceSearchAttributeRequest2(p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db,
bta_sdp_search_cback, (void *)bta_sdp_search_uuid)) {
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
@@ -558,7 +590,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 +608,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);
}
}
diff --git a/lib/bt/host/bluedroid/bta/sdp/bta_sdp_api.c b/lib/bt/host/bluedroid/bta/sdp/bta_sdp_api.c
index cafb1a4a..d46f784b 100644
--- a/lib/bt/host/bluedroid/bta/sdp/bta_sdp_api.c
+++ b/lib/bt/host/bluedroid/bta/sdp/bta_sdp_api.c
@@ -65,7 +65,9 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
#if BTA_DYNAMIC_MEMORY == TRUE
/* Malloc buffer for SDP configuration structure */
p_bta_sdp_cfg->p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(p_bta_sdp_cfg->sdp_db_size);
- if (p_bta_sdp_cfg->p_sdp_db == NULL) {
+ p_bta_sdp_cfg->p_sdp_raw_data = (UINT8 *)osi_malloc(p_bta_sdp_cfg->sdp_raw_size);
+ if (p_bta_sdp_cfg->p_sdp_db == NULL || p_bta_sdp_cfg->p_sdp_raw_data == NULL) {
+ BTA_SdpCleanup();
return BTA_SDP_FAILURE;
}
#endif
@@ -101,15 +103,34 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
*******************************************************************************/
tBTA_SDP_STATUS BTA_SdpDisable(void)
{
+ BT_HDR *p_buf = NULL;
tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
+ if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
+ p_buf->event = BTA_SDP_API_DISABLE_EVT;
+ bta_sys_sendmsg(p_buf);
+ status = BTA_SDP_FAILURE;
+ }
+
+ return status;
+}
+
+tBTA_SDP_STATUS BTA_SdpCleanup(void)
+{
bta_sys_deregister(BTA_ID_SDP);
#if BTA_DYNAMIC_MEMORY == TRUE
/* Free buffer for SDP configuration structure */
- osi_free(p_bta_sdp_cfg->p_sdp_db);
- p_bta_sdp_cfg->p_sdp_db = NULL;
+ if (p_bta_sdp_cfg->p_sdp_db) {
+ osi_free(p_bta_sdp_cfg->p_sdp_db);
+ p_bta_sdp_cfg->p_sdp_db = NULL;
+ }
+
+ if (p_bta_sdp_cfg->p_sdp_raw_data) {
+ osi_free(p_bta_sdp_cfg->p_sdp_raw_data);
+ p_bta_sdp_cfg->p_sdp_raw_data = NULL;
+ }
#endif
- return (status);
+ return BTA_SDP_SUCCESS;
}
/*******************************************************************************
diff --git a/lib/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c b/lib/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c
index 322b25ca..423905bc 100644
--- a/lib/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c
+++ b/lib/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c
@@ -30,16 +30,24 @@
#define BTA_SDP_DB_SIZE 1500
#endif
+#ifndef BTA_SDP_RAW_DATA_SIZE
+#define BTA_SDP_RAW_DATA_SIZE 1024
+#endif
+
#if BTA_DYNAMIC_MEMORY == FALSE
+static UINT8 bta_sdp_raw_data[BTA_SDP_RAW_DATA_SIZE];
static UINT8 __attribute__ ((aligned(4))) bta_sdp_db_data[BTA_SDP_DB_SIZE];
#endif
/* SDP configuration structure */
tBTA_SDP_CFG bta_sdp_cfg = {
+ BTA_SDP_RAW_DATA_SIZE,
BTA_SDP_DB_SIZE,
#if BTA_DYNAMIC_MEMORY == FALSE
+ bta_sdp_raw_data,
(tSDP_DISCOVERY_DB *)bta_sdp_db_data /* The data buffer to keep SDP database */
#else
+ NULL,
NULL
#endif
};
diff --git a/lib/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h b/lib/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h
index cf0eb99c..f350ae37 100644
--- a/lib/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h
+++ b/lib/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h
@@ -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
diff --git a/lib/bt/host/bluedroid/bta/sys/utl.c b/lib/bt/host/bluedroid/bta/sys/utl.c
index c18567cd..94348e85 100644
--- a/lib/bt/host/bluedroid/bta/sys/utl.c
+++ b/lib/bt/host/bluedroid/bta/sys/utl.c
@@ -170,11 +170,12 @@ void utl_freebuf(void **p)
** p_cod - Pointer to the device class to set to
**
** cmd - the fields of the device class to update.
+** BTA_UTL_SET_COD_RESERVED_2 - overwrite the two least significant bits reserved_2
** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class
** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input
** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input
-** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class
-** BTA_UTL_INIT_COD - overwrite major, minor, and service class
+** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class, reserved_2 remain unchanged
+** BTA_UTL_INIT_COD - overwrite major, minor, and service class, reserved_2 remain unchanged
**
** Returns TRUE if successful, Otherwise FALSE
**
@@ -183,15 +184,19 @@ BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd)
{
UINT8 *dev;
UINT16 service;
- UINT8 minor, major;
+ UINT8 minor, major, reserved_2;
DEV_CLASS dev_class;
dev = BTM_ReadDeviceClass();
BTM_COD_SERVICE_CLASS( service, dev );
BTM_COD_MINOR_CLASS(minor, dev );
BTM_COD_MAJOR_CLASS(major, dev );
+ BTM_COD_RESERVED_2(reserved_2, dev);
switch (cmd) {
+ case BTA_UTL_SET_COD_RESERVED_2:
+ reserved_2 = p_cod->reserved_2 & BTM_COD_RESERVED_2_MASK;
+ break;
case BTA_UTL_SET_COD_MAJOR_MINOR:
minor = p_cod->minor & BTM_COD_MINOR_CLASS_MASK;
major = p_cod->major & BTM_COD_MAJOR_CLASS_MASK;
@@ -226,7 +231,7 @@ BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd)
}
/* convert the fields into the device class type */
- FIELDS_TO_COD(dev_class, minor, major, service);
+ FIELDS_TO_COD(dev_class, reserved_2, minor, major, service);
if (BTM_SetDeviceClass(dev_class) == BTM_SUCCESS) {
return TRUE;
@@ -252,16 +257,18 @@ BOOLEAN utl_get_device_class(tBTA_UTL_COD *p_cod)
{
UINT8 *dev;
UINT16 service;
- UINT8 minor, major;
+ UINT8 minor, major, reserved_2;
dev = BTM_ReadDeviceClass();
BTM_COD_SERVICE_CLASS( service, dev );
BTM_COD_MINOR_CLASS(minor, dev );
BTM_COD_MAJOR_CLASS(major, dev );
+ BTM_COD_RESERVED_2(reserved_2, dev );
p_cod->minor = minor;
p_cod->major = major;
p_cod->service = service;
+ p_cod->reserved_2 = reserved_2;
return TRUE;
}
diff --git a/lib/bt/host/bluedroid/btc/core/btc_ble_storage.c b/lib/bt/host/bluedroid/btc/core/btc_ble_storage.c
index 7df1bfe0..f20a7241 100644
--- a/lib/bt/host/bluedroid/btc/core/btc_ble_storage.c
+++ b/lib/bt/host/bluedroid/btc/core/btc_ble_storage.c
@@ -15,7 +15,7 @@
#if (SMP_INCLUDED == TRUE)
-//the maximum nubmer of bonded devices
+//the maximum number of bonded devices
#define BONED_DEVICES_MAX_COUNT (BTM_SEC_MAX_DEVICE_RECORDS)
static void _btc_storage_save(void)
@@ -58,7 +58,7 @@ static void _btc_storage_save(void)
addr_section_count ++;
iter = btc_config_section_next(iter);
}
- /*exceeded the maximum nubmer of bonded devices, delete them */
+ /*exceeded the maximum number of bonded devices, delete them */
if (need_remove_iter) {
while(need_remove_iter != btc_config_section_end()) {
const char *need_remove_section = btc_config_section_name(need_remove_iter);
@@ -954,6 +954,7 @@ bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr,
bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num)
{
bt_bdaddr_t bd_addr;
+ int addr_t;
char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0};
btc_config_lock();
@@ -975,6 +976,14 @@ bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev
string_to_bdaddr(name, &bd_addr);
memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t));
+ //get address type
+ if (_btc_storage_get_remote_addr_type((bt_bdaddr_t *)bond_dev->bd_addr, &addr_t) == BT_STATUS_SUCCESS) {
+ bond_dev->bd_addr_type = (uint8_t) addr_t;
+ } else {
+ // Set an invalid address type
+ bond_dev->bd_addr_type = 0xFF;
+ BTC_TRACE_ERROR("%s, %s get address type fail", __func__, name);
+ }
//resolve the peer device long term key
if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) {
bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK;
diff --git a/lib/bt/host/bluedroid/btc/core/btc_config.c b/lib/bt/host/bluedroid/btc/core/btc_config.c
index f46aef89..e2cce6da 100644
--- a/lib/bt/host/bluedroid/btc/core/btc_config.c
+++ b/lib/bt/host/bluedroid/btc/core/btc_config.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -29,6 +29,17 @@ static void btc_key_value_to_string(uint8_t *key_value, char *value_str, int key
static osi_mutex_t lock; // protects operations on |config|.
static config_t *config;
+
+int btc_config_file_path_get(char *file_path)
+{
+ if (file_path == NULL) {
+ return -1;
+ }
+
+ strcpy(file_path, CONFIG_FILE_PATH);
+ return 0;
+}
+
int btc_config_file_path_update(const char *file_path)
{
if (file_path != NULL && strlen(file_path) < NVS_NS_NAME_MAX_SIZE) {
diff --git a/lib/bt/host/bluedroid/btc/core/btc_dm.c b/lib/bt/host/bluedroid/btc/core/btc_dm.c
index 7e242a73..782569c2 100644
--- a/lib/bt/host/bluedroid/btc/core/btc_dm.c
+++ b/lib/bt/host/bluedroid/btc/core/btc_dm.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -182,11 +182,12 @@ static void btc_dm_remove_ble_bonding_keys(void)
btc_storage_remove_ble_bonding_keys(&bd_addr);
}
+#if BLE_SMP_BOND_NVS_FLASH
static void btc_dm_save_ble_bonding_keys(void)
{
if (!(btc_dm_cb.pairing_cb.ble.is_penc_key_rcvd || btc_dm_cb.pairing_cb.ble.is_pid_key_rcvd || btc_dm_cb.pairing_cb.ble.is_pcsrk_key_rcvd ||
- btc_dm_cb.pairing_cb.ble.is_lenc_key_rcvd || btc_dm_cb.pairing_cb.ble.is_lcsrk_key_rcvd || btc_dm_cb.pairing_cb.ble.is_lidk_key_rcvd)) {
- return ;
+ btc_dm_cb.pairing_cb.ble.is_lenc_key_rcvd || btc_dm_cb.pairing_cb.ble.is_lcsrk_key_rcvd || btc_dm_cb.pairing_cb.ble.is_lidk_key_rcvd)) {
+ return;
}
bt_bdaddr_t bd_addr;
@@ -244,13 +245,13 @@ static void btc_dm_save_ble_bonding_keys(void)
btc_dm_cb.pairing_cb.ble.is_lidk_key_rcvd = false;
}
}
+#endif
static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
{
/* Save link key, if not temporary */
BTC_TRACE_DEBUG("%s, status = %d", __func__, p_auth_cmpl->success);
bt_status_t status = BT_STATUS_FAIL;
- int addr_type;
bt_bdaddr_t bdaddr;
bdcpy(bdaddr.address, p_auth_cmpl->bd_addr);
bdcpy(btc_dm_cb.pairing_cb.bd_addr, p_auth_cmpl->bd_addr);
@@ -266,6 +267,9 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
return;
}
+#if BLE_SMP_BOND_NVS_FLASH
+ int addr_type;
+
if (btc_dm_cb.pairing_cb.ble.is_pid_key_rcvd) {
// delete unused section in NVS
btc_storage_remove_unused_sections(p_auth_cmpl->bd_addr, &btc_dm_cb.pairing_cb.ble.pid_key);
@@ -276,6 +280,7 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
}
btc_storage_set_ble_dev_auth_mode(&bdaddr, p_auth_cmpl->auth_mode, true);
btc_dm_save_ble_bonding_keys();
+#endif
} else {
/*Map the HCI fail reason to bt status */
switch (p_auth_cmpl->fail_reason) {
@@ -288,6 +293,9 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
status = BT_STATUS_AUTH_REJECTED;
break;
default:
+ BTC_TRACE_WARNING ("%s, remove bond in flash bd_addr: %08x%04x", __func__,
+ (p_auth_cmpl->bd_addr[0] << 24) + (p_auth_cmpl->bd_addr[1] << 16) + (p_auth_cmpl->bd_addr[2] << 8) + p_auth_cmpl->bd_addr[3],
+ (p_auth_cmpl->bd_addr[4] << 8) + p_auth_cmpl->bd_addr[5]);
btc_dm_remove_ble_bonding_keys();
status = BT_STATUS_FAIL;
break;
@@ -326,6 +334,7 @@ static void btc_dm_link_up_evt(tBTA_DM_LINK_UP *p_link_up)
}
}
+#if (SMP_INCLUDED == TRUE)
static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
{
/* Save link key, if not temporary */
@@ -485,6 +494,7 @@ static void btc_dm_pin_req_evt(tBTA_DM_PIN_REQ *p_pin_req)
}
#endif /// BTC_GAP_BT_INCLUDED == TRUE
}
+#endif // #if (SMP_INCLUDED == TRUE)
#if (CLASSIC_BT_INCLUDED == TRUE)
static void btc_dm_sp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_cfm_req)
@@ -625,6 +635,7 @@ static void btc_dm_pm_mode_chg_evt(tBTA_DM_MODE_CHG *p_mode_chg)
msg->act = BTC_GAP_BT_MODE_CHG_EVT;
memcpy(param.mode_chg.bda, p_mode_chg->bd_addr, ESP_BD_ADDR_LEN);
param.mode_chg.mode = p_mode_chg->mode;
+ param.mode_chg.interval= p_mode_chg->interval;
memcpy(msg->arg, &param, sizeof(esp_bt_gap_cb_param_t));
ret = btc_inter_profile_call(msg);
@@ -707,10 +718,9 @@ bt_status_t btc_dm_disable_service(tBTA_SERVICE_ID service_id)
return BT_STATUS_SUCCESS;
}
-
+#if (BTC_GAP_BT_INCLUDED == TRUE)
static void btc_dm_acl_link_stat(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat)
{
-#if (BTC_GAP_BT_INCLUDED == TRUE)
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_event_t event = ESP_BT_GAP_EVT_MAX;
bt_bdaddr_t bt_addr;
@@ -752,8 +762,8 @@ static void btc_dm_acl_link_stat(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat)
if (cb) {
cb(event, &param);
}
-#endif
}
+#endif
void btc_dm_sec_cb_handler(btc_msg_t *msg)
{
@@ -805,6 +815,7 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
btc_disable_bluetooth_evt();
break;
}
+#if (SMP_INCLUDED == TRUE)
case BTA_DM_PIN_REQ_EVT:
BTC_TRACE_DEBUG("BTA_DM_PIN_REQ_EVT");
btc_dm_pin_req_evt(&p_data->pin_req);
@@ -818,6 +829,7 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
case BTA_DM_BOND_CANCEL_CMPL_EVT:
BTC_TRACE_DEBUG("BTA_DM_BOND_CANCEL_CMPL_EVT");
break;
+#endif // #if (SMP_INCLUDED == TRUE)
#if (CLASSIC_BT_INCLUDED == TRUE)
case BTA_DM_SP_CFM_REQ_EVT:
btc_dm_sp_cfm_req_evt(&p_data->cfm_req);
@@ -838,7 +850,10 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
break;
#endif /* BTM_OOB_INCLUDED == TRUE */
case BTA_DM_ACL_LINK_STAT_EVT: {
+#if (BTC_GAP_BT_INCLUDED == TRUE)
+ btc_gap_bt_acl_link_num_update(&p_data->acl_link_stat);
btc_dm_acl_link_stat(&p_data->acl_link_stat);
+#endif
break;
}
case BTA_DM_DEV_UNPAIRED_EVT: {
diff --git a/lib/bt/host/bluedroid/btc/core/btc_main.c b/lib/bt/host/bluedroid/btc/core/btc_main.c
index 28f70b4b..cee4c251 100644
--- a/lib/bt/host/bluedroid/btc/core/btc_main.c
+++ b/lib/bt/host/bluedroid/btc/core/btc_main.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -60,6 +60,7 @@ static void btc_init_bluetooth(void)
#if (BLE_INCLUDED == TRUE)
//load the ble local key which has been stored in the flash
btc_dm_load_ble_local_keys();
+ bta_dm_co_security_param_init();
#endif ///BLE_INCLUDED == TRUE
#endif /* #if (SMP_INCLUDED) */
#if BTA_DYNAMIC_MEMORY
@@ -121,6 +122,11 @@ uint32_t btc_get_ble_status(void)
{
uint32_t status = BTC_BLE_STATUS_IDLE;
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ BTC_TRACE_ERROR("%s Bluedroid not enabled", __func__);
+ return status;
+ }
+
#if (BLE_INCLUDED == TRUE)
// Number of active advertising
extern uint8_t btm_ble_adv_active_count(void);
@@ -140,11 +146,29 @@ uint32_t btc_get_ble_status(void)
status |= BIT(BTC_BLE_STATUS_CONN);
}
+ // Number of active ACL connection
+ extern uint8_t btm_ble_acl_active_count(void);
+ if (btm_ble_acl_active_count()) {
+ status |= BIT(BTC_BLE_STATUS_CONN);
+ }
+
+ // Number of active L2C plcb
+ extern uint8_t l2cu_ble_plcb_active_count(void);
+ if (l2cu_ble_plcb_active_count()) {
+ status |= BIT(BTC_BLE_STATUS_CONN);
+ }
+
+ // Address resolve status
+ extern uint8_t btm_get_ble_addr_resolve_disable_status(void);
+ if (btm_get_ble_addr_resolve_disable_status()) {
+ status |= BIT(BTC_BLE_STATUS_ADDR_RESOLVE_DISABLE);
+ }
+
#if (SMP_INCLUDED == TRUE)
// Number of recorded devices
- extern uint8_t btm_ble_sec_dev_active_count(void);
- if (btm_ble_sec_dev_active_count()) {
- status |= BIT(BTC_BLE_STATUS_KEYS);
+ extern uint8_t btm_ble_sec_dev_record_count(void);
+ if (btm_ble_sec_dev_record_count()) {
+ status |= BIT(BTC_BLE_STATUS_DEVICE_REC);
}
// Number of saved bonded devices
@@ -170,18 +194,6 @@ uint32_t btc_get_ble_status(void)
}
#endif
- // Number of active ACL connection
- extern uint8_t btm_acl_active_count(void);
- if (btm_acl_active_count()) {
- status |= BIT(BTC_BLE_STATUS_CONN);
- }
-
- // Number of active L2C plcb
- extern uint8_t l2cu_plcb_active_count(void);
- if (l2cu_plcb_active_count()) {
- status |= BIT(BTC_BLE_STATUS_CONN);
- }
-
#if (GATTC_INCLUDED == TRUE)
// Number of registered GATTC APP
extern uint8_t bta_gattc_cl_rcb_active_count(void);
@@ -204,5 +216,12 @@ uint32_t btc_get_ble_status(void)
}
#endif
+ #if SMP_INCLUDED == TRUE
+ extern uint8_t smp_get_state(void);
+ if (smp_get_state()) {
+ status |= BIT(BTC_BLE_STATUS_SMP_STATE);
+ }
+ #endif
+
return status;
}
diff --git a/lib/bt/host/bluedroid/btc/core/btc_util.c b/lib/bt/host/bluedroid/btc/core/btc_util.c
index 5e29aba8..e22efce3 100644
--- a/lib/bt/host/bluedroid/btc/core/btc_util.c
+++ b/lib/bt/host/bluedroid/btc/core/btc_util.c
@@ -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
*/
@@ -349,10 +349,10 @@ esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status)
return esp_status;
}
-esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status)
+esp_bt_status_t btc_btm_status_to_esp_status(uint8_t btm_status)
{
esp_bt_status_t esp_status = ESP_BT_STATUS_FAIL;
- switch(btm_status){
+ switch(btm_status) {
case BTM_SUCCESS:
esp_status = ESP_BT_STATUS_SUCCESS;
break;
@@ -381,14 +381,18 @@ esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status)
esp_status = ESP_BT_STATUS_FAIL;
break;
default:
- esp_status = ESP_BT_STATUS_FAIL;
+ if (btm_status & BTM_HCI_ERROR) {
+ esp_status = ESP_BT_STATUS_BASE_FOR_HCI_ERR | (btm_status & 0x7F);
+ } else {
+ esp_status = ESP_BT_STATUS_FAIL;
+ }
break;
}
return esp_status;
}
-esp_bt_status_t btc_bta_status_to_esp_status (uint8_t bta_status)
+esp_bt_status_t btc_bta_status_to_esp_status(uint8_t bta_status)
{
esp_bt_status_t esp_status = ESP_BT_STATUS_FAIL;
switch(bta_status){
@@ -420,3 +424,36 @@ esp_bt_status_t btc_bta_status_to_esp_status (uint8_t bta_status)
return esp_status;
}
+
+void bta_to_btc_uuid(esp_bt_uuid_t *p_dest, tBT_UUID *p_src)
+{
+ p_dest->len = p_src->len;
+ if (p_src->len == LEN_UUID_16) {
+ p_dest->uuid.uuid16 = p_src->uu.uuid16;
+ } else if (p_src->len == LEN_UUID_32) {
+ p_dest->uuid.uuid32 = p_src->uu.uuid32;
+ } else if (p_src->len == LEN_UUID_128) {
+ memcpy(&p_dest->uuid.uuid128, p_src->uu.uuid128, p_dest->len);
+ } else if (p_src->len == 0) {
+ /* do nothing for now, there's some scenario will input 0
+ such as, receive notify, the descriptor may be 0 */
+ } else {
+ BTC_TRACE_ERROR("%s UUID len is invalid %d\n", __func__, p_src->len);
+ }
+}
+
+void btc_to_bta_uuid(tBT_UUID *p_dest, esp_bt_uuid_t *p_src)
+{
+ p_dest->len = p_src->len;
+ if (p_src->len == LEN_UUID_16) {
+ p_dest->uu.uuid16 = p_src->uuid.uuid16;
+ } else if (p_src->len == LEN_UUID_32) {
+ p_dest->uu.uuid32 = p_src->uuid.uuid32;
+ } else if (p_src->len == LEN_UUID_128) {
+ memcpy(&p_dest->uu.uuid128, p_src->uuid.uuid128, p_dest->len);
+ } else if (p_src->len == 0) {
+ /* do nothing for now, there's some scenario will input 0 */
+ } else {
+ BTC_TRACE_ERROR("%s UUID len is invalid %d\n", __func__, p_src->len);
+ }
+}
diff --git a/lib/bt/host/bluedroid/btc/include/btc/btc_config.h b/lib/bt/host/bluedroid/btc/include/btc/btc_config.h
index 8467ced8..6727c0ca 100644
--- a/lib/bt/host/bluedroid/btc/include/btc/btc_config.h
+++ b/lib/bt/host/bluedroid/btc/include/btc/btc_config.h
@@ -49,4 +49,6 @@ void btc_config_lock(void);
void btc_config_unlock(void);
int btc_config_file_path_update(const char *file_path);
+
+int btc_config_file_path_get(char *file_path);
#endif
diff --git a/lib/bt/host/bluedroid/btc/include/btc/btc_main.h b/lib/bt/host/bluedroid/btc/include/btc/btc_main.h
index df20a638..83f87b56 100644
--- a/lib/bt/host/bluedroid/btc/include/btc/btc_main.h
+++ b/lib/bt/host/bluedroid/btc/include/btc/btc_main.h
@@ -34,12 +34,14 @@ typedef enum {
BTC_BLE_STATUS_EXT_ADV, // Extended advertising exist
BTC_BLE_STATUS_SCAN, // Scanning exist
BTC_BLE_STATUS_CONN, // Connection exist
- BTC_BLE_STATUS_KEYS, // Device keys record exist
+ BTC_BLE_STATUS_DEVICE_REC, // Device record exist
BTC_BLE_STATUS_BOND, // Bond info exist
BTC_BLE_STATUS_GATTC_CACHE, // GATTC cache exist
BTC_BLE_STATUS_GATTC_APP, // GATTC application exist
BTC_BLE_STATUS_GATTS_SRVC, // GATTS service exist
BTC_BLE_STATUS_PRIVACY, // Privacy enabled
+ BTC_BLE_STATUS_ADDR_RESOLVE_DISABLE,// Address resolution disable status
+ BTC_BLE_STATUS_SMP_STATE, // SMP state machine
} tBTC_BLE_STATUS;
future_t **btc_main_get_future_p(btc_main_future_type_t type);
diff --git a/lib/bt/host/bluedroid/btc/include/btc/btc_util.h b/lib/bt/host/bluedroid/btc/include/btc/btc_util.h
index deb55990..1b96d6f4 100644
--- a/lib/bt/host/bluedroid/btc/include/btc/btc_util.h
+++ b/lib/bt/host/bluedroid/btc/include/btc/btc_util.h
@@ -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
*/
@@ -57,8 +57,11 @@ void uuid128_be_to_esp_uuid(esp_bt_uuid_t *u, uint8_t* uuid128);
void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str);
esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status);
-esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status);
-esp_bt_status_t btc_bta_status_to_esp_status (uint8_t bta_status);
+esp_bt_status_t btc_btm_status_to_esp_status(uint8_t btm_status);
+esp_bt_status_t btc_bta_status_to_esp_status(uint8_t bta_status);
+
+void bta_to_btc_uuid(esp_bt_uuid_t *p_dest, tBT_UUID *p_src);
+void btc_to_bta_uuid(tBT_UUID *p_dest, esp_bt_uuid_t *p_src);
#ifdef __cplusplus
}
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c
index 3c628d84..f2668e2e 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c
@@ -70,7 +70,7 @@ const UINT8 bta_av_co_cp_scmst[BTA_AV_CP_INFO_LEN] = "\x02\x02\x00";
/* SBC SRC codec capabilities */
const tA2D_SBC_CIE bta_av_co_sbc_caps = {
- (A2D_SBC_IE_SAMP_FREQ_44 | A2D_SBC_IE_SAMP_FREQ_48), /* samp_freq */
+ (A2D_SBC_IE_SAMP_FREQ_44), /* samp_freq */
(A2D_SBC_IE_CH_MD_MONO | A2D_SBC_IE_CH_MD_STEREO | A2D_SBC_IE_CH_MD_JOINT | A2D_SBC_IE_CH_MD_DUAL), /* ch_mode */
(A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 | A2D_SBC_IE_BLOCKS_8 | A2D_SBC_IE_BLOCKS_4), /* block_len */
(A2D_SBC_IE_SUBBAND_4 | A2D_SBC_IE_SUBBAND_8), /* num_subbands */
@@ -91,13 +91,13 @@ const tA2D_SBC_CIE bta_av_co_sbc_sink_caps = {
};
#if !defined(BTC_AV_SBC_DEFAULT_SAMP_FREQ)
-#define BTC_AV_SBC_DEFAULT_SAMP_FREQ A2D_SBC_IE_SAMP_FREQ_48
+#define BTC_AV_SBC_DEFAULT_SAMP_FREQ A2D_SBC_IE_SAMP_FREQ_44
#endif
/* Default SBC codec configuration */
const tA2D_SBC_CIE btc_av_sbc_default_config = {
BTC_AV_SBC_DEFAULT_SAMP_FREQ, /* samp_freq */
- A2D_SBC_IE_CH_MD_JOINT, /* ch_mode */
+ A2D_SBC_IE_CH_MD_JOINT, /* ch_mode */
A2D_SBC_IE_BLOCKS_16, /* block_len */
A2D_SBC_IE_SUBBAND_8, /* num_subbands */
A2D_SBC_IE_ALLOC_MD_L, /* alloc_mthd */
@@ -122,7 +122,6 @@ static UINT8 bta_av_co_audio_sink_supports_config(UINT8 codec_type, const UINT8
static BOOLEAN bta_av_co_audio_peer_src_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_src_index);
-
/*******************************************************************************
**
** Function bta_av_co_cp_is_active
@@ -245,18 +244,29 @@ BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_
UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID);
} while (0);
#endif
+#if (BTC_AV_EXT_CODEC == TRUE)
+ /* for external codec, we get codec capability from BTA_AV */
+ bta_av_co_cb.codec_caps.id = *p_codec_type;
+ memcpy(bta_av_co_cb.codec_caps.info, p_codec_info, AVDT_CODEC_SIZE);
+ bta_av_co_audio_codec_reset();
+#else
/* Set up for SBC codec for SRC*/
*p_codec_type = BTA_AV_CODEC_SBC;
-
/* This should not fail because we are using constants for parameters */
A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_caps, p_codec_info);
+#endif
return TRUE;
} else if (tsep == AVDT_TSEP_SNK) {
+#if (BTC_AV_EXT_CODEC == TRUE)
+ /* for external codec, we get codec capability from BTA_AV */
+ bta_av_co_cb.codec_caps.id = *p_codec_type;
+ memcpy(bta_av_co_cb.codec_caps.info, p_codec_info, AVDT_CODEC_SIZE);
+ bta_av_co_audio_codec_reset();
+#else
*p_codec_type = BTA_AV_CODEC_SBC;
-
/* This should not fail because we are using constants for parameters */
A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_sink_caps, p_codec_info);
-
+#endif
/* Codec is valid */
return TRUE;
} else {
@@ -387,7 +397,7 @@ void bta_av_build_src_cfg (UINT8 *p_pref_cfg, UINT8 *p_src_cap)
/* now try to build a preferred one */
/* parse configuration */
if ((status = A2D_ParsSbcInfo(&src_cap, p_src_cap, TRUE)) != 0) {
- APPL_TRACE_DEBUG(" Cant parse src cap ret = %d", status);
+ APPL_TRACE_DEBUG(" Can't parse src cap ret = %d", status);
return ;
}
@@ -1062,12 +1072,12 @@ static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UIN
memcpy(p_codec_cfg, bta_av_co_cb.codec_cfg.info, BTA_AV_CO_SBC_MAX_BITPOOL_OFF + 1);
/* Update the bit pool boundaries with the codec capabilities */
- p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF];
- p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF];
+ p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF] = BTA_AV_CO_MAX(p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF]);
+ p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] = BTA_AV_CO_MIN(p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF], p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
APPL_TRACE_EVENT("bta_av_co_audio_codec_build_config : bitpool min %d, max %d",
p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
- p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
+ p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
break;
default:
APPL_TRACE_ERROR("bta_av_co_audio_codec_build_config: unsupported codec id %d", bta_av_co_cb.codec_cfg.id);
@@ -1301,10 +1311,20 @@ static BOOLEAN bta_av_co_audio_peer_src_supports_codec(tBTA_AV_CO_PEER *p_peer,
if (p_src_index) {
*p_src_index = index;
}
+#if (BTC_AV_EXT_CODEC == TRUE)
+ tA2D_SBC_CIE cap_cie;
+ if (A2D_ParsSbcInfo(&cap_cie, bta_av_co_cb.codec_caps.info, TRUE) != A2D_SUCCESS) {
+ return FALSE;
+ }
+ if (0 == bta_av_sbc_cfg_matches_cap((UINT8 *)p_peer->srcs[index].codec_caps, &cap_cie)) {
+ return TRUE;
+ }
+#else
if (0 == bta_av_sbc_cfg_matches_cap((UINT8 *)p_peer->srcs[index].codec_caps,
- (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps)) {
+ (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps)) {
return TRUE;
}
+#endif
break;
default:
@@ -1334,7 +1354,11 @@ static UINT8 bta_av_co_audio_sink_supports_config(UINT8 codec_type, const UINT8
switch (codec_type) {
case BTA_AV_CODEC_SBC:
+#if (BTC_AV_EXT_CODEC == TRUE)
+ status = bta_av_sbc_cfg_in_external_codec_cap((UINT8 *)p_codec_cfg, (UINT8 *)bta_av_co_cb.codec_caps.info);
+#else
status = bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps);
+#endif
break;
case BTA_AV_CODEC_M12:
case BTA_AV_CODEC_M24:
@@ -1365,7 +1389,11 @@ static UINT8 bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8
switch (codec_type) {
case BTA_AV_CODEC_SBC:
+#if (BTC_AV_EXT_CODEC == TRUE)
+ status = bta_av_sbc_cfg_in_external_codec_cap((UINT8 *)p_codec_cfg, (UINT8 *)bta_av_co_cb.codec_caps.info);
+#else
status = bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_caps);
+#endif
break;
case BTA_AV_CODEC_M12:
case BTA_AV_CODEC_M24:
@@ -1478,12 +1506,16 @@ void bta_av_co_audio_codec_reset(void)
osi_mutex_global_lock();
FUNC_TRACE();
+#if (BTC_AV_EXT_CODEC == TRUE)
+ bta_av_co_cb.codec_cfg.id = bta_av_co_cb.codec_caps.id;
+ bta_av_build_src_cfg(bta_av_co_cb.codec_cfg.info, bta_av_co_cb.codec_caps.info);
+#else
/* Reset the current configuration to SBC */
bta_av_co_cb.codec_cfg.id = BTC_AV_CODEC_SBC;
-
if (A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, (tA2D_SBC_CIE *)&btc_av_sbc_default_config, bta_av_co_cb.codec_cfg.info) != A2D_SUCCESS) {
APPL_TRACE_ERROR("bta_av_co_audio_codec_reset A2D_BldSbcInfo failed");
}
+#endif
osi_mutex_global_unlock();
}
@@ -1564,7 +1596,6 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_
/* The new config was correctly built */
bta_av_co_cb.codec_cfg = new_cfg;
-
/* Check all devices support it */
*p_status = BTC_AV_SUCCESS;
return bta_av_co_audio_codec_supported(p_status);
@@ -1666,13 +1697,16 @@ void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl)
** Returns Nothing
**
*******************************************************************************/
-void bta_av_co_init(void)
+void bta_av_co_init(tBTC_AV_CODEC_INFO *codec_caps)
{
FUNC_TRACE();
/* Reset the control block */
memset(&bta_av_co_cb, 0, sizeof(bta_av_co_cb));
+ if (codec_caps) {
+ memcpy(&bta_av_co_cb.codec_caps, codec_caps, sizeof(tBTC_AV_CODEC_INFO));
+ }
bta_av_co_cb.codec_cfg_setconfig.id = BTC_AV_CODEC_NONE;
#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
@@ -1685,7 +1719,6 @@ void bta_av_co_init(void)
bta_av_co_audio_codec_reset();
}
-
/*******************************************************************************
**
** Function bta_av_co_peer_cp_supported
@@ -1729,7 +1762,7 @@ BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl)
** of our exported bitpool range. If set we will set the
** remote preference.
**
- ** Returns TRUE if config set, FALSE otherwize
+ ** Returns TRUE if config set, FALSE otherwise
**
*******************************************************************************/
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c
index 279b1001..86025021 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c
@@ -49,7 +49,12 @@ void btc_a2dp_on_idle(void)
}
#endif // BTC_AV_SRC_INCLUDED
- bta_av_co_init();
+#if (BTC_AV_EXT_CODEC == TRUE)
+ tBTC_AV_CODEC_INFO *codec_caps = btc_av_codec_cap_get();
+#else
+ tBTC_AV_CODEC_INFO *codec_caps = NULL;
+#endif
+ bta_av_co_init(codec_caps);
#if BTC_AV_SINK_INCLUDED
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC && btc_av_get_service_id() == BTA_A2DP_SINK_SERVICE_ID) {
@@ -88,9 +93,11 @@ BOOLEAN btc_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start)
ack = TRUE;
}
} else {
+#if (BTC_AV_EXT_CODEC == FALSE)
/* we were remotely started, make sure codec
is setup before datapath is started */
btc_a2dp_source_setup_codec();
+#endif
}
/* media task is autostarted upon a2dp audiopath connection */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c
index ba264f93..3076e882 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c
@@ -71,8 +71,10 @@ static void btc_a2dp_datapath_open(void)
/* Start the media task to encode SBC */
btc_a2dp_source_start_audio_req();
+#if (BTC_AV_EXT_CODEC == FALSE)
/* make sure we update any changed sbc encoder params */
btc_a2dp_source_encoder_update();
+#endif
}
#endif
#if (BTC_AV_SINK_INCLUDED == TRUE)
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c
index 4a1f060f..d81f0958 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,12 +30,13 @@
#include "btc_av.h"
#include "btc/btc_util.h"
#include "esp_a2dp_api.h"
-#include "oi_codec_sbc.h"
-#include "oi_status.h"
#include "osi/future.h"
#include <assert.h>
-#if (BTC_AV_SINK_INCLUDED == TRUE)
+#if (BTC_AV_SINK_INCLUDED == TRUE) && (BTC_AV_EXT_CODEC == FALSE)
+
+#include "oi_codec_sbc.h"
+#include "oi_status.h"
/*****************************************************************************
** Constants
@@ -86,13 +87,6 @@ typedef struct {
} a2dp_sink_task_evt_t;
typedef struct {
- UINT16 num_frames_to_be_processed;
- UINT16 len;
- UINT16 offset;
- UINT16 layer_specific;
-} tBT_SBC_HDR;
-
-typedef struct {
BOOLEAN rx_flush; /* discards any incoming data when true */
UINT8 channel_count;
struct osi_event *data_ready_event;
@@ -121,7 +115,7 @@ static void btc_a2dp_sink_rx_flush(void);
static int btc_a2dp_sink_get_track_frequency(UINT8 frequency);
static int btc_a2dp_sink_get_track_channel_count(UINT8 channeltype);
/* Handle incoming media packets A2DP SINK streaming*/
-static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg);
+static void btc_a2dp_sink_handle_inc_media(BT_HDR *p_msg);
static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg);
static void btc_a2dp_sink_handle_clear_track(void);
static BOOLEAN btc_a2dp_sink_clear_track(void);
@@ -346,7 +340,7 @@ void btc_a2dp_sink_reset_decoder(UINT8 *p_av)
static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
{
- tBT_SBC_HDR *p_msg;
+ BT_HDR *p_msg;
int nb_of_msgs_to_process = 0;
if (fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ)) {
@@ -362,13 +356,12 @@ static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_ON){
return;
}
- p_msg = (tBT_SBC_HDR *)fixed_queue_dequeue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, 0);
+ p_msg = (BT_HDR *)fixed_queue_dequeue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, 0);
if ( p_msg == NULL ) {
APPL_TRACE_ERROR("Insufficient data in que ");
break;
}
btc_a2dp_sink_handle_inc_media(p_msg);
- osi_free(p_msg);
nb_of_msgs_to_process--;
}
APPL_TRACE_DEBUG(" Process Frames - ");
@@ -526,25 +519,27 @@ static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg
** Returns void
**
*******************************************************************************/
-static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
+static void btc_a2dp_sink_handle_inc_media(BT_HDR *p_msg)
{
UINT8 *sbc_start_frame = ((UINT8 *)(p_msg + 1) + p_msg->offset + 1);
int count;
UINT32 pcmBytes, availPcmBytes;
OI_INT16 *pcmDataPointer = a2dp_sink_local_param.pcmData; /*Will be overwritten on next packet receipt*/
OI_STATUS status;
- int num_sbc_frames = p_msg->num_frames_to_be_processed;
+ int num_sbc_frames = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
UINT32 sbc_frame_len = p_msg->len - 1;
availPcmBytes = sizeof(a2dp_sink_local_param.pcmData);
/* XXX: Check if the below check is correct, we are checking for peer to be sink when we are sink */
if (btc_av_get_peer_sep() == AVDT_TSEP_SNK || (a2dp_sink_local_param.btc_aa_snk_cb.rx_flush)) {
APPL_TRACE_DEBUG(" State Changed happened in this tick ");
+ osi_free(p_msg);
return;
}
// ignore data if no one is listening
if (!btc_a2dp_control_get_datachnl_stat()) {
+ osi_free(p_msg);
return;
}
@@ -565,9 +560,9 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
for (count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++) {
pcmBytes = availPcmBytes;
status = OI_CODEC_SBC_DecodeFrame(&a2dp_sink_local_param.context, (const OI_BYTE **)&sbc_start_frame,
- (OI_UINT32 *)&sbc_frame_len,
- (OI_INT16 *)pcmDataPointer,
- (OI_UINT32 *)&pcmBytes);
+ (OI_UINT32 *)&sbc_frame_len,
+ (OI_INT16 *)pcmDataPointer,
+ (OI_UINT32 *)&pcmBytes);
if (!OI_SUCCESS(status)) {
APPL_TRACE_ERROR("Decoding failure: %d\n", status);
break;
@@ -577,6 +572,7 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
p_msg->offset += (p_msg->len - 1) - sbc_frame_len;
p_msg->len = sbc_frame_len + 1;
}
+ osi_free(p_msg);
btc_a2d_data_cb_to_app((uint8_t *)a2dp_sink_local_param.pcmData, (sizeof(a2dp_sink_local_param.pcmData) - availPcmBytes));
}
@@ -663,35 +659,28 @@ static int btc_a2dp_sink_get_track_channel_count(UINT8 channeltype)
*******************************************************************************/
UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt)
{
- tBT_SBC_HDR *p_msg;
-
if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_ON){
+ osi_free(p_pkt);
return 0;
}
- if (a2dp_sink_local_param.btc_aa_snk_cb.rx_flush == TRUE) { /* Flush enabled, do not enque*/
+ if (a2dp_sink_local_param.btc_aa_snk_cb.rx_flush == TRUE) { /* Flush enabled, do not enqueue */
+ osi_free(p_pkt);
return fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ);
}
if (fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ) >= MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ) {
+ osi_free(p_pkt);
APPL_TRACE_WARNING("Pkt dropped\n");
return fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ);
}
APPL_TRACE_DEBUG("btc_a2dp_sink_enque_buf + ");
- /* allocate and Queue this buffer */
- if ((p_msg = (tBT_SBC_HDR *) osi_malloc(sizeof(tBT_SBC_HDR) +
- p_pkt->offset + p_pkt->len)) != NULL) {
- memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len));
- p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
- APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
- fixed_queue_enqueue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
- osi_thread_post_event(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event, OSI_THREAD_MAX_TIMEOUT);
- } else {
- /* let caller deal with a failed allocation */
- APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - ");
- }
+ // p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
+ fixed_queue_enqueue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, p_pkt, FIXED_QUEUE_MAX_TIMEOUT);
+ osi_thread_post_event(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event, OSI_THREAD_MAX_TIMEOUT);
+
return fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ);
}
@@ -749,4 +738,4 @@ static void btc_a2dp_sink_thread_cleanup(UNUSED_ATTR void *context)
a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event = NULL;
}
-#endif /* BTC_AV_SINK_INCLUDED */
+#endif /* (BTC_AV_SINK_INCLUDED == TRUE) && (BTC_AV_EXT_CODEC == FALSE) */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink_ext_coedc.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink_ext_coedc.c
new file mode 100644
index 00000000..d2a6164b
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink_ext_coedc.c
@@ -0,0 +1,286 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "common/bt_target.h"
+#include "common/bt_trace.h"
+#include <string.h>
+#include <stdint.h>
+#include "common/bt_defs.h"
+#include "osi/allocator.h"
+#include "osi/mutex.h"
+#include "osi/thread.h"
+#include "osi/fixed_queue.h"
+#include "stack/a2d_api.h"
+#include "bta/bta_av_api.h"
+#include "bta/bta_av_ci.h"
+#include "btc_av_co.h"
+#include "btc_a2dp.h"
+#include "btc_a2dp_control.h"
+#include "btc_a2dp_sink.h"
+#include "btc/btc_manage.h"
+#include "btc_av.h"
+#include "btc/btc_util.h"
+#include "esp_a2dp_api.h"
+#include "osi/future.h"
+#include <assert.h>
+
+#if (BTC_AV_SINK_INCLUDED == TRUE) && (BTC_AV_EXT_CODEC == TRUE)
+
+#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (25)
+#define BTC_A2DP_SNK_DATA_QUEUE_IDX (1)
+
+enum {
+ BTC_A2DP_SINK_STATE_OFF = 0,
+ BTC_A2DP_SINK_STATE_ON = 1,
+};
+
+typedef struct {
+ BOOLEAN rx_flush; /* discards any incoming data when true */
+ struct osi_event *data_ready_event;
+ fixed_queue_t *audio_rx_q;
+} tBTC_A2DP_SINK_CB;
+
+typedef struct {
+ uint16_t expected_seq_num;
+ bool seq_num_recount;
+} a2dp_sink_media_pkt_seq_num_t;
+
+typedef struct {
+ tBTC_A2DP_SINK_CB btc_aa_snk_cb;
+ osi_thread_t *btc_aa_snk_task_hdl;
+ a2dp_sink_media_pkt_seq_num_t media_pkt_seq_num;
+} a2dp_sink_local_param_t;
+
+static int btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
+static esp_a2d_sink_audio_data_cb_t bt_aa_snk_audio_data_cb = NULL;
+
+#if A2D_DYNAMIC_MEMORY == FALSE
+static a2dp_sink_local_param_t a2dp_sink_local_param;
+#else
+static a2dp_sink_local_param_t *a2dp_sink_local_param_ptr;
+#define a2dp_sink_local_param (*a2dp_sink_local_param_ptr)
+#endif ///A2D_DYNAMIC_MEMORY == FALSE
+
+static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context);
+static void btc_a2dp_sink_handle_inc_media(BT_HDR *p_msg);
+
+void btc_a2dp_sink_reg_audio_data_cb(esp_a2d_sink_audio_data_cb_t callback)
+{
+ bt_aa_snk_audio_data_cb = callback;
+}
+
+static inline void btc_a2d_audio_data_cb_to_app(uint16_t conn_hdl, uint8_t *buf, uint8_t *data, uint16_t len, uint16_t number_frame, uint32_t timestamp)
+{
+ if (bt_aa_snk_audio_data_cb) {
+ /* AVDT media packet offset is larger than sizeof(esp_a2d_audio_buff_t), it safe to do this */
+ esp_a2d_audio_buff_t *audio_buff = (esp_a2d_audio_buff_t *)buf;
+ audio_buff->buff_size = len;
+ audio_buff->number_frame = number_frame;
+ audio_buff->data_len = len;
+ audio_buff->data = data;
+ audio_buff->timestamp = timestamp;
+ bt_aa_snk_audio_data_cb(conn_hdl, audio_buff);
+ }
+ else {
+ osi_free(buf);
+ }
+}
+
+static void btc_a2dp_sink_rx_flush(void)
+{
+ while (!fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q)) {
+ osi_free(fixed_queue_dequeue(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q, 0));
+ }
+}
+
+bool btc_a2dp_sink_startup(void)
+{
+ if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_OFF) {
+ APPL_TRACE_ERROR("a2dp sink already start up");
+ return false;
+ }
+
+#if A2D_DYNAMIC_MEMORY == TRUE
+ if ((a2dp_sink_local_param_ptr = (a2dp_sink_local_param_t *)osi_malloc(sizeof(a2dp_sink_local_param_t))) == NULL) {
+ APPL_TRACE_ERROR("%s malloc failed!", __func__);
+ return false;
+ }
+ memset((void *)a2dp_sink_local_param_ptr, 0, sizeof(a2dp_sink_local_param_t));
+#endif
+
+ a2dp_sink_local_param.btc_aa_snk_task_hdl = btc_get_current_thread();
+
+ struct osi_event *data_event = osi_event_create(btc_a2dp_sink_data_ready, NULL);
+ assert (data_event != NULL);
+ osi_event_bind(data_event, a2dp_sink_local_param.btc_aa_snk_task_hdl, BTC_A2DP_SNK_DATA_QUEUE_IDX);
+ a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event = data_event;
+ a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q = fixed_queue_new(QUEUE_SIZE_MAX);
+ btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON;
+
+ btc_a2dp_control_init();
+
+ return true;
+}
+
+void btc_a2dp_sink_shutdown(void)
+{
+ if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_ON) {
+ APPL_TRACE_ERROR("a2dp sink already shutdown");
+ return;
+ }
+
+ btc_a2dp_control_set_datachnl_stat(FALSE);
+
+ btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
+
+ btc_a2dp_control_cleanup();
+
+ fixed_queue_free(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q, osi_free_func);
+
+ a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q = NULL;
+
+ osi_event_delete(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event);
+ a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event = NULL;
+
+ a2dp_sink_local_param.btc_aa_snk_task_hdl = NULL;
+
+#if A2D_DYNAMIC_MEMORY == TRUE
+ osi_free(a2dp_sink_local_param_ptr);
+ a2dp_sink_local_param_ptr = NULL;
+#endif
+}
+
+void btc_a2dp_sink_on_idle(void)
+{
+ a2dp_sink_local_param.btc_aa_snk_cb.rx_flush = TRUE;
+ btc_a2dp_sink_rx_flush();
+}
+
+void btc_a2dp_sink_on_stopped(tBTA_AV_SUSPEND *p_av)
+{
+ UNUSED(p_av);
+
+ a2dp_sink_local_param.btc_aa_snk_cb.rx_flush = TRUE;
+ btc_a2dp_control_set_datachnl_stat(FALSE);
+ btc_a2dp_sink_rx_flush();
+}
+
+void btc_a2dp_sink_on_suspended(tBTA_AV_SUSPEND *p_av)
+{
+ UNUSED(p_av);
+
+ a2dp_sink_local_param.btc_aa_snk_cb.rx_flush = TRUE;
+ btc_a2dp_sink_rx_flush();
+}
+
+void btc_a2dp_sink_set_rx_flush(BOOLEAN enable)
+{
+ if (enable == FALSE) {
+ a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num = 0x1;
+ a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount = true;
+ }
+ a2dp_sink_local_param.btc_aa_snk_cb.rx_flush = enable;
+ btc_a2dp_sink_rx_flush();
+}
+
+static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
+{
+ BT_HDR *p_msg;
+ int nb_of_msgs_to_process = 0;
+
+ if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_ON){
+ return;
+ }
+
+ if (!fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q)) {
+ if (a2dp_sink_local_param.btc_aa_snk_cb.rx_flush == TRUE) {
+ btc_a2dp_sink_rx_flush();
+ return;
+ }
+ nb_of_msgs_to_process = fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q);
+ APPL_TRACE_DEBUG("%s nb msgs:%d", __func__, nb_of_msgs_to_process);
+ while (nb_of_msgs_to_process > 0) {
+ p_msg = (BT_HDR *)fixed_queue_dequeue(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q, 0);
+ if ( p_msg == NULL ) {
+ APPL_TRACE_ERROR("%s insufficient data in queue", __func__);
+ break;
+ }
+ btc_a2dp_sink_handle_inc_media(p_msg);
+ nb_of_msgs_to_process--;
+ }
+
+ if (!fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q)) {
+ osi_thread_post_event(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event, OSI_THREAD_MAX_TIMEOUT);
+ }
+ }
+}
+
+static void btc_a2dp_sink_handle_inc_media(BT_HDR *p_msg)
+{
+ UINT8 *sbc_start_frame = ((UINT8 *)(p_msg + 1) + p_msg->offset + 1);
+ int num_sbc_frames = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
+ UINT32 sbc_frame_len = p_msg->len - 1;
+
+ if (a2dp_sink_local_param.btc_aa_snk_cb.rx_flush) {
+ osi_free(p_msg);
+ return;
+ }
+
+ /* ignore data if no one is listening */
+ if (!btc_a2dp_control_get_datachnl_stat()) {
+ osi_free(p_msg);
+ return;
+ }
+
+ if (p_msg->layer_specific != a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num) {
+ /* Because the sequence number of some devices is not recounted */
+ if (!a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount ||
+ a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num != 0x1) {
+ APPL_TRACE_WARNING("Sequence numbers error, recv:0x%x, expect:0x%x, recount:0x%x",
+ p_msg->layer_specific, a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num,
+ a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount);
+ }
+ }
+ a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num = p_msg->layer_specific + 1;
+ a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount = false;
+
+ APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d\n", num_sbc_frames, sbc_frame_len);
+
+ UINT32 timestamp = *((UINT32 *) (p_msg + 1));
+ UINT16 conn_hdl = btc_a2d_conn_handle_get();
+ btc_a2d_audio_data_cb_to_app(conn_hdl, (uint8_t *)p_msg, sbc_start_frame, sbc_frame_len, num_sbc_frames, timestamp);
+ /* dont free p_msg here */
+}
+
+UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt)
+{
+ if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_ON){
+ osi_free(p_pkt);
+ return 0;
+ }
+
+ if (a2dp_sink_local_param.btc_aa_snk_cb.rx_flush == TRUE) {
+ /* Flush enabled, do not enqueue */
+ osi_free(p_pkt);
+ return fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q);
+ }
+
+ if (fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q) >= MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ) {
+ osi_free(p_pkt);
+ APPL_TRACE_WARNING("Pkt dropped\n");
+ return fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q);
+ }
+
+ APPL_TRACE_DEBUG("btc_a2dp_sink_enque_buf + ");
+
+ // p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
+ fixed_queue_enqueue(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q, p_pkt, FIXED_QUEUE_MAX_TIMEOUT);
+ osi_thread_post_event(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event, OSI_THREAD_MAX_TIMEOUT);
+
+ return fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.audio_rx_q);
+}
+
+#endif
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
index 4fcdd5b7..40b3db00 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -36,11 +36,12 @@
#include "btc_av.h"
#include "btc/btc_util.h"
#include "esp_a2dp_api.h"
-#include "sbc_encoder.h"
#include "osi/future.h"
#include <assert.h>
-#if BTC_AV_SRC_INCLUDED
+#if (BTC_AV_SRC_INCLUDED == TRUE) && (BTC_AV_EXT_CODEC == FALSE)
+
+#include "sbc_encoder.h"
/*****************************************************************************
** BQB global variables
@@ -74,21 +75,15 @@ enum {
/* Media task tick in milliseconds, must be set to multiple of
(1000/TICKS_PER_SEC) */
-#define BTC_MEDIA_TIME_TICK_MS (20)
+#define BTC_MEDIA_TIME_TICK_MS (30)
#define A2DP_DATA_READ_POLL_MS (BTC_MEDIA_TIME_TICK_MS / 2)
#ifndef MAX_PCM_FRAME_NUM_PER_TICK
-#define MAX_PCM_FRAME_NUM_PER_TICK 14 // 14 for 20ms
+#define MAX_PCM_FRAME_NUM_PER_TICK 21 // 14 for 20ms
#endif
#define BTC_MEDIA_AA_BUF_SIZE (4096+16)
-#if (BTA_AV_CO_CP_SCMS_T == TRUE)
-#define BTC_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE + 1)
-#else
-#define BTC_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE)
-#endif
-
#ifndef BTC_MEDIA_BITRATE_STEP
#define BTC_MEDIA_BITRATE_STEP 5
#endif
@@ -97,8 +92,8 @@ enum {
#define BTC_A2DP_NON_EDR_MAX_RATE 229
#endif
-/* Extreme quality quality setting @ 48 khz */
-#define DEFAULT_SBC_BITRATE 672
+/* Middle quality quality setting @ 44.1 khz */
+#define DEFAULT_SBC_BITRATE 328
/*
* CONGESTION COMPENSATION CTRL ::
@@ -120,7 +115,8 @@ enum {
layers we might need to temporarily buffer up data */
/* 5 frames is equivalent to 6.89*5*2.9 ~= 100 ms @ 44.1 khz, 20 ms mediatick */
-#define MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ (50) // 18 for 20ms tick
+#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ (5)
+#define MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ (27) // 18 for 20ms tick
#define BTC_A2DP_SRC_DATA_QUEUE_IDX (1)
@@ -169,6 +165,10 @@ typedef struct {
UINT64 last_frame_us;
} a2dp_source_local_param_t;
+static BOOLEAN btc_a2dp_source_stop_audio_req(void);
+static BOOLEAN btc_a2dp_source_tx_flush_req(void);
+static BOOLEAN btc_a2dp_source_audio_feeding_init_req(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_msg);
+
static void btc_a2dp_source_thread_init(UNUSED_ATTR void *context);
static void btc_a2dp_source_thread_cleanup(UNUSED_ATTR void *context);
static void btc_a2dp_source_flush_q(fixed_queue_t *p_q);
@@ -225,11 +225,6 @@ static inline void btc_aa_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_t
** BTC ADAPTATION
*****************************************************************************/
-bool btc_a2dp_source_is_streaming(void)
-{
- return a2dp_source_local_param.btc_aa_src_cb.is_tx_timer == TRUE;
-}
-
bool btc_a2dp_source_is_task_shutting_down(void)
{
return btc_a2dp_source_state == BTC_A2DP_SOURCE_STATE_SHUTTING_DOWN;
@@ -504,7 +499,7 @@ BOOLEAN btc_a2dp_source_start_audio_req(void)
** Returns TRUE is success
**
*******************************************************************************/
-BOOLEAN btc_a2dp_source_stop_audio_req(void)
+static BOOLEAN btc_a2dp_source_stop_audio_req(void)
{
/*
* Explicitly check whether the btc_aa_src_ctrl_queue is not NULL to
@@ -535,7 +530,7 @@ BOOLEAN btc_a2dp_source_stop_audio_req(void)
** Returns TRUE is success
**
*******************************************************************************/
-BOOLEAN btc_a2dp_source_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg)
+static BOOLEAN btc_a2dp_source_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg)
{
tBTC_MEDIA_INIT_AUDIO *p_buf;
if (NULL == (p_buf = osi_malloc(sizeof(tBTC_MEDIA_INIT_AUDIO)))) {
@@ -558,7 +553,7 @@ BOOLEAN btc_a2dp_source_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg)
** Returns TRUE is success
**
*******************************************************************************/
-BOOLEAN btc_a2dp_source_enc_update_req(tBTC_MEDIA_UPDATE_AUDIO *p_msg)
+static BOOLEAN btc_a2dp_source_enc_update_req(tBTC_MEDIA_UPDATE_AUDIO *p_msg)
{
tBTC_MEDIA_UPDATE_AUDIO *p_buf;
if (NULL == (p_buf = osi_malloc(sizeof(tBTC_MEDIA_UPDATE_AUDIO)))) {
@@ -1450,6 +1445,7 @@ static void btc_a2dp_source_prep_2_send(UINT8 nb_frame)
*******************************************************************************/
static void btc_a2dp_source_send_aa_frame(void)
{
+ /* if external codec is used, skip generate audio frame */
UINT8 nb_frame_2_send;
/* get the number of frame to send */
@@ -1460,8 +1456,8 @@ static void btc_a2dp_source_send_aa_frame(void)
btc_a2dp_source_prep_2_send(nb_frame_2_send);
}
- /* send it */
- BTC_TRACE_VERBOSE("%s: send %d frames", __FUNCTION__, nb_frame_2_send);
+ BTC_TRACE_VERBOSE("%s: send %d new frames", __FUNCTION__, nb_frame_2_send);
+
bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
}
@@ -1538,8 +1534,8 @@ static void btc_a2dp_source_aa_stop_tx(void)
when the DUT and the remote device issue SUSPEND simultaneously
and due to the processing of the SUSPEND request from the remote,
the media path is torn down. If the A2DP HAL happens to wait
- for ACK for the initiated SUSPEND, it would never receive it casuing
- a block/wait. Due to this acknowledgement, the A2DP HAL is guranteed
+ for ACK for the initiated SUSPEND, it would never receive it causing
+ a block/wait. Due to this acknowledgement, the A2DP HAL is guaranteed
to get the ACK for any pending command in such cases. */
if (send_ack) {
@@ -1646,4 +1642,4 @@ static void btc_a2dp_source_thread_cleanup(UNUSED_ATTR void *context)
a2dp_source_local_param.btc_aa_src_cb.poll_data = NULL;
}
-#endif /* BTC_AV_INCLUDED */
+#endif /* (BTC_AV_SRC_INCLUDED == TRUE) && (BTC_AV_EXT_CODEC == FALSE) */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source_ext_codec.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source_ext_codec.c
new file mode 100644
index 00000000..f6a71add
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source_ext_codec.c
@@ -0,0 +1,235 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "common/bt_target.h"
+#include "common/bt_trace.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include "osi/allocator.h"
+#include "osi/fixed_queue.h"
+#include "stack/a2d_api.h"
+#include "bta/bta_av_api.h"
+#include "bta/bta_av_ci.h"
+#include "btc/btc_manage.h"
+#include "btc/btc_common.h"
+#include "btc_av_co.h"
+#include "btc_a2dp.h"
+#include "btc_a2dp_control.h"
+#include "btc_a2dp_source.h"
+#include "btc_av.h"
+#include "esp_a2dp_api.h"
+#include <assert.h>
+
+#if (BTC_AV_SRC_INCLUDED == TRUE) && (BTC_AV_EXT_CODEC == TRUE)
+
+#define MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ (27)
+
+enum {
+ BTC_A2DP_SOURCE_STATE_OFF = 0,
+ BTC_A2DP_SOURCE_STATE_ON = 1,
+};
+
+typedef struct {
+ BOOLEAN stream_started;
+ BOOLEAN tx_flush;
+ fixed_queue_t *audio_tx_q;
+} a2dp_source_local_param_t;
+
+static int btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF;
+#if A2D_DYNAMIC_MEMORY == FALSE
+static a2dp_source_local_param_t a2dp_source_local_param;
+#else
+static a2dp_source_local_param_t *a2dp_source_local_param_ptr;
+#define a2dp_source_local_param (*a2dp_source_local_param_ptr)
+#endif ///A2D_DYNAMIC_MEMORY == FALSE
+
+static inline void btc_aa_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
+{
+ esp_a2d_cb_t btc_aa_cb = (esp_a2d_cb_t)btc_profile_cb_get(BTC_PID_A2DP);
+ if (btc_aa_cb) {
+ btc_aa_cb(event, param);
+ }
+}
+
+static void btc_a2dp_source_tx_flush(void)
+{
+ while (!fixed_queue_is_empty(a2dp_source_local_param.audio_tx_q)) {
+ osi_free(fixed_queue_dequeue(a2dp_source_local_param.audio_tx_q, 0));
+ }
+}
+
+static void btc_a2dp_source_tx_stop(void)
+{
+ if (a2dp_source_local_param.stream_started == TRUE) {
+ a2dp_source_local_param.stream_started = FALSE;
+ /* ack to command */
+ btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
+ }
+
+ /* flush tx queue */
+ btc_a2dp_source_tx_flush();
+ a2dp_source_local_param.tx_flush = FALSE;
+}
+
+BOOLEAN btc_a2dp_source_enqueue_audio_frame(BT_HDR *p_buf)
+{
+ if (btc_a2dp_source_state != BTC_A2DP_SOURCE_STATE_ON) {
+ APPL_TRACE_WARNING("%s source not start up", __func__);
+ return FALSE;
+ }
+
+ if (a2dp_source_local_param.tx_flush) {
+ APPL_TRACE_WARNING("%s try to send data when tx flush enable", __func__);
+ return FALSE;
+ }
+
+ if (fixed_queue_length(a2dp_source_local_param.audio_tx_q) > MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ) {
+ APPL_TRACE_WARNING("%s audio tx queue overflow: %d", __func__, fixed_queue_length(a2dp_source_local_param.audio_tx_q));
+ return FALSE;
+ }
+
+ fixed_queue_enqueue(a2dp_source_local_param.audio_tx_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
+ bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
+ return TRUE;
+}
+
+void btc_source_report_delay_value(UINT16 delay_value)
+{
+ esp_a2d_cb_param_t param;
+
+ if (btc_a2dp_source_state != BTC_A2DP_SOURCE_STATE_ON){
+ return;
+ }
+
+ param.a2d_report_delay_value_stat.delay_value = delay_value;
+
+ btc_aa_cb_to_app(ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT, &param);
+}
+
+BOOLEAN btc_a2dp_source_start_audio_req(void)
+{
+ a2dp_source_local_param.stream_started = TRUE;
+ return TRUE;
+}
+
+BT_HDR *btc_a2dp_source_audio_readbuf(void)
+{
+ if (btc_a2dp_source_state != BTC_A2DP_SOURCE_STATE_ON || a2dp_source_local_param.tx_flush){
+ return NULL;
+ }
+ return fixed_queue_dequeue(a2dp_source_local_param.audio_tx_q, 0);
+}
+
+void btc_a2dp_source_set_tx_flush(BOOLEAN enable)
+{
+ a2dp_source_local_param.tx_flush = enable;
+ if (enable) {
+ btc_a2dp_source_tx_flush();
+ }
+}
+
+void btc_a2dp_source_on_suspended(tBTA_AV_SUSPEND *p_av)
+{
+ /* check for status failures */
+ if (p_av->status != BTA_AV_SUCCESS) {
+ if (p_av->initiator == TRUE) {
+ btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
+ }
+ }
+
+ /* stop tx, ack to cmd, flush tx queue */
+ btc_a2dp_source_tx_stop();
+}
+
+void btc_a2dp_source_on_stopped(tBTA_AV_SUSPEND *p_av)
+{
+ /* allow using this api for other than suspend */
+ if (p_av != NULL) {
+ if (p_av->status != BTA_AV_SUCCESS) {
+ if (p_av->initiator) {
+ btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
+ }
+ return;
+ }
+ }
+
+ /* stop tx, ack to cmd, flush tx queue */
+ btc_a2dp_source_tx_stop();
+}
+
+void btc_a2dp_source_on_idle(void)
+{
+ /* stop tx, ack to cmd, flush tx queue */
+ btc_a2dp_source_tx_stop();
+}
+
+bool btc_a2dp_source_is_task_shutting_down(void)
+{
+ /* always return false, remove this api when internal codec is remove */
+ return false;
+}
+
+bool btc_a2dp_source_startup(void)
+{
+ if (btc_a2dp_source_state != BTC_A2DP_SOURCE_STATE_OFF) {
+ APPL_TRACE_ERROR("%s A2DP source already start up", __func__);
+ return false;
+ }
+
+#if A2D_DYNAMIC_MEMORY == TRUE
+ if ((a2dp_source_local_param_ptr = (a2dp_source_local_param_t *)osi_malloc(sizeof(a2dp_source_local_param_t))) == NULL) {
+ APPL_TRACE_ERROR("%s malloc failed!", __func__);
+ return false;
+ }
+ memset((void *)a2dp_source_local_param_ptr, 0, sizeof(a2dp_source_local_param_t));
+#endif
+
+ btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_ON;
+
+ a2dp_source_local_param.audio_tx_q = fixed_queue_new(QUEUE_SIZE_MAX);
+ if(a2dp_source_local_param.audio_tx_q == NULL) {
+ goto error_exit;
+ }
+
+ btc_a2dp_control_init();
+
+ return true;
+
+error_exit:;
+ APPL_TRACE_ERROR("%s A2DP source start up failed", __func__);
+
+#if A2D_DYNAMIC_MEMORY == TRUE
+ osi_free(a2dp_source_local_param_ptr);
+ a2dp_source_local_param_ptr = NULL;
+#endif
+
+ return false;
+}
+
+void btc_a2dp_source_shutdown(void)
+{
+ if (btc_a2dp_source_state != BTC_A2DP_SOURCE_STATE_ON) {
+ APPL_TRACE_ERROR("%s A2DP source already shutdown", __func__);
+ return;
+ }
+ btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF;
+
+ btc_a2dp_control_cleanup();
+
+ fixed_queue_free(a2dp_source_local_param.audio_tx_q, osi_free_func);
+
+ a2dp_source_local_param.audio_tx_q = NULL;
+ a2dp_source_local_param.tx_flush = FALSE;
+ a2dp_source_local_param.stream_started = FALSE;
+
+#if A2D_DYNAMIC_MEMORY == TRUE
+ osi_free(a2dp_source_local_param_ptr);
+ a2dp_source_local_param_ptr = NULL;
+#endif
+}
+
+#endif /* (BTC_AV_SRC_INCLUDED == TRUE) && (BTC_AV_EXT_CODEC == TRUE) */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c
index 4c237b1e..f13d1255 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -22,6 +22,7 @@
#include "btc/btc_common.h"
#include "btc/btc_manage.h"
#include "btc_av.h"
+#include "btc_av_co.h"
#include "btc_avrc.h"
#include "btc/btc_util.h"
#include "btc/btc_profile_queue.h"
@@ -34,7 +35,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;
@@ -46,6 +47,9 @@ bool g_a2dp_source_ongoing_deinit;
bool g_a2dp_sink_ongoing_deinit;
+/* reserve some bytes for media payload header (currently, only SBC, 1 byte) */
+#define BTC_AV_AUDIO_MTU_RESERVE 1
+
/*****************************************************************************
** Constants & Macros
******************************************************************************/
@@ -74,6 +78,9 @@ typedef enum {
#define BTC_AV_FLAG_PENDING_START 0x4
#define BTC_AV_FLAG_PENDING_STOP 0x8
+#define BTC_AV_SBC_CIE_OFFSET 3
+#define BTC_AV_SBC_CIE_LEN 4
+
/*****************************************************************************
** Local type definitions
******************************************************************************/
@@ -81,11 +88,13 @@ typedef enum {
typedef struct {
int service_id;
tBTA_AV_HNDL bta_handle;
+ UINT16 mtu;
bt_bdaddr_t peer_bda;
btc_sm_handle_t sm_handle;
UINT8 flags;
tBTA_AV_EDR edr;
UINT8 peer_sep; /* sep type of peer device */
+ tBTC_AV_CODEC_INFO codec_caps;
#if BTC_AV_SRC_INCLUDED
osi_alarm_t *tle_av_open_on_rc;
#endif /* BTC_AV_SRC_INCLUDED */
@@ -127,6 +136,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; \
@@ -168,6 +179,7 @@ static void btc_av_event_free_data(btc_msg_t *msg);
extern tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
extern tBTA_AVRC_CO_FUNCTS bta_avrc_cos;
+extern tA2D_SBC_CIE btc_av_sbc_default_config;
/*****************************************************************************
** Local helper functions
******************************************************************************/
@@ -220,7 +232,7 @@ UNUSED_ATTR static const char *dump_av_sm_event_name(btc_av_sm_event_t event)
CASE_RETURN_STR(BTC_AV_DISCONNECT_REQ_EVT)
CASE_RETURN_STR(BTC_AV_START_STREAM_REQ_EVT)
CASE_RETURN_STR(BTC_AV_SUSPEND_STREAM_REQ_EVT)
- CASE_RETURN_STR(BTC_AV_SINK_CONFIG_REQ_EVT)
+ CASE_RETURN_STR(BTC_AV_CONFIG_EVT)
default: return "UNKNOWN_EVENT";
}
}
@@ -261,7 +273,7 @@ static void btc_initiate_av_open_tmr_hdlr(void *arg)
/*****************************************************************************
** Static functions
******************************************************************************/
-static void btc_report_connection_state(esp_a2d_connection_state_t state, bt_bdaddr_t *bd_addr, int disc_rsn)
+static void btc_report_connection_state(esp_a2d_connection_state_t state, bt_bdaddr_t *bd_addr, uint16_t mtu, int disc_rsn)
{
// todo: add callback for SRC
esp_a2d_cb_param_t param;
@@ -270,8 +282,15 @@ static void btc_report_connection_state(esp_a2d_connection_state_t state, bt_bda
param.conn_stat.state = state;
if (bd_addr) {
memcpy(param.conn_stat.remote_bda, bd_addr, sizeof(esp_bd_addr_t));
+ if (memcmp(bd_addr, &(btc_av_cb.peer_bda), sizeof(bt_bdaddr_t)) == 0) {
+ param.conn_stat.conn_hdl = btc_av_cb.bta_handle;
+ }
+ }
+ if (state == ESP_A2D_CONNECTION_STATE_CONNECTED) {
+ param.conn_stat.audio_mtu = mtu;
+ btc_av_cb.mtu = mtu;
}
- if (state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
+ else if (state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
param.conn_stat.disc_rsn = (disc_rsn == 0) ? ESP_A2D_DISC_RSN_NORMAL :
ESP_A2D_DISC_RSN_ABNORMAL;
}
@@ -287,6 +306,9 @@ static void btc_report_audio_state(esp_a2d_audio_state_t state, bt_bdaddr_t *bd_
param.audio_stat.state = state;
if (bd_addr) {
memcpy(param.audio_stat.remote_bda, bd_addr, sizeof(esp_bd_addr_t));
+ if (memcmp(bd_addr, &(btc_av_cb.peer_bda), sizeof(bt_bdaddr_t)) == 0) {
+ param.audio_stat.conn_hdl = btc_av_cb.bta_handle;
+ }
}
btc_a2d_cb_to_app(ESP_A2D_AUDIO_STATE_EVT, &param);
}
@@ -326,6 +348,12 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data)
case BTA_AV_REGISTER_EVT:
btc_av_cb.bta_handle = ((tBTA_AV *)p_data)->registr.hndl;
break;
+ case BTA_AV_SEP_REG_EVT:
+ param.a2d_sep_reg_stat.seid = ((tBTA_AV *)p_data)->sep_reg.seid;
+ param.a2d_sep_reg_stat.reg_state = (((tBTA_AV *)p_data)->sep_reg.reg_state == BTA_AV_SUCCESS) ? ESP_A2D_SEP_REG_SUCCESS :
+ ESP_A2D_SEP_REG_FAIL;
+ btc_a2d_cb_to_app(ESP_A2D_SEP_REG_STATE_EVT, &param);
+ break;
case BTA_AV_PENDING_EVT:
case BTC_AV_CONNECT_REQ_EVT: {
@@ -356,7 +384,7 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data)
case BTC_AV_DISCONNECT_REQ_EVT:
BTC_TRACE_WARNING("No Link At All.");
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &((btc_av_disconn_req_t *)p_data)->target_bda, 0);
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &((btc_av_disconn_req_t *)p_data)->target_bda, 0, 0);
break;
case BTA_AV_RC_OPEN_EVT:
@@ -382,6 +410,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;
@@ -444,7 +474,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
switch (event) {
case BTC_SM_ENTER_EVT:
/* inform the application that we are entering connecting state */
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_CONNECTING, &(btc_av_cb.peer_bda), 0);
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_CONNECTING, &(btc_av_cb.peer_bda), 0, 0);
break;
case BTC_SM_EXIT_EVT:
@@ -452,7 +482,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
case BTA_AV_REJECT_EVT:
BTC_TRACE_WARNING(" Received BTA_AV_REJECT_EVT \n");
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0);
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0, 0);
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
break;
@@ -460,13 +490,14 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
tBTA_AV *p_bta_data = (tBTA_AV *)p_data;
esp_a2d_connection_state_t conn_stat;
btc_sm_state_t av_state;
+ uint16_t mtu = 0;
BTC_TRACE_DEBUG("status:%d, edr 0x%x, peer sep %d\n", p_bta_data->open.status,
p_bta_data->open.edr, p_bta_data->open.sep);
if (p_bta_data->open.status == BTA_AV_SUCCESS) {
btc_av_cb.edr = p_bta_data->open.edr;
btc_av_cb.peer_sep = p_bta_data->open.sep;
-
+ mtu = p_bta_data->open.mtu - BTC_AV_AUDIO_MTU_RESERVE;
conn_stat = ESP_A2D_CONNECTION_STATE_CONNECTED;
av_state = BTC_AV_STATE_OPENED;
} else {
@@ -476,7 +507,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
av_state = BTC_AV_STATE_IDLE;
}
/* inform the application of the event */
- btc_report_connection_state(conn_stat, &(btc_av_cb.peer_bda), 0);
+ btc_report_connection_state(conn_stat, &(btc_av_cb.peer_bda), mtu, 0);
/* change state to open/idle based on the status */
btc_sm_change_state(btc_av_cb.sm_handle, av_state);
@@ -498,13 +529,12 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
btc_queue_advance();
} break;
- case BTC_AV_SINK_CONFIG_REQ_EVT: {
- if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
- esp_a2d_cb_param_t param;
- memcpy(param.audio_cfg.remote_bda, &btc_av_cb.peer_bda, sizeof(esp_bd_addr_t));
- memcpy(&param.audio_cfg.mcc, p_data, sizeof(esp_a2d_mcc_t));
- btc_a2d_cb_to_app(ESP_A2D_AUDIO_CFG_EVT, &param);
- }
+ case BTC_AV_CONFIG_EVT: {
+ esp_a2d_cb_param_t param;
+ param.audio_cfg.conn_hdl = btc_av_cb.bta_handle;
+ memcpy(param.audio_cfg.remote_bda, &btc_av_cb.peer_bda, sizeof(esp_bd_addr_t));
+ memcpy(&param.audio_cfg.mcc, p_data, sizeof(esp_a2d_mcc_t));
+ btc_a2d_cb_to_app(ESP_A2D_AUDIO_CFG_EVT, &param);
} break;
case BTC_AV_CONNECT_REQ_EVT:
@@ -516,7 +546,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
break;
} else {
BTC_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request\n", __func__);
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t *)p_data, 0);
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t *)p_data, 0, 0);
btc_queue_advance();
break;
}
@@ -619,7 +649,7 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data)
case BTA_AV_CLOSE_EVT: {
tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
/* inform the application that we are disconnecting */
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn);
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0, close->disc_rsn);
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
break;
}
@@ -689,7 +719,9 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
case BTC_AV_START_STREAM_REQ_EVT:
#if BTC_AV_SRC_INCLUDED
if (btc_av_cb.peer_sep != AVDT_TSEP_SRC) {
+#if (BTC_AV_EXT_CODEC == FALSE)
btc_a2dp_source_setup_codec();
+#endif
}
#endif /* BTC_AV_SRC_INCLUDED */
BTA_AvStart();
@@ -755,7 +787,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
}
/* inform the application that we are disconnecting */
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0);
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0, 0);
break;
case BTA_AV_CLOSE_EVT: {
@@ -763,7 +795,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
btc_a2dp_on_stopped(NULL);
tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
/* inform the application that we are disconnected */
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda),
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0,
close->disc_rsn);
if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) {
@@ -800,7 +832,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
} else {
BTC_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req\n", __func__);
btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED,
- (bt_bdaddr_t *)p_data, ESP_A2D_DISC_RSN_NORMAL);
+ (bt_bdaddr_t *)p_data, 0, ESP_A2D_DISC_RSN_NORMAL);
}
btc_queue_advance();
break;
@@ -913,7 +945,7 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
}
/* inform the application that we are disconnecting */
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0);
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0, 0);
/* wait in closing state until fully closed */
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_CLOSING);
@@ -978,7 +1010,7 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
btc_a2dp_on_stopped(NULL);
tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
/* inform the application that we are disconnected */
- btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda),
+ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0,
close->disc_rsn);
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
@@ -1333,7 +1365,7 @@ static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
}
#if BTC_AV_SINK_INCLUDED
-static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
+static void bte_av_media_sink_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
{
btc_sm_state_t state;
UINT8 que_len;
@@ -1347,15 +1379,18 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
que_len = btc_a2dp_sink_enque_buf((BT_HDR *)p_data);
BTC_TRACE_DEBUG(" Packets in Que %d\n", que_len);
} else {
+ osi_free(p_data);
return;
}
}
- if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
+ if (event == BTA_AV_MEDIA_CFG_EVT) {
+#if (BTC_AV_EXT_CODEC == FALSE)
/* send a command to BT Media Task */
btc_a2dp_sink_reset_decoder((UINT8 *)p_data);
+#endif
- /* 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;
@@ -1363,11 +1398,11 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_A2DP;
- msg.act = BTC_AV_SINK_CONFIG_REQ_EVT;
+ msg.act = BTC_AV_CONFIG_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
arg.mcc.type = ESP_A2D_MCT_SBC;
- memcpy(arg.mcc.cie.sbc, (uint8_t *)p_data + 3, ESP_A2D_CIE_LEN_SBC);
+ memcpy(&arg.mcc.cie.sbc_info, (uint8_t *)p_data + BTC_AV_SBC_CIE_OFFSET, BTC_AV_SBC_CIE_LEN);
btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
} else {
BTC_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
@@ -1376,7 +1411,42 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
UNUSED(que_len);
}
#else
-static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
+static void bte_av_media_sink_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
+{
+ UNUSED(event);
+ UNUSED(p_data);
+ BTC_TRACE_WARNING("%s : event %u\n", __func__, event);
+}
+#endif
+
+#if BTC_AV_SRC_INCLUDED
+static void bte_av_media_source_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
+{
+ tA2D_STATUS a2d_status;
+ tA2D_SBC_CIE sbc_cie;
+
+ if (event == BTA_AV_MEDIA_CFG_EVT) {
+ /* currently only supports SBC */
+ a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
+ if (a2d_status == A2D_SUCCESS) {
+ btc_msg_t msg;
+ btc_av_args_t arg;
+
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_A2DP;
+ msg.act = BTC_AV_CONFIG_EVT;
+
+ memset(&arg, 0, sizeof(btc_av_args_t));
+ arg.mcc.type = ESP_A2D_MCT_SBC;
+ memcpy(&arg.mcc.cie.sbc_info, (uint8_t *)p_data + BTC_AV_SBC_CIE_OFFSET, BTC_AV_SBC_CIE_LEN);
+ btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
+ } else {
+ BTC_TRACE_ERROR("A2D_ParsSbcInfo fail:%d\n", a2d_status);
+ }
+ }
+}
+#else
+static void bte_av_media_source_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
{
UNUSED(event);
UNUSED(p_data);
@@ -1384,6 +1454,47 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
}
#endif
+#if (BTC_AV_EXT_CODEC == TRUE)
+
+tBTC_AV_CODEC_INFO *btc_av_codec_cap_get(void)
+{
+ return &btc_av_cb.codec_caps;
+}
+
+static void btc_av_reg_sep(uint8_t tsep, uint8_t seid, esp_a2d_mcc_t *mcc)
+{
+ tBTA_AV_DATA_CBACK *p_data_cback = NULL;
+ esp_a2d_cb_param_t param;
+
+ param.a2d_sep_reg_stat.seid = seid;
+ if (btc_av_cb.sm_handle == NULL || btc_sm_get_state(btc_av_cb.sm_handle) != BTC_AV_STATE_IDLE) {
+ param.a2d_sep_reg_stat.reg_state = ESP_A2D_SEP_REG_INVALID_STATE;
+ btc_a2d_cb_to_app(ESP_A2D_SEP_REG_STATE_EVT, &param);
+ BTC_TRACE_WARNING("%s: try to reg sep when a2dp not init or connected", __func__);
+ }
+
+ if (mcc->type == ESP_A2D_MCT_SBC) {
+ A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, (tA2D_SBC_CIE *)&btc_av_sbc_default_config, btc_av_cb.codec_caps.info);
+ /* overwrite sbc cie */
+ memcpy(btc_av_cb.codec_caps.info + A2D_SBC_CIE_OFF, &mcc->cie, A2D_SBC_CIE_LEN);
+
+ if (tsep == AVDT_TSEP_SNK) {
+ p_data_cback = bte_av_media_sink_callback;
+ }
+ else {
+ p_data_cback = bte_av_media_source_callback;
+ }
+ BTA_AvRegSEP(BTA_AV_CHNL_AUDIO, seid, tsep, BTA_AV_CODEC_SBC, btc_av_cb.codec_caps.info, p_data_cback);
+ }
+ else {
+ param.a2d_sep_reg_stat.reg_state = ESP_A2D_SEP_REG_UNSUPPORTED;
+ btc_a2d_cb_to_app(ESP_A2D_SEP_REG_STATE_EVT, &param);
+ BTC_TRACE_WARNING("%s: unsupported codec type %d", __func__, mcc->type);
+ }
+}
+
+#endif
+
/*******************************************************************************
**
** Function btc_av_execute_service
@@ -1395,7 +1506,15 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
*******************************************************************************/
bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep)
{
+ tBTA_AV_DATA_CBACK *p_data_cback = NULL;
+
if (b_enable) {
+ if (tsep == AVDT_TSEP_SNK) {
+ p_data_cback = bte_av_media_sink_callback;
+ }
+ else {
+ p_data_cback = bte_av_media_source_callback;
+ }
/* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
* handle this request in order to allow incoming connections to succeed.
* We need to put this back once support for this is added */
@@ -1409,11 +1528,11 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep)
BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_DELAY_RPT,
bte_av_callback);
- BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, &bta_avrc_cos, tsep);
+ BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, p_data_cback, &bta_av_a2d_cos, &bta_avrc_cos, tsep);
} else {
BTC_TRACE_WARNING("A2DP Enable without AVRC")
BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_DELAY_RPT, bte_av_callback);
- BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, NULL, tsep);
+ BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, p_data_cback, &bta_av_a2d_cos, NULL, tsep);
}
} else {
BTA_AvDeregister(btc_av_cb.bta_handle);
@@ -1472,6 +1591,11 @@ BOOLEAN btc_av_is_connected(void)
return ((state == BTC_AV_STATE_OPENED) || (state == BTC_AV_STATE_STARTED));
}
+BOOLEAN btc_av_is_started(void)
+{
+ return ((btc_sm_get_state(btc_av_cb.sm_handle) == BTC_AV_STATE_STARTED));
+}
+
/*******************************************************************************
*
* Function btc_av_get_service_id
@@ -1544,15 +1668,17 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
btc_av_args_t *arg = (btc_av_args_t *)(msg->arg);
switch (msg->act) {
#if BTC_AV_SINK_INCLUDED
- case BTC_AV_SINK_CONFIG_REQ_EVT: {
- btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (void *)(msg->arg));
- break;
- }
case BTC_AV_SINK_API_INIT_EVT: {
btc_a2d_sink_init();
// todo: callback to application
break;
}
+#if (BTC_AV_EXT_CODEC == TRUE)
+ case BTC_AV_SINK_API_REG_SEP_EVT: {
+ btc_av_reg_sep(AVDT_TSEP_SNK, arg->reg_sep.seid, &arg->reg_sep.mcc);
+ break;
+ }
+#endif
case BTC_AV_SINK_API_DEINIT_EVT: {
btc_a2d_sink_deinit();
// todo: callback to application
@@ -1570,10 +1696,17 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, &disconn_req);
break;
}
+#if (BTC_AV_EXT_CODEC == TRUE)
+ case BTC_AV_SINK_API_REG_AUDIO_DATA_CB_EVT: {
+ btc_a2dp_sink_reg_audio_data_cb(arg->audio_data_cb);
+ break;
+ }
+#else
case BTC_AV_SINK_API_REG_DATA_CB_EVT: {
btc_a2dp_sink_reg_data_cb(arg->data_cb);
break;
}
+#endif
case BTC_AV_SINK_API_SET_DELAY_VALUE_EVT: {
btc_a2d_sink_set_delay_value(arg->delay_value);
break;
@@ -1588,6 +1721,12 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
btc_a2d_src_init();
break;
}
+#if (BTC_AV_EXT_CODEC == TRUE)
+ case BTC_AV_SRC_API_REG_SEP_EVT: {
+ btc_av_reg_sep(AVDT_TSEP_SRC, arg->reg_sep.seid, &arg->reg_sep.mcc);
+ break;
+ }
+#endif
case BTC_AV_SRC_API_DEINIT_EVT: {
btc_a2d_src_deinit();
break;
@@ -1603,10 +1742,12 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, &disconn_req);
break;
}
+#if (BTC_AV_EXT_CODEC == FALSE)
case BTC_AV_SRC_API_REG_DATA_CB_EVT: {
btc_a2dp_src_reg_data_cb(arg->src_data_cb);
break;
}
+#endif
#endif /* BTC_AV_SRC_INCLUDED */
case BTC_AV_API_MEDIA_CTRL_EVT: {
btc_a2dp_control_media_ctrl(arg->ctrl);
@@ -1632,6 +1773,35 @@ void btc_a2dp_cb_handler(btc_msg_t *msg)
btc_av_event_free_data(msg);
}
+void btc_a2dp_get_profile_status(esp_a2d_profile_status_t *param)
+{
+ // Not initialized by default
+ param->a2d_snk_inited = false;
+ param->a2d_src_inited = false;
+
+#if A2D_DYNAMIC_MEMORY == TRUE
+ if (btc_av_cb_ptr)
+#endif
+ {
+ if (btc_av_cb.sm_handle) {
+ if (btc_av_cb.service_id == BTA_A2DP_SINK_SERVICE_ID) {
+ param->a2d_src_inited = false;
+ param->a2d_snk_inited = true;
+ } else if (btc_av_cb.service_id == BTA_A2DP_SOURCE_SERVICE_ID) {
+ param->a2d_src_inited = true;
+ param->a2d_snk_inited = false;
+ } else {
+ param->a2d_snk_inited = false;
+ param->a2d_src_inited = false;
+ return;
+ }
+ if (btc_av_is_connected()) {
+ param->conn_num++;
+ }
+ }
+ }
+}
+
#if BTC_AV_SINK_INCLUDED
/*******************************************************************************
@@ -1730,6 +1900,56 @@ static bt_status_t btc_a2d_src_connect(bt_bdaddr_t *remote_bda)
return btc_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, remote_bda, connect_int);
}
+BOOLEAN btc_a2d_src_audio_mtu_check(uint16_t data_len)
+{
+
+ return (data_len <= btc_av_cb.mtu);
+}
+
+bt_status_t btc_a2d_src_audio_data_send(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf)
+{
+#if (BTC_AV_EXT_CODEC == TRUE)
+ if (conn_hdl != btc_av_cb.bta_handle) {
+ return BT_STATUS_FAIL;
+ }
+ BT_HDR *p_buf = (BT_HDR *)audio_buf;
+ assert(audio_buf->data - (UINT8 *)(p_buf + 1) >= BTC_AUDIO_BUFF_OFFSET);
+ /* since p_buf and audio_buf point to the same memory, backup those value before modify p_buf */
+ uint16_t number_frame = audio_buf->number_frame;
+ uint16_t data_len = audio_buf->data_len;
+ uint32_t timestamp = audio_buf->timestamp;
+ p_buf->offset = audio_buf->data - (UINT8 *)(p_buf + 1);
+ p_buf->layer_specific = number_frame;
+ p_buf->len = data_len;
+ *((UINT32 *) (p_buf + 1)) = timestamp;
+
+ if (btc_a2dp_source_enqueue_audio_frame(p_buf)) {
+ return BT_STATUS_SUCCESS;
+ }
+#endif
+ return BT_STATUS_FAIL;
+}
+
#endif /* BTC_AV_SRC_INCLUDED */
+uint16_t btc_a2d_conn_handle_get(void)
+{
+ return btc_av_cb.bta_handle;
+}
+
+void btc_av_audio_buff_alloc(uint16_t size, uint8_t **pp_buff, uint8_t **pp_data)
+{
+ /* todo */
+ BT_HDR *p_buf= (BT_HDR *)osi_calloc(sizeof(BT_HDR) + BTC_AUDIO_BUFF_OFFSET + size);
+ if (p_buf != NULL) {
+ *pp_buff = (uint8_t *)p_buf;
+ *pp_data = (uint8_t *)(p_buf + 1) + BTC_AUDIO_BUFF_OFFSET;
+ }
+}
+
+void btc_av_audio_buff_free(uint8_t *p_buf)
+{
+ osi_free(p_buf);
+}
+
#endif /* #if BTC_AV_INCLUDED */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h b/lib/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h
index 34d7a729..9a4f6280 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -64,6 +64,7 @@ typedef struct {
typedef struct {
/* Connected peer information */
tBTA_AV_CO_PEER peers[BTA_AV_NUM_STRS];
+ tBTC_AV_CODEC_INFO codec_caps;
/* Current codec configuration - access to this variable must be protected */
tBTC_AV_CODEC_INFO codec_cfg;
tBTC_AV_CODEC_INFO codec_cfg_setconfig; /* remote peer setconfig preference */
@@ -189,8 +190,7 @@ void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl);
** Returns Nothing
**
*******************************************************************************/
-void bta_av_co_init(void);
-
+void bta_av_co_init(tBTC_AV_CODEC_INFO *codec_caps);
/*******************************************************************************
**
@@ -211,7 +211,7 @@ BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl);
** of our exported bitpool range. If set we will set the
** remote preference.
**
- ** Returns TRUE if config set, FALSE otherwize
+ ** Returns TRUE if config set, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max);
diff --git a/lib/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c b/lib/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c
index 7e7f1b2b..3ed8a02a 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 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);
@@ -170,8 +175,7 @@ bool btc_avrc_ct_init_p(void)
bool btc_avrc_tg_connected_p(void)
{
return (s_rc_tg_init == BTC_RC_TG_INIT_MAGIC) &&
- (btc_rc_cb.rc_connected == TRUE) &&
- (btc_rc_cb.rc_features & BTA_AV_FEAT_RCCT);
+ (btc_rc_cb.rc_connected == TRUE);
}
bool btc_avrc_ct_connected_p(void)
@@ -181,6 +185,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;
@@ -253,10 +303,6 @@ static bool btc_avrc_tg_set_rn_supported_evt(uint16_t evt_set)
static inline void btc_avrc_ct_cb_to_app(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
{
- if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
- return;
- }
-
esp_avrc_ct_cb_t btc_avrc_ct_cb = (esp_avrc_ct_cb_t)btc_profile_cb_get(BTC_PID_AVRC_CT);
if (btc_avrc_ct_cb) {
btc_avrc_ct_cb(event, param);
@@ -265,10 +311,6 @@ static inline void btc_avrc_ct_cb_to_app(esp_avrc_ct_cb_event_t event, esp_avrc_
static inline void btc_avrc_tg_cb_to_app(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param)
{
- if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
- return;
- }
-
esp_avrc_tg_cb_t btc_avrc_tg_cb = (esp_avrc_tg_cb_t)btc_profile_cb_get(BTC_PID_AVRC_TG);
if (btc_avrc_tg_cb) {
btc_avrc_tg_cb(event, param);
@@ -456,7 +498,7 @@ static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
}
- if (p_rc_open->peer_features & BTA_AV_FEAT_RCCT) {
+ if (btc_avrc_tg_init_p()) {
esp_avrc_tg_cb_param_t param;
memset(&param, 0, sizeof(esp_avrc_tg_cb_param_t));
param.conn_stat.connected = true;
@@ -499,14 +541,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));
@@ -515,7 +571,7 @@ static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
}
- if (rc_features & BTA_AV_FEAT_RCCT) {
+ if (btc_avrc_tg_init_p()) {
esp_avrc_tg_cb_param_t param;
memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
param.conn_stat.connected = false;
@@ -636,6 +692,18 @@ static void handle_rc_set_absolute_volume_rsp(tAVRC_SET_VOLUME_RSP *rsp)
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT, &param);
}
+static void handle_rc_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP *rsp)
+{
+ esp_avrc_ct_cb_param_t param;
+ memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
+
+ param.play_status_rsp.song_length = rsp->song_len;
+ param.play_status_rsp.song_position = rsp->song_pos;
+ param.play_status_rsp.play_status = rsp->play_status;
+
+ btc_avrc_ct_cb_to_app(ESP_AVRC_CT_PLAY_STATUS_RSP_EVT, &param);
+}
+
/***************************************************************************
* Function handle_rc_metamsg_cmd
*
@@ -751,7 +819,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
@@ -834,6 +902,9 @@ static void handle_rc_metamsg_rsp (tBTA_AV_META_MSG *p_meta_msg)
handle_rc_set_absolute_volume_rsp(&avrc_response.volume);
}
break;
+ case AVRC_PDU_GET_PLAY_STATUS:
+ handle_rc_get_play_status_rsp(&avrc_response.get_play_status);
+ break;
default:
BTC_TRACE_WARNING("%s: unhandled meta rsp: pdu 0x%x", __FUNCTION__, avrc_response.rsp.pdu);
}
@@ -941,14 +1012,10 @@ void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
memcpy(param.conn_stat.remote_bda, btc_rc_cb.rc_addr, sizeof(esp_bd_addr_t));
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
}
- if ((p_data->rc_feat.peer_features & BTA_AV_FEAT_RCCT) &&
- !(old_feats & BTA_AV_FEAT_RCCT)) {
- esp_avrc_tg_cb_param_t param;
- 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);
- }
+ /**
+ * @note ESP_AVRC_TG_CONNECTION_STATE_EVT has been reported on rc connect/disconnect event,
+ * it doesn't rely on the SDP results.
+ */
} while (0);
btc_rc_cb.rc_features = p_data->rc_feat.peer_features;
btc_rc_cb.rc_ct_features = p_data->rc_feat.peer_ct_features;
@@ -967,6 +1034,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);
}
@@ -1003,27 +1100,39 @@ BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr)
*******************************************************************************/
static void btc_avrc_ct_init(void)
{
- BTC_TRACE_DEBUG("## %s ##", __FUNCTION__);
- if (s_rc_ct_init == BTC_RC_CT_INIT_MAGIC) {
- BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
- return;
- }
+ esp_avrc_init_state_t state = ESP_AVRC_INIT_SUCCESS;
- /// initialize CT-specific resources
- s_rc_ct_init = BTC_RC_CT_INIT_MAGIC;
+ BTC_TRACE_DEBUG("## %s ##", __FUNCTION__);
- /// initialize CT-TG shared resources
- if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
- memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
+ do {
- if (!g_av_with_rc) {
- g_av_with_rc = true;
+ if (s_rc_ct_init == BTC_RC_CT_INIT_MAGIC) {
+ BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
+ state = ESP_AVRC_INIT_ALREADY;
+ break;
}
- if (g_a2dp_on_init) {
- BTC_TRACE_WARNING("AVRC Controller is expected to be initialized in advance of A2DP !!!");
+ /// initialize CT-TG shared resources
+ if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
+ if (g_a2dp_on_init) {
+ BTC_TRACE_WARNING("AVRC Controller is expected to be initialized in advance of A2DP !!!");
+ state = ESP_AVRC_INIT_FAIL;
+ break;
+ }
+ memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
+
+ if (!g_av_with_rc) {
+ g_av_with_rc = true;
+ }
}
- }
+
+ /// initialize CT-specific resources
+ s_rc_ct_init = BTC_RC_CT_INIT_MAGIC;
+ } while (0);
+
+ esp_avrc_ct_cb_param_t param = {0};
+ param.avrc_ct_init_stat.state = state;
+ btc_avrc_ct_cb_to_app(ESP_AVRC_CT_PROF_STATE_EVT, &param);
}
@@ -1038,29 +1147,37 @@ static void btc_avrc_ct_init(void)
***************************************************************************/
static void btc_avrc_ct_deinit(void)
{
+ esp_avrc_init_state_t state = ESP_AVRC_DEINIT_SUCCESS;
+
BTC_TRACE_API("## %s ##", __FUNCTION__);
- if (g_a2dp_on_deinit) {
- BTC_TRACE_WARNING("A2DP already deinit, AVRC CT shuold deinit in advance of A2DP !!!");
- }
+ do {
+ if (g_a2dp_on_deinit) {
+ BTC_TRACE_WARNING("A2DP already deinit, AVRC CT should deinit in advance of A2DP !!!");
+ }
- if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
- BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
- return;
- }
+ if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
+ BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
+ state = ESP_AVRC_DEINIT_ALREADY;
+ break;
+ }
- /// deinit CT-specific resources
- s_rc_ct_init = 0;
+ /// deinit CT-specific resources
+ s_rc_ct_init = 0;
- /// deinit CT-TG shared resources
- if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
- memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
- if (g_av_with_rc) {
- g_av_with_rc = false;
+ /// deinit CT-TG shared resources
+ if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
+ memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
+ if (g_av_with_rc) {
+ g_av_with_rc = false;
+ }
}
- }
+ BTC_TRACE_API("## %s ## completed", __FUNCTION__);
+ } while (0);
- BTC_TRACE_API("## %s ## completed", __FUNCTION__);
+ esp_avrc_ct_cb_param_t param = {0};
+ param.avrc_ct_init_stat.state = state;
+ btc_avrc_ct_cb_to_app(ESP_AVRC_CT_PROF_STATE_EVT, &param);
}
static bt_status_t btc_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id)
@@ -1243,6 +1360,38 @@ static bt_status_t btc_avrc_ct_send_metadata_cmd (uint8_t tl, uint8_t attr_mask)
return status;
}
+static bt_status_t btc_avrc_ct_send_get_play_status_cmd(uint8_t tl)
+{
+ tAVRC_STS status = BT_STATUS_UNSUPPORTED;
+
+#if (AVRC_METADATA_INCLUDED == TRUE)
+ CHECK_ESP_RC_CONNECTED;
+
+ tAVRC_COMMAND avrc_cmd = {0};
+ BT_HDR *p_msg = NULL;
+
+ avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
+ avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
+ avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
+
+ if (btc_rc_cb.rc_features & BTA_AV_FEAT_METADATA) {
+ status = AVRC_BldCommand(&avrc_cmd, &p_msg);
+ if (status == AVRC_STS_NO_ERROR) {
+ BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, AVRC_CMD_STATUS, p_msg);
+ status = BT_STATUS_SUCCESS;
+ }
+ } else {
+ status = BT_STATUS_FAIL;
+ BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
+ }
+
+#else
+ BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
+#endif
+
+ return status;
+}
+
static bt_status_t btc_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
{
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
@@ -1255,7 +1404,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 +1416,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 */
/*******************************************************************************
**
@@ -1279,30 +1486,42 @@ static bt_status_t btc_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code
*******************************************************************************/
static void btc_avrc_tg_init(void)
{
+ esp_avrc_init_state_t state = ESP_AVRC_INIT_SUCCESS;
+
BTC_TRACE_DEBUG("## %s ##", __FUNCTION__);
- if (s_rc_tg_init == BTC_RC_TG_INIT_MAGIC) {
- BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
- return;
- }
- /// initialize TG-specific resources
- memcpy(s_psth_supported_cmd, cs_psth_dft_supported_cmd, sizeof(s_psth_supported_cmd));
- s_rn_supported_evt = cs_rn_dft_supported_evt;
+ do {
+ if (s_rc_tg_init == BTC_RC_TG_INIT_MAGIC) {
+ BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
+ state = ESP_AVRC_INIT_ALREADY;
+ break;
+ }
- /// initialize CT-TG shared resources
- if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
- memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
+ /// initialize CT-TG shared resources
+ if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
+ if (g_a2dp_on_init) {
+ BTC_TRACE_WARNING("AVRC Target is expected to be initialized in advance of A2DP !!!");
+ state = ESP_AVRC_INIT_FAIL;
+ break;
+ }
- if (!g_av_with_rc) {
- g_av_with_rc = true;
- }
+ memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
- if (g_a2dp_on_init) {
- BTC_TRACE_WARNING("AVRC Taget is expected to be initialized in advance of A2DP !!!");
+ if (!g_av_with_rc) {
+ g_av_with_rc = true;
+ }
}
- }
- s_rc_tg_init = BTC_RC_TG_INIT_MAGIC;
+ /// initialize TG-specific resources
+ memcpy(s_psth_supported_cmd, cs_psth_dft_supported_cmd, sizeof(s_psth_supported_cmd));
+ s_rn_supported_evt = cs_rn_dft_supported_evt;
+
+ s_rc_tg_init = BTC_RC_TG_INIT_MAGIC;
+ } while (0);
+
+ esp_avrc_tg_cb_param_t param = {0};
+ param.avrc_tg_init_stat.state = state;
+ btc_avrc_tg_cb_to_app(ESP_AVRC_TG_PROF_STATE_EVT, &param);
}
@@ -1317,31 +1536,40 @@ static void btc_avrc_tg_init(void)
***************************************************************************/
static void btc_avrc_tg_deinit(void)
{
+ esp_avrc_init_state_t state = ESP_AVRC_DEINIT_SUCCESS;
+
BTC_TRACE_API("## %s ##", __FUNCTION__);
- if (g_a2dp_on_deinit) {
- BTC_TRACE_WARNING("A2DP already deinit, AVRC TG shuold deinit in advance of A2DP !!!");
- }
+ do {
+ if (g_a2dp_on_deinit) {
+ BTC_TRACE_WARNING("A2DP already deinit, AVRC TG should deinit in advance of A2DP !!!");
+ }
- if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
- BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
- return;
- }
+ if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
+ BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
+ state = ESP_AVRC_DEINIT_ALREADY;
+ break;
+ }
- /// deinit TG-specific resources
- memset(s_psth_supported_cmd, 0, sizeof(s_psth_supported_cmd));
- s_rn_supported_evt = 0;
- s_rc_tg_init = 0;
+ /// deinit TG-specific resources
+ memset(s_psth_supported_cmd, 0, sizeof(s_psth_supported_cmd));
+ s_rn_supported_evt = 0;
+ s_rc_tg_init = 0;
- /// deinit CT-TG shared resources
- if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
- memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
- if (g_av_with_rc) {
- g_av_with_rc = false;
+ /// deinit CT-TG shared resources
+ if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
+ memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
+ if (g_av_with_rc) {
+ g_av_with_rc = false;
+ }
}
- }
- BTC_TRACE_API("## %s ## completed", __FUNCTION__);
+ BTC_TRACE_API("## %s ## completed", __FUNCTION__);
+ } while (0);
+
+ esp_avrc_tg_cb_param_t param = {0};
+ param.avrc_tg_init_stat.state = state;
+ btc_avrc_tg_cb_to_app(ESP_AVRC_TG_PROF_STATE_EVT, &param);
}
static void btc_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp, const esp_avrc_rn_param_t *param)
@@ -1402,6 +1630,10 @@ void btc_avrc_ct_call_handler(btc_msg_t *msg)
btc_avrc_ct_send_metadata_cmd(arg->md_cmd.tl, arg->md_cmd.attr_mask);
break;
}
+ case BTC_AVRC_STATUS_API_SND_GET_PLAY_STATUS_EVT: {
+ btc_avrc_ct_send_get_play_status_cmd(arg->get_play_status_cmd.tl);
+ break;
+ }
case BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT: {
btc_avrc_ct_send_get_rn_caps_cmd(arg->get_caps_cmd.tl);
break;
@@ -1418,6 +1650,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);
}
@@ -1455,4 +1709,25 @@ void btc_avrc_tg_call_handler(btc_msg_t *msg)
btc_avrc_tg_arg_deep_free(msg);
}
+void btc_avrc_get_profile_status(esp_avrc_profile_status_t *param)
+{
+ param->avrc_ct_inited = false;
+ param->avrc_tg_inited = false;
+
+#if AVRC_DYNAMIC_MEMORY == TRUE
+ if (btc_rc_cb_ptr)
+#endif
+ {
+ if (btc_avrc_tg_init_p()) {
+ param->avrc_tg_inited = true;
+ }
+ if (btc_avrc_ct_init_p()) {
+ param->avrc_ct_inited = true;
+ }
+ if (btc_rc_cb.rc_cover_art_connected) {
+ param->ct_cover_art_conn_num++;
+ }
+ }
+}
+
#endif /* #if BTC_AV_INCLUDED */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c b/lib/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c
new file mode 100644
index 00000000..a4f4377c
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c
@@ -0,0 +1,395 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+
+#include "osi/allocator.h"
+
+#include "bta/bta_api.h"
+#include "bta/bta_dm_co.h"
+#include "btc/btc_task.h"
+#include "btc/btc_util.h"
+#if (BLE_FEAT_CTE_EN == TRUE)
+#include "btc_ble_cte.h"
+
+static inline void btc_cte_ble_cb_to_app(esp_ble_cte_cb_event_t event, esp_ble_cte_cb_param_t *param)
+{
+ esp_ble_cte_cb_t btc_cte_ble_cb = (esp_ble_cte_cb_t)btc_profile_cb_get(BTC_PID_BLE_CTE);
+ if (btc_cte_ble_cb) {
+ btc_cte_ble_cb(event, param);
+ }
+}
+
+static void btc_ble_cte_callback(tBTM_BLE_CTE_EVENT event,
+ tBTM_BLE_CTE_CB_PARAMS *params)
+{
+ esp_ble_cte_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_BLE_CTE;
+
+ BTC_TRACE_DEBUG("%s event %d\n", __func__, event);
+
+ switch(event) {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case BTA_BLE_CTE_SET_TRANS_PARAMS_EVT:
+ msg.act = ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT;
+ param.set_trans_params_cmpl.status = btc_btm_status_to_esp_status(params->cte_trans_params_cmpl.status);
+ break;
+ case BTA_BLE_CTE_SET_TRANS_ENABLE_EVT:
+ msg.act = ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT;
+ param.set_trans_enable_cmpl.status = btc_btm_status_to_esp_status(params->cte_trans_params_cmpl.status);
+ break;
+ case BTA_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT:
+ msg.act = ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT;
+ param.iq_sampling_enable_cmpl.status = btc_btm_status_to_esp_status(params->cte_iq_samp_en_cmpl.status);
+ param.iq_sampling_enable_cmpl.sync_handle = params->cte_iq_samp_en_cmpl.sync_handle;
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case BTA_BLE_CTE_SET_CONN_RECV_PARAMS_EVT:
+ msg.act = ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT;
+ param.conn_recv_params_cmpl.status = btc_btm_status_to_esp_status(params->cte_recv_params_cmpl.status);
+ param.conn_recv_params_cmpl.conn_handle = params->cte_recv_params_cmpl.conn_handle;
+ break;
+ case BTA_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT:
+ msg.act = ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT;
+ param.conn_trans_params_cmpl.status = btc_btm_status_to_esp_status(params->cte_conn_trans_params_cmpl.status);
+ param.conn_trans_params_cmpl.conn_handle = params->cte_conn_trans_params_cmpl.conn_handle;
+ break;
+ case BTA_BLE_CTE_SET_CONN_REQ_ENABLE_EVT:
+ msg.act = ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT;
+ param.conn_req_en_cmpl.status = btc_btm_status_to_esp_status(params->cte_conn_req_en_cmpl.status);
+ param.conn_req_en_cmpl.conn_handle = params->cte_conn_req_en_cmpl.conn_handle;
+ break;
+ case BTA_BLE_CTE_SET_CONN_RSP_ENABLE_EVT:
+ msg.act = ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT;
+ param.conn_rsp_en_cmpl.status = btc_btm_status_to_esp_status(params->cte_conn_rsp_en_cmpl.status);
+ param.conn_rsp_en_cmpl.conn_handle = params->cte_conn_rsp_en_cmpl.conn_handle;
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case BTA_BLE_CTE_READ_ANT_INFOR_EVT:
+ msg.act = ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT;
+ param.read_ant_infor_cmpl.status = btc_btm_status_to_esp_status(params->cte_read_ant_infor_cmpl.status);
+ param.read_ant_infor_cmpl.supported_switching_sampling_rates = params->cte_read_ant_infor_cmpl.supported_switching_sampling_rates;
+ param.read_ant_infor_cmpl.num_antennae = params->cte_read_ant_infor_cmpl.num_ant;
+ param.read_ant_infor_cmpl.max_switching_pattern_len = params->cte_read_ant_infor_cmpl.max_switching_pattern_len;
+ param.read_ant_infor_cmpl.max_cte_len = params->cte_read_ant_infor_cmpl.max_cte_len;
+ break;
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case BTA_BLE_CTE_CONNLESS_IQ_REPORT_EVT:
+ msg.act = ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT;
+ param.connless_iq_rpt.sync_handle = params->cte_connless_iq_rpt.sync_handle;
+ param.connless_iq_rpt.channel_idx = params->cte_connless_iq_rpt.channel_idx;
+ param.connless_iq_rpt.rssi = params->cte_connless_iq_rpt.rssi;
+ param.connless_iq_rpt.rssi_ant_id = params->cte_connless_iq_rpt.rssi_ant_id;
+ param.connless_iq_rpt.cte_type = params->cte_connless_iq_rpt.cte_type;
+ param.connless_iq_rpt.slot_dur = params->cte_connless_iq_rpt.slot_dur;
+ param.connless_iq_rpt.pkt_status = params->cte_connless_iq_rpt.pkt_status;
+ param.connless_iq_rpt.periodic_evt_counter = params->cte_connless_iq_rpt.periodic_evt_counter;
+ param.connless_iq_rpt.sample_count = params->cte_connless_iq_rpt.sample_count;
+ param.connless_iq_rpt.i_sample = &(params->cte_connless_iq_rpt.i_sample[0]);
+ param.connless_iq_rpt.q_sample = &(params->cte_connless_iq_rpt.q_sample[0]);
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case BTA_BLE_CTE_CONN_IQ_REPORT_EVT:
+ msg.act = ESP_BLE_CTE_CONN_IQ_REPORT_EVT;
+ param.conn_iq_rpt.conn_handle = params->cte_conn_iq_rpt.conn_handle;
+ param.conn_iq_rpt.data_channel_idx = params->cte_conn_iq_rpt.data_channel_idx;
+ param.conn_iq_rpt.rssi = params->cte_conn_iq_rpt.rssi;
+ param.conn_iq_rpt.rssi_ant_id = params->cte_conn_iq_rpt.rssi_ant_id;
+ param.conn_iq_rpt.cte_type = params->cte_conn_iq_rpt.cte_type;
+ param.conn_iq_rpt.slot_dur = params->cte_conn_iq_rpt.slot_dur;
+ param.conn_iq_rpt.pkt_status = params->cte_conn_iq_rpt.pkt_status;
+ param.conn_iq_rpt.conn_evt_counter = params->cte_conn_iq_rpt.conn_evt_counter;
+ param.conn_iq_rpt.sample_count = params->cte_conn_iq_rpt.sample_count;
+ param.conn_iq_rpt.i_sample = &params->cte_conn_iq_rpt.i_sample[0];
+ param.conn_iq_rpt.q_sample = &params->cte_conn_iq_rpt.q_sample[0];
+ break;
+ case BTA_BLE_CTE_REQUEST_FAILED_EVT:
+ msg.act = ESP_BLE_CTE_REQUEST_FAILED_EVT;
+ param.req_failed_evt.reason = btc_btm_status_to_esp_status(params->cte_req_failed.status);
+ param.req_failed_evt.conn_handle = params->cte_req_failed.conn_handle;
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ default:
+ break;
+ }
+
+ ret = btc_transfer_context(&msg, &param,
+ sizeof(esp_ble_cte_cb_param_t), btc_ble_cte_cb_deep_copy, btc_ble_cte_cb_deep_free);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+
+void btc_ble_cte_cb_handler(btc_msg_t *msg)
+{
+ BTC_TRACE_DEBUG("%s act %d \n", __func__, msg->act);
+ esp_ble_cte_cb_param_t *param = (esp_ble_cte_cb_param_t *)msg->arg;
+
+ if (msg->act < ESP_BLE_CTE_EVT_MAX) {
+ btc_cte_ble_cb_to_app(msg->act, param);
+ } else {
+ BTC_TRACE_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
+ }
+
+ btc_ble_cte_cb_deep_free(msg);
+
+}
+
+void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+#if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE))
+ btc_ble_cte_args_t *src = (btc_ble_cte_args_t *)p_src;
+ btc_ble_cte_args_t *dst = (btc_ble_cte_args_t *)p_dest;
+#endif // #if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE))
+ switch (msg->act) {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case BTC_CTE_ACT_SET_TRANS_PARAMS:
+ if (src->cte_trans_params.switching_pattern_len && src->cte_trans_params.antenna_ids) {
+ dst->cte_trans_params.antenna_ids = osi_malloc(src->cte_trans_params.switching_pattern_len);
+ if (dst->cte_trans_params.antenna_ids) {
+ memcpy(dst->cte_trans_params.antenna_ids, src->cte_trans_params.antenna_ids, src->cte_trans_params.switching_pattern_len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
+ case BTC_CTE_ACT_SET_IQ_SAMPLING_EN:
+ if (src->cte_iq_sampling_en.switching_pattern_len && src->cte_iq_sampling_en.antenna_ids) {
+ dst->cte_iq_sampling_en.antenna_ids = osi_malloc(src->cte_iq_sampling_en.switching_pattern_len);
+ if (dst->cte_iq_sampling_en.antenna_ids) {
+ memcpy(dst->cte_iq_sampling_en.antenna_ids, src->cte_iq_sampling_en.antenna_ids, src->cte_iq_sampling_en.switching_pattern_len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS:
+ if (src->cte_recv_params.switching_pattern_len && src->cte_recv_params.antenna_ids) {
+ dst->cte_recv_params.antenna_ids = osi_malloc(src->cte_recv_params.switching_pattern_len);
+ if (dst->cte_recv_params.antenna_ids) {
+ memcpy(dst->cte_recv_params.antenna_ids, src->cte_recv_params.antenna_ids, src->cte_recv_params.switching_pattern_len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
+ case BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS:
+ if (src->cte_conn_trans_params.switching_pattern_len && src->cte_conn_trans_params.antenna_ids) {
+ dst->cte_conn_trans_params.antenna_ids = osi_malloc(src->cte_conn_trans_params.switching_pattern_len);
+ if (dst->cte_conn_trans_params.antenna_ids) {
+ memcpy(dst->cte_conn_trans_params.antenna_ids, src->cte_conn_trans_params.antenna_ids, src->cte_conn_trans_params.switching_pattern_len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ default:
+ BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
+ break;
+ }
+}
+
+void btc_ble_cte_arg_deep_free(btc_msg_t *msg)
+{
+ BTC_TRACE_DEBUG("%s \n", __func__);
+ switch (msg->act) {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case BTC_CTE_ACT_SET_TRANS_PARAMS: {
+ uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_trans_params.antenna_ids;
+ if (antenna_ids) {
+ osi_free(antenna_ids);
+ }
+ break;
+ }
+ case BTC_CTE_ACT_SET_IQ_SAMPLING_EN: {
+ uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_iq_sampling_en.antenna_ids;
+ if (antenna_ids) {
+ osi_free(antenna_ids);
+ }
+ break;
+ }
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS: {
+ uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_recv_params.antenna_ids;
+ if (antenna_ids) {
+ osi_free(antenna_ids);
+ }
+ break;
+ }
+ case BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS: {
+ uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_conn_trans_params.antenna_ids;
+ if (antenna_ids) {
+ osi_free(antenna_ids);
+ }
+ break;
+ }
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ default:
+ BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act);
+ break;
+ }
+}
+
+void btc_ble_cte_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+ esp_ble_cte_cb_param_t *src = (esp_ble_cte_cb_param_t *)p_src;
+ esp_ble_cte_cb_param_t *dst = (esp_ble_cte_cb_param_t *) p_dest;
+
+ switch (msg->act) {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT:
+ if (src->connless_iq_rpt.sample_count) {
+ dst->connless_iq_rpt.i_sample = osi_malloc(src->connless_iq_rpt.sample_count);
+ if (dst->connless_iq_rpt.i_sample) {
+ memcpy(dst->connless_iq_rpt.i_sample, &(src->connless_iq_rpt.i_sample[0]),
+ src->connless_iq_rpt.sample_count);
+ } else {
+ BTC_TRACE_ERROR("%s, i_sample malloc failed\n", __func__);
+ }
+ dst->connless_iq_rpt.q_sample = osi_malloc(src->connless_iq_rpt.sample_count);
+ if (dst->connless_iq_rpt.q_sample) {
+ memcpy(dst->connless_iq_rpt.q_sample, &(src->connless_iq_rpt.q_sample[0]),
+ src->connless_iq_rpt.sample_count);
+ } else {
+ BTC_TRACE_ERROR("%s, q_sample malloc failed\n", __func__);
+ }
+ }
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case ESP_BLE_CTE_CONN_IQ_REPORT_EVT:
+ if (src->conn_iq_rpt.sample_count) {
+ dst->conn_iq_rpt.i_sample = osi_malloc(src->conn_iq_rpt.sample_count);
+ if (dst->conn_iq_rpt.i_sample) {
+ memcpy(dst->conn_iq_rpt.i_sample, src->conn_iq_rpt.i_sample,
+ src->conn_iq_rpt.sample_count);
+ } else {
+ BTC_TRACE_ERROR("%s, i_sample malloc failed\n", __func__);
+ }
+ dst->conn_iq_rpt.q_sample = osi_malloc(src->conn_iq_rpt.sample_count);
+ if (dst->conn_iq_rpt.q_sample) {
+ memcpy(dst->conn_iq_rpt.q_sample, src->conn_iq_rpt.q_sample,
+ src->conn_iq_rpt.sample_count);
+ } else {
+ BTC_TRACE_ERROR("%s, q_sample malloc failed\n", __func__);
+ }
+ }
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ default:
+ BTC_TRACE_DEBUG("%s, Unhandled deep copy %d\n", __func__, msg->act);
+ break;
+ }
+}
+
+void btc_ble_cte_cb_deep_free(btc_msg_t *msg)
+{
+ BTC_TRACE_DEBUG("%s", __func__);
+ switch (msg->act) {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT: {
+ esp_ble_cte_cb_param_t *params = (esp_ble_cte_cb_param_t *)msg->arg;
+ uint8_t *i_sample = &(params->connless_iq_rpt.i_sample[0]);
+ uint8_t *q_sample = &(params->connless_iq_rpt.q_sample[0]);
+ if (i_sample) {
+ osi_free(i_sample);
+ }
+ if (q_sample) {
+ osi_free(q_sample);
+ }
+ break;
+ }
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case ESP_BLE_CTE_CONN_IQ_REPORT_EVT: {
+ esp_ble_cte_cb_param_t *params = (esp_ble_cte_cb_param_t *)msg->arg;
+ uint8_t *i_sample = params->conn_iq_rpt.i_sample;
+ uint8_t *q_sample = params->conn_iq_rpt.q_sample;
+ if (i_sample) {
+ osi_free(i_sample);
+ }
+ if (q_sample) {
+ osi_free(q_sample);
+ }
+ break;
+ }
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ default:
+ BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act);
+ break;
+ }
+}
+
+void btc_ble_cte_call_handler(btc_msg_t *msg)
+{
+#if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE))
+ btc_ble_cte_args_t *arg = (btc_ble_cte_args_t *)msg->arg;
+#endif // #if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE))
+ BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act);
+
+ switch (msg->act) {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case BTC_CTE_ACT_SET_TRANS_PARAMS:
+ struct cte_set_trans_params_arg *cte_trans_params = &arg->cte_trans_params;
+ BTA_DmBleCteSetConnectionlessTransParams(cte_trans_params->adv_handle, cte_trans_params->cte_len, cte_trans_params->cte_type,
+ cte_trans_params->cte_count, cte_trans_params->switching_pattern_len, cte_trans_params->antenna_ids);
+ break;
+ case BTC_CTE_ACT_SET_TRANS_ENABLE:
+ BTA_DmBleCteSetConnectionlessTransEnable(arg->cte_trans_enable.adv_handle, arg->cte_trans_enable.cte_enable);
+ break;
+ case BTC_CTE_ACT_SET_IQ_SAMPLING_EN:
+ struct cte_iq_sampling_en_arg *iq_sampling_en = &arg->cte_iq_sampling_en;
+ BTA_DmBleCteSetConnectionlessIqSamplingEnable(iq_sampling_en->sync_handle, iq_sampling_en->sampling_en, iq_sampling_en->slot_dur,
+ iq_sampling_en->max_sampled_ctes, iq_sampling_en->switching_pattern_len, iq_sampling_en->antenna_ids);
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS:
+ struct cte_recv_params_arg *recv_params = &arg->cte_recv_params;
+ BTA_DmBleCteSetConnectionReceiveParams(recv_params->conn_handle, recv_params->sampling_en, recv_params->slot_dur,
+ recv_params->switching_pattern_len, recv_params->antenna_ids);
+ break;
+ case BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS:
+ struct cte_set_conn_trans_params_arg *trans_params = &arg->cte_conn_trans_params;
+ BTA_DmBleCteSetConnectionTransParams(trans_params->conn_handle, trans_params->cte_types, trans_params->switching_pattern_len, trans_params->antenna_ids);
+ break;
+ case BTC_CTE_ACT_SET_CONN_CTE_REQUEST_EN:
+ struct cte_req_en_arg *cte_req_en = &arg->cte_req_en;
+ BTA_DmBleCteSetConnectionRequestEnable(cte_req_en->conn_handle, cte_req_en->enable, cte_req_en->cte_req_interval,
+ cte_req_en->req_cte_len, cte_req_en->req_cte_Type);
+ break;
+ case BTC_CTE_ACT_SET_CONN_CTE_RESPONSE_EN:
+ BTA_DmBleCteSetConnectionRspEnable(arg->cte_rsp_en.conn_handle, arg->cte_rsp_en.enable);
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case BTC_CTE_ACT_READ_ANTENNA_INFOR:
+ BTA_DmBleCteReadAntInfor();
+ break;
+ default:
+ break;
+ }
+
+ btc_ble_cte_arg_deep_free(msg);
+}
+
+//register connection parameter update callback
+void btc_cte_callback_init(void)
+{
+ BTM_BleCteRegisterCallback(btc_ble_cte_callback);
+}
+
+#endif ///BLE_FEAT_CTE_EN == TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c
index 53d0b835..e2872ce5 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,6 +30,7 @@
#if (BLE_INCLUDED == TRUE)
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
#if BTC_DYNAMIC_MEMORY == FALSE
static tBTA_BLE_ADV_DATA gl_bta_adv_data;
static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
@@ -37,33 +38,22 @@ static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
tBTA_BLE_ADV_DATA *gl_bta_adv_data_ptr;
tBTA_BLE_ADV_DATA *gl_bta_scan_rsp_data_ptr;
#endif
+#endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
-#if SCAN_QUEUE_CONGEST_CHECK
-static list_t *adv_filter_list;
-static osi_mutex_t adv_list_lock;
-bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type);
-uint32_t btc_get_adv_list_length(void);
-void btc_adv_list_refresh(void);
-void btc_adv_list_lock(void);
-void btc_adv_list_unlock(void);
-static uint16_t btc_adv_list_count = 0;
-
-#define BTC_ADV_LIST_MAX_LENGTH 50
-#define BTC_ADV_LIST_MAX_COUNT 200
-#endif
-
#define BTC_GAP_BLE_ADV_RPT_QUEUE_IDX (1)
#define BTC_GAP_BLE_ADV_RPT_BATCH_SIZE (10)
#define BTC_GAP_BLE_ADV_RPT_QUEUE_LEN_MAX (200)
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
typedef struct {
struct pkt_queue *adv_rpt_queue;
struct osi_event *adv_rpt_ready;
} btc_gap_ble_env_t;
static btc_gap_ble_env_t btc_gap_ble_env;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#endif
static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
@@ -102,6 +92,7 @@ static void btc_gap_ble_get_dev_name_callback(UINT8 status, char *name)
}
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
static void btc_gap_adv_point_cleanup(void **buf)
{
if (NULL == *buf) {
@@ -476,25 +467,7 @@ static void btc_stop_adv_callback(uint8_t status)
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
-
-static void btc_clear_adv_callback(uint8_t status)
-{
- esp_ble_gap_cb_param_t param;
- bt_status_t ret;
- btc_msg_t msg = {0};
-
- msg.sig = BTC_SIG_API_CB;
- msg.pid = BTC_PID_GAP_BLE;
- msg.act = ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT;
- param.adv_clear_cmpl.status = btc_hci_to_esp_status(status);
-
- ret = btc_transfer_context(&msg, &param,
- sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
-
- if (ret != BT_STATUS_SUCCESS) {
- BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
- }
-}
+#endif // #if (BLE_42_ADV_EN == TRUE)
void btc_update_duplicate_exceptional_list_callback(tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info)
{
@@ -525,6 +498,7 @@ static void btc_ble_update_duplicate_exceptional_list(uint8_t subcode, uint32_t
BTA_DmUpdateDuplicateExceptionalList(subcode, info_type, device_info, p_update_duplicate_ignore_list_cback);
}
+#if (BLE_42_ADV_EN == TRUE)
static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBTA_START_ADV_CMPL_CBACK start_adv_cback)
{
tBLE_BD_ADDR peer_addr;
@@ -575,8 +549,9 @@ static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBT
&peer_addr,
start_adv_cback);
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
-
+#if (BLE_42_SCAN_EN == TRUE)
static void btc_scan_params_callback(tGATT_IF gatt_if, tBTM_STATUS status)
{
esp_ble_gap_cb_param_t param;
@@ -641,20 +616,6 @@ static void btc_gap_ble_adv_pkt_handler(void *arg)
static void btc_process_adv_rpt_pkt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
-#if SCAN_QUEUE_CONGEST_CHECK
- if(btc_check_queue_is_congest()) {
- BTC_TRACE_DEBUG("BtcQueue is congested");
- if(btc_get_adv_list_length() > BTC_ADV_LIST_MAX_LENGTH || btc_adv_list_count > BTC_ADV_LIST_MAX_COUNT) {
- btc_adv_list_refresh();
- btc_adv_list_count = 0;
- }
- if(btc_check_adv_list(p_data->inq_res.bd_addr, p_data->inq_res.ble_addr_type)) {
- return;
- }
- }
- btc_adv_list_count ++;
-#endif
-
// drop ADV packets if data queue length goes above threshold
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
if (pkt_queue_length(p_env->adv_rpt_queue) >= BTC_GAP_BLE_ADV_RPT_QUEUE_LEN_MAX) {
@@ -770,10 +731,8 @@ static void btc_stop_scan_callback(tBTA_STATUS status)
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
-#if SCAN_QUEUE_CONGEST_CHECK
- btc_adv_list_refresh();
-#endif
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params)
{
@@ -957,8 +916,31 @@ static void btc_read_ble_rssi_cmpl_callback(void *p_data)
}
}
+static void btc_ble_read_channel_map_callback(void *p_data)
+{
+ tBTA_BLE_CH_MAP_RESULTS *result = (tBTA_BLE_CH_MAP_RESULTS *)p_data;
+ esp_ble_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg = {0};
+
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT;
+
+ param.read_ble_channel_map_cmpl.status = btc_btm_status_to_esp_status(result->status);
+ memcpy(param.read_ble_channel_map_cmpl.channel_map, result->channel_map, 5);
+ memcpy(param.read_ble_channel_map_cmpl.remote_addr, result->rem_bda, sizeof(BD_ADDR));
+
+ ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+
+
#if (BLE_50_FEATURE_SUPPORT == TRUE)
-static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
+void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
tBTA_DM_BLE_5_GAP_CB_PARAMS *params)
{
esp_ble_gap_cb_param_t param;
@@ -986,62 +968,86 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
param.set_perf_phy.status = btc_btm_status_to_esp_status(params->set_perf_phy.status);
break;
}
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTA_DM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT:
msg.act = ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT;
param.ext_adv_set_rand_addr.status = btc_btm_status_to_esp_status(params->set_ext_rand_addr.status);
+ param.ext_adv_set_rand_addr.instance = params->set_ext_rand_addr.instance;
break;
case BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT;
- param.ext_adv_set_rand_addr.status = btc_btm_status_to_esp_status(params->set_params.status);
+ param.ext_adv_set_params.status = btc_btm_status_to_esp_status(params->set_params.status);
+ param.ext_adv_set_params.instance = params->set_params.instance;
break;
}
case BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT;
param.ext_adv_data_set.status = btc_btm_status_to_esp_status(params->adv_data_set.status);
+ param.ext_adv_data_set.instance = params->adv_data_set.instance;
break;
}
case BTA_DM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT;
param.scan_rsp_set.status = btc_btm_status_to_esp_status(params->scan_rsp_data_set.status);
+ param.scan_rsp_set.instance = params->scan_rsp_data_set.instance;
break;
}
case BTA_DM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT;
param.ext_adv_start.status = btc_btm_status_to_esp_status(params->adv_start.status);
+ for (UINT8 i = 0; i < params->adv_start.instance_num; i++) {
+ param.ext_adv_start.instance[i] = params->adv_start.instance[i];
+ }
+
+ param.ext_adv_start.instance_num = params->adv_start.instance_num;
break;
}
case BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT:
msg.act = ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT;
param.ext_adv_stop.status = btc_btm_status_to_esp_status(params->adv_start.status);
+ for (UINT8 i = 0; i < params->adv_start.instance_num; i++) {
+ param.ext_adv_stop.instance[i] = params->adv_start.instance[i];
+ }
+ param.ext_adv_stop.instance_num = params->adv_start.instance_num;
break;
case BTA_DM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT:
msg.act = ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT;
param.ext_adv_remove.status = btc_btm_status_to_esp_status(params->adv_start.status);
+ param.ext_adv_remove.instance = params->adv_start.instance[0];
break;
case BTA_DM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT:
msg.act = ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT;
param.ext_adv_clear.status = btc_btm_status_to_esp_status(params->adv_start.status);
break;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
case BTA_DM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT;
param.peroid_adv_set_params.status = btc_btm_status_to_esp_status(params->per_adv_set_params.status);
+ param.peroid_adv_set_params.instance = params->per_adv_set_params.instance;
break;
}
case BTA_DM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT;
param.period_adv_data_set.status = btc_btm_status_to_esp_status(params->per_adv_data_set.status);
+ param.period_adv_data_set.instance = params->per_adv_data_set.instance;
break;
}
case BTA_DM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT;
param.period_adv_start.status = btc_btm_status_to_esp_status(params->per_adv_start.status);
+ param.period_adv_start.instance = params->per_adv_start.instance;
break;
}
case BTA_DM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT;
param.period_adv_stop.status = btc_btm_status_to_esp_status(params->per_adv_stop.status);
+ param.period_adv_stop.instance = params->per_adv_stop.instance;
break;
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
case BTA_DM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT;
param.period_adv_create_sync.status = btc_btm_status_to_esp_status(params->per_adv_sync_create.status);
@@ -1072,6 +1078,9 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
param.period_adv_clear_dev.status = btc_btm_status_to_esp_status(params->per_adv_clear_dev.status);
break;
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
case BTA_DM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_SET_EXT_SCAN_PARAMS_COMPLETE_EVT;
param.set_ext_scan_params.status = btc_btm_status_to_esp_status(params->ext_scan.status);
@@ -1087,6 +1096,7 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
param.ext_scan_stop.status = btc_btm_status_to_esp_status(params->scan_stop.status);
break;
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
case BTA_DM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT: {
msg.act = ESP_GAP_BLE_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT;
param.ext_conn_params_set.status = btc_btm_status_to_esp_status(params->ext_conn_set_params.status);
@@ -1099,6 +1109,7 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
param.phy_update.tx_phy = params->phy_update.tx_phy;
param.phy_update.rx_phy = params->phy_update.rx_phy;
break;
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
case BTA_DM_BLE_5_GAP_EXT_ADV_REPORT_EVT:
msg.act = ESP_GAP_BLE_EXT_ADV_REPORT_EVT;
memcpy(&param.ext_adv_report.params, &params->ext_adv_report, sizeof(esp_ble_gap_ext_adv_report_t));
@@ -1110,6 +1121,8 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
case BTA_DM_BLE_5_GAP_SCAN_TIMEOUT_EVT:
msg.act = ESP_GAP_BLE_SCAN_TIMEOUT_EVT;
break;
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT: {
param.adv_terminate.status = params->adv_term.status;
param.adv_terminate.adv_instance = params->adv_term.adv_handle;
@@ -1125,16 +1138,24 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
memcpy(param.scan_req_received.scan_addr, params->scan_req.scan_addr, sizeof(BD_ADDR));
break;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTA_DM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT: {
msg.act = ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT;
param.channel_sel_alg.conn_handle = params->channel_sel.conn_handle;
param.channel_sel_alg.channel_sel_alg = params->channel_sel.channel_sel_alg;
break;
}
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
case BTA_DM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT: {
msg.act = ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT;
- memcpy(&param.period_adv_report, &params->period_adv_report,
- sizeof(esp_ble_gap_periodic_adv_report_t));
+ param.period_adv_report.params.sync_handle = params->period_adv_report.sync_handle;
+ param.period_adv_report.params.tx_power = params->period_adv_report.tx_power;
+ param.period_adv_report.params.rssi = params->period_adv_report.rssi;
+ #if (BLE_FEAT_CTE_EN == TRUE)
+ param.period_adv_report.params.cte_type = params->period_adv_report.cte_type;
+ #endif // #if (BLE_FEAT_CTE_EN == TRUE)
+ param.period_adv_report.params.data_status = params->period_adv_report.data_status;
+ param.period_adv_report.params.data_length = params->period_adv_report.data_length;
if (params->period_adv_report.data) {
memcpy(param.period_adv_report.params.data, params->period_adv_report.data,
params->period_adv_report.data_length);
@@ -1159,6 +1180,8 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
param.periodic_adv_sync_estab.adv_clk_accuracy = params->sync_estab.adv_clk_accuracy;
break;
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
case BTA_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT:
msg.act = ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT;
@@ -1193,6 +1216,76 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
param.past_received.adv_clk_accuracy = params->past_recv.adv_clk_accuracy;
break;
#endif
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ case BTA_BLE_GAP_ENH_READ_TRANS_POWER_LEVEL_EVT:
+ msg.act = ESP_GAP_BLE_ENH_READ_TRANS_PWR_LEVEL_EVT;
+ param.enh_trans_pwr_level_cmpl.status = btc_btm_status_to_esp_status(params->enh_trans_pwr_level_cmpl.status);
+ param.enh_trans_pwr_level_cmpl.conn_handle = params->enh_trans_pwr_level_cmpl.conn_handle;
+ param.enh_trans_pwr_level_cmpl.phy = params->enh_trans_pwr_level_cmpl.phy;
+ param.enh_trans_pwr_level_cmpl.cur_tx_pwr_level = params->enh_trans_pwr_level_cmpl.cur_tx_pwr_level;
+ param.enh_trans_pwr_level_cmpl.max_tx_pwr_level = params->enh_trans_pwr_level_cmpl.max_tx_pwr_level;
+ break;
+ case BTA_BLE_GAP_READ_REMOTE_TRANS_POWER_LEVEL_EVT:
+ msg.act = ESP_GAP_BLE_READ_REMOTE_TRANS_PWR_LEVEL_EVT;
+ param.read_remote_trans_pwr_level_cmpl.status = btc_btm_status_to_esp_status(params->remote_pwr_level_cmpl.status);
+ break;
+ case BTA_BLE_GAP_SET_PATH_LOSS_REPORTING_PARAMS_EVT:
+ msg.act = ESP_GAP_BLE_SET_PATH_LOSS_RPTING_PARAMS_EVT;
+ param.set_path_loss_rpting_params.status = btc_btm_status_to_esp_status(params->path_loss_rpting_params.status);
+ param.set_path_loss_rpting_params.conn_handle = params->path_loss_rpting_params.conn_handle;
+ break;
+ case BTA_BLE_GAP_SET_PATH_LOSS_REPORTING_ENABLE_EVT:
+ msg.act = ESP_GAP_BLE_SET_PATH_LOSS_RPTING_ENABLE_EVT;
+ param.set_path_loss_rpting_enable.status = btc_btm_status_to_esp_status(params->path_loss_rpting_enable.status);
+ param.set_path_loss_rpting_enable.conn_handle = params->path_loss_rpting_enable.conn_handle;
+ break;
+ case BTA_BLE_GAP_SET_TRANS_POWER_REPORTING_ENABLE_EVT:
+ msg.act = ESP_GAP_BLE_SET_TRANS_PWR_RPTING_ENABLE_EVT;
+ param.set_trans_pwr_rpting_enable.status = btc_btm_status_to_esp_status(params->trans_pwr_rpting_enable.status);
+ param.set_trans_pwr_rpting_enable.conn_handle = params->trans_pwr_rpting_enable.conn_handle;
+ break;
+ case BTA_BLE_GAP_PATH_LOSS_THRESHOLD_EVT:
+ msg.act = ESP_GAP_BLE_PATH_LOSS_THRESHOLD_EVT;
+ param.path_loss_thres_evt.conn_handle = params->path_loss_thres_evt.conn_handle;
+ param.path_loss_thres_evt.cur_path_loss = params->path_loss_thres_evt.cur_path_loss;
+ param.path_loss_thres_evt.zone_entered = params->path_loss_thres_evt.zone_entered;
+ break;
+ case BTA_BLE_GAP_TRANMIT_POWER_REPORTING_EVT:
+ msg.act = ESP_GAP_BLE_TRANS_PWR_RPTING_EVT;
+ param.trans_power_report_evt.status = btc_btm_status_to_esp_status(params->trans_pwr_report_evt.status);
+ param.trans_power_report_evt.conn_handle = params->trans_pwr_report_evt.conn_handle;
+ param.trans_power_report_evt.reason = params->trans_pwr_report_evt.reason;
+ param.trans_power_report_evt.phy = params->trans_pwr_report_evt.phy;
+ param.trans_power_report_evt.tx_power_level = params->trans_pwr_report_evt.tx_power_level;
+ param.trans_power_report_evt.tx_power_level_flag = params->trans_pwr_report_evt.tx_power_level_flag;
+ param.trans_power_report_evt.delta = params->trans_pwr_report_evt.delta;
+ break;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ case BTA_BLE_GAP_SET_DEFAULT_SUBRATE_EVT:
+ msg.act = ESP_GAP_BLE_SET_DEFAULT_SUBRATE_COMPLETE_EVT;
+ param.set_default_subrate_evt.status = btc_btm_status_to_esp_status(params->status);
+ break;
+ case BTA_BLE_GAP_SUBRATE_REQUEST_EVT:
+ msg.act = ESP_GAP_BLE_SUBRATE_REQUEST_COMPLETE_EVT;
+ param.subrate_req_cmpl_evt.status = btc_btm_status_to_esp_status(params->status);
+ break;
+ case BTA_BLE_GAP_SUBRATE_CHANGE_EVT:
+ msg.act = ESP_GAP_BLE_SUBRATE_CHANGE_EVT;
+ param.subrate_change_evt.status = btc_btm_status_to_esp_status(params->subrate_change_evt.status);
+ param.subrate_change_evt.conn_handle = params->subrate_change_evt.conn_handle;
+ param.subrate_change_evt.subrate_factor = params->subrate_change_evt.subrate_factor;
+ param.subrate_change_evt.peripheral_latency = params->subrate_change_evt.peripheral_latency;
+ param.subrate_change_evt.continuation_number = params->subrate_change_evt.continuation_number;
+ param.subrate_change_evt.supervision_timeout = params->subrate_change_evt.supervision_timeout;
+ break;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ case BTA_BLE_GAP_SET_HOST_FEATURE_EVT:
+ msg.act = ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT;
+ param.host_feature.status = btc_btm_status_to_esp_status(params->status);
+ break;
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
default:
break;
}
@@ -1206,6 +1299,7 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
void btc_dtm_tx_start_callback(void *p1)
{
UINT8 status;
@@ -1260,7 +1354,9 @@ void btc_dtm_rx_start_callback(void *p1)
}
}
}
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
void btc_dtm_stop_callback(void *p1)
{
UINT8 status;
@@ -1289,6 +1385,46 @@ void btc_dtm_stop_callback(void *p1)
}
}
}
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
+
+static void btc_ble_set_privacy_mode_callback(UINT8 status)
+{
+ esp_ble_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg = {0};
+
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT;
+
+ param.set_privacy_mode_cmpl.status = btc_btm_status_to_esp_status(status);
+
+ ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+
+#if (BLE_VENDOR_HCI_EN == TRUE)
+static void btc_clear_adv_callback(uint8_t status)
+{
+ esp_ble_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg = {0};
+
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT;
+ param.adv_clear_cmpl.status = btc_hci_to_esp_status(status);
+
+ ret = btc_transfer_context(&msg, &param,
+ sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
static void btc_ble_vendor_hci_cmd_complete_callback(tBTA_VSC_CMPL *p_param)
{
@@ -1326,7 +1462,7 @@ static void btc_ble_vendor_hci_cmd_complete_callback(tBTA_VSC_CMPL *p_param)
}
}
-static void btc_ble_set_privacy_mode_callback(UINT8 status)
+static void btc_ble_set_csa_support_callback(UINT8 status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
@@ -1334,9 +1470,9 @@ static void btc_ble_set_privacy_mode_callback(UINT8 status)
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
- msg.act = ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT;
+ msg.act = ESP_GAP_BLE_SET_CSA_SUPPORT_COMPLETE_EVT;
- param.set_privacy_mode_cmpl.status = btc_btm_status_to_esp_status(status);
+ param.set_csa_support_cmpl.status = btc_btm_status_to_esp_status(status);
ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
@@ -1345,20 +1481,89 @@ static void btc_ble_set_privacy_mode_callback(UINT8 status)
}
}
+static void btc_ble_set_vendor_evt_mask_callback(UINT8 status)
+{
+ esp_ble_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg = {0};
+
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = ESP_GAP_BLE_SET_VENDOR_EVT_MASK_COMPLETE_EVT;
+
+ param.set_vendor_evt_mask_cmpl.status = btc_btm_status_to_esp_status(status);
+
+ ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+
+static void btc_ble_vendor_hci_event_callback(UINT8 subevt_code, UINT8 param_len, UINT8 *params)
+{
+ esp_ble_gap_cb_param_t param = {0};
+ bt_status_t ret;
+ btc_msg_t msg = {0};
+ esp_ble_vendor_evt_param_t *evt_param = &param.vendor_hci_evt.param;
+ bool copy_param = false;
+
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BLE;
+ msg.act = ESP_GAP_BLE_VENDOR_HCI_EVT;
+
+ param.vendor_hci_evt.subevt_code = subevt_code;
+ param.vendor_hci_evt.param_len = 0;
+ param.vendor_hci_evt.param_buf = NULL;
+ switch (subevt_code) {
+ case BLE_VENDOR_PDU_RECV_EVT:
+ param.vendor_hci_evt.subevt_code = ESP_BLE_VENDOR_PDU_RECV_EVT;
+ STREAM_TO_UINT8(evt_param->pdu_recv.type, params);
+ STREAM_TO_UINT8(evt_param->pdu_recv.handle, params);
+ STREAM_TO_UINT8(evt_param->pdu_recv.addr_type, params);
+ STREAM_TO_BDADDR(evt_param->pdu_recv.peer_addr, params);
+ break;
+ case BLE_VENDOR_CHMAP_UPDATE_EVT:
+ param.vendor_hci_evt.subevt_code = ESP_BLE_VENDOR_CHAN_MAP_UPDATE_EVT;
+ STREAM_TO_UINT8(evt_param->chan_map_update.status, params);
+ STREAM_TO_UINT16(evt_param->chan_map_update.conn_handle, params);
+ REVERSE_STREAM_TO_ARRAY(evt_param->chan_map_update.ch_map, params, ESP_GAP_BLE_CHANNELS_LEN);
+ break;
+ case BLE_VENDOR_SLEEP_WAKEUP_EVT:
+ param.vendor_hci_evt.subevt_code = ESP_BLE_VENDOR_SLEEP_WAKEUP_EVT;
+ // No parameters
+ break;
+ default:
+ copy_param = true;
+ break;
+ }
+
+ if (copy_param) {
+ param.vendor_hci_evt.param_len = param_len;
+ param.vendor_hci_evt.param_buf = (param_len) ? params : NULL;
+ ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy, btc_gap_ble_cb_deep_free);
+ } else {
+ ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
+ }
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+
void btc_get_whitelist_size(uint16_t *length)
{
BTM_BleGetWhiteListSize(length);
return;
}
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
static void btc_ble_start_scanning(uint32_t duration,
tBTA_DM_SEARCH_CBACK *results_cb,
tBTA_START_STOP_SCAN_CMPL_CBACK *start_scan_cb)
{
if ((results_cb != NULL) && (start_scan_cb != NULL)) {
-#if SCAN_QUEUE_CONGEST_CHECK
- btc_adv_list_refresh();
-#endif
//Start scan the device
BTA_DmBleScan(true, duration, results_cb, start_scan_cb);
} else {
@@ -1371,18 +1576,17 @@ static void btc_ble_stop_scanning(tBTA_START_STOP_SCAN_CMPL_CBACK *stop_scan_cb)
uint8_t duration = 0;
BTA_DmBleScan(false, duration, NULL, stop_scan_cb);
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
static void btc_ble_stop_advertising(tBTA_START_STOP_ADV_CMPL_CBACK *stop_adv_cb)
{
bool stop_adv = false;
BTA_DmBleBroadcast(stop_adv, stop_adv_cb);
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
-static void btc_ble_clear_advertising(tBTA_CLEAR_ADV_CMPL_CBACK *clear_adv_cb)
-{
- BTA_DmBleClearAdv(clear_adv_cb);
-}
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int,
uint16_t max_int, uint16_t latency, uint16_t timeout)
@@ -1491,7 +1695,7 @@ static void btc_gap_ble_set_channels(esp_gap_ble_channels channels)
BTA_DmBleSetChannels(channels, btc_gap_ble_set_channels_cmpl_callback);
}
-#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_DTM_TEST_EN == TRUE)
static void btc_ble_dtm_tx_start(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback)
{
BTA_DmBleDtmTxStart(tx_channel, len_of_data, pkt_payload, p_dtm_cmpl_cback);
@@ -1502,9 +1706,9 @@ static void btc_ble_dtm_rx_start(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_
BTA_DmBleDtmRxStart(rx_channel, p_dtm_cmpl_cback);
}
-#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
-#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
static void btc_ble_dtm_enhance_tx_start(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback)
{
BTA_DmBleDtmEnhTxStart(tx_channel, len_of_data, pkt_payload, phy, p_dtm_cmpl_cback);
@@ -1515,14 +1719,22 @@ static void btc_ble_dtm_enhance_rx_start(uint8_t rx_channel, uint8_t phy, uint8_
BTA_DmBleDtmEnhRxStart(rx_channel, phy, modulation_index, p_dtm_cmpl_cback);
}
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+void btc_get_periodic_list_size(uint8_t *size)
+{
+ BTM_BleGetPeriodicAdvListSize(size);
+ return;
+}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
static void btc_ble_dtm_stop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback)
{
BTA_DmBleDtmStop(p_dtm_cmpl_cback);
}
-
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
static void btc_ble_set_privacy_mode(uint8_t addr_type,
BD_ADDR addr,
uint8_t privacy_mode,
@@ -1549,6 +1761,7 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
case BTC_GAP_BLE_ACT_CFG_ADV_DATA: {
btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src;
btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *) p_dest;
@@ -1594,6 +1807,7 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
case BTC_GAP_BLE_SET_SECURITY_PARAM_EVT: {
btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src;
@@ -1647,6 +1861,7 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
break;
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW:
case BTC_GAP_BLE_CFG_EXT_SCAN_RSP_DATA_RAW: {
btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src;
@@ -1664,6 +1879,8 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
case BTC_GAP_BLE_CFG_PERIODIC_ADV_DATA_RAW: {
btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src;
btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest;
@@ -1680,6 +1897,8 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTC_GAP_BLE_EXT_ADV_START: {
btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src;
btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest;
@@ -1706,7 +1925,9 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_VENDOR_HCI_EN == TRUE)
case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT: {
btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src;
btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *)p_dest;
@@ -1720,6 +1941,7 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
case BTC_GAP_BLE_ACT_SET_DEV_NAME:{
btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src;
btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *)p_dest;
@@ -1756,6 +1978,18 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
+ case ESP_GAP_BLE_VENDOR_HCI_EVT: {
+ if (src->vendor_hci_evt.param_len) {
+ dst->vendor_hci_evt.param_buf = osi_malloc(src->vendor_hci_evt.param_len);
+ if (dst->vendor_hci_evt.param_buf) {
+ memcpy(dst->vendor_hci_evt.param_buf, src->vendor_hci_evt.param_buf,
+ src->vendor_hci_evt.param_len);
+ } else {
+ BTC_TRACE_ERROR("%s, malloc failed\n", __func__);
+ }
+ }
+ break;
+ }
default:
BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act);
break;
@@ -1767,6 +2001,7 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
BTC_TRACE_DEBUG("%s \n", __func__);
switch (msg->act) {
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
case BTC_GAP_BLE_ACT_CFG_ADV_DATA: {
esp_ble_adv_data_t *adv = &((btc_ble_gap_args_t *)msg->arg)->cfg_adv_data.adv_data;
if (adv->p_service_data) {
@@ -1796,6 +2031,7 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
}
break;
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
case BTC_GAP_BLE_SET_SECURITY_PARAM_EVT: {
uint8_t *value = ((btc_ble_gap_args_t *)msg->arg)->set_security_param.value;
@@ -1823,6 +2059,7 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
break;
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW:
case BTC_GAP_BLE_CFG_EXT_SCAN_RSP_DATA_RAW: {
uint8_t *value = ((btc_ble_5_gap_args_t *)msg->arg)->ext_adv_cfg_data.data;
@@ -1831,6 +2068,8 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
}
break;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
case BTC_GAP_BLE_CFG_PERIODIC_ADV_DATA_RAW: {
uint8_t *value = ((btc_ble_5_gap_args_t *)msg->arg)->periodic_adv_cfg_data.data;
if (value) {
@@ -1838,6 +2077,8 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
}
break;
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTC_GAP_BLE_EXT_ADV_START: {
esp_ble_gap_ext_adv_t *value = ((btc_ble_5_gap_args_t *)msg->arg)->ext_adv_start.ext_adv;
if (value) {
@@ -1852,7 +2093,9 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
}
break;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_VENDOR_HCI_EN == TRUE)
case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT: {
uint8_t *p_param_buf = ((btc_ble_gap_args_t *)msg->arg)->vendor_cmd_send.p_param_buf;
if (p_param_buf) {
@@ -1860,6 +2103,7 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
}
break;
}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
case BTC_GAP_BLE_ACT_SET_DEV_NAME:{
char *p_name = ((btc_ble_gap_args_t *)msg->arg)->set_dev_name.device_name;
if (p_name) {
@@ -1892,6 +2136,13 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg)
}
break;
}
+ case ESP_GAP_BLE_VENDOR_HCI_EVT: {
+ void *value = ((esp_ble_gap_cb_param_t *)msg->arg)->vendor_hci_evt.param_buf;
+ if (value) {
+ osi_free(value);
+ }
+ break;
+ }
default:
BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act);
break;
@@ -1909,6 +2160,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
switch (msg->act) {
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
case BTC_GAP_BLE_ACT_CFG_ADV_DATA: {
if (arg->cfg_adv_data.adv_data.set_scan_rsp == false) {
btc_ble_set_adv_data(&arg->cfg_adv_data.adv_data, btc_adv_data_callback);
@@ -1917,6 +2169,8 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
}
break;
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
case BTC_GAP_BLE_ACT_SET_SCAN_PARAM:
btc_ble_set_scan_params(&arg->set_scan_param.scan_params, btc_scan_params_callback);
break;
@@ -1926,15 +2180,15 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
case BTC_GAP_BLE_ACT_STOP_SCAN:
btc_ble_stop_scanning(btc_stop_scan_callback);
break;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
case BTC_GAP_BLE_ACT_START_ADV:
btc_ble_start_advertising(&arg->start_adv.adv_params, btc_start_adv_callback);
break;
case BTC_GAP_BLE_ACT_STOP_ADV:
btc_ble_stop_advertising(btc_stop_adv_callback);
break;
- case BTC_GAP_BLE_ACT_CLEAR_ADV:
- btc_ble_clear_advertising(btc_clear_adv_callback);
- break;
+#endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
case BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM:
btc_ble_update_conn_params(arg->conn_update_params.conn_params.bda,
@@ -1982,6 +2236,9 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
case BTC_GAP_BLE_ACT_READ_RSSI:
BTA_DmReadRSSI(arg->read_rssi.remote_addr, BTA_TRANSPORT_LE, btc_read_ble_rssi_cmpl_callback);
break;
+ case BTC_GAP_BLE_READ_CHANNEL_MAP:
+ BTA_DmBleReadChannelMap(arg->read_channel_map.bd_addr, btc_ble_read_channel_map_callback);
+ break;
#if (BLE_42_FEATURE_SUPPORT == TRUE)
case BTC_GAP_BLE_ACT_SET_CONN_PARAMS:
BTA_DmSetBlePrefConnParams(arg->set_conn_params.bd_addr, arg->set_conn_params.min_conn_int,
@@ -1996,6 +2253,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
BTA_DmGetDeviceName(btc_gap_ble_get_dev_name_callback, BT_DEVICE_TYPE_BLE);
break;
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW:
btc_ble_set_adv_data_raw(arg->cfg_adv_data_raw.raw_adv,
arg->cfg_adv_data_raw.raw_adv_len,
@@ -2006,6 +2264,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
arg->cfg_scan_rsp_data_raw.raw_scan_rsp_len,
btc_scan_rsp_data_raw_callback);
break;
+#endif // #if (BLE_42_ADV_EN == TRUE)
case BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST:
btc_ble_update_duplicate_exceptional_list(arg->update_duplicate_exceptional_list.subcode,
arg->update_duplicate_exceptional_list.info_type,
@@ -2151,6 +2410,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
arg_5->set_def_phy.rx_phy_mask,
arg_5->set_def_phy.phy_options);
break;
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case BTC_GAP_BLE_SET_EXT_ADV_RAND_ADDR:
BTA_DmBleGapExtAdvSetRandaddr(arg_5->ext_adv_set_rand_addr.instance, arg_5->ext_adv_set_rand_addr.rand_addr);
break;
@@ -2226,6 +2486,8 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
case BTC_GAP_BLE_EXT_ADV_SET_CLEAR:
BTA_DmBleGapExtAdvSetClear();
break;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
case BTC_GAP_BLE_SET_PERIODIC_ADV_PARAMS: {
tBTA_DM_BLE_Periodic_Adv_Params params = {0};
params.interval_min = arg_5->peridic_adv_set_params.params.interval_min;
@@ -2251,6 +2513,8 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_STOP");
BTA_DmBleGapPeriodicAdvEnable(FALSE, arg_5->periodic_adv_stop.instance);
break;
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
case BTC_GAP_BLE_PERIODIC_ADV_CREATE_SYNC: {
tBTA_DM_BLE_Periodic_Sync_Params params = {0};
params.filter_policy = arg_5->periodic_adv_create_sync.params.filter_policy;
@@ -2258,10 +2522,13 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
params.addr_type = arg_5->periodic_adv_create_sync.params.addr_type;
params.skip = arg_5->periodic_adv_create_sync.params.skip;
params.sync_timeout = arg_5->periodic_adv_create_sync.params.sync_timeout;
- #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
+#if (BLE_FEAT_CTE_EN == TRUE)
+ params.sync_cte_type = arg_5->periodic_adv_create_sync.params.sync_cte_type;
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
params.reports_disabled = arg_5->periodic_adv_create_sync.params.reports_disabled;
params.filter_duplicates = arg_5->periodic_adv_create_sync.params.filter_duplicates;
- #endif
+#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
memcpy(params.addr, arg_5->periodic_adv_create_sync.params.addr, sizeof(BD_ADDR));
BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_CREATE_SYNC");
@@ -2292,6 +2559,9 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_CLEAR_DEV");
BTA_DmBleGapPeriodicAdvClearDev();
break;
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
case BTC_GAP_BLE_SET_EXT_SCAN_PARAMS: {
tBTA_DM_BLE_EXT_SCAN_PARAMS params = {0};
params.own_addr_type = arg_5->set_ext_scan_params.params.own_addr_type;
@@ -2322,6 +2592,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
BTC_TRACE_DEBUG("BTC_GAP_BLE_STOP_EXT_SCAN");
BTA_DmBleGapExtScan(FALSE, 0, 0);
break;
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
case BTC_GAP_BLE_SET_EXT_PEFER_CONNET_PARAMS:
BTC_TRACE_DEBUG("BTC_GAP_BLE_SET_EXT_PEFER_CONNET_PARAMS");
BTA_DmBleGapPreferExtConnectParamsSet(arg_5->set_ext_conn_params.addr,
@@ -2355,35 +2626,81 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
(tBTA_DM_BLE_PAST_PARAMS *)&arg_5->set_periodic_adv_sync_trans_params.params);
break;
#endif
-#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_DTM_TEST_EN == TRUE)
case BTC_GAP_BLE_DTM_TX_START:
btc_ble_dtm_tx_start(arg->dtm_tx_start.tx_channel, arg->dtm_tx_start.len_of_data, arg->dtm_tx_start.pkt_payload, btc_dtm_tx_start_callback);
break;
case BTC_GAP_BLE_DTM_RX_START:
btc_ble_dtm_rx_start(arg->dtm_rx_start.rx_channel, btc_dtm_rx_start_callback);
break;
-#endif // if (BLE_42_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
case BTC_GAP_BLE_DTM_STOP:
btc_ble_dtm_stop(btc_dtm_stop_callback);
break;
-#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
+#if (BLE_50_DTM_TEST_EN == TRUE)
case BTC_GAP_BLE_DTM_ENH_TX_START:
btc_ble_dtm_enhance_tx_start(arg_5->dtm_enh_tx_start.tx_channel, arg_5->dtm_enh_tx_start.len_of_data, arg_5->dtm_enh_tx_start.pkt_payload, arg_5->dtm_enh_tx_start.phy, btc_dtm_tx_start_callback);
break;
case BTC_GAP_BLE_DTM_ENH_RX_START:
btc_ble_dtm_enhance_rx_start(arg_5->dtm_enh_rx_start.rx_channel, arg_5->dtm_enh_rx_start.phy, arg_5->dtm_enh_rx_start.modulation_index, btc_dtm_rx_start_callback);
break;
-#endif // if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+ case BTC_GAP_BLE_SET_PRIVACY_MODE:
+ btc_ble_set_privacy_mode(arg->set_privacy_mode.addr_type, arg->set_privacy_mode.addr,
+ arg->set_privacy_mode.privacy_mode, btc_ble_set_privacy_mode_callback);
+ break;
+#if (BLE_VENDOR_HCI_EN == TRUE)
+ case BTC_GAP_BLE_ACT_CLEAR_ADV:
+ BTA_DmBleClearAdv(btc_clear_adv_callback);
+ break;
case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT:
BTA_DmsendVendorHciCmd(arg->vendor_cmd_send.opcode,
arg->vendor_cmd_send.param_len,
arg->vendor_cmd_send.p_param_buf,
btc_ble_vendor_hci_cmd_complete_callback);
break;
- case BTC_GAP_BLE_SET_PRIVACY_MODE:
- btc_ble_set_privacy_mode(arg->set_privacy_mode.addr_type, arg->set_privacy_mode.addr,
- arg->set_privacy_mode.privacy_mode, btc_ble_set_privacy_mode_callback);
+ case BTC_GAP_BLE_SET_CSA_SUPPORT:
+ BTA_DmBleGapSetCsaSupport(arg->set_csa_support.csa_select, btc_ble_set_csa_support_callback);
+ break;
+ case BTC_GAP_BLE_ACT_SET_VENDOR_EVT_MASK:
+ BTA_DmBleGapSetVendorEventMask(arg->set_vendor_evt_mask.evt_mask, btc_ble_set_vendor_evt_mask_callback);
+ break;
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ case BTC_GAP_BLE_ENH_READ_TRANS_POWER_LEVEL:
+ BTA_DmBleGapEnhReadTransPwrLevel(arg_5->enh_read_trans_pwr_level.conn_handle, arg_5->enh_read_trans_pwr_level.phy);
+ break;
+ case BTC_GAP_BLE_READ_REM_TRANS_POWER_LEVEL:
+ BTA_DmBleGapReadRemoteTransPwrLevel(arg_5->read_rem_trans_pwr_level.conn_handle, arg_5->read_rem_trans_pwr_level.phy);
+ break;
+ case BTC_GAP_BLE_SET_PATH_LOSS_REPORT_PARAMS:
+ BTA_DmBleGapSetPathLossRptParams(arg_5->set_path_loss_rpt_params.conn_handle, arg_5->set_path_loss_rpt_params.high_threshold, arg_5->set_path_loss_rpt_params.high_hysteresis,
+ arg_5->set_path_loss_rpt_params.low_threshold, arg_5->set_path_loss_rpt_params.low_hysteresis, arg_5->set_path_loss_rpt_params.min_time_spent);
+ break;
+ case BTC_GAP_BLE_SET_PATH_LOSS_REPORTING_EN:
+ BTA_DmBleGapSetPathLossRptEnable(arg_5->set_path_loss_rpt_en.conn_handle, arg_5->set_path_loss_rpt_en.enable);
+ break;
+ case BTC_GAP_BLE_SET_TRANS_POWER_REPORTING_EN:
+ BTA_DmBleGapSetTransPwrRptEnable(arg_5->set_trans_pwr_rpting_en.conn_handle, arg_5->set_trans_pwr_rpting_en.local_enable, arg_5->set_trans_pwr_rpting_en.remote_enable);
+ break;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ case BTC_GAP_BLE_SET_DEFALT_SUBRATE:
+ BTA_DmBleGapSetDefaultSubrate(arg_5->default_subrate_param.subrate_min, arg_5->default_subrate_param.subrate_max, arg_5->default_subrate_param.max_latency,
+ arg_5->default_subrate_param.continuation_number, arg_5->default_subrate_param.supervision_timeout);
break;
+ case BTC_GAP_BLE_SUBRATE_REQUEST:
+ BTA_DmBleGapSubrateReqest(arg_5->subrate_req_param.conn_handle, arg_5->subrate_req_param.subrate_min, arg_5->subrate_req_param.subrate_max,
+ arg_5->subrate_req_param.max_latency, arg_5->subrate_req_param.continuation_number, arg_5->subrate_req_param.supervision_timeout);
+ break;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ case BTC_GAP_ACT_SET_HOST_FEATURE:
+ BTA_DmBleGapSetHostFeature(arg_5->set_host_feature_params.bit_num, arg_5->set_host_feature_params.bit_val);
+ break;
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
default:
break;
}
@@ -2399,11 +2716,15 @@ void btc_gap_callback_init(void)
#if (BLE_50_FEATURE_SUPPORT == TRUE)
BTM_BleGapRegisterCallback(btc_ble_5_gap_callback);
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_VENDOR_HCI_EN == TRUE)
+ BTM_BleRegisterVendorHciEventCallback(btc_ble_vendor_hci_event_callback);
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
}
bool btc_gap_ble_init(void)
{
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
p_env->adv_rpt_queue = pkt_queue_create();
assert(p_env->adv_rpt_queue != NULL);
@@ -2411,6 +2732,7 @@ bool btc_gap_ble_init(void)
p_env->adv_rpt_ready = osi_event_create(btc_gap_ble_adv_pkt_handler, NULL);
assert(p_env->adv_rpt_ready != NULL);
osi_event_bind(p_env->adv_rpt_ready, btc_get_current_thread(), BTC_GAP_BLE_ADV_RPT_QUEUE_IDX);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#endif
return true;
}
@@ -2418,6 +2740,7 @@ bool btc_gap_ble_init(void)
void btc_gap_ble_deinit(void)
{
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
osi_event_delete(p_env->adv_rpt_ready);
@@ -2425,105 +2748,11 @@ void btc_gap_ble_deinit(void)
pkt_queue_destroy(p_env->adv_rpt_queue, NULL);
p_env->adv_rpt_queue = NULL;
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
btc_cleanup_adv_data(&gl_bta_adv_data);
btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
+#endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
}
-
-#if SCAN_QUEUE_CONGEST_CHECK
-void btc_adv_list_free(void *data)
-{
- osi_free(data);
-}
-
-void btc_adv_list_init(void)
-{
- osi_mutex_new(&adv_list_lock);
- adv_filter_list = list_new(btc_adv_list_free);
-}
-
-void btc_adv_list_deinit(void)
-{
- osi_mutex_free(&adv_list_lock);
- if(adv_filter_list) {
- list_free(adv_filter_list);
- adv_filter_list = NULL;
- }
-}
-void btc_adv_list_add_packet(void * data)
-{
- if(!data) {
- BTC_TRACE_ERROR("%s data is NULL", __func__);
- return;
- }
- btc_adv_list_lock();
- list_prepend(adv_filter_list, data);
- btc_adv_list_unlock();
-}
-
-uint32_t btc_get_adv_list_length(void)
-{
- if(!adv_filter_list) {
- BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
- return 0;
- }
- btc_adv_list_lock();
- size_t length = list_length(adv_filter_list);
- btc_adv_list_unlock();
-
- return length;
-}
-
-void btc_adv_list_refresh(void)
-{
- if(!adv_filter_list) {
- BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
- return ;
- }
- btc_adv_list_lock();
- list_clear(adv_filter_list);
- btc_adv_list_unlock();
-}
-
-bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type)
-{
- bool found = false;
- if(!adv_filter_list || !addr) {
- BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
- return found;
- }
-
- btc_adv_list_lock();
- for (const list_node_t *node = list_begin(adv_filter_list); node != list_end(adv_filter_list); node = list_next(node)) {
- btc_adv_packet_t *packet = (btc_adv_packet_t *)list_node(node);
- if(!bdcmp(addr, packet->addr) && packet->addr_type == addr_type) {
- found = true;
- break;
- }
- }
- btc_adv_list_unlock();
- if(!found) {
- btc_adv_packet_t *adv_packet = osi_malloc(sizeof(btc_adv_packet_t));
- if(adv_packet) {
- adv_packet->addr_type = addr_type;
- bdcpy(adv_packet->addr, addr);
- btc_adv_list_add_packet(adv_packet);
- } else {
- BTC_TRACE_ERROR("%s adv_packet malloc failed", __func__);
- }
- }
- return found;
-}
-
-void btc_adv_list_lock(void)
-{
- osi_mutex_lock(&adv_list_lock, OSI_MUTEX_MAX_TIMEOUT);
-}
-
-void btc_adv_list_unlock(void)
-{
- osi_mutex_unlock(&adv_list_lock);
-}
-#endif
#endif ///BLE_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c
index 9e9d7b01..e1278954 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -24,14 +24,27 @@
#define BTC_STORAGE_FILL_PROPERTY(p_prop, t, l, p_v) \
(p_prop)->type = t;(p_prop)->len = l; (p_prop)->val = (p_v);
+typedef struct {
+ esp_bt_gap_discovery_state_t disc_stat;
+ esp_bt_connection_mode_t conn_mode;
+ esp_bt_discovery_mode_t disc_mode;
+ uint8_t bredr_acl_link_num;
+ uint16_t handle[MAX_ACL_CONNECTIONS];
+} gap_bt_local_param_t;
+
+#if BTC_GAP_BT_DYNAMIC_MEMORY == FALSE
+static gap_bt_local_param_t gap_bt_local_param;
+#else
+static gap_bt_local_param_t *gap_bt_local_param_ptr;
+#define gap_bt_local_param (*gap_bt_local_param_ptr)
+#endif
+
static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src);
static void search_service_record_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src);
-static bool btc_gap_bt_inquiry_in_progress = false;
-
static inline void btc_gap_bt_cb_to_app(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
esp_bt_gap_cb_t cb = (esp_bt_gap_cb_t)btc_profile_cb_get(BTC_PID_GAP_BT);
@@ -45,6 +58,9 @@ static void btc_bt_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discove
tBTA_DM_DISC disc_mode;
tBTA_DM_CONN conn_mode;
+ gap_bt_local_param.conn_mode = c_mode;
+ gap_bt_local_param.disc_mode = d_mode;
+
switch (c_mode) {
case ESP_BT_NON_CONNECTABLE:
conn_mode = BTA_DM_NON_CONN;
@@ -93,7 +109,7 @@ static void btc_gap_bt_start_discovery(btc_gap_bt_args_t *arg)
/* TODO: Filter device by BDA needs to be implemented here */
/* Will be enabled to TRUE once inquiry busy level has been received */
- btc_gap_bt_inquiry_in_progress = FALSE;
+ gap_bt_local_param.disc_stat = ESP_BT_GAP_DISCOVERY_STOPPED;
/* find nearby devices */
BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
@@ -374,7 +390,7 @@ static void btc_gap_bt_search_devices_evt(tBTA_DM_SEARCH_PARAM *p_data)
* if inquiry is in progress, then we don't want to act on this cancel_cmpl_evt
* but instead wait for the cancel_cmpl_evt_via the busy level
*/
- if (btc_gap_bt_inquiry_in_progress == false) {
+ if (gap_bt_local_param.disc_stat == ESP_BT_GAP_DISCOVERY_STOPPED) {
esp_bt_gap_cb_param_t param;
param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STOPPED;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
@@ -585,6 +601,7 @@ static void btc_gap_bt_set_cod(btc_gap_bt_args_t *arg)
{
tBTA_UTL_COD p_cod;
esp_bt_cod_t *cod = &(arg->set_cod.cod);
+ p_cod.reserved_2 = cod->reserved_2;
p_cod.minor = cod->minor << 2;
p_cod.major = cod->major;
p_cod.service = cod->service << 5;
@@ -602,6 +619,7 @@ esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod)
BTC_TRACE_ERROR("%s get class of device failed!",__func__);
return ESP_BT_STATUS_FAIL;
}
+ cod->reserved_2 = p_cod.reserved_2;
cod->minor = p_cod.minor >> 2;
cod->major = p_cod.major;
cod->service = p_cod.service >> 5;
@@ -1156,15 +1174,15 @@ void btc_gap_bt_busy_level_updated(uint8_t bl_flags)
if (bl_flags == BTM_BL_INQUIRY_STARTED) {
param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STARTED;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
- btc_gap_bt_inquiry_in_progress = true;
+ gap_bt_local_param.disc_stat = ESP_BT_GAP_DISCOVERY_STARTED;
} else if (bl_flags == BTM_BL_INQUIRY_CANCELLED) {
param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STOPPED;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
- btc_gap_bt_inquiry_in_progress = false;
+ gap_bt_local_param.disc_stat = ESP_BT_GAP_DISCOVERY_STOPPED;
} else if (bl_flags == BTM_BL_INQUIRY_COMPLETE) {
/* The Inquiry Complete event is not transported to app layer,
since the app only cares about the Name Discovery Complete event */
- btc_gap_bt_inquiry_in_progress = false;
+ gap_bt_local_param.disc_stat = ESP_BT_GAP_DISCOVERY_STOPPED;
}
}
@@ -1305,4 +1323,76 @@ void btc_gap_bt_cb_handler(btc_msg_t *msg)
}
btc_gap_bt_cb_deep_free(msg);
}
+
+void btc_gap_bt_init(void)
+{
+#if BTC_GAP_BT_DYNAMIC_MEMORY == TRUE
+ if ((gap_bt_local_param_ptr = (gap_bt_local_param_t *)osi_malloc(sizeof(gap_bt_local_param_t))) == NULL) {
+ BTC_TRACE_ERROR("%s malloc failed\n", __func__);
+ return;
+ }
+ memset((void *)gap_bt_local_param_ptr, 0, sizeof(gap_bt_local_param_t));
+#else
+ memset(&gap_bt_local_param, 0, sizeof(gap_bt_local_param_t));
+#endif
+}
+
+void btc_gap_bt_deinit(void)
+{
+#if BTC_GAP_BT_DYNAMIC_MEMORY == TRUE
+ if (gap_bt_local_param_ptr) {
+ osi_free(gap_bt_local_param_ptr);
+ gap_bt_local_param_ptr = NULL;
+ }
+#endif
+}
+
+static void btc_gap_bt_acl_link_handle_store(uint16_t handle)
+{
+ for (int i = 0; i < MAX_ACL_CONNECTIONS; i++) {
+ if (gap_bt_local_param.handle[i] == 0) {
+ gap_bt_local_param.handle[i] = handle;
+ gap_bt_local_param.bredr_acl_link_num++;
+ break;
+ }
+ }
+
+ if (gap_bt_local_param.bredr_acl_link_num > MAX_ACL_CONNECTIONS) {
+ assert(0);
+ }
+}
+
+static void btc_gap_bt_acl_link_handle_remove(uint16_t handle)
+{
+ for (int i = 0; i < MAX_ACL_CONNECTIONS; i++) {
+ if (gap_bt_local_param.handle[i] == handle) {
+ gap_bt_local_param.handle[i] = 0;
+ gap_bt_local_param.bredr_acl_link_num--;
+ break;
+ }
+ }
+
+ if (gap_bt_local_param.bredr_acl_link_num > MAX_ACL_CONNECTIONS) {
+ assert(0);
+ }
+}
+
+void btc_gap_bt_acl_link_num_update(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat)
+{
+ if (p_acl_link_stat->event == BTA_ACL_LINK_STAT_CONN_CMPL &&
+ p_acl_link_stat->link_act.conn_cmpl.status == HCI_SUCCESS) {
+ btc_gap_bt_acl_link_handle_store(p_acl_link_stat->link_act.conn_cmpl.handle);
+ } else if (p_acl_link_stat->event == BTA_ACL_LINK_STAT_DISCONN_CMPL) {
+ btc_gap_bt_acl_link_handle_remove(p_acl_link_stat->link_act.disconn_cmpl.handle);
+ }
+}
+
+void btc_gap_bt_status_get(esp_bt_gap_profile_status_t *param)
+{
+ param->disc_stat = gap_bt_local_param.disc_stat;
+ param->conn_mode = gap_bt_local_param.conn_mode;
+ param->disc_mode = gap_bt_local_param.disc_mode;
+ param->bredr_acl_link_num = gap_bt_local_param.bredr_acl_link_num;
+}
+
#endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c b/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c
index bca8ea66..9d4d108b 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c
@@ -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
*/
@@ -82,23 +82,6 @@ void btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src)
/*******************************************************************************
* BTC -> BTA conversion functions
*******************************************************************************/
-
-void btc_to_bta_uuid(tBT_UUID *p_dest, esp_bt_uuid_t *p_src)
-{
- p_dest->len = p_src->len;
- if (p_src->len == LEN_UUID_16) {
- p_dest->uu.uuid16 = p_src->uuid.uuid16;
- } else if (p_src->len == LEN_UUID_32) {
- p_dest->uu.uuid32 = p_src->uuid.uuid32;
- } else if (p_src->len == LEN_UUID_128) {
- memcpy(&p_dest->uu.uuid128, p_src->uuid.uuid128, p_dest->len);
- } else if (p_src->len == 0) {
- /* do nothing for now, there's some scenario will input 0 */
- } else {
- BTC_TRACE_ERROR("%s UUID len is invalid %d\n", __func__, p_src->len);
- }
-}
-
void btc_to_bta_gatt_id(tBTA_GATT_ID *p_dest, esp_gatt_id_t *p_src)
{
p_dest->inst_id = p_src->inst_id;
@@ -115,23 +98,6 @@ void btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID *p_dest, esp_gatt_srvc_id_t *p_src)
/*******************************************************************************
* BTA -> BTC conversion functions
*******************************************************************************/
-void bta_to_btc_uuid(esp_bt_uuid_t *p_dest, tBT_UUID *p_src)
-{
- p_dest->len = p_src->len;
- if (p_src->len == LEN_UUID_16) {
- p_dest->uuid.uuid16 = p_src->uu.uuid16;
- } else if (p_src->len == LEN_UUID_32) {
- p_dest->uuid.uuid32 = p_src->uu.uuid32;
- } else if (p_src->len == LEN_UUID_128) {
- memcpy(&p_dest->uuid.uuid128, p_src->uu.uuid128, p_dest->len);
- } else if (p_src->len == 0) {
- /* do nothing for now, there's some scenario will input 0
- such as, receive notify, the descriptor may be 0 */
- } else {
- BTC_TRACE_ERROR("%s UUID len is invalid %d\n", __func__, p_src->len);
- }
-}
-
void bta_to_btc_gatt_id(esp_gatt_id_t *p_dest, tBTA_GATT_ID *p_src)
{
p_dest->inst_id = p_src->inst_id;
diff --git a/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c b/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c
index e69eed48..86221e3c 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c
@@ -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
@@ -212,9 +212,12 @@ static void btc_gattc_app_unregister(btc_ble_gattc_args_t *arg)
static void btc_gattc_open(btc_ble_gattc_args_t *arg)
{
tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
- BTA_GATTC_Open(arg->open.gattc_if, arg->open.remote_bda,
+
+ BTA_GATTC_Enh_Open(arg->open.gattc_if, arg->open.remote_bda,
arg->open.remote_addr_type, arg->open.is_direct,
- transport, arg->open.is_aux);
+ transport, arg->open.is_aux, arg->open.own_addr_type,
+ arg->open.phy_mask, (void *)&arg->open.phy_1m_conn_params,
+ (void *)&arg->open.phy_2m_conn_params, (void *)&arg->open.phy_coded_conn_params);
}
static void btc_gattc_close(btc_ble_gattc_args_t *arg)
diff --git a/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c b/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c
index df9a4ceb..7eab806e 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -469,7 +469,7 @@ static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gat
if(gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_16 &&
gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_32 &&
gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_128) {
- BTC_TRACE_ERROR("%s, The Charateristic uuid length = %d is invalid", __func__,\
+ BTC_TRACE_ERROR("%s, The Characteristic uuid length = %d is invalid", __func__,\
gatts_attr_db[i+1].att_desc.uuid_length);
return ESP_GATT_INVALID_ATTR_LEN;
}
@@ -481,7 +481,7 @@ static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gat
uuid == ESP_GATT_UUID_CHAR_SRVR_CONFIG || uuid == ESP_GATT_UUID_CHAR_PRESENT_FORMAT ||
uuid == ESP_GATT_UUID_CHAR_AGG_FORMAT || uuid == ESP_GATT_UUID_CHAR_VALID_RANGE ||
uuid == ESP_GATT_UUID_EXT_RPT_REF_DESCR || uuid == ESP_GATT_UUID_RPT_REF_DESCR) {
- BTC_TRACE_ERROR("%s, The charateristic value uuid = %d is invalid", __func__, uuid);
+ BTC_TRACE_ERROR("%s, The characteristic value uuid = %d is invalid", __func__, uuid);
return ESP_GATT_INVALID_PDU;
}
}
@@ -694,6 +694,7 @@ void btc_gatts_call_handler(btc_msg_t *msg)
}
param.rsp.status = 0;
+ param.rsp.conn_id = BTC_GATT_GET_CONN_ID(arg->send_rsp.conn_id);
btc_gatts_cb_to_app(ESP_GATTS_RESPONSE_EVT, BTC_GATT_GET_GATT_IF(arg->send_rsp.conn_id), &param);
break;
}
diff --git a/lib/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c b/lib/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c
index 6000f832..2f095ab3 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c
@@ -35,9 +35,11 @@
* CONST
********************************************************************************/
#if (BTM_SCO_HCI_INCLUDED == TRUE)
+#if (BTC_HFP_EXT_CODEC == FALSE)
#include "oi_codec_sbc.h"
#include "oi_status.h"
#include "sbc_encoder.h"
+#endif
#if (PLC_INCLUDED == TRUE)
#include "sbc_plc.h"
@@ -58,21 +60,39 @@ static bta_hf_ct_plc_t *bta_hf_ct_plc_ptr;
#define HF_SBC_DEC_RAW_DATA_SIZE 240
#define HF_SBC_ENC_RAW_DATA_SIZE 240
+// H2: Header with synchronization word and sequence number
+#define BTA_HF_H2_HEADER_SYNC_WORD 0x0801
+#define BTA_HF_H2_HEADER_SYNC_WORD_MASK 0x0FFF
+#define BTA_HF_H2_HEADER_BIT0_MASK (1 << 0)
+#define BTA_HF_H2_HEADER_BIT1_MASK (1 << 1)
+#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
+#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
+#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
+#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
+
+#define BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p) ((*((uint16_t *)p) & BTA_HF_H2_HEADER_SYNC_WORD_MASK) == BTA_HF_H2_HEADER_SYNC_WORD)
+
/* BTA-AG-CO control block to map bdaddr to BTA handle */
typedef struct
{
+#if (BTC_HFP_EXT_CODEC == FALSE)
OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
OI_UINT32 decoder_context_data[HF_SBC_DEC_CONTEXT_DATA_LEN];
OI_INT16 decode_raw_data[HF_SBC_DEC_RAW_DATA_SIZE];
SBC_ENC_PARAMS encoder;
-
UINT8 sequence_number;
bool is_bad_frame;
bool decode_first_pkt;
- OI_BYTE decode_msbc_data[BTM_MSBC_FRAME_SIZE];
bool encode_first_pkt;
+ OI_BYTE decode_msbc_data[BTM_MSBC_FRAME_SIZE];
OI_BYTE encode_msbc_data[BTM_MSBC_FRAME_SIZE];
+#else
+ UINT8 sequence_number;
+ BOOLEAN rx_first_pkt;
+ BOOLEAN is_bad_frame;
+ UINT8 rx_half_msbc_data[BTM_MSBC_FRAME_SIZE/2];
+#endif
} bta_ag_co_cb_t;
#if HFP_DYNAMIC_MEMORY == FALSE
@@ -151,7 +171,7 @@ void bta_ag_ci_rx_write(UINT16 handle, char *p_data, UINT16 len)
** Function bta_ag_ci_slc_ready
**
** Description This function is called to notify AG that SLC is up at
-** the application. This funcion is only used when the app
+** the application. This function is only used when the app
** is running in pass-through mode.
**
** Returns void
@@ -179,18 +199,9 @@ void bta_ag_ci_slc_ready(UINT16 handle)
** Returns void
**
*******************************************************************************/
-static void bta_ag_h2_header(UINT16 *p_buf)
+void bta_ag_h2_header(UINT16 *p_buf)
{
- // H2: Header with synchronization word and sequence number
-#define BTA_HF_H2_HEADER 0x0801
-#define BTA_HF_H2_HEADER_BIT0_MASK (1 << 0)
-#define BTA_HF_H2_HEADER_BIT1_MASK (1 << 1)
-#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
-#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
-#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
-#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
-
- UINT16 h2_header = BTA_HF_H2_HEADER;
+ UINT16 h2_header = BTA_HF_H2_HEADER_SYNC_WORD;
UINT8 h2_header_sn0 = bta_ag_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT0_MASK;
UINT8 h2_header_sn1 = bta_ag_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT1_MASK;
h2_header |= (h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET1
@@ -202,6 +213,19 @@ static void bta_ag_h2_header(UINT16 *p_buf)
*p_buf = h2_header;
}
+#if (BTC_HFP_EXT_CODEC == TRUE)
+
+static void bta_ag_pkt_state_reset(void)
+{
+ bta_ag_co_cb.sequence_number = 0;
+ bta_ag_co_cb.rx_first_pkt = TRUE;
+ bta_ag_co_cb.is_bad_frame = FALSE;
+}
+
+#endif
+
+#if (BTC_HFP_EXT_CODEC == FALSE)
+
/*******************************************************************************
**
** Function bta_hf_dec_init
@@ -217,6 +241,7 @@ static void bta_hf_dec_init(void)
sbc_plc_init(&(bta_hf_ct_plc.plc_state));
#endif ///(PLC_INCLUDED == TRUE)
+
OI_STATUS status = OI_CODEC_SBC_DecoderReset(&bta_ag_co_cb.decoder_context, bta_ag_co_cb.decoder_context_data,
HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE);
if (!OI_SUCCESS(status)) {
@@ -326,15 +351,21 @@ static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad
APPL_TRACE_ERROR("Frame decode error: %d", status);
break;
}
-#endif ///(PLC_INCLUDED == TRUE)
if (OI_SUCCESS(status)) {
btc_hf_incoming_data_cb_to_app((const uint8_t *)(bta_hf_ct_plc.sbc_plc_out), sbc_raw_data_size);
}
+#else
+ if (OI_SUCCESS(status)) {
+ btc_hf_incoming_data_cb_to_app((const uint8_t *)(bta_ag_co_cb.decode_raw_data), sbc_raw_data_size);
+ }
+#endif
}
+#endif
+
/*******************************************************************************
- * BTA AG SCO CO FUNCITONS
+ * BTA AG SCO CO FUNCTIONS
********************************************************************************/
/*******************************************************************************
**
@@ -418,8 +449,12 @@ void bta_ag_sco_co_open(UINT16 handle, tBTM_SCO_AIR_MODE_TYPE air_mode, UINT8 in
}
#endif ///(PLC_INCLUDED == TRUE)
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
+#if (BTC_HFP_EXT_CODEC == TRUE)
+ bta_ag_pkt_state_reset();
+#else
bta_hf_dec_init();
bta_hf_enc_init();
+#endif
return;
} else {
return; // Nothing to do
@@ -476,6 +511,8 @@ void bta_ag_sco_co_close(void)
hf_inout_pkt_size = 0;
}
+#if (BTC_HFP_EXT_CODEC == FALSE)
+
/*******************************************************************************
**
** Function bta_ag_sco_co_out_data
@@ -525,7 +562,7 @@ uint32_t bta_ag_sco_co_out_data(UINT8 *p_buf)
//Never run to here.
}
} else {
- APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
+ APPL_TRACE_ERROR("%s invalid air mode: %d", __FUNCTION__, hf_air_mode);
}
return 0;
}
@@ -546,6 +583,65 @@ void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
STREAM_SKIP_UINT16(p);
STREAM_TO_UINT8(pkt_size, p);
+#if (BTC_HFP_EXT_CODEC == TRUE)
+ if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
+ btc_hf_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, pkt_size, status != BTM_SCO_DATA_CORRECT);
+ }
+ else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
+ if (pkt_size != hf_inout_pkt_size) {
+ bta_ag_co_cb.is_bad_frame = true;
+ }
+ if (status != BTM_SCO_DATA_CORRECT) {
+ bta_ag_co_cb.is_bad_frame = true;
+ }
+ if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
+ if (pkt_size > BTM_MSBC_FRAME_SIZE / 2) {
+ pkt_size = BTM_MSBC_FRAME_SIZE / 2;
+ }
+ if (bta_ag_co_cb.rx_first_pkt){
+ memcpy(bta_ag_co_cb.rx_half_msbc_data, p, pkt_size);
+ osi_free(p_buf);
+ } else {
+ BT_HDR *p_new_buf = osi_calloc(sizeof(BT_HDR) + BTM_MSBC_FRAME_SIZE);
+ p_new_buf->offset = 0;
+ UINT8 *p_data = (UINT8 *)(p_new_buf + 1) + p_new_buf->offset;
+ memcpy(p_data, bta_ag_co_cb.rx_half_msbc_data, BTM_MSBC_FRAME_SIZE / 2);
+ memcpy(p_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
+ osi_free(p_buf);
+ if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p_data)) {
+ /* H2 header sync word found, skip */
+ p_data += 2;
+ }
+ else if (!bta_ag_co_cb.is_bad_frame){
+ /* not a bad frame, assume as H1 header */
+ p_data += 1;
+ }
+ btc_hf_audio_data_cb_to_app((uint8_t *)p_new_buf, (uint8_t *)p_data, BTM_MSBC_FRAME_SIZE, bta_ag_co_cb.is_bad_frame);
+ bta_ag_co_cb.is_bad_frame = false;
+ memset(bta_ag_co_cb.decode_msbc_data, 0, BTM_MSBC_FRAME_SIZE);
+ }
+ bta_ag_co_cb.rx_first_pkt = !bta_ag_co_cb.rx_first_pkt;
+ }
+ else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
+ if (pkt_size > BTM_MSBC_FRAME_SIZE) {
+ pkt_size = BTM_MSBC_FRAME_SIZE;
+ }
+ if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p)) {
+ /* H2 header sync word found, skip */
+ p += 2;
+ }
+ else if (!bta_ag_co_cb.is_bad_frame){
+ /* not a bad frame, assume as H1 header */
+ p += 1;
+ }
+ btc_hf_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, pkt_size, bta_ag_co_cb.is_bad_frame);
+ bta_ag_co_cb.is_bad_frame = false;
+ }
+ else {
+ osi_free(p_buf);
+ }
+ }
+#else
if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
// CVSD
if(status != BTM_SCO_DATA_CORRECT) {
@@ -583,8 +679,12 @@ void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
//Never run to here.
}
} else {
- APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
+ APPL_TRACE_ERROR("%s invalid air mode: %d", __FUNCTION__, hf_air_mode);
}
+ osi_free(p_buf);
+#endif
}
+#endif
+
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c b/lib/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c
index 99f7a19f..b7df3635 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -236,12 +236,15 @@ static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *param)
else if (BTA_AG_OPEN_EVT == event) {
param_len = sizeof(tBTA_AG_OPEN);
}
- else if ((BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event)) {
+ else if ((BTA_AG_CLOSE_EVT == event)) {
param_len = sizeof(tBTA_AG_HDR);
}
else if (BTA_AG_CONN_EVT == event) {
param_len = sizeof(tBTA_AG_CONN);
}
+ else if ((BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event) || (BTA_AG_AUDIO_MSBC_OPEN_EVT == event)) {
+ param_len = sizeof(tBTA_AG_AUDIO_STAT);
+ }
else if (param) {
param_len = sizeof(tBTA_AG_VAL);
}
@@ -265,6 +268,26 @@ void btc_hf_reg_data_cb(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_
hf_local_param[0].btc_hf_outgoing_data_cb = send;
}
+void btc_hf_reg_audio_data_cb(esp_hf_ag_audio_data_cb_t callback)
+{
+ hf_local_param[0].btc_hf_audio_data_cb = callback;
+}
+
+void btc_hf_audio_data_cb_to_app(uint8_t *buf, uint8_t *data, uint16_t len, bool is_bad_frame)
+{
+ if (hf_local_param[0].btc_hf_audio_data_cb) {
+ /* we always have sizeof(BT_HDR) bytes free space before data, it is enough for esp_hf_audio_buff_t */
+ esp_hf_audio_buff_t *audio_buff = (esp_hf_audio_buff_t *)buf;
+ audio_buff->buff_size = len;
+ audio_buff->data_len = len;
+ audio_buff->data = data;
+ hf_local_param[0].btc_hf_audio_data_cb(hf_local_param[0].btc_hf_cb.sync_conn_hdl, audio_buff, is_bad_frame);
+ }
+ else {
+ osi_free(buf);
+ }
+}
+
void btc_hf_incoming_data_cb_to_app(const uint8_t *data, uint32_t len)
{
int idx = 0;
@@ -316,6 +339,19 @@ bt_status_t btc_hf_init(void)
{
int idx = 0;
+#if HFP_DYNAMIC_MEMORY == TRUE
+ if (hf_local_param)
+#endif
+ {
+ if (hf_local_param[idx].btc_hf_cb.initialized) {
+ esp_hf_cb_param_t param = {
+ .prof_stat.state = ESP_HF_INIT_ALREADY,
+ };
+ btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, &param);
+ return BT_STATUS_SUCCESS;
+ }
+ }
+
BTC_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btc_max_hf_clients);
#if HFP_DYNAMIC_MEMORY == TRUE
@@ -338,8 +374,9 @@ bt_status_t btc_hf_init(void)
#endif
clear_phone_state();
memset(&hf_local_param[idx].btc_hf_cb, 0, sizeof(btc_hf_cb_t));
- // custom initialization here
- hf_local_param[idx].btc_hf_cb.initialized = true;
+ for (int i = 0; i < BTC_HF_NUM_CB; i++) {
+ hf_local_param[i].btc_hf_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE;
+ }
// set audio path
#if (BT_CONTROLLER_INCLUDED == TRUE)
#if BTM_SCO_HCI_INCLUDED
@@ -349,14 +386,30 @@ bt_status_t btc_hf_init(void)
#endif
esp_bredr_sco_datapath_set(data_path);
#endif
+
return BT_STATUS_SUCCESS;
}
void btc_hf_deinit(void)
{
BTC_TRACE_EVENT("%s", __FUNCTION__);
+
+ int idx = 0;
+
+#if HFP_DYNAMIC_MEMORY == TRUE
+ if (hf_local_param)
+#endif
+ {
+ if (!hf_local_param[idx].btc_hf_cb.initialized) {
+ esp_hf_cb_param_t param = {
+ .prof_stat.state = ESP_HF_DEINIT_ALREADY,
+ };
+ btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, &param);
+ return;
+ }
+ }
+
btc_dm_disable_service(BTA_HFP_SERVICE_ID);
- hf_local_param[0].btc_hf_cb.initialized = false;
}
static void btc_hf_cb_release(void)
@@ -922,6 +975,20 @@ bt_status_t btc_hf_ci_sco_data(void)
return status;
}
+bool btc_hf_ag_audio_data_send(uint16_t sync_conn_hdl, uint8_t *p_buff_start, uint8_t *p_data, uint8_t data_len)
+{
+#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
+ /* currently, sync_conn_hdl is not used */
+ int idx = btc_hf_latest_connected_idx();
+ CHECK_HF_SLC_CONNECTED(idx);
+ if (idx != BTC_HF_INVALID_IDX) {
+ BTA_AgAudioDataSend(hf_local_param[idx].btc_hf_cb.handle, p_buff_start, p_data, data_len);
+ return true;
+ }
+#endif
+ return false;
+}
+
/************************************************************************************
** Memory malloc and release
************************************************************************************/
@@ -1239,6 +1306,13 @@ void btc_hf_call_handler(btc_msg_t *msg)
btc_hf_reg_data_cb(arg->reg_data_cb.recv, arg->reg_data_cb.send);
break;
}
+
+ case BTC_HF_REGISTER_AUDIO_DATA_CALLBACK_EVT:
+ {
+ btc_hf_reg_audio_data_cb(arg->reg_audio_data_cb.callback);
+ break;
+ }
+
case BTC_HF_REQUEST_PKT_STAT_EVT:
{
btc_hf_pkt_stat_nums_get(arg->pkt_sync_hd.sync_conn_handle);
@@ -1268,7 +1342,18 @@ void btc_hf_cb_handler(btc_msg_t *msg)
break;
case BTA_AG_DISABLE_EVT:
{
- btc_hf_cb_release();
+ idx = 0;
+#if HFP_DYNAMIC_MEMORY == TRUE
+ if (hf_local_param)
+#endif
+ {
+ if (hf_local_param[idx].btc_hf_cb.initialized) {
+ hf_local_param[idx].btc_hf_cb.initialized = false;
+ btc_hf_cb_release();
+ param.prof_stat.state = ESP_HF_DEINIT_SUCCESS;
+ btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, &param);
+ }
+ }
break;
}
case BTA_AG_REGISTER_EVT:
@@ -1278,6 +1363,11 @@ void btc_hf_cb_handler(btc_msg_t *msg)
hf_local_param[idx].btc_hf_cb.handle = p_data->reg.hdr.handle;
BTC_TRACE_DEBUG("%s: BTA_AG_REGISTER_EVT," "hf_local_param[%d].btc_hf_cb.handle = %d",
__FUNCTION__, idx, hf_local_param[idx].btc_hf_cb.handle);
+ if (!hf_local_param[idx].btc_hf_cb.initialized) {
+ param.prof_stat.state = ESP_HF_INIT_SUCCESS;
+ btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, &param);
+ }
+ hf_local_param[idx].btc_hf_cb.initialized = true;
break;
}
@@ -1368,7 +1458,9 @@ void btc_hf_cb_handler(btc_msg_t *msg)
do {
param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED;
memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
+ hf_local_param[idx].btc_hf_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle;
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
+ param.audio_stat.preferred_frame_size = p_data->audio_stat.preferred_frame_size;
btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, &param);
} while(0);
break;
@@ -1381,7 +1473,9 @@ void btc_hf_cb_handler(btc_msg_t *msg)
do {
param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED_MSBC;
memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
+ hf_local_param[idx].btc_hf_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle;
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
+ param.audio_stat.preferred_frame_size = p_data->audio_stat.preferred_frame_size;
btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, &param);
} while (0);
break;
@@ -1392,6 +1486,7 @@ void btc_hf_cb_handler(btc_msg_t *msg)
CHECK_HF_IDX(idx);
do {
param.audio_stat.state = ESP_HF_AUDIO_STATE_DISCONNECTED;
+ hf_local_param[idx].btc_hf_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE;
memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t));
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, &param);
@@ -1623,4 +1718,26 @@ void btc_hf_cb_handler(btc_msg_t *msg)
break;
}
}
+
+void btc_hf_get_profile_status(esp_hf_profile_status_t *param)
+{
+ param->hfp_ag_inited = false; // Not initialized by default
+
+#if HFP_DYNAMIC_MEMORY == TRUE
+ if (hf_local_param)
+#endif
+ {
+ for (int idx = 0; idx < BTC_HF_NUM_CB; idx++) {
+ if (hf_local_param[idx].btc_hf_cb.initialized) {
+ param->hfp_ag_inited = true;
+ if (hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_SLC_CONNECTED) {
+ param->slc_conn_num++;
+ if (hf_local_param[idx].btc_hf_cb.sync_conn_hdl != ESP_INVALID_CONN_HANDLE) {
+ param->sync_conn_num++;
+ }
+ }
+ }
+ }
+ }
+}
#endif // #if (BTC_HF_INCLUDED == TRUE)
diff --git a/lib/bt/host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c b/lib/bt/host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c
index 555e7137..c785c739 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,9 +14,23 @@
#if (BTM_SCO_HCI_INCLUDED == TRUE)
+#if (BTC_HFP_EXT_CODEC == FALSE)
#include "oi_codec_sbc.h"
#include "oi_status.h"
#include "sbc_encoder.h"
+#endif
+
+// H2: Header with synchronization word and sequence number
+#define BTA_HF_H2_HEADER_SYNC_WORD 0x0801
+#define BTA_HF_H2_HEADER_SYNC_WORD_MASK 0x0FFF
+#define BTA_HF_H2_HEADER_BIT0_MASK (1 << 0)
+#define BTA_HF_H2_HEADER_BIT1_MASK (1 << 1)
+#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
+#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
+#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
+#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
+
+#define BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p) ((*((uint16_t *)p) & BTA_HF_H2_HEADER_SYNC_WORD_MASK) == BTA_HF_H2_HEADER_SYNC_WORD)
#if (PLC_INCLUDED == TRUE)
#include "sbc_plc.h"
@@ -44,18 +58,23 @@ static bta_hf_ct_plc_t *bta_hf_ct_plc_ptr;
/* BTA-HF-CO control block to map bdaddr to BTA handle */
typedef struct
{
+#if (BTC_HFP_EXT_CODEC == FALSE)
OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
OI_UINT32 decoder_context_data[HF_SBC_DEC_CONTEXT_DATA_LEN];
OI_INT16 decode_raw_data[HF_SBC_DEC_RAW_DATA_SIZE];
-
SBC_ENC_PARAMS encoder;
-
UINT8 sequence_number;
bool is_bad_frame;
bool decode_first_pkt;
- OI_BYTE decode_msbc_data[BTM_MSBC_FRAME_SIZE];
bool encode_first_pkt;
+ OI_BYTE decode_msbc_data[BTM_MSBC_FRAME_SIZE];
OI_BYTE encode_msbc_data[BTM_MSBC_FRAME_SIZE];
+#else
+ UINT8 sequence_number;
+ BOOLEAN rx_first_pkt;
+ BOOLEAN is_bad_frame;
+ UINT8 rx_half_msbc_data[BTM_MSBC_FRAME_SIZE/2];
+#endif
} bta_hf_client_co_cb_t;
#if HFP_DYNAMIC_MEMORY == FALSE
@@ -118,6 +137,8 @@ tBTA_HFP_SCO_ROUTE_TYPE bta_hf_client_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
return BTA_HFP_SCO_ROUTE_HCI;
}
+#if (BTC_HFP_EXT_CODEC == FALSE)
+
/*******************************************************************************
**
** Function bta_hf_dec_init
@@ -168,6 +189,19 @@ static void bta_hf_enc_init(void) {
SBC_Encoder_Init(&(bta_hf_client_co_cb.encoder));
}
+#endif
+
+#if (BTC_HFP_EXT_CODEC == TRUE)
+
+void bta_hf_pkt_state_reset(void)
+{
+ bta_hf_client_co_cb.sequence_number = 0;
+ bta_hf_client_co_cb.rx_first_pkt = TRUE;
+ bta_hf_client_co_cb.is_bad_frame = FALSE;
+}
+
+#endif
+
/*******************************************************************************
**
** Function bta_hf_client_sco_co_open
@@ -204,8 +238,12 @@ void bta_hf_client_sco_co_open(UINT16 handle, UINT8 air_mode, UINT8 inout_pkt_si
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
+#if (BTC_HFP_EXT_CODEC == TRUE)
+ bta_hf_pkt_state_reset();
+#else
bta_hf_dec_init();
bta_hf_enc_init();
+#endif
return;
} else {
@@ -280,18 +318,9 @@ void bta_hf_client_sco_co_close(void)
** Returns void
**
*******************************************************************************/
-static void bta_hf_client_h2_header(UINT16 *p_buf)
+void bta_hf_client_h2_header(UINT16 *p_buf)
{
- // H2: Header with synchronization word and sequence number
-#define BTA_HF_H2_HEADER 0x0801
-#define BTA_HF_H2_HEADER_BIT0_MASK (1 << 0)
-#define BTA_HF_H2_HEADER_BIT1_MASK (1 << 1)
-#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
-#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
-#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
-#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
-
- UINT16 h2_header = BTA_HF_H2_HEADER;
+ UINT16 h2_header = BTA_HF_H2_HEADER_SYNC_WORD;
UINT8 h2_header_sn0 = bta_hf_client_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT0_MASK;
UINT8 h2_header_sn1 = bta_hf_client_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT1_MASK;
h2_header |= (h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET1
@@ -304,6 +333,8 @@ static void bta_hf_client_h2_header(UINT16 *p_buf)
*p_buf = h2_header;
}
+#if (BTC_HFP_EXT_CODEC == FALSE)
+
/*******************************************************************************
**
** Function bta_hf_client_sco_co_out_data
@@ -364,7 +395,7 @@ uint32_t bta_hf_client_sco_co_out_data(UINT8 *p_buf)
} else {
- APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
+ APPL_TRACE_ERROR("%s invalid air mode: %d", __FUNCTION__, hf_air_mode);
}
return 0;
}
@@ -439,6 +470,8 @@ static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN
}
}
+#endif
+
/*******************************************************************************
**
** Function bta_hf_client_sco_co_in_data
@@ -450,12 +483,77 @@ static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN
*******************************************************************************/
void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
{
+ if (hf_air_mode != BTM_SCO_AIR_MODE_CVSD && hf_air_mode != BTM_SCO_AIR_MODE_TRANSPNT) {
+ APPL_TRACE_ERROR("%s invalid air mode: %d", __FUNCTION__, hf_air_mode);
+ osi_free(p_buf);
+ return;
+ }
+
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
UINT8 pkt_size = 0;
STREAM_SKIP_UINT16(p);
STREAM_TO_UINT8 (pkt_size, p);
+#if (BTC_HFP_EXT_CODEC == TRUE)
+ if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
+ btc_hf_client_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, pkt_size, status != BTM_SCO_DATA_CORRECT);
+ }
+ else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
+ if (pkt_size != hf_inout_pkt_size) {
+ bta_hf_client_co_cb.is_bad_frame = true;
+ }
+ if (status != BTM_SCO_DATA_CORRECT) {
+ bta_hf_client_co_cb.is_bad_frame = true;
+ }
+ if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
+ if (pkt_size > BTM_MSBC_FRAME_SIZE / 2) {
+ pkt_size = BTM_MSBC_FRAME_SIZE / 2;
+ }
+ if (bta_hf_client_co_cb.rx_first_pkt){
+ memcpy(bta_hf_client_co_cb.rx_half_msbc_data, p, pkt_size);
+ osi_free(p_buf);
+ } else {
+ BT_HDR *p_new_buf = osi_calloc(sizeof(BT_HDR) + BTM_MSBC_FRAME_SIZE);
+ p_new_buf->offset = 0;
+ UINT8 *p_data = (UINT8 *)(p_new_buf + 1) + p_new_buf->offset;
+ memcpy(p_data, bta_hf_client_co_cb.rx_half_msbc_data, BTM_MSBC_FRAME_SIZE / 2);
+ memcpy(p_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
+ osi_free(p_buf);
+ if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p_data)) {
+ /* H2 header sync word found, skip */
+ p_data += 2;
+ }
+ else if (!bta_hf_client_co_cb.is_bad_frame){
+ /* not a bad frame, assume as H1 header */
+ p_data += 1;
+ }
+ btc_hf_client_audio_data_cb_to_app((uint8_t *)p_new_buf, (uint8_t *)p_data, BTM_MSBC_FRAME_SIZE, bta_hf_client_co_cb.is_bad_frame);
+ bta_hf_client_co_cb.is_bad_frame = false;
+ memset(bta_hf_client_co_cb.rx_half_msbc_data, 0, BTM_MSBC_FRAME_SIZE);
+ }
+ bta_hf_client_co_cb.rx_first_pkt = !bta_hf_client_co_cb.rx_first_pkt;
+ }
+ else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
+ if (pkt_size > BTM_MSBC_FRAME_SIZE) {
+ pkt_size = BTM_MSBC_FRAME_SIZE;
+ }
+ if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p)) {
+ /* H2 header sync word found, skip */
+ p += 2;
+ }
+ else if (!bta_hf_client_co_cb.is_bad_frame){
+ /* not a bad frame, assume as H1 header */
+ p += 1;
+ }
+ btc_hf_client_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, pkt_size, bta_hf_client_co_cb.is_bad_frame);
+ bta_hf_client_co_cb.is_bad_frame = false;
+ }
+ else {
+ osi_free(p_buf);
+ }
+ }
+#else
if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
// CVSD
if(status != BTM_SCO_DATA_CORRECT){
@@ -496,8 +594,10 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
//Never run to here.
}
} else {
- APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
+ APPL_TRACE_ERROR("%s invalid air mode: %d", __FUNCTION__, hf_air_mode);
}
+ osi_free(p_buf);
+#endif
}
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c b/lib/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c
index 67973bc2..cac3afb5 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -114,6 +114,7 @@ static inline void btc_hf_client_cb_to_app(esp_hf_client_cb_event_t event, esp_h
static void clear_state(void)
{
memset(&hf_client_local_param.btc_hf_client_cb, 0, sizeof(btc_hf_client_cb_t));
+ hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE;
}
static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
@@ -132,6 +133,26 @@ void btc_hf_client_reg_data_cb(esp_hf_client_incoming_data_cb_t recv,
hf_client_local_param.btc_hf_client_outgoing_data_cb = send;
}
+static void btc_hf_client_reg_audio_data_cb(esp_hf_client_audio_data_cb_t callback)
+{
+ hf_client_local_param.btc_hf_client_audio_data_cb = callback;
+}
+
+void btc_hf_client_audio_data_cb_to_app(uint8_t *buf, uint8_t *data, uint16_t len, bool is_bad_frame)
+{
+ if (hf_client_local_param.btc_hf_client_audio_data_cb) {
+ /* we always have sizeof(BT_HDR) bytes free space before data, it is enough for esp_hf_audio_buff_t */
+ esp_hf_audio_buff_t *audio_buff = (esp_hf_audio_buff_t *)buf;
+ audio_buff->buff_size = len;
+ audio_buff->data_len = len;
+ audio_buff->data = data;
+ hf_client_local_param.btc_hf_client_audio_data_cb(hf_client_local_param.btc_hf_client_cb.sync_conn_hdl, audio_buff, is_bad_frame);
+ }
+ else {
+ osi_free(buf);
+ }
+}
+
void btc_hf_client_incoming_data_cb_to_app(const uint8_t *data, uint32_t len)
{
// todo: critical section protection
@@ -169,12 +190,18 @@ bt_status_t btc_hf_client_init(void)
{
BTC_TRACE_EVENT("%s", __FUNCTION__);
+ if (hf_client_local_param.btc_hf_client_cb.initialized) {
+ esp_hf_client_cb_param_t param = {
+ .prof_stat.state = ESP_HF_INIT_ALREADY,
+ };
+ btc_hf_client_cb_to_app(ESP_HF_CLIENT_PROF_STATE_EVT, &param);
+ return BT_STATUS_SUCCESS;
+ }
+
btc_dm_enable_service(BTA_HFP_HS_SERVICE_ID);
clear_state();
- hf_client_local_param.btc_hf_client_cb.initialized = true;
-
#if (BT_CONTROLLER_INCLUDED == TRUE)
#if BTM_SCO_HCI_INCLUDED
uint8_t data_path = ESP_SCO_DATA_PATH_HCI;
@@ -232,9 +259,15 @@ void btc_hf_client_deinit( void )
{
BTC_TRACE_EVENT("%s", __FUNCTION__);
- btc_dm_disable_service(BTA_HFP_HS_SERVICE_ID);
+ if (!hf_client_local_param.btc_hf_client_cb.initialized) {
+ esp_hf_client_cb_param_t param = {
+ .prof_stat.state = ESP_HF_DEINIT_ALREADY,
+ };
+ btc_hf_client_cb_to_app(ESP_HF_CLIENT_PROF_STATE_EVT, &param);
+ return;
+ }
- hf_client_local_param.btc_hf_client_cb.initialized = false;
+ btc_dm_disable_service(BTA_HFP_HS_SERVICE_ID);
}
/*******************************************************************************
@@ -852,10 +885,21 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
switch (event)
{
case BTA_HF_CLIENT_ENABLE_EVT:
+ break;
case BTA_HF_CLIENT_DISABLE_EVT:
+ if (hf_client_local_param.btc_hf_client_cb.initialized) {
+ param.prof_stat.state = ESP_HF_DEINIT_SUCCESS,
+ btc_hf_client_cb_to_app(ESP_HF_CLIENT_PROF_STATE_EVT, &param);
+ }
+ hf_client_local_param.btc_hf_client_cb.initialized = false;
break;
case BTA_HF_CLIENT_REGISTER_EVT:
hf_client_local_param.btc_hf_client_cb.handle = p_data->reg.handle;
+ if (!hf_client_local_param.btc_hf_client_cb.initialized) {
+ param.prof_stat.state = ESP_HF_INIT_SUCCESS,
+ btc_hf_client_cb_to_app(ESP_HF_CLIENT_PROF_STATE_EVT, &param);
+ }
+ hf_client_local_param.btc_hf_client_cb.initialized = true;
break;
case BTA_HF_CLIENT_OPEN_EVT:
if (p_data->open.status == BTA_HF_CLIENT_SUCCESS)
@@ -1053,7 +1097,9 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED;
memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda,
sizeof(esp_bd_addr_t));
+ hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle;
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
+ param.audio_stat.preferred_frame_size = p_data->audio_stat.preferred_frame_size;
btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, &param);
} while (0);
break;
@@ -1062,7 +1108,9 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC;
memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda,
sizeof(esp_bd_addr_t));
+ hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle;
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
+ param.audio_stat.preferred_frame_size = p_data->audio_stat.preferred_frame_size;
btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, &param);
} while (0);
break;
@@ -1071,7 +1119,9 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED;
memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda,
sizeof(esp_bd_addr_t));
+ hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE;
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
+ param.audio_stat.preferred_frame_size = 0;
btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, &param);
} while (0);
break;
@@ -1160,6 +1210,9 @@ void btc_hf_client_call_handler(btc_msg_t *msg)
case BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT:
btc_hf_client_reg_data_cb(arg->reg_data_cb.recv, arg->reg_data_cb.send);
break;
+ case BTC_HF_CLIENT_REGISTER_AUDIO_DATA_CALLBACK_EVT:
+ btc_hf_client_reg_audio_data_cb(arg->reg_audio_data_cb.callback);
+ break;
case BTC_HF_CLIENT_SEND_NREC_EVT:
btc_hf_client_send_nrec();
break;
@@ -1177,4 +1230,24 @@ void btc_hf_client_call_handler(btc_msg_t *msg)
}
}
+void btc_hf_client_get_profile_status(esp_hf_client_profile_status_t *param)
+{
+ param->hf_client_inited = false; // Not initialized by default
+
+#if HFP_DYNAMIC_MEMORY == TRUE
+ if (hf_client_local_param_ptr)
+#endif
+ {
+ if (hf_client_local_param.btc_hf_client_cb.initialized) {
+ param->hf_client_inited = true;
+ if (hf_client_local_param.btc_hf_client_cb.state == ESP_HF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) {
+ param->slc_conn_num++;
+ if (hf_client_local_param.btc_hf_client_cb.sync_conn_hdl != ESP_INVALID_CONN_HANDLE) {
+ param->sync_conn_num++;
+ }
+ }
+ }
+ }
+}
+
#endif /* #if (BTC_HF_CLIENT_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c b/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c
index 0d99c030..82ff2b8d 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c
@@ -844,6 +844,7 @@ void btc_hd_cb_handler(btc_msg_t *msg)
// }
// btc_storage_set_hidd((bt_bdaddr_t *)&p_data->conn.bda);
btc_hd_cb.status = BTC_HD_CONNECTED;
+ btc_hd_cb.in_use = TRUE;
} else if (p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) {
btc_hd_cb.status = BTC_HD_DISCONNECTED;
}
@@ -903,14 +904,10 @@ void btc_hd_cb_handler(btc_msg_t *msg)
btc_hd_cb_to_app(ESP_HIDD_INTR_DATA_EVT, &param);
break;
case BTA_HD_VC_UNPLUG_EVT: {
- bt_bdaddr_t *bd_addr = (bt_bdaddr_t *)&p_data->conn.bda;
- if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) {
- BTC_TRACE_DEBUG("%s: Removing bonding as only HID profile connected", __func__);
- BTA_DmRemoveDevice((uint8_t *)&p_data->conn.bda, BT_TRANSPORT_BR_EDR);
- } else {
- BTC_TRACE_DEBUG("%s: Only removing HID data as some other profiles connected", __func__);
- btc_hd_remove_device(*bd_addr);
- }
+#if BTC_HID_REMOVE_DEVICE_BONDING
+ BTC_TRACE_DEBUG("%s: Removing bonding information", __func__);
+ BTA_DmRemoveDevice((uint8_t *)&p_data->conn.bda, BT_TRANSPORT_BR_EDR);
+#endif
if (btc_hd_cb.status == BTC_HD_DISCONNECTING || btc_hd_cb.status == BTC_HD_CONNECTING ||
btc_hd_cb.status == BTC_HD_CONNECTED) {
@@ -920,6 +917,8 @@ void btc_hd_cb_handler(btc_msg_t *msg)
btc_hd_cb_to_app(ESP_HIDD_CLOSE_EVT, &param);
}
+ btc_hd_cb.in_use = FALSE;
+
param.vc_unplug.status = p_data->conn.status;
param.vc_unplug.conn_status = p_data->conn.conn_status;
btc_hd_cb_to_app(ESP_HIDD_VC_UNPLUG_EVT, &param);
@@ -963,4 +962,22 @@ void btc_hd_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
}
+void btc_hd_get_profile_status(esp_hidd_profile_status_t *param)
+{
+ if (is_hidd_init()) {
+ param->hidd_inited = true;
+ if (btc_hd_cb.status == BTC_HD_CONNECTED) {
+ param->conn_num++;
+ }
+ if (btc_hd_cb.in_use) {
+ param->plug_vc_dev_num++;
+ }
+ if (btc_hd_cb.app_registered) {
+ param->reg_app_num++;
+ }
+ } else {
+ param->hidd_inited = false;
+ }
+}
+
#endif // HID_DEV_INCLUDED==TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c b/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c
index 1d6f2020..55fe3f69 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c
@@ -1372,7 +1372,10 @@ void btc_hh_cb_handler(btc_msg_t *msg)
*/
if (p_dev->local_vup) {
p_dev->local_vup = false;
+#if BTC_HID_REMOVE_DEVICE_BONDING
BTA_DmRemoveDevice(p_dev->bd_addr, BT_TRANSPORT_BR_EDR);
+#endif
+ btc_hh_remove_device(p_dev->bd_addr);
}
btc_hh_cb.status = (BTC_HH_STATUS)BTC_HH_DEV_DISCONNECTED;
@@ -1406,8 +1409,9 @@ void btc_hh_cb_handler(btc_msg_t *msg)
// [boblane]
if (p_dev->local_vup) {
p_dev->local_vup = false;
+#if BTC_HID_REMOVE_DEVICE_BONDING
BTA_DmRemoveDevice(p_dev->bd_addr, BT_TRANSPORT_BR_EDR);
- } else {
+#endif
btc_hh_remove_device(p_dev->bd_addr);
}
param.unplug.status = p_data->dev_status.status;
@@ -1571,4 +1575,21 @@ void btc_hh_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
}
+void btc_hh_get_profile_status(esp_hidh_profile_status_t *param)
+{
+ if (is_hidh_init()) {
+ param->hidh_inited = true;
+ if (btc_hh_cb.status == BTC_HH_DEV_CONNECTED) {
+ param->conn_num++;
+ }
+ for (int i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
+ if (memcmp(btc_hh_cb.added_devices[i].bd_addr, bd_addr_null, BD_ADDR_LEN) != 0) {
+ param->plug_vc_dev_num++;
+ }
+ }
+ } else {
+ param->hidh_inited = false;
+ }
+}
+
#endif // HID_HOST_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h b/lib/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h
index 63ca09a8..69fac9d6 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h
@@ -34,55 +34,48 @@ typedef enum {
SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server
SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client
SDP_TYPE_OPP_SERVER, // Object Push Profile
- SDP_TYPE_SAP_SERVER // SIM Access Profile
+ SDP_TYPE_SAP_SERVER, // SIM Access Profile
+ SDP_TYPE_DIP_SERVER, // Device Identification Profile
} bluetooth_sdp_types;
-typedef struct _bluetooth_sdp_hdr {
- bluetooth_sdp_types type;
- esp_bt_uuid_t uuid;
- uint32_t service_name_length;
- char *service_name;
- int32_t rfcomm_channel_number;
- int32_t l2cap_psm;
- int32_t profile_version;
-} bluetooth_sdp_hdr;
-
/**
* Some signals need additional pointers, hence we introduce a
* generic way to handle these pointers.
*/
typedef struct _bluetooth_sdp_hdr_overlay {
bluetooth_sdp_types type;
- esp_bt_uuid_t bt_uuid;
- 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;
+ 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;
+ int user1_ptr_len;
+ uint8_t *user1_ptr;
+ int user2_ptr_len; // not used
+ uint8_t *user2_ptr; // not used
} bluetooth_sdp_hdr_overlay;
+typedef struct _bluetooth_sdp_raw_record {
+ bluetooth_sdp_hdr_overlay hdr;
+} bluetooth_sdp_raw_record;
+
typedef struct _bluetooth_sdp_mas_record {
bluetooth_sdp_hdr_overlay hdr;
- uint32_t mas_instance_id;
- uint32_t supported_features;
- uint32_t supported_message_types;
+ 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;
+ 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;
+ uint32_t supported_features;
+ uint32_t supported_repositories;
} bluetooth_sdp_pse_record;
typedef struct _bluetooth_sdp_pce_record {
@@ -91,22 +84,33 @@ typedef struct _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];
+ 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_sap_record;
+typedef struct _bluetooth_sdp_dip_record {
+ bluetooth_sdp_hdr_overlay hdr;
+ uint16_t vendor;
+ uint16_t vendor_id_source;
+ uint16_t product;
+ uint16_t version;
+ bool primary_record;
+} bluetooth_sdp_dip_record;
+
typedef union {
- bluetooth_sdp_hdr_overlay hdr;
- bluetooth_sdp_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_overlay hdr;
+ bluetooth_sdp_raw_record raw;
+ bluetooth_sdp_mas_record mas;
+ bluetooth_sdp_mns_record mns;
+ bluetooth_sdp_pse_record pse;
+ bluetooth_sdp_pce_record pce;
+ bluetooth_sdp_ops_record ops;
+ bluetooth_sdp_sap_record sap;
+ bluetooth_sdp_dip_record dip;
} bluetooth_sdp_record;
#endif /* __BT_SDP_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h
index f7ce1cbc..3f0e79f8 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -23,6 +23,7 @@
/*******************************************************************************
** Data types
*******************************************************************************/
+#if (BTC_AV_EXT_CODEC == FALSE)
/* tBTC_MEDIA_INIT_AUDIO msg structure */
typedef struct {
@@ -50,6 +51,8 @@ typedef struct {
tBTC_AV_MEDIA_FEEDINGS feeding;
} tBTC_MEDIA_INIT_AUDIO_FEEDING;
+#endif
+
/*******************************************************************************
** Public functions
*******************************************************************************/
@@ -78,29 +81,6 @@ void btc_a2dp_source_shutdown(void);
/*******************************************************************************
**
- ** Function btc_a2dp_source_enc_init_req
- **
- ** Description Request to initialize the media task encoder
- **
- ** Returns TRUE is success
- **
- *******************************************************************************/
-BOOLEAN btc_a2dp_source_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg);
-
-/*******************************************************************************
- **
- ** Function btc_a2dp_source_enc_udpate_req
- **
- ** Description Request to update the media task encoder
- **
- ** Returns TRUE is success
- **
- *******************************************************************************/
-BOOLEAN btc_a2dp_source_enc_update_req(tBTC_MEDIA_UPDATE_AUDIO *p_msg);
-
-
-/*******************************************************************************
- **
** Function btc_a2dp_source_start_audio_req
**
** Description Request to start audio encoding task
@@ -112,28 +92,6 @@ BOOLEAN btc_a2dp_source_start_audio_req(void);
/*******************************************************************************
**
- ** Function btc_a2dp_source_stop_audio_req
- **
- ** Description Request to stop audio encoding task
- **
- ** Returns TRUE is success
- **
- *******************************************************************************/
-BOOLEAN btc_a2dp_source_stop_audio_req(void);
-
-/*******************************************************************************
- **
- ** Function btc_a2dp_source_tx_flush_req
- **
- ** Description Request to flush audio encoding pipe
- **
- ** Returns TRUE is success
- **
- *******************************************************************************/
-BOOLEAN btc_a2dp_source_tx_flush_req(void);
-
-/*******************************************************************************
- **
** Function btc_a2dp_source_audio_readbuf
**
** Description Read an audio buffer from the BTC media TX queue
@@ -145,27 +103,6 @@ BT_HDR *btc_a2dp_source_audio_readbuf(void);
/*******************************************************************************
**
- ** Function btc_a2dp_source_audio_feeding_init_req
- **
- ** Description Request to initialize audio feeding
- **
- ** Returns TRUE if success
- **
- *******************************************************************************/
-
-BOOLEAN btc_a2dp_source_audio_feeding_init_req(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_msg);
-
-/*******************************************************************************
- **
- ** Function btc_a2dp_source_is_streaming
- **
- ** Description Check whether A2DP source is in streaming state
- **
- *******************************************************************************/
-bool btc_a2dp_source_is_streaming(void);
-
-/*******************************************************************************
- **
** Function btc_a2dp_source_is_task_shutting_down
**
** Description Check whether A2DP source media task is shutting down
@@ -206,21 +143,23 @@ void btc_a2dp_source_on_suspended(tBTA_AV_SUSPEND *p_av);
/*******************************************************************************
**
- ** Function btc_a2dp_source_setup_codec
+ ** Function btc_a2dp_source_set_tx_flush
**
- ** Description initialize the encoder parameters
+ ** Description enable/disable discarding of transmitted frames
**
*******************************************************************************/
-void btc_a2dp_source_setup_codec(void);
+void btc_a2dp_source_set_tx_flush(BOOLEAN enable);
+
+#if (BTC_AV_EXT_CODEC == FALSE)
/*******************************************************************************
**
- ** Function btc_a2dp_source_set_tx_flush
+ ** Function btc_a2dp_source_setup_codec
**
- ** Description enable/disable discarding of transmitted frames
+ ** Description initialize the encoder parameters
**
*******************************************************************************/
-void btc_a2dp_source_set_tx_flush(BOOLEAN enable);
+void btc_a2dp_source_setup_codec(void);
/*******************************************************************************
**
@@ -231,6 +170,8 @@ void btc_a2dp_source_set_tx_flush(BOOLEAN enable);
*******************************************************************************/
void btc_a2dp_source_encoder_update(void);
+#endif
+
/*****************************************************************************
**
** Function btc_source_report_delay_value
@@ -240,6 +181,19 @@ void btc_a2dp_source_encoder_update(void);
*******************************************************************************/
void btc_source_report_delay_value(UINT16 delay_value);
+#if (BTC_AV_EXT_CODEC == TRUE)
+
+/*****************************************************************************
+**
+** Function btc_a2dp_source_enqueue_audio_frame
+**
+** Description Enqueue source audio frame to tx queue
+**
+*******************************************************************************/
+BOOLEAN btc_a2dp_source_enqueue_audio_frame(BT_HDR *p_buf);
+
+#endif
+
#endif /* #if BTC_AV_SRC_INCLUDED */
#endif /* __BTC_A2DP_SOURCE_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_av.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_av.h
index 3dd2ebe6..f23ff670 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_av.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_av.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -22,11 +22,21 @@
#include "btc/btc_task.h"
#include "btc/btc_common.h"
#include "btc/btc_sm.h"
+#include "btc_av_api.h"
#include "bta/bta_av_api.h"
+#include "bta/bta_av_sbc.h"
#if (BTC_AV_INCLUDED == TRUE)
-// global variable to inidcate avrc is initialized with a2dp
+#if (BTA_AV_CO_CP_SCMS_T == TRUE)
+#define BTC_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE + 1)
+#else
+#define BTC_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE)
+#endif
+
+#define BTC_AUDIO_BUFF_OFFSET BTC_MEDIA_AA_SBC_OFFSET
+
+// global variable to indicate avrc is initialized with a2dp
extern bool g_av_with_rc;
// global variable to indicate a2dp is initialized
extern bool g_a2dp_on_init;
@@ -51,21 +61,24 @@ typedef enum {
BTC_AV_DISCONNECT_REQ_EVT,
BTC_AV_START_STREAM_REQ_EVT,
BTC_AV_SUSPEND_STREAM_REQ_EVT,
- BTC_AV_SINK_CONFIG_REQ_EVT,
+ BTC_AV_CONFIG_EVT,
} btc_av_sm_event_t;
typedef enum {
#if BTC_AV_SINK_INCLUDED
BTC_AV_SINK_API_INIT_EVT = 0,
+ BTC_AV_SINK_API_REG_SEP_EVT,
BTC_AV_SINK_API_DEINIT_EVT,
BTC_AV_SINK_API_CONNECT_EVT,
BTC_AV_SINK_API_DISCONNECT_EVT,
BTC_AV_SINK_API_REG_DATA_CB_EVT,
+ BTC_AV_SINK_API_REG_AUDIO_DATA_CB_EVT,
BTC_AV_SINK_API_SET_DELAY_VALUE_EVT,
BTC_AV_SINK_API_GET_DELAY_VALUE_EVT,
#endif /* BTC_AV_SINK_INCLUDED */
#if BTC_AV_SRC_INCLUDED
BTC_AV_SRC_API_INIT_EVT,
+ BTC_AV_SRC_API_REG_SEP_EVT,
BTC_AV_SRC_API_DEINIT_EVT,
BTC_AV_SRC_API_CONNECT_EVT,
BTC_AV_SRC_API_DISCONNECT_EVT,
@@ -77,14 +90,14 @@ typedef enum {
/* btc_av_args_t */
typedef union {
#if BTC_AV_SINK_INCLUDED
- // BTC_AV_SINK_CONFIG_REQ_EVT -- internal event
- esp_a2d_mcc_t mcc;
// BTC_AV_SINK_API_CONNECT_EVT
bt_bdaddr_t connect;
// BTC_AV_SINK_API_DISCONNECT_EVT
bt_bdaddr_t disconn;
// BTC_AV_SINK_API_REG_DATA_CB_EVT
esp_a2d_sink_data_cb_t data_cb;
+ // BTC_AV_SINK_API_REG_AUDIO_DATA_CB_EVT
+ esp_a2d_sink_audio_data_cb_t audio_data_cb;
// BTC_AV_SINK_API_SET_DELAY_VALUE_EVT
uint16_t delay_value;
#endif /* BTC_AV_SINK_INCLUDED */
@@ -96,6 +109,13 @@ typedef union {
// BTC_AV_SRC_API_DISCONNECT_EVT
bt_bdaddr_t src_disconn;
#endif /* BTC_AV_SRC_INCLUDED */
+ // BTC_AV_CONFIG_EVT
+ esp_a2d_mcc_t mcc;
+ // BTC_AV_SINK_API_REG_SEP_EVT or BTC_AV_SRC_API_REG_SEP_EVT
+ struct {
+ uint8_t seid;
+ esp_a2d_mcc_t mcc;
+ } reg_sep;
// BTC_AV_API_MEDIA_CTRL_EVT
esp_a2d_media_ctrl_t ctrl;
} btc_av_args_t;
@@ -108,8 +128,36 @@ void btc_a2dp_call_handler(btc_msg_t *msg);
void btc_a2dp_cb_handler(btc_msg_t *msg);
+void btc_a2dp_get_profile_status(esp_a2d_profile_status_t *param);
+
void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback);
+/*******************************************************************************
+**
+** Function btc_a2dp_sink_reg_audio_data_cb
+**
+** Description Register a2dp sink audio data callback
+**
+** Returns None
+**
+*******************************************************************************/
+void btc_a2dp_sink_reg_audio_data_cb(esp_a2d_sink_audio_data_cb_t callback);
+
+#if (BTC_AV_EXT_CODEC == TRUE)
+
+/*******************************************************************************
+**
+** Function btc_av_codec_cap_get
+**
+** Description Get external codec capability
+**
+** Returns Pointer to codec capability
+**
+*******************************************************************************/
+tBTC_AV_CODEC_INFO *btc_av_codec_cap_get(void);
+
+#endif
+
void btc_a2dp_src_reg_data_cb(esp_a2d_source_data_cb_t callback);
/*******************************************************************************
**
@@ -172,6 +220,16 @@ void btc_dispatch_sm_event(btc_av_sm_event_t event, void *p_data, int len);
BOOLEAN btc_av_is_connected(void);
+/*******************************************************************************
+**
+** Function btc_av_is_started
+**
+** Description Checks if av is started
+**
+** Returns BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN btc_av_is_started(void);
/*******************************************************************************
*
@@ -225,4 +283,60 @@ uint8_t btc_av_get_service_id(void);
#endif ///BTC_AV_INCLUDED == TRUE
+/*******************************************************************************
+**
+** Function btc_a2d_conn_handle_get
+**
+** Description Get connection handle from btc_av_cb
+**
+** Returns Void
+**
+*******************************************************************************/
+uint16_t btc_a2d_conn_handle_get(void);
+
+/*******************************************************************************
+**
+** Function btc_av_audio_buff_alloc
+**
+** Description Allocate audio buffer with specific size
+**
+** Returns Void
+**
+*******************************************************************************/
+void btc_av_audio_buff_alloc(uint16_t size, uint8_t **pp_buff, uint8_t **pp_data);
+
+/*******************************************************************************
+**
+** Function btc_av_audio_buff_free
+**
+** Description Free audio buffer
+**
+** Returns Void
+**
+*******************************************************************************/
+void btc_av_audio_buff_free(uint8_t *p_buf);
+
+/*******************************************************************************
+**
+** Function btc_a2d_src_audio_mtu_check
+**
+** Description Checks if data length is valid, not bigger than mtu
+**
+** Returns BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN btc_a2d_src_audio_mtu_check(uint16_t data_len);
+
+/*******************************************************************************
+**
+** Function btc_a2d_src_audio_data_send
+**
+** Description Send audio data to lower layer, audio buffer is consumed
+** only when operation is success
+**
+** Returns BT_STATUS_SUCCESS if success, otherwise, BT_STATUS_FAIL
+**
+*******************************************************************************/
+bt_status_t btc_a2d_src_audio_data_send(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf);
+
#endif /* __BTC_AV_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_av_api.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_av_api.h
index 72ee3bb7..57d14fbf 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_av_api.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_av_api.h
@@ -23,6 +23,9 @@
#include "stack/a2d_sbc.h"
#if (BTC_AV_INCLUDED == TRUE)
+#ifdef __cplusplus
+extern "C" {
+#endif
/*****************************************************************************
** Constants and data types
*****************************************************************************/
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h
index 83200ae1..c44a5e48 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h
@@ -37,9 +37,17 @@ typedef enum {
BTC_AVRC_STATUS_API_SND_META_EVT,
BTC_AVRC_STATUS_API_SND_PLAY_STATUS_EVT,
BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT,
+ BTC_AVRC_STATUS_API_SND_GET_PLAY_STATUS_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 {
@@ -69,6 +77,10 @@ typedef struct {
uint8_t tl;
} get_caps_cmd_t;
+typedef struct {
+ uint8_t tl;
+} get_play_status_cmd_t;
+
#define BTC_AVRC_MIN_VOLUME 0x00
#define BTC_AVRC_MAX_VOLUME 0x7f
@@ -77,6 +89,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;
@@ -84,7 +118,14 @@ typedef union {
rn_cmd_t rn_cmd;
ps_cmd_t ps_cmd;
get_caps_cmd_t get_caps_cmd;
+ get_play_status_cmd_t get_play_status_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 +165,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 +206,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 +225,8 @@ 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);
+void btc_avrc_get_profile_status(esp_avrc_profile_status_t *param);
#endif ///BTC_AV_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h
new file mode 100644
index 00000000..659bfb31
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h
@@ -0,0 +1,98 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __BTC_CTE_BLE_H__
+#define __BTC_CTE_BLE_H__
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#include "esp_bt_defs.h"
+#include "esp_ble_cte_api.h"
+#include "btc/btc_manage.h"
+
+typedef enum {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ BTC_CTE_ACT_SET_TRANS_PARAMS,
+ BTC_CTE_ACT_SET_TRANS_ENABLE,
+ BTC_CTE_ACT_SET_IQ_SAMPLING_EN,
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS,
+ BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS,
+ BTC_CTE_ACT_SET_CONN_CTE_REQUEST_EN,
+ BTC_CTE_ACT_SET_CONN_CTE_RESPONSE_EN,
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ BTC_CTE_ACT_READ_ANTENNA_INFOR,
+} btc_cte_ble_act_t;
+
+/* btc_ble_cte_args_t */
+typedef union {
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ struct cte_set_trans_params_arg {
+ uint8_t adv_handle;
+ uint8_t cte_len;
+ uint8_t cte_type;
+ uint8_t cte_count;
+ uint8_t switching_pattern_len;
+ uint8_t *antenna_ids;
+ } cte_trans_params;
+
+ struct cte_set_trans_enable_arg {
+ uint8_t adv_handle;
+ uint8_t cte_enable;
+ } cte_trans_enable;
+
+ struct cte_iq_sampling_en_arg {
+ uint16_t sync_handle;
+ uint8_t sampling_en;
+ uint8_t slot_dur;
+ uint8_t max_sampled_ctes;
+ uint8_t switching_pattern_len;
+ uint8_t *antenna_ids;
+ } cte_iq_sampling_en;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ struct cte_recv_params_arg {
+ uint16_t conn_handle;
+ uint8_t sampling_en;
+ uint8_t slot_dur;
+ uint8_t switching_pattern_len;
+ uint8_t *antenna_ids;
+ } cte_recv_params;
+
+ struct cte_set_conn_trans_params_arg {
+ uint16_t conn_handle;
+ uint8_t cte_types;
+ uint8_t switching_pattern_len;
+ uint8_t *antenna_ids;
+ } cte_conn_trans_params;
+
+ struct cte_req_en_arg {
+ uint16_t conn_handle;
+ uint8_t enable;
+ uint16_t cte_req_interval;
+ uint8_t req_cte_len;
+ uint8_t req_cte_Type;
+ } cte_req_en;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+ struct cte_rsp_en_arg {
+ uint16_t conn_handle;
+ uint8_t enable;
+ } cte_rsp_en;
+
+} btc_ble_cte_args_t;
+
+void btc_ble_cte_call_handler(btc_msg_t *msg);
+void btc_ble_cte_cb_handler(btc_msg_t *msg);
+void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+void btc_ble_cte_arg_deep_free(btc_msg_t *msg);
+void btc_ble_cte_cb_deep_free(btc_msg_t *msg);
+void btc_ble_cte_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+void btc_cte_callback_init(void);
+
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#endif /* __BTC_CTE_BLE_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h
index e540116d..03b1e088 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -11,15 +11,23 @@
#include "esp_gap_ble_api.h"
#if BTC_DYNAMIC_MEMORY == TRUE
+#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
#include "bta/bta_api.h"
extern tBTA_BLE_ADV_DATA *gl_bta_adv_data_ptr;
extern tBTA_BLE_ADV_DATA *gl_bta_scan_rsp_data_ptr;
#define gl_bta_adv_data (*gl_bta_adv_data_ptr)
#define gl_bta_scan_rsp_data (*gl_bta_scan_rsp_data_ptr)
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#endif // BLE_42_FEATURE_SUPPORT
#endif
#define BLE_ISVALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)))
+#define BLE_VENDOR_PDU_RECV_EVT (0xC0)
+#define BLE_VENDOR_CHMAP_UPDATE_EVT (0xC1)
+#define BLE_VENDOR_SLEEP_WAKEUP_EVT (0xC3)
+
typedef enum {
#if (BLE_42_FEATURE_SUPPORT == TRUE)
BTC_GAP_BLE_ACT_CFG_ADV_DATA = 0,
@@ -62,6 +70,7 @@ typedef enum {
BTC_GAP_BLE_READ_PHY,
BTC_GAP_BLE_SET_PREFERED_DEF_PHY,
BTC_GAP_BLE_SET_DEF_PHY,
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
BTC_GAP_BLE_SET_EXT_ADV_RAND_ADDR,
BTC_GAP_BLE_SET_EXT_ADV_PARAMS,
BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW,
@@ -70,23 +79,32 @@ typedef enum {
BTC_GAP_BLE_EXT_ADV_STOP,
BTC_GAP_BLE_EXT_ADV_SET_REMOVE,
BTC_GAP_BLE_EXT_ADV_SET_CLEAR,
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
BTC_GAP_BLE_SET_PERIODIC_ADV_PARAMS,
BTC_GAP_BLE_CFG_PERIODIC_ADV_DATA_RAW,
BTC_GAP_BLE_PERIODIC_ADV_START,
BTC_GAP_BLE_PERIODIC_ADV_STOP,
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
BTC_GAP_BLE_PERIODIC_ADV_CREATE_SYNC,
BTC_GAP_BLE_PERIODIC_ADV_SYNC_CANCEL,
BTC_GAP_BLE_PERIODIC_ADV_SYNC_TERMINATE,
BTC_GAP_BLE_PERIODIC_ADV_ADD_DEV_TO_LIST,
BTC_GAP_BLE_PERIODIC_REMOVE_ADD_DEV_FROM_LIST,
BTC_GAP_BLE_PERIODIC_CLEAR_DEV,
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
BTC_GAP_BLE_SET_EXT_SCAN_PARAMS,
BTC_GAP_BLE_START_EXT_SCAN,
BTC_GAP_BLE_STOP_EXT_SCAN,
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
BTC_GAP_BLE_SET_EXT_PEFER_CONNET_PARAMS,
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
BTC_GAP_BLE_DTM_ENH_TX_START,
BTC_GAP_BLE_DTM_ENH_RX_START,
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
BTC_GAP_BLE_ACT_GET_DEV_NAME,
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE,
@@ -94,18 +112,35 @@ typedef enum {
BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS,
BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS,
#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
-#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_42_DTM_TEST_EN == TRUE)
BTC_GAP_BLE_DTM_TX_START,
BTC_GAP_BLE_DTM_RX_START,
-#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
BTC_GAP_BLE_DTM_STOP,
-#if (BLE_42_FEATURE_SUPPORT == TRUE)
+#if (BLE_VENDOR_HCI_EN == TRUE)
BTC_GAP_BLE_ACT_CLEAR_ADV,
-#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
+ BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT,
+ BTC_GAP_BLE_SET_CSA_SUPPORT,
+ BTC_GAP_BLE_ACT_SET_VENDOR_EVT_MASK,
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
BTC_GAP_BLE_ACT_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT,
BTC_GAP_BLE_ACT_ADD_DEVICE_TO_RESOLVING_LIST,
- BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT,
BTC_GAP_BLE_SET_PRIVACY_MODE,
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ BTC_GAP_BLE_ENH_READ_TRANS_POWER_LEVEL,
+ BTC_GAP_BLE_READ_REM_TRANS_POWER_LEVEL,
+ BTC_GAP_BLE_SET_PATH_LOSS_REPORT_PARAMS,
+ BTC_GAP_BLE_SET_PATH_LOSS_REPORTING_EN,
+ BTC_GAP_BLE_SET_TRANS_POWER_REPORTING_EN,
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ BTC_GAP_BLE_SET_DEFALT_SUBRATE,
+ BTC_GAP_BLE_SUBRATE_REQUEST,
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ BTC_GAP_ACT_SET_HOST_FEATURE,
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+ BTC_GAP_BLE_READ_CHANNEL_MAP,
} btc_gap_ble_act_t;
/* btc_ble_gap_args_t */
@@ -254,6 +289,7 @@ typedef union {
struct set_channels_args {
esp_gap_ble_channels channels;
} set_channels;
+#if (BLE_42_DTM_TEST_EN == TRUE)
struct dtm_tx_start_args {
uint8_t tx_channel;
uint8_t len_of_data;
@@ -262,6 +298,7 @@ typedef union {
struct dtm_rx_start_args {
uint8_t rx_channel;
} dtm_rx_start;
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
//BTC_DEV_VENDOR_HCI_CMD_EVT
struct vendor_cmd_send_args {
uint16_t opcode;
@@ -274,6 +311,17 @@ typedef union {
esp_bd_addr_t addr;
uint8_t privacy_mode;
} set_privacy_mode;
+ // BTC_GAP_BLE_SET_CSA_SUPPORT
+ struct set_csa_support_args {
+ uint8_t csa_select;
+ } set_csa_support;
+ // BTC_GAP_BLE_ACT_SET_VENDOR_EVT_MASK
+ struct set_vendor_evt_mask_args {
+ uint32_t evt_mask;
+ } set_vendor_evt_mask;
+ struct read_channel_map_args {
+ esp_bd_addr_t bd_addr;
+ } read_channel_map;
} btc_ble_gap_args_t;
#if (BLE_50_FEATURE_SUPPORT == TRUE)
@@ -294,7 +342,7 @@ typedef union {
esp_ble_gap_phy_mask_t rx_phy_mask;
uint16_t phy_options;
} set_def_phy;
-
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
struct ext_adv_set_rand_addr_args {
uint8_t instance;
esp_bd_addr_t rand_addr;
@@ -330,7 +378,9 @@ typedef union {
struct ext_adv_set_remove_args {
uint8_t instance;
} ext_adv_set_remove;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
struct peridic_adv_set_params_args {
uint8_t instance;
esp_ble_gap_periodic_adv_params_t params;
@@ -351,6 +401,7 @@ typedef union {
struct periodic_adv_stop_args {
uint8_t instance;
} periodic_adv_stop;
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
struct periodic_adv_create_sync_args {
esp_ble_gap_periodic_adv_sync_params_t params;
@@ -428,12 +479,70 @@ typedef union {
uint8_t phy;
uint8_t modulation_index;
} dtm_enh_rx_start;
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ // BTC_GAP_BLE_ENH_READ_TRANS_POWER_LEVEL
+ struct enh_read_trans_pwr_level_args {
+ uint8_t conn_handle;
+ uint8_t phy;
+ } enh_read_trans_pwr_level;
+ // BTC_GAP_BLE_READ_REM_TRANS_POWER_LEVEL
+ struct read_rem_trans_pwr_level_args {
+ uint8_t conn_handle;
+ uint8_t phy;
+ } read_rem_trans_pwr_level;
+ // BTC_GAP_BLE_SET_PATH_LOSS_REPORT_PARAMS
+ struct set_path_loss_rpt_params_args {
+ uint16_t conn_handle;
+ uint8_t high_threshold;
+ uint8_t high_hysteresis;
+ uint8_t low_threshold;
+ uint8_t low_hysteresis;
+ uint16_t min_time_spent;
+ } set_path_loss_rpt_params;
+ // BTC_GAP_BLE_SET_PATH_LOSS_REPORTING_EN
+ struct set_path_loss_rpt_en_args {
+ uint16_t conn_handle;
+ uint8_t enable;
+ } set_path_loss_rpt_en;
+ // BTC_GAP_BLE_SET_TRANS_POWER_REPORTING_EN
+ struct set_trans_pwr_rpting_en_args {
+ uint16_t conn_handle;
+ uint8_t local_enable;
+ uint8_t remote_enable;
+ } set_trans_pwr_rpting_en;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ // BTC_GAP_BLE_SET_DEFALT_SUBRATE
+ struct default_subrate_param_args {
+ uint16_t subrate_min;
+ uint16_t subrate_max;
+ uint16_t max_latency;
+ uint16_t continuation_number;
+ uint16_t supervision_timeout;
+ } default_subrate_param;
+ // BTC_GAP_BLE_SUBRATE_REQUEST
+ struct subrate_req_param_args {
+ uint16_t conn_handle;
+ uint16_t subrate_min;
+ uint16_t subrate_max;
+ uint16_t max_latency;
+ uint16_t continuation_number;
+ uint16_t supervision_timeout;
+ } subrate_req_param;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ struct set_host_feature_arg {
+ uint16_t bit_num;
+ uint8_t bit_val;
+ } set_host_feature_params;
} btc_ble_5_gap_args_t;
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
void btc_gap_ble_call_handler(btc_msg_t *msg);
void btc_gap_ble_cb_handler(btc_msg_t *msg);
void btc_get_whitelist_size(uint16_t *length);
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+void btc_get_periodic_list_size(uint8_t *length);
+#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE)
void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_ble_arg_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h
index 6855449c..b35e6425 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h
@@ -13,6 +13,7 @@
#include "esp_gap_bt_api.h"
#include "btc/btc_task.h"
#include "bta/utl.h"
+#include "bta/bta_api.h"
#if (BTC_GAP_BT_INCLUDED == TRUE)
typedef enum {
@@ -192,8 +193,12 @@ void btc_gap_bt_cb_handler(btc_msg_t *msg);
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_bt_arg_deep_free(btc_msg_t *msg);
void btc_gap_bt_busy_level_updated(uint8_t bl_flags);
+void btc_gap_bt_init(void);
+void btc_gap_bt_deinit(void);
+void btc_gap_bt_acl_link_num_update(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat);
esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod);
+void btc_gap_bt_status_get(esp_bt_gap_profile_status_t *param);
#endif /* #if BTC_GAP_BT_INCLUDED */
#endif /* __BTC_GAP_BT_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gatt_util.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gatt_util.h
index 3eb38abd..487708e6 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gatt_util.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gatt_util.h
@@ -9,6 +9,7 @@
#include "stack/bt_types.h"
#include "bta/bta_gatt_api.h"
+#include "btc/btc_util.h"
#include "esp_bt_defs.h"
#include "esp_gatt_defs.h"
#include "esp_gattc_api.h"
@@ -18,12 +19,10 @@
#define BTC_GATT_GET_GATT_IF(conn_id) ((uint8_t)(conn_id))
void btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src);
-void btc_to_bta_uuid(tBT_UUID *p_dest, esp_bt_uuid_t *p_src);
void btc_to_bta_gatt_id(tBTA_GATT_ID *p_dest, esp_gatt_id_t *p_src);
void btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID *p_dest, esp_gatt_srvc_id_t *p_src);
void btc_to_bta_response(tBTA_GATTS_RSP *rsp_struct, esp_gatt_rsp_t *p_rsp);
-void bta_to_btc_uuid(esp_bt_uuid_t *p_dest, tBT_UUID *p_src);
void bta_to_btc_gatt_id(esp_gatt_id_t *p_dest, tBTA_GATT_ID *p_src);
void bta_to_btc_srvc_id(esp_gatt_srvc_id_t *p_dest, tBTA_GATT_SRVC_ID *p_src);
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h
index eeebb427..1c8ef828 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h
@@ -57,6 +57,11 @@ typedef union {
esp_ble_addr_type_t remote_addr_type;
bool is_direct;
bool is_aux;
+ esp_ble_addr_type_t own_addr_type;
+ esp_ble_phy_mask_t phy_mask;
+ esp_ble_conn_params_t phy_1m_conn_params;
+ esp_ble_conn_params_t phy_2m_conn_params;
+ esp_ble_conn_params_t phy_coded_conn_params;
} open;
//BTC_GATTC_ACT_CLOSE,
struct close_arg {
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hd.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hd.h
index 313930a4..15b59393 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hd.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hd.h
@@ -55,6 +55,7 @@ typedef struct {
bool app_registered;
bool service_dereg_active;
bool forced_disc;
+ bool in_use;
tBTA_HD_APP_INFO app_info;
tBTA_HD_QOS_INFO in_qos;
tBTA_HD_QOS_INFO out_qos;
@@ -97,13 +98,11 @@ void btc_hd_call_handler(btc_msg_t *msg);
void btc_hd_cb_handler(btc_msg_t *msg);
-// extern btc_hd_cb_t btc_hd_cb;
-// extern void btc_hd_remove_device(bt_bdaddr_t bd_addr);
-// extern void btc_hd_service_registration();
-
void btc_hd_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_hd_cb_arg_deep_free(btc_msg_t *msg);
+void btc_hd_get_profile_status(esp_hidd_profile_status_t *param);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h
index 5cecdd99..e2706193 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -57,6 +57,7 @@ typedef enum
BTC_HF_END_CALL_EVT,
//REG
BTC_HF_REGISTER_DATA_CALLBACK_EVT,
+ BTC_HF_REGISTER_AUDIO_DATA_CALLBACK_EVT,
BTC_HF_REQUEST_PKT_STAT_EVT
} btc_hf_act_t;
@@ -189,6 +190,11 @@ typedef union
esp_hf_outgoing_data_cb_t send;
} reg_data_cb;
+ // BTC_HF_REGISTER_AUDIO_DATA_CALLBACK_EVT
+ struct ag_reg_audio_data_callback {
+ esp_hf_ag_audio_data_cb_t callback;
+ } reg_audio_data_cb;
+
// BTC_HF_REQUEST_PKT_STAT_EVT
struct ag_req_pkt_stat_sync_handle {
UINT16 sync_conn_handle;
@@ -211,6 +217,7 @@ typedef struct
{
bool initialized;
UINT16 handle;
+ UINT16 sync_conn_hdl;
bt_bdaddr_t connected_bda;
tBTA_AG_PEER_FEAT peer_feat;
tBTA_AG_CHLD_FEAT chld_feat;
@@ -231,6 +238,7 @@ typedef struct
btc_hf_cb_t btc_hf_cb;
esp_hf_incoming_data_cb_t btc_hf_incoming_data_cb;
esp_hf_outgoing_data_cb_t btc_hf_outgoing_data_cb;
+ esp_hf_ag_audio_data_cb_t btc_hf_audio_data_cb;
} hf_local_param_t;
#if HFP_DYNAMIC_MEMORY == TRUE
@@ -247,6 +255,8 @@ void btc_hf_cb_handler(btc_msg_t *msg); //handle the event from bta
void btc_hf_incoming_data_cb_to_app(const uint8_t *data, uint32_t len);
+void btc_hf_audio_data_cb_to_app(uint8_t *buf, uint8_t *data, uint16_t len, bool is_bad_frame);
+
uint32_t btc_hf_outgoing_data_cb_to_app(uint8_t *data, uint32_t len);
void btc_hf_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
@@ -255,6 +265,9 @@ void btc_hf_arg_deep_free(btc_msg_t *msg);
bt_status_t btc_hf_ci_sco_data(void);
+bool btc_hf_ag_audio_data_send(uint16_t sync_conn_hdl, uint8_t *p_buff_start, uint8_t *p_data, uint8_t data_len);
+
+void btc_hf_get_profile_status(esp_hf_profile_status_t *param);
#endif // BTC_HF_INCLUDED == TRUE
#endif /* __BTC_HF_AG_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h
index 4f10371b..7211d87c 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -49,6 +49,7 @@ typedef enum {
BTC_HF_CLIENT_SEND_DTMF_EVT,
BTC_HF_CLIENT_REQUEST_LAST_VOICE_TAG_NUMBER_EVT,
BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT,
+ BTC_HF_CLIENT_REGISTER_AUDIO_DATA_CALLBACK_EVT,
BTC_HF_CLIENT_SEND_NREC_EVT,
BTC_HF_CLIENT_SEND_XAPL_EVT,
BTC_HF_CLIENT_SEND_IPHONEACCEV_EVT,
@@ -107,6 +108,11 @@ typedef union {
esp_hf_client_outgoing_data_cb_t send;
} reg_data_cb;
+ // BTC_HF_CLIENT_REGISTER_AUDIO_DATA_CALLBACK_EVT
+ struct hf_client_reg_audio_data_callback {
+ esp_hf_client_audio_data_cb_t callback;
+ } reg_audio_data_cb;
+
//BTC_HF_CLIENT_SEND_XAPL_EVT
struct send_xapl_args {
char information[ESP_BT_HF_AT_SEND_XAPL_LEN + 1];
@@ -134,6 +140,7 @@ typedef struct
{
bool initialized;
UINT16 handle;
+ UINT16 sync_conn_hdl;
bt_bdaddr_t connected_bda;
esp_hf_client_connection_state_t state;
esp_hf_vr_state_t vr_state;
@@ -147,6 +154,7 @@ typedef struct
btc_hf_client_cb_t btc_hf_client_cb;
esp_hf_client_incoming_data_cb_t btc_hf_client_incoming_data_cb;
esp_hf_client_outgoing_data_cb_t btc_hf_client_outgoing_data_cb;
+ esp_hf_client_audio_data_cb_t btc_hf_client_audio_data_cb;
}hf_client_local_param_t;
#if HFP_DYNAMIC_MEMORY == TRUE
@@ -155,16 +163,20 @@ extern hf_client_local_param_t *hf_client_local_param_ptr;
#endif
/*******************************************************************************
-** BTC HF AG API
+** BTC HF CLIENT API
********************************************************************************/
void btc_hf_client_call_handler(btc_msg_t *msg);
void btc_hf_client_cb_handler(btc_msg_t *msg);
+void btc_hf_client_audio_data_cb_to_app(uint8_t *buf, uint8_t *data, uint16_t len, bool is_bad_frame);
+
void btc_hf_client_incoming_data_cb_to_app(const uint8_t *data, uint32_t len);
uint32_t btc_hf_client_outgoing_data_cb_to_app(uint8_t *data, uint32_t len);
+
+void btc_hf_client_get_profile_status(esp_hf_client_profile_status_t *param);
#endif ///BTC_HF_CLIENT_INCLUDED == TRUE
#endif /* __BTC_HF_CLIENT_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hh.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hh.h
index ae6faefc..f1158c6f 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_hh.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_hh.h
@@ -186,4 +186,6 @@ void btc_hh_cb_arg_deep_free(btc_msg_t *msg);
bool btc_hh_add_added_dev(BD_ADDR bd_addr, uint16_t attr_mask);
+void btc_hh_get_profile_status(esp_hidh_profile_status_t *param);
+
#endif /* BTC_HH_H */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h
new file mode 100644
index 00000000..4e734b12
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h
@@ -0,0 +1,222 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __BTC_ISO_BLE_H__
+#define __BTC_ISO_BLE_H__
+
+#if (BLE_FEAT_ISO_EN == TRUE)
+#include "esp_bt_defs.h"
+#include "esp_ble_iso_api.h"
+#include "btc/btc_manage.h"
+
+struct btc_iso_cis_params {
+ uint8_t cis_id;
+ uint16_t max_sdu_c_to_p;
+ uint16_t max_sdu_p_to_c;
+ uint8_t phy_c_to_p;
+ uint8_t phy_p_to_c;
+ uint8_t rtn_c_to_p;
+ uint8_t rtn_p_to_c;
+} __attribute__((packed));
+
+struct btc_iso_cis_params_test {
+ uint8_t cis_id;
+ uint8_t nse;
+ uint16_t max_sdu_c_to_p;
+ uint16_t max_sdu_p_to_c;
+ uint16_t max_pdu_c_to_p;
+ uint16_t max_pdu_p_to_c;
+ uint8_t phy_c_to_p;
+ uint8_t phy_p_to_c;
+ uint8_t bn_c_to_p;
+ uint8_t bn_p_to_c;
+} __attribute__((packed));
+
+struct btc_iso_cis_hdls {
+ uint16_t cis_hdl;
+ uint16_t acl_hdl;
+}__attribute__((packed));
+
+typedef enum {
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ BTC_ISO_ACT_BIG_CREATE,
+ BTC_ISO_ACT_BIG_CREATE_TEST,
+ BTC_ISO_ACT_BIG_TERMINATE,
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ BTC_ISO_ACT_BIG_SYNC_CREATE,
+ BTC_ISO_ACT_BIG_SYNC_TERMINATE,
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ BTC_ISO_ACT_SET_DATA_PATH,
+ BTC_ISO_ACT_REMOVE_DATA_PATH,
+ BTC_ISO_ACT_READ_ISO_TX_SYNC,
+ BTC_ISO_ACT_READ_ISO_LINK_QUALITY,
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ BTC_ISO_ACT_SET_CIG_PARAMS,
+ BTC_ISO_ACT_SET_CIG_PARAMS_TEST,
+ BTC_ISO_ACT_CREATE_CIS,
+ BTC_ISO_ACT_REMOVE_CIG,
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ BTC_ISO_ACT_ACCEPT_CIS_REQ,
+ BTC_ISO_ACT_REJECT_CIS_REQ,
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ BTC_ISO_ACT_DISCON_CIS,
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+} btc_iso_ble_act_t;
+
+/* btc_ble_iso_args_t */
+typedef union {
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ struct iso_big_create_args {
+ uint8_t big_handle;
+ uint8_t adv_handle;
+ uint8_t num_bis;
+ uint32_t sdu_interval;
+ uint16_t max_sdu;
+ uint16_t max_transport_latency;
+ uint8_t rtn;
+ uint8_t phy;
+ uint8_t packing;
+ uint8_t framing;
+ uint8_t encryption;
+ uint8_t broadcast_code[16];
+ } iso_big_creat_params;
+
+ struct iso_big_create_test_args {
+ uint8_t big_handle;
+ uint8_t adv_handle;
+ uint8_t num_bis;
+ uint32_t sdu_interval;
+ uint16_t iso_interval;
+ uint8_t nse;
+ uint16_t max_sdu;
+ uint16_t max_pdu;
+ uint8_t phy;
+ uint8_t packing;
+ uint8_t framing;
+ uint8_t bn;
+ uint8_t irc;
+ uint8_t pto;
+ uint8_t encryption;
+ uint8_t broadcast_code[16];
+ } iso_big_creat_test_params;
+
+ struct iso_big_terminate_args {
+ uint8_t big_handle;
+ uint8_t reason;
+ } iso_big_terminate_params;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ struct iso_big_sync_creat_arg {
+ uint8_t big_handle;
+ uint16_t sync_handle;
+ uint8_t encryption;
+ uint8_t bc_code[16];
+ uint8_t mse;
+ uint16_t big_sync_timeout;
+ uint8_t num_bis;
+ uint8_t bis[BLE_ISO_BIS_MAX_COUNT];
+ } iso_big_sync_creat_params;
+
+ struct iso_big_sync_terminate_arg {
+ uint8_t big_handle;
+ } iso_big_sync_terminate_params;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ struct iso_set_data_path_arg {
+ uint16_t conn_handle;
+ uint8_t data_path_dir;
+ uint8_t data_path_id;
+ uint8_t coding_fmt;
+ uint16_t company_id;
+ uint16_t vs_codec_id;
+ uint32_t controller_delay;
+ uint8_t codec_cfg_len;
+ uint8_t *codec_cfg;
+ } iso_set_data_path_params;
+
+ struct iso_remove_data_path_arg {
+ uint16_t conn_handle;
+ uint8_t data_path_dir;
+ } iso_remove_data_path_params;
+
+ struct iso_read_tx_sync_arg {
+ uint16_t iso_handle;
+ } iso_read_tx_sync_params;
+
+ struct iso_read_link_quality_arg {
+ uint16_t iso_handle;
+ } iso_read_link_quality_params;
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ struct set_cig_params_arg {
+ uint8_t cig_id;
+ uint32_t sdu_int_c_to_p;
+ uint32_t sdu_int_p_to_c;
+ uint8_t worse_case_SCA;
+ uint8_t packing;
+ uint8_t framing;
+ uint16_t mtl_c_to_p;
+ uint16_t mtl_p_to_c;
+ uint8_t cis_cnt;
+ struct btc_iso_cis_params cis_params[BLE_ISO_CIS_MAX_COUNT];
+ } set_cig_params;
+
+ struct set_cig_params_test_arg {
+ uint8_t cig_id;
+ uint32_t sdu_int_c_to_p;
+ uint32_t sdu_int_p_to_c;
+ uint8_t ft_c_to_p;
+ uint8_t ft_p_to_c;
+ uint16_t iso_interval;
+ uint8_t worse_case_SCA;
+ uint8_t packing;
+ uint8_t framing;
+ uint8_t cis_cnt;
+ struct btc_iso_cis_params_test cis_params_test[ESP_BLE_MAX_CIS_NUM];
+ } set_cig_params_test;
+
+ struct creat_cis_arg {
+ uint8_t cis_count;
+ struct btc_iso_cis_hdls cis_hdls[BLE_ISO_CIS_MAX_COUNT];
+ } creat_cis_params;
+ struct remove_cig_arg {
+ uint8_t cig_id;
+ } remove_cig_params;
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ struct accept_cis_req_arg {
+ uint16_t cis_handle;
+ } accept_cis_req_params;
+
+ struct reject_cis_req_arg {
+ uint16_t cis_handle;
+ uint8_t reason;
+ } reject_cis_req_params;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ struct discon_cis_arg {
+ uint16_t cis_handle;
+ uint8_t reason;
+ } discon_cis_params;
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+} btc_ble_iso_args_t;
+
+void btc_iso_ble_call_handler(btc_msg_t *msg);
+void btc_iso_ble_cb_handler(btc_msg_t *msg);
+void btc_iso_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+void btc_iso_ble_arg_deep_free(btc_msg_t *msg);
+void btc_iso_ble_cb_deep_free(btc_msg_t *msg);
+void btc_iso_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+void btc_iso_callback_init(void);
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#endif /* __BTC_ISO_BLE_H__ */
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h
index 83708dbb..bf61852d 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h
@@ -24,6 +24,8 @@ typedef enum {
BTC_L2CAP_ACT_CONNECT,
BTC_L2CAP_ACT_START_SRV,
BTC_L2CAP_ACT_STOP_SRV,
+ BTC_L2CAP_ACT_VFS_REGISTER,
+ BTC_L2CAP_ACT_VFS_UNREGISTER,
} btc_l2cap_act_t;
/* btc_l2cap_args_t */
@@ -65,8 +67,8 @@ typedef union {
void btc_l2cap_call_handler(btc_msg_t *msg);
void btc_l2cap_cb_handler(btc_msg_t *msg);
-esp_err_t btc_l2cap_vfs_register(void);
-esp_err_t btc_l2cap_vfs_unregister(void);
+
+void btc_l2cap_get_protocol_status(esp_bt_l2cap_protocol_status_t *param);
#endif ///defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE
#endif ///__BTC_L2CAP_H__
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_pba_client.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_pba_client.h
new file mode 100644
index 00000000..0a718fa3
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_pba_client.h
@@ -0,0 +1,90 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "common/bt_defs.h"
+#include "esp_pbac_api.h"
+
+#if BTC_PBA_CLIENT_INCLUDED
+
+typedef enum {
+ BTC_PBA_CLIENT_INIT_EVT = 0,
+ BTC_PBA_CLIENT_DEINIT_EVT,
+ BTC_PBA_CLIENT_CONNECT_EVT,
+ BTC_PBA_CLIENT_DISCONNECT_EVT,
+ BTC_PBA_CLIENT_PULL_PHONE_BOOK_EVT,
+ BTC_PBA_CLIENT_SET_PHONE_BOOK_EVT,
+ BTC_PBA_CLIENT_SET_PHONE_BOOK2_EVT,
+ BTC_PBA_CLIENT_PULL_VCARD_LISTING_EVT,
+ BTC_PBA_CLIENT_PULL_VCARD_ENTRY_EVT
+} BTC_PBA_CLIENT_EVT;
+
+/* equal to BTA max conn */
+#define BTC_PBA_CLIENT_MAX_CONN_NUM 2
+
+typedef struct {
+ uint16_t handle;
+ bt_bdaddr_t bd_addr;
+ char *path;
+ uint16_t path_len;
+ uint16_t path_pos;
+ bool busy;
+} btc_pba_client_ccb_t;
+
+typedef struct {
+ btc_pba_client_ccb_t ccb[BTC_PBA_CLIENT_MAX_CONN_NUM];
+} btc_pba_client_cb_t;
+
+typedef union {
+ // BTC_PBA_CLIENT_CONNECT_EVT
+ struct pba_client_connect_arg {
+ bt_bdaddr_t bd_addr;
+ } connect;
+
+ // BTC_PBA_CLIENT_DISCONNECT_EVT
+ struct pba_client_disconnect_arg {
+ uint16_t handle;
+ } disconnect;
+
+ // BTC_PBA_CLIENT_PULL_PHONE_BOOK_EVT
+ struct pba_client_pull_phone_book_arg {
+ uint16_t handle;
+ char *name;
+ bool include_app_param;
+ esp_pbac_pull_phone_book_app_param_t app_param;
+ } pull_phone_book;
+
+ // BTC_PBA_CLIENT_SET_PHONE_BOOK_EVT
+ struct pba_client_set_phone_book_arg {
+ uint16_t handle;
+ uint8_t flags;
+ char *name;
+ } set_phone_book;
+
+ // BTC_PBA_CLIENT_PULL_VCARD_LISTING_EVT
+ struct pba_client_pull_vcard_listing_arg {
+ uint16_t handle;
+ char *name;
+ bool include_app_param;
+ esp_pbac_pull_vcard_listing_app_param_t app_param;
+ } pull_vcard_listing;
+
+ // BTC_PBA_CLIENT_PULL_VCARD_ENTRY_EVT
+ struct pba_client_pull_vcard_entry_arg {
+ uint16_t handle;
+ char *name;
+ bool include_app_param;
+ esp_pbac_pull_vcard_entry_app_param_t app_param;
+ } pull_vcard_entry;
+} btc_pba_client_args_t;
+
+void btc_pba_client_call_handler(btc_msg_t *msg);
+void btc_pba_client_cb_handler(btc_msg_t *msg);
+void btc_pba_client_args_deep_free(btc_msg_t *msg);
+void btc_pba_client_args_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+
+#endif
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h
index 60772fa3..234c79b8 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h
@@ -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
*/
@@ -12,8 +12,9 @@
#include "common/bt_target.h"
#include "bta/bta_sdp_api.h"
#include "bt_sdp.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 {
BTC_SDP_ACT_INIT = 0,
@@ -32,9 +33,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 +50,7 @@ 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
+void btc_sdp_get_protocol_status(esp_sdp_protocol_status_t *param);
+
+#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE
#endif ///__BTC_SDP_H__
diff --git a/lib/bt/host/bluedroid/btc/profile/std/include/btc_spp.h b/lib/bt/host/bluedroid/btc/profile/std/include/btc_spp.h
index b3498132..5082a135 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/include/btc_spp.h
+++ b/lib/bt/host/bluedroid/btc/profile/std/include/btc_spp.h
@@ -90,5 +90,6 @@ void btc_spp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_spp_arg_deep_free(btc_msg_t *msg);
esp_err_t spp_send_data_to_btc(uint32_t handle, int len, uint8_t *p_data, esp_spp_mode_t spp_mode);
+void btc_spp_get_profile_status(esp_spp_profile_status_t *param);
#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE
#endif ///__BTC_SPP_H__
diff --git a/lib/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c b/lib/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c
new file mode 100644
index 00000000..825d9563
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c
@@ -0,0 +1,384 @@
+/*
+ * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+
+#include "osi/allocator.h"
+
+#include "bta/bta_api.h"
+#include "bta/bta_dm_co.h"
+#include "btc/btc_task.h"
+#include "btc/btc_util.h"
+#if (BLE_FEAT_ISO_EN == TRUE)
+#include "btc_iso_ble.h"
+#include "esp_ble_iso_api.h"
+
+static inline void btc_iso_ble_cb_to_app(esp_ble_iso_cb_event_t event, esp_ble_iso_cb_param_t *param)
+{
+ esp_ble_iso_cb_t btc_iso_ble_cb = (esp_ble_iso_cb_t)btc_profile_cb_get(BTC_PID_ISO_BLE);
+ if (btc_iso_ble_cb) {
+ btc_iso_ble_cb(event, param);
+ }
+}
+
+static void btc_ble_iso_callback(tBTM_BLE_ISO_EVENT event,
+ tBTM_BLE_ISO_CB_PARAMS *params)
+{
+ esp_ble_iso_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_ISO_BLE;
+
+ switch(event) {
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ case BTA_BLE_ISO_BIG_CREATE_COMPLETE_EVT:
+ msg.act = ESP_BLE_ISO_BIG_CREATE_CMPL_EVT;
+ param.create_big_cmpl.status = btc_btm_status_to_esp_status(params->btm_big_cmpl.status);
+ param.create_big_cmpl.big_handle = params->btm_big_cmpl.big_handle;
+ param.create_big_cmpl.big_sync_delay = params->btm_big_cmpl.big_sync_delay;
+ param.create_big_cmpl.transport_latency = params->btm_big_cmpl.transport_latency;
+ param.create_big_cmpl.phy = params->btm_big_cmpl.phy;
+ param.create_big_cmpl.nse = params->btm_big_cmpl.nse;
+ param.create_big_cmpl.bn = params->btm_big_cmpl.bn;
+ param.create_big_cmpl.pto = params->btm_big_cmpl.pto;
+ param.create_big_cmpl.irc = params->btm_big_cmpl.irc;
+ param.create_big_cmpl.max_pdu = params->btm_big_cmpl.max_pdu;
+ param.create_big_cmpl.iso_interval = params->btm_big_cmpl.iso_interval;
+ param.create_big_cmpl.num_bis = params->btm_big_cmpl.num_bis;
+ for (uint8_t i = 0; i < params->btm_big_cmpl.num_bis; i++)
+ {
+ param.create_big_cmpl.bis_handle[i] = params->btm_big_cmpl.bis_handle[i];
+ }
+ break;
+ case BTA_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT:
+ msg.act = ESP_BLE_ISO_BIG_TERMINATE_CMPL_EVT;
+ param.term_big_cmpl.status = btc_btm_status_to_esp_status(params->btm_big_term.status);
+ param.term_big_cmpl.big_handle = params->btm_big_term.big_handle;
+ param.term_big_cmpl.reason = params->btm_big_term.reason;
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case BTA_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT:
+ msg.act = ESP_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT;
+ param.big_sync_estab.status = btc_btm_status_to_esp_status(params->btm_big_sync_estab.status);
+ param.big_sync_estab.big_handle = params->btm_big_sync_estab.big_handle;
+ param.big_sync_estab.transport_latency = params->btm_big_sync_estab.transport_latency_big;
+ param.big_sync_estab.nse = params->btm_big_sync_estab.nse;
+ param.big_sync_estab.bn = params->btm_big_sync_estab.bn;
+ param.big_sync_estab.pto = params->btm_big_sync_estab.pto;
+ param.big_sync_estab.irc = params->btm_big_sync_estab.irc;
+ param.big_sync_estab.max_pdu = params->btm_big_sync_estab.max_pdu;
+ param.big_sync_estab.iso_interval = params->btm_big_sync_estab.iso_interval;
+ param.big_sync_estab.num_bis = params->btm_big_sync_estab.num_bis;
+ for (uint8_t i = 0; i < params->btm_big_sync_estab.num_bis; i++)
+ {
+ param.big_sync_estab.bis_handle[i] = params->btm_big_sync_estab.bis_handle[i];
+ }
+ break;
+ case BTA_BLE_ISO_BIG_SYNC_LOST_EVT:
+ msg.act = ESP_BLE_ISO_BIG_SYNC_LOST_EVT;
+ param.big_sync_lost.big_handle = params->btm_big_sync_lost.big_handle;
+ param.big_sync_lost.reason = params->btm_big_sync_lost.reason;
+ break;
+ case BTA_BLE_ISO_BIG_SYNC_TERMINATE_COMPLETE_EVT:
+ msg.act = ESP_BLE_ISO_BIG_SYNC_TERMINATE_CMPL_EVT;
+ param.term_big_sync.status = btc_btm_status_to_esp_status(params->btm_big_sync_ter.status);
+ param.term_big_sync.big_handle = params->btm_big_sync_ter.big_hdl;
+ break;
+ case BTA_BLE_ISO_BIGINFO_ADV_REPORT_EVT:
+ msg.act = ESP_BLE_ISO_BIGINFO_ADV_REPORT_EVT;
+ param.biginfo_report.sync_handle = params->btm_biginfo_report.sync_handle;
+ param.biginfo_report.num_bis = params->btm_biginfo_report.num_bis;
+ param.biginfo_report.nse = params->btm_biginfo_report.nse;
+ param.biginfo_report.iso_interval = params->btm_biginfo_report.iso_interval;
+ param.biginfo_report.bn = params->btm_biginfo_report.bn;
+ param.biginfo_report.pto = params->btm_biginfo_report.pto;
+ param.biginfo_report.irc = params->btm_biginfo_report.irc;
+ param.biginfo_report.max_pdu = params->btm_biginfo_report.max_pdu;
+ param.biginfo_report.sdu_interval = params->btm_biginfo_report.sdu_interval;
+ param.biginfo_report.max_sdu = params->btm_biginfo_report.max_sdu;
+ param.biginfo_report.phy = params->btm_biginfo_report.phy;
+ param.biginfo_report.framing = params->btm_biginfo_report.framing;
+ param.biginfo_report.encryption = params->btm_biginfo_report.encryption;
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case BTA_BLE_ISO_DATA_PATH_UPFATE_EVT:
+ msg.act = ESP_BLE_ISO_ISO_DATA_PATH_UPDATE_EVT;
+ param.data_path.op_type = params->btm_data_path_update.op_type;
+ param.data_path.status = btc_btm_status_to_esp_status(params->btm_data_path_update.status);
+ param.data_path.iso_hdl = params->btm_data_path_update.conn_hdl;
+ break;
+ case BTA_BLE_ISO_READ_TX_SYNC_EVT:
+ msg.act = ESP_BLE_ISO_READ_ISO_TX_SYNC_CMPL_EVT;
+ param.read_tx_sync.status = btc_btm_status_to_esp_status(params->btm_read_tx_sync.status);
+ param.read_tx_sync.iso_hdl = params->btm_read_tx_sync.conn_hdl;
+ param.read_tx_sync.pkt_seq_num = params->btm_read_tx_sync.pkt_seq_num;
+ param.read_tx_sync.tx_time_stamp = params->btm_read_tx_sync.tx_time_stamp;
+ param.read_tx_sync.time_offset = params->btm_read_tx_sync.time_offset;
+ break;
+ case BTA_BLE_ISO_READ_LINK_QUALITY_EVT:
+ msg.act = ESP_BLE_ISO_READ_LINK_QUALITY_CMPL_EVT;
+ param.read_link_quality.status = btc_btm_status_to_esp_status(params->btm_read_link_quality.status);
+ param.read_link_quality.iso_hdl = params->btm_read_link_quality.conn_hdl;
+ param.read_link_quality.tx_unacked_pkts = params->btm_read_link_quality.tx_unacked_pkts;
+ param.read_link_quality.tx_flushed_pkts = params->btm_read_link_quality.tx_flushed_pkts;
+ param.read_link_quality.tx_last_subevt_pkts = params->btm_read_link_quality.tx_last_subevt_pkts;
+ param.read_link_quality.retransmitted_pkts = params->btm_read_link_quality.retransmitted_pkts;
+ param.read_link_quality.crc_error_pkts = params->btm_read_link_quality.crc_error_pkts;
+ param.read_link_quality.rx_unreceived_pkts = params->btm_read_link_quality.rx_unreceived_pkts;
+ param.read_link_quality.duplicate_pkts = params->btm_read_link_quality.duplicate_pkts;
+ break;
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ case BTA_BLE_ISO_CIS_ESTABLISHED_EVT:
+ msg.act = ESP_BLE_ISO_CIS_ESTABLISHED_EVT;
+ param.cis_estab.status = btc_btm_status_to_esp_status(params->btm_cis_established_evt.status);
+ param.cis_estab.cis_handle = params->btm_cis_established_evt.conn_handle;
+ param.cis_estab.cig_sync_delay = params->btm_cis_established_evt.cig_sync_delay;
+ param.cis_estab.cis_sync_delay = params->btm_cis_established_evt.cis_sync_delay;
+ param.cis_estab.trans_lat_c_to_p = params->btm_cis_established_evt.trans_lat_c_to_p;
+ param.cis_estab.trans_lat_p_to_c = params->btm_cis_established_evt.trans_lat_p_to_c;
+ param.cis_estab.phy_c_to_p = params->btm_cis_established_evt.phy_c_to_p;
+ param.cis_estab.phy_p_to_c = params->btm_cis_established_evt.phy_p_to_c;
+ param.cis_estab.nse = params->btm_cis_established_evt.nse;
+ param.cis_estab.bn_c_to_p = params->btm_cis_established_evt.bn_c_to_p;
+ param.cis_estab.bn_p_to_c = params->btm_cis_established_evt.bn_p_to_c;
+ param.cis_estab.ft_c_to_p = params->btm_cis_established_evt.ft_c_to_p;
+ param.cis_estab.ft_p_to_c = params->btm_cis_established_evt.ft_p_to_c;
+ param.cis_estab.max_pdu_c_to_p = params->btm_cis_established_evt.max_pdu_c_to_p;
+ param.cis_estab.max_pdu_p_to_c = params->btm_cis_established_evt.max_pdu_p_to_c;
+ param.cis_estab.iso_interval = params->btm_cis_established_evt.iso_interval;
+#if (BLE_FEAT_ISO_60_EN == TRUE)
+ param.cis_estab.sub_interval = params->btm_cis_established_evt.sub_interval;
+ param.cis_estab.max_sdu_c_to_p = params->btm_cis_established_evt.max_sdu_c_to_p;
+ param.cis_estab.max_sdu_p_to_c = params->btm_cis_established_evt.max_sdu_p_to_c;
+ param.cis_estab.sdu_int_c_to_p = params->btm_cis_established_evt.sdu_int_c_to_p;
+ param.cis_estab.sdu_int_p_to_c = params->btm_cis_established_evt.sdu_int_p_to_c;
+ param.cis_estab.framing = params->btm_cis_established_evt.framing;
+#endif // #if (BLE_FEAT_ISO_60_EN == TRUE)
+ break;
+ case BTA_BLE_ISO_CIS_DISCONNECTED_EVT:
+ msg.act = ESP_BLE_ISO_CIS_DISCONNECTED_EVT;
+ param.cis_disconnected.cis_handle = params->btm_cis_disconnectd_evt.cis_handle;
+ param.cis_disconnected.reason = params->btm_cis_disconnectd_evt.reason;
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ case BTM_BLE_ISO_CIS_REQUEST_EVT:
+ msg.act = ESP_BLE_ISO_CIS_REQUEST_EVT;
+ param.cis_request.acl_handle = params->btm_cis_request_evt.acl_handle;
+ param.cis_request.cis_handle = params->btm_cis_request_evt.cis_handle;
+ param.cis_request.cig_id = params->btm_cis_request_evt.cig_id;
+ param.cis_request.cis_id = params->btm_cis_request_evt.cis_id;
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ case BTA_BLE_ISO_SET_CIG_PARAMS_EVT:
+ msg.act = ESP_BLE_ISO_SET_CIG_PARAMS_CMPL_EVT;
+ param.set_cig_params.status = btc_btm_status_to_esp_status(params->btm_set_cig_params.status);
+ param.set_cig_params.cig_id = params->btm_set_cig_params.cig_id;
+ param.set_cig_params.cis_count = params->btm_set_cig_params.cis_count;
+ memcpy(&param.set_cig_params.cis_hdl[0], &params->btm_set_cig_params.conn_hdl[0], params->btm_set_cig_params.cis_count * 2);
+ break;
+ case BTA_BLE_ISO_CREATE_CIS_EVT:
+ msg.act = ESP_BLE_ISO_CREATE_CIS_CMPL_EVT;
+ param.create_cis.status = btc_btm_status_to_esp_status(params->status);
+ break;
+ case BTA_BLE_ISO_REMOVE_CIG_EVT:
+ msg.act = ESP_BLE_ISO_REMOVE_CIG_CMPL_EVT;
+ param.remove_cig.status = btc_btm_status_to_esp_status(params->btm_remove_cig.status);
+ param.remove_cig.cig_id = params->btm_remove_cig.cig_id;
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ case BTA_BLE_ISO_ACCEPT_CIS_REQ_EVT:
+ msg.act = ESP_BLE_ISO_ACCEPT_CIS_REQ_CMPL_EVT;
+ param.accept_req.status = btc_btm_status_to_esp_status(params->status);
+ break;
+ case BTA_BLE_ISO_REJECT_CIS_REQ_EVT:
+ msg.act = ESP_BLE_ISO_REJECT_CIS_REQ_CMPL_EVT;
+ param.reject_req.status = btc_btm_status_to_esp_status(params->btm_reject_cis_req.status);
+ param.reject_req.cis_handle = params->btm_reject_cis_req.cis_handle;
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ default:
+ break;
+ }
+
+ ret = btc_transfer_context(&msg, &param,
+ sizeof(esp_ble_iso_cb_param_t), NULL, NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+
+void btc_iso_ble_cb_handler(btc_msg_t *msg)
+{
+ BTC_TRACE_DEBUG("%s act %d \n", __func__, msg->act);
+ esp_ble_iso_cb_param_t *param = (esp_ble_iso_cb_param_t *)msg->arg;
+
+ if (msg->act < ESP_BLE_ISO_EVT_MAX) {
+ btc_iso_ble_cb_to_app(msg->act, param);
+ } else {
+ BTC_TRACE_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
+ }
+
+ btc_iso_ble_cb_deep_free(msg);
+
+}
+
+void btc_iso_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+ btc_ble_iso_args_t *src = (btc_ble_iso_args_t *)p_src;
+ btc_ble_iso_args_t *dst = (btc_ble_iso_args_t *)p_dest;
+
+ switch (msg->act) {
+ case BTC_ISO_ACT_SET_DATA_PATH: {
+ if (src->iso_set_data_path_params.codec_cfg_len && src->iso_set_data_path_params.codec_cfg) {
+ dst->iso_set_data_path_params.codec_cfg = osi_malloc(src->iso_set_data_path_params.codec_cfg_len);
+ if (dst->iso_set_data_path_params.codec_cfg) {
+ memcpy(dst->iso_set_data_path_params.codec_cfg, src->iso_set_data_path_params.codec_cfg, src->iso_set_data_path_params.codec_cfg_len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
+ }
+ default:
+ BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
+ break;
+ }
+}
+
+void btc_iso_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+ // esp_ble_iso_cb_param_t *src = (esp_ble_iso_cb_param_t *)p_src;
+ // esp_ble_iso_cb_param_t *dst = (esp_ble_iso_cb_param_t *) p_dest;
+
+ switch (msg->act) {
+ default:
+ BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act);
+ break;
+ }
+}
+
+void btc_iso_ble_arg_deep_free(btc_msg_t *msg)
+{
+ BTC_TRACE_DEBUG("%s \n", __func__);
+ switch (msg->act) {
+
+ case BTC_ISO_ACT_SET_DATA_PATH: {
+ uint8_t *p_codec_cfg = ((btc_ble_iso_args_t *)msg->arg)->iso_set_data_path_params.codec_cfg;
+ if (p_codec_cfg) {
+ osi_free(p_codec_cfg);
+ }
+ break;
+ }
+ default:
+ BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act);
+ break;
+ }
+}
+
+void btc_iso_ble_cb_deep_free(btc_msg_t *msg)
+{
+ BTC_TRACE_DEBUG("%s", __func__);
+ switch (msg->act) {
+ default:
+ BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act);
+ break;
+ }
+}
+
+void btc_iso_ble_call_handler(btc_msg_t *msg)
+{
+ btc_ble_iso_args_t *arg = (btc_ble_iso_args_t *)msg->arg;
+ BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act);
+
+ switch (msg->act) {
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ case BTC_ISO_ACT_BIG_CREATE:
+ BTA_DmBleGapIsoBigCreate((tBTA_DM_BLE_BIG_CREATE_PARAMS *)&arg->iso_big_creat_params);
+ break;
+ case BTC_ISO_ACT_BIG_CREATE_TEST:
+ BTA_DmBleGapIsoBigCreateTest((tBTA_DM_BLE_BIG_CREATE_TEST_PARAMS *)&arg->iso_big_creat_test_params);
+ break;
+ case BTC_ISO_ACT_BIG_TERMINATE:
+ BTA_DmBleGapIsoBigTerminate((tBTA_DM_BLE_BIG_TERMINATE_PARAMS *)&arg->iso_big_terminate_params);
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case BTC_ISO_ACT_BIG_SYNC_CREATE:
+ BTA_DmBleGapIsoBigSyncCreate((tBTA_DM_BLE_BIG_SYNC_CREATE_PARAMS *)&arg->iso_big_sync_creat_params);
+ break;
+ case BTC_ISO_ACT_BIG_SYNC_TERMINATE:
+ BTA_DmBleGapIsoBigSyncTerminate((tBTA_DM_BLE_BIG_SYNC_TERMINATE_PARAMS *)&arg->iso_big_sync_terminate_params);
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case BTC_ISO_ACT_SET_DATA_PATH:
+ BTA_DmBleGapIsoDataPathSet((tBTA_DM_BLE_ISO_SET_DATA_PATH_PARAMS *)&arg->iso_set_data_path_params);
+ break;
+ case BTC_ISO_ACT_REMOVE_DATA_PATH:
+ BTA_DmBleGapIsoDataPathRemove((tBTA_DM_BLE_ISO_REMOVE_DATA_PATH_PARAMS *)&arg->iso_remove_data_path_params);
+ break;
+ case BTC_ISO_ACT_READ_ISO_TX_SYNC:
+ BTA_DmBleGapIsoReadTxSync(arg->iso_read_tx_sync_params.iso_handle);
+ break;
+ case BTC_ISO_ACT_READ_ISO_LINK_QUALITY:
+ break;
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ case BTC_ISO_ACT_SET_CIG_PARAMS: {
+ struct set_cig_params_arg *set_cig_params = (struct set_cig_params_arg *)arg;
+ BTA_DmBleIsoSetCigParams(set_cig_params->cig_id, set_cig_params->sdu_int_c_to_p, set_cig_params->sdu_int_p_to_c,
+ set_cig_params->worse_case_SCA, set_cig_params->packing, set_cig_params->framing,
+ set_cig_params->mtl_c_to_p, set_cig_params->mtl_p_to_c, set_cig_params->cis_cnt,
+ (uint8_t *)&set_cig_params->cis_params[0]);
+ break;
+ }
+ case BTC_ISO_ACT_SET_CIG_PARAMS_TEST:
+ struct set_cig_params_test_arg *set_cig_params_test = (struct set_cig_params_test_arg *)arg;
+ BTA_DmBleIsoSetCigParamsTest(set_cig_params_test->cig_id, set_cig_params_test->sdu_int_c_to_p, set_cig_params_test->sdu_int_p_to_c,
+ set_cig_params_test->ft_c_to_p, set_cig_params_test->ft_p_to_c, set_cig_params_test->iso_interval,
+ set_cig_params_test->worse_case_SCA, set_cig_params_test->packing, set_cig_params_test->framing,
+ set_cig_params_test->cis_cnt, (uint8_t *)&set_cig_params_test->cis_params_test[0]);
+ break;
+ case BTC_ISO_ACT_CREATE_CIS: {
+ struct creat_cis_arg * create_cis = (struct creat_cis_arg *)arg;
+ BTA_DmBleIsoCreateCis(create_cis->cis_count, (uint8_t *)&create_cis->cis_hdls[0]);
+ break;
+ }
+ case BTC_ISO_ACT_REMOVE_CIG:
+ BTA_DmBleIsoRemoveCig(arg->remove_cig_params.cig_id);
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ case BTC_ISO_ACT_ACCEPT_CIS_REQ:
+ BTA_DmBleIsoAcceptCisReq(arg->accept_cis_req_params.cis_handle);
+ break;
+ case BTC_ISO_ACT_REJECT_CIS_REQ:
+ BTA_DmBleIsoRejectCisReq(arg->reject_cis_req_params.cis_handle, arg->reject_cis_req_params.reason);
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ case BTC_ISO_ACT_DISCON_CIS:
+ BTA_DmBleIsoDisconCis(arg->discon_cis_params.cis_handle, arg->discon_cis_params.reason);
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ default:
+ break;
+ }
+
+ btc_iso_ble_arg_deep_free(msg);
+}
+
+//register connection parameter update callback
+void btc_iso_callback_init(void)
+{
+ BTM_BleIsoRegisterCallback(btc_ble_iso_callback);
+}
+
+#endif ///BLE_FEAT_ISO_EN == TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/lib/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c
index 5cd777c5..9155784f 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -72,7 +72,6 @@ typedef struct {
uint8_t service_uuid[16];
} l2cap_slot_t;
-
typedef struct {
l2cap_slot_t *l2cap_slots[BTA_JV_MAX_L2C_CONN + 1];
uint32_t l2cap_slot_id;
@@ -81,7 +80,12 @@ typedef struct {
esp_vfs_id_t l2cap_vfs_id;
} l2cap_local_param_t;
+#if L2CAP_DYNAMIC_MEMORY == FALSE
static l2cap_local_param_t l2cap_local_param;
+#else
+static l2cap_local_param_t *l2cap_local_param_ptr;
+#define l2cap_local_param (*l2cap_local_param_ptr)
+#endif
/* L2CAP default options for OBEX connections */
static const tL2CAP_FCR_OPTS obex_l2c_fcr_opts_def =
@@ -103,13 +107,15 @@ static const tL2CAP_ERTM_INFO obex_l2c_etm_opt =
OBX_FCR_TX_POOL_ID
};
-
#if L2CAP_DYNAMIC_MEMORY == FALSE
#define is_l2cap_init() (l2cap_local_param.l2cap_slot_mutex != NULL)
#else
#define is_l2cap_init() (&l2cap_local_param != NULL && l2cap_local_param.l2cap_slot_mutex != NULL)
#endif
+static void btc_l2cap_vfs_register(void);
+static void btc_l2cap_vfs_unregister(void);
+
static void l2cap_osi_free(void *p)
{
osi_free(p);
@@ -281,7 +287,7 @@ static void close_timeout_handler(void *arg)
status = btc_transfer_context(&msg, slot->alarm_arg, sizeof(tBTA_JV), NULL, NULL);
if (slot->alarm_arg) {
- free(slot->alarm_arg);
+ osi_free(slot->alarm_arg);
slot->alarm_arg = NULL;
}
@@ -355,12 +361,20 @@ static void *btc_l2cap_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
// to do
break;
case BTA_JV_FREE_SCN_EVT:
- slot = l2cap_find_slot_by_id(id);
- if (slot) {
- l2cap_free_slot(slot);
- } else {
- BTC_TRACE_ERROR("%s unable to find L2CAP slot, event:%d!", __func__, event);
- p_data->free_scn.status = ESP_BT_L2CAP_NO_CONNECTION;
+ if (user_data) {
+ id = ((tBTA_JV_FREE_SCN_USER_DATA *)user_data)->slot_id;
+ slot = l2cap_find_slot_by_id(id);
+ if (slot) {
+ if (((tBTA_JV_FREE_SCN_USER_DATA *)user_data)->server_status != BTA_JV_SERVER_CONNECTED) {
+ l2cap_free_slot(slot);
+ } else {
+ // Currently running in btu task, free in btc task. It will be free when handling the disconnect event.
+ }
+ } else {
+ BTC_TRACE_ERROR("%s unable to find L2CAP slot, event:%d!", __func__, event);
+ p_data->free_scn.status = ESP_BT_L2CAP_NO_CONNECTION;
+ }
+ osi_free(user_data);
}
break;
default:
@@ -458,6 +472,7 @@ static void btc_l2cap_init(void)
static void btc_l2cap_uninit(void)
{
esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS;
+ tBTA_JV_SERVER_STATUS server_status = BTA_JV_SERVER_RUNNING;
do {
if (!is_l2cap_init()) {
@@ -468,7 +483,8 @@ static void btc_l2cap_uninit(void)
osi_mutex_lock(&l2cap_local_param.l2cap_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
// first, remove all connection
for (size_t i = 1; i <= BTA_JV_MAX_L2C_CONN; i++) {
- if (l2cap_local_param.l2cap_slots[i] != NULL && !l2cap_local_param.l2cap_slots[i]->is_server) {
+ if (l2cap_local_param.l2cap_slots[i] != NULL && l2cap_local_param.l2cap_slots[i]->connected) {
+ server_status = BTA_JV_SERVER_CONNECTED;
BTA_JvL2capClose(l2cap_local_param.l2cap_slots[i]->handle, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb,
(void *)l2cap_local_param.l2cap_slots[i]->id);
}
@@ -481,8 +497,17 @@ static void btc_l2cap_uninit(void)
(void *)l2cap_local_param.l2cap_slots[i]->id);
}
+ tBTA_JV_FREE_SCN_USER_DATA *user_data = osi_malloc(sizeof(tBTA_JV_FREE_SCN_USER_DATA));
+ if (user_data) {
+ user_data->server_status = server_status;
+ user_data->slot_id = l2cap_local_param.l2cap_slots[i]->id;
+ } else {
+ BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
+ assert(0);
+ }
+
BTA_JvFreeChannel(l2cap_local_param.l2cap_slots[i]->psm, BTA_JV_CONN_TYPE_L2CAP,
- (tBTA_JV_RFCOMM_CBACK *)btc_l2cap_inter_cb, (void *)l2cap_local_param.l2cap_slots[i]->id);
+ (tBTA_JV_RFCOMM_CBACK *)btc_l2cap_inter_cb, (void *)user_data);
}
}
BTA_JvDisable((tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb);
@@ -547,7 +572,8 @@ static void btc_l2cap_stop_srv(btc_l2cap_args_t *arg)
esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS;
bool is_remove_all = false;
uint8_t i, j, srv_cnt = 0;
- uint8_t *srv_psm_arr = osi_malloc(BTA_JV_MAX_L2C_CONN);
+ uint16_t *srv_psm_arr = osi_malloc(BTA_JV_MAX_L2C_CONN);
+ tBTA_JV_SERVER_STATUS server_status = BTA_JV_SERVER_RUNNING;
if (arg->stop_srv.psm == BTC_L2CAP_INVALID_PSM) {
is_remove_all = true;
@@ -594,6 +620,7 @@ static void btc_l2cap_stop_srv(btc_l2cap_args_t *arg)
if (l2cap_local_param.l2cap_slots[i] != NULL && l2cap_local_param.l2cap_slots[i]->connected &&
l2cap_local_param.l2cap_slots[i]->handle != 0xffff &&
l2cap_local_param.l2cap_slots[i]->psm == srv_psm_arr[j]) {
+ server_status = BTA_JV_SERVER_CONNECTED;
BTA_JvL2capClose(l2cap_local_param.l2cap_slots[i]->handle, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb,
(void *)l2cap_local_param.l2cap_slots[i]->id);
}
@@ -606,14 +633,19 @@ static void btc_l2cap_stop_srv(btc_l2cap_args_t *arg)
if (l2cap_local_param.l2cap_slots[i] != NULL && l2cap_local_param.l2cap_slots[i]->is_server &&
l2cap_local_param.l2cap_slots[i]->handle != 0xffff &&
l2cap_local_param.l2cap_slots[i]->psm == srv_psm_arr[j]) {
-
- if (l2cap_local_param.l2cap_slots[i]->handle > 0) {
- BTA_JvL2capStopServer(l2cap_local_param.l2cap_slots[i]->psm,
- (void *)l2cap_local_param.l2cap_slots[i]->id);
+ BTA_JvL2capStopServer(l2cap_local_param.l2cap_slots[i]->psm,
+ (void *)l2cap_local_param.l2cap_slots[i]->id);
+
+ tBTA_JV_FREE_SCN_USER_DATA *user_data = osi_malloc(sizeof(tBTA_JV_FREE_SCN_USER_DATA));
+ if (user_data) {
+ user_data->server_status = server_status;
+ user_data->slot_id = l2cap_local_param.l2cap_slots[i]->id;
+ } else {
+ BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
+ assert(0);
}
-
BTA_JvFreeChannel(l2cap_local_param.l2cap_slots[i]->psm, BTA_JV_CONN_TYPE_L2CAP,
- (tBTA_JV_RFCOMM_CBACK *)btc_l2cap_inter_cb, (void *)l2cap_local_param.l2cap_slots[i]->id);
+ (tBTA_JV_RFCOMM_CBACK *)btc_l2cap_inter_cb, (void *)user_data);
}
}
}
@@ -756,6 +788,12 @@ void btc_l2cap_call_handler(btc_msg_t *msg)
case BTC_L2CAP_ACT_STOP_SRV:
btc_l2cap_stop_srv(arg);
break;
+ case BTC_L2CAP_ACT_VFS_REGISTER:
+ btc_l2cap_vfs_register();
+ break;
+ case BTC_L2CAP_ACT_VFS_UNREGISTER:
+ btc_l2cap_vfs_unregister();
+ break;
default:
BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
break;
@@ -832,7 +870,7 @@ void btc_l2cap_cb_handler(btc_msg_t *msg)
// if rx still has data, delay free slot
if (slot->close_alarm == NULL && slot->rx.queue && fixed_queue_length(slot->rx.queue) > 0) {
tBTA_JV *p_arg = NULL;
- if ((p_arg = malloc(sizeof(tBTA_JV))) == NULL) {
+ if ((p_arg = osi_malloc(sizeof(tBTA_JV))) == NULL) {
param.close.status = ESP_BT_L2CAP_NO_RESOURCE;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
BTC_TRACE_ERROR("%s unable to malloc slot close_alarm arg!", __func__);
@@ -842,7 +880,7 @@ void btc_l2cap_cb_handler(btc_msg_t *msg)
slot->alarm_arg = (void *)p_arg;
if ((slot->close_alarm =
osi_alarm_new("slot", close_timeout_handler, (void *)slot, VFS_CLOSE_TIMEOUT)) == NULL) {
- free(p_arg);
+ osi_free(p_arg);
slot->alarm_arg = NULL;
param.close.status = ESP_BT_L2CAP_NO_RESOURCE;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
@@ -850,7 +888,7 @@ void btc_l2cap_cb_handler(btc_msg_t *msg)
break;
}
if (osi_alarm_set(slot->close_alarm, VFS_CLOSE_TIMEOUT) != OSI_ALARM_ERR_PASS) {
- free(p_arg);
+ osi_free(p_arg);
slot->alarm_arg = NULL;
osi_alarm_free(slot->close_alarm);
param.close.status = ESP_BT_L2CAP_BUSY;
@@ -906,7 +944,6 @@ void btc_l2cap_cb_handler(btc_msg_t *msg)
fixed_queue_enqueue(slot->rx.queue, p_data_buf, FIXED_QUEUE_MAX_TIMEOUT);
} else {
osi_free(p_data_buf);
- break;
}
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
@@ -945,12 +982,11 @@ void btc_l2cap_cb_handler(btc_msg_t *msg)
break; // to do disconnect
}
memset(p_data_buf, 0, count + sizeof(BT_HDR));
- p_data_buf->len = BTA_JvL2capRead(p_data->data_ind.handle, slot->id, p_data_buf->data, count);
+ p_data_buf->len = BTA_JvL2capRead(p_data->l2c_read.handle, slot->id, p_data_buf->data, count);
if (p_data_buf->len > 0) {
fixed_queue_enqueue(slot->rx.queue, p_data_buf, FIXED_QUEUE_MAX_TIMEOUT);
} else {
osi_free(p_data_buf);
- break;
}
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
@@ -1060,7 +1096,7 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size)
if (!enqueue_status) {
BTC_TRACE_DEBUG("%s tx_len:%d, fd:%d\n", __func__, fixed_queue_length(slot->tx.queue), fd);
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
- //block untill under water level, be closed or time out
+ //block until under water level, be closed or time out
tx_event_group_val =
xEventGroupWaitBits(l2cap_local_param.tx_event_group, SLOT_WRITE_BIT(serial) | SLOT_CLOSE_BIT(serial), pdTRUE,
pdFALSE, VFS_WRITE_TIMEOUT / portTICK_PERIOD_MS);
@@ -1201,14 +1237,14 @@ static ssize_t l2cap_vfs_read(int fd, void * dst, size_t size)
return item_size;
}
-esp_err_t btc_l2cap_vfs_register(void)
+static void btc_l2cap_vfs_register(void)
{
- esp_err_t ret = ESP_OK;
+ esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS;
do {
if (!is_l2cap_init()) {
BTC_TRACE_ERROR("%s L2CAP have not been init\n", __func__);
- ret = ESP_FAIL;
+ ret = ESP_BT_L2CAP_NEED_INIT;
break;
}
@@ -1225,33 +1261,54 @@ esp_err_t btc_l2cap_vfs_register(void)
// No FD range is registered here: l2cap_vfs_id is used to register/unregister
// file descriptors
if (esp_vfs_register_with_id(&vfs, NULL, &l2cap_local_param.l2cap_vfs_id) != ESP_OK) {
- ret = ESP_FAIL;
+ ret = ESP_BT_L2CAP_FAILURE;
break;
}
} while (0);
- return ret;
+ esp_bt_l2cap_cb_param_t param = {0};
+ param.vfs_register.status = ret;
+ btc_l2cap_cb_to_app(ESP_BT_L2CAP_VFS_REGISTER_EVT, &param);
}
-esp_err_t btc_l2cap_vfs_unregister(void)
+static void btc_l2cap_vfs_unregister(void)
{
- esp_err_t ret = ESP_OK;
+ esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS;
+
do {
if (!is_l2cap_init()) {
BTC_TRACE_ERROR("%s L2CAP have not been init\n", __func__);
- ret = ESP_FAIL;
+ ret = ESP_BT_L2CAP_NEED_INIT;
break;
}
if (l2cap_local_param.l2cap_vfs_id != -1) {
if (esp_vfs_unregister_with_id(l2cap_local_param.l2cap_vfs_id) != ESP_OK) {
- ret = ESP_FAIL;
+ ret = ESP_BT_L2CAP_FAILURE;
}
}
l2cap_local_param.l2cap_vfs_id = -1;
} while (0);
- return ret;
+ esp_bt_l2cap_cb_param_t param = {0};
+ param.vfs_unregister.status = ret;
+ btc_l2cap_cb_to_app(ESP_BT_L2CAP_VFS_UNREGISTER_EVT, &param);
+}
+
+void btc_l2cap_get_protocol_status(esp_bt_l2cap_protocol_status_t *param)
+{
+ if (is_l2cap_init()) {
+ param->l2cap_inited = true;
+ osi_mutex_lock(&l2cap_local_param.l2cap_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
+ for (size_t i = 1; i <= BTA_JV_MAX_L2C_CONN; i++) {
+ if (l2cap_local_param.l2cap_slots[i] != NULL && l2cap_local_param.l2cap_slots[i]->connected) {
+ param->conn_num++;
+ }
+ }
+ osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
+ } else {
+ param->l2cap_inited = false;
+ }
}
#endif ///defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/pba/btc_pba_client.c b/lib/bt/host/bluedroid/btc/profile/std/pba/btc_pba_client.c
new file mode 100644
index 00000000..ede18df3
--- /dev/null
+++ b/lib/bt/host/bluedroid/btc/profile/std/pba/btc_pba_client.c
@@ -0,0 +1,968 @@
+/*
+ * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "osi/allocator.h"
+
+#include "bta/bta_api.h"
+#include "bta/bta_pba_defs.h"
+#include "bta/bta_pba_client_api.h"
+#include "btc/btc_profile_queue.h"
+#include "btc/btc_manage.h"
+#include "btc/btc_task.h"
+#include "btc_pba_client.h"
+#include "esp_pbac_api.h"
+
+#if BTC_PBA_CLIENT_INCLUDED
+
+#define BTC_PBA_CLIENT_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
+
+static bool s_btc_pba_client_init = 0;
+
+btc_pba_client_cb_t btc_pba_client_cb;
+
+static void bte_pba_client_evt(tBTA_PBA_CLIENT_EVT event, tBTA_PBA_CLIENT *p_data)
+{
+ bt_status_t status;
+ int param_len = 0;
+ bool ignore = false;
+
+ switch (event) {
+ case BTA_PBA_CLIENT_CONN_OPEN_EVT:
+ case BTA_PBA_CLIENT_CONN_CLOSE_EVT:
+ param_len = sizeof(tBTA_PBA_CLIENT_CONN);
+ break;
+ case BTA_PBA_CLIENT_PULL_PHONE_BOOK_RSP_EVT:
+ case BTA_PBA_CLIENT_SET_PHONE_BOOK_RSP_EVT:
+ case BTA_PBA_CLIENT_PULL_VCARD_LISTING_RSP_EVT:
+ case BTA_PBA_CLIENT_PULL_VCARD_ENTRY_RSP_EVT:
+ param_len = sizeof(tBTA_PBA_CLIENT_RESPONSE);
+ break;
+ case BTA_PBA_CLIENT_REGISTER_EVT:
+ param_len = 0;
+ break;
+ case BTA_PBA_CLIENT_DISABLE_EVT:
+ param_len = 0;
+ break;
+ case BTA_PBA_CLIENT_ENABLE_EVT:
+ case BTA_PBA_CLIENT_DEREGISTER_EVT:
+ default:
+ ignore = true;
+ break;
+ }
+
+ if (ignore) {
+ return;
+ }
+
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_PBA_CLIENT;
+ msg.act = event;
+
+ status = btc_transfer_context(&msg, p_data, param_len, NULL, NULL);
+ if (status != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("context transfer failed");
+ }
+}
+
+static void btc_pba_client_callback_to_app(esp_pbac_event_t event, esp_pbac_param_t *param)
+{
+ esp_pbac_callback_t callback = (esp_pbac_callback_t)btc_profile_cb_get(BTC_PID_PBA_CLIENT);
+ if (callback) {
+ callback(event, param);
+ }
+}
+
+static void btc_pba_client_init(void)
+{
+ if (!s_btc_pba_client_init) {
+ s_btc_pba_client_init = true;
+ memset(&btc_pba_client_cb, 0, sizeof(btc_pba_client_cb_t));
+ /* enable pba client */
+ BTA_PbaClientEnable(bte_pba_client_evt);
+ /* register sdp record */
+ BTA_PbaClientRegister("Phonebook Access PCE");
+ }
+}
+
+static void btc_pba_client_deinit(void)
+{
+ if (s_btc_pba_client_init) {
+ s_btc_pba_client_init = false;
+ /* deregister sdp record */
+ BTA_PbaClientDeregister();
+ /* disable pba client */
+ BTA_PbaClientDisable();
+ }
+}
+
+static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
+{
+ for (int i = 0; i < BTC_PBA_CLIENT_MAX_CONN_NUM; ++i) {
+ if (btc_pba_client_cb.ccb[i].handle != 0 && bdcmp(bd_addr->address, btc_pba_client_cb.ccb[i].bd_addr.address) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
+{
+ if (is_connected(bd_addr)) {
+ return BT_STATUS_BUSY;
+ }
+
+ BTA_PbaClientOpen(bd_addr->address, BTC_PBA_CLIENT_SECURITY, (uint32_t)BTC_PBA_SUPPORTED_FEAT, (uint16_t)BTC_PBA_PREFERRED_MTU);
+
+ return BT_STATUS_SUCCESS;
+}
+
+static void btc_pba_client_connect(bt_bdaddr_t *bd_addr)
+{
+ if (!s_btc_pba_client_init) {
+ return;
+ }
+
+ btc_queue_connect(UUID_SERVCLASS_PBAP_PCE, bd_addr, connect_int);
+}
+
+static void btc_pba_client_disconnect(uint16_t handle)
+{
+ do {
+ if (!s_btc_pba_client_init) {
+ break;
+ }
+
+ if (handle == 0 || handle > BTC_PBA_CLIENT_MAX_CONN_NUM) {
+ /* invalid handle value */
+ break;
+ }
+
+ btc_pba_client_ccb_t *p_ccb = &btc_pba_client_cb.ccb[handle - 1];
+ if (p_ccb->handle != handle) {
+ /* not connect */
+ break;
+ }
+
+ BTA_PbaClientClose(handle);
+ } while (0);
+}
+
+static bool btc_pba_client_pull_phone_book(uint16_t handle, char *name, bool include_app_param, esp_pbac_pull_phone_book_app_param_t *app_param)
+{
+ bt_status_t err = BT_STATUS_FAIL;
+ uint8_t *app_param_buff = NULL;
+ uint16_t app_param_len = 0;
+
+ do {
+ if (!s_btc_pba_client_init) {
+ /* pba client not init */
+ err = BT_STATUS_NOT_READY;
+ break;
+ }
+
+ if (handle == 0 || handle > BTC_PBA_CLIENT_MAX_CONN_NUM) {
+ /* invalid handle value */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ btc_pba_client_ccb_t *p_ccb = &btc_pba_client_cb.ccb[handle - 1];
+ if (p_ccb->handle != handle) {
+ /* not connect */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ if (p_ccb->busy) {
+ /* busy */
+ err = BT_STATUS_BUSY;
+ break;
+ }
+
+ if (include_app_param) {
+ app_param_buff = osi_malloc(BTA_PBAP_PULL_PHONE_BOOK_APP_PARAM_BUFF_SIZE_MIN);
+ if (app_param_buff == NULL) {
+ err = BT_STATUS_NOMEM;
+ break;
+ }
+ uint8_t *p = app_param_buff;
+ if (app_param->include_property_selector) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_PROPERTY_SELECTOR);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_PROPERTY_SELECTOR);
+ UINT64_TO_BE_STREAM(p, app_param->property_selector);
+ }
+ if (app_param->include_format) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_FORMAT);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_FORMAT);
+ UINT8_TO_BE_STREAM(p, app_param->format);
+ }
+ if (app_param->include_max_list_count) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_MAX_LIST_COUNT);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_MAX_LIST_COUNT);
+ UINT16_TO_BE_STREAM(p, app_param->max_list_count);
+ }
+ if (app_param->include_list_start_offset) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LIST_START_OFFSET);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_LIST_START_OFFSET);
+ UINT16_TO_BE_STREAM(p, app_param->list_start_offset);
+ }
+ if (app_param->include_reset_new_missed_calls) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_RESET_NEW_MISSED_CALLS);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_RESET_NEW_MISSED_CALLS);
+ UINT8_TO_BE_STREAM(p, app_param->reset_new_missed_calls);
+ }
+ if (app_param->include_vcard_selector) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_VCARD_SELECTOR);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_VCARD_SELECTOR);
+ UINT64_TO_BE_STREAM(p, app_param->vcard_selector);
+ }
+ if (app_param->include_vcard_selector_operator) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_VCARD_SELECTOR_OPERATOR);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_VCARD_SELECTOR_OPERATOR);
+ UINT8_TO_BE_STREAM(p, app_param->vcard_selector_operator);
+ }
+ app_param_len = p - app_param_buff;
+ assert(app_param_len <= BTA_PBAP_PULL_PHONE_BOOK_APP_PARAM_BUFF_SIZE_MIN);
+ if (app_param_len == 0) {
+ /* user give us an empty app param, allow but not recommend */
+ osi_free(app_param_buff);
+ app_param_buff = NULL;
+ }
+ }
+
+ p_ccb->busy = true;
+ BTA_PbaClientPullPhoneBook(handle, name, app_param_buff, app_param_len);
+ err = BT_STATUS_SUCCESS;
+ } while (0);
+
+ if (err != BT_STATUS_SUCCESS) {
+ BTC_TRACE_WARNING("%s failed, handle: %d, reason: %d", __FUNCTION__, handle, err);
+ return false;
+ }
+
+ return true;
+}
+
+static bool btc_pba_client_set_phone_book(uint16_t handle, uint8_t flags, char *name)
+{
+ bt_status_t err = BT_STATUS_FAIL;
+
+ do {
+ if (!s_btc_pba_client_init) {
+ /* pba client not init */
+ err = BT_STATUS_NOT_READY;
+ break;
+ }
+
+ if (handle == 0 || handle > BTC_PBA_CLIENT_MAX_CONN_NUM) {
+ /* invalid handle value */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ btc_pba_client_ccb_t *p_ccb = &btc_pba_client_cb.ccb[handle - 1];
+ if (p_ccb->handle != handle) {
+ /* not connect */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ if (p_ccb->busy) {
+ /* busy */
+ err = BT_STATUS_BUSY;
+ break;
+ }
+
+ p_ccb->busy = true;
+ BTA_PbaClientSetPhoneBook(handle, flags, (char *)name);
+ err = BT_STATUS_SUCCESS;
+ } while (0);
+
+ if (err != BT_STATUS_SUCCESS) {
+ BTC_TRACE_WARNING("%s failed, handle: %d, reason: %d", __FUNCTION__, handle, err);
+ return false;
+ }
+
+ return true;
+}
+
+static bool btc_pba_client_set_phone_book2(uint16_t handle, char *path)
+{
+ bt_status_t err = BT_STATUS_FAIL;
+
+ do {
+ if (!s_btc_pba_client_init) {
+ /* pba client not init */
+ err = BT_STATUS_NOT_READY;
+ break;
+ }
+
+ if (handle == 0 || handle > BTC_PBA_CLIENT_MAX_CONN_NUM) {
+ /* invalid handle value */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ btc_pba_client_ccb_t *p_ccb = &btc_pba_client_cb.ccb[handle - 1];
+ if (p_ccb->handle != handle) {
+ /* not connect */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ if (p_ccb->busy) {
+ /* busy */
+ err = BT_STATUS_BUSY;
+ break;
+ }
+
+ p_ccb->busy = true;
+ if (path != NULL) {
+ p_ccb->path_len = strlen(path) + 1;
+ /* ignore the first slash */
+ if (path[0] == '/') {
+ p_ccb->path_pos = 1;
+ }
+ else {
+ p_ccb->path_pos = 0;
+ }
+ /* since we use absolute path, treat empty path as go to ROOT */
+ if (p_ccb->path_len == p_ccb->path_pos + 1) {
+ p_ccb->path_len = 0;
+ p_ccb->path_pos = 0;
+ osi_free(path);
+ path = NULL;
+ }
+ else {
+ p_ccb->path = path;
+ }
+ }
+ /* anyway, go to ROOT first */
+ char *empty_name = osi_malloc(1);
+ assert(empty_name != NULL);
+ *empty_name = '\0';
+ BTA_PbaClientSetPhoneBook(handle, ESP_PBAC_SET_PHONE_BOOK_FLAGS_ROOT, empty_name);
+ err = BT_STATUS_SUCCESS;
+ } while (0);
+
+ if (err != BT_STATUS_SUCCESS) {
+ BTC_TRACE_WARNING("%s failed, handle: %d, reason: %d", __FUNCTION__, handle, err);
+ return false;
+ }
+
+ return true;
+}
+
+static bool btc_pba_client_pull_vcard_listing(uint16_t handle, char *name, bool include_app_param, esp_pbac_pull_vcard_listing_app_param_t *app_param)
+{
+ bt_status_t err = BT_STATUS_FAIL;
+ uint8_t *app_param_buff = NULL;
+ uint16_t app_param_len = 0;
+
+ do {
+ if (!s_btc_pba_client_init) {
+ /* pba client not init */
+ err = BT_STATUS_NOT_READY;
+ break;
+ }
+
+ if (handle == 0 || handle > BTC_PBA_CLIENT_MAX_CONN_NUM) {
+ /* invalid handle value */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ btc_pba_client_ccb_t *p_ccb = &btc_pba_client_cb.ccb[handle - 1];
+ if (p_ccb->handle != handle) {
+ /* not connect */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ if (p_ccb->busy) {
+ /* busy */
+ err = BT_STATUS_BUSY;
+ break;
+ }
+
+ if (include_app_param) {
+ uint8_t search_value_len = 0;
+ if (app_param->include_search_value) {
+ search_value_len = strlen(app_param->search_value) + 1;
+ }
+ app_param_buff = osi_malloc(BTA_PBAP_PULL_VCARD_LISTING_APP_PARAM_BUFF_SIZE_MIN + search_value_len);
+ if (app_param_buff == NULL) {
+ err = BT_STATUS_NOMEM;
+ break;
+ }
+
+ uint8_t *p = app_param_buff;
+ if (app_param->include_order) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_ORDER);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_ORDER);
+ UINT8_TO_BE_STREAM(p, app_param->order);
+ }
+ if (app_param->include_search_value) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_SEARCH_VALUE);
+ UINT8_TO_BE_STREAM(p, search_value_len);
+ memcpy(p, app_param->search_value, search_value_len);
+ p += search_value_len;
+ }
+ if (app_param->include_search_property) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_SEARCH_PROPERTY);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_SEARCH_PROPERTY);
+ UINT8_TO_BE_STREAM(p, app_param->search_property);
+ }
+ if (app_param->include_max_list_count) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_MAX_LIST_COUNT);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_MAX_LIST_COUNT);
+ UINT16_TO_BE_STREAM(p, app_param->max_list_count);
+ }
+ if (app_param->include_list_start_offset) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LIST_START_OFFSET);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_LIST_START_OFFSET);
+ UINT16_TO_BE_STREAM(p, app_param->list_start_offset);
+ }
+ if (app_param->include_reset_new_missed_calls) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_RESET_NEW_MISSED_CALLS);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_RESET_NEW_MISSED_CALLS);
+ UINT8_TO_BE_STREAM(p, app_param->reset_new_missed_calls);
+ }
+ if (app_param->include_vcard_selector) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_VCARD_SELECTOR);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_VCARD_SELECTOR);
+ UINT64_TO_BE_STREAM(p, app_param->vcard_selector);
+ }
+ if (app_param->include_vcard_selector_operator) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_VCARD_SELECTOR_OPERATOR);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_VCARD_SELECTOR_OPERATOR);
+ UINT8_TO_BE_STREAM(p, app_param->vcard_selector_operator);
+ }
+ app_param_len = p - app_param_buff;
+ assert(app_param_len <= BTA_PBAP_PULL_VCARD_LISTING_APP_PARAM_BUFF_SIZE_MIN + search_value_len);
+ if (app_param_len == 0) {
+ /* user give us an empty app param, allow but not recommend */
+ osi_free(app_param_buff);
+ app_param_buff = NULL;
+ }
+ /* free search_value (allocated by deep_copy) */
+ if (app_param->include_search_value && app_param->search_value) {
+ osi_free(app_param->search_value);
+ app_param->search_value = NULL;
+ }
+ }
+
+ p_ccb->busy = true;
+ BTA_PbaClientPullvCardListing(handle, (char *)name, app_param_buff, app_param_len);
+ err = BT_STATUS_SUCCESS;
+ } while (0);
+
+ if (err != BT_STATUS_SUCCESS) {
+ BTC_TRACE_WARNING("%s failed, handle: %d, reason: %d", __FUNCTION__, handle, err);
+ return false;
+ }
+
+ return true;
+}
+
+static bool btc_pba_client_pull_vcard_entry(uint16_t handle, char *name, bool include_app_param, esp_pbac_pull_vcard_entry_app_param_t *app_param)
+{
+ bt_status_t err = BT_STATUS_FAIL;
+ uint8_t *app_param_buff = NULL;
+ uint16_t app_param_len = 0;
+
+ do {
+ if (!s_btc_pba_client_init) {
+ /* pba client not init */
+ err = BT_STATUS_NOT_READY;
+ break;
+ }
+
+ if (handle == 0 || handle > BTC_PBA_CLIENT_MAX_CONN_NUM) {
+ /* invalid handle value */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ btc_pba_client_ccb_t *p_ccb = &btc_pba_client_cb.ccb[handle - 1];
+ if (p_ccb->handle != handle) {
+ /* not connect */
+ err = BT_STATUS_PARM_INVALID;
+ break;
+ }
+
+ if (p_ccb->busy) {
+ /* busy */
+ err = BT_STATUS_BUSY;
+ break;
+ }
+
+ if (include_app_param) {
+ app_param_buff = osi_malloc(BTA_PBAP_PULL_VCARD_ENTRY_APP_PARAM_BUFF_SIZE_MIN);
+ if (app_param_buff == NULL) {
+ err = BT_STATUS_NOMEM;
+ break;
+ }
+ uint8_t *p = app_param_buff;
+ if (app_param->include_property_selector) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_PROPERTY_SELECTOR);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_PROPERTY_SELECTOR);
+ UINT64_TO_BE_STREAM(p, app_param->property_selector);
+ }
+ if (app_param->include_format) {
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_FORMAT);
+ UINT8_TO_BE_STREAM(p, BTA_PBAP_APP_PARAM_LENGTH_FORMAT);
+ UINT8_TO_BE_STREAM(p, app_param->format);
+ }
+ app_param_len = p - app_param_buff;
+ assert(app_param_len <= BTA_PBAP_PULL_VCARD_ENTRY_APP_PARAM_BUFF_SIZE_MIN);
+ if (app_param_len == 0) {
+ /* user give us an empty app param, allow but not recommend */
+ osi_free(app_param_buff);
+ app_param_buff = NULL;
+ }
+ }
+
+ p_ccb->busy = true;
+ BTA_PbaClientPullvCardEntry(handle, (char *)name, app_param_buff, app_param_len);
+ err = BT_STATUS_SUCCESS;
+ } while (0);
+
+ if (err != BT_STATUS_SUCCESS) {
+ BTC_TRACE_WARNING("%s failed, handle: %d, reason: %d", __FUNCTION__, handle, err);
+ return false;
+ }
+
+ return true;
+}
+
+void btc_pba_client_args_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+ btc_pba_client_args_t *dst = (btc_pba_client_args_t *)p_dest;
+ btc_pba_client_args_t *src = (btc_pba_client_args_t *)p_src;
+ size_t len;
+
+ switch (msg->act) {
+ case BTC_PBA_CLIENT_PULL_PHONE_BOOK_EVT:
+ len = strlen(src->pull_phone_book.name) + 1;
+ dst->pull_phone_book.name = (char *)osi_malloc(len);
+ if (dst->pull_phone_book.name) {
+ memcpy(dst->pull_phone_book.name, src->pull_phone_book.name, len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n", __FUNCTION__, msg->act);
+ }
+ break;
+ case BTC_PBA_CLIENT_PULL_VCARD_LISTING_EVT:
+ len = strlen(src->pull_vcard_listing.name) + 1;
+ dst->pull_vcard_listing.name = (char *)osi_malloc(len);
+ if (dst->pull_vcard_listing.name) {
+ memcpy(dst->pull_vcard_listing.name, src->pull_vcard_listing.name, len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n", __FUNCTION__, msg->act);
+ }
+ if (src->pull_vcard_listing.include_app_param && src->pull_vcard_listing.app_param.include_search_value) {
+ len = strlen(src->pull_vcard_listing.app_param.search_value) + 1;
+ dst->pull_vcard_listing.app_param.search_value = (char *)osi_malloc(len);
+ if (dst->pull_vcard_listing.app_param.search_value) {
+ memcpy(dst->pull_vcard_listing.app_param.search_value, src->pull_vcard_listing.app_param.search_value, len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n", __FUNCTION__, msg->act);
+ }
+ }
+ break;
+ case BTC_PBA_CLIENT_PULL_VCARD_ENTRY_EVT:
+ len = strlen(src->pull_vcard_entry.name) + 1;
+ dst->pull_vcard_entry.name = (char *)osi_malloc(len);
+ if (dst->pull_vcard_entry.name) {
+ memcpy(dst->pull_vcard_entry.name, src->pull_vcard_entry.name, len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n", __FUNCTION__, msg->act);
+ }
+ break;
+ case BTC_PBA_CLIENT_SET_PHONE_BOOK_EVT:
+ case BTC_PBA_CLIENT_SET_PHONE_BOOK2_EVT:
+ /* set phone book name may be NULL */
+ if (src->set_phone_book.name) {
+ len = strlen(src->set_phone_book.name) + 1;
+ dst->set_phone_book.name = (char *)osi_malloc(len);
+ if (dst->set_phone_book.name) {
+ memcpy(dst->set_phone_book.name, src->set_phone_book.name, len);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n", __FUNCTION__, msg->act);
+ }
+ }
+ break;
+ default:
+ BTC_TRACE_DEBUG("%s Unhandled deep copy %d\n", __FUNCTION__, msg->act);
+ UNUSED(dst);
+ UNUSED(src);
+ UNUSED(len);
+ break;
+ }
+}
+
+void btc_pba_client_args_deep_free(btc_msg_t *msg)
+{
+ btc_pba_client_args_t *arg = (btc_pba_client_args_t *)msg->arg;
+
+ switch (msg->act) {
+ case BTC_PBA_CLIENT_PULL_PHONE_BOOK_EVT:
+ if (arg->pull_phone_book.name) {
+ osi_free(arg->pull_phone_book.name);
+ }
+ break;
+ case BTC_PBA_CLIENT_PULL_VCARD_LISTING_EVT:
+ if (arg->pull_vcard_listing.name) {
+ osi_free(arg->pull_vcard_listing.name);
+ }
+ if (arg->pull_vcard_listing.include_app_param
+ && arg->pull_vcard_listing.app_param.include_search_value
+ && arg->pull_vcard_listing.app_param.search_value) {
+ osi_free(arg->pull_vcard_listing.app_param.search_value);
+ }
+ break;
+ case BTC_PBA_CLIENT_PULL_VCARD_ENTRY_EVT:
+ if (arg->pull_vcard_entry.name) {
+ osi_free(arg->pull_vcard_entry.name);
+ }
+ break;
+ case BTC_PBA_CLIENT_SET_PHONE_BOOK_EVT:
+ case BTC_PBA_CLIENT_SET_PHONE_BOOK2_EVT:
+ if (arg->set_phone_book.name) {
+ osi_free(arg->set_phone_book.name);
+ }
+ break;
+ default:
+ BTC_TRACE_DEBUG("%s Unhandled deep free %d\n", __FUNCTION__, msg->act);
+ UNUSED(arg);
+ break;
+ }
+}
+
+void btc_pba_client_call_handler(btc_msg_t *msg)
+{
+ bool ret = true;
+ btc_pba_client_args_t *arg = (btc_pba_client_args_t *)(msg->arg);
+ switch (msg->act) {
+ case BTC_PBA_CLIENT_INIT_EVT:
+ btc_pba_client_init();
+ break;
+ case BTC_PBA_CLIENT_DEINIT_EVT:
+ btc_pba_client_deinit();
+ break;
+ case BTC_PBA_CLIENT_CONNECT_EVT:
+ btc_pba_client_connect(&arg->connect.bd_addr);
+ break;
+ case BTC_PBA_CLIENT_DISCONNECT_EVT:
+ btc_pba_client_disconnect(arg->disconnect.handle);
+ break;
+ case BTC_PBA_CLIENT_PULL_PHONE_BOOK_EVT:
+ ret = btc_pba_client_pull_phone_book(arg->pull_phone_book.handle, arg->pull_phone_book.name, arg->pull_phone_book.include_app_param, &arg->pull_phone_book.app_param);
+ break;
+ case BTC_PBA_CLIENT_SET_PHONE_BOOK_EVT:
+ ret = btc_pba_client_set_phone_book(arg->set_phone_book.handle, arg->set_phone_book.flags, arg->set_phone_book.name);
+ break;
+ case BTC_PBA_CLIENT_SET_PHONE_BOOK2_EVT:
+ ret = btc_pba_client_set_phone_book2(arg->set_phone_book.handle, arg->set_phone_book.name);
+ break;
+ case BTC_PBA_CLIENT_PULL_VCARD_LISTING_EVT:
+ ret = btc_pba_client_pull_vcard_listing(arg->pull_vcard_listing.handle, arg->pull_vcard_listing.name, arg->pull_vcard_listing.include_app_param, &arg->pull_vcard_listing.app_param);
+ break;
+ case BTC_PBA_CLIENT_PULL_VCARD_ENTRY_EVT:
+ ret = btc_pba_client_pull_vcard_entry(arg->pull_vcard_entry.handle, arg->pull_vcard_entry.name, arg->pull_vcard_entry.include_app_param, &arg->pull_vcard_entry.app_param);
+ break;
+ default:
+ BTC_TRACE_WARNING("unknown pba client action %i", msg->act);
+ break;
+ }
+
+ if (!ret) {
+ /* operation failed, do deep free */
+ btc_pba_client_args_deep_free(msg);
+ }
+}
+
+static void parse_pull_phone_book_app_param(esp_pbac_param_t *param, uint8_t *app_param, uint16_t app_param_len)
+{
+ if (app_param == NULL || app_param_len == 0) {
+ return;
+ }
+ uint8_t *ptr = app_param;
+ while(ptr < app_param + app_param_len) {
+ switch (*ptr)
+ {
+ case BTA_PBAP_APP_PARAM_PHONE_BOOK_SIZE:
+ param->pull_phone_book_rsp.include_phone_book_size = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ BE_STREAM_TO_UINT16(param->pull_phone_book_rsp.phone_book_size, ptr);
+ break;
+ case BTA_PBAP_APP_PARAM_NEW_MISSED_CALLS:
+ param->pull_phone_book_rsp.include_new_missed_calls = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ BE_STREAM_TO_UINT8(param->pull_phone_book_rsp.new_missed_calls, ptr);
+ break;
+ case BTA_PBAP_APP_PARAM_PRIMARY_FOLDER_VERSION:
+ param->pull_phone_book_rsp.include_primary_folder_version = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ /* don't copy */
+ param->pull_phone_book_rsp.primary_folder_version = ptr;
+ ptr += BTA_PBAP_APP_PARAM_LENGTH_PRIMARY_FOLDER_VERSION;
+ break;
+ case BTA_PBAP_APP_PARAM_SECONDARY_FOLDER_VERSION:
+ param->pull_phone_book_rsp.include_secondary_folder_version = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ /* don't copy */
+ param->pull_phone_book_rsp.secondary_folder_version = ptr;
+ ptr += BTA_PBAP_APP_PARAM_LENGTH_SECONDARY_FOLDER_VERSION;
+ break;
+ case BTA_PBAP_APP_PARAM_DATABASE_IDENTIFIER:
+ param->pull_phone_book_rsp.include_database_identifier = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ /* don't copy */
+ param->pull_phone_book_rsp.database_identifier = ptr;
+ ptr += BTA_PBAP_APP_PARAM_LENGTH_DATABASE_IDENTIFIER;
+ break;
+ default:
+ goto error;
+ break;
+ }
+ }
+error:
+ return;
+}
+
+static void parse_pull_vcard_listing_app_param(esp_pbac_param_t *param, uint8_t *app_param, uint16_t app_param_len)
+{
+ if (app_param == NULL || app_param_len == 0) {
+ return;
+ }
+ uint8_t *ptr = app_param;
+ while(ptr < app_param + app_param_len) {
+ switch (*ptr)
+ {
+ case BTA_PBAP_APP_PARAM_PHONE_BOOK_SIZE:
+ param->pull_vcard_listing_rsp.include_phone_book_size = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ BE_STREAM_TO_UINT16(param->pull_vcard_listing_rsp.phone_book_size, ptr);
+ break;
+ case BTA_PBAP_APP_PARAM_NEW_MISSED_CALLS:
+ param->pull_vcard_listing_rsp.include_new_missed_calls = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ BE_STREAM_TO_UINT8(param->pull_vcard_listing_rsp.new_missed_calls, ptr);
+ break;
+ case BTA_PBAP_APP_PARAM_PRIMARY_FOLDER_VERSION:
+ param->pull_vcard_listing_rsp.include_primary_folder_version = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ /* don't copy */
+ param->pull_vcard_listing_rsp.primary_folder_version = ptr;
+ ptr += BTA_PBAP_APP_PARAM_LENGTH_PRIMARY_FOLDER_VERSION;
+ break;
+ case BTA_PBAP_APP_PARAM_SECONDARY_FOLDER_VERSION:
+ param->pull_vcard_listing_rsp.include_secondary_folder_version = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ /* don't copy */
+ param->pull_vcard_listing_rsp.secondary_folder_version = ptr;
+ ptr += BTA_PBAP_APP_PARAM_LENGTH_SECONDARY_FOLDER_VERSION;
+ break;
+ case BTA_PBAP_APP_PARAM_DATABASE_IDENTIFIER:
+ param->pull_vcard_listing_rsp.include_database_identifier = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ /* don't copy */
+ param->pull_vcard_listing_rsp.database_identifier = ptr;
+ ptr += BTA_PBAP_APP_PARAM_LENGTH_DATABASE_IDENTIFIER;
+ break;
+ default:
+ goto error;
+ break;
+ }
+ }
+error:
+ return;
+}
+
+static void parse_pull_vcard_entry_app_param(esp_pbac_param_t *param, uint8_t *app_param, uint16_t app_param_len)
+{
+ if (app_param == NULL || app_param_len == 0) {
+ return;
+ }
+ uint8_t *ptr = app_param;
+ while(ptr < app_param + app_param_len) {
+ switch (*ptr)
+ {
+ case BTA_PBAP_APP_PARAM_DATABASE_IDENTIFIER:
+ param->pull_vcard_entry_rsp.include_database_identifier = 1;
+ ptr += BTA_PBAP_APP_PARAM_HEADER_LENGTH;
+ /* don't copy */
+ param->pull_vcard_entry_rsp.database_identifier = ptr;
+ ptr += BTA_PBAP_APP_PARAM_LENGTH_DATABASE_IDENTIFIER;
+ break;
+ default:
+ goto error;
+ break;
+ }
+ }
+error:
+ return;
+}
+
+static uint16_t get_next_dir_len_from_path(char *path, uint16_t path_len, uint16_t path_pos)
+{
+ uint16_t ret = 0;
+ for (int i = path_pos; i < path_len; ++i) {
+ if (path[i] == '/' || path[i] == '\0') {
+ break;
+ }
+ else {
+ ++ret;
+ }
+ }
+ return ret;
+}
+
+void btc_pba_client_cb_handler(btc_msg_t *msg)
+{
+ uint16_t event = msg->act;
+ tBTA_PBA_CLIENT *p_data = (tBTA_PBA_CLIENT *)msg->arg;
+ btc_pba_client_ccb_t *p_ccb = NULL;
+ esp_pbac_param_t param = {0};
+
+ switch (event) {
+ case BTA_PBA_CLIENT_CONN_OPEN_EVT:
+ if (p_data->conn.error == BTA_PBA_CLIENT_NO_ERROR) {
+ /* allocate ccb */
+ p_ccb = &btc_pba_client_cb.ccb[p_data->conn.handle - 1];
+ p_ccb->handle = p_data->conn.handle;
+ bdcpy(p_ccb->bd_addr.address, p_data->conn.bd_addr);
+ p_ccb->busy = false;
+ param.conn_stat.connected = true;
+ param.conn_stat.peer_supported_repo = p_data->conn.peer_supported_repo;
+ param.conn_stat.peer_supported_feat = p_data->conn.peer_supported_feat;
+ param.conn_stat.reason = BTA_PBA_CLIENT_NO_ERROR;
+ }
+ else {
+ param.conn_stat.connected = false;
+ /* error codes are compatible */
+ param.conn_stat.reason = p_data->conn.error;
+ }
+ bdcpy(param.conn_stat.remote_bda, p_data->conn.bd_addr);
+ param.conn_stat.handle = p_data->conn.handle;
+ btc_pba_client_callback_to_app(ESP_PBAC_CONNECTION_STATE_EVT, &param);
+ btc_queue_advance();
+ break;
+ case BTA_PBA_CLIENT_CONN_CLOSE_EVT:
+ if (p_data->conn.handle != 0) {
+ /* clear ccb */
+ p_ccb = &btc_pba_client_cb.ccb[p_data->conn.handle - 1];
+ if (p_ccb->path) {
+ osi_free(p_ccb->path);
+ }
+ memset(p_ccb, 0, sizeof(btc_pba_client_ccb_t));
+ }
+ param.conn_stat.connected = false;
+ bdcpy(param.conn_stat.remote_bda, p_data->conn.bd_addr);
+ param.conn_stat.handle = p_data->conn.handle;
+ /* error codes are compatible */
+ param.conn_stat.reason = p_data->conn.error;
+ btc_pba_client_callback_to_app(ESP_PBAC_CONNECTION_STATE_EVT, &param);
+ btc_queue_advance();
+ break;
+ case BTA_PBA_CLIENT_PULL_PHONE_BOOK_RSP_EVT:
+ if (p_data->response.final) {
+ p_ccb = &btc_pba_client_cb.ccb[p_data->response.handle - 1];
+ p_ccb->busy = false;
+ }
+ param.pull_phone_book_rsp.handle = p_data->response.handle;
+ param.pull_phone_book_rsp.final = p_data->response.final;
+ param.pull_phone_book_rsp.result = p_data->response.status;
+ param.pull_phone_book_rsp.data = p_data->response.data;
+ param.pull_phone_book_rsp.data_len = p_data->response.data_len;
+ parse_pull_phone_book_app_param(&param, p_data->response.app_param, p_data->response.app_param_len);
+ btc_pba_client_callback_to_app(ESP_PBAC_PULL_PHONE_BOOK_RESPONSE_EVT, &param);
+ if (p_data->response.pkt != NULL) {
+ osi_free(p_data->response.pkt);
+ }
+ break;
+ case BTA_PBA_CLIENT_SET_PHONE_BOOK_RSP_EVT:
+ p_ccb = &btc_pba_client_cb.ccb[p_data->response.handle - 1];
+ if (p_data->response.status == BTA_PBA_CLIENT_NO_ERROR && p_ccb->path_pos < p_ccb->path_len) {
+ /* since path_len is not zero, path should not be NULL, use asset to check */
+ assert(p_ccb->path != NULL);
+ uint16_t dir_name_len = get_next_dir_len_from_path(p_ccb->path, p_ccb->path_len, p_ccb->path_pos);
+ if (dir_name_len > 0) {
+ char *dir_name = osi_malloc(dir_name_len + 1);
+ assert(dir_name != NULL);
+ memcpy(dir_name, p_ccb->path + p_ccb->path_pos, dir_name_len);
+ dir_name[dir_name_len] = '\0';
+ p_ccb->path_pos += dir_name_len + 1;
+ BTA_PbaClientSetPhoneBook(p_data->response.handle, ESP_PBAC_SET_PHONE_BOOK_FLAGS_DOWN, dir_name);
+ /* break here, don't report event to upper */
+ break;
+ }
+ }
+ /* set path done or failed, clear status */
+ p_ccb->path_len = 0;
+ p_ccb->path_pos = 0;
+ if (p_ccb->path) {
+ osi_free(p_ccb->path);
+ p_ccb->path = NULL;
+ }
+ p_ccb->busy = false;
+ param.set_phone_book_rsp.handle = p_data->response.handle;
+ param.set_phone_book_rsp.result = p_data->response.status;
+ btc_pba_client_callback_to_app(ESP_PBAC_SET_PHONE_BOOK_RESPONSE_EVT, &param);
+ if (p_data->response.pkt != NULL) {
+ osi_free(p_data->response.pkt);
+ }
+ break;
+ case BTA_PBA_CLIENT_PULL_VCARD_LISTING_RSP_EVT:
+ if (p_data->response.final) {
+ p_ccb = &btc_pba_client_cb.ccb[p_data->response.handle - 1];
+ p_ccb->busy = false;
+ }
+ param.pull_vcard_listing_rsp.handle = p_data->response.handle;
+ param.pull_vcard_listing_rsp.final = p_data->response.final;
+ param.pull_vcard_listing_rsp.result = p_data->response.status;
+ param.pull_vcard_listing_rsp.data = p_data->response.data;
+ param.pull_vcard_listing_rsp.data_len = p_data->response.data_len;
+ parse_pull_vcard_listing_app_param(&param, p_data->response.app_param, p_data->response.app_param_len);
+ btc_pba_client_callback_to_app(ESP_PBAC_PULL_VCARD_LISTING_RESPONSE_EVT, &param);
+ if (p_data->response.pkt != NULL) {
+ osi_free(p_data->response.pkt);
+ }
+ break;
+ case BTA_PBA_CLIENT_PULL_VCARD_ENTRY_RSP_EVT:
+ if (p_data->response.final) {
+ p_ccb = &btc_pba_client_cb.ccb[p_data->response.handle - 1];
+ p_ccb->busy = false;
+ }
+ param.pull_vcard_entry_rsp.handle = p_data->response.handle;
+ param.pull_vcard_entry_rsp.final = p_data->response.final;
+ param.pull_vcard_entry_rsp.result = p_data->response.status;
+ param.pull_vcard_entry_rsp.data = p_data->response.data;
+ param.pull_vcard_entry_rsp.data_len = p_data->response.data_len;
+ parse_pull_vcard_entry_app_param(&param, p_data->response.app_param, p_data->response.app_param_len);
+ btc_pba_client_callback_to_app(ESP_PBAC_PULL_VCARD_ENTRY_RESPONSE_EVT, &param);
+ if (p_data->response.pkt != NULL) {
+ osi_free(p_data->response.pkt);
+ }
+ break;
+ case BTA_PBA_CLIENT_REGISTER_EVT:
+ /* init process: Enable -> Register */
+ btc_pba_client_callback_to_app(ESP_PBAC_INIT_EVT, NULL);
+ break;
+ case BTA_PBA_CLIENT_DISABLE_EVT:
+ /* deinit process: Deregister -> Disable */
+ btc_pba_client_callback_to_app(ESP_PBAC_DEINIT_EVT, NULL);
+ break;
+ default:
+ BTC_TRACE_WARNING("%s: unknown event (%d)", __func__, event);
+ break;
+ }
+}
+
+#endif
diff --git a/lib/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c b/lib/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c
index 6eaf6cfb..23ee72eb 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -9,6 +9,7 @@
#include "btc_sdp.h"
#include "btc/btc_manage.h"
#include "btc/btc_task.h"
+#include "btc/btc_util.h"
#include "bta/bta_sdp_api.h"
#include "bta/bta_sys.h"
#include "bta/utl.h"
@@ -17,7 +18,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 +26,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 +58,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 +82,33 @@ 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;
+
+ 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 +116,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;
+ 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);
- 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;
+ 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 +198,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 +209,88 @@ 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 */
-
- for(int i = 0; i < count; i++) {
- in_record = &in_records[i];
- out_record = &out_records[i];
- *out_record = *in_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;
- }
+ uint8_t *free_ptr = (uint8_t *)(out_record + 1); /* set pointer to after the last entry */
+
+ 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 = (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++;
+ }
+}
+
+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 +298,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 +383,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;
@@ -301,6 +392,7 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec)
UINT8 temp[LEN_UUID_128];
UINT8* p_temp = temp;
UINT32 sdp_handle = 0;
+ const esp_bt_uuid_t *p_uuid = &rec->hdr.uuid;
BTC_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n service name %s", __func__,
rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name);
@@ -310,15 +402,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 (p_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, p_uuid->uuid.uuid16);
+ } else if (p_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, p_uuid->uuid.uuid32);
+ } else if (p_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, p_uuid->uuid.uuid128, LEN_UUID_128);
} else {
SDP_DeleteRecord(sdp_handle);
sdp_handle = 0;
@@ -357,7 +449,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 +457,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 (p_uuid->len == ESP_UUID_LEN_16) {
+ bta_sys_add_uuid(p_uuid->uuid.uuid16);
+ } else if (p_uuid->len == ESP_UUID_LEN_32) {
+ bta_sys_add_uuid_32(p_uuid->uuid.uuid32);
+ } else if (p_uuid->len == ESP_UUID_LEN_128) {
+ bta_sys_add_uuid_128((UINT8 *)&p_uuid->uuid.uuid128);
}
BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle);
}
@@ -448,7 +540,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 +615,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 +695,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 +741,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 +828,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 +891,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,66 +906,209 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
return sdp_handle;
}
+static int add_dips_sdp(bluetooth_sdp_dip_record *rec)
+{
+ UINT32 sdp_handle = 0;
+ tBTA_DI_RECORD device_info = {0};
+
+ 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;
+
+ BTA_DmSetLocalDiRecord(&device_info, &sdp_handle);
+
+ return sdp_handle;
+}
+
static int btc_handle_create_record_event(int id)
{
- int handle = -1;
- const sdp_slot_t *sdp_slot = NULL;
+ 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__);
- sdp_slot = start_create_sdp(id);
- if(sdp_slot != NULL) {
- bluetooth_sdp_record* record = sdp_slot->record_data;
- switch(record->hdr.type) {
+ if (record != NULL) {
+ switch (record->hdr.type) {
case SDP_TYPE_RAW:
- handle = add_raw_sdp(record);
+ sdp_handle = add_raw_sdp(&record->raw);
+ memcpy(&service_uuid, &record->hdr.uuid, sizeof(esp_bt_uuid_t));
break;
case SDP_TYPE_MAP_MAS:
- handle = add_maps_sdp(&record->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:
- handle = add_mapc_sdp(&record->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:
- handle = add_pbaps_sdp(&record->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:
- handle = add_pbapc_sdp(&record->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:
- handle = add_opps_sdp(&record->ops);
+ 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:
- handle = add_saps_sdp(&record->sap);
+ 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);
+ BTC_TRACE_DEBUG("Record type %d is not supported", record->hdr.type);
break;
}
- if(handle != -1) {
- set_sdp_handle(id, handle);
+
+ 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;
}
- return handle;
+ if (sdp_handle == -1) {
+ free_sdp_slot(id);
+ }
+
+ return sdp_handle;
}
-static bool btc_sdp_remove_record_event(int 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};
- BTC_TRACE_DEBUG("Sdp Server %s", __func__);
+ get_sdp_slot_info(id, &sdp_handle, &service_uuid, &flag);
- if(handle != -1 && handle != 0) {
- result = SDP_DeleteRecord(handle);
- if(result == false) {
- BTC_TRACE_ERROR(" Unable to remove handle 0x%08x", handle);
+ 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;
}
}
return result;
}
+static void btc_sdp_cb_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+ switch (msg->act) {
+ case BTA_SDP_SEARCH_COMP_EVT: {
+ tBTA_SDP_SEARCH_COMP *src_search_comp = (tBTA_SDP_SEARCH_COMP *)p_src;
+ tBTA_SDP_SEARCH_COMP *dest_search_comp = (tBTA_SDP_SEARCH_COMP *)p_dest;
+ int record_count = src_search_comp->record_count;
+
+ for (int i = 0; i < record_count; i++) {
+ bluetooth_sdp_record *src_record = &src_search_comp->records[i];
+ bluetooth_sdp_record *dest_record = &dest_search_comp->records[i];
+ // deep copy service name
+ uint32_t src_service_name_length = src_record->hdr.service_name_length;
+ char *src_service_name = src_record->hdr.service_name;
+ dest_record->hdr.service_name_length = 0;
+ dest_record->hdr.service_name = NULL;
+ if (src_service_name && src_service_name_length) {
+ char *service_name = (char *)osi_malloc(src_service_name_length + 1);
+ if (service_name) {
+ memcpy(service_name, src_service_name, src_service_name_length);
+ service_name[src_service_name_length] = '\0';
+
+ dest_record->hdr.service_name_length = src_service_name_length;
+ dest_record->hdr.service_name = service_name;
+ } else {
+ BTC_TRACE_ERROR("%s malloc service name failed, orig service name:%s", __func__, src_service_name);
+ }
+ }
+
+ // deep copy user1_ptr fow RAW type
+ int src_user1_ptr_len = src_record->hdr.user1_ptr_len;
+ uint8_t *src_user1_ptr = src_record->hdr.user1_ptr;
+ dest_record->hdr.user1_ptr_len = 0;
+ dest_record->hdr.user1_ptr = NULL;
+ if (src_record->hdr.type == SDP_TYPE_RAW && src_user1_ptr && src_user1_ptr_len) {
+ uint8_t *user1_ptr = (uint8_t *)osi_malloc(src_user1_ptr_len);
+ if (user1_ptr) {
+ memcpy(user1_ptr, src_user1_ptr, src_user1_ptr_len);
+
+ dest_record->hdr.user1_ptr_len = src_user1_ptr_len;
+ dest_record->hdr.user1_ptr = user1_ptr;
+ } else {
+ BTC_TRACE_ERROR("%s malloc user1_ptr failed", __func__);
+ }
+ }
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void btc_sdp_cb_arg_deep_free(btc_msg_t *msg)
+{
+ switch (msg->act) {
+ case BTA_SDP_SEARCH_COMP_EVT: {
+ tBTA_SDP_SEARCH_COMP *search_comp = (tBTA_SDP_SEARCH_COMP *)msg->arg;
+ for (size_t i = 0; i < search_comp->record_count; i++) {
+ bluetooth_sdp_record *record = &search_comp->records[i];
+ if (record->hdr.service_name) {
+ osi_free(record->hdr.service_name);
+ }
+
+ if (record->hdr.user1_ptr) {
+ osi_free(record->hdr.user1_ptr);
+ }
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+}
+
static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_data)
{
btc_msg_t msg;
@@ -881,18 +1116,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;
}
}
}
@@ -905,7 +1140,7 @@ static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_da
msg.pid = BTC_PID_SDP;
msg.act = event;
- status = btc_transfer_context(&msg, p_data, sizeof(tBTA_SDP), NULL, NULL);
+ status = btc_transfer_context(&msg, p_data, sizeof(tBTA_SDP), btc_sdp_cb_arg_deep_copy, btc_sdp_cb_arg_deep_free);
if (status != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed", __func__);
@@ -930,23 +1165,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 +1195,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 +1204,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 +1221,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 +1232,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 +1250,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 +1260,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 +1290,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,26 +1312,21 @@ 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;
-
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));
+ case BTC_SDP_ACT_CREATE_RECORD: {
+ 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;
+ 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;
}
@@ -1116,17 +1334,15 @@ 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;
-
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);
+ case BTC_SDP_ACT_CREATE_RECORD: {
+ btc_sdp_args_t *arg = (btc_sdp_args_t *)msg->arg;
+ bluetooth_sdp_record *record = arg->create_record.record;
+ if (record) {
+ osi_free(record);
}
break;
+ }
default:
break;
}
@@ -1172,35 +1388,22 @@ 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));
- memcpy(&param.search.sdp_uuid, &p_data->sdp_search_comp.uuid, sizeof(tSDP_UUID));
- param.search.record_count = p_data->sdp_search_comp.record_count;
- param.search.records = osi_malloc(sizeof(esp_bluetooth_sdp_record_t)*p_data->sdp_search_comp.record_count);
- if (param.search.records != NULL) {
- memcpy(param.search.records, p_data->sdp_search_comp.records,
- sizeof(esp_bluetooth_sdp_record_t)*p_data->sdp_search_comp.record_count);
- } else {
- BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, event);
- param.search.status = ESP_SDP_NO_RESOURCE;
- }
- }
+ memcpy(param.search.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR));
+ bta_to_btc_uuid(&param.search.sdp_uuid, &p_data->sdp_search_comp.uuid);
+ param.search.record_count = p_data->sdp_search_comp.record_count;
+ param.search.records = (esp_bluetooth_sdp_record_t *)p_data->sdp_search_comp.records;
btc_sdp_cb_to_app(ESP_SDP_SEARCH_COMP_EVT, &param);
- if (param.search.records != NULL) {
- osi_free(param.search.records);
- }
break;
case BTA_SDP_CREATE_RECORD_USER_EVT:
param.create_record.status = p_data->sdp_create_record.status;
@@ -1208,13 +1411,41 @@ 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:
BTC_TRACE_DEBUG("%s: Unhandled event (%d)!", __func__, msg->act);
break;
}
+
+ btc_sdp_cb_arg_deep_free(msg);
+}
+
+void btc_sdp_get_protocol_status(esp_sdp_protocol_status_t *param)
+{
+ if (is_sdp_init()) {
+ param->sdp_inited = true;
+ osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
+ for (size_t i = 0; i <= SDP_MAX_RECORDS; i++) {
+ if (sdp_local_param.sdp_slots[i] != NULL && sdp_local_param.sdp_slots[i]->state == SDP_RECORD_ALLOCED) {
+ param->records_num++;
+ }
+ }
+ osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
+ } else {
+ param->sdp_inited = false;
+ }
}
-#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE
+#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c b/lib/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c
index cf334494..bb142531 100644
--- a/lib/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c
+++ b/lib/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -909,6 +909,9 @@ static void btc_spp_write(btc_spp_args_t *arg)
} else {
if (fixed_queue_enqueue(slot->tx.queue, arg->write.p_data, 0)) {
BTA_JvRfcommWrite(arg->write.handle, slot->id, arg->write.len, arg->write.p_data);
+ // The TX queue of SPP will handle this memory properly.
+ // Set it to NULL here to prevent deep free handler from releasing it.
+ arg->write.p_data = NULL;
} else {
ret = ESP_SPP_NO_RESOURCE;
}
@@ -966,6 +969,13 @@ void btc_spp_arg_deep_free(btc_msg_t *msg)
case BTC_SPP_ACT_START_DISCOVERY:
if (arg->start_discovery.p_uuid_list) {
osi_free(arg->start_discovery.p_uuid_list);
+ arg->start_discovery.p_uuid_list = NULL;
+ }
+ break;
+ case BTC_SPP_ACT_WRITE:
+ if (arg->write.p_data) {
+ osi_free(arg->write.p_data);
+ arg->write.p_data = NULL;
}
break;
default:
@@ -1099,7 +1109,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
break;
case BTA_JV_RFCOMM_WRITE_EVT:
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = spp_find_slot_by_handle(p_data->rfc_write.handle);
+ slot = spp_find_slot_by_id(p_data->rfc_write.req_id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!, handle:%d", __func__, p_data->rfc_write.handle);
}
@@ -1165,7 +1175,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
param.close.async = p_data->rfc_close.async;
if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) {
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = spp_find_slot_by_handle(p_data->rfc_close.handle);
+ slot = spp_find_slot_by_id((uint32_t)p_data->rfc_close.user_data);
if (!slot) {
param.close.status = ESP_SPP_NO_CONNECTION;
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
@@ -1179,7 +1189,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
bool need_call = true;
do {
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = spp_find_slot_by_handle(p_data->rfc_close.handle);
+ slot = spp_find_slot_by_id((uint32_t)p_data->rfc_close.user_data);
if (!slot) {
param.close.status = ESP_SPP_NO_CONNECTION;
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
@@ -1199,7 +1209,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
slot->alarm_arg = (void *)p_arg;
if ((slot->close_alarm =
osi_alarm_new("slot", close_timeout_handler, (void *)slot, VFS_CLOSE_TIMEOUT)) == NULL) {
- free(p_arg);
+ osi_free(p_arg);
slot->alarm_arg = NULL;
param.close.status = ESP_SPP_NO_RESOURCE;
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
@@ -1207,7 +1217,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
break;
}
if (osi_alarm_set(slot->close_alarm, VFS_CLOSE_TIMEOUT) != OSI_ALARM_ERR_PASS) {
- free(p_arg);
+ osi_free(p_arg);
slot->alarm_arg = NULL;
osi_alarm_free(slot->close_alarm);
param.close.status = ESP_SPP_BUSY;
@@ -1488,7 +1498,7 @@ static ssize_t spp_vfs_write(int fd, const void * data, size_t size)
BTC_TRACE_DEBUG("%s items_waiting:%d, fd:%d\n", __func__, items_waiting, fd);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
- // block untill under water level, be closed or time out
+ // block until under water level, be closed or time out
tx_event_group_val =
xEventGroupWaitBits(spp_local_param.tx_event_group, SLOT_WRITE_BIT(serial) | SLOT_CLOSE_BIT(serial), pdTRUE,
pdFALSE, VFS_WRITE_TIMEOUT / portTICK_PERIOD_MS);
@@ -1687,4 +1697,20 @@ static void btc_spp_vfs_unregister(void)
btc_spp_cb_to_app(ESP_SPP_VFS_UNREGISTER_EVT, &param);
}
+void btc_spp_get_profile_status(esp_spp_profile_status_t *param)
+{
+ if (is_spp_init()) {
+ param->spp_inited = true;
+ osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
+ for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
+ if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected) {
+ param->conn_num++;
+ }
+ }
+ osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
+ } else {
+ param->spp_inited = false;
+ }
+}
+
#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE
diff --git a/lib/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/lib/bt/host/bluedroid/common/include/common/bluedroid_user_config.h
index 81cfbaac..16a6320d 100644
--- a/lib/bt/host/bluedroid/common/include/common/bluedroid_user_config.h
+++ b/lib/bt/host/bluedroid/common/include/common/bluedroid_user_config.h
@@ -39,6 +39,25 @@
#define UC_BT_A2DP_ENABLED FALSE
#endif
+#ifdef CONFIG_BT_A2DP_USE_EXTERNAL_CODEC
+#define UC_BT_A2DP_USE_EXTERNAL_CODEC CONFIG_BT_A2DP_USE_EXTERNAL_CODEC
+#else
+#define UC_BT_A2DP_USE_EXTERNAL_CODEC 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 +67,37 @@
//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
+
+// SDP Pad Length
+#ifdef CONFIG_BT_SDP_PAD_LEN
+#define UC_SDP_MAX_PAD_LEN CONFIG_BT_SDP_PAD_LEN
+#else
+#define UC_SDP_MAX_PAD_LEN 300
+#endif
+
+// SDP Max Attribute Length
+#ifdef CONFIG_BT_SDP_ATTR_LEN
+#define UC_SDP_MAX_ATTR_LEN CONFIG_BT_SDP_ATTR_LEN
+#else
+#define UC_SDP_MAX_ATTR_LEN 300
#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)
@@ -67,6 +107,12 @@
#define UC_BT_HFP_CLIENT_ENABLED FALSE
#endif
+#ifdef CONFIG_BT_HFP_USE_EXTERNAL_CODEC
+#define UC_BT_HFP_USE_EXTERNAL_CODEC CONFIG_BT_HFP_USE_EXTERNAL_CODEC
+#else
+#define UC_BT_HFP_USE_EXTERNAL_CODEC FALSE
+#endif
+
//HID
#ifdef CONFIG_BT_HID_ENABLED
#define UC_BT_HID_ENABLED CONFIG_BT_HID_ENABLED
@@ -88,6 +134,13 @@
#define UC_BT_HID_DEVICE_ENABLED FALSE
#endif
+//HID remove device bonding option
+#ifdef CONFIG_BT_HID_REMOVE_DEVICE_BONDING_ENABLED
+#define UC_BT_HID_REMOVE_DEVICE_BONDING_ENABLED CONFIG_BT_HID_REMOVE_DEVICE_BONDING_ENABLED
+#else
+#define UC_BT_HID_REMOVE_DEVICE_BONDING_ENABLED FALSE
+#endif
+
//BQB(BT)
#ifdef CONFIG_BT_CLASSIC_BQB_ENABLED
#define UC_BT_CLASSIC_BQB_ENABLED CONFIG_BT_CLASSIC_BQB_ENABLED
@@ -104,6 +157,32 @@
#define UC_BT_ENC_KEY_SIZE_CTRL_MODE 0
#endif
+//PBAP Client
+#ifdef CONFIG_BT_PBAC_ENABLED
+#define UC_BT_PBAC_ENABLED CONFIG_BT_PBAC_ENABLED
+#else
+#define UC_BT_PBAC_ENABLED FALSE
+#endif
+
+#ifdef CONFIG_BT_PBAC_SUPPORTED_FEAT
+#define UC_BT_PBAC_SUPPORTED_FEAT CONFIG_BT_PBAC_SUPPORTED_FEAT
+#else
+#define UC_BT_PBAC_SUPPORTED_FEAT 0x00
+#endif
+
+#ifdef CONFIG_BT_PBAC_PREFERRED_MTU
+#define UC_BT_PBAC_PREFERRED_MTU CONFIG_BT_PBAC_PREFERRED_MTU
+#else
+#define UC_BT_PBAC_PREFERRED_MTU 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
@@ -133,12 +212,60 @@
#define UC_BT_BLE_42_FEATURES_SUPPORTED FALSE
#endif
+#ifdef CONFIG_BT_BLE_42_DTM_TEST_EN
+#define UC_BT_BLE_42_DTM_TEST_EN CONFIG_BT_BLE_42_DTM_TEST_EN
+#else
+#define UC_BT_BLE_42_DTM_TEST_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_42_ADV_EN
+#define UC_BT_BLE_42_ADV_EN CONFIG_BT_BLE_42_ADV_EN
+#else
+#define UC_BT_BLE_42_ADV_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_42_SCAN_EN
+#define UC_BT_BLE_42_SCAN_EN CONFIG_BT_BLE_42_SCAN_EN
+#else
+#define UC_BT_BLE_42_SCAN_EN FALSE
+#endif
+
#ifdef CONFIG_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER
#define UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER CONFIG_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER
#else
#define UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE
#endif
+#ifdef CONFIG_BT_BLE_50_EXTEND_ADV_EN
+#define UC_BT_BLE_50_EXTEND_ADV_EN CONFIG_BT_BLE_50_EXTEND_ADV_EN
+#else
+#define UC_BT_BLE_50_EXTEND_ADV_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_50_PERIODIC_ADV_EN
+#define UC_BT_BLE_50_PERIODIC_ADV_EN CONFIG_BT_BLE_50_PERIODIC_ADV_EN
+#else
+#define UC_BT_BLE_50_PERIODIC_ADV_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_50_EXTEND_SCAN_EN
+#define UC_BT_BLE_50_EXTEND_SCAN_EN CONFIG_BT_BLE_50_EXTEND_SCAN_EN
+#else
+#define UC_BT_BLE_50_EXTEND_SCAN_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_50_EXTEND_SYNC_EN
+#define UC_BT_BLE_50_EXTEND_SYNC_EN CONFIG_BT_BLE_50_EXTEND_SYNC_EN
+#else
+#define UC_BT_BLE_50_EXTEND_SYNC_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_50_DTM_TEST_EN
+#define UC_BT_BLE_50_DTM_TEST_EN CONFIG_BT_BLE_50_DTM_TEST_EN
+#else
+#define UC_BT_BLE_50_DTM_TEST_EN FALSE
+#endif
+
#ifdef CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH
#define UC_BT_BLE_FEAT_PERIODIC_ADV_ENH CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH
#else
@@ -151,6 +278,98 @@
#define UC_BT_BLE_FEAT_CREATE_SYNC_ENH FALSE
#endif
+#ifdef CONFIG_BT_BLE_FEAT_ISO_EN
+#define UC_BT_BLE_FEAT_ISO_EN CONFIG_BT_BLE_FEAT_ISO_EN
+#else
+#define UC_BT_BLE_FEAT_ISO_EN FALSE
+#endif
+
+#if CONFIG_BT_BLE_FEAT_ISO_60_EN
+#define UC_BT_BLE_FEAT_ISO_60_EN CONFIG_BT_BLE_FEAT_ISO_60_EN
+#else
+#define UC_BT_BLE_FEAT_ISO_60_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_ISO_BIG_SYNCER
+#define UC_BT_BLE_FEAT_ISO_BIG_SYNCER CONFIG_BT_BLE_FEAT_ISO_BIG_SYNCER
+#else
+#define UC_BT_BLE_FEAT_ISO_BIG_SYNCER FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_ISO_BIG_BROCASTER
+#define UC_BT_BLE_FEAT_ISO_BIG_BROCASTER CONFIG_BT_BLE_FEAT_ISO_BIG_BROCASTER
+#else
+#define UC_BT_BLE_FEAT_ISO_BIG_BROCASTER FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_ISO_CIG_CENTRAL
+#define UC_BT_BLE_FEAT_ISO_CIG_CENTRAL CONFIG_BT_BLE_FEAT_ISO_CIG_CENTRAL
+#else
+#define UC_BT_BLE_FEAT_ISO_CIG_CENTRAL FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_ISO_CIG_PERIPHERAL
+#define UC_BT_BLE_FEAT_ISO_CIG_PERIPHERAL CONFIG_BT_BLE_FEAT_ISO_CIG_PERIPHERAL
+#else
+#define UC_BT_BLE_FEAT_ISO_CIG_PERIPHERAL FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_ISO_CIS_MAX_COUNT
+#define UC_BT_BLE_ISO_CIS_MAX_COUNT CONFIG_BT_BLE_ISO_CIS_MAX_COUNT
+#else
+#define UC_BT_BLE_ISO_CIS_MAX_COUNT (0)
+#endif
+
+#ifdef CONFIG_BT_BLE_ISO_BIS_MAX_COUNT
+#define UC_BT_BLE_ISO_BIS_MAX_COUNT CONFIG_BT_BLE_ISO_BIS_MAX_COUNT
+#else
+#define UC_BT_BLE_ISO_BIS_MAX_COUNT (0)
+#endif
+
+#ifdef CONFIG_BT_BLE_ISO_STD_FLOW_CTRL
+#define UC_BT_BLE_ISO_STD_FLOW_CTRL CONFIG_BT_BLE_ISO_STD_FLOW_CTRL
+#endif
+
+#ifdef CONFIG_BT_BLE_ISO_NON_STD_FLOW_CTRL
+#define UC_BT_BLE_ISO_NON_STD_FLOW_CTRL CONFIG_BT_BLE_ISO_NON_STD_FLOW_CTRL
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_CTE_EN
+#define UC_BT_BLE_FEAT_CTE_EN CONFIG_BT_BLE_FEAT_CTE_EN
+#else
+#define UC_BT_BLE_FEAT_CTE_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN
+#define UC_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN CONFIG_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN
+#else
+#define UC_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_CTE_CONNECTION_EN
+#define UC_BT_BLE_FEAT_CTE_CONNECTION_EN CONFIG_BT_BLE_FEAT_CTE_CONNECTION_EN
+#else
+#define UC_BT_BLE_FEAT_CTE_CONNECTION_EN FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_POWER_CONTROL
+#define UC_BT_BLE_FEAT_POWER_CONTROL CONFIG_BT_BLE_FEAT_POWER_CONTROL
+#else
+#define UC_BT_BLE_FEAT_POWER_CONTROL FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_FEAT_CONN_SUBRATING
+#define UC_BT_BLE_FEAT_CONN_SUBRATING CONFIG_BT_BLE_FEAT_CONN_SUBRATING
+#else
+#define UC_BT_BLE_FEAT_CONN_SUBRATING FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_VENDOR_HCI_EN
+#define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN
+#else
+#define UC_BT_BLE_VENDOR_HCI_EN FALSE
+#endif
+
#ifdef CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL
#define UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL
#else
@@ -218,7 +437,19 @@
#define UC_BT_SMP_MAX_BONDS 8
#endif
-//Device Nane Maximum Length
+#ifdef CONFIG_BT_BLE_SMP_ID_RESET_ENABLE
+#define UC_BT_BLE_SMP_ID_RESET_ENABLE CONFIG_BT_BLE_SMP_ID_RESET_ENABLE
+#else
+#define UC_BT_BLE_SMP_ID_RESET_ENABLE FALSE
+#endif
+
+#ifdef CONFIG_BT_BLE_SMP_BOND_NVS_FLASH
+#define UC_BT_BLE_SMP_BOND_NVS_FLASH CONFIG_BT_BLE_SMP_BOND_NVS_FLASH
+#else
+#define UC_BT_BLE_SMP_BOND_NVS_FLASH FALSE
+#endif
+
+//Device Name Maximum Length
#ifdef CONFIG_BT_MAX_DEVICE_NAME_LEN
#define UC_MAX_LOC_BD_NAME_LEN CONFIG_BT_MAX_DEVICE_NAME_LEN
#else
@@ -294,14 +525,6 @@
#define UC_BT_BLE_ESTAB_LINK_CONN_TOUT 30
#endif
-
-//HOST QUEUE CONGEST CHECK
-#ifdef CONFIG_BT_BLE_HOST_QUEUE_CONGESTION_CHECK
-#define UC_BT_BLE_HOST_QUEUE_CONGESTION_CHECK CONFIG_BT_BLE_HOST_QUEUE_CONGESTION_CHECK
-#else
-#define UC_BT_BLE_HOST_QUEUE_CONGESTION_CHECK FALSE
-#endif
-
#ifdef CONFIG_BT_GATTS_PPCP_CHAR_GAP
#define UC_CONFIG_BT_GATTS_PPCP_CHAR_GAP CONFIG_BT_GATTS_PPCP_CHAR_GAP
#else
@@ -375,20 +598,6 @@
* Memory reference
**********************************************************/
-//MEMORY ALLOCATOR
-#ifdef CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
-#define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
-#else
-#define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE
-#endif
-
-//MEMORY DEBUG
-#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
-#define UC_BT_BLUEDROID_MEM_DEBUG CONFIG_BT_BLUEDROID_MEM_DEBUG
-#else
-#define UC_BT_BLUEDROID_MEM_DEBUG FALSE
-#endif
-
//ESP COEXIST VSC
#ifdef CONFIG_BT_BLUEDROID_ESP_COEX_VSC
#define UC_BT_BLUEDROID_ESP_COEX_VSC CONFIG_BT_BLUEDROID_ESP_COEX_VSC
diff --git a/lib/bt/host/bluedroid/common/include/common/bt_target.h b/lib/bt/host/bluedroid/common/include/common/bt_target.h
index 0adad84f..d1dfd177 100644
--- a/lib/bt/host/bluedroid/common/include/common/bt_target.h
+++ b/lib/bt/host/bluedroid/common/include/common/bt_target.h
@@ -88,9 +88,19 @@
#define BTC_AV_INCLUDED TRUE
#define BTA_AV_SINK_INCLUDED TRUE
#define BTC_AV_SINK_INCLUDED TRUE
-#define SBC_DEC_INCLUDED TRUE
#define BTC_AV_SRC_INCLUDED TRUE
+#if (UC_BT_A2DP_USE_EXTERNAL_CODEC == TRUE)
+#define BTC_AV_EXT_CODEC TRUE
+#define BTA_AV_EXT_CODEC TRUE
+#else
+#define SBC_DEC_INCLUDED TRUE
#define SBC_ENC_INCLUDED TRUE
+#endif
+#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 +113,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
@@ -114,14 +127,22 @@
#ifndef BTM_SCO_INCLUDED
#define BTM_SCO_INCLUDED TRUE
#endif
+#if (UC_BT_HFP_AUDIO_DATA_PATH_HCI == TRUE)
+#if (UC_BT_HFP_USE_EXTERNAL_CODEC == TRUE)
+#define BTC_HFP_EXT_CODEC TRUE
+#define BTA_HFP_EXT_CODEC TRUE
+#define PLC_INCLUDED FALSE
+#else
#ifndef SBC_DEC_INCLUDED
#define SBC_DEC_INCLUDED TRUE
#endif
#ifndef SBC_ENC_INCLUDED
#define SBC_ENC_INCLUDED TRUE
#endif
-#ifndef PLC_INCLUDED
#define PLC_INCLUDED TRUE
+#endif /* (UC_BT_HFP_USE_EXTERNAL_CODEC == TRUE) */
+#else
+#define PLC_INCLUDED FALSE
#endif
#if (UC_BT_HFP_AG_ENABLED == TRUE)
@@ -168,6 +189,27 @@
#define BTC_HD_INCLUDED TRUE
#endif /* UC_BT_HID_DEVICE_ENABLED */
+#if UC_BT_HID_REMOVE_DEVICE_BONDING_ENABLED
+#define BTC_HID_REMOVE_DEVICE_BONDING TRUE
+#endif
+
+#if UC_BT_GOEPC_ENABLED
+#ifndef RFCOMM_INCLUDED
+#define RFCOMM_INCLUDED TRUE
+#endif
+#ifndef OBEX_INCLUDED
+#define OBEX_INCLUDED TRUE
+#endif
+#define GOEPC_INCLUDED TRUE
+#endif /* UC_BT_GOEPC_ENABLED */
+
+#if UC_BT_PBAC_ENABLED
+#define BTC_PBA_CLIENT_INCLUDED TRUE
+#define BTC_PBA_SUPPORTED_FEAT UC_BT_PBAC_SUPPORTED_FEAT
+#define BTC_PBA_PREFERRED_MTU UC_BT_PBAC_PREFERRED_MTU
+#define BTA_PBA_CLIENT_INCLUDED TRUE
+#endif
+
#endif /* UC_BT_CLASSIC_ENABLED */
/* This is set to enable use of GAP L2CAP connections. */
@@ -200,11 +242,64 @@
#define BLE_50_FEATURE_SUPPORT FALSE
#endif
+#if (UC_BT_BLE_ENABLED ==TRUE)
#if (UC_BT_BLE_42_FEATURES_SUPPORTED == TRUE || BLE_50_FEATURE_SUPPORT == FALSE)
#define BLE_42_FEATURE_SUPPORT TRUE
#else
#define BLE_42_FEATURE_SUPPORT FALSE
#endif
+#else
+#define BLE_42_FEATURE_SUPPORT FALSE
+#define BLE_50_FEATURE_SUPPORT FALSE
+#endif /* UC_BT_BLE_ENABLED */
+
+#if (UC_BT_BLE_42_DTM_TEST_EN == TRUE)
+#define BLE_42_DTM_TEST_EN TRUE
+#else
+#define BLE_42_DTM_TEST_EN FALSE
+#endif
+
+#if (UC_BT_BLE_42_ADV_EN == TRUE)
+#define BLE_42_ADV_EN TRUE
+#else
+#define BLE_42_ADV_EN FALSE
+#endif
+
+#if (UC_BT_BLE_42_SCAN_EN == TRUE)
+#define BLE_42_SCAN_EN TRUE
+#else
+#define BLE_42_SCAN_EN FALSE
+#endif
+
+#if (UC_BT_BLE_50_EXTEND_ADV_EN == TRUE)
+#define BLE_50_EXTEND_ADV_EN TRUE
+#else
+#define BLE_50_EXTEND_ADV_EN FALSE
+#endif
+
+#if (UC_BT_BLE_50_PERIODIC_ADV_EN == TRUE)
+#define BLE_50_PERIODIC_ADV_EN TRUE
+#else
+#define BLE_50_PERIODIC_ADV_EN FALSE
+#endif
+
+#if (UC_BT_BLE_50_EXTEND_SCAN_EN == TRUE)
+#define BLE_50_EXTEND_SCAN_EN TRUE
+#else
+#define BLE_50_EXTEND_SCAN_EN FALSE
+#endif
+
+#if (UC_BT_BLE_50_EXTEND_SYNC_EN == TRUE)
+#define BLE_50_EXTEND_SYNC_EN TRUE
+#else
+#define BLE_50_EXTEND_SYNC_EN FALSE
+#endif
+
+#if (UC_BT_BLE_50_DTM_TEST_EN == TRUE)
+#define BLE_50_DTM_TEST_EN TRUE
+#else
+#define BLE_50_DTM_TEST_EN FALSE
+#endif
#if (UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER TRUE
@@ -224,6 +319,108 @@
#define BLE_FEAT_CREATE_SYNC_ENH FALSE
#endif
+#if (UC_BT_BLE_FEAT_ISO_EN == TRUE)
+#define BLE_FEAT_ISO_EN TRUE
+#else
+#define BLE_FEAT_ISO_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_ISO_60_EN == TRUE)
+#define BLE_FEAT_ISO_60_EN TRUE
+#else
+#define BLE_FEAT_ISO_60_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_ISO_BIG_BROCASTER == TRUE)
+#define BLE_FEAT_ISO_BIG_BROCASTER_EN TRUE
+#else
+#define BLE_FEAT_ISO_BIG_BROCASTER_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_ISO_BIG_SYNCER == TRUE)
+#define BLE_FEAT_ISO_BIG_SYNCER_EN TRUE
+#else
+#define BLE_FEAT_ISO_BIG_SYNCER_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_ISO_CIG_CENTRAL == TRUE)
+#define BLE_FEAT_ISO_CIG_CENTRAL_EN TRUE
+#else
+#define BLE_FEAT_ISO_CIG_CENTRAL_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_ISO_CIG_PERIPHERAL == TRUE)
+#define BLE_FEAT_ISO_CIG_PERIPHERAL_EN TRUE
+#else
+#define BLE_FEAT_ISO_CIG_PERIPHERAL_EN FALSE
+#endif
+
+#if ((BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) || (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE))
+#define BLE_FEAT_ISO_CIG_EN TRUE
+#else
+#define BLE_FEAT_ISO_CIG_EN FALSE
+#endif
+
+#ifdef UC_BT_BLE_ISO_CIS_MAX_COUNT
+#define BLE_ISO_CIS_MAX_COUNT UC_BT_BLE_ISO_CIS_MAX_COUNT
+#else
+#define BLE_ISO_CIS_MAX_COUNT (0)
+#endif
+
+#ifdef CONFIG_BT_BLE_ISO_BIS_MAX_COUNT
+#define BLE_ISO_BIS_MAX_COUNT CONFIG_BT_BLE_ISO_BIS_MAX_COUNT
+#else
+#define BLE_ISO_BIS_MAX_COUNT (0)
+#endif
+
+#ifdef UC_BT_BLE_ISO_STD_FLOW_CTRL
+#define BLE_ISO_STD_FLOW_CTRL TRUE
+#endif
+
+#ifdef UC_BT_BLE_ISO_NON_STD_FLOW_CTRL
+#define BLE_ISO_NON_STD_FLOW_CTRL TRUE
+#endif
+
+#if ((UC_BT_BLE_ISO_STD_FLOW_CTRL == TRUE) && (UC_BT_BLE_ISO_NON_STD_FLOW_CTRL == TRUE))
+#error "Only one of standard or non-standard can be enabled"
+#endif
+
+#if (UC_BT_BLE_FEAT_CTE_EN == TRUE)
+#define BLE_FEAT_CTE_EN TRUE
+#else
+#define BLE_FEAT_CTE_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#define BLE_FEAT_CTE_CONNECTIONLESS_EN TRUE
+#else
+#define BLE_FEAT_CTE_CONNECTIONLESS_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define BLE_FEAT_CTE_CONNECTION_EN TRUE
+#else
+#define BLE_FEAT_CTE_CONNECTION_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_POWER_CONTROL == TRUE)
+#define BLE_FEAT_POWER_CONTROL_EN TRUE
+#else
+#define BLE_FEAT_POWER_CONTROL_EN FALSE
+#endif
+
+#if (UC_BT_BLE_FEAT_CONN_SUBRATING == TRUE)
+#define BLE_FEAT_CONN_SUBRATING TRUE
+#else
+#define BLE_FEAT_CONN_SUBRATING FALSE
+#endif
+
+#if (UC_BT_BLE_VENDOR_HCI_EN == TRUE)
+#define BLE_VENDOR_HCI_EN TRUE
+#else
+#define BLE_VENDOR_HCI_EN FALSE
+#endif
+
#if (UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL == TRUE)
#define BLE_HIGH_DUTY_ADV_INTERVAL TRUE
#else
@@ -290,6 +487,18 @@
#define SMP_SLAVE_CON_PARAMS_UPD_ENABLE FALSE
#endif /* UC_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE */
+#if (UC_BT_BLE_SMP_ID_RESET_ENABLE)
+#define BLE_SMP_ID_RESET_ENABLE TRUE
+#else
+#define BLE_SMP_ID_RESET_ENABLE FALSE
+#endif
+
+#if (UC_BT_BLE_SMP_BOND_NVS_FLASH)
+#define BLE_SMP_BOND_NVS_FLASH TRUE
+#else
+#define BLE_SMP_BOND_NVS_FLASH FALSE
+#endif
+
#ifdef UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
#define BLE_ADV_REPORT_FLOW_CONTROL (UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP && BLE_INCLUDED)
#endif /* UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP */
@@ -367,6 +576,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
@@ -375,6 +588,10 @@
#define BTC_AV_SRC_INCLUDED FALSE
#endif
+#ifndef BTC_AV_EXT_CODEC
+#define BTC_AV_EXT_CODEC FALSE
+#endif
+
#ifndef BTC_SPP_INCLUDED
#define BTC_SPP_INCLUDED FALSE
#endif
@@ -387,6 +604,10 @@
#define BTC_HD_INCLUDED FALSE
#endif
+#ifndef BTC_HID_REMOVE_DEVICE_BONDING
+#define BTC_HID_REMOVE_DEVICE_BONDING FALSE
+#endif
+
#ifndef SBC_DEC_INCLUDED
#define SBC_DEC_INCLUDED FALSE
#endif
@@ -395,6 +616,10 @@
#define SBC_ENC_INCLUDED FALSE
#endif
+#ifndef BTC_HFP_EXT_CODEC
+#define BTC_HFP_EXT_CODEC FALSE
+#endif
+
/******************************************************************************
**
** BTA-layer components
@@ -440,6 +665,14 @@
#define BTA_AV_INCLUDED FALSE
#endif
+#ifndef BTA_AV_CA_INCLUDED
+#define BTA_AV_CA_INCLUDED FALSE
+#endif
+
+#ifndef BTA_AV_EXT_CODEC
+#define BTA_AV_EXT_CODEC FALSE
+#endif
+
#ifndef BTA_AV_SINK_INCLUDED
#define BTA_AV_SINK_INCLUDED FALSE
#endif
@@ -452,6 +685,10 @@
#define BTA_SDP_INCLUDED FALSE
#endif
+#ifndef BTA_HFP_EXT_CODEC
+#define BTA_HFP_EXT_CODEC FALSE
+#endif
+
/* This is set to enable use of GAP L2CAP connections. */
#ifndef VND_BT_JV_BTA_L2CAP
#define VND_BT_JV_BTA_L2CAP FALSE
@@ -523,12 +760,6 @@
#define BTA_AV_CO_CP_SCMS_T FALSE
#endif
-#if UC_BT_BLE_HOST_QUEUE_CONGESTION_CHECK
-#define SCAN_QUEUE_CONGEST_CHECK TRUE
-#else
-#define SCAN_QUEUE_CONGEST_CHECK FALSE
-#endif
-
#ifdef UC_CONFIG_BT_GATTS_PPCP_CHAR_GAP
#define BTM_PERIPHERAL_ENABLED UC_CONFIG_BT_GATTS_PPCP_CHAR_GAP
#endif
@@ -569,7 +800,7 @@
#define BT_CLASSIC_BQB_INCLUDED FALSE
#endif
-/* This feature is used to eanble interleaved scan*/
+/* This feature is used to enable interleaved scan*/
#ifndef BTA_HOST_INTERLEAVE_SEARCH
#define BTA_HOST_INTERLEAVE_SEARCH FALSE
#endif
@@ -904,9 +1135,95 @@
#define BTM_SEC_MAX_DEVICE_RECORDS UC_BT_SMP_MAX_BONDS
#endif
-/* The number of security records for services. 32 AS Default*/
+#if BTA_SDP_INCLUDED
+#define BTM_SDP_SEC_SERVICE_RECORDS 1
+#else
+#define BTM_SDP_SEC_SERVICE_RECORDS 0
+#endif
+
+#if BTA_AG_INCLUDED
+#define BTM_AG_SEC_SERVICE_RECORDS 1
+#else
+#define BTM_AG_SEC_SERVICE_RECORDS 0
+#endif
+
+#if BTA_HF_INCLUDED
+#define BTM_HF_SEC_SERVICE_RECORDS 1
+#else
+#define BTM_HF_SEC_SERVICE_RECORDS 0
+#endif
+
+#if BTA_JV_INCLUDED
+#define BTM_JV_SEC_SERVICE_RECORDS (MAX_RFC_PORTS - BTM_HF_SEC_SERVICE_RECORDS - BTM_AG_SEC_SERVICE_RECORDS)
+#else
+#define BTM_JV_SEC_SERVICE_RECORDS 0
+#endif
+
+#if BTA_PBA_CLIENT_INCLUDED
+#define BTM_PBA_SEC_SERVICE_RECORDS 2
+#else
+#define BTM_PBA_SEC_SERVICE_RECORDS 0
+#endif
+
+#if BTA_AV_CA_INCLUDED
+#define BTM_AC_VA_SEC_SERVICE_RECORDS 1
+#else
+#define BTM_AC_VA_SEC_SERVICE_RECORDS 0
+#endif
+
+#if AVCT_INCLUDED
+#if AVCT_BROWSE_INCLUDED
+#define BTM_AVCT_SEC_SERVICE_RECORDS 2
+#else
+#define BTM_AVCT_SEC_SERVICE_RECORDS 1
+#endif // AVCT_BROWSE_INCLUDED
+#else
+#define BTM_AVCT_SEC_SERVICE_RECORDS 0
+#endif
+
+#if AVDT_INCLUDED
+#if AVDT_REPORTING
+#define BTM_AVDT_SEC_SERVICE_RECORDS 3
+#else
+#define BTM_AVDT_SEC_SERVICE_RECORDS 2
+#endif // AVDT_INCLUDED
+#else
+#define BTM_AVDT_SEC_SERVICE_RECORDS 0
+#endif
+
+#if GAP_CONN_INCLUDED
+#define BTM_GAP_SEC_SERVICE_RECORDS GAP_MAX_CONNECTIONS
+#else
+#define BTM_GAP_SEC_SERVICE_RECORDS 0
+#endif
+
+#if HID_DEV_INCLUDED
+#define BTM_HIDD_SEC_SERVICE_RECORDS 3
+#else
+#define BTM_HIDD_SEC_SERVICE_RECORDS 0
+#endif
+
+#if HID_HOST_INCLUDED
+#define BTM_HIDH_SEC_SERVICE_RECORDS 3
+#else
+#define BTM_HIDH_SEC_SERVICE_RECORDS 0
+#endif
+
+#if BLE_INCLUDED
+#define BTM_GATT_SEC_SERVICE_RECORDS 1
+#else
+#define BTM_GATT_SEC_SERVICE_RECORDS 0
+#endif
+
+#define BTM_SEC_DEV_SERVICE_RECORDS 1
+
+/* The number of security records for services. */
#ifndef BTM_SEC_MAX_SERVICE_RECORDS
-#define BTM_SEC_MAX_SERVICE_RECORDS 8 // 32
+#define BTM_SEC_MAX_SERVICE_RECORDS (BTM_SDP_SEC_SERVICE_RECORDS + BTM_AG_SEC_SERVICE_RECORDS \
+ + BTM_AVCT_SEC_SERVICE_RECORDS + BTM_AVDT_SEC_SERVICE_RECORDS + BTM_GAP_SEC_SERVICE_RECORDS \
+ + BTM_HIDD_SEC_SERVICE_RECORDS + BTM_GATT_SEC_SERVICE_RECORDS + BTM_PBA_SEC_SERVICE_RECORDS \
+ + BTM_HIDH_SEC_SERVICE_RECORDS + BTM_SEC_DEV_SERVICE_RECORDS + BTM_HF_SEC_SERVICE_RECORDS \
+ + BTM_JV_SEC_SERVICE_RECORDS + BTM_AC_VA_SEC_SERVICE_RECORDS )
#endif
/* If True, force a retrieval of remote device name for each bond in case it's changed */
@@ -1028,10 +1345,12 @@
**************************/
/* 4.1/4.2 secure connections feature */
-#ifndef SC_MODE_INCLUDED
-// Disable AES-CCM (BT 4.1) for BT Classic to workaround controller AES issue. E0 encryption (BT 4.0) will be used.
+#if defined(CONFIG_IDF_TARGET_ESP32) && (BT_CONTROLLER_INCLUDED == TRUE)
+// Disable AES-CCM (BT 4.1) for BT Classic to workaround controller AES issue on ESP32 controller. E0 encryption (BT 4.0) will be used.
#define SC_MODE_INCLUDED FALSE
-#endif
+#else
+#define SC_MODE_INCLUDED TRUE
+#endif // CONFIG_IDF_TARGET_ESP32
/* Used for conformance testing ONLY */
#ifndef BTM_BLE_CONFORMANCE_TESTING
@@ -1247,7 +1566,72 @@
#endif
#ifndef BLE_ANDROID_CONTROLLER_SCAN_FILTER
-#define BLE_ANDROID_CONTROLLER_SCAN_FILTER TRUE
+#define BLE_ANDROID_CONTROLLER_SCAN_FILTER FALSE
+#endif
+
+#ifndef BLE_HOST_BLE_MULTI_ADV_EN
+#define BLE_HOST_BLE_MULTI_ADV_EN FALSE
+#endif
+
+#ifndef BLE_HOST_TRACK_ADVERTISER_EN
+#define BLE_HOST_TRACK_ADVERTISER_EN FALSE
+#endif
+
+#ifndef BLE_HOST_ENERGY_INFO_EN
+#define BLE_HOST_ENERGY_INFO_EN FALSE
+#endif
+
+
+#ifndef BLE_HOST_ENABLE_TEST_MODE_EN
+#define BLE_HOST_ENABLE_TEST_MODE_EN FALSE
+#endif
+
+#ifndef BLE_HOST_EXECUTE_CBACK_EN
+#define BLE_HOST_EXECUTE_CBACK_EN FALSE
+#endif
+
+#ifndef BLE_HOST_REMOVE_ALL_ACL_EN
+#define BLE_HOST_REMOVE_ALL_ACL_EN FALSE
+#endif
+
+#ifndef BLE_HOST_REMOVE_AN_ACL_EN
+#define BLE_HOST_REMOVE_AN_ACL_EN FALSE
+#endif
+
+#ifndef BLE_HOST_READ_TX_POWER_EN
+#define BLE_HOST_READ_TX_POWER_EN FALSE
+#endif
+
+#ifndef BLE_HOST_STOP_ADV_UNUSED
+#define BLE_HOST_STOP_ADV_UNUSED FALSE
+#endif
+
+#ifndef BLE_HOST_BLE_OBSERVE_EN
+#define BLE_HOST_BLE_OBSERVE_EN FALSE
+#endif
+
+#ifndef BLE_HOST_BLE_SCAN_PARAM_UNUSED
+#define BLE_HOST_BLE_SCAN_PARAM_UNUSED FALSE
+#endif
+
+#ifndef BLE_HOST_CONN_SCAN_PARAM_EN
+#define BLE_HOST_CONN_SCAN_PARAM_EN FALSE
+#endif
+
+#ifndef BLE_HOST_SETUP_STORAGE_EN
+#define BLE_HOST_SETUP_STORAGE_EN FALSE
+#endif
+
+#ifndef BLE_HOST_READ_SCAN_REPORTS_EN
+#define BLE_HOST_READ_SCAN_REPORTS_EN FALSE
+#endif
+
+#ifndef BLE_HOST_BATCH_SCAN_EN
+#define BLE_HOST_BATCH_SCAN_EN FALSE
+#endif
+
+#ifndef BLE_HOST_BG_CONNECT_EN
+#define BLE_HOST_BG_CONNECT_EN FALSE
#endif
#ifndef LOCAL_BLE_CONTROLLER_ID
@@ -1281,7 +1665,7 @@
#ifdef CONFIG_IDF_TARGET_ESP32
#define BTM_BLE_ADV_TX_POWER {-12, -9, -6, -3, 0, 3, 6, 9}
#else
-#define BTM_BLE_ADV_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21}
+#define BTM_BLE_ADV_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 20}
#endif
#endif
@@ -1289,7 +1673,7 @@
#ifdef CONFIG_IDF_TARGET_ESP32
#define BTM_TX_POWER {-12, -9, -6, -3, 0, 3, 6, 9}
#else
-#define BTM_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21}
+#define BTM_TX_POWER {-24, -21, -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 20}
#endif
#endif
@@ -1385,7 +1769,7 @@
#define GATT_CONFORMANCE_TESTING FALSE
#endif
-/* number of background connection device allowence, ideally to be the same as WL size
+/* number of background connection device allowance, ideally to be the same as WL size
*/
#ifndef GATT_MAX_BG_CONN_DEV
#define GATT_MAX_BG_CONN_DEV 8 /*MAX is 32*/
@@ -1494,20 +1878,21 @@
/* 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
#endif /* defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE) */
#endif
+/* The maximum length, in bytes, of all SDP attributes combined. */
#ifndef SDP_MAX_PAD_LEN
-#define SDP_MAX_PAD_LEN 300
+#define SDP_MAX_PAD_LEN UC_SDP_MAX_PAD_LEN
#endif
/* The maximum length, in bytes, of an attribute. */
#ifndef SDP_MAX_ATTR_LEN
-#define SDP_MAX_ATTR_LEN 400
+#define SDP_MAX_ATTR_LEN UC_SDP_MAX_ATTR_LEN
#endif
/* The maximum number of attribute filters supported by SDP databases. */
@@ -1800,6 +2185,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
/******************************************************************************
**
@@ -2133,6 +2538,20 @@
#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
*/
#ifndef A2D_INCLUDED
@@ -2170,6 +2589,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
@@ -2372,12 +2795,6 @@ The maximum number of payload octets that the local device can receive in a sing
#define BTSNOOP_MEM FALSE
#endif
-#if UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST
-#define HEAP_ALLOCATION_FROM_SPIRAM_FIRST TRUE
-#else
-#define HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE
-#endif
-
#include "common/bt_trace.h"
#endif /* BT_TARGET_H */
diff --git a/lib/bt/host/bluedroid/common/include/common/bt_trace.h b/lib/bt/host/bluedroid/common/include/common/bt_trace.h
index a4f1ca74..b5f0a9bb 100644
--- a/lib/bt/host/bluedroid/common/include/common/bt_trace.h
+++ b/lib/bt/host/bluedroid/common/include/common/bt_trace.h
@@ -25,6 +25,9 @@
#include "stack/bt_types.h"
#include "bt_common.h"
+#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+#include "ble_log/ble_log_spi_out.h"
+#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t len)
{
uint16_t i;
@@ -217,20 +220,76 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
/* Define tracing for BTM
*/
+#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
+#define BTM_TRACE_ERROR(fmt, args...) { \
+ if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args); \
+}
+
+#define BTM_TRACE_WARNING(fmt, args...) { \
+ if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args); \
+}
+
+#define BTM_TRACE_API(fmt, args...) { \
+ ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_BTM", fmt, ## args); \
+ if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM, API)) BT_PRINT_I("BT_BTM", fmt, ## args); \
+}
+
+#define BTM_TRACE_EVENT(fmt, args...) { \
+ ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_BTM", fmt, ## args); \
+ if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM, EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args); \
+}
+
+#define BTM_TRACE_DEBUG(fmt, args...) { \
+ if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM, DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args); \
+}
+
+#else
+
#define BTM_TRACE_ERROR(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args);}
#define BTM_TRACE_WARNING(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args);}
#define BTM_TRACE_API(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM,API)) BT_PRINT_I("BT_BTM", fmt, ## args);}
#define BTM_TRACE_EVENT(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM,EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args);}
#define BTM_TRACE_DEBUG(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM,DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args);}
+#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
/* Define tracing for the L2CAP unit
*/
+#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
+#define L2CAP_TRACE_ERROR(fmt, args...) { \
+ if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args); \
+}
+
+#define L2CAP_TRACE_WARNING(fmt, args...) { \
+ if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args); \
+}
+
+#define L2CAP_TRACE_API(fmt, args...) { \
+ ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_L2CAP", fmt, ## args); \
+ if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP, API)) BT_PRINT_I("BT_L2CAP", fmt, ## args); \
+}
+
+#define L2CAP_TRACE_EVENT(fmt, args...) { \
+ if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP, EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args); \
+}
+
+#define L2CAP_TRACE_DEBUG(fmt, args...) { \
+ if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP, DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args); \
+}
+
+#else
+
#define L2CAP_TRACE_ERROR(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_WARNING(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_API(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP,API)) BT_PRINT_I("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_EVENT(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP,EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args);}
#define L2CAP_TRACE_DEBUG(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP,DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args);}
+#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
+
/* Define tracing for the SDP unit
*/
#define SDP_TRACE_ERROR(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SDP, ERROR)) BT_PRINT_E("BT_SDP", fmt, ## args);}
@@ -248,11 +307,35 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
#define RFCOMM_TRACE_DEBUG(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(RFCOMM,DEBUG)) BT_PRINT_D("BT_RFCOMM", fmt, ## args);}
/* Generic Access Profile traces */
+#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
+#define GAP_TRACE_ERROR(fmt, args...) { \
+ if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args); \
+}
+
+#define GAP_TRACE_WARNING(fmt, args...) { \
+ if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args); \
+}
+
+#define GAP_TRACE_API(fmt, args...) { \
+ ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_GAP", fmt, ## args); \
+ if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP, API)) BT_PRINT_I("BT_GAP", fmt, ## args); \
+}
+
+#define GAP_TRACE_EVENT(fmt, args...) { \
+ if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP, EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args); \
+}
+
+#else
+
#define GAP_TRACE_ERROR(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args);}
#define GAP_TRACE_API(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP,API)) BT_PRINT_I("BT_GAP", fmt, ## args);}
#define GAP_TRACE_EVENT(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP,EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args);}
#define GAP_TRACE_WARNING(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args);}
+#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
+
/* define traces for HID Host */
#define HIDH_TRACE_ERROR(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(HIDH, ERROR)) BT_PRINT_E("BT_HIDH", fmt, ## args);}
#define HIDH_TRACE_WARNING(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(HIDH, WARNING)) BT_PRINT_W("BT_HIDH", fmt, ## args);}
@@ -316,6 +399,34 @@ 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 OBEX_TL_RFCOMM */
+#define OBEX_TL_RFCOMM_TRACE_ERROR(fmt, args...) {if (obex_tl_rfcomm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(AVRC, ERROR)) BT_PRINT_E("OBEX_TL_RFCOMM", fmt, ## args);}
+#define OBEX_TL_RFCOMM_TRACE_WARNING(fmt, args...) {if (obex_tl_rfcomm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(AVRC, WARNING)) BT_PRINT_W("OBEX_TL_RFCOMM", fmt, ## args);}
+#define OBEX_TL_RFCOMM_TRACE_API(fmt, args...) {if (obex_tl_rfcomm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(AVRC,API)) BT_PRINT_I("OBEX_TL_RFCOMM", fmt, ## args);}
+#define OBEX_TL_RFCOMM_TRACE_EVENT(fmt, args...) {if (obex_tl_rfcomm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(AVRC,EVENT)) BT_PRINT_D("OBEX_TL_RFCOMM", fmt, ## args);}
+#define OBEX_TL_RFCOMM_TRACE_DEBUG(fmt, args...) {if (obex_tl_rfcomm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(AVRC,DEBUG)) BT_PRINT_D("OBEX_TL_RFCOMM", 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);}
@@ -326,20 +437,73 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
/* Define tracing for the ATT/GATT unit
*/
+#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
+#define GATT_TRACE_ERROR(fmt, args...) { \
+ if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args); \
+}
+
+#define GATT_TRACE_WARNING(fmt, args...) { \
+ if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args); \
+}
+
+#define GATT_TRACE_API(fmt, args...) { \
+ ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_GATT", fmt, ## args); \
+ if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT, API)) BT_PRINT_I("BT_GATT", fmt, ## args); \
+}
+
+#define GATT_TRACE_EVENT(fmt, args...) { \
+ if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT, EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args); \
+}
+
+#define GATT_TRACE_DEBUG(fmt, args...) { \
+ if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT, DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args); \
+}
+
+#else
+
#define GATT_TRACE_ERROR(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args);}
#define GATT_TRACE_WARNING(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args);}
#define GATT_TRACE_API(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT,API)) BT_PRINT_I("BT_GATT", fmt, ## args);}
#define GATT_TRACE_EVENT(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT,EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args);}
#define GATT_TRACE_DEBUG(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT,DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args);}
+#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
/* Define tracing for the SMP unit
*/
+#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
+
+#define SMP_TRACE_ERROR(fmt, args...) { \
+ if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args); \
+}
+
+#define SMP_TRACE_WARNING(fmt, args...) { \
+ if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args); \
+}
+
+#define SMP_TRACE_API(fmt, args...) { \
+ ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_SMP", fmt, ## args); \
+ if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP, API)) BT_PRINT_I("BT_SMP", fmt, ## args); \
+}
+
+#define SMP_TRACE_EVENT(fmt, args...) { \
+ if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP, EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args); \
+}
+
+#define SMP_TRACE_DEBUG(fmt, args...) { \
+ if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP, DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args); \
+}
+
+#else
+
#define SMP_TRACE_ERROR(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args);}
#define SMP_TRACE_WARNING(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args);}
#define SMP_TRACE_API(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP,API)) BT_PRINT_I("BT_SMP", fmt, ## args);}
#define SMP_TRACE_EVENT(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP,EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args);}
#define SMP_TRACE_DEBUG(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP,DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args);}
+#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED)
extern UINT8 btif_trace_level;
@@ -484,6 +648,34 @@ 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 tracing for OBEX L2CAP transport layer */
+#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 OBEX RFCOMM transport layer */
+#define OBEX_TL_RFCOMM_TRACE_ERROR(fmt, args...)
+#define OBEX_TL_RFCOMM_TRACE_WARNING(fmt, args...)
+#define OBEX_TL_RFCOMM_TRACE_API(fmt, args...)
+#define OBEX_TL_RFCOMM_TRACE_EVENT(fmt, args...)
+#define OBEX_TL_RFCOMM_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...)
diff --git a/lib/bt/host/bluedroid/config/include/config/stack_config.h b/lib/bt/host/bluedroid/config/include/config/stack_config.h
index 8b777723..ca48316e 100644
--- a/lib/bt/host/bluedroid/config/include/config/stack_config.h
+++ b/lib/bt/host/bluedroid/config/include/config/stack_config.h
@@ -12,10 +12,11 @@
struct bluedroid_config {
bool (*get_ssp_enabled)(void);
+ bool (*get_sc_enabled) (void);
};
-bt_status_t bluedriod_config_init(esp_bluedroid_config_t *cfg);
+bt_status_t bluedroid_config_init(esp_bluedroid_config_t *cfg);
-void bluedriod_config_deinit(void);
+void bluedroid_config_deinit(void);
-const struct bluedroid_config *bluedriod_config_get(void);
+const struct bluedroid_config *bluedroid_config_get(void);
diff --git a/lib/bt/host/bluedroid/config/stack_config.c b/lib/bt/host/bluedroid/config/stack_config.c
index 66d04a63..94ec24d7 100644
--- a/lib/bt/host/bluedroid/config/stack_config.c
+++ b/lib/bt/host/bluedroid/config/stack_config.c
@@ -25,7 +25,14 @@ static bool get_ssp_enabled(void)
return cfg->ssp_en;
}
-bt_status_t bluedriod_config_init(esp_bluedroid_config_t *cfg)
+static bool get_sc_enabled(void)
+{
+ assert(s_stack_config_env);
+ esp_bluedroid_config_t *cfg = &s_stack_config_env->cfg;
+ return cfg->sc_en;
+}
+
+bt_status_t bluedroid_config_init(esp_bluedroid_config_t *cfg)
{
s_stack_config_env = osi_calloc(sizeof(struct stack_config_env_tag));
if (!s_stack_config_env) {
@@ -36,11 +43,12 @@ bt_status_t bluedriod_config_init(esp_bluedroid_config_t *cfg)
struct bluedroid_config *interface = &s_stack_config_env->interface;
interface->get_ssp_enabled = get_ssp_enabled;
+ interface->get_sc_enabled = get_sc_enabled;
return BT_STATUS_SUCCESS;
}
-void bluedriod_config_deinit(void)
+void bluedroid_config_deinit(void)
{
if (s_stack_config_env) {
osi_free(s_stack_config_env);
@@ -48,7 +56,7 @@ void bluedriod_config_deinit(void)
}
}
-const struct bluedroid_config *bluedriod_config_get(void)
+const struct bluedroid_config *bluedroid_config_get(void)
{
assert(s_stack_config_env);
return &s_stack_config_env->interface;
diff --git a/lib/bt/host/bluedroid/device/controller.c b/lib/bt/host/bluedroid/device/controller.c
index beb7d676..4b68eb93 100644
--- a/lib/bt/host/bluedroid/device/controller.c
+++ b/lib/bt/host/bluedroid/device/controller.c
@@ -31,10 +31,10 @@
#include "osi/future.h"
#include "config/stack_config.h"
#if (BLE_50_FEATURE_SUPPORT == TRUE)
-const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\xff\xff\xff" };
+const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x07\xff\xff\xff\xff" };
#else
const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" };
-#endif
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_INCLUDED)
const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_DUMO_EVENT_MASK_EXT };
@@ -83,7 +83,12 @@ typedef struct {
bool simple_pairing_supported;
bool secure_connections_supported;
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
uint16_t ble_ext_adv_data_max_len;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ uint16_t get_ble_periodic_advertiser_list_size;
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE)
} controller_local_param_t;
@@ -96,11 +101,16 @@ static controller_local_param_t *controller_param_ptr;
#define AWAIT_COMMAND(command) future_await(controller_param.hci->transmit_command_futured(command))
+static bool loaded = false;
// Module lifecycle functions
static void start_up(void)
{
BT_HDR *response;
+#if (BLE_FEAT_ISO_EN == TRUE)
+ uint16_t iso_pktlen = 0;
+ uint8_t iso_max_pkts = 0;
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
// Send the initial reset command
response = AWAIT_COMMAND(controller_param.packet_factory->make_reset());
@@ -119,11 +129,13 @@ static void start_up(void)
response = AWAIT_COMMAND(controller_param.packet_factory->make_set_c2h_flow_control(HCI_HOST_FLOW_CTRL_ACL_ON));
controller_param.packet_parser->parse_generic_command_complete(response);
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
// Enable adv flow control
response = AWAIT_COMMAND(controller_param.packet_factory->make_set_adv_report_flow_control(HCI_HOST_FLOW_CTRL_ADV_REPORT_ON, (uint16_t)BLE_ADV_REPORT_FLOW_CONTROL_NUM, (uint16_t)BLE_ADV_REPORT_DISCARD_THRSHOLD));
controller_param.packet_parser->parse_generic_command_complete(response);
#endif
+#endif // #if (BLE_42_SCAN_EN == TRUE)
// Tell the controller about our buffer sizes and buffer counts next
// TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?
response = AWAIT_COMMAND(
@@ -176,7 +188,7 @@ static void start_up(void)
// dependent on what we configure from page 0 and host SSP configuration
controller_param.simple_pairing_supported = HCI_SIMPLE_PAIRING_SUPPORTED(
controller_param.features_classic[0].as_array) &&
- (bluedriod_config_get()->get_ssp_enabled());
+ (bluedroid_config_get()->get_ssp_enabled());
if (controller_param.simple_pairing_supported) {
response = AWAIT_COMMAND(controller_param.packet_factory->make_write_simple_pairing_mode(HCI_SP_MODE_ENABLED));
controller_param.packet_parser->parse_generic_command_complete(response);
@@ -211,13 +223,13 @@ static void start_up(void)
}
#endif
-#if (SC_MODE_INCLUDED == TRUE)
+if ((bluedroid_config_get()->get_sc_enabled())) {
controller_param.secure_connections_supported = HCI_SC_CTRLR_SUPPORTED(controller_param.features_classic[2].as_array);
if (controller_param.secure_connections_supported) {
response = AWAIT_COMMAND(controller_param.packet_factory->make_write_secure_connections_host_support(HCI_SC_MODE_ENABLED));
controller_param.packet_parser->parse_generic_command_complete(response);
}
-#endif
+}
#if (BLE_INCLUDED == TRUE)
#if (CLASSIC_BT_INCLUDED)
@@ -237,7 +249,19 @@ static void start_up(void)
&controller_param.acl_data_size_ble,
&controller_param.acl_buffer_count_ble
);
-
+#if (BLE_FEAT_ISO_EN == TRUE)
+ // Request the ble buffer size next
+ response = AWAIT_COMMAND(controller_param.packet_factory->make_ble_read_buffer_size_v2());
+ controller_param.packet_parser->parse_ble_read_buffer_size_response_v2(
+ response,
+ &controller_param.acl_data_size_ble,
+ &controller_param.acl_buffer_count_ble,
+ &iso_pktlen,
+ &iso_max_pkts
+ );
+ extern int ble_hci_set_iso_buf_sz(uint16_t pktlen, uint8_t max_pkts);
+ ble_hci_set_iso_buf_sz(iso_pktlen, iso_max_pkts);
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
// Response of 0 indicates ble has the same buffer size as classic
if (controller_param.acl_data_size_ble == 0) {
controller_param.acl_data_size_ble = controller_param.acl_data_size_classic;
@@ -265,16 +289,26 @@ static void start_up(void)
&controller_param.ble_resolving_list_max_size);
}
#if BLE_50_FEATURE_SUPPORT == TRUE
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
controller_param.ble_ext_adv_data_max_len = BLE_EXT_ADV_DATA_LEN_MAX;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif //#if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_50_FEATURE_SUPPORT == TRUE && BLE_42_FEATURE_SUPPORT == FALSE)
- if (HCI_LE_ENHANCED_PRIVACY_SUPPORTED(controller_param.features_ble.as_array)) {
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
+ if (HCI_LE_EXT_ADV_SUPPORTED(controller_param.features_ble.as_array)) {
response = AWAIT_COMMAND(controller_param.packet_factory->make_read_max_adv_data_len());
controller_param.packet_parser->parse_ble_read_adv_max_len_response(
response,
&controller_param.ble_ext_adv_data_max_len);
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ response = AWAIT_COMMAND(controller_param.packet_factory->read_periodic_adv_list_size());
+ controller_param.packet_parser->parse_ble_read_periodic_adv_list_size_response(
+ response,
+ &controller_param.get_ble_periodic_advertiser_list_size);
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // (BLE_50_FEATURE_SUPPORT == TRUE && BLE_42_FEATURE_SUPPORT == FALSE)
if (HCI_LE_DATA_LEN_EXT_SUPPORTED(controller_param.features_ble.as_array)) {
@@ -315,6 +349,17 @@ static void shut_down(void)
controller_param.readable = false;
}
+#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
+void free_controller_param(void)
+{
+ if (controller_param_ptr) {
+ osi_free(controller_param_ptr);
+ controller_param_ptr = NULL;
+ loaded = false;
+ }
+}
+#endif
+
static bool get_is_ready(void)
{
return controller_param.readable;
@@ -508,6 +553,7 @@ static void set_ble_resolving_list_max_size(int resolving_list_max_size)
controller_param.ble_resolving_list_max_size = resolving_list_max_size;
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
static uint16_t ble_get_ext_adv_data_max_len(void)
{
assert(controller_param.readable);
@@ -515,6 +561,15 @@ static uint16_t ble_get_ext_adv_data_max_len(void)
return controller_param.ble_ext_adv_data_max_len;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+static uint8_t get_ble_periodic_adv_list_size(void)
+{
+ assert(controller_param.readable);
+ assert(controller_param.ble_supported);
+ return controller_param.get_ble_periodic_advertiser_list_size;
+}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BTM_SCO_HCI_INCLUDED == TRUE)
static uint8_t get_sco_data_size(void)
@@ -574,7 +629,12 @@ static const controller_t interface = {
get_ble_resolving_list_max_size,
set_ble_resolving_list_max_size,
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
ble_get_ext_adv_data_max_len,
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ get_ble_periodic_adv_list_size,
+#endif // (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BTM_SCO_HCI_INCLUDED == TRUE)
get_sco_data_size,
@@ -584,7 +644,6 @@ static const controller_t interface = {
const controller_t *controller_get_interface(void)
{
- static bool loaded = false;
if (!loaded) {
loaded = true;
#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
diff --git a/lib/bt/host/bluedroid/device/include/device/controller.h b/lib/bt/host/bluedroid/device/include/device/controller.h
index 6fc766f3..6345d7a9 100644
--- a/lib/bt/host/bluedroid/device/include/device/controller.h
+++ b/lib/bt/host/bluedroid/device/include/device/controller.h
@@ -81,7 +81,12 @@ typedef struct controller_t {
void (*set_ble_resolving_list_max_size)(int resolving_list_max_size);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
uint16_t (*ble_get_ext_adv_data_max_len)(void);
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ uint8_t (*get_ble_periodic_adv_list_size)(void);
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // BLE_50_FEATURE_SUPPORT
#if (BTM_SCO_HCI_INCLUDED == TRUE)
diff --git a/lib/bt/host/bluedroid/external/sbc/decoder/include/oi_codec_sbc.h b/lib/bt/host/bluedroid/external/sbc/decoder/include/oi_codec_sbc.h
index 495fbf6b..ae87317c 100644
--- a/lib/bt/host/bluedroid/external/sbc/decoder/include/oi_codec_sbc.h
+++ b/lib/bt/host/bluedroid/external/sbc/decoder/include/oi_codec_sbc.h
@@ -372,7 +372,7 @@ OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
*
* @param frameData Pointer to the SBC data.
*
- * @param frameBytes Number of bytes avaiable in the frameData buffer
+ * @param frameBytes Number of bytes available in the frameData buffer
*
*/
OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE *frameData,
diff --git a/lib/bt/host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c b/lib/bt/host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c
index c0ab99b8..fa1d40c9 100644
--- a/lib/bt/host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c
+++ b/lib/bt/host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c
@@ -18,7 +18,7 @@
/******************************************************************************
*
- * contains code for encoder flow and initalization of encoder
+ * contains code for encoder flow and initialization of encoder
*
******************************************************************************/
@@ -62,7 +62,7 @@ void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
pstrEncParams->ps16NextPcmBuffer = pstrEncParams->as16PcmBuffer;
#endif
do {
- /* SBC ananlysis filter*/
+ /* SBC analysis filter*/
if (s32NumOfSubBands == 4) {
SbcAnalysisFilter4(pstrEncParams);
} else {
@@ -73,7 +73,7 @@ void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
ps16ScfL = pstrEncParams->as16ScaleFactor;
s32Ch = pstrEncParams->s16NumOfChannels * s32NumOfSubBands;
- pstrEncParams->ps16NextPcmBuffer += s32Ch * s32NumOfBlocks; /* in case of multible sbc frame to encode update the pcm pointer */
+ pstrEncParams->ps16NextPcmBuffer += s32Ch * s32NumOfBlocks; /* in case of multiple sbc frame to encode update the pcm pointer */
for (s32Sb = 0; s32Sb < s32Ch; s32Sb++) {
SbBuffer = pstrEncParams->s32SbBuffer + s32Sb;
@@ -101,7 +101,7 @@ void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
/* In case of JS processing,check whether to use JS */
#if (SBC_JOINT_STE_INCLUDED == TRUE)
if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) {
- /* Calculate sum and differance scale factors for making JS decision */
+ /* Calculate sum and difference scale factors for making JS decision */
ps16ScfL = pstrEncParams->as16ScaleFactor ;
/* calculate the scale factor of Joint stereo max sum and diff */
for (s32Sb = 0; s32Sb < s32NumOfSubBands - 1; s32Sb++) {
@@ -191,7 +191,7 @@ void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
}
/****************************************************************************
-* InitSbcAnalysisFilt - Initalizes the input data to 0
+* InitSbcAnalysisFilt - Initializes the input data to 0
*
* RETURNS : N/A
*/
@@ -306,7 +306,7 @@ void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams)
/* allocation method: loudness */
pstrEncParams->s16AllocationMethod = SBC_LOUDNESS;
- /* set the header paramers, unused for mSBC */
+ /* set the header parameters, unused for mSBC */
pstrEncParams->FrameHeader = 0;
}
diff --git a/lib/bt/host/bluedroid/hci/ble_hci_iso.c b/lib/bt/host/bluedroid/hci/ble_hci_iso.c
new file mode 100644
index 00000000..9c73fae2
--- /dev/null
+++ b/lib/bt/host/bluedroid/hci/ble_hci_iso.c
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string.h>
+#include <assert.h>
+#include "hci/ble_hci_iso.h"
+#include "common/bt_target.h"
+#include "osi/mutex.h"
+
+#if (BLE_FEAT_ISO_EN == TRUE)
+
+#define BLE_HCI_ISO_PB_FIRST_FRAG 0
+#define BLE_HCI_ISO_PB_CONT_FRAG 1
+#define BLE_HCI_ISO_PB_COMP_SDU 2
+#define BLE_HCI_ISO_PB_LAST_FRAG 3
+
+#define BLE_HCI_ISO_DATA_HDR_SZ 4
+#define BLE_HCI_ISO_DATA_LOAD_TS_SZ 4
+#define BLE_HCI_ISO_DATA_LOAD_HDR_SZ 4
+
+#ifndef min
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+static uint16_t ble_hs_iso_buf_sz;
+static uint8_t ble_hs_iso_max_pkts;
+
+#if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+/* Number of available ISO transmit buffers on the controller.
+ * It must only be accessed while the host mutex is locked.
+ */
+static uint16_t ble_hs_iso_avail_pkts;
+#endif // #if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+
+static struct ble_hci_iso_conn g_iso_conn[BLE_ISO_BIS_MAX_COUNT + BLE_ISO_CIS_MAX_COUNT];
+
+int
+ble_hci_set_iso_buf_sz(uint16_t pktlen, uint8_t max_pkts)
+{
+ if (pktlen == 0 || max_pkts == 0) {
+ return 3;
+ }
+
+ ble_hs_iso_buf_sz = pktlen;
+ ble_hs_iso_max_pkts = max_pkts;
+
+#if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+ ble_hs_iso_avail_pkts = max_pkts;
+#endif /* (BLE_ISO_STD_FLOW_CTRL) */
+
+ HCI_TRACE_WARNING("ISO Flow Control:\n");
+ HCI_TRACE_WARNING(" Length: %u\n", pktlen);
+ HCI_TRACE_WARNING(" Count: %u\n", max_pkts);
+ HCI_TRACE_WARNING(" Status: ");
+#if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+ HCI_TRACE_WARNING("%s\n", "Standard");
+#elif (BLE_ISO_NON_STD_FLOW_CTRL == TRUE)
+ HCI_TRACE_WARNING("%s\n", "Non-standard");
+#else
+ HCI_TRACE_WARNING("%s\n", "Not support");
+#endif
+
+ return 0;
+}
+
+void
+ble_hci_get_iso_buf_size(uint16_t *pktlen, uint8_t *max_pkts)
+{
+ assert(pktlen && max_pkts);
+
+ *pktlen = ble_hs_iso_buf_sz;
+ *max_pkts = ble_hs_iso_max_pkts;
+}
+
+#if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+void
+ble_hci_add_iso_avail_pkts(uint16_t delta)
+{
+ osi_mutex_global_lock();
+
+ if (ble_hs_iso_avail_pkts + delta > ble_hs_iso_max_pkts) {
+ HCI_TRACE_ERROR("ISO_HS_RESET %u %u %u\n", ble_hs_iso_avail_pkts, delta, ble_hs_iso_max_pkts);
+ // ble_hs_sched_reset(BLE_HS_ECONTROLLER);
+ assert(0);
+ } else {
+ ble_hs_iso_avail_pkts += delta;
+ }
+
+ osi_mutex_global_unlock();
+}
+#endif /* (BLE_ISO_STD_FLOW_CTRL) */
+
+#define BLE_ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+struct ble_hci_iso_conn *
+ble_hci_iso_conn_find(uint16_t conn_handle)
+{
+ for (size_t i = 0; i < BLE_ARRAY_SIZE(g_iso_conn); i++) {
+ struct ble_hci_iso_conn *conn = &g_iso_conn[i];
+
+ if (conn->enabled &&
+ conn->conn_handle == conn_handle) {
+ return conn;
+ }
+ }
+
+ return NULL;
+}
+
+int ble_hci_iso_conn_free(uint16_t conn_handle)
+{
+ for (size_t i = 0; i < BLE_ARRAY_SIZE(g_iso_conn); i++) {
+ struct ble_hci_iso_conn *conn = &g_iso_conn[i];
+
+ if (conn->enabled &&
+ conn->conn_handle == conn_handle) {
+ conn->enabled = 0;
+ conn->conn_handle = 0;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static struct ble_hci_iso_conn *
+ble_hci_iso_alloc_conn(uint16_t conn_handle)
+{
+ for (size_t i = 0; i < BLE_ARRAY_SIZE(g_iso_conn); i++) {
+ struct ble_hci_iso_conn *conn = &g_iso_conn[i];
+
+ if (!conn->enabled) {
+ conn->enabled = 1;
+ conn->conn_handle = conn_handle;
+ conn->pkt_seq_num = 0; /* Initialize to 0 */
+ return conn;
+ }
+ }
+
+ return NULL;
+}
+
+#if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+static uint8_t
+ble_hci_iso_buf_needed(struct ble_hs_iso_conn *conn)
+{
+ uint16_t sdu_offset;
+ uint16_t dl_len;
+ uint8_t dlh_len;
+ uint8_t count;
+
+ dlh_len = (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0) + BLE_HCI_ISO_DATA_LOAD_HDR_SZ;
+ sdu_offset = 0;
+ count = 1; /* 1 extra since framed pdu may be used */
+
+ while (1) {
+ dl_len = min(dlh_len + conn->sdu_len - sdu_offset, ble_hs_iso_buf_sz);
+
+ count += 1;
+
+ sdu_offset += dl_len - dlh_len;
+ assert(sdu_offset <= conn->sdu_len);
+
+ if (sdu_offset == conn->sdu_len) {
+ break;
+ }
+
+ /* No data load header for continuation/last segment */
+ dlh_len = 0;
+ }
+
+ return count;
+}
+#endif /* (BLE_ISO_STD_FLOW_CTRL) */
+
+static void
+ble_hci_iso_hdr_append(struct ble_hci_iso_conn *conn,
+ uint8_t *frag,
+ uint8_t pb_flag, uint16_t dl_len)
+{
+ uint32_t pkt_hdr;
+ uint32_t dl_hdr;
+
+ pkt_hdr = conn->conn_handle;
+ pkt_hdr |= (pb_flag << 12);
+ if (pb_flag == BLE_HCI_ISO_PB_FIRST_FRAG ||
+ pb_flag == BLE_HCI_ISO_PB_COMP_SDU) {
+ pkt_hdr |= (conn->ts_flag << 14);
+ }
+ pkt_hdr |= (dl_len << 16);
+
+ memcpy(frag, &pkt_hdr, BLE_HCI_ISO_DATA_HDR_SZ);
+
+ /* No data load header for continuation/last segment */
+ if (pb_flag == BLE_HCI_ISO_PB_CONT_FRAG ||
+ pb_flag == BLE_HCI_ISO_PB_LAST_FRAG) {
+ return;
+ }
+
+ if (conn->ts_flag) {
+ memcpy(frag + BLE_HCI_ISO_DATA_HDR_SZ, &conn->time_stamp, BLE_HCI_ISO_DATA_LOAD_TS_SZ);
+ }
+
+ dl_hdr = (conn->sdu_len << 16) | conn->pkt_seq_num;
+
+ memcpy(frag + BLE_HCI_ISO_DATA_HDR_SZ + (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0),
+ &dl_hdr, BLE_HCI_ISO_DATA_LOAD_HDR_SZ);
+}
+
+int
+ble_hci_tx_iso_data(const uint8_t *data, uint16_t len, void *arg)
+{
+ int rc = 1;
+#if CONFIG_BT_LE_ISO_SUPPORT
+ // return ble_transport_to_ll_iso(data, len, arg);
+ extern int ble_hci_trans_hs_iso_tx(const uint8_t *data, uint16_t length, void *arg);
+ rc = ble_hci_trans_hs_iso_tx(data, len, arg);
+#endif // #if CONFIG_BT_LE_ISO_SUPPORT
+ return rc;
+}
+
+static int
+ble_hci_iso_tx_now(struct ble_hci_iso_conn *conn, const uint8_t *sdu,
+ uint32_t time_stamp, uint16_t pkt_seq_num)
+{
+ uint8_t dlh_len;
+ uint8_t *frag;
+ int rc;
+
+#if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+ /* Get the Controller ISO buffer needed for the SDU */
+ uint8_t count = ble_hs_hci_iso_buf_needed(conn);
+
+ /* Make sure the Controller ISO buffer can accommodate the SDU completely */
+ if (count > ble_hs_iso_avail_pkts) {
+ HCI_TRACE_ERROR("ISO flow control(%u/%u)!\n", count, ble_hs_iso_avail_pkts);
+ return 1;
+ }
+#elif (BLE_ISO_NON_STD_FLOW_CTRL == TRUE)
+ extern uint16_t ble_ll_iso_free_buf_num_get(uint16_t conn_handle);
+ if (ble_ll_iso_free_buf_num_get(conn->conn_handle) == 0) {
+ HCI_TRACE_ERROR("ISO flow control!\n");
+ return 1;
+ }
+#endif
+
+ dlh_len = (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0) + BLE_HCI_ISO_DATA_LOAD_HDR_SZ;
+
+ frag = malloc(BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len);
+ if (frag == NULL) {
+ HCI_TRACE_ERROR("frag is null\n");
+ return 6;
+ }
+
+ ble_hci_iso_hdr_append(conn,
+ frag,
+ BLE_HCI_ISO_PB_COMP_SDU,
+ dlh_len + conn->sdu_len);
+
+ memcpy(frag + BLE_HCI_ISO_DATA_HDR_SZ + dlh_len,
+ sdu,
+ conn->sdu_len);
+
+ rc = ble_hci_tx_iso_data(frag, BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len, NULL);
+ if (rc) {
+ HCI_TRACE_ERROR("iso tx failed\n");
+ return 14;
+ }
+
+#if (BLE_ISO_STD_FLOW_CTRL == TRUE)
+ /* If an ISO SDU is fragmented into fragments, flow control is not supported.
+ *
+ * Currently even if an SDU is larger than the ISO buffer size, fragmentation
+ * will not happen here, the SDU will be posted to Controller completely.
+ */
+ ble_hs_iso_avail_pkts -= 1;
+#endif /* (BLE_ISO_STD_FLOW_CTRL) */
+
+ return 0;
+}
+
+int
+esp_ble_hci_iso_tx(uint16_t conn_handle, const uint8_t *sdu, uint16_t sdu_len,
+ bool ts_flag, uint32_t time_stamp, uint16_t pkt_seq_num)
+{
+ struct ble_hci_iso_conn *conn;
+ uint16_t max_sdu;
+ int rc;
+
+ osi_mutex_global_lock();
+
+ /* For sending empty SDU, we could use an SDU with zero length. */
+ if (sdu == NULL && sdu_len != 0) {
+ HCI_TRACE_ERROR("Invalid iso sdu\n");
+ rc = 3;
+ goto end;
+ }
+
+ /* TODO:
+ * Use Host functions to replace the above LL implementation.
+ */
+ max_sdu = 0x0FFF;
+
+ if (sdu_len > max_sdu) {
+ HCI_TRACE_ERROR("Too large iso sdu %d, max_sdu %d\n", sdu_len, max_sdu);
+ rc = 8;
+ goto end;
+ }
+
+ conn = ble_hci_iso_conn_find(conn_handle);
+ if (!conn) {
+ conn = ble_hci_iso_alloc_conn(conn_handle);
+ }
+ if (!conn) {
+ rc = 7;
+ goto end;
+ }
+
+ conn->ts_flag = ts_flag;
+ conn->time_stamp = time_stamp;
+ conn->pkt_seq_num = pkt_seq_num;
+ conn->sdu_len = sdu_len;
+
+ rc = ble_hci_iso_tx_now(conn, sdu, time_stamp, pkt_seq_num);
+end:
+ osi_mutex_global_unlock();
+ return rc;
+}
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
diff --git a/lib/bt/host/bluedroid/hci/hci_hal_h4.c b/lib/bt/host/bluedroid/hci/hci_hal_h4.c
index 9663126a..1dcdf67d 100644
--- a/lib/bt/host/bluedroid/hci/hci_hal_h4.c
+++ b/lib/bt/host/bluedroid/hci/hci_hal_h4.c
@@ -35,16 +35,16 @@
#include "esp_bluedroid_hci.h"
#include "stack/hcimsgs.h"
-#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
-#include "ble_hci_trans.h"
-#endif
-
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
#include "l2c_int.h"
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
#include "stack/hcimsgs.h"
#include "hci_log/bt_hci_log.h"
+#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
+#include "ble_log/ble_log_spi_out.h"
+#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
+
#define HCI_BLE_EVENT 0x3e
#define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
#define PACKET_TYPE_TO_INDEX(type) ((type) - 1)
@@ -56,9 +56,6 @@
#define HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX (200)
#endif
-extern bool BTU_check_queue_is_congest(void);
-
-
static const uint8_t preamble_sizes[] = {
HCI_COMMAND_PREAMBLE_SIZE,
HCI_ACL_PREAMBLE_SIZE,
@@ -75,6 +72,7 @@ static const uint16_t outbound_event_types[] = {
typedef struct {
fixed_queue_t *rx_q;
+#if (BLE_42_SCAN_EN == TRUE)
struct pkt_queue *adv_rpt_q;
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
osi_mutex_t adv_flow_lock;
@@ -84,6 +82,7 @@ typedef struct {
pkt_linked_item_t *adv_fc_cmd_buf;
bool cmd_buf_in_use;
#endif
+#endif // #if (BLE_42_SCAN_EN == TRUE)
hci_hal_callbacks_t *callbacks;
osi_thread_t *hci_h4_thread;
struct osi_event *upstream_data_ready;
@@ -97,15 +96,18 @@ static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb;
static void host_send_pkt_available_cb(void);
static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet);
+#if (BLE_42_SCAN_EN == TRUE)
static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
static void hci_upstream_data_handler(void *arg);
static bool hci_upstream_data_post(uint32_t timeout);
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
static void hci_adv_flow_monitor(void *context);
static void hci_adv_flow_cmd_free_cb(pkt_linked_item_t *linked_pkt);
#endif
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thread_t *task_thread)
{
assert(upper_callbacks != NULL);
@@ -113,7 +115,7 @@ static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thr
hci_hal_env.hci_h4_thread = task_thread;
hci_hal_env.callbacks = (hci_hal_callbacks_t *)upper_callbacks;
-
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_hal_env.adv_fc_cmd_buf = osi_calloc(HCI_CMD_LINKED_BUF_SIZE(HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL));
assert(hci_hal_env.adv_fc_cmd_buf != NULL);
@@ -126,12 +128,13 @@ static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thr
hci_hal_env.adv_flow_monitor = osi_alarm_new("adv_fc_mon", hci_adv_flow_monitor, NULL, HCI_ADV_FLOW_MONITOR_PERIOD_MS);
assert (hci_hal_env.adv_flow_monitor != NULL);
#endif
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
hci_hal_env.rx_q = fixed_queue_new(QUEUE_SIZE_MAX);
assert(hci_hal_env.rx_q != NULL);
-
+#if (BLE_42_SCAN_EN == TRUE)
hci_hal_env.adv_rpt_q = pkt_queue_create();
assert(hci_hal_env.adv_rpt_q != NULL);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
struct osi_event *event = osi_event_create(hci_upstream_data_handler, NULL);
assert(event != NULL);
@@ -144,19 +147,22 @@ static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thr
static void hci_hal_env_deinit(void)
{
fixed_queue_t *rx_q = hci_hal_env.rx_q;
+#if (BLE_42_SCAN_EN == TRUE)
struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
struct osi_event *upstream_data_ready = hci_hal_env.upstream_data_ready;
hci_hal_env.rx_q = NULL;
+#if (BLE_42_SCAN_EN == TRUE)
hci_hal_env.adv_rpt_q = NULL;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
hci_hal_env.upstream_data_ready = NULL;
-
fixed_queue_free(rx_q, osi_free_func);
-
+#if (BLE_42_SCAN_EN == TRUE)
pkt_queue_destroy(adv_rpt_q, NULL);
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
osi_event_delete(upstream_data_ready);
-
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_hal_env.cmd_buf_in_use = true;
osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
@@ -166,7 +172,7 @@ static void hci_hal_env_deinit(void)
osi_free(hci_hal_env.adv_fc_cmd_buf);
hci_hal_env.adv_fc_cmd_buf = NULL;
#endif
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
hci_hal_env.hci_h4_thread = NULL;
memset(&hci_hal_env, 0, sizeof(hci_hal_env_t));
@@ -225,11 +231,37 @@ static uint16_t transmit_data(serial_data_type_t type,
return length - 1;
}
+#if (BLE_FEAT_ISO_EN == TRUE)
+typedef void ble_host_rx_iso_data_fn(uint8_t *data, uint16_t len);
+
+static ble_host_rx_iso_data_fn *ble_host_iso_rx_cb = NULL;
+
+void ble_host_register_rx_iso_data_cb(void *cb)
+{
+ /* If the iso rx cb is already registered, we will give
+ * a warning log here, and the cb will still be updated.
+ */
+ if (ble_host_iso_rx_cb) {
+ HCI_TRACE_WARNING("iso rx cb %p already registered\n", ble_host_iso_rx_cb);
+ }
+
+ ble_host_iso_rx_cb = cb;
+}
+
+void ble_hci_register_rx_iso_data_cb(void *cb)
+{
+ ble_host_register_rx_iso_data_cb(cb);
+}
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
// Internal functions
static void hci_upstream_data_handler(void *arg)
{
fixed_queue_t *rx_q = hci_hal_env.rx_q;
+#if (BLE_42_SCAN_EN == TRUE)
struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
size_t pkts_to_process;
do {
@@ -241,7 +273,7 @@ static void hci_upstream_data_handler(void *arg)
}
}
} while (0);
-
+#if (BLE_42_SCAN_EN == TRUE)
do {
pkts_to_process = pkt_queue_length(adv_rpt_q);
for (size_t i = 0; i < pkts_to_process; i++) {
@@ -251,8 +283,12 @@ static void hci_upstream_data_handler(void *arg)
}
}
} while (0);
-
- if (!fixed_queue_is_empty(rx_q) || pkt_queue_length(adv_rpt_q) > 0) {
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+ if (!fixed_queue_is_empty(rx_q)
+#if (BLE_42_SCAN_EN == TRUE)
+ || pkt_queue_length(adv_rpt_q) > 0
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+ ) {
hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT);
}
}
@@ -293,6 +329,7 @@ bool host_recv_adv_packet(uint8_t *packet)
return false;
}
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
static void hci_adv_flow_monitor(void *context)
{
@@ -418,6 +455,7 @@ int hci_adv_credits_force_release(uint16_t num)
return credits_released;
}
#endif
+#endif // #if (BLE_42_SCAN_EN == TRUE)
static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
{
@@ -479,7 +517,7 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
hci_hal_env.callbacks->packet_ready(packet);
}
-
+#if (BLE_42_SCAN_EN == TRUE)
static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt)
{
uint8_t type;
@@ -515,13 +553,6 @@ static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt)
goto _discard_packet;
}
-#if SCAN_QUEUE_CONGEST_CHECK
- if(BTU_check_queue_is_congest()) {
- HCI_TRACE_DEBUG("BtuQueue is congested");
- goto _discard_packet;
- }
-#endif
-
packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
hci_hal_env.callbacks->adv_rpt_ready(linked_pkt);
@@ -533,6 +564,7 @@ _discard_packet:
hci_adv_credits_prep_to_release(1);
#endif
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
static void host_send_pkt_available_cb(void)
{
@@ -555,7 +587,12 @@ void bt_record_hci_data(uint8_t *data, uint16_t len)
)) {
bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2);
} else {
- uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]);
+ uint8_t data_type;
+ if (data[0] == HCI_LOG_DATA_TYPE_ISO_DATA) {
+ data_type = HCI_LOG_DATA_TYPE_ISO_DATA;
+ } else {
+ data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]);
+ }
bt_hci_log_record_hci_data(data_type, &data[1], len - 1);
}
#endif // (BT_HCI_LOG_INCLUDED == TRUE)
@@ -563,17 +600,33 @@ void bt_record_hci_data(uint8_t *data, uint16_t len)
static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
{
+#if (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
+ ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM, data, len);
+#endif // (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER)
//Target has packet to host, malloc new buffer for packet
BT_HDR *pkt = NULL;
+#if (BLE_42_SCAN_EN == TRUE)
pkt_linked_item_t *linked_pkt = NULL;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
size_t pkt_size;
- if (hci_hal_env.rx_q == NULL) {
+ if ((hci_hal_env.rx_q == NULL) || (data == NULL)) {
return 0;
}
bt_record_hci_data(data, len);
+#if (BLE_FEAT_ISO_EN == TRUE)
+ if (data[0] == DATA_TYPE_ISO) {
+ if (ble_host_iso_rx_cb) {
+ ble_host_iso_rx_cb(&data[1], len -1);
+ }
+
+ free(data);
+ return 0;
+ }
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
bool is_adv_rpt = host_recv_adv_packet(data);
if (!is_adv_rpt) {
@@ -588,8 +641,11 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
pkt->len = len;
pkt->layer_specific = 0;
memcpy(pkt->data, data, len);
- fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
+ {
+ fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
+ }
} else {
+#if (BLE_42_SCAN_EN == TRUE)
#if !BLE_ADV_REPORT_FLOW_CONTROL
// drop the packets if pkt_queue length goes beyond upper limit
if (pkt_queue_length(hci_hal_env.adv_rpt_q) > HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX) {
@@ -597,7 +653,11 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
}
#endif
pkt_size = BT_PKT_LINKED_HDR_SIZE + BT_HDR_SIZE + len;
+ #if HEAP_MEMORY_DEBUG
linked_pkt = (pkt_linked_item_t *) osi_calloc(pkt_size);
+ #else
+ linked_pkt = (pkt_linked_item_t *) osi_calloc_base(pkt_size);
+ #endif
if (!linked_pkt) {
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_consumed(1);
@@ -614,6 +674,9 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_consumed(1);
#endif
+#else
+ assert(0);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT);
@@ -622,42 +685,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
return 0;
}
-#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
-int
-ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg)
-{
- if(esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
- ble_hci_trans_buf_free(hci_ev);
- return 0;
- }
- uint16_t len = hci_ev[1] + 3;
- uint8_t *data = (uint8_t *)malloc(len);
- assert(data != NULL);
- data[0] = 0x04;
- memcpy(&data[1], hci_ev, len - 1);
- ble_hci_trans_buf_free(hci_ev);
- host_recv_pkt_cb(data, len);
- free(data);
- return 0;
-}
-
-
-int
-ble_hs_rx_data(struct os_mbuf *om, void *arg)
-{
- uint16_t len = OS_MBUF_PKTHDR(om)->omp_len + 1;
- uint8_t *data = (uint8_t *)malloc(len);
- assert(data != NULL);
- data[0] = 0x02;
- os_mbuf_copydata(om, 0, len - 1, &data[1]);
- host_recv_pkt_cb(data, len);
- free(data);
- os_mbuf_free_chain(om);
- return 0;
-}
-
-#endif
static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb = {
.notify_host_send_available = host_send_pkt_available_cb,
.notify_host_recv = host_recv_pkt_cb,
diff --git a/lib/bt/host/bluedroid/hci/hci_layer.c b/lib/bt/host/bluedroid/hci/hci_layer.c
index c9f1f5e3..e5cd263f 100644
--- a/lib/bt/host/bluedroid/hci/hci_layer.c
+++ b/lib/bt/host/bluedroid/hci/hci_layer.c
@@ -537,9 +537,11 @@ static void dispatch_adv_report(pkt_linked_item_t *linked_pkt)
//Tell Up-layer received packet.
if (btu_task_post(SIG_BTU_HCI_ADV_RPT_MSG, linked_pkt, OSI_THREAD_MAX_TIMEOUT) == false) {
osi_free(linked_pkt);
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_try_release(1);
#endif
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
}
// Misc internal functions
diff --git a/lib/bt/host/bluedroid/hci/hci_packet_factory.c b/lib/bt/host/bluedroid/hci/hci_packet_factory.c
index 5010e99d..6a84f9ca 100644
--- a/lib/bt/host/bluedroid/hci/hci_packet_factory.c
+++ b/lib/bt/host/bluedroid/hci/hci_packet_factory.c
@@ -52,6 +52,7 @@ static BT_HDR *make_set_c2h_flow_control(uint8_t enable)
return packet;
}
+#if (BLE_42_SCAN_EN == TRUE)
static BT_HDR *make_set_adv_report_flow_control(uint8_t enable, uint16_t num, uint16_t lost_threshold)
{
uint8_t *stream;
@@ -63,7 +64,7 @@ static BT_HDR *make_set_adv_report_flow_control(uint8_t enable, uint16_t num, ui
UINT16_TO_STREAM(stream, lost_threshold);
return packet;
}
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count)
{
uint8_t *stream;
@@ -158,6 +159,13 @@ static BT_HDR *make_ble_read_buffer_size(void)
return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE);
}
+#if (BLE_FEAT_ISO_EN == TRUE)
+static BT_HDR *make_ble_read_buffer_size_v2(void)
+{
+ return make_command_no_params(HCI_BLE_READ_BUFFER_SZIE_V2);
+}
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
static BT_HDR *make_ble_read_supported_states(void)
{
return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES);
@@ -219,10 +227,18 @@ static BT_HDR *make_write_default_erroneous_data_report(uint8_t enable)
return packet;
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
static BT_HDR *make_read_max_adv_data_len(void)
{
return make_command_no_params(HCI_BLE_RD_MAX_ADV_DATA_LEN);
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+static BT_HDR *read_periodic_adv_list_size(void)
+{
+ return make_command_no_params(HCI_BLE_RD_PERIOD_ADV_LIST_SIZE);
+}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
// Internal functions
@@ -252,7 +268,9 @@ static const hci_packet_factory_t interface = {
make_reset,
make_read_buffer_size,
make_set_c2h_flow_control,
+#if (BLE_42_SCAN_EN == TRUE)
make_set_adv_report_flow_control,
+#endif // #if (BLE_42_SCAN_EN == TRUE)
make_host_buffer_size,
make_read_local_version_info,
make_read_bd_addr,
@@ -265,11 +283,19 @@ static const hci_packet_factory_t interface = {
make_ble_write_host_support,
make_ble_read_white_list_size,
make_ble_read_buffer_size,
+#if (BLE_FEAT_ISO_EN == TRUE)
+ make_ble_read_buffer_size_v2,
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
make_ble_read_supported_states,
make_ble_read_local_supported_features,
make_ble_read_resolving_list_size,
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
make_read_max_adv_data_len,
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ read_periodic_adv_list_size,
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
make_ble_read_suggested_default_data_length,
make_ble_write_suggested_default_data_length,
diff --git a/lib/bt/host/bluedroid/hci/hci_packet_parser.c b/lib/bt/host/bluedroid/hci/hci_packet_parser.c
index 88515376..b254c9be 100644
--- a/lib/bt/host/bluedroid/hci/hci_packet_parser.c
+++ b/lib/bt/host/bluedroid/hci/hci_packet_parser.c
@@ -155,6 +155,26 @@ static void parse_ble_read_buffer_size_response(
osi_free(response);
}
+#if (BLE_FEAT_ISO_EN == TRUE)
+static void parse_ble_read_buffer_size_response_v2 (
+ BT_HDR *response,
+ uint16_t *data_size_ptr,
+ uint8_t *acl_buffer_count_ptr,
+ uint16_t *iso_pkt_len_ptr,
+ uint8_t *iso_pkt_num_ptr)
+{
+
+ uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SZIE_V2, 3 /* bytes after */);
+ assert(stream != NULL);
+ STREAM_TO_UINT16(*data_size_ptr, stream);
+ STREAM_TO_UINT8(*acl_buffer_count_ptr, stream);
+ STREAM_TO_UINT16(*iso_pkt_len_ptr, stream);
+ STREAM_TO_UINT8(*iso_pkt_num_ptr, stream);
+
+ osi_free(response);
+}
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
static void parse_ble_read_supported_states_response(
BT_HDR *response,
uint8_t *supported_states,
@@ -186,7 +206,9 @@ static void parse_ble_read_resolving_list_size_response(
{
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_RESOLVING_LIST_SIZE, 1 /* bytes after */);
- STREAM_TO_UINT8(*resolving_list_size_ptr, stream);
+ if (stream) {
+ STREAM_TO_UINT8(*resolving_list_size_ptr, stream);
+ }
osi_free(response);
}
@@ -198,22 +220,43 @@ static void parse_ble_read_suggested_default_data_length_response(
{
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */);
- STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream);
- STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream);
+ if (stream) {
+ STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream);
+ STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream);
+ }
+
osi_free(response);
}
+
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
static void parse_ble_read_adv_max_len_response(
BT_HDR *response,
uint16_t *adv_max_len_ptr)
{
uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */);
- // Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length
- STREAM_TO_UINT16(*adv_max_len_ptr, stream);
+ if (stream) {
+ // Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length
+ STREAM_TO_UINT16(*adv_max_len_ptr, stream);
+ }
+ osi_free(response);
+}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+static void parse_ble_read_periodic_adv_list_size_response(
+ BT_HDR *response,
+ uint16_t *periodic_adv_list_size_ptr)
+{
+ uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_PERIOD_ADV_LIST_SIZE, 1 /* bytes after */);
+ if (stream) {
+ // Size: 1 Octets ; Value: 0x01 to 0xFF ; Total number of Periodic Advertiser list entries that can be stored in the Controller
+ STREAM_TO_UINT8(*periodic_adv_list_size_ptr, stream);
+ }
osi_free(response);
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
@@ -254,6 +297,7 @@ static uint8_t *read_command_complete_header(
STREAM_TO_UINT8(status, stream);
if (status != HCI_SUCCESS) {
+ HCI_TRACE_ERROR("%s failed: opcode 0x%04x, status 0x%02x", __func__, opcode, status);
return NULL;
}
@@ -270,11 +314,19 @@ static const hci_packet_parser_t interface = {
parse_read_local_extended_features_response,
parse_ble_read_white_list_size_response,
parse_ble_read_buffer_size_response,
+#if (BLE_FEAT_ISO_EN == TRUE)
+ parse_ble_read_buffer_size_response_v2,
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
parse_ble_read_supported_states_response,
parse_ble_read_local_supported_features_response,
parse_ble_read_resolving_list_size_response,
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
parse_ble_read_adv_max_len_response,
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ parse_ble_read_periodic_adv_list_size_response,
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
parse_ble_read_suggested_default_data_length_response
};
diff --git a/lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h b/lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h
new file mode 100644
index 00000000..9b289677
--- /dev/null
+++ b/lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLE_HCI_ISO_
+#define H_BLE_HCI_ISO_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ble_hci_iso_pkt_hdr {
+ uint16_t conn_handle : 12,
+ pb_flag : 2,
+ ts_flag : 1;
+ uint16_t data_load_len;
+} __attribute__((packed));
+
+struct ble_hci_iso_pkt {
+ /* ISO header */
+ uint16_t conn_handle; /* CIS or BIS handle. */
+ uint8_t pb_flag : 2, /* Packet boundary flag. */
+ ts_flag : 1; /* Timestamp flag. */
+ uint16_t iso_data_load_len; /* ISO Data Load length. */
+
+ /* ISO Data Load */
+ uint32_t time_stamp; /* Timestamp. */
+ uint16_t packet_seq; /* Packet sequence number. */
+ uint16_t iso_sdu_len; /* SDU length. */
+ uint8_t ps_flag; /* Packet status. */
+ const uint8_t *sdu; /* First byte of ISO SDU. */
+};
+
+struct ble_hci_iso_tx {
+ struct ble_hci_iso_pkt pkt;
+};
+
+struct ble_hci_iso_rx {
+ struct ble_hci_iso_pkt pkt;
+};
+
+struct ble_hci_iso_conn {
+ uint16_t conn_handle;
+ uint8_t enabled : 1,
+ pb_flag : 2,
+ ts_flag : 1;
+ uint32_t time_stamp;
+ uint16_t pkt_seq_num;
+ uint16_t sdu_len;
+};
+
+int ble_hci_set_iso_buf_sz(uint16_t pktlen, uint8_t max_pkts);
+
+void ble_hci_get_iso_buf_size(uint16_t *pktlen, uint8_t *max_pkts);
+
+void ble_hci_add_iso_avail_pkts(uint16_t delta);
+
+struct ble_hci_iso_conn *ble_hci_iso_conn_find(uint16_t conn_handle);
+
+int esp_ble_hci_iso_tx(uint16_t conn_handle, const uint8_t *sdu, uint16_t sdu_len,
+ bool ts_flag, uint32_t time_stamp, uint16_t pkt_seq_num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_BLE_HCI_ISO_ */
diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h b/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h
index fe5796db..aec926b6 100644
--- a/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h
+++ b/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h
@@ -31,7 +31,8 @@ typedef enum {
DATA_TYPE_COMMAND = 1,
DATA_TYPE_ACL = 2,
DATA_TYPE_SCO = 3,
- DATA_TYPE_EVENT = 4
+ DATA_TYPE_EVENT = 4,
+ DATA_TYPE_ISO = 5,
} serial_data_type_t;
typedef void (*packet_ready_cb)(BT_HDR *packet);
diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h b/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h
index 8e822f0f..c48d0565 100644
--- a/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h
+++ b/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h
@@ -104,10 +104,11 @@ void hci_shut_down(void);
bool hci_downstream_data_post(uint32_t timeout);
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
int hci_adv_credits_prep_to_release(uint16_t num);
int hci_adv_credits_try_release(uint16_t num);
int hci_adv_credits_force_release(uint16_t num);
#endif
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#endif /* _HCI_LAYER_H_ */
diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h
index c1580fd8..2d36051a 100644
--- a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h
+++ b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h
@@ -26,7 +26,9 @@ typedef struct {
BT_HDR *(*make_reset)(void);
BT_HDR *(*make_read_buffer_size)(void);
BT_HDR *(*make_set_c2h_flow_control)(uint8_t enable);
+#if (BLE_42_SCAN_EN == TRUE)
BT_HDR *(*make_set_adv_report_flow_control)(uint8_t enable, uint16_t num, uint16_t lost_threshold);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
BT_HDR *(*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count);
BT_HDR *(*make_read_local_version_info)(void);
BT_HDR *(*make_read_bd_addr)(void);
@@ -39,11 +41,19 @@ typedef struct {
BT_HDR *(*make_ble_write_host_support)(uint8_t supported_host, uint8_t simultaneous_host);
BT_HDR *(*make_ble_read_white_list_size)(void);
BT_HDR *(*make_ble_read_buffer_size)(void);
+#if (BLE_FEAT_ISO_EN == TRUE)
+ BT_HDR *(*make_ble_read_buffer_size_v2)(void);
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
BT_HDR *(*make_ble_read_supported_states)(void);
BT_HDR *(*make_ble_read_local_supported_features)(void);
BT_HDR *(*make_ble_read_resolving_list_size)(void);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
BT_HDR *(*make_read_max_adv_data_len)(void);
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ BT_HDR *(*read_periodic_adv_list_size)(void);
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
BT_HDR *(*make_ble_read_suggested_default_data_length)(void);
BT_HDR *(*make_ble_write_suggested_default_data_length)(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime);
diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h
index e46acc17..c40ffef9 100644
--- a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h
+++ b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h
@@ -79,6 +79,16 @@ typedef struct {
uint8_t *acl_buffer_count_ptr
);
+#if (BLE_FEAT_ISO_EN == TRUE)
+ void (*parse_ble_read_buffer_size_response_v2) (
+ BT_HDR *response,
+ uint16_t *data_size_ptr,
+ uint8_t *acl_buffer_count_ptr,
+ uint16_t *iso_pkt_len_ptr,
+ uint8_t *iso_pkt_num_ptr
+ );
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
void (*parse_ble_read_supported_states_response)(
BT_HDR *response,
uint8_t *supported_states,
@@ -95,10 +105,18 @@ typedef struct {
uint8_t *resolving_list_size_ptr
);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
void (*parse_ble_read_adv_max_len_response) (
- BT_HDR *respone,
+ BT_HDR *response,
uint16_t *ble_ext_adv_data_max_len_ptr
);
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ void (*parse_ble_read_periodic_adv_list_size_response) (
+ BT_HDR *response,
+ uint16_t *periodic_advertiser_list_size
+ );
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
void (*parse_ble_read_suggested_default_data_length_response)(
BT_HDR *response,
diff --git a/lib/bt/host/bluedroid/hci/packet_fragmenter.c b/lib/bt/host/bluedroid/hci/packet_fragmenter.c
index 78b6151e..d8f2ff91 100644
--- a/lib/bt/host/bluedroid/hci/packet_fragmenter.c
+++ b/lib/bt/host/bluedroid/hci/packet_fragmenter.c
@@ -171,6 +171,12 @@ static void reassemble_and_dispatch(BT_HDR *packet)
return;
}
partial_packet = (BT_HDR *)osi_calloc(full_length + sizeof(BT_HDR));
+
+ if (partial_packet == NULL) {
+ HCI_TRACE_WARNING("%s full_length %d no memory.\n", __func__, full_length);
+ assert(0);
+ }
+
partial_packet->event = packet->event;
partial_packet->len = full_length;
partial_packet->offset = packet->len;
diff --git a/lib/bt/host/bluedroid/main/bte_init.c b/lib/bt/host/bluedroid/main/bte_init.c
index 80c4357b..c60f6f7b 100644
--- a/lib/bt/host/bluedroid/main/bte_init.c
+++ b/lib/bt/host/bluedroid/main/bte_init.c
@@ -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"
@@ -147,6 +156,10 @@
#include "bta_pan_int.h"
#endif
+#if BTA_PBA_CLIENT_INCLUDED == TRUE
+#include "bta_pba_client_int.h"
+#endif
+
#include "bta_sys_int.h"
// control block for patch ram downloading
@@ -175,6 +188,12 @@ void BTE_DeinitStack(void)
{
//BTA Modules
#if (BTA_INCLUDED == TRUE && BTA_DYNAMIC_MEMORY == TRUE)
+#if BTA_PBA_CLIENT_INCLUDED == TRUE
+ if (bta_pba_client_cb_ptr) {
+ osi_free(bta_pba_client_cb_ptr);
+ bta_pba_client_cb_ptr = NULL;
+ }
+#endif
#if GATTS_INCLUDED == TRUE
if (bta_gatts_cb_ptr){
osi_free(bta_gatts_cb_ptr);
@@ -267,6 +286,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 +415,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) {
@@ -492,6 +531,12 @@ bt_status_t BTE_InitStack(void)
#if BTA_PAN_INCLUDED==TRUE
memset((void *)bta_pan_cb_ptr, 0, sizeof(tBTA_PAN_CB));
#endif
+#if BTA_PBA_CLIENT_INCLUDED == TRUE
+ if ((bta_pba_client_cb_ptr = (tBTA_PBA_CLIENT_CB *)osi_malloc(sizeof(tBTA_PBA_CLIENT_CB))) == NULL) {
+ goto error_exit;
+ }
+ memset((void *)bta_pba_client_cb_ptr, 0, sizeof(tBTA_PBA_CLIENT_CB));
+#endif
#endif // BTA_INCLUDED == TRUE
return BT_STATUS_SUCCESS;
diff --git a/lib/bt/host/bluedroid/main/bte_main.c b/lib/bt/host/bluedroid/main/bte_main.c
index c47bdc15..c974037e 100644
--- a/lib/bt/host/bluedroid/main/bte_main.c
+++ b/lib/bt/host/bluedroid/main/bte_main.c
@@ -64,6 +64,9 @@ static void bte_main_enable(void);
bluedroid_init_done_cb_t bluedroid_init_done_cb;
extern void osi_mem_dbg_init(void);
+#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
+extern void free_controller_param(void);
+#endif
/******************************************************************************
**
** Function bte_main_boot_entry
@@ -85,7 +88,7 @@ int bte_main_boot_entry(bluedroid_init_done_cb_t cb)
osi_init();
- //Enbale HCI
+ //Enable HCI
bte_main_enable();
return 0;
@@ -105,6 +108,11 @@ void bte_main_shutdown(void)
#if (BLE_INCLUDED == TRUE)
BTA_VendorCleanup();
#endif
+
+#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
+ free_controller_param();
+#endif
+
bte_main_disable();
osi_deinit();
diff --git a/lib/bt/host/bluedroid/stack/avct/avct_lcb.c b/lib/bt/host/bluedroid/stack/avct/avct_lcb.c
index 61f6c9a5..84a0f021 100644
--- a/lib/bt/host/bluedroid/stack/avct/avct_lcb.c
+++ b/lib/bt/host/bluedroid/stack/avct/avct_lcb.c
@@ -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;
}
diff --git a/lib/bt/host/bluedroid/stack/avdt/avdt_api.c b/lib/bt/host/bluedroid/stack/avdt/avdt_api.c
index f37db816..9fb84fb9 100644
--- a/lib/bt/host/bluedroid/stack/avdt/avdt_api.c
+++ b/lib/bt/host/bluedroid/stack/avdt/avdt_api.c
@@ -266,6 +266,37 @@ UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs)
/*******************************************************************************
**
+** Function AVDT_UpdateCodecInfo
+**
+** Description Update codec capability for a stream endpoint.
+**
+**
+** Returns AVDT_SUCCESS if successful, otherwise error.
+**
+*******************************************************************************/
+UINT16 AVDT_UpdateCodecInfo(UINT8 handle, UINT8 num_codec, UINT8 *codec_info, UINT16 codec_info_len)
+{
+ UINT16 result = AVDT_SUCCESS;
+ tAVDT_SCB *p_scb;
+
+ /* look up scb */
+ if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) {
+ result = AVDT_BAD_HANDLE;
+ }
+ else if (num_codec != 1 || codec_info == NULL || codec_info_len != AVDT_CODEC_SIZE) {
+ /* currently, only allow one codec info */
+ result = AVDT_BAD_PARAMS;
+ }
+ else {
+ /* update codec info */
+ p_scb->cs.cfg.num_codec = num_codec;
+ memcpy(p_scb->cs.cfg.codec_info, codec_info, codec_info_len);
+ }
+ return result;
+}
+
+/*******************************************************************************
+**
** Function AVDT_RemoveStream
**
** Description Remove a stream endpoint. This function is called when
diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c b/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c
index 18106870..279313d4 100644
--- a/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c
+++ b/lib/bt/host/bluedroid/stack/avrc/avrc_bld_ct.c
@@ -50,7 +50,7 @@ static tAVRC_STS avrc_bld_next_cmd (tAVRC_NEXT_CMD *p_cmd, BT_HDR *p_pkt)
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
p_data = p_start + 2; /* pdu + rsvd */
- /* add fixed lenth 1 - pdu_id (1) */
+ /* add fixed length 1 - pdu_id (1) */
UINT16_TO_BE_STREAM(p_data, 1);
UINT8_TO_BE_STREAM(p_data, p_cmd->target_pdu);
p_pkt->len = (p_data - p_start);
@@ -81,7 +81,7 @@ static tAVRC_STS avrc_bld_set_abs_volume_cmd (tAVRC_SET_VOLUME_CMD *p_cmd, BT_HD
/* get the existing length, if any, and also the num attributes */
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
p_data = p_start + 2; /* pdu + rsvd */
- /* add fixed lenth 1 - volume (1) */
+ /* add fixed length 1 - volume (1) */
UINT16_TO_BE_STREAM(p_data, 1);
UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_cmd->volume));
p_pkt->len = (p_data - p_start);
@@ -163,7 +163,7 @@ static BT_HDR *avrc_bld_init_cmd_buffer(tAVRC_COMMAND *p_cmd)
/* reserved 0, packet_type 0 */
UINT8_TO_BE_STREAM(p_data, 0);
/* continue to the next "case to add length */
- /* add fixed lenth - 0 */
+ /* add fixed length - 0 */
UINT16_TO_BE_STREAM(p_data, 0);
break;
}
@@ -237,6 +237,20 @@ static tAVRC_STS avrc_bld_get_element_attr_cmd (tAVRC_GET_ELEM_ATTRS_CMD *p_cmd,
return AVRC_STS_NO_ERROR;
}
+static tAVRC_STS avrc_bld_get_play_status_cmd(tAVRC_CMD *p_cmd, BT_HDR *p_pkt)
+{
+ UINT8 *p_data, *p_start;
+
+ AVRC_TRACE_API("avrc_bld_get_play_status");
+ /* get the existing length */
+ p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
+ p_data = p_start + 2; /* pdu + rsvd */
+ /* add parameter length 0 */
+ UINT16_TO_BE_STREAM(p_data, 0);
+ p_pkt->len = (p_data - p_start);
+ return AVRC_STS_NO_ERROR;
+}
+
static tAVRC_STS avrc_bld_get_caps_cmd(tAVRC_GET_CAPS_CMD *p_cmd, BT_HDR *p_pkt)
{
UINT8 *p_data, *p_start;
@@ -309,6 +323,10 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt)
status = avrc_bld_get_element_attr_cmd(&p_cmd->get_elem_attrs, p_pkt);
break;
+ case AVRC_PDU_GET_PLAY_STATUS: /* 0x30 */
+ status = avrc_bld_get_play_status_cmd(&p_cmd->get_play_status, p_pkt);
+ break;
+
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
status = avrc_bld_register_change_notfn(p_cmd->reg_notif.event_id, p_cmd->reg_notif.param, p_pkt);
break;
diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c
index f185e7b5..72f26513 100644
--- a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c
+++ b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c
@@ -113,6 +113,19 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
}
}
break;
+ case AVRC_PDU_GET_PLAY_STATUS:
+ if (p_msg->hdr.ctype == AVRC_RSP_IMPL_STBL) {
+ BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
+ BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
+ BE_STREAM_TO_UINT8(p_result->get_play_status.play_status, p);
+ }
+ else {
+ /* got error response */
+ p_result->get_play_status.song_len = 0;
+ p_result->get_play_status.song_pos = 0;
+ p_result->get_play_status.play_status = AVRC_PLAYSTATE_ERROR;
+ }
+ break;
default:
status = AVRC_STS_BAD_CMD;
break;
diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c
index c30bf94a..fe04ca8f 100644
--- a/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c
+++ b/lib/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c
@@ -71,7 +71,7 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
p++; /* skip the reserved byte */
BE_STREAM_TO_UINT16 (len, p);
if ((len + 4) != (p_msg->vendor_len)) {
- status = AVRC_STS_INTERNAL_ERR;
+ status = AVRC_STS_NOT_FOUND;
}
if (status != AVRC_STS_NO_ERROR) {
diff --git a/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c b/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c
index fa98082e..0b624b3f 100644
--- a/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c
+++ b/lib/bt/host/bluedroid/stack/avrc/avrc_sdp.c
@@ -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.
**
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_acl.c b/lib/bt/host/bluedroid/stack/btm/btm_acl.c
index 4b7e7eed..90506785 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_acl.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_acl.c
@@ -335,7 +335,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L
#if (CLASSIC_BT_INCLUDED == TRUE)
const UINT8 req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);
#endif ///CLASSIC_BT_INCLUDED == TRUE
- /* Store the Peer Security Capabilites (in SM4 and rmt_sec_caps) */
+ /* Store the Peer Security Capabilities (in SM4 and rmt_sec_caps) */
#if (SMP_INCLUDED == TRUE)
btm_sec_set_peer_sec_caps(p, p_dev_rec);
#endif ///SMP_INCLUDED == TRUE
@@ -350,7 +350,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L
return;
}
} else {
- /* If remote features indicated secure connection (SC) mode, check the remote feautres again*/
+ /* If remote features indicated secure connection (SC) mode, check the remote features again*/
/* this is to prevent from BIAS attack where attacker can downgrade SC mode*/
btm_read_remote_features (p->hci_handle);
}
@@ -474,7 +474,7 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport)
BTM_TRACE_DEBUG("Bonded\n");
}
} else {
- BTM_TRACE_DEBUG("Bletooth link down\n");
+ BTM_TRACE_DEBUG("Bluetooth link down\n");
p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED
| BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
}
@@ -531,10 +531,11 @@ void btm_acl_device_down (void)
*******************************************************************************/
void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
{
- tBTM_BL_UPDATE_DATA evt;
- UINT8 busy_level;
- BTM_TRACE_DEBUG ("btm_acl_update_busy_level\n");
+ UINT8 busy_level_flags = 0;
BOOLEAN old_inquiry_state = btm_cb.is_inquiry;
+
+ BTM_TRACE_DEBUG ("btm_acl_update_busy_level\n");
+
switch (event) {
case BTM_BLI_ACL_UP_EVT:
BTM_TRACE_DEBUG ("BTM_BLI_ACL_UP_EVT\n");
@@ -545,30 +546,31 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
case BTM_BLI_PAGE_EVT:
BTM_TRACE_DEBUG ("BTM_BLI_PAGE_EVT\n");
btm_cb.is_paging = TRUE;
- evt.busy_level_flags = BTM_BL_PAGING_STARTED;
+ busy_level_flags = BTM_BL_PAGING_STARTED;
break;
case BTM_BLI_PAGE_DONE_EVT:
BTM_TRACE_DEBUG ("BTM_BLI_PAGE_DONE_EVT\n");
btm_cb.is_paging = FALSE;
- evt.busy_level_flags = BTM_BL_PAGING_COMPLETE;
+ busy_level_flags = BTM_BL_PAGING_COMPLETE;
break;
case BTM_BLI_INQ_EVT:
BTM_TRACE_DEBUG ("BTM_BLI_INQ_EVT\n");
btm_cb.is_inquiry = TRUE;
- evt.busy_level_flags = BTM_BL_INQUIRY_STARTED;
+ busy_level_flags = BTM_BL_INQUIRY_STARTED;
break;
case BTM_BLI_INQ_CANCEL_EVT:
BTM_TRACE_DEBUG ("BTM_BLI_INQ_CANCEL_EVT\n");
btm_cb.is_inquiry = FALSE;
- evt.busy_level_flags = BTM_BL_INQUIRY_CANCELLED;
+ busy_level_flags = BTM_BL_INQUIRY_CANCELLED;
break;
case BTM_BLI_INQ_DONE_EVT:
BTM_TRACE_DEBUG ("BTM_BLI_INQ_DONE_EVT\n");
btm_cb.is_inquiry = FALSE;
- evt.busy_level_flags = BTM_BL_INQUIRY_COMPLETE;
+ busy_level_flags = BTM_BL_INQUIRY_COMPLETE;
break;
}
+ UINT8 busy_level;
if (btm_cb.is_paging || btm_cb.is_inquiry) {
busy_level = 10;
} else {
@@ -576,8 +578,11 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
}
if ((busy_level != btm_cb.busy_level) || (old_inquiry_state != btm_cb.is_inquiry)) {
- evt.event = BTM_BL_UPDATE_EVT;
- evt.busy_level = busy_level;
+ tBTM_BL_UPDATE_DATA evt = {
+ .event = BTM_BL_UPDATE_EVT,
+ .busy_level = busy_level,
+ .busy_level_flags = busy_level_flags,
+ };
btm_cb.busy_level = busy_level;
if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_UPDATE_MASK)) {
(*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
@@ -1016,7 +1021,7 @@ void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages)
const UINT8 req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);
#if (SMP_INCLUDED == TRUE)
- /* Store the Peer Security Capabilites (in SM4 and rmt_sec_caps) */
+ /* Store the Peer Security Capabilities (in SM4 and rmt_sec_caps) */
btm_sec_set_peer_sec_caps(p_acl_cb, p_dev_rec);
#endif ///SMP_INCLUDED == TRUE
BTM_TRACE_API("%s: pend:%d\n", __FUNCTION__, req_pend);
@@ -1455,7 +1460,7 @@ void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset)
**
** Function btm_acl_role_changed
**
-** Description This function is called whan a link's master/slave role change
+** Description This function is called when a link's master/slave role change
** event or command status event (with error) is received.
** It updates the link control block, and calls
** the registered callback with status and role (if registered).
@@ -2060,6 +2065,7 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
return (BTM_UNKNOWN_ADDR);
}
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
/*******************************************************************************
**
** Function BTM_ReadTxPower
@@ -2116,6 +2122,7 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_C
/* If here, no BD Addr found */
return (BTM_UNKNOWN_ADDR);
}
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_CB *p_cb)
{
@@ -2182,6 +2189,55 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types)
}
#if (BLE_INCLUDED == TRUE)
+
+/*******************************************************************************
+**
+** Function BTM_ReadChannelMap
+**
+** Description This function is called to read the current channel map
+** for the given connection. The results are returned via
+** the callback (tBTM_BLE_CH_MAP_RESULTS).
+**
+** Returns BTM_CMD_STARTED if successfully initiated or error code
+**
+*******************************************************************************/
+tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
+{
+ tACL_CONN *p;
+ tBTM_BLE_CH_MAP_RESULTS result;
+
+ BTM_TRACE_DEBUG("BTM_ReadChannelMap: RemBdAddr: %02x%02x%02x%02x%02x%02x\n",
+ remote_bda[0], remote_bda[1], remote_bda[2],
+ remote_bda[3], remote_bda[4], remote_bda[5]);
+
+ memset(result.channel_map, 0, sizeof(result.channel_map)); // Clear channel map data
+ /* If someone already waiting for the channel map, do not allow another */
+ if (btm_cb.devcb.p_ble_ch_map_cmpl_cb) {
+ result.status = BTM_BUSY;
+ (*p_cb)(&result);
+ return BTM_BUSY;
+ }
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE);
+ if (p != NULL) {
+ btm_cb.devcb.p_ble_ch_map_cmpl_cb = p_cb;
+
+ if (!btsnd_hcic_ble_read_chnl_map(p->hci_handle)) {
+ btm_cb.devcb.p_ble_ch_map_cmpl_cb = NULL;
+ result.status = BTM_NO_RESOURCES;
+ (*p_cb)(&result);
+ return BTM_NO_RESOURCES;
+ } else {
+ return BTM_CMD_STARTED;
+ }
+ }
+
+ /* If here, no BD Addr found */
+ result.status = BTM_UNKNOWN_ADDR;
+ (*p_cb)(&result);
+ return BTM_UNKNOWN_ADDR;
+}
+
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb)
{
BOOLEAN ret;
@@ -2208,6 +2264,7 @@ tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb)
return BTM_CMD_STARTED;
}
}
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
void BTM_BleGetWhiteListSize(uint16_t *length)
{
@@ -2218,8 +2275,21 @@ void BTM_BleGetWhiteListSize(uint16_t *length)
*length = p_cb->white_list_avail_size;
return;
}
+
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+void BTM_BleGetPeriodicAdvListSize(uint8_t *size)
+{
+ tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
+ if (p_cb->periodic_adv_list_size == 0) {
+ BTM_TRACE_WARNING("%s Periodic Adv list is full.", __func__);
+ }
+ *size = p_cb->periodic_adv_list_size;
+}
+#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+
#endif ///BLE_INCLUDED == TRUE
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
/*******************************************************************************
**
** Function btm_read_tx_power_complete
@@ -2273,6 +2343,63 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble)
(*p_cb)(&results);
}
}
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
+
+/*******************************************************************************
+**
+** Function btm_read_channel_map_complete
+**
+** Description This function is called when the command complete message
+** is received from the HCI for the read channel map request.
+** It processes the received channel map data and invokes the
+** registered callback function with the results.
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_read_channel_map_complete(UINT8 *p)
+{
+ tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_ble_ch_map_cmpl_cb;
+ tBTM_BLE_CH_MAP_RESULTS results;
+ UINT16 handle;
+ tACL_CONN *p_acl_cb = NULL;
+
+ BTM_TRACE_DEBUG("btm_read_channel_map_complete\n");
+
+ /* Reset the callback pointer to prevent duplicate calls */
+ btm_cb.devcb.p_ble_ch_map_cmpl_cb = NULL;
+
+ if (p_cb) {
+ /* Extract HCI status from the response */
+ STREAM_TO_UINT8(results.hci_status, p);
+
+ if (results.hci_status == HCI_SUCCESS) {
+ results.status = BTM_SUCCESS;
+
+ /* Extract the connection handle and channel map */
+ STREAM_TO_UINT16(handle, p);
+ STREAM_TO_ARRAY(results.channel_map, p, 5);
+
+ BTM_TRACE_DEBUG("BTM Channel Map Complete: handle 0x%04x, hci status 0x%02x", handle, results.hci_status);
+ BTM_TRACE_DEBUG("Channel Map: %02x %02x %02x %02x %02x",
+ results.channel_map[0], results.channel_map[1], results.channel_map[2],
+ results.channel_map[3], results.channel_map[4]);
+
+ /* Retrieve the remote BD address using the connection handle */
+ p_acl_cb = btm_handle_to_acl(handle);
+ if (p_acl_cb) {
+ memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
+ }
+ } else {
+ results.status = BTM_ERR_PROCESSING;
+ BTM_TRACE_ERROR("BTM Channel Map Read Failed: hci status 0x%02x", results.hci_status);
+ }
+
+ /* Invoke the registered callback with the results */
+ (*p_cb)(&results);
+ }
+}
+
/*******************************************************************************
**
@@ -2705,7 +2832,7 @@ void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mo
l2c_link_hci_conn_comp(status, handle, bda);
}
#if BTM_SCO_INCLUDED == TRUE
- else {
+ else if (link_type == HCI_LINK_TYPE_SCO) {
memset(&esco_data, 0, sizeof(tBTM_ESCO_DATA));
esco_data.link_type = HCI_LINK_TYPE_SCO;
memcpy (esco_data.bd_addr, bda, BD_ADDR_LEN);
@@ -2721,9 +2848,10 @@ void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mo
** Description Handle ACL disconnection complete event
**
*******************************************************************************/
-void btm_acl_disconnected(UINT16 handle, UINT8 reason)
+BOOLEAN btm_acl_disconnected(UINT16 handle, UINT8 reason)
{
-
+ BOOLEAN status = FALSE;
+ BOOLEAN dis_status;
/* Report BR/EDR ACL disconnection result to upper layer */
tACL_CONN *conn = btm_handle_to_acl(handle);
if (conn) {
@@ -2731,6 +2859,7 @@ void btm_acl_disconnected(UINT16 handle, UINT8 reason)
if (conn->transport == BT_TRANSPORT_BR_EDR)
#endif
{
+ status = TRUE;
tBTM_ACL_LINK_STAT_EVENT_DATA evt_data = {
.event = BTM_ACL_DISCONN_CMPL_EVT,
.link_act.disconn_cmpl.reason = reason,
@@ -2742,16 +2871,29 @@ void btm_acl_disconnected(UINT16 handle, UINT8 reason)
}
#if BTM_SCO_INCLUDED == TRUE
+ dis_status = l2c_link_hci_disc_comp (handle, reason);
/* If L2CAP doesn't know about it, send it to SCO */
- if (!l2c_link_hci_disc_comp (handle, reason)) {
- btm_sco_removed (handle, reason);
+ if (!dis_status) {
+ dis_status = btm_sco_removed (handle, reason);
+ } else {
+ status = TRUE;
}
#else
- l2c_link_hci_disc_comp(handle, reason);
+ dis_status = l2c_link_hci_disc_comp(handle, reason);
#endif /* BTM_SCO_INCLUDED */
+ if (dis_status) {
+ // find tL2C_LCB
+ status = TRUE;
+ }
#if (SMP_INCLUDED == TRUE)
/* Notify security manager */
- btm_sec_disconnected(handle, reason);
+ if (btm_sec_disconnected(handle, reason)) {
+ // find tBTM_SEC_DEV_REC
+ status = TRUE;
+ }
+
#endif /* SMP_INCLUDED == TRUE */
+
+ return status;
}
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble.c b/lib/bt/host/bluedroid/stack/btm/btm_ble.c
index 334001fe..8f676a65 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble.c
@@ -217,7 +217,7 @@ void BTM_BleLoadLocalKeys(UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
break;
default:
- BTM_TRACE_ERROR("unknow local key type: %d", key_type);
+ BTM_TRACE_ERROR("unknown local key type: %d", key_type);
break;
}
}
@@ -553,6 +553,7 @@ void BTM_BleSecureConnectionCreateOobData(void)
#endif
}
+#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
/******************************************************************************
**
** Function BTM_BleSetConnScanParams
@@ -582,15 +583,17 @@ void BTM_BleSetConnScanParams (UINT32 scan_interval, UINT32 scan_window)
p_ble_cb->scan_win = scan_window;
new_param = TRUE;
}
-
+#if (tGATT_BG_CONN_DEV == TRUE)
if (new_param && p_ble_cb->conn_state == BLE_BG_CONN) {
btm_ble_suspend_bg_conn();
}
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
} else {
BTM_TRACE_ERROR("Illegal Connection Scan Parameters");
}
#endif
}
+#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE)
/********************************************************
**
@@ -694,7 +697,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR
BTM_TRACE_DEBUG ("btm_find_dev_type - unknown device, BR/EDR assumed");
}
}
- } else { /* there is a security device record exisitng */
+ } else { /* there is a security device record existing */
/* new inquiry result, overwrite device type in security device record */
if (p_inq_info) {
p_dev_rec->device_type = p_inq_info->results.device_type;
@@ -707,7 +710,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR
} else if (memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0) {
*p_dev_type = BT_DEVICE_TYPE_BLE;
*p_addr_type = p_dev_rec->ble.ble_addr_type;
- } else { /* matching static adddress only */
+ } else { /* matching static address only */
*p_dev_type = BT_DEVICE_TYPE_BREDR;
*p_addr_type = BLE_ADDR_PUBLIC;
}
@@ -766,6 +769,7 @@ BOOLEAN BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda, tBT_TRANSPORT tran
}
#if (BLE_INCLUDED == TRUE)
+#if (BLE_42_DTM_TEST_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleReceiverTest
@@ -805,7 +809,8 @@ void BTM_BleTransmitterTest(UINT8 tx_freq, UINT8 test_data_len,
BTM_TRACE_ERROR("%s: Unable to Trigger LE transmitter test", __FUNCTION__);
}
}
-
+#endif // #if (BLE_42_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
/*******************************************************************************
**
** Function BTM_BleTestEnd
@@ -837,9 +842,9 @@ void btm_ble_test_command_complete(UINT8 *p)
(*p_cb)(p);
}
}
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
-
-#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleEnhancedReceiverTest
@@ -882,7 +887,7 @@ void BTM_BleEnhancedTransmitterTest(UINT8 tx_freq, UINT8 test_data_len,
BTM_TRACE_ERROR("%s: Unable to Trigger LE enhanced transmitter test", __FUNCTION__);
}
}
-#endif // BLE_50_FEATURE_SUPPORT
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
/*******************************************************************************
**
@@ -1061,7 +1066,7 @@ tBTM_SEC_ACTION btm_ble_determine_security_act(BOOLEAN is_originator, BD_ADDR bd
** LE link for LE COC.
**
** Parameter bdaddr: remote device address.
-** psm : PSM of the LE COC sevice.
+** psm : PSM of the LE COC service.
** is_originator: TRUE if outgoing connection.
** p_callback : Pointer to the callback function.
** p_ref_data : Pointer to be returned along with the callback.
@@ -1078,7 +1083,7 @@ BOOLEAN btm_ble_start_sec_check(BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originat
/* If there is no application registered with this PSM do not allow connection */
if (!p_serv_rec)
{
- BTM_TRACE_WARNING ("%s PSM: %d no application registerd", __func__, psm);
+ BTM_TRACE_WARNING ("%s PSM: %d no application registered", __func__, psm);
(*p_callback) (bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_MODE_UNSUPPORTED);
return FALSE;
}
@@ -1151,7 +1156,7 @@ void btm_ble_rand_enc_complete (UINT8 *p, UINT16 op_code, tBTM_RAND_ENC_CB *p_en
/* If there was a callback address for vcs complete, call it */
if (p_enc_cplt_cback && p) {
- /* Pass paramters to the callback function */
+ /* Pass parameters to the callback function */
STREAM_TO_UINT8(params.status, p); /* command status */
if (params.status == HCI_SUCCESS) {
@@ -1208,7 +1213,7 @@ void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, BOOLEAN is_local )
** Function btm_ble_get_enc_key_type
**
** Description This function is to get the BLE key type that has been exchanged
-** in betweem local device and peer device.
+** in between local device and peer device.
**
** Returns p_key_type: output parameter to carry the key type value.
**
@@ -1235,7 +1240,7 @@ BOOLEAN btm_ble_get_enc_key_type(BD_ADDR bd_addr, UINT8 *p_key_types)
**
** Description This function is called to read the local DIV
**
-** Returns TRUE - if a valid DIV is availavle
+** Returns TRUE - if a valid DIV is available
*******************************************************************************/
BOOLEAN btm_get_local_div (BD_ADDR bd_addr, UINT16 *p_div)
{
@@ -1487,7 +1492,7 @@ void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE
BTM_TRACE_DEBUG ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags);
- /* currently encrpted */
+ /* currently encrypted */
if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED) {
if (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED) {
cur_sec_level = BTM_LE_SEC_AUTHENTICATED;
@@ -1691,7 +1696,7 @@ tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
**
** Function btm_ble_link_encrypted
**
-** Description This function is called when LE link encrption status is changed.
+** Description This function is called when LE link encryption status is changed.
**
** Returns void
**
@@ -1949,7 +1954,7 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data)
** Function btm_ble_connected
**
** Description This function is when a LE connection to the peer device is
-** establsihed
+** established
**
** Returns void
**
@@ -2060,7 +2065,7 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced)
peer_addr_type = bda_type;
match = btm_identity_addr_to_random_pseudo (bda, &bda_type, FALSE);
- /* possiblly receive connection complete with resolvable random on
+ /* possibly receive connection complete with resolvable random on
slave role while the device has been paired */
/* It will cause that scanner doesn't send scan request to advertiser
@@ -2143,6 +2148,16 @@ void btm_ble_create_ll_conn_complete (UINT8 status)
if (status != HCI_SUCCESS) {
btm_ble_set_conn_st(BLE_CONN_IDLE);
btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status);
+ if(l2cb.is_ble_connecting) {
+ /* see L2CA_CancelBleConnectReq() */
+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(l2cb.ble_connecting_bda, BT_TRANSPORT_LE);
+ /* Do not remove lcb if an LE link is already up as a peripheral */
+ if (p_lcb != NULL &&
+ !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_LE_ACL_IS_CONNECTED(l2cb.ble_connecting_bda))) {
+ p_lcb->disc_reason = L2CAP_CONN_CANCEL;
+ l2cu_release_lcb (p_lcb);
+ }
+ }
}
}
@@ -2279,17 +2294,16 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
}
- } else {
- if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) {
- tBTM_LE_EVT_DATA evt_data;
- memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA));
- if (btm_cb.api.p_le_callback) {
- (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data);
- }
- } else {
- BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device");
+ }
+
+ if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) {
+ tBTM_LE_EVT_DATA evt_data;
+ memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA));
+ if (btm_cb.api.p_le_callback) {
+ (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data);
}
}
+
return 0;
}
#endif ///SMP_INCLUDED == TRUE
@@ -2300,7 +2314,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
** Function BTM_BleDataSignature
**
** Description This function is called to sign the data using AES128 CMAC
-** algorith.
+** algorithm.
**
** Parameter bd_addr: target device the data to be signed for.
** p_text: singing data
@@ -2308,7 +2322,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
** signature: output parameter where data signature is going to
** be stored.
**
-** Returns TRUE if signing sucessul, otherwise FALSE.
+** Returns TRUE if signing successful, otherwise FALSE.
**
*******************************************************************************/
#if (SMP_INCLUDED == TRUE)
@@ -2491,7 +2505,7 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning(BD_ADDR bd_addr)
** Function BTM_BleGetSupportedKeySize
**
** Description This function gets the maximum encryption key size in bytes
-** the local device can suport.
+** the local device can support.
** record.
**
** Returns the key size or 0 if the size can't be retrieved.
@@ -2932,7 +2946,7 @@ uint8_t btm_ble_scan_active_count(void)
}
#if (SMP_INCLUDED == TRUE)
-uint8_t btm_ble_sec_dev_active_count(void)
+uint8_t btm_ble_sec_dev_record_count(void)
{
tBTM_SEC_DEV_REC *p_dev_rec = NULL;
list_node_t *p_node = NULL;
@@ -2948,6 +2962,12 @@ uint8_t btm_ble_sec_dev_active_count(void)
return count;
}
+
+void btm_ble_clear_sec_dev_record(void)
+{
+ /* only used when connection is closed */
+ if(btm_cb.p_sec_dev_rec_list) list_clear(btm_cb.p_sec_dev_rec_list);
+}
#endif
#if (BLE_PRIVACY_SPT == TRUE)
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c
index 04ad4804..76fe63c0 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c
@@ -21,6 +21,7 @@ extern BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda);
extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda);
extern void BTM_BleSetStaticAddr(BD_ADDR rand_addr);
extern uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS *params);
static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, UINT8 *data);
@@ -35,6 +36,8 @@ typedef struct {
} tBTM_EXT_ADV_RECORD;
tBTM_EXT_ADV_RECORD adv_record[MAX_BLE_ADV_INSTANCE] = {0};
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+
extern void btm_ble_inter_set(bool extble_inter);
#if !UC_BT_STACK_NO_LOG
@@ -193,11 +196,12 @@ void btm_ble_extendadvcb_init(void)
{
memset(&extend_adv_cb, 0, sizeof(tBTM_BLE_EXTENDED_CB));
}
-
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
void btm_ble_advrecod_init(void)
{
memset(&adv_record[0], 0, sizeof(tBTM_EXT_ADV_RECORD)*MAX_BLE_ADV_INSTANCE);
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
void BTM_BleGapRegisterCallback(tBTM_BLE_5_HCI_CBACK cb)
{
@@ -249,10 +253,10 @@ tBTM_STATUS BTM_BleSetPreferDefaultPhy(UINT8 tx_phy_mask, UINT8 rx_phy_mask)
if ((err = btsnd_hcic_ble_set_prefered_default_phy(all_phys, tx_phy_mask, rx_phy_mask)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
- cb_params.set_perf_def_phy.status = err;
+ cb_params.set_perf_def_phy.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT, &cb_params);
@@ -286,6 +290,7 @@ tBTM_STATUS BTM_BleSetPreferPhy(BD_ADDR bd_addr, UINT8 all_phys, UINT8 tx_phy_ma
return BTM_SUCCESS;
}
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr)
{
tBTM_STATUS status = BTM_SUCCESS;
@@ -330,7 +335,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr)
if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
} else {
// set random address success, update address info
if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) {
@@ -340,8 +345,8 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr)
}
end:
- cb_params.status = status;
-
+ cb_params.set_ext_rand_addr.status = status;
+ cb_params.set_ext_rand_addr.instance = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, &cb_params);
return status;
@@ -403,7 +408,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR
params->primary_phy, params->max_skip,
params->secondary_phy, params->sid, params->scan_req_notif)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
goto end;
}
@@ -414,13 +419,14 @@ end:
// update RPA address
if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
} else {
// set addr success, update address info
BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr);
}
}
- cb_params.status = status;
+ cb_params.set_params.status = status;
+ cb_params.set_params.instance = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
return status;
@@ -451,27 +457,36 @@ tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance,
} else if (rem_len <= BTM_BLE_EXT_ADV_DATA_LEN_MAX) {
operation = BTM_BLE_ADV_DATA_OP_LAST_FRAG;
} else {
- operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG;
- }
+ operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG;
+ }
}
if (!is_scan_rsp) {
if ((err = btsnd_hcic_ble_set_ext_adv_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetAdvData: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
+ break;
}
} else {
if ((err = btsnd_hcic_ble_set_ext_adv_scan_rsp_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetScanRspData: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
+ break;
}
}
rem_len -= send_data_len;
- data_offset += send_data_len;
+ data_offset += send_data_len;
} while (rem_len);
end:
- cb_params.status = status;
+ if (is_scan_rsp) {
+ cb_params.scan_rsp_data_set.status = status;
+ cb_params.scan_rsp_data_set.instance = instance;
+ } else {
+ cb_params.adv_data_set.status = status;
+ cb_params.adv_data_set.instance = instance;
+ }
+
BTM_ExtBleCallbackTrigger(is_scan_rsp ? BTM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
return status;
@@ -514,7 +529,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_
if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, instance,
duration, max_events)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
osi_free(instance);
@@ -525,7 +540,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_
if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, NULL, NULL, NULL)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
goto end;
}
@@ -574,7 +589,12 @@ end:
}
}
- cb_params.status = status;
+ cb_params.adv_start.status = status;
+ cb_params.adv_start.instance_num = num;
+ for (uint8_t i = 0; i < num; i++) {
+ cb_params.adv_start.instance[i] = ext_adv[i].instance;
+ }
+
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params);
return status;
@@ -593,6 +613,7 @@ tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t con_handle)
}
if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid)) {
+ BTM_TRACE_WARNING("%s failed to find extend adv, adv_handle %u con_handle %u", __func__, index, con_handle);
return BTM_WRONG_MODE;
}
@@ -618,7 +639,7 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance)
if ((err = btsnd_hcic_ble_remove_adv_set(instance)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EAS Rm: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
} else {
extend_adv_cb.inst[instance].configured = false;
extend_adv_cb.inst[instance].legacy_pdu = false;
@@ -629,7 +650,9 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance)
end:
- cb_params.status = status;
+ cb_params.adv_start.status = status;
+ cb_params.adv_start.instance_num = 1;
+ cb_params.adv_start.instance[0] = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT, &cb_params);
@@ -644,7 +667,7 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void)
if ((err = btsnd_hcic_ble_clear_adv_set()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EAS Clr: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
} else {
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
extend_adv_cb.inst[i].configured = false;
@@ -655,13 +678,15 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void)
}
}
- cb_params.status = status;
+ cb_params.adv_start.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT, &cb_params);
return status;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Params *params)
{
tBTM_STATUS status = BTM_SUCCESS;
@@ -688,12 +713,13 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa
if ((err= btsnd_hcic_ble_set_periodic_adv_params(instance, params->interval_min,
params->interval_max, params->properties)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SetParams: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
end:
- cb_params.status = status;
+ cb_params.per_adv_set_params.status = status;
+ cb_params.per_adv_set_params.instance = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
@@ -740,14 +766,18 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data
if ((err = btsnd_hcic_ble_set_periodic_adv_data(instance, operation, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SetData: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
+ break;
}
+
rem_len -= send_data_len;
- data_offset += send_data_len;
+ data_offset += send_data_len;
} while(rem_len);
end:
- cb_params.status = status;
+ cb_params.per_adv_data_set.status = status;
+ cb_params.per_adv_data_set.instance = instance;
+
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
return status;
@@ -767,19 +797,26 @@ tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, UINT8 enable)
if ((err = btsnd_hcic_ble_periodic_adv_enable(enable, instance)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA En=%d: cmd err=0x%x", enable, err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
end:
-
- cb_params.status = status;
+ if (enable) {
+ cb_params.per_adv_start.status = status;
+ cb_params.per_adv_start.instance = instance;
+ } else {
+ cb_params.per_adv_stop.status = status;
+ cb_params.per_adv_stop.instance = instance;
+ }
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT, &cb_params);
return status;
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params)
{
//tHCI_STATUS err = HCI_SUCCESS;
@@ -794,10 +831,10 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params)
if ((params->sync_timeout < 0x0a || params->sync_timeout > 0x4000)
|| (params->filter_policy > 0x01)
- #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
+#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
|| (params->reports_disabled > 0x01)
|| (params->filter_duplicates > 0x01)
- #endif
+#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
/*If the Periodic Advertiser List is not used,
the Advertising_SID, Advertiser Address_Type, and Advertiser Address
parameters specify the periodic advertising device to listen to; otherwise they
@@ -814,17 +851,17 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params)
SET_BIT(option, 0);
}
- #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
+#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
if (params->reports_disabled) {
SET_BIT(option, 1);
}
if (params->filter_duplicates) {
SET_BIT(option, 2);
}
- #endif
+#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
if (!btsnd_hcic_ble_periodic_adv_create_sync(option, params->sid, params->addr_type,
- params->addr, params->sync_timeout, 0)) {
+ params->addr, params->sync_timeout, params->sync_cte_type)) {
BTM_TRACE_ERROR("LE PA CreateSync cmd failed");
status = BTM_ILLEGAL_VALUE;
}
@@ -837,6 +874,8 @@ end:
return status;
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+
void btm_set_phy_callback(UINT8 status)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
@@ -845,6 +884,8 @@ void btm_set_phy_callback(UINT8 status)
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
}
+
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
void btm_create_sync_callback(UINT8 status)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
@@ -852,6 +893,7 @@ void btm_create_sync_callback(UINT8 status)
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params);
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_phy, uint8_t rx_phy)
{
@@ -872,6 +914,7 @@ void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT, &cb_params);
}
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void)
{
tHCI_STATUS err = HCI_SUCCESS;
@@ -880,7 +923,7 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void)
if ((err = btsnd_hcic_ble_periodic_adv_create_sync_cancel()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
cb_params.status = status;
@@ -898,7 +941,7 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncTerm(UINT16 sync_handle)
if (( err = btsnd_hcic_ble_periodic_adv_term_sync(sync_handle)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SyncTerm: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
cb_params.status = status;
@@ -922,7 +965,7 @@ tBTM_STATUS BTM_BlePeriodicAdvAddDevToList(tBLE_ADDR_TYPE addr_type, BD_ADDR add
if ((err = btsnd_hcic_ble_add_dev_to_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA AddDevToList: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
end:
@@ -946,7 +989,7 @@ tBTM_STATUS BTM_BlePeriodicAdvRemoveDevFromList(tBLE_ADDR_TYPE addr_type, BD_ADD
if ((err = btsnd_hcic_ble_rm_dev_from_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA RmDevFromList: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
end:
@@ -964,7 +1007,7 @@ tBTM_STATUS BTM_BlePeriodicAdvClearDev(void)
if ((err = btsnd_hcic_ble_clear_periodic_adv_list()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA ClrDev: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
cb_params.status = status;
@@ -972,7 +1015,9 @@ tBTM_STATUS BTM_BlePeriodicAdvClearDev(void)
return status;
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params)
{
UINT8 phy_mask = 0;
@@ -1016,7 +1061,7 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params)
if ((err = btsnd_hcic_ble_set_ext_scan_params(params->own_addr_type, params->filter_policy, phy_mask, phy_count,
hci_params)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE ES SetParams: cmd err=0x%x", err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
end:
@@ -1042,7 +1087,7 @@ tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period)
if ((err = btsnd_hcic_ble_ext_scan_enable(enable, extend_adv_cb.scan_duplicate, duration, period)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE ES En=%d: cmd err=0x%x", enable, err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
end:
@@ -1053,22 +1098,28 @@ end:
return status;
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
void BTM_BleSetPreferExtenedConnParams (BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params)
{
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bd_addr);
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (p_dev_rec) {
if (params) {
memcpy(&p_dev_rec->ext_conn_params, params, sizeof(tBTM_EXT_CONN_PARAMS));
} else {
- BTM_TRACE_ERROR("Invalid Extand connection parameters");
+ BTM_TRACE_ERROR("Invalid Extended connection parameters");
+ status = BTM_ILLEGAL_VALUE;
}
} else {
- BTM_TRACE_ERROR("Unknown Device, setting rejected");
+ BTM_TRACE_ERROR("Unknown Device, setting rejected");
+ status = BTM_UNKNOWN_ADDR;
}
- return;
+ cb_params.status = status;
+ BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT, &cb_params);
}
void btm_ble_extended_init(void)
@@ -1081,6 +1132,7 @@ void btm_ble_extended_cleanup(void)
}
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS *params)
{
if (!params) {
@@ -1157,6 +1209,7 @@ static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len,
return BTM_SUCCESS;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
void btm_ble_update_phy_evt(tBTM_BLE_UPDATE_PHY *params)
{
@@ -1184,11 +1237,14 @@ void btm_ble_update_phy_evt(tBTM_BLE_UPDATE_PHY *params)
return;
}
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
void btm_ble_scan_timeout_evt(void)
{
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT, NULL);
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
@@ -1199,7 +1255,7 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
}
// adv terminated due to connection, save the adv handle and connection handle
- if(params->completed_event == 0x00) {
+ if(params->status == 0x00) {
adv_record[params->adv_handle].ter_con_handle = params->conn_handle;
} else {
adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE;
@@ -1214,7 +1270,9 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
return;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
@@ -1232,7 +1290,9 @@ void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params)
return;
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
@@ -1249,7 +1309,7 @@ void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params)
return;
}
-
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
@@ -1267,6 +1327,7 @@ void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params)
return;
}
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
void btm_ble_periodic_adv_report_evt(tBTM_PERIOD_ADV_REPORT *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
@@ -1320,7 +1381,9 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par
return;
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
uint8_t btm_ble_ext_adv_active_count(void)
{
uint8_t count = 0;
@@ -1333,6 +1396,7 @@ uint8_t btm_ble_ext_adv_active_count(void)
return count;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
@@ -1378,7 +1442,7 @@ void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable)
if ((err = btsnd_hcic_ble_set_periodic_adv_recv_enable(sync_handle, enable)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
cb_params.status = status;
@@ -1437,7 +1501,7 @@ void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 sk
tHCI_STATUS err = HCI_SUCCESS;
if ((err = btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(mode, skip, sync_timeout, cte_type)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
- status = BTM_ILLEGAL_VALUE;
+ status = BTM_HCI_ERROR | err;
}
cb_params.set_past_params.status = status;
@@ -1476,3 +1540,192 @@ void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_REC
BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, &cb_params);
}
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void BTM_BleEnhReadTransPowerLevel(uint16_t conn_handle, uint8_t phy)
+{
+ btsnd_hcic_ble_enh_read_trans_power_level(conn_handle, phy);
+}
+
+void BTM_BleReadRemoteTransPwrLevel(uint16_t conn_handle, uint8_t phy)
+{
+ btsnd_hcic_ble_read_remote_trans_power_level(conn_handle, phy);
+}
+
+void BTM_BleSetPathLossRptParams(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis,
+ uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent)
+{
+ tBTM_STATUS status = BTM_SUCCESS;
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_path_loss_rpt_params(conn_handle, high_threshold, high_hysteresis, low_threshold, low_hysteresis, min_time_spent)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.path_loss_rpting_params.status = status;
+ cb_params.path_loss_rpting_params.conn_handle = conn_handle;
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_PARAMS_EVT, &cb_params);
+}
+
+void BTM_BleSetPathLossRptEnable(uint16_t conn_handle, uint8_t enable)
+{
+ tBTM_STATUS status = BTM_SUCCESS;
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_path_loss_rpt_enable(conn_handle, enable)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.path_loss_rpting_enable.status = status;
+ cb_params.path_loss_rpting_enable.conn_handle = conn_handle;
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_ENABLE_EVT, &cb_params);
+}
+
+void BTM_BleSetTransPwrRptEnable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable)
+{
+ tBTM_STATUS status = BTM_SUCCESS;
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_trans_pwr_rpt_enable(conn_handle, local_enable, remote_enable)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.trans_pwr_rpting_enable.status = status;
+ cb_params.trans_pwr_rpting_enable.conn_handle = conn_handle;
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_TRANS_POWER_REPORTING_ENABLE_EVT, &cb_params);
+}
+
+void btm_enh_read_trans_pwr_level_cmpl_evt(uint8_t *p)
+{
+ uint8_t hci_status;
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ STREAM_TO_UINT8(hci_status, p);
+ STREAM_TO_UINT16(cb_params.enh_trans_pwr_level_cmpl.conn_handle, p);
+ STREAM_TO_UINT8(cb_params.enh_trans_pwr_level_cmpl.phy, p);
+ STREAM_TO_UINT8(cb_params.enh_trans_pwr_level_cmpl.cur_tx_pwr_level, p);
+ STREAM_TO_UINT8(cb_params.enh_trans_pwr_level_cmpl.max_tx_pwr_level, p);
+
+ if(hci_status != HCI_SUCCESS) {
+ hci_status = BTM_HCI_ERROR | hci_status;
+ BTM_TRACE_ERROR("%s error status %d", __func__, hci_status);
+ }
+ cb_params.enh_trans_pwr_level_cmpl.status = hci_status;
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_ENH_READ_TRANS_POWER_LEVEL_EVT, &cb_params);
+}
+
+void btm_read_remote_trans_pwr_level_cmpl(UINT8 status)
+{
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ if (status != HCI_SUCCESS) {
+ status = (status | BTM_HCI_ERROR);
+ }
+
+ cb_params.remote_pwr_level_cmpl.status = status;
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_READ_REMOTE_TRANS_POWER_LEVEL_EVT, &cb_params);
+}
+
+void btm_ble_path_loss_threshold_evt(tBTM_BLE_PATH_LOSS_THRESHOLD_EVT *params)
+{
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ // If the user has register the callback function, should callback it to the application.
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PATH_LOSS_THRESHOLD_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params);
+}
+
+void btm_ble_transmit_power_report_evt(tBTM_BLE_TRANS_POWER_REPORT_EVT *params)
+{
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ if (params->status != HCI_SUCCESS) {
+ params->status = (params->status | BTM_HCI_ERROR);
+ }
+
+ // If the user has register the callback function, should callback it to the application.
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_TRANMIT_POWER_REPORTING_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params);
+}
+
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void BTM_BleSetDefaultSubrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, UINT16 continuation_number, UINT16 supervision_timeout)
+{
+ tBTM_STATUS status = BTM_SUCCESS;
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_default_subrate(subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.status = status;
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_DEFAULT_SUBRATE_EVT, &cb_params);
+}
+
+void BTM_BleSubrateRequest(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, UINT16 continuation_number, UINT16 supervision_timeout)
+{
+ btsnd_hcic_ble_subrate_request(conn_handle, subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout);
+}
+
+void btm_subrate_req_cmd_status(UINT8 status)
+{
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ if (status != HCI_SUCCESS) {
+ status = (status | BTM_HCI_ERROR);
+ }
+ cb_params.status = status;
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SUBRATE_REQUEST_EVT, &cb_params);
+}
+
+void btm_ble_subrate_change_evt(tBTM_BLE_SUBRATE_CHANGE_EVT *params)
+{
+ if (params->status != HCI_SUCCESS) {
+ params->status = (params->status | BTM_HCI_ERROR);
+ }
+
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SUBRATE_CHANGE_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params);
+}
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+tBTM_STATUS BTM_BleSetHostFeature(uint16_t bit_num, uint8_t bit_val)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
+
+ BTM_TRACE_DEBUG("BTM_BleSetHostFeature bit_num %d bit_value %d\n", bit_num, bit_val);
+
+ if ((err = btsnd_hcic_ble_set_host_feature(bit_num, bit_val)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("set host feature, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.status = status;
+ BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_HOST_FEATURE_EVT, &cb_params);
+
+ return status;
+}
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c
index d7ed2095..60548a76 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_addr.c
@@ -384,6 +384,10 @@ static BOOLEAN btm_ble_match_random_bda(tBTM_SEC_DEV_REC *p_dev_rec)
void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK *p_cback, void *p)
{
#if (SMP_INCLUDED == TRUE)
+ if (btm_cb.addr_res_en == FALSE) {
+ return;
+ }
+
tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
list_node_t *p_node = NULL;
tBTM_SEC_DEV_REC *p_dev_rec = NULL;
@@ -458,6 +462,10 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_identity_addr(BD_ADDR bd_addr, UINT8 addr_type
BOOLEAN btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type, BOOLEAN refresh)
{
#if BLE_PRIVACY_SPT == TRUE
+ if (btm_cb.addr_res_en == FALSE) {
+ return TRUE;
+ }
+
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_identity_addr(bd_addr, *p_addr_type);
BTM_TRACE_EVENT ("%s", __func__);
@@ -491,6 +499,10 @@ BOOLEAN btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type,
BOOLEAN btm_random_pseudo_to_identity_addr(BD_ADDR random_pseudo, UINT8 *p_static_addr_type)
{
#if BLE_PRIVACY_SPT == TRUE
+ if (btm_cb.addr_res_en == FALSE) {
+ return TRUE;
+ }
+
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (random_pseudo);
if (p_dev_rec != NULL) {
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c
index c0ae0aaa..9da09143 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c
@@ -22,6 +22,7 @@
#include "common/bt_target.h"
#if (BLE_INCLUDED == TRUE)
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
#include "stack/bt_types.h"
#include "stack/hcimsgs.h"
#include "stack/btu.h"
@@ -445,11 +446,11 @@ BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filte
**
** Function btm_ble_update_pf_local_name
**
-** Description this function update(add,delete or clear) the adv lcoal name filtering condition.
+** Description this function update(add,delete or clear) the adv local name filtering condition.
**
**
-** Returns BTM_SUCCESS if sucessful,
-** BTM_ILLEGAL_VALUE if paramter is not valid.
+** Returns BTM_SUCCESS if successful,
+** BTM_ILLEGAL_VALUE if parameter is not valid.
**
*******************************************************************************/
tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action,
@@ -506,8 +507,8 @@ tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action,
** Description this function update(add/remove) service data change filter.
**
**
-** Returns BTM_SUCCESS if sucessful,
-** BTM_ILLEGAL_VALUE if paramter is not valid.
+** Returns BTM_SUCCESS if successful,
+** BTM_ILLEGAL_VALUE if parameter is not valid.
**
*******************************************************************************/
tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action,
@@ -534,8 +535,8 @@ tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action,
** data filtering condition.
**
**
-** Returns BTM_SUCCESS if sucessful,
-** BTM_ILLEGAL_VALUE if paramter is not valid.
+** Returns BTM_SUCCESS if successful,
+** BTM_ILLEGAL_VALUE if parameter is not valid.
**
*******************************************************************************/
tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action,
@@ -708,8 +709,8 @@ UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
** Description this function update(add,delete or clear) the address filter of adv.
**
**
-** Returns BTM_SUCCESS if sucessful,
-** BTM_ILLEGAL_VALUE if paramter is not valid.
+** Returns BTM_SUCCESS if successful,
+** BTM_ILLEGAL_VALUE if parameter is not valid.
**
*******************************************************************************/
tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action,
@@ -757,8 +758,8 @@ tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action,
** Description this function update(add,delete or clear) service UUID filter.
**
**
-** Returns BTM_SUCCESS if sucessful,
-** BTM_ILLEGAL_VALUE if paramter is not valid.
+** Returns BTM_SUCCESS if successful,
+** BTM_ILLEGAL_VALUE if parameter is not valid.
**
*******************************************************************************/
tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
@@ -872,7 +873,7 @@ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
}
} else {
- BTM_TRACE_ERROR("UUID filter udpating failed");
+ BTM_TRACE_ERROR("UUID filter updating failed");
}
return st;
@@ -886,8 +887,8 @@ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
** Description clear all adv payload filter by de-select all the adv pf feature bits
**
**
-** Returns BTM_SUCCESS if sucessful,
-** BTM_ILLEGAL_VALUE if paramter is not valid.
+** Returns BTM_SUCCESS if successful,
+** BTM_ILLEGAL_VALUE if parameter is not valid.
**
*******************************************************************************/
tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action,
@@ -1303,4 +1304,5 @@ void btm_ble_adv_filter_cleanup(void)
#endif
}
+#endif // #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
#endif
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c
index 5b0fcd8f..b4b58643 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c
@@ -29,15 +29,22 @@
#include "stack/hcimsgs.h"
#if (BLE_INCLUDED == TRUE)
+#if (BLE_HOST_BATCH_SCAN_EN == TRUE)
#if BTM_DYNAMIC_MEMORY == FALSE
tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb;
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
#else
tBTM_BLE_BATCH_SCAN_CB *ble_batchscan_cb_ptr;
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
tBTM_BLE_ADV_TRACK_CB *ble_advtrack_cb_ptr;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
#define ble_batchscan_cb (*ble_batchscan_cb_ptr)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
#define ble_advtrack_cb (*ble_advtrack_cb_ptr)
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
#endif
/* length of each batch scan command */
@@ -66,10 +73,11 @@ void btm_ble_batchscan_cleanup(void);
*******************************************************************************/
void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p)
{
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
tBTM_BLE_TRACK_ADV_DATA adv_data;
-
- UINT8 sub_event = 0;
tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+ UINT8 sub_event = 0;
STREAM_TO_UINT8(sub_event, p);
BTM_TRACE_EVENT("btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x", sub_event);
@@ -78,7 +86,7 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p)
ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value);
return;
}
-
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event && NULL != ble_advtrack_cb.p_track_cback) {
if (len < 10) {
return;
@@ -125,6 +133,7 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p)
ble_advtrack_cb.p_track_cback(&adv_data);
return;
}
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
}
/*******************************************************************************
@@ -598,6 +607,7 @@ tBTM_STATUS btm_ble_enable_disable_batchscan(BOOLEAN should_enable)
return status;
}
+#if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleSetStorageConfig
@@ -676,7 +686,7 @@ tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_
return status;
}
-
+#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE)
/*******************************************************************************
**
@@ -796,6 +806,7 @@ tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value)
return status;
}
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleReadScanReports
@@ -854,8 +865,9 @@ tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
}
return status;
}
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
-
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleTrackAdvertiser
@@ -888,6 +900,7 @@ tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback,
ble_advtrack_cb.ref_value = ref_value;
return BTM_CMD_STARTED;
}
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
@@ -904,7 +917,9 @@ void btm_ble_batchscan_init(void)
{
#if BTM_DYNAMIC_MEMORY == TRUE
ble_batchscan_cb_ptr = (tBTM_BLE_BATCH_SCAN_CB *)osi_malloc(sizeof(tBTM_BLE_BATCH_SCAN_CB));
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
ble_advtrack_cb_ptr = (tBTM_BLE_ADV_TRACK_CB *)osi_malloc(sizeof(tBTM_BLE_ADV_TRACK_CB));
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
if (ble_batchscan_cb_ptr == NULL || ble_advtrack_cb_ptr == NULL) {
BTM_TRACE_ERROR("%s malloc failed", __func__);
return;
@@ -912,7 +927,9 @@ void btm_ble_batchscan_init(void)
#endif
BTM_TRACE_EVENT (" btm_ble_batchscan_init");
memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB));
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB));
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, TRUE);
}
@@ -940,14 +957,21 @@ void btm_ble_batchscan_cleanup(void)
}
memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB));
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB));
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
#if BTM_DYNAMIC_MEMORY == TRUE
osi_free(ble_batchscan_cb_ptr);
- osi_free(ble_advtrack_cb_ptr);
ble_batchscan_cb_ptr = NULL;
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+ osi_free(ble_advtrack_cb_ptr);
ble_advtrack_cb_ptr = NULL;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
+
#endif
}
+#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE)
+
#endif
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c
index 4cb282b7..bf9b1adb 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c
@@ -201,7 +201,12 @@ BOOLEAN btm_add_dev_to_controller (BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_TY
/* Controller do not support resolvable address now, only support public address and static random address */
BOOLEAN started = FALSE;
- if(wl_addr_type > BLE_ADDR_RANDOM) {
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ if (wl_addr_type > BLE_ADDR_RANDOM && wl_addr_type != BLE_ADDR_ANONYMOUS)
+#else
+ if (wl_addr_type > BLE_ADDR_RANDOM)
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+ {
BTM_TRACE_ERROR("wl_addr_type is error\n");
return started;
}
@@ -278,7 +283,12 @@ void btm_enq_wl_dev_operation(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_TYPE ad
*******************************************************************************/
BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb)
{
- if(addr_type > BLE_ADDR_RANDOM) {
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ if (addr_type > BLE_ADDR_RANDOM && addr_type != BLE_ADDR_ANONYMOUS)
+#else
+ if (addr_type > BLE_ADDR_RANDOM)
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+ {
BTM_TRACE_ERROR("%s address type is error, unable to add device", __func__);
if (update_wl_cb){
update_wl_cb(HCI_ERR_ILLEGAL_PARAMETER_FMT,to_add);
@@ -423,6 +433,23 @@ void btm_ble_white_list_init(UINT8 white_list_size)
btm_cb.ble_ctr_cb.white_list_avail_size = white_list_size;
}
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+/*******************************************************************************
+**
+** Function btm_ble_periodic_adv_list_init
+**
+** Description Initialize the periodic advertiser list size.
+**
+** Parameters periodic_adv_size: The size of the periodic advertiser list to be initialized.
+**
+*******************************************************************************/
+void btm_ble_periodic_adv_list_init(UINT8 periodic_adv_size)
+{
+ BTM_TRACE_DEBUG("%s white_list_size = %d", __func__, periodic_adv_size);
+ btm_cb.ble_ctr_cb.periodic_adv_list_size = periodic_adv_size;
+}
+#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+
/*******************************************************************************
**
** Function btm_ble_add_2_white_list_complete
@@ -648,6 +675,7 @@ void btm_ble_initiate_select_conn(BD_ADDR bda)
BTM_TRACE_ERROR("btm_ble_initiate_select_conn failed");
}
}
+#if (tGATT_BG_CONN_DEV == TRUE)
/*******************************************************************************
**
** Function btm_ble_suspend_bg_conn
@@ -672,6 +700,8 @@ BOOLEAN btm_ble_suspend_bg_conn(void)
return FALSE;
}
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
+
/*******************************************************************************
**
** Function btm_suspend_wl_activity
@@ -689,10 +719,11 @@ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state)
if (wl_state & BTM_BLE_WL_SCAN) {
btm_ble_start_select_conn(FALSE, NULL);
}
+#if (BLE_42_ADV_EN == TRUE)
if (wl_state & BTM_BLE_WL_ADV) {
btm_ble_stop_adv();
}
-
+#endif // #if (BLE_42_ADV_EN == TRUE)
}
/*******************************************************************************
**
@@ -705,9 +736,13 @@ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state)
*******************************************************************************/
void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state)
{
+#if (tGATT_BG_CONN_DEV == TRUE)
btm_ble_resume_bg_conn();
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
if (wl_state & BTM_BLE_WL_ADV) {
+#if (BLE_42_ADV_EN == TRUE)
btm_ble_start_adv();
+#endif // #if (BLE_42_ADV_EN == TRUE)
}
}
@@ -724,12 +759,13 @@ void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state)
static void btm_wl_update_to_controller(void)
{
/* whitelist will be added in the btm_ble_resume_bg_conn(), we do not
- support background connection now, so we nedd to use btm_execute_wl_dev_operation
+ support background connection now, so we need to use btm_execute_wl_dev_operation
to add whitelist directly ,if we support background connection in the future,
please delete btm_execute_wl_dev_operation(). */
btm_execute_wl_dev_operation();
}
+#if (tGATT_BG_CONN_DEV == TRUE)
/*******************************************************************************
**
** Function btm_ble_resume_bg_conn
@@ -759,6 +795,8 @@ BOOLEAN btm_ble_resume_bg_conn(void)
return ret;
}
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
+
/*******************************************************************************
**
** Function btm_ble_get_conn_st
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c
index dd23d3e9..4b68fe80 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c
@@ -20,6 +20,7 @@
#include "common/bt_target.h"
#if (BLE_INCLUDED == TRUE)
+#if (BLE_HOST_ENERGY_INFO_EN == TRUE)
#include "stack/bt_types.h"
#include "stack/hcimsgs.h"
#include "stack/btu.h"
@@ -104,5 +105,6 @@ tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback)
return status;
}
+#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE)
#endif
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_cte.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_cte.c
new file mode 100644
index 00000000..a79932de
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_cte.c
@@ -0,0 +1,237 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "btm_int.h"
+#include "stack/hcimsgs.h"
+#include "osi/allocator.h"
+#include "device/controller.h"
+#include <string.h>
+#include "l2c_int.h"
+
+tBTM_BLE_CTE_CBACK ble_cte_cb;
+
+extern void btm_ble_inter_set(bool extble_inter);
+
+void BTM_BleCteRegisterCallback(tBTM_BLE_CTE_CBACK cb)
+{
+ if (cb) {
+ ble_cte_cb = cb;
+ } else {
+ BTM_TRACE_ERROR("%s, register fail, the cb function is NULL.", __func__);
+ }
+}
+
+void BTM_CteBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_CTE_CB_PARAMS *params)
+{
+ BTM_TRACE_DEBUG("%s event %x", __func__, event);
+
+ if(params && params->status == BTM_SUCCESS) {
+ btm_ble_inter_set(true);
+ }
+ if (ble_cte_cb) {
+ ble_cte_cb(event, params);
+ }
+}
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids)
+{
+
+
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_connless_cte_trans_params(adv_handle, cte_len, cte_type, cte_count, switching_pattern_len, antenna_ids)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte set trans params, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.cte_trans_params_cmpl.status = status;
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_TRANS_PARAMS_EVT, &cb_params);
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_connless_cte_enable(adv_handle, cte_en)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte set trans enable, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.cte_trans_en_cmpl.status = status;
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_TRANS_ENABLE_EVT, &cb_params);
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_connless_iq_sampling_enable(sync_handle, sampling_en, slot_dur, max_sampled_ctes, switching_pattern_len, ant_ids)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte set trans enable, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.cte_iq_samp_en_cmpl.status = status;
+ cb_params.cte_iq_samp_en_cmpl.sync_handle = sync_handle;
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT, &cb_params);
+
+ return status;
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+tBTM_STATUS BTM_BleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t switching_pattern_len, uint8_t *ant_ids)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_conn_cte_receive_params(conn_handle, sampling_en, slot_dur, switching_pattern_len, ant_ids)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte set conn recv params, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.cte_recv_params_cmpl.status = status;
+ cb_params.cte_recv_params_cmpl.conn_handle = conn_handle;
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT, &cb_params);
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_set_conn_cte_trans_params(conn_handle, cte_types, switching_pattern_len, ant_ids)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte set conn trans params, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.cte_conn_trans_params_cmpl.status = status;
+ cb_params.cte_conn_trans_params_cmpl.conn_handle = conn_handle;
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT, &cb_params);
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_int,
+ uint8_t req_cte_len, uint8_t req_cte_type)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_conn_cte_req_enable(conn_handle, enable, cte_req_int, req_cte_len, req_cte_type)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte set conn req en, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.cte_conn_req_en_cmpl.status = status;
+ cb_params.cte_conn_req_en_cmpl.conn_handle = conn_handle;
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT, &cb_params);
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_conn_cte_rsp_enable(conn_handle, enable)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte set conn rsp en, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.cte_conn_rsp_en_cmpl.status = status;
+ cb_params.cte_conn_rsp_en_cmpl.conn_handle = conn_handle;
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT, &cb_params);
+
+ return status;
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+tBTM_STATUS BTM_BleCteReadAntInfor(void)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+
+ if ((err = btsnd_hcic_ble_read_antenna_info()) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("cte read ant information, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ return status;
+}
+
+void btm_ble_cte_read_ant_infor_complete(UINT8 *p)
+{
+ tBTM_BLE_CTE_CB_PARAMS cb_params = {0};
+
+ STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.status, p);
+ STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.supported_switching_sampling_rates, p);
+ STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.num_ant, p);
+ STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.max_switching_pattern_len, p);
+ STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.max_cte_len, p);
+
+ if (cb_params.cte_read_ant_infor_cmpl.status != HCI_SUCCESS) {
+ cb_params.cte_read_ant_infor_cmpl.status = (BTM_HCI_ERROR | cb_params.cte_read_ant_infor_cmpl.status);
+ }
+
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_READ_ANT_INFOR_EVT, &cb_params);
+}
+
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+void btm_ble_connless_iq_report_evt(tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT *params)
+{
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+void btm_ble_conn_iq_report_evt(tBTM_BLE_CTE_CONN_IQ_REPORT_EVT *params)
+{
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_CONN_IQ_REPORT_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params);
+}
+
+void btm_ble_cte_req_failed_evt(tBTM_BLE_CTE_REQ_FAILED_EVT *params)
+{
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ if (params->status != HCI_SUCCESS) {
+ params->status = (params->status | BTM_HCI_ERROR);
+ }
+
+ BTM_CteBleCallbackTrigger(BTM_BLE_CTE_REQUEST_FAILED_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c
index df24fa08..f3886643 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_gap.c
@@ -71,20 +71,28 @@ static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL;
#endif
tBTM_CallbackFunc conn_callback_func;
+// BLE vendor HCI event callback
+#if (BLE_VENDOR_HCI_EN == TRUE)
+static tBTM_BLE_VENDOR_HCI_EVT_CBACK *ble_vs_evt_callback = NULL;
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
/*******************************************************************************
** Local functions
*******************************************************************************/
static void btm_ble_update_adv_flag(UINT8 flag);
static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p);
+
UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
tBTM_BLE_ADV_DATA *p_data);
+
static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
BD_ADDR_PTR p_peer_addr_ptr,
tBLE_ADDR_TYPE *p_peer_addr_type,
tBLE_ADDR_TYPE *p_own_addr_type);
static void btm_ble_stop_observe(void);
static void btm_ble_stop_discover(void);
+#if (BLE_42_SCAN_EN == TRUE)
static void btm_adv_pkt_handler(void *arg);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
#define BTM_BLE_INQ_RESULT 0x01
@@ -246,56 +254,77 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = {
/* check LE combo state supported */
#define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y))
+#if (BLE_42_ADV_EN == TRUE)
static osi_mutex_t adv_enable_lock;
static osi_mutex_t adv_data_lock;
static osi_mutex_t adv_param_lock;
-static osi_mutex_t scan_enable_lock;
-static osi_mutex_t scan_param_lock;
osi_sem_t adv_enable_sem;
osi_sem_t adv_data_sem;
osi_sem_t adv_param_sem;
-osi_sem_t scan_enable_sem;
-osi_sem_t scan_param_sem;
uint8_t adv_enable_status = 0;
uint8_t adv_data_status = 0;
uint8_t adv_param_status = 0;
+#endif // #if (BLE_42_ADV_EN == TRUE)
+
+#if (BLE_42_SCAN_EN == TRUE)
+static osi_mutex_t scan_enable_lock;
+static osi_mutex_t scan_param_lock;
+osi_sem_t scan_enable_sem;
+osi_sem_t scan_param_sem;
uint8_t scan_enable_status = 0;
uint8_t scan_param_status = 0;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
void btm_ble_lock_init(void)
{
+#if (BLE_42_ADV_EN == TRUE)
osi_mutex_new(&adv_enable_lock);
osi_mutex_new(&adv_data_lock);
osi_mutex_new(&adv_param_lock);
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
osi_mutex_new(&scan_enable_lock);
osi_mutex_new(&scan_param_lock);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
void btm_ble_lock_free(void)
{
+#if (BLE_42_ADV_EN == TRUE)
osi_mutex_free(&adv_enable_lock);
osi_mutex_free(&adv_data_lock);
osi_mutex_free(&adv_param_lock);
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
osi_mutex_free(&scan_enable_lock);
osi_mutex_free(&scan_param_lock);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
void btm_ble_sem_init(void)
{
+#if (BLE_42_ADV_EN == TRUE)
osi_sem_new(&adv_enable_sem, 1, 0);
osi_sem_new(&adv_data_sem, 1, 0);
osi_sem_new(&adv_param_sem, 1, 0);
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
osi_sem_new(&scan_enable_sem, 1, 0);
osi_sem_new(&scan_param_sem, 1, 0);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
void btm_ble_sem_free(void)
{
+#if (BLE_42_ADV_EN == TRUE)
osi_sem_free(&adv_enable_sem);
osi_sem_free(&adv_data_sem);
osi_sem_free(&adv_param_sem);
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
osi_sem_free(&scan_enable_sem);
osi_sem_free(&scan_param_sem);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
/*******************************************************************************
@@ -326,6 +355,13 @@ void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk
conn_callback_func.set_pkt_data_length_cb = ptk_len_chane_cb;
}
+#if (BLE_VENDOR_HCI_EN == TRUE)
+void BTM_BleRegisterVendorHciEventCallback(tBTM_BLE_VENDOR_HCI_EVT_CBACK *vendor_hci_evt_cb)
+{
+ ble_vs_evt_callback = vendor_hci_evt_cb;
+}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+
/*******************************************************************************
**
** Function BTM_BleUpdateAdvWhitelist
@@ -380,14 +416,22 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy)
if (p_cb->afp != adv_policy) {
p_cb->afp = adv_policy;
+#if (BLE_42_ADV_EN == TRUE)
/* if adv active, stop and restart */
btm_ble_stop_adv ();
+#endif // #if (BLE_42_ADV_EN == TRUE)
if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE) {
p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type,
&p_cb->adv_addr_type);
}
+ uint8_t null_addr[BD_ADDR_LEN] = {0};
+ if ((p_cb->evt_type == 0x01 || p_cb->evt_type == 0x04) && memcmp(p_addr_ptr, null_addr, BD_ADDR_LEN) == 0) {
+ /* directed advertising */
+ return;
+ }
+
btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min :
BTM_BLE_GAP_ADV_SLOW_INT),
(UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max :
@@ -400,7 +444,9 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy)
p_cb->afp);
if (adv_mode == BTM_BLE_ADV_ENABLE) {
+#if (BLE_42_ADV_EN == TRUE)
btm_ble_start_adv ();
+#endif // #if (BLE_42_ADV_EN == TRUE)
}
}
@@ -506,8 +552,9 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration,
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
BTM_BLE_DEFAULT_SFP);
}
-
+#if (BLE_42_SCAN_EN == TRUE)
status = btm_ble_start_scan();
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
if (status == BTM_CMD_STARTED) {
@@ -529,6 +576,7 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration,
}
+#if (BLE_42_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleScan
@@ -606,7 +654,9 @@ tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
return status;
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleBroadcast
@@ -665,7 +715,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s
}
return status;
}
-
+#endif // #if (BLE_42_ADV_EN == TRUE)
#if BLE_VND_INCLUDED == TRUE
/*******************************************************************************
**
@@ -717,11 +767,11 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_
__func__, status, btm_cb.cmn_ble_vsc_cb.max_irk_list_sz,
btm_cb.cmn_ble_vsc_cb.adv_inst_max, btm_cb.cmn_ble_vsc_cb.rpa_offloading,
btm_cb.cmn_ble_vsc_cb.energy_support, btm_cb.cmn_ble_vsc_cb.extended_scan_support);
-
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
if (BTM_BleMaxMultiAdvInstanceCount() > 0) {
btm_ble_multi_adv_init();
}
-
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
if (btm_cb.cmn_ble_vsc_cb.max_filter > 0) {
btm_ble_adv_filter_init();
}
@@ -899,9 +949,11 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK
btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low);
#endif
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
if (BTM_BleMaxMultiAdvInstanceCount() > 0) {
btm_ble_multi_adv_enb_privacy(privacy_mode);
}
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/* 4.2 controller only allow privacy 1.2 or mixed mode, resolvable private address in controller */
if (controller_get_interface()->supports_ble_privacy()) {
@@ -1139,6 +1191,7 @@ void BTM_BleConfigConnParams(uint16_t int_min, uint16_t int_max, uint16_t latenc
#endif
}
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleMaxMultiAdvInstanceCount
@@ -1153,6 +1206,7 @@ extern UINT8 BTM_BleMaxMultiAdvInstanceCount(void)
return btm_cb.cmn_ble_vsc_cb.adv_inst_max < BTM_BLE_MULTI_ADV_MAX ?
btm_cb.cmn_ble_vsc_cb.adv_inst_max : BTM_BLE_MULTI_ADV_MAX;
}
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
#if BLE_PRIVACY_SPT == TRUE
/*******************************************************************************
@@ -1291,7 +1345,9 @@ void BTM_BleClearBgConnDev(void)
{
btm_ble_start_auto_conn(FALSE);
btm_ble_clear_white_list(NULL);
+#if (tGATT_BG_CONN_DEV == TRUE)
gatt_reset_bgdev_list();
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
}
/*******************************************************************************
@@ -1314,7 +1370,7 @@ BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR remote_bda)
BTM_TRACE_EVENT("%s() add=%d", __func__, add_remove);
return btm_update_dev_to_white_list(add_remove, remote_bda, 0, NULL);
}
-
+#if 0
/*******************************************************************************
**
** Function BTM_BleSetConnectableMode
@@ -1342,7 +1398,7 @@ tBTM_STATUS BTM_BleSetConnectableMode(tBTM_BLE_CONN_MODE connectable_mode)
p_cb->directed_conn = connectable_mode;
return btm_ble_set_connectability( p_cb->connectable_mode);
}
-
+#endif
/*******************************************************************************
**
** Function btm_set_conn_mode_adv_init_addr
@@ -1435,76 +1491,7 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
return evt_type;
}
-/*******************************************************************************
-**
-** Function BTM_BleSetAdvParams
-**
-** Description This function is called to set advertising parameters.
-**
-** Parameters adv_int_min: minimum advertising interval
-** adv_int_max: maximum advertising interval
-** p_dir_bda: connectable direct initiator's LE device address
-** chnl_map: advertising channel map.
-**
-** Returns void
-**
-*******************************************************************************/
-tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max,
- tBLE_BD_ADDR *p_dir_bda,
- tBTM_BLE_ADV_CHNL_MAP chnl_map)
-{
- tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
- tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
- tBTM_STATUS status = BTM_SUCCESS;
- BD_ADDR p_addr_ptr = {0};
- tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC;
- tBLE_ADDR_TYPE own_addr_type = p_addr_cb->own_addr_type;
- UINT8 adv_mode = p_cb->adv_mode;
-
- BTM_TRACE_EVENT ("BTM_BleSetAdvParams");
-
- if (!controller_get_interface()->supports_ble()) {
- return BTM_ILLEGAL_VALUE;
- }
-
- if (!BTM_BLE_ISVALID_PARAM(adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) ||
- !BTM_BLE_ISVALID_PARAM(adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX)) {
- return BTM_ILLEGAL_VALUE;
- }
-
- p_cb->adv_interval_min = adv_int_min;
- p_cb->adv_interval_max = adv_int_max;
- p_cb->adv_chnl_map = chnl_map;
-
- if (p_dir_bda) {
- memcpy(&p_cb->direct_bda, p_dir_bda, sizeof(tBLE_BD_ADDR));
- }
-
- BTM_TRACE_EVENT ("update params for an active adv\n");
-
- btm_ble_stop_adv();
-
- p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type,
- &own_addr_type);
-
- /* update adv params */
- btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min,
- p_cb->adv_interval_max,
- p_cb->evt_type,
- own_addr_type,
- init_addr_type,
- p_addr_ptr,
- p_cb->adv_chnl_map,
- p_cb->afp);
-
- if (adv_mode == BTM_BLE_ADV_ENABLE) {
- btm_ble_start_adv();
- }
-
- return status;
-}
-
-
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleSetAdvParamsAll
@@ -1599,6 +1586,7 @@ tBTM_STATUS BTM_BleStartAdv(void)
return status;
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleReadAdvParams
@@ -1632,6 +1620,7 @@ void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max,
}
}
+#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
/*******************************************************************************
**
** Function BTM_BleSetScanParams
@@ -1690,7 +1679,9 @@ void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_
}
}
+#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window,
tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBTM_BLE_SFP scan_filter_policy,
tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback)
@@ -1746,8 +1737,9 @@ tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval,
osi_mutex_unlock(&scan_param_lock);
return ret;
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
-
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleWriteScanRsp
@@ -1822,6 +1814,7 @@ tBTM_STATUS BTM_BleWriteScanRspRaw(UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_le
return ret;
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
@@ -1888,6 +1881,7 @@ tBTM_STATUS BTM_UpdateBleDuplicateExceptionalList(uint8_t subcode, uint32_t type
return status;
}
+#if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleWriteAdvData
@@ -1940,38 +1934,6 @@ tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p
/*******************************************************************************
**
-** Function BTM_BleWriteLongAdvData
-**
-** Description This function is called to write long advertising data.
-**
-** Parameters: adv_data: long advertising data
-** adv_data_len: the length of long advertising data
-**
-** Returns void
-**
-*******************************************************************************/
-tBTM_STATUS BTM_BleWriteLongAdvData(uint8_t *adv_data, uint8_t adv_data_len)
-{
- tBTM_STATUS status = BTM_NO_RESOURCES;
- if (!controller_get_interface()->supports_ble()) {
- return BTM_ILLEGAL_VALUE;
- }
- if(!adv_data || adv_data_len <= 0 || adv_data_len > BTM_BLE_LONG_ADV_MAX_LEN) {
- return BTM_ILLEGAL_VALUE;
- }
- uint8_t long_adv[BTM_BLE_LONG_ADV_MAX_LEN + 1] = {0};
- long_adv[0] = adv_data_len;
- memcpy(&long_adv[1], adv_data, adv_data_len);
- status = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_LONG_ADV_DATA, BTM_BLE_LONG_ADV_MAX_LEN + 1, long_adv, NULL);
- if(status == BTM_CMD_STARTED) {
- status = BTM_SUCCESS;
- }
-
- return status;
-}
-
-/*******************************************************************************
-**
** Function BTM_BleWriteAdvDataRaw
**
** Description This function is called to write raw advertising data.
@@ -1995,7 +1957,7 @@ tBTM_STATUS BTM_BleWriteAdvDataRaw(UINT8 *p_raw_adv, UINT32 raw_adv_len)
return ret;
}
-
+#endif // #if (BLE_42_ADV_EN == TRUE)
/*******************************************************************************
**
@@ -2082,6 +2044,7 @@ BOOLEAN BTM_BleGetCurrentAddress(BD_ADDR addr, uint8_t *addr_type)
return TRUE;
}
+#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
/*******************************************************************************
**
** Function BTM_CheckAdvData
@@ -2095,7 +2058,7 @@ BOOLEAN BTM_BleGetCurrentAddress(BD_ADDR addr, uint8_t *addr_type)
** Returns pointer of ADV data
**
*******************************************************************************/
-UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
+UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT16 adv_data_len, UINT8 type, UINT8 *p_length)
{
UINT8 *p = p_adv;
UINT8 length;
@@ -2104,7 +2067,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
STREAM_TO_UINT8(length, p);
- while ( length && (p - p_adv < BTM_BLE_CACHE_ADV_DATA_MAX)) {
+ while ( length && (p - p_adv < adv_data_len)) {
STREAM_TO_UINT8(adv_type, p);
if ( adv_type == type ) {
@@ -2117,7 +2080,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
/* Break loop if advertising data is in an incorrect format,
as it may lead to memory overflow */
- if (p >= p_adv + BTM_BLE_CACHE_ADV_DATA_MAX) {
+ if (p >= p_adv + adv_data_len) {
break;
}
@@ -2127,7 +2090,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
*p_length = 0;
return NULL;
}
-
+#endif // #if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
/*******************************************************************************
**
** Function BTM__BLEReadDiscoverability
@@ -2165,16 +2128,20 @@ UINT16 BTM_BleReadConnectability(void)
void BTM_Recovery_Pre_State(void)
{
+#if ((BLE_42_ADV_EN == TRUE) || (BLE_42_SCAN_EN == TRUE))
tBTM_BLE_INQ_CB *ble_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
-
+#endif // #if ((BLE_42_ADV_EN == TRUE) || (BLE_42_SCAN_EN == TRUE))
+#if (BLE_42_ADV_EN == TRUE)
if (ble_inq_cb->state & BTM_BLE_ADVERTISING) {
btm_ble_stop_adv();
btm_ble_start_adv();
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
if (ble_inq_cb->state & BTM_BLE_SCANNING) {
btm_ble_start_scan();
}
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
return;
}
@@ -2205,6 +2172,26 @@ BOOLEAN BTM_GetCurrentConnParams(BD_ADDR bda, uint16_t *interval, uint16_t *late
/*******************************************************************************
**
+** Function btm_ble_map_adv_tx_power
+**
+** Description return the actual power in dBm based on the mapping in config file
+**
+** Parameters advertise parameters used for this instance.
+**
+** Returns tx power in dBm
+**
+*******************************************************************************/
+static const int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER;
+char btm_ble_map_adv_tx_power(int tx_power_index)
+{
+ if (0 <= tx_power_index && tx_power_index <= BTM_BLE_ADV_TX_POWER_MAX) {
+ return (char)btm_ble_tx_power[tx_power_index];
+ }
+ return 0;
+}
+
+/*******************************************************************************
+**
** Function btm_ble_build_adv_data
**
** Description This function is called build the adv data and rsp data.
@@ -2564,6 +2551,7 @@ void btm_ble_set_adv_flag(UINT16 connect_mode, UINT16 disc_mode)
btm_ble_update_adv_flag(flag);
}
}
+#if 0
/*******************************************************************************
**
** Function btm_ble_set_discoverability
@@ -2615,7 +2603,9 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
if (evt_type != p_cb->evt_type || p_cb->adv_addr_type != own_addr_type
|| !p_cb->fast_adv_on) {
+#if (BLE_42_ADV_EN == TRUE)
btm_ble_stop_adv();
+#endif // #if (BLE_42_ADV_EN == TRUE)
/* update adv params */
if (!btsnd_hcic_ble_write_adv_params (adv_int_min,
@@ -2635,11 +2625,13 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
}
if (status == BTM_SUCCESS && p_cb->adv_mode != new_mode) {
+#if (BLE_42_ADV_EN == TRUE)
if (new_mode == BTM_BLE_ADV_ENABLE) {
status = btm_ble_start_adv();
} else {
status = btm_ble_stop_adv();
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
}
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
@@ -2662,7 +2654,7 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
}
return status;
}
-
+#endif
/*******************************************************************************
**
** Function btm_ble_set_connectability
@@ -2710,7 +2702,9 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
btm_ble_set_adv_flag (combined_mode, btm_cb.btm_inq_vars.discoverable_mode);
if (p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type
|| !p_cb->fast_adv_on) {
+#if (BLE_42_ADV_EN == TRUE)
btm_ble_stop_adv();
+#endif // #if (BLE_42_ADV_EN == TRUE)
if (!btsnd_hcic_ble_write_adv_params (adv_int_min,
adv_int_max,
@@ -2730,11 +2724,13 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
/* update advertising mode */
if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode) {
+#if (BLE_42_ADV_EN == TRUE)
if (new_mode == BTM_BLE_ADV_ENABLE) {
status = btm_ble_start_adv();
} else {
status = btm_ble_stop_adv();
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
}
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
@@ -2795,7 +2791,9 @@ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration)
/* enable IRK list */
//btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN);
#endif
+#if (BLE_42_SCAN_EN == TRUE)
status = btm_ble_start_scan();
+#endif // #if (BLE_42_SCAN_EN == TRUE)
} else if ((p_ble_cb->inq_var.scan_interval != BTM_BLE_LOW_LATENCY_SCAN_INT) ||
(p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) {
BTM_TRACE_DEBUG("%s, restart LE scan with low latency scan params", __FUNCTION__);
@@ -3170,7 +3168,7 @@ UINT8 btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p)
}
if (p_le_inq_cb->adv_len != 0) {
- if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache,
+ if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len,
BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL) {
flag = * p_flag;
@@ -3386,7 +3384,7 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type
p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
if (p_le_inq_cb->adv_len != 0) {
- if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL) {
+ if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL) {
p_cur->flag = * p_flag;
}
}
@@ -3396,11 +3394,11 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type
* then try to convert the appearance value to a class of device value Bluedroid can use.
* Otherwise fall back to trying to infer if it is a HID device based on the service class.
*/
- p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_APPEARANCE, &len);
+ p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_APPEARANCE, &len);
if (p_uuid16 && len == 2) {
btm_ble_appearance_to_cod((UINT16)p_uuid16[0] | (p_uuid16[1] << 8), p_cur->dev_class);
} else {
- if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache,
+ if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len,
BTM_BLE_AD_TYPE_16SRV_CMPL, &len)) != NULL) {
UINT8 i;
for (i = 0; i + 2 <= len; i = i + 2) {
@@ -3487,10 +3485,10 @@ void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_dat
/* get the device name if exist in ADV data */
if (data_len != 0) {
- p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_CMPL, &len);
+ p_dev_name = BTM_CheckAdvData(p_data, data_len, BTM_BLE_AD_TYPE_NAME_CMPL, &len);
if (p_dev_name == NULL) {
- p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_SHORT, &len);
+ p_dev_name = BTM_CheckAdvData(p_data, data_len, BTM_BLE_AD_TYPE_NAME_SHORT, &len);
}
if (p_dev_name) {
@@ -3504,6 +3502,7 @@ void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_dat
}
}
+#if (BLE_42_SCAN_EN == TRUE)
static void btm_adv_pkt_handler(void *arg)
{
UINT8 hci_evt_code, hci_evt_len;
@@ -3546,6 +3545,7 @@ static void btm_adv_pkt_handler(void *arg)
UNUSED(hci_evt_code);
UNUSED(hci_evt_len);
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
/*******************************************************************************
**
@@ -3832,6 +3832,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
void btm_ble_process_adv_discard_evt(UINT8 *p)
{
+#if (BLE_42_SCAN_EN == TRUE)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
uint32_t num_dis = 0;
STREAM_TO_UINT32 (num_dis, p);
@@ -3840,6 +3841,7 @@ void btm_ble_process_adv_discard_evt(UINT8 *p)
(p_obs_discard_cb)(num_dis);
}
#endif
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
void btm_ble_process_direct_adv_pkt(UINT8 *p)
@@ -3847,6 +3849,7 @@ void btm_ble_process_direct_adv_pkt(UINT8 *p)
// TODO
}
+#if (BLE_42_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function btm_ble_start_scan
@@ -3884,6 +3887,7 @@ tBTM_STATUS btm_ble_start_scan(void)
osi_mutex_unlock(&scan_enable_lock);
return status;
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
/*******************************************************************************
**
@@ -3933,8 +3937,10 @@ void btm_ble_stop_inquiry(void)
} else if ((p_ble_cb->inq_var.scan_interval != BTM_BLE_LOW_LATENCY_SCAN_INT) ||
(p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) {
BTM_TRACE_DEBUG("%s: setting default params for ongoing observe", __FUNCTION__);
+#if (BLE_42_SCAN_EN == TRUE)
btm_ble_stop_scan();
btm_ble_start_scan();
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
/* If we have a callback registered for inquiry complete, call it */
@@ -3985,6 +3991,7 @@ static void btm_ble_stop_observe(void)
*******************************************************************************/
static void btm_ble_stop_discover(void)
{
+#if (BLE_42_SCAN_EN == TRUE)
tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
tBTM_CMPL_CB *p_scan_cb = p_ble_cb->p_scan_cmpl_cb;
btu_stop_timer (&p_ble_cb->scan_timer_ent);
@@ -3997,18 +4004,21 @@ static void btm_ble_stop_discover(void)
if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
/* Clear the inquiry callback if set */
- btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
btm_cb.ble_ctr_cb.inq_var.state &= ~BTM_BLE_SCANNING;
/* stop discovery now */
if(btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE)) {
osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT);
}
+ /* reset status */
+ btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
+ btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
}
if (p_scan_cb) {
(p_scan_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info);
}
osi_mutex_unlock(&scan_enable_lock);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
}
/*******************************************************************************
@@ -4021,6 +4031,7 @@ static void btm_ble_stop_discover(void)
**
*******************************************************************************/
typedef BOOLEAN (BTM_TOPOLOGY_FUNC_PTR)(tBTM_BLE_STATE_MASK);
+#if (BLE_42_ADV_EN == TRUE)
static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UINT8 adv_evt)
{
BOOLEAN rt = FALSE;
@@ -4053,7 +4064,6 @@ static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UI
return rt;
}
-
/*******************************************************************************
**
** Function btm_ble_start_adv
@@ -4165,14 +4175,19 @@ tBTM_STATUS btm_ble_stop_adv(void)
}
return rt;
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda)
{
tBTM_STATUS rt = BTM_SUCCESS;
-
+#if (BLE_42_ADV_EN == TRUE)
osi_mutex_lock(&adv_enable_lock, OSI_MUTEX_MAX_TIMEOUT);
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
osi_mutex_lock(&scan_enable_lock, OSI_MUTEX_MAX_TIMEOUT);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) {
osi_sem_take(&adv_enable_sem, OSI_SEM_MAX_TIMEOUT);
@@ -4181,7 +4196,9 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda)
rt = BTM_BAD_VALUE_RET;
}
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_SCAN_DUPLICATE_DISABLE)) {
osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT);
@@ -4190,11 +4207,13 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda)
rt = BTM_BAD_VALUE_RET;
}
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
if (rt == BTM_SUCCESS) {
btsnd_hcic_ble_set_random_addr(random_bda);
}
+#if (BLE_42_ADV_EN == TRUE)
if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) {
osi_sem_take(&adv_enable_sem, OSI_SEM_MAX_TIMEOUT);
@@ -4203,7 +4222,9 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda)
rt = BTM_BAD_VALUE_RET;
}
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, btm_cb.ble_ctr_cb.inq_var.scan_duplicate_filter)) {
osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT);
@@ -4212,9 +4233,14 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda)
rt = BTM_BAD_VALUE_RET;
}
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (BLE_42_ADV_EN == TRUE)
osi_mutex_unlock(&adv_enable_lock);
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
osi_mutex_unlock(&scan_enable_lock);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
return rt;
}
@@ -4231,6 +4257,7 @@ tBTM_STATUS btm_ble_set_random_addr(BD_ADDR random_bda)
*******************************************************************************/
static void btm_ble_start_slow_adv (void)
{
+#if (BLE_42_ADV_EN == TRUE)
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
@@ -4249,9 +4276,9 @@ static void btm_ble_start_slow_adv (void)
p_cb->evt_type, own_addr_type,
init_addr_type, p_addr_ptr,
p_cb->adv_chnl_map, p_cb->afp);
-
btm_ble_start_adv();
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
}
/*******************************************************************************
**
@@ -4291,9 +4318,11 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low);
#endif
} else {
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
if (BTM_BleMaxMultiAdvInstanceCount() > 0) {
btm_ble_multi_adv_configure_rpa((tBTM_BLE_MULTI_ADV_INST *)p_tle->param);
}
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
}
}
break;
@@ -4515,12 +4544,36 @@ BOOLEAN btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, UINT8 st
now in order */
if (btm_ble_get_conn_st() == BLE_CONN_IDLE && status != HCI_ERR_HOST_REJECT_RESOURCES &&
!btm_send_pending_direct_conn()) {
+#if (tGATT_BG_CONN_DEV == TRUE)
bg_con = btm_ble_resume_bg_conn();
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
}
return bg_con;
}
+#if (BLE_VENDOR_HCI_EN == TRUE)
+static void btm_ble_vs_evt_callback(UINT8 len, UINT8 *p)
+{
+ UINT8 sub_event;
+
+ if (!len || !p) {
+ return;
+ }
+
+ STREAM_TO_UINT8(sub_event, p);
+ len--;
+
+ if (sub_event < HCI_VSE_LE_SUBEVT_BASE) {
+ return;
+ }
+
+ if (ble_vs_evt_callback) {
+ ble_vs_evt_callback(sub_event, len, p);
+ }
+}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+
/*******************************************************************************
**
** Function btm_ble_init
@@ -4566,17 +4619,22 @@ void btm_ble_init (void)
p_cb->scan_int = p_cb->scan_win = BTM_BLE_SCAN_PARAM_UNDEF;
p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT;
-
+#if (BLE_42_SCAN_EN == TRUE)
p_cb->adv_rpt_queue = pkt_queue_create();
assert(p_cb->adv_rpt_queue != NULL);
p_cb->adv_rpt_ready = osi_event_create(btm_adv_pkt_handler, NULL);
assert(p_cb->adv_rpt_ready != NULL);
osi_event_bind(p_cb->adv_rpt_ready, btu_get_current_thread(), 0);
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#if BLE_VND_INCLUDED == FALSE
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
btm_ble_adv_filter_init();
+#endif // #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
#endif
+#if (BLE_VENDOR_HCI_EN == TRUE)
+ BTM_RegisterForVSEvents(btm_ble_vs_evt_callback, TRUE);
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
}
/*******************************************************************************
@@ -4595,19 +4653,25 @@ void btm_ble_free (void)
BTM_TRACE_DEBUG("%s", __func__);
fixed_queue_free(p_cb->conn_pending_q, osi_free_func);
-
+#if (BLE_42_SCAN_EN == TRUE)
pkt_queue_destroy(p_cb->adv_rpt_queue, NULL);
p_cb->adv_rpt_queue = NULL;
osi_event_delete(p_cb->adv_rpt_ready);
p_cb->adv_rpt_ready = NULL;
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#if BTM_DYNAMIC_MEMORY == TRUE
osi_free(cmn_ble_gap_vsc_cb_ptr);
cmn_ble_gap_vsc_cb_ptr = NULL;
#endif
}
+static bool enable_topology_check_flag = true;
+void esp_qa_enable_topology_check(bool enable)
+{
+ // This is a workaround: If the topology check is disabled, the 'Supported States' will not be checked.
+ enable_topology_check_flag = enable;
+}
/*******************************************************************************
**
** Function btm_ble_topology_check
@@ -4620,6 +4684,7 @@ void btm_ble_free (void)
*******************************************************************************/
BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask)
{
+ if(!enable_topology_check_flag) return TRUE;
BOOLEAN rt = FALSE;
UINT8 state_offset = 0;
@@ -4696,6 +4761,7 @@ BOOLEAN BTM_Ble_Authorization(BD_ADDR bd_addr, BOOLEAN authorize)
return FALSE;
}
+#if (BLE_VENDOR_HCI_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleClearAdv
@@ -4717,6 +4783,30 @@ BOOLEAN BTM_BleClearAdv(tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback)
p_cb->inq_var.p_clear_adv_cb = p_clear_adv_cback;
return TRUE;
}
+
+BOOLEAN BTM_BleSetCsaSupport(UINT8 csa_select, tBTM_SET_CSA_SUPPORT_CMPL_CBACK *p_callback)
+{
+ if (btsnd_hcic_ble_set_csa_support(csa_select) != TRUE) {
+ BTM_TRACE_ERROR("LE SetCsaSupport csa_select=%d: error", csa_select);
+ return FALSE;
+ }
+
+ btm_cb.ble_ctr_cb.set_csa_support_cmpl_cb = p_callback;
+ return TRUE;
+}
+
+BOOLEAN BTM_BleSetVendorEventMask(UINT32 evt_mask, tBTM_SET_VENDOR_EVT_MASK_CBACK *p_callback)
+{
+ if (btsnd_hcic_ble_set_vendor_evt_mask(evt_mask) != TRUE) {
+ BTM_TRACE_ERROR("LE SetVendorEventMask evt_mask=%x: error", evt_mask);
+ return FALSE;
+ }
+
+ btm_cb.ble_ctr_cb.set_vendor_evt_mask_cmpl_cb = p_callback;
+ return TRUE;
+}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
+
BOOLEAN BTM_BleSetRpaTimeout(uint16_t rpa_timeout,tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_set_rpa_timeout_cback)
{
if ((btsnd_hcic_ble_set_rand_priv_addr_timeout(rpa_timeout)) != TRUE) {
@@ -4752,6 +4842,7 @@ BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type, BD_ADDR bd_addr, UINT8 privacy_mo
return TRUE;
}
+#if (BLE_42_SCAN_EN == TRUE)
bool btm_ble_adv_pkt_ready(void)
{
tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
@@ -4770,4 +4861,6 @@ bool btm_ble_adv_pkt_post(pkt_linked_item_t *pkt)
pkt_queue_enqueue(p_cb->adv_rpt_queue, pkt);
return true;
}
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+
#endif /* BLE_INCLUDED */
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_iso.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_iso.c
new file mode 100644
index 00000000..c66f10b9
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_iso.c
@@ -0,0 +1,525 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "btm_int.h"
+#include "stack/hcimsgs.h"
+#include "osi/allocator.h"
+#include "device/controller.h"
+#include <string.h>
+#include "l2c_int.h"
+
+tBTM_BLE_ISO_CBACK ble_iso_cb;
+
+extern void btm_ble_inter_set(bool extble_inter);
+
+void BTM_BleIsoRegisterCallback(tBTM_BLE_ISO_CBACK cb)
+{
+ if (cb) {
+ ble_iso_cb = cb;
+ } else {
+ BTM_TRACE_ERROR("%s, register fail, the cb function is NULL.", __func__);
+ }
+}
+
+void BTM_IsoBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_ISO_CB_PARAMS *params)
+{
+ if(params && params->status == BTM_SUCCESS) {
+ btm_ble_inter_set(true);
+ }
+ if (ble_iso_cb) {
+ ble_iso_cb(event, params);
+ }
+}
+
+void btm_ble_iso_read_iso_tx_sync_complete(UINT8 *p)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ STREAM_TO_UINT8(cb_params.btm_read_tx_sync.status, p);
+ STREAM_TO_UINT16(cb_params.btm_read_tx_sync.conn_hdl, p);
+ STREAM_TO_UINT16(cb_params.btm_read_tx_sync.pkt_seq_num, p);
+ STREAM_TO_UINT32(cb_params.btm_read_tx_sync.tx_time_stamp, p);
+ STREAM_TO_UINT24(cb_params.btm_read_tx_sync.time_offset, p);
+
+ if (cb_params.btm_read_tx_sync.status != HCI_SUCCESS) {
+ cb_params.btm_read_tx_sync.status = (BTM_HCI_ERROR | cb_params.btm_read_tx_sync.status);
+ }
+ cb_params.btm_read_tx_sync.conn_hdl = (cb_params.btm_read_tx_sync.conn_hdl & 0xEFF);
+ cb_params.btm_read_tx_sync.time_offset = (cb_params.btm_read_tx_sync.time_offset & 0xFFFFFF);
+ BTM_TRACE_DEBUG("read tx sync cmpl, status 0x%x conn_hdl 0x%x pkt_seq_num %d tx_time_stamp %ld time_offset %ld\n",
+ cb_params.btm_read_tx_sync.status, cb_params.btm_read_tx_sync.conn_hdl, cb_params.btm_read_tx_sync.pkt_seq_num,
+ cb_params.btm_read_tx_sync.tx_time_stamp, cb_params.btm_read_tx_sync.time_offset);
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_READ_TX_SYNC_EVT, &cb_params);
+}
+
+void btm_ble_iso_read_iso_link_quality_complete(UINT8 *p)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ STREAM_TO_UINT8(cb_params.btm_read_link_quality.status, p);
+ STREAM_TO_UINT16(cb_params.btm_read_link_quality.conn_hdl, p);
+ STREAM_TO_UINT32(cb_params.btm_read_link_quality.tx_unacked_pkts, p);
+ STREAM_TO_UINT32(cb_params.btm_read_link_quality.tx_flushed_pkts, p);
+ STREAM_TO_UINT32(cb_params.btm_read_link_quality.tx_last_subevt_pkts, p);
+ STREAM_TO_UINT32(cb_params.btm_read_link_quality.retransmitted_pkts, p);
+ STREAM_TO_UINT32(cb_params.btm_read_link_quality.crc_error_pkts, p);
+ STREAM_TO_UINT32(cb_params.btm_read_link_quality.rx_unreceived_pkts, p);
+ STREAM_TO_UINT32(cb_params.btm_read_link_quality.duplicate_pkts, p);
+
+ if (cb_params.btm_read_link_quality.status != HCI_SUCCESS) {
+ cb_params.btm_read_link_quality.status = (BTM_HCI_ERROR | cb_params.btm_read_link_quality.status);
+ }
+
+ BTM_TRACE_DEBUG("read link quality cmpl, status 0x%x conn_hdl 0x%x tx_unacked_pkts %d tx_flushed_pkts %ld tx_last_subevt_pkts %ld retransmitted_pkts %d\
+ crc_error_pkts %d rx_unreceived_pkts %d duplicate_pkts %d\n",
+ cb_params.btm_read_link_quality.status, cb_params.btm_read_link_quality.conn_hdl, cb_params.btm_read_link_quality.tx_unacked_pkts,
+ cb_params.btm_read_link_quality.tx_flushed_pkts, cb_params.btm_read_link_quality.tx_last_subevt_pkts, cb_params.btm_read_link_quality.retransmitted_pkts,
+ cb_params.btm_read_link_quality.crc_error_pkts, cb_params.btm_read_link_quality.rx_unreceived_pkts, cb_params.btm_read_link_quality.duplicate_pkts);
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_READ_LINK_QUALITY_EVT, &cb_params);
+}
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+void btm_ble_iso_set_cig_params_complete(UINT8 *p)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+
+ STREAM_TO_UINT8(cb_params.btm_set_cig_params.status, p);
+ STREAM_TO_UINT8(cb_params.btm_set_cig_params.cig_id, p);
+ STREAM_TO_UINT8(cb_params.btm_set_cig_params.cis_count, p);
+ for (uint8_t i = 0; i < cb_params.btm_set_cig_params.cis_count; i++)
+ {
+ STREAM_TO_UINT16(cb_params.btm_set_cig_params.conn_hdl[i], p);
+ BTM_TRACE_DEBUG("i = %d, conn_hdl = %d", i, cb_params.btm_set_cig_params.conn_hdl[i]);
+ }
+
+ if (cb_params.btm_set_cig_params.status != HCI_SUCCESS) {
+ cb_params.btm_set_cig_params.status = (BTM_HCI_ERROR | cb_params.btm_set_cig_params.status);
+ }
+
+ BTM_TRACE_DEBUG("set cig params, status 0x%x cig_id %d cis_count %d\n",
+ cb_params.btm_set_cig_params.status, cb_params.btm_set_cig_params.cig_id, cb_params.btm_set_cig_params.cis_count);
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_SET_CIG_PARAMS_EVT, &cb_params);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+void btm_ble_cis_disconnected_evt(tBTM_BLE_CIS_DISCON_CMPL *params)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+ cb_params.btm_cis_disconnectd_evt.cis_handle = params->cis_handle;
+ cb_params.btm_cis_disconnectd_evt.reason = params->reason;
+
+ BTM_TRACE_DEBUG("btm cis disconnect, cis_handle %d reason 0x%x\n", params->cis_handle, params->reason);
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CIS_DISCONNECTED_EVT, &cb_params);
+}
+
+void btm_ble_cis_established_evt(tBTM_BLE_CIS_ESTABLISHED_CMPL *params)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ if (params->status != HCI_SUCCESS) {
+ params->status = (params->status | BTM_HCI_ERROR);
+ }
+
+ memcpy(&cb_params.btm_cis_established_evt, params, sizeof(tBTM_BLE_CIS_ESTABLISHED_CMPL));
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CIS_ESTABLISHED_EVT, &cb_params);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+void btm_ble_cis_request_evt(tBTM_BLE_CIS_REQUEST_CMPL *params)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+ memcpy(&cb_params.btm_cis_request_evt, params, sizeof(tBTM_BLE_CIS_REQUEST_CMPL));
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CIS_REQUEST_EVT, &cb_params);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params)
+{
+ BTM_TRACE_DEBUG("%s", __func__);
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ if (params->status != HCI_SUCCESS) {
+ params->status = (params->status | BTM_HCI_ERROR);
+ }
+
+ cb_params.btm_big_cmpl.status = params->status;
+ cb_params.btm_big_cmpl.big_handle = params->big_handle;
+ cb_params.btm_big_cmpl.big_sync_delay = params->big_sync_delay;
+ cb_params.btm_big_cmpl.transport_latency = params->transport_latency;
+ cb_params.btm_big_cmpl.phy = params->phy;
+ cb_params.btm_big_cmpl.nse = params->nse;
+ cb_params.btm_big_cmpl.bn = params->bn;
+ cb_params.btm_big_cmpl.pto = params->pto;
+ cb_params.btm_big_cmpl.irc = params->irc;
+ cb_params.btm_big_cmpl.max_pdu = params->max_pdu;
+ cb_params.btm_big_cmpl.iso_interval = params->iso_interval;
+ cb_params.btm_big_cmpl.num_bis = params->num_bis;
+ // for (uint8_t i = 0; i < params->num_bis; i++)
+ // {
+ // cb_params.btm_big_cmpl.bis_handle[i] = params->bis_handle[i];
+ // }
+ memcpy(&cb_params.btm_big_cmpl.bis_handle[0], &params->bis_handle[0], params->num_bis * 2);
+
+ //memcpy(&cb_params.btm_big_cmpl, params, sizeof(tBTM_BLE_BIG_CREATE_CMPL));
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT, &cb_params);
+}
+
+void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *params)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+ memcpy(&cb_params.btm_big_term, params, sizeof(tBTM_BLE_BIG_TERMINATE_CMPL));
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT, &cb_params);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ if (params->status != HCI_SUCCESS) {
+ params->status = (params->status | BTM_HCI_ERROR);
+ }
+
+ memcpy(&cb_params.btm_big_sync_estab, params, sizeof(tBTM_BLE_BIG_SYNC_ESTAB_CMPL));
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT, &cb_params);
+}
+
+void btm_ble_big_sync_terminate_complete(UINT8 hci_status, UINT8 big_handle)
+{
+ BTM_TRACE_DEBUG("%s hci_status 0x%x big_handle %d\n", __func__, hci_status, big_handle);
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+
+ if (hci_status != HCI_SUCCESS) {
+ hci_status = (hci_status | BTM_HCI_ERROR);
+ }
+
+ cb_params.status = hci_status;
+ cb_params.btm_big_sync_ter.big_hdl = big_handle;
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_TERMINATE_COMPLETE_EVT, &cb_params);
+}
+
+void btm_ble_big_sync_lost_evt(tBTM_BLE_BIG_SYNC_LOST_EVT *params)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ memcpy(&cb_params.btm_big_sync_lost, params, sizeof(tBTM_BLE_BIG_SYNC_LOST_EVT));
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_LOST_EVT, &cb_params);
+}
+
+void btm_ble_biginfo_adv_report_evt(tBTM_BLE_BIGINFO_ADV_REPORT_EVT *params)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (!params) {
+ BTM_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ memcpy(&cb_params.btm_biginfo_report, params, sizeof(tBTM_BLE_BIGINFO_ADV_REPORT_EVT));
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIGINFO_ADV_REPORT_EVT, &cb_params);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+void btm_ble_iso_data_path_update_complete(UINT16 opcode, UINT8 hci_status, UINT16 conn_handle)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ BTM_TRACE_DEBUG("data path update cmpl, opcode 0x%x status 0x%x conn_hdl %d\n", opcode, hci_status, conn_handle);
+ if (hci_status != HCI_SUCCESS) {
+ hci_status = (BTM_HCI_ERROR | hci_status);
+ }
+ cb_params.status = hci_status;
+ cb_params.btm_data_path_update.op_type = ((opcode == HCI_BLE_ISO_SET_DATA_PATH) ? BTM_BLE_ISO_DATA_PATH_SETUP : BTM_BLE_ISO_DATA_PATH_REMOVE);
+ cb_params.btm_data_path_update.conn_hdl = conn_handle;
+
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_DATA_PATH_UPFATE_EVT, &cb_params);
+}
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency,
+ uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing,
+ uint8_t encryption, uint8_t *broadcast_code)
+{
+ BTM_TRACE_API("big_handle %d adv_handle %d num_bis %d sdu_interval %d max_sdu %d max_transport_latency %d \
+ rtn %d phy %d packing %d framing %d encryption %d broadcast_code %d", big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency,\
+ rtn, phy, packing, framing, encryption, broadcast_code);
+
+ btsnd_hcic_ble_big_create(big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency,
+ rtn, phy, packing, framing, encryption, broadcast_code);
+
+
+ return BTM_SUCCESS;
+}
+
+tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse,
+ uint16_t max_sdu, uint16_t max_pdu, uint8_t phy,
+ uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc,
+ uint8_t pto, uint8_t encryption, uint8_t *broadcast_code)
+{
+ btsnd_hcic_ble_big_create_test(big_handle, adv_handle, num_bis, sdu_interval, iso_interval, nse,
+ max_sdu, max_pdu, phy, packing, framing, bn, irc, pto, encryption,
+ broadcast_code);
+ return BTM_SUCCESS;
+}
+
+tBTM_STATUS BTM_BleBigTerminate(UINT8 big_handle, UINT8 reason)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_big_terminate(big_handle, reason)) != TRUE) {
+ BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ if (status != BTM_SUCCESS) {
+ cb_params.status = status;
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT, &cb_params);
+ }
+
+ return status;
+}
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle,
+ uint8_t encryption, uint8_t *bc_code,
+ uint8_t mse, uint16_t big_sync_timeout,
+ uint8_t num_bis, uint8_t *bis)
+{
+ btsnd_hcic_ble_big_sync_create(big_handle, sync_handle, encryption, bc_code,
+ mse, big_sync_timeout, num_bis, bis);
+ return BTM_SUCCESS;
+}
+
+tBTM_STATUS BTM_BleBigSyncTerminate(uint8_t big_handle)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+
+ if ((err = btsnd_hcic_ble_big_sync_terminate(big_handle)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("LE big sync terminate, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ return status;
+}
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+tBTM_STATUS BTM_BleIsoSetDataPath(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt,
+ uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len,
+ uint8_t *codec_cfg)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+
+ if (codec_len && (codec_cfg == NULL)) {
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ status = BTM_ILLEGAL_VALUE;
+ cb_params.btm_data_path_update.op_type = BTM_BLE_ISO_DATA_PATH_SETUP;
+ cb_params.status = status;
+ cb_params.btm_data_path_update.conn_hdl = conn_handle;
+ BTM_TRACE_ERROR("codec_cfg is NULL, set data path error");
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_DATA_PATH_UPFATE_EVT, &cb_params);
+ return status;
+ }
+
+ BTM_TRACE_DEBUG("BTM_BleIsoSetDataPath conn_handle %d data_path_dir %d\n", conn_handle, data_path_dir);
+
+ if ((err = btsnd_hcic_ble_iso_set_data_path(conn_handle, data_path_dir, data_path_id, coding_fmt, company_id, vs_codec_id,
+ controller_delay, codec_len, codec_cfg)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso data path update, cmd err=0x%x", err);
+ return BTM_HCI_ERROR | err;
+ }
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleIsoRemoveDataPath(uint16_t conn_handle, uint8_t data_path_dir)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+
+ BTM_TRACE_DEBUG("BTM_BleIsoRemoveDataPath conn_handle %d data_path_dir %d\n", conn_handle, data_path_dir);
+
+ if ((err = btsnd_hcic_ble_iso_remove_data_path(conn_handle, data_path_dir)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso data path remove, cmd err=0x%x", err);
+ return BTM_HCI_ERROR | err;
+ }
+
+ return BTM_SUCCESS;
+}
+
+tBTM_STATUS BTM_BleIsoReadTxSync(uint16_t iso_hdl)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+
+ BTM_TRACE_DEBUG("BTM_BleIsoReadTxSync iso_hdl %d\n", iso_hdl);
+
+ if ((err = btsnd_hcic_ble_iso_read_tx_sync(iso_hdl)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso read tx sync, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleIsoReadLinkQuality(uint16_t iso_hdl)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+
+ BTM_TRACE_DEBUG("BTM_BleIsoReadLinkQuality iso_hdl %d\n", iso_hdl);
+
+ if ((err = btsnd_hcic_ble_iso_read_iso_link_quality(iso_hdl)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso read link quality, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ return status;
+}
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+tBTM_STATUS BTM_BleSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing,
+ uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, uint8_t *cis_params)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+
+ if ((err = btsnd_hcic_ble_iso_set_cig_params(cig_id, sdu_int_c_to_p, sdu_int_p_to_c, worse_case_SCA, packing,
+ framing, mtl_c_to_p, mtl_p_to_c, cis_cnt, (struct ble_hci_le_cis_params *)cis_params)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso set cig params, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ return status;
+}
+
+tBTM_STATUS BTM_BleSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c, uint16_t iso_interval,
+ uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, uint8_t *cis_params)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+
+ if ((err = btsnd_hcic_ble_iso_set_cig_params_test(cig_id, sdu_int_c_to_p, sdu_int_p_to_c,ft_c_to_p, ft_p_to_c, iso_interval,
+ worse_case_SCA, packing, framing, cis_cnt, (struct ble_hci_le_cis_params_test *)cis_params)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso set cig params test, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ return status;
+}
+
+void btm_ble_create_cis_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params)
+{
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_CREATE_CIS_EVT, cb_params);
+}
+
+tBTM_STATUS BTM_BleCreateCis(uint8_t cis_count, uint8_t *cis_hdls)
+{
+ btsnd_hcic_ble_iso_create_cis(cis_count, (struct ble_hci_cis_hdls *)cis_hdls);
+
+ return BTM_SUCCESS;
+}
+
+tBTM_STATUS BTM_BleRemoveCig(uint8_t cig_id)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_iso_remove_cig(cig_id)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso remove cig, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.btm_remove_cig.status = status;
+ cb_params.btm_remove_cig.cig_id = cig_id;
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_REMOVE_CIG_EVT, &cb_params);
+
+ return status;
+}
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+void btm_ble_accept_cis_req_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params)
+{
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_ACCEPT_CIS_REQ_EVT, cb_params);
+}
+
+tBTM_STATUS BTM_BleAcceptCisReq(uint16_t cis_handle)
+{
+ btsnd_hcic_ble_iso_accept_cis_req(cis_handle);
+ return BTM_SUCCESS;
+}
+
+tBTM_STATUS BTM_BleRejectCisReq(uint16_t cis_handle, uint8_t reason)
+{
+ tHCI_STATUS err = HCI_SUCCESS;
+ tBTM_STATUS status = BTM_SUCCESS;
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+
+ if ((err = btsnd_hcic_ble_iso_reject_cis_req(cis_handle, reason)) != HCI_SUCCESS) {
+ BTM_TRACE_ERROR("iso reject cis req, cmd err=0x%x", err);
+ status = BTM_HCI_ERROR | err;
+ }
+
+ cb_params.btm_reject_cis_req.status = status;
+ cb_params.btm_reject_cis_req.cis_handle = cis_handle;
+ BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_REJECT_CIS_REQ_EVT, &cb_params);
+ return status;
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+tBTM_STATUS BTM_BleDisconCis(uint16_t cis_handle, uint8_t reason)
+{
+ btsnd_hcic_disconnect(cis_handle, reason);
+
+ return BTM_SUCCESS;
+}
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c
index bc300b02..31d60546 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c
@@ -22,6 +22,8 @@
#include "device/controller.h"
#if (BLE_INCLUDED == TRUE)
+
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
#include "stack/bt_types.h"
#include "stack/hcimsgs.h"
#include "stack/btu.h"
@@ -218,25 +220,7 @@ tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_ev
}
return rt;
}
-/*******************************************************************************
-**
-** Function btm_ble_map_adv_tx_power
-**
-** Description return the actual power in dBm based on the mapping in config file
-**
-** Parameters advertise parameters used for this instance.
-**
-** Returns tx power in dBm
-**
-*******************************************************************************/
-static const int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER;
-char btm_ble_map_adv_tx_power(int tx_power_index)
-{
- if (0 <= tx_power_index && tx_power_index <= BTM_BLE_ADV_TX_POWER_MAX) {
- return (char)btm_ble_tx_power[tx_power_index];
- }
- return 0;
-}
+
/*******************************************************************************
**
** Function btm_ble_multi_adv_set_params
@@ -882,4 +866,5 @@ void *btm_ble_multi_adv_get_ref(UINT8 inst_id)
return NULL;
}
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
#endif
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c
index be4b9d15..28e06658 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_ble_privacy.c
@@ -330,7 +330,7 @@ void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
BTM_TRACE_DEBUG("%s status = %d", __func__, status);
if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
- BTM_TRACE_ERROR("%s no pending resolving list operation", __func__);
+ BTM_TRACE_DEBUG("%s no pending resolving list operation", __func__);
return;
}
@@ -683,20 +683,22 @@ BOOLEAN btm_ble_suspend_resolving_list_activity(void)
p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
+#if (BLE_42_ADV_EN == TRUE)
if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
btm_ble_stop_adv();
p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
}
+#endif // #if (BLE_42_ADV_EN == TRUE)
if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
btm_ble_stop_scan();
p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
}
-
+#if (tGATT_BG_CONN_DEV == TRUE)
if (btm_ble_suspend_bg_conn()) {
p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;
}
-
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
return TRUE;
}
@@ -714,19 +716,21 @@ BOOLEAN btm_ble_suspend_resolving_list_activity(void)
void btm_ble_resume_resolving_list_activity(void)
{
tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
-
+#if (BLE_42_ADV_EN == TRUE)
if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) {
btm_ble_start_adv();
}
-
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) {
btm_ble_start_scan();
}
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
+#if (tGATT_BG_CONN_DEV == TRUE)
if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) {
btm_ble_resume_bg_conn();
}
-
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
}
@@ -1147,6 +1151,9 @@ void btm_ble_add_default_entry_to_resolving_list(void)
BD_ADDR peer_addr = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
BT_OCTET16 peer_irk = {0x0};
+ // Remove the existing entry in resolving list When resetting the device identity
+ btsnd_hcic_ble_rm_device_resolving_list(BLE_ADDR_PUBLIC, peer_addr);
+
btsnd_hcic_ble_add_device_resolving_list (BLE_ADDR_PUBLIC, peer_addr, peer_irk, btm_cb.devcb.id_keys.irk);
}
#endif
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_dev.c b/lib/bt/host/bluedroid/stack/btm/btm_dev.c
index f9e3ed2b..f705a8dc 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_dev.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_dev.c
@@ -179,20 +179,33 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
*******************************************************************************/
BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport)
{
-
tBTM_SEC_DEV_REC *p_dev_rec;
if (BTM_IsAclConnectionUp(bd_addr, transport)) {
BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active\n", __func__);
return FALSE;
}
+
if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) {
+#if (CLASSIC_BT_INCLUDED == TRUE)
/* Tell controller to get rid of the link key, if it has one stored */
BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
+#endif // (CLASSIC_BT_INCLUDED == TRUE)
- btm_sec_free_dev(p_dev_rec, transport);
+ btm_sec_free_dev(p_dev_rec, transport);
}
+#if (BLE_SMP_ID_RESET_ENABLE == TRUE)
+ /*
+ * There are tracking risks associated with using a fixed or static IRK.
+ * A best-practices approach, when all pairing and bonding records are deleted,
+ * assign a new randomly-generated IRK.
+ */
+ if (list_is_empty(btm_cb.p_sec_dev_rec_list)) {
+ btm_ble_reset_id();
+ }
+#endif
+
return TRUE;
}
@@ -640,7 +653,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
tBTM_SEC_DEV_REC *p_dev_rec = NULL;
tBTM_SEC_DEV_REC *p_oldest = NULL;
list_node_t *p_node = NULL;
- UINT32 ot = 0xFFFFFFFF;
+ UINT32 old_ts = 0xFFFFFFFF;
/* First look for the non-paired devices for the oldest entry */
for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
@@ -650,13 +663,13 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
continue; /* Device is paired so skip it */
}
- if (p_dev_rec->timestamp < ot) {
+ if (p_dev_rec->timestamp < old_ts) {
p_oldest = p_dev_rec;
- ot = p_dev_rec->timestamp;
+ old_ts = p_dev_rec->timestamp;
}
}
- if (ot != 0xFFFFFFFF) {
+ if (old_ts != 0xFFFFFFFF) {
return (p_oldest);
}
@@ -666,9 +679,9 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
continue;
}
- if (p_dev_rec->timestamp < ot) {
+ if (p_dev_rec->timestamp < old_ts) {
p_oldest = p_dev_rec;
- ot = p_dev_rec->timestamp;
+ old_ts = p_dev_rec->timestamp;
}
}
return (p_oldest);
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_devctl.c b/lib/bt/host/bluedroid/stack/btm/btm_devctl.c
index bab88739..2250c78b 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_devctl.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_devctl.c
@@ -82,7 +82,9 @@ void btm_dev_init (void)
/* Initialize nonzero defaults */
#if (BTM_MAX_LOC_BD_NAME_LEN > 0)
memset(btm_cb.cfg.ble_bd_name, 0, sizeof(tBTM_LOC_BD_NAME));
+#if (CLASSIC_BT_INCLUDED == TRUE)
memset(btm_cb.cfg.bredr_bd_name, 0, sizeof(tBTM_LOC_BD_NAME));
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#endif
btm_cb.devcb.reset_timer.param = (TIMER_PARAM_TYPE)TT_DEV_RESET;
@@ -169,8 +171,12 @@ static void reset_complete(void)
btm_cb.ble_ctr_cb.conn_state = BLE_CONN_IDLE;
btm_cb.ble_ctr_cb.bg_conn_type = BTM_BLE_CONN_NONE;
btm_cb.ble_ctr_cb.p_select_cback = NULL;
+#if (tGATT_BG_CONN_DEV == TRUE)
gatt_reset_bgdev_list();
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
btm_ble_multi_adv_init();
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
#endif
btm_pm_reset();
@@ -193,6 +199,9 @@ static void reset_complete(void)
if (controller->supports_ble()) {
btm_ble_white_list_init(controller->get_ble_white_list_size());
+ #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ btm_ble_periodic_adv_list_init(controller->get_ble_periodic_adv_list_size());
+ #endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE)
l2c_link_processs_ble_num_bufs(controller->get_acl_buffer_count_ble());
}
#endif
@@ -471,7 +480,7 @@ tBTM_STATUS BTM_SetLocalDeviceName (char *p_name, tBT_DEVICE_TYPE name_type)
btm_cb.cfg.ble_bd_name[BTM_MAX_LOC_BD_NAME_LEN] = '\0';
}
}
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
if (name_type & BT_DEVICE_TYPE_BREDR) {
p = (UINT8 *)btm_cb.cfg.bredr_bd_name;
if (p != (UINT8 *)p_name) {
@@ -479,6 +488,7 @@ tBTM_STATUS BTM_SetLocalDeviceName (char *p_name, tBT_DEVICE_TYPE name_type)
btm_cb.cfg.bredr_bd_name[BTM_MAX_LOC_BD_NAME_LEN] = '\0';
}
}
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#else
p = (UINT8 *)p_name;
#endif
@@ -519,21 +529,22 @@ tBTM_STATUS BTM_ReadLocalDeviceName (char **p_name, tBT_DEVICE_TYPE name_type)
*/
#if BTM_MAX_LOC_BD_NAME_LEN > 0
+#if (CLASSIC_BT_INCLUDED == TRUE)
if ((name_type == BT_DEVICE_TYPE_DUMO) &&
(BCM_STRNCMP_S(btm_cb.cfg.bredr_bd_name, btm_cb.cfg.ble_bd_name, BTM_MAX_LOC_BD_NAME_LEN) != 0)) {
*p_name = NULL;
BTM_TRACE_ERROR("Error, BLE and BREDR have different names, return NULL\n");
return (BTM_NO_RESOURCES);
}
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
if (name_type & BT_DEVICE_TYPE_BLE) {
*p_name = btm_cb.cfg.ble_bd_name;
}
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
if (name_type & BT_DEVICE_TYPE_BREDR) {
*p_name = btm_cb.cfg.bredr_bd_name;
}
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
return (BTM_SUCCESS);
#else
*p_name = NULL;
@@ -752,9 +763,6 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
#if (BLE_INCLUDED == TRUE)
tBTM_BLE_CB *ble_cb = &btm_cb.ble_ctr_cb;
switch(opcode) {
- case HCI_VENDOR_BLE_LONG_ADV_DATA:
- BTM_TRACE_EVENT("Set long adv data complete\n");
- break;
case HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST: {
uint8_t subcode, status; uint32_t length;
STREAM_TO_UINT8(status, p);
@@ -773,6 +781,22 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
}
break;
}
+ case HCI_VENDOR_BLE_SET_CSA_SUPPORT: {
+ uint8_t status;
+ STREAM_TO_UINT8(status, p);
+ if (ble_cb && ble_cb->set_csa_support_cmpl_cb) {
+ ble_cb->set_csa_support_cmpl_cb(status);
+ }
+ break;
+ }
+ case HCI_VENDOR_BLE_SET_EVT_MASK: {
+ uint8_t status;
+ STREAM_TO_UINT8(status, p);
+ if (ble_cb && ble_cb->set_vendor_evt_mask_cmpl_cb) {
+ ble_cb->set_vendor_evt_mask_cmpl_cb(status);
+ }
+ break;
+ }
default:
break;
}
@@ -863,7 +887,7 @@ void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len)
STREAM_TO_UINT8(sub_event, p_evt);
/* Check in subevent if authentication is through Legacy Authentication. */
- if (sub_event == ESP_VS_REM_LEGACY_AUTH_CMP) {
+ if (sub_event == HCI_VENDOR_LEGACY_REM_AUTH_EVT_SUBCODE) {
UINT16 hci_handle;
STREAM_TO_UINT16(hci_handle, p_evt);
btm_sec_handle_remote_legacy_auth_cmp(hci_handle);
@@ -1066,6 +1090,7 @@ tBTM_STATUS BTM_WriteVoiceSettings(UINT16 settings)
return (BTM_NO_RESOURCES);
}
+#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
/*******************************************************************************
**
** Function BTM_EnableTestMode
@@ -1122,7 +1147,9 @@ tBTM_STATUS BTM_EnableTestMode(void)
return (BTM_NO_RESOURCES);
}
}
+#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE)
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function BTM_DeleteStoredLinkKey
@@ -1197,6 +1224,7 @@ void btm_delete_stored_link_key_complete (UINT8 *p)
}
}
+#endif // (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btm_report_device_status
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_inq.c b/lib/bt/host/bluedroid/stack/btm/btm_inq.c
index b8da2327..528c7a06 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_inq.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_inq.c
@@ -163,7 +163,7 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter
UINT8 scan_mode = 0;
UINT16 service_class;
UINT8 *p_cod;
- UINT8 major, minor;
+ UINT8 major, minor, reserved_2;
DEV_CLASS cod;
LAP temp_lap[2];
BOOLEAN is_limited;
@@ -255,13 +255,14 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter
if (is_limited ^ cod_limited) {
BTM_COD_MINOR_CLASS(minor, p_cod );
BTM_COD_MAJOR_CLASS(major, p_cod );
+ BTM_COD_RESERVED_2(reserved_2, p_cod);
if (is_limited) {
service_class |= BTM_COD_SERVICE_LMTD_DISCOVER;
} else {
service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER;
}
- FIELDS_TO_COD(cod, minor, major, service_class);
+ FIELDS_TO_COD(cod, reserved_2, minor, major, service_class);
(void) BTM_SetDeviceClass (cod);
}
@@ -515,7 +516,7 @@ tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, UINT16 max_d
/* Before beginning the inquiry the current filter must be cleared, so initiate the command */
if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED) {
- /* If set filter command is not succesful reset the state */
+ /* If set filter command is not successful reset the state */
p_inq->p_inq_results_cb = NULL;
p_inq->state = BTM_INQ_INACTIVE_STATE;
@@ -688,7 +689,7 @@ UINT16 BTM_ReadConnectability (UINT16 *p_window, UINT16 *p_interval)
** Description This function returns a bit mask of the current inquiry state
**
** Returns BTM_INQUIRY_INACTIVE if inactive (0)
-** BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active
+** BTM_LIMITED_INQUIRY_ACTIVE if a limited inquiry is active
** BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active
** BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active
**
@@ -783,7 +784,7 @@ tBTM_STATUS BTM_CancelInquiry(void)
** Description This function is called to start an inquiry.
**
** Parameters: p_inqparms - pointer to the inquiry information
-** mode - GENERAL or LIMITED inquiry, BR/LE bit mask seperately
+** mode - GENERAL or LIMITED inquiry, BR/LE bit mask separately
** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
** max_resps - maximum amount of devices to search for before ending the inquiry
** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
@@ -1858,7 +1859,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
#if BLE_INCLUDED == TRUE
/* new device response */
&& ( p_i == NULL ||
- /* exisiting device with BR/EDR info */
+ /* existing device with BR/EDR info */
(p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)
)
#endif
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_main.c b/lib/bt/host/bluedroid/stack/btm/btm_main.c
index 8e49aa3e..67882af0 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_main.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_main.c
@@ -39,7 +39,9 @@ tBTM_CB *btm_cb_ptr;
#if (BLE_50_FEATURE_SUPPORT == TRUE)
extern void btm_ble_extendadvcb_init(void);
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
extern void btm_ble_advrecod_init(void);
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif
@@ -84,11 +86,14 @@ void btm_init (void)
#if BLE_INCLUDED == TRUE
btm_ble_lock_init();
btm_ble_sem_init();
+ btm_cb.addr_res_en = TRUE;
#endif
btm_sec_dev_init();
#if (BLE_50_FEATURE_SUPPORT == TRUE)
btm_ble_extendadvcb_init();
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
btm_ble_advrecod_init();
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif
}
@@ -109,6 +114,9 @@ void btm_free(void)
fixed_queue_free(btm_cb.sec_pending_q, osi_free_func);
btm_acl_free();
btm_sec_dev_free();
+#if BTM_SCO_INCLUDED == TRUE
+ btm_sco_free();
+#endif
#if BTM_DYNAMIC_MEMORY
FREE_AND_RESET(btm_cb_ptr);
#endif
@@ -118,7 +126,8 @@ void btm_free(void)
#endif
}
-uint8_t btm_acl_active_count(void)
+#if (BLE_INCLUDED == TRUE)
+uint8_t btm_ble_acl_active_count(void)
{
list_node_t *p_node = NULL;
tACL_CONN *p_acl_conn = NULL;
@@ -126,10 +135,23 @@ uint8_t btm_acl_active_count(void)
for (p_node = list_begin(btm_cb.p_acl_db_list); p_node; p_node = list_next(p_node)) {
p_acl_conn = list_node(p_node);
- if (p_acl_conn && p_acl_conn->in_use) {
+ if (p_acl_conn && p_acl_conn->in_use && p_acl_conn->transport == BT_TRANSPORT_LE) {
count++;
}
}
return count;
}
+
+// Address resolution status
+uint8_t btm_get_ble_addr_resolve_disable_status(void)
+{
+ // Returns false if address resolution is enabled, true if disabled
+ return (btm_cb.addr_res_en) ? 0 : 1;
+}
+
+void btm_ble_addr_resolve_enable(bool enable)
+{
+ btm_cb.addr_res_en = enable;
+}
+#endif /*BLE_INCLUDED*/
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_pm.c b/lib/bt/host/bluedroid/stack/btm/btm_pm.c
index 4c52348e..1c46a744 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_pm.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_pm.c
@@ -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)
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_sco.c b/lib/bt/host/bluedroid/stack/btm/btm_sco.c
index 53a9768a..69640280 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_sco.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_sco.c
@@ -117,14 +117,28 @@ void btm_sco_init (void)
}
#endif
/* Initialize nonzero defaults */
- btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
-
btm_cb.sco_cb.def_esco_parms = btm_esco_defaults; /* Initialize with defaults */
btm_cb.sco_cb.desired_sco_mode = BTM_DEFAULT_SCO_MODE;
}
/*******************************************************************************
**
+** Function btm_sco_free
+**
+** Description Free sco specific fixed_queue from btm control block
+**
+*******************************************************************************/
+void btm_sco_free(void)
+{
+#if (BTM_SCO_HCI_INCLUDED == TRUE)
+ for (int i = 0; i < BTM_MAX_SCO_LINKS; i++) {
+ fixed_queue_free(btm_cb.sco_cb.sco_db[i].xmit_data_q, osi_free_func);
+ }
+#endif
+}
+
+/*******************************************************************************
+**
** Function btm_esco_conn_rsp
**
** Description This function is called upon receipt of an (e)SCO connection
@@ -233,7 +247,7 @@ void btm_sco_process_num_bufs (UINT16 num_lm_sco_bufs)
** pointer is used, PCM parameter maintained in
** the control block will be used; otherwise update
** control block value.
-** err_data_rpt: Lisbon feature to enable the erronous data report
+** err_data_rpt: Lisbon feature to enable the erroneous data report
** or not.
**
** Returns BTM_SUCCESS if the successful.
@@ -598,12 +612,12 @@ static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle,
** If so, we cannot use SCO-only packet types (HFP 1.7)
*/
if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr)) {
- temp_pkt_types &= ~(BTM_SCO_PKT_TYPE_MASK);
+ temp_pkt_types &= ~(BTM_SCO_LINK_ONLY_MASK);
BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)", __FUNCTION__,
temp_pkt_types);
/* Return error if no packet types left */
- if (temp_pkt_types == 0) {
+ if (temp_pkt_types == BTM_SCO_EXCEPTION_PKTS_MASK) {
BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",__FUNCTION__);
return (BTM_WRONG_MODE);
}
@@ -947,7 +961,7 @@ void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type)
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
/*
* If the sco state is in the SCO_ST_CONNECTING state, we still need
- * to return accept sco to avoid race conditon for sco creation
+ * to return accept sco to avoid race condition for sco creation
*/
int rem_bd_matches = p->rem_bd_known &&
!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
@@ -1032,7 +1046,6 @@ void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle,
tBTM_CHG_ESCO_PARAMS parms;
#endif
- btm_cb.sco_cb.sco_disc_reason = hci_status;
BTM_TRACE_API("%s, handle %x", __FUNCTION__, hci_handle);
#if (BTM_MAX_SCO_LINKS>0)
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
@@ -1203,21 +1216,16 @@ void btm_remove_sco_links (BD_ADDR bda)
** Returns void
**
*******************************************************************************/
-void btm_sco_removed (UINT16 hci_handle, UINT8 reason)
+BOOLEAN btm_sco_removed (UINT16 hci_handle, UINT8 reason)
{
#if (BTM_MAX_SCO_LINKS>0)
tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
UINT16 xx;
-#endif
-
- btm_cb.sco_cb.sco_disc_reason = reason;
-#if (BTM_MAX_SCO_LINKS>0)
p = &btm_cb.sco_cb.sco_db[0];
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle)) {
btm_sco_flush_sco_data(xx);
-
p->state = SCO_ST_UNUSED;
#if BTM_SCO_HCI_INCLUDED == TRUE
btm_cb.sco_cb.xmit_window_size += p->sent_not_acked;
@@ -1232,10 +1240,11 @@ void btm_sco_removed (UINT16 hci_handle, UINT8 reason)
p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
(*p->p_disc_cb)(xx);
- return;
+ return TRUE;
}
}
#endif
+ return FALSE;
}
@@ -1361,24 +1370,6 @@ UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
/*******************************************************************************
**
-** Function BTM_ReadScoDiscReason
-**
-** Description This function is returns the reason why an (e)SCO connection
-** has been removed. It contains the value until read, or until
-** another (e)SCO connection has disconnected.
-**
-** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
-**
-*******************************************************************************/
-UINT16 BTM_ReadScoDiscReason (void)
-{
- UINT16 res = btm_cb.sco_cb.sco_disc_reason;
- btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
- return (res);
-}
-
-/*******************************************************************************
-**
** Function BTM_ReadDeviceScoPacketTypes
**
** Description This function is read the SCO packet types that
@@ -1878,10 +1869,6 @@ UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx)
{
return ((UINT8 *) NULL);
}
-UINT16 BTM_ReadScoDiscReason (void)
-{
- return (BTM_INVALID_SCO_DISC_REASON);
-}
tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
{
return (BTM_MODE_UNSUPPORTED);
diff --git a/lib/bt/host/bluedroid/stack/btm/btm_sec.c b/lib/bt/host/bluedroid/stack/btm/btm_sec.c
index ca5f99e1..3ed5d4b1 100644
--- a/lib/bt/host/bluedroid/stack/btm/btm_sec.c
+++ b/lib/bt/host/bluedroid/stack/btm/btm_sec.c
@@ -1001,12 +1001,12 @@ tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
return (BTM_SUCCESS);
}
+#if (CLASSIC_BT_INCLUDED == TRUE)
/* Tell controller to get rid of the link key if it has one stored */
if ((BTM_DeleteStoredLinkKey (bd_addr, NULL)) != BTM_SUCCESS) {
return (BTM_NO_RESOURCES);
}
-#if (CLASSIC_BT_INCLUDED == TRUE)
/* Save the PIN code if we got a valid one */
if (p_pin && (pin_len <= PIN_CODE_LEN) && (pin_len != 0)) {
btm_cb.pin_code_len = pin_len;
@@ -1720,7 +1720,7 @@ void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c, BT_O
btsnd_hcic_rem_oob_reply (bd_addr, c, r);
}
}
-
+#if 0
/*******************************************************************************
**
** Function BTM_BuildOobData
@@ -1745,8 +1745,10 @@ UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c,
UINT8 *p = p_data;
UINT16 len = 0;
#if BTM_MAX_LOC_BD_NAME_LEN > 0
+#if (CLASSIC_BT_INCLUDED == TRUE)
UINT16 name_size;
UINT8 name_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#endif
if (p_data && max_len >= BTM_OOB_MANDATORY_SIZE) {
@@ -1789,6 +1791,7 @@ UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c,
max_len -= delta;
}
#if BTM_MAX_LOC_BD_NAME_LEN > 0
+#if (CLASSIC_BT_INCLUDED == TRUE)
name_size = name_len;
if (name_size > strlen(btm_cb.cfg.bredr_bd_name)) {
name_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
@@ -1802,6 +1805,7 @@ UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c,
len += delta;
max_len -= delta;
}
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#endif
/* update len */
p = p_data;
@@ -1871,6 +1875,7 @@ UINT8 *BTM_ReadOobData(UINT8 *p_data, UINT8 eir_tag, UINT8 *p_len)
return p_ret;
}
+#endif
#endif ///BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
#if (CLASSIC_BT_INCLUDED == TRUE)
@@ -4589,10 +4594,10 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason)
** Description This function is when a connection to the peer device is
** dropped
**
-** Returns void
+** Returns tBTM_SEC_DEV_REC is not NULL
**
*******************************************************************************/
-void btm_sec_disconnected (UINT16 handle, UINT8 reason)
+BOOLEAN btm_sec_disconnected (UINT16 handle, UINT8 reason)
{
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
UINT8 old_pairing_flags = btm_cb.pairing_flags;
@@ -4608,7 +4613,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
#endif
if (!p_dev_rec) {
- return;
+ return FALSE;
}
p_dev_rec->enc_init_by_we = FALSE;
transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE;
@@ -4649,7 +4654,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
if (p_dev_rec->sec_state == BTM_SEC_STATE_DISCONNECTING_BOTH) {
p_dev_rec->sec_state = (transport == BT_TRANSPORT_LE) ?
BTM_SEC_STATE_DISCONNECTING : BTM_SEC_STATE_DISCONNECTING_BLE;
- return;
+ return TRUE;
}
#endif
p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
@@ -4685,6 +4690,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
p_dev_rec->sec_bd_name, result);
}
}
+ return TRUE;
}
/*******************************************************************************
diff --git a/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h
index 0f8888fb..de25c6fa 100644
--- a/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h
+++ b/lib/bt/host/bluedroid/stack/btm/include/btm_ble_int.h
@@ -212,11 +212,14 @@ typedef struct {
#define BTM_BLE_MAX_BG_CONN_DEV_NUM 10
typedef struct {
+ UINT16 scan_interval;
+ UINT16 scan_window;
UINT16 min_conn_int;
UINT16 max_conn_int;
UINT16 slave_latency;
UINT16 supervision_tout;
-
+ UINT16 min_ce_len;
+ UINT16 max_ce_len;
} tBTM_LE_CONN_PRAMS;
@@ -339,10 +342,10 @@ typedef struct {
tBTM_INQ_RESULTS_CB *p_scan_results_cb;
tBTM_CMPL_CB *p_scan_cmpl_cb;
TIMER_LIST_ENT scan_timer_ent;
-
+#if (BLE_42_SCAN_EN == TRUE)
struct pkt_queue *adv_rpt_queue;
struct osi_event *adv_rpt_ready;
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
/* background connection procedure cb value */
tBTM_BLE_CONN_TYPE bg_conn_type;
UINT32 scan_int;
@@ -350,6 +353,10 @@ typedef struct {
tBTM_BLE_SEL_CBACK *p_select_cback;
/* white list information */
UINT8 white_list_avail_size;
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+ /* periodic list information */
+ UINT8 periodic_adv_list_size;
+#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE)
tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb;
tBTM_BLE_WL_STATE wl_state;
@@ -377,6 +384,8 @@ typedef struct {
tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */
UINT8 link_count[2]; /* total link count master and slave*/
tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *update_exceptional_list_cmp_cb;
+ tBTM_SET_CSA_SUPPORT_CMPL_CBACK *set_csa_support_cmpl_cb;
+ tBTM_SET_VENDOR_EVT_MASK_CBACK *set_vendor_evt_mask_cmpl_cb;
} tBTM_BLE_CB;
#ifdef __cplusplus
@@ -384,12 +393,14 @@ extern "C" {
#endif
void btm_ble_timeout(TIMER_LIST_ENT *p_tle);
+#if (BLE_42_SCAN_EN == TRUE)
void btm_ble_process_adv_pkt (UINT8 *p);
void btm_ble_process_adv_discard_evt(UINT8 *p);
void btm_ble_process_direct_adv_pkt (UINT8 *p);
bool btm_ble_adv_pkt_ready(void);
bool btm_ble_adv_pkt_post(pkt_linked_item_t *pkt);
void btm_ble_proc_scan_rsp_rpt (UINT8 *p);
+#endif // #if (BLE_42_SCAN_EN == TRUE)
tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur, tBTM_CMPL_CB *p_cb);
BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda);
@@ -405,7 +416,11 @@ void btm_ble_init (void);
void btm_ble_free (void);
void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched);
void btm_ble_read_remote_features_complete(UINT8 *p);
+
+#if (BLE_42_ADV_EN == TRUE)
void btm_ble_write_adv_enable_complete(UINT8 *p);
+#endif // #if (BLE_42_ADV_EN == TRUE)
+
void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced);
void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len);
tBTM_BLE_CONN_ST btm_ble_get_conn_st(void);
@@ -455,9 +470,12 @@ void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len);
void btm_ble_clear_white_list_complete(UINT8 *p, UINT16 evt_len);
void btm_ble_white_list_init(UINT8 white_list_size);
+#if (tGATT_BG_CONN_DEV == TRUE)
/* background connection function */
BOOLEAN btm_ble_suspend_bg_conn(void);
BOOLEAN btm_ble_resume_bg_conn(void);
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
+
void btm_ble_initiate_select_conn(BD_ADDR bda);
BOOLEAN btm_ble_start_auto_conn(BOOLEAN start);
BOOLEAN btm_ble_start_select_conn(BOOLEAN start, tBTM_BLE_SEL_CBACK *p_select_cback);
@@ -500,12 +518,14 @@ void btm_ble_add_default_entry_to_resolving_list(void);
void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len);
#endif
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst);
void btm_ble_multi_adv_init(void);
void *btm_ble_multi_adv_get_ref(UINT8 inst_id);
void btm_ble_multi_adv_cleanup(void);
void btm_ble_multi_adv_reenable(UINT8 inst_id);
void btm_ble_multi_adv_enb_privacy(BOOLEAN enable);
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
char btm_ble_map_adv_tx_power(int tx_power_index);
void btm_ble_batchscan_init(void);
void btm_ble_batchscan_cleanup(void);
@@ -536,12 +556,57 @@ void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params);
void btm_ble_periodic_adv_report_evt(tBTM_PERIOD_ADV_REPORT *params);
void btm_ble_periodic_adv_sync_lost_evt(tBTM_BLE_PERIOD_ADV_SYNC_LOST *params);
void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *params);
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+void btm_ble_periodic_adv_list_init(UINT8 periodic_adv_size);
+#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV *params);
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+void btm_ble_cis_established_evt(tBTM_BLE_CIS_ESTABLISHED_CMPL *params);
+void btm_ble_cis_disconnected_evt(tBTM_BLE_CIS_DISCON_CMPL *params);
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+void btm_ble_iso_read_iso_tx_sync_complete(UINT8 *p);
+void btm_ble_iso_read_iso_link_quality_complete(UINT8 *p);
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+void btm_ble_cis_request_evt(tBTM_BLE_CIS_REQUEST_CMPL *params);
+void btm_ble_accept_cis_req_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params);
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+void btm_ble_create_cis_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params);
+void btm_ble_iso_set_cig_params_complete(UINT8 *p);
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *param);
+void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *params);
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params);
+void btm_ble_big_sync_lost_evt(tBTM_BLE_BIG_SYNC_LOST_EVT *params);
+void btm_ble_biginfo_adv_report_evt(tBTM_BLE_BIGINFO_ADV_REPORT_EVT *params);
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+void btm_ble_iso_data_path_update_complete(UINT16 opcode, UINT8 hci_status, UINT16 conn_handle);
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+void btm_ble_cte_read_ant_infor_complete(UINT8 *p);
+void btm_ble_connless_iq_report_evt(tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT *params);
+void btm_ble_conn_iq_report_evt(tBTM_BLE_CTE_CONN_IQ_REPORT_EVT *params);
+void btm_ble_cte_req_failed_evt(tBTM_BLE_CTE_REQ_FAILED_EVT *params);
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void btm_ble_path_loss_threshold_evt(tBTM_BLE_PATH_LOSS_THRESHOLD_EVT *params);
+void btm_ble_transmit_power_report_evt(tBTM_BLE_TRANS_POWER_REPORT_EVT *params);
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void btm_ble_subrate_change_evt(tBTM_BLE_SUBRATE_CHANGE_EVT *params);
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
/*
#ifdef __cplusplus
}
diff --git a/lib/bt/host/bluedroid/stack/btm/include/btm_int.h b/lib/bt/host/bluedroid/stack/btm/include/btm_int.h
index 3d01a5c2..d5b69c68 100644
--- a/lib/bt/host/bluedroid/stack/btm/include/btm_int.h
+++ b/lib/bt/host/bluedroid/stack/btm/include/btm_int.h
@@ -43,13 +43,12 @@ typedef struct tBTM_SEC_DEV_REC tBTM_SEC_DEV_REC;
#include "stack/smp_api.h"
#endif
-#define ESP_VS_REM_LEGACY_AUTH_CMP 0x03
-
#if BTM_MAX_LOC_BD_NAME_LEN > 0
typedef char tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1];
#endif
#define BTM_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_BR_EDR) != NULL)
+#define BTM_LE_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_LE) != NULL)
/* Definitions for Server Channel Number (SCN) management
*/
@@ -192,6 +191,10 @@ tBTM_CMPL_CB *p_rln_cmpl_cb; /* Callback function to be called when
TIMER_LIST_ENT rssi_timer;
tBTM_CMPL_CB *p_rssi_cmpl_cb; /* Callback function to be called when */
/* read rssi function completes */
+
+tBTM_CMPL_CB *p_ble_ch_map_cmpl_cb; /* Callback function to be called when */
+/* read channel map function completes */
+
TIMER_LIST_ENT lnk_quality_timer;
tBTM_CMPL_CB *p_lnk_qual_cmpl_cb;/* Callback function to be called when */
/* read link quality function completes */
@@ -207,8 +210,10 @@ tBTM_ROLE_SWITCH_CMPL switch_role_ref_data;
tBTM_CMPL_CB *p_switch_role_cb; /* Callback function to be called when */
/* requested switch role is completed */
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
TIMER_LIST_ENT tx_power_timer;
tBTM_CMPL_CB *p_tx_power_cmpl_cb;/* Callback function to be called */
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
#if CLASSIC_BT_INCLUDED == TRUE
TIMER_LIST_ENT afh_channels_timer;
@@ -469,7 +474,6 @@ typedef struct {
tSCO_CONN sco_db[BTM_MAX_SCO_LINKS];
tBTM_ESCO_PARAMS def_esco_parms;
BD_ADDR xfer_addr;
- UINT16 sco_disc_reason;
BOOLEAN esco_supported; /* TRUE if 1.2 cntlr AND supports eSCO links */
tBTM_SCO_TYPE desired_sco_mode;
tBTM_SCO_TYPE xfer_sco_type;
@@ -724,14 +728,18 @@ struct tBTM_SEC_DEV_REC{
*/
typedef struct {
#if BTM_MAX_LOC_BD_NAME_LEN > 0
+#if (CLASSIC_BT_INCLUDED == TRUE)
tBTM_LOC_BD_NAME bredr_bd_name; /* local BREDR device name */
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
tBTM_LOC_BD_NAME ble_bd_name; /* local BLE device name */
#endif
+#if (CLASSIC_BT_INCLUDED == TRUE)
BOOLEAN pin_type; /* TRUE if PIN type is fixed */
UINT8 pin_code_len; /* Bonding information */
PIN_CODE pin_code; /* PIN CODE if pin type is fixed */
- BOOLEAN connectable; /* If TRUE page scan should be enabled */
- UINT8 def_inq_scan_mode; /* ??? limited/general/none */
+ // BOOLEAN connectable; /* If TRUE page scan should be enabled */
+ // UINT8 def_inq_scan_mode; /* ??? limited/general/none */
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
} tBTM_CFG;
enum {
@@ -885,6 +893,7 @@ typedef struct {
UINT16 ediv; /* received ediv value from LTK request */
UINT8 key_size;
tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+ BOOLEAN addr_res_en; /* internal use for test: address resolution enable/disable */
#endif
/* Packet types supported by the local device */
@@ -951,7 +960,7 @@ typedef struct {
#endif // SMP_INCLUDED == TRUE || BT_CLASSIC_ENABLED == TRUE
list_t *p_sec_dev_rec_list;
tBTM_SEC_SERV_REC *p_out_serv;
- tBTM_MKEY_CALLBACK *mkey_cback;
+ // tBTM_MKEY_CALLBACK *mkey_cback;
BD_ADDR connecting_bda;
DEV_CLASS connecting_dc;
@@ -1063,6 +1072,7 @@ void btm_cont_rswitch (tACL_CONN *p,
tACL_CONN *btm_handle_to_acl (UINT16 hci_handle);
void btm_read_link_policy_complete (UINT8 *p);
void btm_read_rssi_complete (UINT8 *p);
+void btm_read_channel_map_complete (UINT8 *p);
void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble);
void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types);
void btm_read_link_quality_complete (UINT8 *p);
@@ -1113,17 +1123,29 @@ void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
void btm_ble_periodic_adv_sync_trans_complete(UINT16 op_code, UINT8 hci_status, UINT16 conn_handle);
#endif
+void btm_ble_big_sync_terminate_complete(UINT8 hci_status, UINT8 big_handle);
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void btm_enh_read_trans_pwr_level_cmpl_evt(uint8_t *p);
+void btm_read_remote_trans_pwr_level_cmpl(UINT8 status);
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void btm_subrate_req_cmd_status(UINT8 status);
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
/* Internal functions provided by btm_sco.c
********************************************
*/
void btm_sco_init (void);
+void btm_sco_free(void);
void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle,
tBTM_ESCO_DATA *p_esco_data);
void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval,
UINT8 retrans_window, UINT16 rx_pkt_len,
UINT16 tx_pkt_len);
void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type);
-void btm_sco_removed (UINT16 hci_handle, UINT8 reason);
+BOOLEAN btm_sco_removed (UINT16 hci_handle, UINT8 reason);
void btm_sco_acl_removed (BD_ADDR bda);
void btm_route_sco_data (BT_HDR *p_msg);
BOOLEAN btm_is_sco_active (UINT16 handle);
@@ -1203,7 +1225,7 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status);
void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable);
void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode);
tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason);
-void btm_sec_disconnected (UINT16 handle, UINT8 reason);
+BOOLEAN btm_sec_disconnected (UINT16 handle, UINT8 reason);
void btm_sec_rmt_name_request_complete (UINT8 *bd_addr, UINT8 *bd_name, UINT8 status);
void btm_sec_rmt_host_support_feat_evt (UINT8 *p);
void btm_io_capabilities_req (UINT8 *p);
diff --git a/lib/bt/host/bluedroid/stack/btu/btu_hcif.c b/lib/bt/host/bluedroid/stack/btu/btu_hcif.c
index 30e76125..eb2995b9 100644
--- a/lib/bt/host/bluedroid/stack/btu/btu_hcif.c
+++ b/lib/bt/host/bluedroid/stack/btu/btu_hcif.c
@@ -55,6 +55,7 @@ extern void btm_ble_test_command_complete(UINT8 *p);
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_inquiry_comp_evt (UINT8 *p);
static void btu_hcif_inquiry_result_evt (UINT8 *p);
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p);
@@ -62,30 +63,46 @@ static void btu_hcif_extended_inquiry_result_evt (UINT8 *p);
static void btu_hcif_connection_comp_evt (UINT8 *p);
static void btu_hcif_connection_request_evt (UINT8 *p);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_disconnection_comp_evt (UINT8 *p);
#if (SMP_INCLUDED == TRUE)
static void btu_hcif_authentication_comp_evt (UINT8 *p);
#endif ///SMP_INCLUDED == TRUE
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#if (SMP_INCLUDED == TRUE)
static void btu_hcif_encryption_change_evt (UINT8 *p);
#endif ///SMP_INCLUDED == TRUE
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_read_rmt_features_comp_evt (UINT8 *p);
static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p);
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_qos_setup_comp_evt (UINT8 *p);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_command_complete_evt (BT_HDR *response, void *context);
static void btu_hcif_command_status_evt (uint8_t status, BT_HDR *command, void *context);
static void btu_hcif_hardware_error_evt (UINT8 *p);
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_flush_occured_evt (void);
static void btu_hcif_role_change_evt (UINT8 *p);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p);
+
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_mode_change_evt (UINT8 *p);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
+
#if (SMP_INCLUDED == TRUE)
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_pin_code_request_evt (UINT8 *p);
static void btu_hcif_link_key_request_evt (UINT8 *p);
static void btu_hcif_link_key_notification_evt (UINT8 *p);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#endif ///SMP_INCLUDED == TRUE
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_loopback_command_evt (void);
static void btu_hcif_data_buf_overflow_evt (void);
static void btu_hcif_max_slots_changed_evt (void);
@@ -98,6 +115,8 @@ static void btu_hcif_esco_connection_comp_evt(UINT8 *p);
static void btu_hcif_esco_connection_chg_evt(UINT8 *p);
static void btu_hcif_host_support_evt (UINT8 *p);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
+
/* Simple Pairing Events */
#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_io_cap_request_evt (UINT8 *p);
@@ -111,12 +130,14 @@ static void btu_hcif_keypress_notif_evt (UINT8 *p);
#if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
static void btu_hcif_rem_oob_request_evt (UINT8 *p);
#endif
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_link_supv_to_changed_evt (UINT8 *p);
#if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE
static void btu_hcif_enhanced_flush_complete_evt (void);
#endif
static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len);
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#if BLE_INCLUDED == TRUE
static void btu_ble_ll_conn_complete_evt (UINT8 *p, UINT16 evt_len);
@@ -136,29 +157,91 @@ static void btu_ble_proc_enhanced_conn_cmpl (UINT8 *p, UINT16 evt_len);
//#endif
#if (BLE_50_FEATURE_SUPPORT == TRUE)
static void btu_ble_phy_update_complete_evt(UINT8 *p);
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len);
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p);
static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len);
static void btu_ble_periodic_adv_sync_lost_evt(UINT8 *p);
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
static void btu_ble_scan_timeout_evt(UINT8 *p);
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
static void btu_ble_adv_set_terminate_evt(UINT8 *p);
static void btu_ble_scan_req_received_evt(UINT8 *p);
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+static void btu_ble_channel_select_alg_evt(UINT8 *p);
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p);
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+void btu_ble_create_big_cmd_status(UINT8 status);
+static void btu_ble_big_create_complete_evt(UINT8 *p);
+void btu_ble_big_terminate_cmd_status(UINT8 status);
+static void btu_ble_big_terminate_complete_evt(UINT8 *p);
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+static void btu_ble_create_big_sync_cmd_status(UINT8 status);
+static void btu_ble_big_sync_establish_evt(UINT8 *p);
+static void btu_ble_big_sync_lost_evt(UINT8 *p);
+static void btu_ble_biginfo_adv_report_evt(UINT8 *p);
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+static void btu_ble_create_cis_cmd_status(UINT8 status);
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+static void btu_ble_accept_cis_req_cmd_status(UINT8 status);
+static void btu_ble_cis_request_evt(UINT8 *p);
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+static void btu_ble_cis_established_evt(UINT8 *p);
+static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason);
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+static void btu_ble_cte_connless_iq_report_evt(UINT8 *p);
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+static void btu_ble_cte_conn_iq_report_evt(UINT8 *p);
+static void btu_ble_cte_req_failed_evt(UINT8 *p);
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+static void btu_ble_path_loss_threshold_evt(UINT8 *p);
+static void btu_ble_transmit_power_report_evt(UINT8 *p);
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+static void btu_ble_subrate_change_evt(UINT8 *p);
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_42_ADV_EN == TRUE)
extern osi_sem_t adv_enable_sem;
extern osi_sem_t adv_data_sem;
extern osi_sem_t adv_param_sem;
-extern osi_sem_t scan_enable_sem;
-extern osi_sem_t scan_param_sem;
extern uint8_t adv_enable_status;
extern uint8_t adv_data_status;
extern uint8_t adv_param_status;
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
+extern osi_sem_t scan_enable_sem;
+extern osi_sem_t scan_param_sem;
extern uint8_t scan_enable_status;
extern uint8_t scan_param_status;
-
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#endif
/*******************************************************************************
@@ -182,6 +265,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
STREAM_TO_UINT8 (hci_evt_len, p);
switch (hci_evt_code) {
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_INQUIRY_COMP_EVT:
btu_hcif_inquiry_comp_evt (p);
break;
@@ -200,6 +284,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_CONNECTION_REQUEST_EVT:
btu_hcif_connection_request_evt (p);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_DISCONNECTION_COMP_EVT:
btu_hcif_disconnection_comp_evt (p);
break;
@@ -208,9 +293,11 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
btu_hcif_authentication_comp_evt (p);
#endif ///SMP_INCLUDED == TRUE
break;
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_RMT_NAME_REQUEST_COMP_EVT:
btu_hcif_rmt_name_request_comp_evt (p, hci_evt_len);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_ENCRYPTION_CHANGE_EVT:
#if (SMP_INCLUDED == TRUE)
btu_hcif_encryption_change_evt (p);
@@ -223,18 +310,22 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
#endif ///SMP_INCLUDED == TRUE
break;
#endif
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_READ_RMT_FEATURES_COMP_EVT:
btu_hcif_read_rmt_features_comp_evt (p);
break;
case HCI_READ_RMT_EXT_FEATURES_COMP_EVT:
btu_hcif_read_rmt_ext_features_comp_evt (p);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_READ_RMT_VERSION_COMP_EVT:
btu_hcif_read_rmt_version_comp_evt (p);
break;
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_QOS_SETUP_COMP_EVT:
btu_hcif_qos_setup_comp_evt (p);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_COMMAND_COMPLETE_EVT:
//HCI_TRACE_ERROR("%s should not have received a command complete event. "
// "Someone didn't go through the hci transmit_command function.", __func__);
@@ -246,19 +337,24 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_HARDWARE_ERROR_EVT:
btu_hcif_hardware_error_evt (p);
break;
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_FLUSH_OCCURED_EVT:
btu_hcif_flush_occured_evt ();
break;
case HCI_ROLE_CHANGE_EVT:
btu_hcif_role_change_evt (p);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_NUM_COMPL_DATA_PKTS_EVT:
btu_hcif_num_compl_data_pkts_evt (p);
break;
+ #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_MODE_CHANGE_EVT:
btu_hcif_mode_change_evt (p);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#if (SMP_INCLUDED == TRUE)
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_PIN_CODE_REQUEST_EVT:
btu_hcif_pin_code_request_evt (p);
break;
@@ -268,7 +364,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_LINK_KEY_NOTIFICATION_EVT:
btu_hcif_link_key_notification_evt (p);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#endif ///SMP_INCLUDED == TRUE
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_LOOPBACK_COMMAND_EVT:
btu_hcif_loopback_command_evt ();
break;
@@ -305,7 +403,6 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT:
btu_hcif_host_support_evt (p);
break;
-#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_IO_CAPABILITY_REQUEST_EVT:
btu_hcif_io_cap_request_evt (p);
break;
@@ -334,7 +431,6 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_KEYPRESS_NOTIFY_EVT:
btu_hcif_keypress_notif_evt (p);
break;
-#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
case HCI_LINK_SUPER_TOUT_CHANGED_EVT:
btu_hcif_link_supv_to_changed_evt (p);
break;
@@ -343,6 +439,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
btu_hcif_enhanced_flush_complete_evt ();
break;
#endif
+#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
#if (BLE_INCLUDED == TRUE)
case HCI_BLE_EVENT:
@@ -388,10 +485,13 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_BLE_PHY_UPDATE_COMPLETE_EVT:
btu_ble_phy_update_complete_evt(p);
break;
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
case HCI_BLE_EXT_ADV_REPORT_EVT:
//HCI_TRACE_ERROR("%s, HCI_BLE_EXT_ADV_REPORT_EVT.", __func__);
btu_ble_ext_adv_report_evt(p, hci_evt_len);
break;
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
case HCI_BLE_PERIOD_ADV_SYNC_ESTAB_EVT:
btu_ble_periodic_adv_sync_establish_evt(p);
break;
@@ -401,16 +501,22 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_BLE_PERIOD_ADV_SYNC_LOST_EVT:
btu_ble_periodic_adv_sync_lost_evt(p);
break;
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
case HCI_BLE_SCAN_TIMEOUT_EVT:
btu_ble_scan_timeout_evt(p);
break;
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case HCI_BLE_ADV_SET_TERMINATED_EVT:
btu_ble_adv_set_terminate_evt(p);
break;
case HCI_BLE_SCAN_REQ_RECEIVED_EVT:
btu_ble_scan_req_received_evt(p);
break;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
case HCI_BLE_CHANNEL_SELECT_ALG:
+ btu_ble_channel_select_alg_evt(p);
break;
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
@@ -418,6 +524,68 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
btu_ble_periodic_adv_sync_trans_recv(p);
break;
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ case HCI_BLE_CIS_ESTABLISHED_V1_EVT:
+ case HCI_BLE_CIS_ESTABLISHED_V2_EVT:
+ btu_ble_cis_established_evt(p);
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ case HCI_BLE_CIS_REQUEST_EVT:
+ btu_ble_cis_request_evt(p);
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ case HCI_BLE_BIG_CREATE_COMPLETE_EVT:
+ btu_ble_big_create_complete_evt(p);
+ break;
+ case HCI_BLE_BIG_TERMINATE_COMPLETE_EVT:
+ btu_ble_big_terminate_complete_evt(p);
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case HCI_BLE_BIG_SYNC_ESTABLISHED_EVT:
+ btu_ble_big_sync_establish_evt(p);
+ break;
+ case HCI_BLE_BIG_SYNC_LOST_EVT:
+ btu_ble_big_sync_lost_evt(p);
+ break;
+ case HCI_BLE_BIGINFO_ADV_REPORT_EVT:
+ btu_ble_biginfo_adv_report_evt(p);
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ case HCI_BLE_CONNLESS_IQ_REPORT_EVT:
+ btu_ble_cte_connless_iq_report_evt(p);
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ case HCI_BLE_CONN_IQ_REPORT_EVT:
+ btu_ble_cte_conn_iq_report_evt(p);
+ break;
+ case HCI_BLE_CTE_REQUEST_FAILED_EVT:
+ btu_ble_cte_req_failed_evt(p);
+ break;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ case HCI_BLE_PATH_LOSS_THRESHOLD_EVT:
+ btu_ble_path_loss_threshold_evt(p);
+ break;
+ case HCI_BLE_TRANS_POWER_REPORTING_EVT:
+ btu_ble_transmit_power_report_evt(p);
+ break;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ case HCI_BLE_SUBRATE_CHANGE_EVT:
+ btu_ble_subrate_change_evt(p);
+ break;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
}
break;
#endif /* BLE_INCLUDED */
@@ -559,7 +727,7 @@ void btu_hcif_send_host_rdy_for_data(void)
btsnd_hcic_host_num_xmitted_pkts (num_ents, handles, num_pkts);
}
}
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_inquiry_comp_evt
@@ -687,7 +855,7 @@ static void btu_hcif_connection_request_evt (UINT8 *p)
}
#endif /* BTM_SCO_INCLUDED */
}
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -702,6 +870,7 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p)
{
UINT16 handle;
UINT8 reason;
+ BOOLEAN dev_find = FALSE;
++p;
STREAM_TO_UINT16 (handle, p);
@@ -709,9 +878,18 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p)
handle = HCID_GET_HANDLE (handle);
- btm_acl_disconnected(handle, reason);
+ dev_find = btm_acl_disconnected(handle, reason);
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ // Not find device. it is iso handle
+ if (!dev_find) {
+ btu_ble_cis_disconnected(handle, reason);
+ }
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
- HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x", handle, reason);
+ HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x dev_find %d", handle, reason, dev_find);
+
+ UNUSED(dev_find);
}
/*******************************************************************************
@@ -736,6 +914,7 @@ static void btu_hcif_authentication_comp_evt (UINT8 *p)
}
#endif ///SMP_INCLUDED == TRUE
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_rmt_name_request_comp_evt
@@ -760,7 +939,7 @@ static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len)
btm_sec_rmt_name_request_complete (bd_addr, p, status);
#endif ///SMP_INCLUDED == TRUE
}
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -786,7 +965,7 @@ static void btu_hcif_encryption_change_evt (UINT8 *p)
btm_sec_encrypt_change (handle, status, encr_enable);
}
#endif ///SMP_INCLUDED == TRUE
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_read_rmt_features_comp_evt
@@ -825,6 +1004,7 @@ static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p)
btm_read_remote_ext_features_failed(status, handle);
}
}
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -840,7 +1020,7 @@ static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p)
btm_read_remote_version_complete (p);
}
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_qos_setup_comp_evt
@@ -934,6 +1114,7 @@ static void btu_hcif_esco_connection_chg_evt (UINT8 *p)
rx_pkt_len, tx_pkt_len);
#endif
}
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -949,6 +1130,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
{
uint8_t status;
switch (opcode) {
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_INQUIRY_CANCEL:
/* Tell inquiry processing that we are done */
btm_process_cancel_complete(HCI_SUCCESS, BTM_BR_INQUIRY_MASK);
@@ -961,37 +1143,39 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
btm_delete_stored_link_key_complete (p);
break;
- case HCI_READ_LOCAL_NAME:
- btm_read_local_name_complete (p, evt_len);
- break;
-
case HCI_GET_LINK_QUALITY:
btm_read_link_quality_complete (p);
break;
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
+ case HCI_READ_LOCAL_NAME:
+ btm_read_local_name_complete (p, evt_len);
+ break;
case HCI_READ_RSSI:
btm_read_rssi_complete (p);
break;
-
+ case HCI_BLE_READ_CHNL_MAP:
+ btm_read_channel_map_complete (p);
+ break;
case HCI_READ_TRANSMIT_POWER_LEVEL:
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
btm_read_tx_power_complete(p, FALSE);
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
break;
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_CREATE_CONNECTION_CANCEL:
btm_create_conn_cancel_complete(p);
break;
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_READ_LOCAL_OOB_DATA:
#if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
btm_read_local_oob_complete(p);
#endif
break;
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_READ_INQ_TX_POWER_LEVEL:
btm_read_linq_tx_power_complete (p);
break;
-#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_SET_AFH_CHANNELS:
btm_set_afh_channels_complete(p);
break;
@@ -1055,22 +1239,26 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
break;
case HCI_BLE_READ_ADV_CHNL_TX_POWER:
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
btm_read_tx_power_complete(p, TRUE);
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
break;
-
+#if (BLE_42_ADV_EN == TRUE)
case HCI_BLE_WRITE_ADV_ENABLE:
btm_ble_write_adv_enable_complete(p);
break;
-
+#endif // #if (BLE_42_ADV_EN == TRUE)
case HCI_BLE_CREATE_LL_CONN:
btm_ble_create_ll_conn_complete(*p);
break;
case HCI_BLE_TRANSMITTER_TEST:
case HCI_BLE_RECEIVER_TEST:
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
case HCI_BLE_TEST_END:
btm_ble_test_command_complete(p);
break;
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
case HCI_BLE_CREATE_CONN_CANCEL:
btm_ble_create_conn_cancel_complete(p);
break;
@@ -1105,6 +1293,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
break;
#endif // #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
case HCI_BLE_SET_EXT_ADV_PARAM:
case HCI_BLE_SET_EXT_ADV_DATA:
case HCI_BLE_SET_EXT_SCAN_RSP_DATA:
@@ -1113,6 +1302,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
HCI_TRACE_EVENT("%s opcode 0x%x status 0x%x", __func__, opcode, status);
break;
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
case HCI_BLE_READ_PHY: {
uint16_t conn_handle;
uint8_t tx_phy;
@@ -1124,11 +1314,14 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
btm_read_phy_callback(status, conn_handle, tx_phy, rx_phy);
break;
}
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
case HCI_BLE_ENH_RX_TEST:
case HCI_BLE_ENH_TX_TEST:
btm_ble_test_command_complete(p);
break;
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
case HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE:
case HCI_BLE_SET_DEFAULT_PAST_PARAMS:
@@ -1143,6 +1336,59 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
break;
}
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case HCI_BLE_BIG_TERMINATE_SYNC:
+ UINT16 big_handle;
+ STREAM_TO_UINT8(status, p);
+ STREAM_TO_UINT8(big_handle, p);
+ btm_ble_big_sync_terminate_complete(status, big_handle);
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case HCI_BLE_ISO_SET_DATA_PATH:
+ case HCI_BLE_ISO_REMOVE_DATA_PATH:
+ UINT16 conn_handle;
+ STREAM_TO_UINT8(status, p);
+ STREAM_TO_UINT16(conn_handle, p);
+ btm_ble_iso_data_path_update_complete(opcode, status, conn_handle);
+ break;
+ case HCI_BLE_ISO_READ_TX_SYNC:
+ btm_ble_iso_read_iso_tx_sync_complete(p);
+ break;
+ case HCI_BLE_ISO_READ_ISO_LINK_QUALITY:
+ btm_ble_iso_read_iso_link_quality_complete(p);
+ break;
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ case HCI_BLE_ISO_SET_CIG_PARAMS:
+ case HCI_BLE_ISO_SET_CIG_PARAMS_TEST:
+ btm_ble_iso_set_cig_params_complete(p);
+ break;
+ case HCI_BLE_ISO_REMOVE_CIG:
+ // do nothing
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ case HCI_BLE_ISO_ACCEPT_CIS_REQ:
+ case HCI_BLE_ISO_REJECT_CIS_REQ:
+ // do nothing
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_CTE_EN == TRUE)
+ case HCI_BLE_READ_ANT_INFOR:
+ btm_ble_cte_read_ant_infor_complete(p);
+ break;
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ case HCI_BLE_ENH_READ_TRANS_POWER_LEVEL:
+ btm_enh_read_trans_pwr_level_cmpl_evt(p);
+ break;
+#endif //#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
#endif /* (BLE_INCLUDED == TRUE) */
default: {
@@ -1192,6 +1438,7 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context)
uint8_t *stream = response->data + response->offset + 3;
STREAM_TO_UINT16(opcode, stream);
switch (opcode) {
+#if (BLE_42_ADV_EN == TRUE)
case HCI_BLE_WRITE_ADV_DATA:
adv_data_status = *stream;
osi_sem_give(&adv_data_sem);
@@ -1209,6 +1456,8 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context)
adv_param_status = *stream;
osi_sem_give(&adv_param_sem);
break;
+#endif // #if (BLE_42_ADV_EN == TRUE)
+#if (BLE_42_SCAN_EN == TRUE)
case HCI_BLE_WRITE_SCAN_PARAMS:
scan_param_status = *stream;
osi_sem_give(&scan_param_sem);
@@ -1217,6 +1466,7 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context)
scan_enable_status = *stream;
osi_sem_give(&scan_enable_sem);
break;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
default:
break;
}
@@ -1265,6 +1515,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
#endif
switch (opcode) {
+#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_EXIT_SNIFF_MODE:
case HCI_EXIT_PARK_MODE:
#if BTM_SCO_WAKE_PARKED_LINK == TRUE
@@ -1284,7 +1535,9 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
case HCI_PARK_MODE:
btm_pm_proc_cmd_status(status);
break;
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
case HCI_BLE_PERIOD_ADV_CREATE_SYNC:
{
uint8_t btm_status = BTM_SUCCESS;
@@ -1295,6 +1548,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
btm_create_sync_callback(btm_status);
break;
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
case HCI_BLE_SET_PHY:
{
uint8_t btm_status = BTM_SUCCESS;
@@ -1306,6 +1560,42 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
break;
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ case HCI_BLE_CREATE_BIG:
+ case HCI_BLE_CREATE_BIG_TEST:
+ btu_ble_create_big_cmd_status(status);
+ break;
+ case HCI_BLE_TERMINATE_BIG:
+ btu_ble_big_terminate_cmd_status(status);
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ case HCI_BLE_BIG_CREATE_SYNC:
+ btu_ble_create_big_sync_cmd_status(status);
+ break;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ case HCI_BLE_ISO_CREATE_CIS:
+ btu_ble_create_cis_cmd_status(status);
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ case HCI_BLE_ISO_ACCEPT_CIS_REQ:
+ btu_ble_accept_cis_req_cmd_status(status);
+ break;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ case HCI_BLE_READ_REMOTE_TRANS_POWER_LEVEL:
+ btm_read_remote_trans_pwr_level_cmpl(status);
+ break;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ case HCI_BLE_SUBRATE_REQUEST:
+ btm_subrate_req_cmd_status(status);
+ break;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
default:
/* If command failed to start, we may need to tell BTM */
if (status != HCI_SUCCESS) {
@@ -1379,6 +1669,9 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
break;
#if BLE_INCLUDED == TRUE
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ case HCI_BLE_EXT_CREATE_CONN:
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
case HCI_BLE_CREATE_LL_CONN:
btm_ble_create_ll_conn_complete(status);
break;
@@ -1498,7 +1791,7 @@ static void btu_hcif_hardware_error_evt (UINT8 *p)
}
}
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_flush_occured_evt
@@ -1535,7 +1828,7 @@ static void btu_hcif_role_change_evt (UINT8 *p)
l2c_link_role_changed (bda, role, status);
btm_acl_role_changed(status, bda, role);
}
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -1556,7 +1849,7 @@ static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p)
btm_sco_process_num_completed_pkts (p);
#endif
}
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_mode_change_evt
@@ -1624,7 +1917,7 @@ static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len)
HCI_TRACE_WARNING("hcif ssr evt: st 0x%x, hdl 0x%x, tx_lat %d rx_lat %d", status, handle, max_tx_lat, max_rx_lat);
}
-
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_pin_code_request_evt
@@ -1635,6 +1928,7 @@ static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len)
**
*******************************************************************************/
#if (SMP_INCLUDED == TRUE)
+#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_pin_code_request_evt (UINT8 *p)
{
#if (CLASSIC_BT_INCLUDED == TRUE)
@@ -1689,9 +1983,10 @@ static void btu_hcif_link_key_notification_evt (UINT8 *p)
btm_sec_link_key_notification (bda, key, key_type);
}
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#endif ///SMP_INCLUDED == TRUE
-
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_loopback_command_evt
@@ -1867,7 +2162,7 @@ static void btu_hcif_host_support_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
-#if (CLASSIC_BT_INCLUDED == TRUE)
+
static void btu_hcif_io_cap_request_evt (UINT8 *p)
{
btm_io_capabilities_req(p);
@@ -1976,6 +2271,7 @@ static void btu_hcif_rem_oob_request_evt (UINT8 *p)
}
#endif
+#if (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btu_hcif_link_supv_to_changed_evt
@@ -2014,6 +2310,7 @@ static void btu_hcif_enhanced_flush_complete_evt (void)
/* This is empty until an upper layer cares about returning event */
}
#endif
+#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/**********************************************
** End of Simple Pairing Events
***********************************************/
@@ -2133,6 +2430,7 @@ static void btu_ble_phy_update_complete_evt(UINT8 *p)
}
#if BLE_PRIVACY_SPT == TRUE
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
/*******************************************************************************
**
** Function btm_ble_resolve_random_addr_adv_ext
@@ -2153,13 +2451,17 @@ static void btm_ble_resolve_random_addr_adv_ext(void *p_rec, void *p)
BDADDR_TO_STREAM(pp,bda);
}
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
#endif
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
{
tBTM_BLE_EXT_ADV_REPORT ext_adv_report = {0};
UINT8 num_reports = {0};
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
UINT8 *pp = p;
+#endif
//UINT8 legacy_event_type = 0;
UINT16 evt_type = 0;
uint8_t addr_type;
@@ -2233,7 +2535,9 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
}
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p)
{
tBTM_BLE_PERIOD_ADV_SYNC_ESTAB sync_estab = {0};
@@ -2274,7 +2578,7 @@ static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len)
STREAM_TO_UINT16(adv_report.sync_handle, p);
STREAM_TO_UINT8(adv_report.tx_power, p);
STREAM_TO_UINT8(adv_report.rssi, p);
- STREAM_TO_UINT8(unused, p);
+ STREAM_TO_UINT8(adv_report.cte_type, p);
STREAM_TO_UINT8(adv_report.data_status, p);
STREAM_TO_UINT8(adv_report.data_length, p);
@@ -2306,14 +2610,18 @@ static void btu_ble_periodic_adv_sync_lost_evt(UINT8 *p)
btm_ble_periodic_adv_sync_lost_evt(&sync_lost);
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
static void btu_ble_scan_timeout_evt(UINT8 *p)
{
UNUSED(p);
btm_ble_scan_timeout_evt();
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
static void btu_ble_adv_set_terminate_evt(UINT8 *p)
{
tBTM_BLE_ADV_TERMINAT adv_term = {0};
@@ -2346,6 +2654,22 @@ static void btu_ble_scan_req_received_evt(UINT8 *p)
btm_ble_scan_req_received_evt(&req_received);
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+
+static void btu_ble_channel_select_alg_evt(UINT8 *p)
+{
+ tBTM_BLE_CHANNEL_SEL_ALG chan_sel_alg = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT16(chan_sel_alg.conn_handle, p);
+ STREAM_TO_UINT8(chan_sel_alg.channel_sel_alg, p);
+
+ btm_ble_channel_select_algorithm_evt(&chan_sel_alg);
+}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
@@ -2380,6 +2704,384 @@ static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p)
}
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+static void btu_ble_create_cis_cmd_status(UINT8 status)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (status != HCI_SUCCESS) {
+ status = (BTM_HCI_ERROR | status);
+ }
+ cb_params.status = status;
+ btm_ble_create_cis_cmd_status(&cb_params);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+static void btu_ble_accept_cis_req_cmd_status(UINT8 status)
+{
+ tBTM_BLE_ISO_CB_PARAMS cb_params = {0};
+ if (status != HCI_SUCCESS) {
+ status = (BTM_HCI_ERROR | status);
+ }
+ cb_params.status = status;
+
+ btm_ble_accept_cis_req_cmd_status(&cb_params);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason)
+{
+ tBTM_BLE_CIS_DISCON_CMPL cis_disconnected_evt = {0};
+ cis_disconnected_evt.cis_handle = handle;
+ cis_disconnected_evt.reason = reason;
+ btm_ble_cis_disconnected_evt(&cis_disconnected_evt);
+}
+
+static void btu_ble_cis_established_evt(UINT8 *p)
+{
+ HCI_TRACE_DEBUG("%s", __func__);
+ tBTM_BLE_CIS_ESTABLISHED_CMPL cis_estab_evt = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(cis_estab_evt.status, p);
+ STREAM_TO_UINT16(cis_estab_evt.conn_handle, p);
+ STREAM_TO_UINT24(cis_estab_evt.cig_sync_delay, p);
+ STREAM_TO_UINT24(cis_estab_evt.cis_sync_delay, p);
+ STREAM_TO_UINT24(cis_estab_evt.trans_lat_c_to_p, p);
+ STREAM_TO_UINT24(cis_estab_evt.trans_lat_p_to_c, p);
+ STREAM_TO_UINT8(cis_estab_evt.phy_c_to_p, p);
+ STREAM_TO_UINT8(cis_estab_evt.phy_p_to_c, p);
+ STREAM_TO_UINT8(cis_estab_evt.nse, p);
+ STREAM_TO_UINT8(cis_estab_evt.bn_c_to_p, p);
+ STREAM_TO_UINT8(cis_estab_evt.bn_p_to_c, p);
+ STREAM_TO_UINT8(cis_estab_evt.ft_c_to_p, p);
+ STREAM_TO_UINT8(cis_estab_evt.ft_p_to_c, p);
+ STREAM_TO_UINT16(cis_estab_evt.max_pdu_c_to_p, p);
+ STREAM_TO_UINT16(cis_estab_evt.max_pdu_p_to_c, p);
+ STREAM_TO_UINT16(cis_estab_evt.iso_interval, p);
+#if (BLE_FEAT_ISO_60_EN == TRUE)
+ STREAM_TO_UINT24(cis_estab_evt.sub_interval, p);
+ STREAM_TO_UINT16(cis_estab_evt.max_sdu_c_to_p, p);
+ STREAM_TO_UINT16(cis_estab_evt.max_sdu_p_to_c, p);
+ STREAM_TO_UINT24(cis_estab_evt.sdu_int_c_to_p, p);
+ STREAM_TO_UINT24(cis_estab_evt.sdu_int_p_to_c, p);
+ STREAM_TO_UINT8(cis_estab_evt.framing, p);
+#endif // #if (BLE_FEAT_ISO_60_EN == TRUE)
+
+ btm_ble_cis_established_evt(&cis_estab_evt);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+static void btu_ble_cis_request_evt(UINT8 *p)
+{
+ HCI_TRACE_DEBUG("%s", __func__);
+ tBTM_BLE_CIS_REQUEST_CMPL cis_req_evt = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT16(cis_req_evt.acl_handle, p);
+ STREAM_TO_UINT16(cis_req_evt.cis_handle, p);
+ STREAM_TO_UINT8(cis_req_evt.cig_id, p);
+ STREAM_TO_UINT8(cis_req_evt.cis_id, p);
+
+
+ btm_ble_cis_request_evt(&cis_req_evt);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+void btu_ble_create_big_cmd_status(UINT8 status)
+{
+ if (status != HCI_SUCCESS) {
+ tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0};
+ btm_ble_big_create_cmpl_evt(&big_cmpl);
+ }
+}
+
+static void btu_ble_big_create_complete_evt(UINT8 *p)
+{
+ HCI_TRACE_DEBUG("%s", __func__);
+ tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(big_cmpl.status, p);
+ STREAM_TO_UINT8(big_cmpl.big_handle, p);
+ STREAM_TO_UINT24(big_cmpl.big_sync_delay, p);
+ STREAM_TO_UINT24(big_cmpl.transport_latency, p);
+ STREAM_TO_UINT8(big_cmpl.phy, p);
+ STREAM_TO_UINT8(big_cmpl.nse, p);
+ STREAM_TO_UINT8(big_cmpl.bn, p);
+ STREAM_TO_UINT8(big_cmpl.pto, p);
+ STREAM_TO_UINT8(big_cmpl.irc, p);
+ STREAM_TO_UINT16(big_cmpl.max_pdu, p);
+ STREAM_TO_UINT16(big_cmpl.iso_interval, p);
+ STREAM_TO_UINT8(big_cmpl.num_bis, p);
+ for (uint8_t i = 0; i < big_cmpl.num_bis; i++)
+ {
+ STREAM_TO_UINT16(big_cmpl.bis_handle[i], p);
+ // only 12 bits meaningful
+ big_cmpl.bis_handle[i] = (big_cmpl.bis_handle[i] & 0x0FFF);
+ }
+
+ btm_ble_big_create_cmpl_evt(&big_cmpl);
+}
+
+void btu_ble_big_terminate_cmd_status(UINT8 status)
+{
+ if (status != HCI_SUCCESS) {
+ tBTM_BLE_BIG_TERMINATE_CMPL big_term = {0};
+ big_term.status = (status | BTM_HCI_ERROR);
+ btm_ble_big_terminate_cmpl_evt(&big_term);
+ }
+}
+
+static void btu_ble_big_terminate_complete_evt(UINT8 *p)
+{
+ tBTM_BLE_BIG_TERMINATE_CMPL big_term = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(big_term.big_handle, p);
+ STREAM_TO_UINT8(big_term.reason, p);
+ big_term.status = HCI_SUCCESS;
+
+ btm_ble_big_terminate_cmpl_evt(&big_term);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+void btu_ble_create_big_sync_cmd_status(UINT8 status)
+{
+ if (status != HCI_SUCCESS) {
+ tBTM_BLE_BIG_SYNC_ESTAB_CMPL big_estb = {0};
+ big_estb.status = status;
+ btm_ble_big_sync_estab_evt(&big_estb);
+ }
+}
+
+static void btu_ble_big_sync_establish_evt(UINT8 *p)
+{
+ tBTM_BLE_BIG_SYNC_ESTAB_CMPL big_estb = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(big_estb.status, p);
+ STREAM_TO_UINT8(big_estb.big_handle, p);
+ STREAM_TO_UINT24(big_estb.transport_latency_big, p);
+ STREAM_TO_UINT8(big_estb.nse, p);
+ STREAM_TO_UINT8(big_estb.bn, p);
+ STREAM_TO_UINT8(big_estb.pto, p);
+ STREAM_TO_UINT8(big_estb.irc, p);
+ STREAM_TO_UINT16(big_estb.max_pdu, p);
+ STREAM_TO_UINT16(big_estb.iso_interval, p);
+ STREAM_TO_UINT8(big_estb.num_bis, p);
+ for (uint8_t i = 0; i < big_estb.num_bis; i++)
+ {
+ STREAM_TO_UINT16(big_estb.bis_handle[i], p);
+ }
+
+ btm_ble_big_sync_estab_evt(&big_estb);
+}
+
+static void btu_ble_big_sync_lost_evt(UINT8 *p)
+{
+ tBTM_BLE_BIG_SYNC_LOST_EVT big_sync_lost = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(big_sync_lost.big_handle, p);
+ STREAM_TO_UINT8(big_sync_lost.reason, p);
+
+ btm_ble_big_sync_lost_evt(&big_sync_lost);
+}
+
+static void btu_ble_biginfo_adv_report_evt(UINT8 *p)
+{
+ tBTM_BLE_BIGINFO_ADV_REPORT_EVT biginfo_report = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT16(biginfo_report.sync_handle, p);
+ STREAM_TO_UINT8(biginfo_report.num_bis, p);
+ STREAM_TO_UINT8(biginfo_report.nse, p);
+ STREAM_TO_UINT16(biginfo_report.iso_interval, p);
+ STREAM_TO_UINT8(biginfo_report.bn, p);
+ STREAM_TO_UINT8(biginfo_report.pto, p);
+ STREAM_TO_UINT8(biginfo_report.irc, p);
+ STREAM_TO_UINT16(biginfo_report.max_pdu, p);
+ STREAM_TO_UINT24(biginfo_report.sdu_interval, p);
+ STREAM_TO_UINT16(biginfo_report.max_sdu, p);
+ STREAM_TO_UINT8(biginfo_report.phy, p);
+ STREAM_TO_UINT8(biginfo_report.framing, p);
+ STREAM_TO_UINT8(biginfo_report.encryption, p);
+
+ btm_ble_biginfo_adv_report_evt(&biginfo_report);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+static void btu_ble_cte_connless_iq_report_evt(UINT8 *p)
+{
+ tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT connless_iq_rpt = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT16(connless_iq_rpt.sync_handle, p);
+ STREAM_TO_UINT8(connless_iq_rpt.channel_idx, p);
+ STREAM_TO_UINT16(connless_iq_rpt.rssi, p);
+ STREAM_TO_UINT8(connless_iq_rpt.rssi_ant_id, p);
+ STREAM_TO_UINT8(connless_iq_rpt.cte_type, p);
+ STREAM_TO_UINT8(connless_iq_rpt.slot_dur, p);
+ STREAM_TO_UINT8(connless_iq_rpt.pkt_status, p);
+ STREAM_TO_UINT16(connless_iq_rpt.periodic_evt_counter, p);
+ STREAM_TO_UINT8(connless_iq_rpt.sample_count, p);
+
+ for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++)
+ {
+ STREAM_TO_UINT8(connless_iq_rpt.i_sample[i], p);
+ STREAM_TO_UINT8(connless_iq_rpt.q_sample[i], p);
+ }
+
+ btm_ble_connless_iq_report_evt(&connless_iq_rpt);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+static void btu_ble_cte_conn_iq_report_evt(UINT8 *p)
+{
+ tBTM_BLE_CTE_CONN_IQ_REPORT_EVT conn_iq_rpt = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT16(conn_iq_rpt.conn_handle, p);
+ STREAM_TO_UINT8(conn_iq_rpt.rx_phy, p);
+ STREAM_TO_UINT8(conn_iq_rpt.data_channel_idx, p);
+ STREAM_TO_UINT16(conn_iq_rpt.rssi, p);
+ STREAM_TO_UINT8(conn_iq_rpt.rssi_ant_id, p);
+ STREAM_TO_UINT8(conn_iq_rpt.cte_type, p);
+ STREAM_TO_UINT8(conn_iq_rpt.slot_dur, p);
+ STREAM_TO_UINT8(conn_iq_rpt.pkt_status, p);
+ STREAM_TO_UINT16(conn_iq_rpt.conn_evt_counter, p);
+ STREAM_TO_UINT8(conn_iq_rpt.sample_count, p);
+
+ for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++)
+ {
+ STREAM_TO_UINT8(conn_iq_rpt.i_sample[i], p);
+ STREAM_TO_UINT8(conn_iq_rpt.q_sample[i], p);
+ }
+
+ btm_ble_conn_iq_report_evt(&conn_iq_rpt);
+}
+
+static void btu_ble_cte_req_failed_evt(UINT8 *p)
+{
+ tBTM_BLE_CTE_REQ_FAILED_EVT cte_req_failed = {0};
+
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(cte_req_failed.status, p);
+ STREAM_TO_UINT16(cte_req_failed.conn_handle, p);
+
+ btm_ble_cte_req_failed_evt(&cte_req_failed);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+static void btu_ble_path_loss_threshold_evt(UINT8 *p)
+{
+ tBTM_BLE_PATH_LOSS_THRESHOLD_EVT path_loss_thres_evt = {0};
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT16(path_loss_thres_evt.conn_handle, p);
+ STREAM_TO_UINT8(path_loss_thres_evt.cur_path_loss, p);
+ STREAM_TO_UINT8(path_loss_thres_evt.zone_entered, p);
+
+ btm_ble_path_loss_threshold_evt(&path_loss_thres_evt);
+}
+
+static void btu_ble_transmit_power_report_evt(UINT8 *p)
+{
+ tBTM_BLE_TRANS_POWER_REPORT_EVT trans_pwr_report_evt = {0};
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(trans_pwr_report_evt.status, p);
+ STREAM_TO_UINT16(trans_pwr_report_evt.conn_handle, p);
+ STREAM_TO_UINT8(trans_pwr_report_evt.reason, p);
+ STREAM_TO_UINT8(trans_pwr_report_evt.phy, p);
+ STREAM_TO_UINT8(trans_pwr_report_evt.tx_power_level, p);
+ STREAM_TO_UINT8(trans_pwr_report_evt.tx_power_level_flag, p);
+ STREAM_TO_UINT8(trans_pwr_report_evt.delta, p);
+
+ btm_ble_transmit_power_report_evt(&trans_pwr_report_evt);
+}
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+static void btu_ble_subrate_change_evt(UINT8 *p)
+{
+ tBTM_BLE_SUBRATE_CHANGE_EVT subrate_change_evt = {0};
+ if (!p) {
+ HCI_TRACE_ERROR("%s, Invalid params.", __func__);
+ return;
+ }
+
+ STREAM_TO_UINT8(subrate_change_evt.status, p);
+ STREAM_TO_UINT16(subrate_change_evt.conn_handle, p);
+ STREAM_TO_UINT16(subrate_change_evt.subrate_factor, p);
+ STREAM_TO_UINT16(subrate_change_evt.peripheral_latency, p);
+ STREAM_TO_UINT16(subrate_change_evt.continuation_number, p);
+ STREAM_TO_UINT16(subrate_change_evt.supervision_timeout, p);
+
+ btm_ble_subrate_change_evt(&subrate_change_evt);
+}
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
/**********************************************
** End of BLE Events Handler
***********************************************/
diff --git a/lib/bt/host/bluedroid/stack/btu/btu_init.c b/lib/bt/host/bluedroid/stack/btu/btu_init.c
index 9ede9c2d..a00b3243 100644
--- a/lib/bt/host/bluedroid/stack/btu/btu_init.c
+++ b/lib/bt/host/bluedroid/stack/btu/btu_init.c
@@ -254,17 +254,6 @@ UINT16 BTU_BleAclPktSize(void)
#endif
}
-#if SCAN_QUEUE_CONGEST_CHECK
-bool BTU_check_queue_is_congest(void)
-{
- if (osi_thread_queue_wait_size(btu_thread, 0) >= BT_QUEUE_CONGEST_SIZE) {
- return true;
- }
-
- return false;
-}
-#endif
-
int get_btu_work_queue_size(void)
{
return osi_thread_queue_wait_size(btu_thread, 0);
diff --git a/lib/bt/host/bluedroid/stack/btu/btu_task.c b/lib/bt/host/bluedroid/stack/btu/btu_task.c
index 9311a36d..bffa6837 100644
--- a/lib/bt/host/bluedroid/stack/btu/btu_task.c
+++ b/lib/bt/host/bluedroid/stack/btu/btu_task.c
@@ -229,11 +229,13 @@ bool btu_task_post(uint32_t sig, void *param, uint32_t timeout)
break;
case SIG_BTU_HCI_ADV_RPT_MSG:
#if BLE_INCLUDED == TRUE
+#if (BLE_42_SCAN_EN == TRUE)
if (param != NULL) {
btm_ble_adv_pkt_post(param);
}
btm_ble_adv_pkt_ready();
status = true;
+#endif // #if (BLE_42_SCAN_EN == TRUE)
#else
osi_free(param);
status = false;
@@ -451,7 +453,7 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
// NOTE: This value is in seconds but stored in a ticks field.
p_tle->ticks = timeout_sec;
p_tle->in_use = TRUE;
- osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
+ osi_alarm_set(alarm, (period_ms_t)((period_ms_t)timeout_sec * 1000));
}
diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_api.c b/lib/bt/host/bluedroid/stack/gatt/gatt_api.c
index 8d8056f6..51e46e22 100644
--- a/lib/bt/host/bluedroid/stack/gatt/gatt_api.c
+++ b/lib/bt/host/bluedroid/stack/gatt/gatt_api.c
@@ -75,7 +75,7 @@ UINT8 GATT_SetTraceLevel (UINT8 new_level)
**
** Function GATTS_AddHandleRange
**
-** Description This function add the allocated handles range for the specifed
+** Description This function add the allocated handles range for the specified
** application UUID, service UUID and service instance
**
** Parameter p_hndl_range: pointer to allocated handles information
@@ -105,7 +105,7 @@ BOOLEAN GATTS_AddHandleRange(tGATTS_HNDL_RANGE *p_hndl_range)
** NV save callback function. There can be one and only one
** NV save callback function.
**
-** Parameter p_cb_info : callback informaiton
+** Parameter p_cb_info : callback information
**
** Returns TRUE if registered OK, else FALSE
**
@@ -151,7 +151,7 @@ static void gatt_update_for_database_change(void)
** num_handles : number of handles needed by the service.
** is_pri : is a primary service or not.
**
-** Returns service handle if sucessful, otherwise 0.
+** Returns service handle if successful, otherwise 0.
**
*******************************************************************************/
UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
@@ -170,7 +170,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
GATT_TRACE_API ("GATTS_CreateService\n" );
if (p_reg == NULL) {
- GATT_TRACE_ERROR ("Inavlid gatt_if=%d\n", gatt_if);
+ GATT_TRACE_ERROR ("Invalid gatt_if=%d\n", gatt_if);
return (0);
}
@@ -491,7 +491,7 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle,
return GATT_SERVICE_STARTED;
}
- /*this is a new application servoce start */
+ /*this is a new application service start */
if ((i_sreg = gatt_sr_alloc_rcb(p_list)) == GATT_MAX_SR_PROFILES) {
GATT_TRACE_ERROR ("GATTS_StartService: no free server registration block");
return GATT_NO_RESOURCES;
@@ -1388,8 +1388,9 @@ void GATT_Deregister (tGATT_IF gatt_if)
}
}
}
-
+#if (tGATT_BG_CONN_DEV == TRUE)
gatt_deregister_bgdev_list(gatt_if);
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
/* update the listen mode */
#if (defined(BLE_PERIPHERAL_MODE_SUPPORT) && (BLE_PERIPHERAL_MODE_SUPPORT == TRUE))
GATT_Listen(gatt_if, FALSE, NULL);
@@ -1468,9 +1469,12 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_
if (is_direct) {
status = gatt_act_connect (p_reg, bd_addr, bd_addr_type, transport, is_aux);
} else {
+#if (tGATT_BG_CONN_DEV == TRUE)
if (transport == BT_TRANSPORT_LE) {
status = gatt_update_auto_connect_dev(gatt_if, TRUE, bd_addr, TRUE);
- } else {
+ } else
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
+ {
GATT_TRACE_ERROR("Unsupported transport for background connection");
}
}
@@ -1483,7 +1487,7 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_
**
** Function GATT_CancelConnect
**
-** Description This function terminate the connection initaition to a remote
+** Description This function terminate the connection initiation to a remote
** device on GATT channel.
**
** Parameters gatt_if: client interface. If 0 used as unconditionally disconnect,
@@ -1527,6 +1531,7 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct
status = gatt_cancel_open(gatt_if, bd_addr);
}
} else {
+#if (tGATT_BG_CONN_DEV == TRUE)
if (!gatt_if) {
if (gatt_get_num_apps_for_bg_dev(bd_addr)) {
while (gatt_find_app_for_bg_dev(bd_addr, &temp_gatt_if)) {
@@ -1539,6 +1544,7 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct
} else {
status = gatt_remove_bg_dev_for_app(gatt_if, bd_addr);
}
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
}
return status;
@@ -1628,7 +1634,7 @@ tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr)
**
** Function GATT_GetConnectionInfor
**
-** Description This function use conn_id to find its associated BD address and applciation
+** Description This function use conn_id to find its associated BD address and application
** interface
**
** Parameters conn_id: connection id (input)
@@ -1665,7 +1671,7 @@ BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_
** Function GATT_GetConnIdIfConnected
**
** Description This function find the conn_id if the logical link for BD address
-** and applciation interface is connected
+** and application interface is connected
**
** Parameters gatt_if: application interface (input)
** bd_addr: peer device address. (input)
@@ -1720,7 +1726,9 @@ BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr)
}
if (bd_addr != NULL) {
+#if (tGATT_BG_CONN_DEV == TRUE)
gatt_update_auto_connect_dev(gatt_if, start, bd_addr, FALSE);
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
} else {
p_reg->listening = start ? GATT_LISTEN_TO_ALL : GATT_LISTEN_TO_NONE;
}
diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_db.c b/lib/bt/host/bluedroid/stack/gatt/gatt_db.c
index efae6413..8844ef5d 100644
--- a/lib/bt/host/bluedroid/stack/gatt/gatt_db.c
+++ b/lib/bt/host/bluedroid/stack/gatt/gatt_db.c
@@ -60,7 +60,7 @@ static BOOLEAN gatts_add_char_desc_value_check (tGATT_ATTR_VAL *attr_val, tGATTS
** Parameter p_db: database pointer.
** len: size of the memory space.
**
-** Returns Status of te operation.
+** Returns Status of the operation.
**
*******************************************************************************/
BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri,
@@ -94,7 +94,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN
** Parameter p_db: database pointer.
** len: size of the memory space.
**
-** Returns Status of te operation.
+** Returns Status of the operation.
**
*******************************************************************************/
tBT_UUID *gatts_get_service_uuid (tGATT_SVC_DB *p_db)
@@ -497,14 +497,14 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e
** Function gatts_add_characteristic
**
** Description This function add a characteristics and its descriptor into
-** a servce identified by the service database pointer.
+** a service identified by the service database pointer.
**
** Parameter p_db: database pointer.
** perm: permission (authentication and key size requirements)
** property: property of the characteristic.
** p_char: characteristic value information.
**
-** Returns Status of te operation.
+** Returns Status of the operation.
**
*******************************************************************************/
UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
@@ -1173,40 +1173,40 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM)) {
status = GATT_WRITE_NOT_PERMIT;
- GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed,handle:0x%04x",handle);
+ GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed,handle %04x,perm %04x", handle, perm);
}
if ((op_code == GATT_SIGN_CMD_WRITE) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
status = GATT_INVALID_PDU;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link,handle:0x%04x",handle);
+ GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encrypted link,handle %04x,perm %04x", handle, perm);
} else if (!(perm & GATT_WRITE_ALLOWED)) {
status = GATT_WRITE_NOT_PERMIT;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT,handle:0x%04x",handle);
+ GATT_TRACE_ERROR("gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT,handle %04x, perm %04x", handle, perm);
}
/* require authentication, but not been authenticated */
else if ((perm & GATT_WRITE_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED)) {
status = GATT_INSUF_AUTHENTICATION;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION,handle:0x%04x",handle);
+ GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION,handle %04x, perm %04x", handle, perm);
} else if ((perm & GATT_WRITE_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) {
status = GATT_INSUF_AUTHENTICATION;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required,handle:0x%04x",handle);
+ GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required,handle %04x,perm %04x", handle, perm);
} else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
status = GATT_INSUF_ENCRYPTION;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION,handle:0x%04x",handle);
+ GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION,handle:0x%04x, perm:0x%04x", handle, perm);
} else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) {
status = GATT_INSUF_KEY_SIZE;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE,handle:0x%04x",handle);
+ GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE,handle %04x,perm %04x", handle, perm);
}
/* LE Authorization check*/
else if ((perm & GATT_WRITE_AUTHORIZATION) && (!(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED) || !(sec_flag & GATT_SEC_FLAG_AUTHORIZATION))){
status = GATT_INSUF_AUTHORIZATION;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION,handle:0x%04x",handle);
+ GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION,handle %04x,perm %04x", handle, perm);
}
/* LE security mode 2 attribute */
else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)
&& (perm & GATT_WRITE_ALLOWED) == 0) {
status = GATT_INSUF_AUTHENTICATION;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required,handle:0x%04x",handle);
- } else { /* writable: must be char value declaration or char descritpors */
+ GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required,handle %04x,perm %04x", handle, perm);
+ } else { /* writable: must be char value declaration or char descriptors */
if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) {
switch (p_attr->uuid) {
case GATT_UUID_CHAR_PRESENT_FORMAT:/* should be readable only */
@@ -1215,13 +1215,19 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
case GATT_UUID_CHAR_VALID_RANGE:
status = GATT_WRITE_NOT_PERMIT;
break;
-
+ case GATT_UUID_GAP_ICON:/* The Appearance characteristic value shall be 2 octets in length */
case GATT_UUID_CHAR_CLIENT_CONFIG:
/* coverity[MISSING_BREAK] */
/* intnended fall through, ignored */
/* fall through */
case GATT_UUID_CHAR_SRVR_CONFIG:
max_size = 2;
+ status = GATT_SUCCESS;
+ break;
+ case GATT_UUID_CLIENT_SUP_FEAT:
+ max_size = 1;
+ status = GATT_SUCCESS;
+ break;
case GATT_UUID_CHAR_DESCRIPTION:
default: /* any other must be character value declaration */
status = GATT_SUCCESS;
@@ -1242,17 +1248,17 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
else if ( (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) &&
(p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG ||
p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG ||
- p_attr->uuid == GATT_UUID_CLIENT_SUP_FEAT ||
+ p_attr->uuid == GATT_UUID_CLIENT_SUP_FEAT ||
p_attr->uuid == GATT_UUID_GAP_ICON
) )
// btla-specific --
{
if (op_code == GATT_REQ_PREPARE_WRITE) { /* does not allow write blob */
status = GATT_REQ_NOT_SUPPORTED;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_REQ_NOT_SUPPORTED,handle:0x%04x",handle);
+ GATT_TRACE_ERROR("gatts_write_attr_perm_check - GATT_REQ_NOT_SUPPORTED,handle %04x,opcode %4x", handle, op_code);
} else if (len != max_size) { /* data does not match the required format */
status = GATT_INVALID_ATTR_LEN;
- GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_ATTR_LEN,handle:0x%04x",handle);
+ GATT_TRACE_ERROR("gatts_write_attr_perm_check - GATT_INVALID_ATTR_LEN,handle %04x,op_code %04x,len %d,max_size %d", handle, op_code, len, max_size);
} else {
status = GATT_SUCCESS;
}
@@ -1554,7 +1560,7 @@ static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_
uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE;
}
- /* add service declration record */
+ /* add service declaration record */
if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL) {
if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID))) {
if (p_service->len == LEN_UUID_16) {
diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_main.c b/lib/bt/host/bluedroid/stack/gatt/gatt_main.c
index d76aefe9..53d9be74 100644
--- a/lib/bt/host/bluedroid/stack/gatt/gatt_main.c
+++ b/lib/bt/host/bluedroid/stack/gatt/gatt_main.c
@@ -502,7 +502,7 @@ static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connect
#endif ///GATTS_INCLUDED == TRUE
}
} else {
- GATT_TRACE_ERROR("CCB max out, no rsources");
+ GATT_TRACE_ERROR("CCB max out, no resources");
}
}
} else {
@@ -929,18 +929,23 @@ static void gatt_send_conn_cback(tGATT_TCB *p_tcb)
{
UINT8 i;
tGATT_REG *p_reg;
+#if (tGATT_BG_CONN_DEV == TRUE)
tGATT_BG_CONN_DEV *p_bg_dev = NULL;
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
UINT16 conn_id;
+#if (tGATT_BG_CONN_DEV == TRUE)
p_bg_dev = gatt_find_bg_dev(p_tcb->peer_bda);
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
/* notifying all applications for the connection up event */
for (i = 0, p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++) {
if (p_reg->in_use) {
+#if (tGATT_BG_CONN_DEV == TRUE)
if (p_bg_dev && gatt_is_bg_dev_for_app(p_bg_dev, p_reg->gatt_if)) {
gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, TRUE);
}
-
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
if (p_reg->app_cb.p_conn_cb) {
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
(*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id,
@@ -1239,7 +1244,8 @@ uint8_t gatt_tcb_active_count(void)
for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
p_tcb = list_node(p_node);
- if (p_tcb && p_tcb->in_use && (p_tcb->ch_state != GATT_CH_CLOSE)) {
+ if (p_tcb && p_tcb->in_use && (p_tcb->transport == BT_TRANSPORT_LE) &&
+ (p_tcb->ch_state != GATT_CH_CLOSE)) {
count++;
}
}
diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c b/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c
index 79e161c1..5947239c 100644
--- a/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c
+++ b/lib/bt/host/bluedroid/stack/gatt/gatt_sr.c
@@ -200,7 +200,7 @@ static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status,
*p++ = GATT_RSP_READ_MULTI;
p_buf->len = 1;
- /* Now walk through the buffers puting the data into the response in order */
+ /* Now walk through the buffers putting the data into the response in order */
list_t *list = NULL;
const list_node_t *node = NULL;
if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
@@ -321,7 +321,7 @@ static BOOLEAN process_read_multi_var_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS sta
*p++ = GATT_RSP_READ_MULTI_VAR;
p_buf->len = 1;
- /* Now walk through the buffers puting the data into the response in order */
+ /* Now walk through the buffers putting the data into the response in order */
list_t *list = NULL;
const list_node_t *node = NULL;
if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) {
@@ -735,7 +735,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_
handle_len = 4 + p_uuid->len;
}
- /* get the length byte in the repsonse */
+ /* get the length byte in the response */
if (p_msg->offset == 0) {
*p ++ = op_code + 1;
p_msg->len ++;
@@ -788,7 +788,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_
** buffer.
**
** Returns TRUE: if data filled successfully.
-** FALSE: packet full, or format mismatch.
+** FALSE: packet full.
**
*******************************************************************************/
static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16 *p_len,
@@ -831,10 +831,9 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg,
gatt_convert_uuid32_to_uuid128(p, ((tGATT_ATTR32 *) p_attr)->uuid);
p += LEN_UUID_128;
} else {
- GATT_TRACE_ERROR("format mismatch");
- status = GATT_NO_RESOURCES;
+ // UUID format mismatch in sequential attributes
+ // A new request will be sent with the starting handle of the next attribute
break;
- /* format mismatch */
}
p_msg->len += info_pair_len[p_msg->offset - 1];
len -= info_pair_len[p_msg->offset - 1];
@@ -889,7 +888,7 @@ static tGATT_STATUS gatts_validate_packet_format(UINT8 op_code, UINT16 *p_len,
/* parse uuid now */
if (gatt_parse_uuid_from_cmd (p_uuid_filter, uuid_len, &p) == FALSE ||
p_uuid_filter->len == 0) {
- GATT_TRACE_DEBUG("UUID filter does not exsit");
+ GATT_TRACE_DEBUG("UUID filter does not exist");
reason = GATT_INVALID_PDU;
} else {
len -= p_uuid_filter->len;
@@ -1042,7 +1041,7 @@ static void gatts_process_find_info(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
**
** Function gatts_process_mtu_req
**
-** Description This function is called to process excahnge MTU request.
+** Description This function is called to process exchange MTU request.
** Only used on LE.
**
** Returns void
@@ -1055,7 +1054,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
BT_HDR *p_buf;
UINT16 conn_id;
- /* BR/EDR conenction, send error response */
+ /* BR/EDR connection, send error response */
if (p_tcb->att_lcid != L2CAP_ATT_CID) {
gatt_send_error_rsp (p_tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, FALSE);
} else if (len < GATT_MTU_REQ_MIN_LEN) {
@@ -1081,7 +1080,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
attp_send_sr_msg (p_tcb, p_buf);
/* Notify all registered application with new MTU size. Us a transaction ID */
- /* of 0, as no response is allowed from applcations */
+ /* of 0, as no response is allowed from applications */
for (i = 0; i < GATT_MAX_APPS; i ++) {
if (gatt_cb.cl_rcb[i].in_use ) {
@@ -1448,7 +1447,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand
}
if ((prepare_record->error_code_app == GATT_SUCCESS)
- // update prepare write status for excute write request
+ // update prepare write status for execute write request
&& (status == GATT_INVALID_OFFSET || status == GATT_INVALID_ATTR_LEN || status == GATT_REQ_NOT_SUPPORTED)) {
prepare_record->error_code_app = status;
}
@@ -1855,7 +1854,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
break;
- case GATT_REQ_FIND_INFO: /* discover char descrptor */
+ case GATT_REQ_FIND_INFO: /* discover char descriptor */
gatts_process_find_info(p_tcb, op_code, len, p_data);
break;
diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c b/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c
index 79d09d7a..d5a4b3a5 100644
--- a/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c
+++ b/lib/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c
@@ -189,7 +189,6 @@ tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash)
#if SMP_INCLUDED == TRUE
BT_OCTET16 key = {0};
aes_cipher_msg_auth_code(key, data_buf, len, 16, hash);
- //ESP_LOG_BUFFER_HEX("db hash", hash, BT_OCTET16_LEN);
#endif
osi_free(data_buf);
diff --git a/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c b/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c
index 621b2468..0644ab70 100644
--- a/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c
+++ b/lib/bt/host/bluedroid/stack/gatt/gatt_utils.c
@@ -108,7 +108,7 @@ void gatt_free_pending_ind(tGATT_TCB *p_tcb)
**
** Function gatt_free_pending_enc_queue
**
-** Description Free all buffers in pending encyption queue
+** Description Free all buffers in pending encryption queue
**
** Returns None
**
@@ -222,7 +222,7 @@ void gatt_set_srv_chg(void)
**
** Description Find the app id in on the new service changed list
**
-** Returns Pointer to the found new service changed item othwerwise NULL
+** Returns Pointer to the found new service changed item otherwise NULL
**
*******************************************************************************/
tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
@@ -299,7 +299,7 @@ tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start(tGATTS_HNDL_RANGE *
**
** Function gatt_add_srv_chg_clt
**
-** Description Add a service chnage client to the service change client queue
+** Description Add a service change client to the service change client queue
**
** Returns Pointer to the service change client buffer; Null no buffer available
**
@@ -682,7 +682,7 @@ BOOLEAN gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_
**
** Function gatt_add_an_item_to_list
**
-** Description add an service handle range to the list in decending
+** Description add an service handle range to the list in descending
** order of the start handle
**
** Returns BOOLEAN TRUE-if add is successful
@@ -808,7 +808,7 @@ BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found
**
** Function gatt_is_srv_chg_ind_pending
**
-** Description Check whether a service chnaged is in the indication pending queue
+** Description Check whether a service changed is in the indication pending queue
** or waiting for an Ack already
**
** Returns BOOLEAN
@@ -846,9 +846,9 @@ BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb)
**
** Function gatt_is_bda_in_the_srv_chg_clt_list
**
-** Description This function check the specified bda is in the srv chg clinet list or not
+** Description This function check the specified bda is in the srv chg client list or not
**
-** Returns pointer to the found elemenet otherwise NULL
+** Returns pointer to the found element otherwise NULL
**
*******************************************************************************/
tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda)
@@ -1205,7 +1205,7 @@ UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid)
if (uuid.len == LEN_UUID_16) {
UINT16_TO_STREAM (p, uuid.uu.uuid16);
len = LEN_UUID_16;
- } else if (uuid.len == LEN_UUID_32) { /* always convert 32 bits into 128 bits as alwats */
+ } else if (uuid.len == LEN_UUID_32) { /* always convert 32 bits into 128 bits as always */
gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
p += LEN_UUID_128;
len = LEN_UUID_128;
@@ -1465,7 +1465,7 @@ UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list )
UINT8 ii = 0;
tGATT_SR_REG *p_sreg = NULL;
- /*this is a new application servoce start */
+ /*this is a new application service start */
for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++) {
if (!p_sreg->in_use) {
memset (p_sreg, 0, sizeof(tGATT_SR_REG));
@@ -1616,7 +1616,7 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
break;
default:
- GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
+ GATT_TRACE_ERROR("invalid UUID len=%d", p_uuid->len);
SDP_DeleteRecord(sdp_handle);
return 0;
break;
@@ -1633,7 +1633,7 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
- /* Make the service browseable */
+ /* Make the service browsable */
SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
return (sdp_handle);
@@ -1868,7 +1868,7 @@ UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb)
**
** Function gatt_num_clcb_by_bd_addr
**
-** Description The function searches all LCB with macthing bd address
+** Description The function searches all LCB with matching bd address
**
** Returns total number of clcb found.
**
@@ -1892,7 +1892,7 @@ UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda)
**
** Function gatt_sr_update_cback_cnt
**
-** Description The function searches all LCB with macthing bd address
+** Description The function searches all LCB with matching bd address
**
** Returns total number of clcb found.
**
@@ -1916,7 +1916,7 @@ void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb )
**
** Function gatt_sr_is_cback_cnt_zero
**
-** Description The function searches all LCB with macthing bd address
+** Description The function searches all LCB with matching bd address
**
** Returns True if thetotal application callback count is zero
**
@@ -2015,7 +2015,7 @@ void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb )
**
** Function gatt_sr_update_cback_cnt
**
-** Description Update the teh application callback count
+** Description Update the the application callback count
**
** Returns None
**
@@ -2045,7 +2045,7 @@ void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc
**
** Function gatt_sr_update_prep_cnt
**
-** Description Update the teh prepare write request count
+** Description Update the the prepare write request count
**
** Returns None
**
@@ -2461,7 +2461,7 @@ void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
}
-
+#if (tGATT_BG_CONN_DEV == TRUE)
/*******************************************************************************
**
** Function gatt_is_bg_dev_for_app
@@ -2552,7 +2552,7 @@ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_init
for (i = 0; i < GATT_MAX_APPS; i ++) {
if (is_initator) {
if (p_dev->gatt_if[i] == gatt_if) {
- GATT_TRACE_ERROR("device already in iniator white list");
+ GATT_TRACE_ERROR("device already in initiator white list");
return TRUE;
} else if (p_dev->gatt_if[i] == 0) {
p_dev->gatt_if[i] = gatt_if;
@@ -2618,9 +2618,9 @@ BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
**
** Function gatt_get_num_apps_for_bg_dev
**
-** Description Gte the number of applciations for the specified background device
+** Description Gte the number of applications for the specified background device
**
-** Returns UINT8 total number fo applications
+** Returns UINT8 total number for applications
**
*******************************************************************************/
UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)
@@ -2842,7 +2842,7 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_
}
return ret;
}
-
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
/*******************************************************************************
diff --git a/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h
index 1161da62..f9d3cd8e 100644
--- a/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h
+++ b/lib/bt/host/bluedroid/stack/gatt/include/gatt_int.h
@@ -130,7 +130,7 @@ typedef union {
tGATT_EXEC_FLAG exec_write; /* execute write */
} tGATT_CL_MSG;
-/* error response strucutre */
+/* error response structure */
typedef struct {
UINT16 handle;
UINT8 cmd_code;
@@ -480,12 +480,14 @@ typedef struct {
UINT32 service_change;
} tGATT_SVC_CHG;
+#if (tGATT_BG_CONN_DEV == TRUE)
typedef struct {
tGATT_IF gatt_if[GATT_MAX_APPS];
tGATT_IF listen_gif[GATT_MAX_APPS];
BD_ADDR remote_bda;
BOOLEAN in_use;
} tGATT_BG_CONN_DEV;
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
#define GATT_SVC_CHANGED_CONNECTING 1 /* wait for connection */
#define GATT_SVC_CHANGED_SERVICE 2 /* GATT service discovery */
@@ -553,8 +555,9 @@ typedef struct {
tGATT_HDL_CFG hdl_cfg;
+#if (tGATT_BG_CONN_DEV == TRUE)
tGATT_BG_CONN_DEV bgconn_dev[GATT_MAX_BG_CONN_DEV];
-
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
BOOLEAN auto_disc; /* internal use: true for auto discovering after connected */
UINT8 srv_chg_mode; /* internal use: service change mode */
tGATTS_RSP rsp; /* use to read internal service attribute */
@@ -667,6 +670,7 @@ extern BOOLEAN gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_L
extern BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_remove);
extern tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg);
+#if (tGATT_BG_CONN_DEV == TRUE)
/* for background connection */
extern BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initiator);
extern BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if);
@@ -676,6 +680,7 @@ extern BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if);
extern tGATT_BG_CONN_DEV *gatt_find_bg_dev(BD_ADDR remote_bda);
extern void gatt_deregister_bgdev_list(tGATT_IF gatt_if);
extern void gatt_reset_bgdev_list(void);
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
/* server function */
extern UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle);
diff --git a/lib/bt/host/bluedroid/stack/goep/goepc_api.c b/lib/bt/host/bluedroid/stack/goep/goepc_api.c
new file mode 100644
index 00000000..06be8f59
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/goep/goepc_api.c
@@ -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) || (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) */
diff --git a/lib/bt/host/bluedroid/stack/goep/goepc_main.c b/lib/bt/host/bluedroid/stack/goep/goepc_main.c
new file mode 100644
index 00000000..e0859580
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/goep/goepc_main.c
@@ -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) */
diff --git a/lib/bt/host/bluedroid/stack/goep/include/goep_int.h b/lib/bt/host/bluedroid/stack/goep/include/goep_int.h
new file mode 100644
index 00000000..0c1915f6
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/goep/include/goep_int.h
@@ -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) */
diff --git a/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c b/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c
index 52a2b2dc..5ad13216 100644
--- a/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c
+++ b/lib/bt/host/bluedroid/stack/hcic/hciblecmds.c
@@ -349,8 +349,8 @@ BOOLEAN btsnd_hcic_ble_create_ll_conn (UINT16 scan_int, UINT16 scan_win,
UINT16_TO_STREAM (pp, conn_latency);
UINT16_TO_STREAM (pp, conn_timeout);
- UINT16_TO_STREAM (pp, min_ce_len);
- UINT16_TO_STREAM (pp, max_ce_len);
+ UINT16_TO_STREAM (pp, min_ce_len ? min_ce_len : BLE_CE_LEN_MIN);
+ UINT16_TO_STREAM (pp, max_ce_len ? max_ce_len : BLE_CE_LEN_MIN);
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
@@ -686,6 +686,7 @@ BOOLEAN btsnd_hcic_ble_ltk_req_neg_reply (UINT16 handle)
return (TRUE);
}
+#if (BLE_42_DTM_TEST_EN == TRUE)
BOOLEAN btsnd_hcic_ble_receiver_test(UINT8 rx_freq)
{
BT_HDR *p;
@@ -733,7 +734,9 @@ BOOLEAN btsnd_hcic_ble_transmitter_test(UINT8 tx_freq, UINT8 test_data_len, UINT
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
}
+#endif // // #if (BLE_42_DTM_TEST_EN == TRUE)
+#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
BOOLEAN btsnd_hcic_ble_test_end(void)
{
BT_HDR *p;
@@ -754,6 +757,7 @@ BOOLEAN btsnd_hcic_ble_test_end(void)
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
}
+#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
BOOLEAN btsnd_hcic_ble_read_host_supported (void)
{
@@ -1084,27 +1088,6 @@ BOOLEAN btsnd_hcic_ble_set_channels (BLE_CHANNELS channels)
return (TRUE);
}
-BOOLEAN btsnd_hcic_ble_clear_adv (void)
-{
- BT_HDR *p;
- UINT8 *pp;
-
- if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_CLEAR_ADV)) == NULL) {
- return (FALSE);
- }
-
- pp = (UINT8 *)(p + 1);
-
- p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_ADV;
- p->offset = 0;
-
- UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_CLEAR_ADV);
- UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CLEAR_ADV);
-
- btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
- return TRUE;
-}
-
#define HCIC_BLE_CMD_CREATED(p, pp, size) do{\
if ((p = HCI_GET_CMD_BUF(size)) == NULL) { \
return FALSE; \
@@ -1174,6 +1157,7 @@ BOOLEAN btsnd_hcic_ble_set_phy(UINT16 conn_handle,
return TRUE;
}
+#if (BLE_50_DTM_TEST_EN == TRUE)
UINT8 btsnd_hcic_ble_enhand_rx_test(UINT8 rx_channel, UINT8 phy,
UINT8 modulation_idx)
{
@@ -1218,7 +1202,9 @@ UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len,
return TRUE;
}
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
UINT8 btsnd_hcic_ble_set_extend_rand_address(UINT8 adv_handle, BD_ADDR rand_addr)
{
BT_HDR *p;
@@ -1432,7 +1418,9 @@ UINT8 btsnd_hcic_ble_clear_adv_set(void)
return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
}
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
UINT8 btsnd_hcic_ble_set_periodic_adv_params(UINT8 adv_handle,
UINT16 interval_min,
UINT16 interval_max,
@@ -1507,7 +1495,9 @@ UINT8 btsnd_hcic_ble_periodic_adv_enable(UINT8 enable, UINT8 adv_handle)
return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
}
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
UINT8 btsnd_hcic_ble_set_ext_scan_params(UINT8 own_addr_type, UINT8 filter_policy,
UINT8 phy_mask, UINT8 phy_count,
tHCI_EXT_SCAN_PARAMS *params)
@@ -1555,6 +1545,7 @@ UINT8 btsnd_hcic_ble_ext_scan_enable(UINT8 enable, UINT8 filter_dups,
return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
}
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
{
@@ -1594,8 +1585,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
UINT16_TO_STREAM(pp, params->conn_interval_max);
UINT16_TO_STREAM(pp, params->conn_latency);
UINT16_TO_STREAM(pp, params->sup_timeout);
- UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
- UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
+ UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN);
+ UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN);
}
if (p_conn->init_phy_mask & 0x02) {
@@ -1606,8 +1597,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
UINT16_TO_STREAM(pp, params->conn_interval_max);
UINT16_TO_STREAM(pp, params->conn_latency);
UINT16_TO_STREAM(pp, params->sup_timeout);
- UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
- UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
+ UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN);
+ UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN);
}
if (p_conn->init_phy_mask & 0x04) {
@@ -1618,8 +1609,8 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
UINT16_TO_STREAM(pp, params->conn_interval_max);
UINT16_TO_STREAM(pp, params->conn_latency);
UINT16_TO_STREAM(pp, params->sup_timeout);
- UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
- UINT16_TO_STREAM(pp, BLE_CE_LEN_MIN);
+ UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN);
+ UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN);
}
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
@@ -1627,14 +1618,15 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn)
}
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 option, UINT8 adv_sid,
UINT8 adv_addr_type, BD_ADDR adv_addr,
- UINT16 sync_timeout, UINT8 unused)
+ UINT16 sync_timeout, UINT8 sync_cte_type)
{
BT_HDR *p;
UINT8 *pp;
- HCI_TRACE_EVENT("%s, option = %d, adv_sid = %d, adv_addr_type = %d, sync_timeout = %d, unused = %d",
- __func__, option, adv_sid, adv_addr_type, sync_timeout, unused);
+ HCI_TRACE_EVENT("%s, option = %d, adv_sid = %d, adv_addr_type = %d, sync_timeout = %d, sync_cte_type = %d",
+ __func__, option, adv_sid, adv_addr_type, sync_timeout, sync_cte_type);
HCI_TRACE_EVENT("addr %02x %02x %02x %02x %02x %02x", adv_addr[0], adv_addr[1], adv_addr[2], adv_addr[3], adv_addr[4], adv_addr[5]);
uint16_t skip = 0;
@@ -1648,7 +1640,7 @@ BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 option, UINT8 adv_sid,
BDADDR_TO_STREAM(pp, adv_addr);
UINT16_TO_STREAM(pp, skip);
UINT16_TO_STREAM(pp, sync_timeout);
- UINT8_TO_STREAM(pp, unused);
+ UINT8_TO_STREAM(pp, sync_cte_type);
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
return TRUE;
@@ -1750,6 +1742,7 @@ UINT8 btsnd_hcic_ble_read_periodic_adv_list_size(void)
return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
}
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
UINT8 btsnd_hcic_ble_read_trans_power(void)
{
@@ -1910,7 +1903,7 @@ UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT
}
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
-UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode)
+BOOLEAN btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode)
{
BT_HDR *p;
UINT8 *pp;
@@ -1933,4 +1926,885 @@ UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 priva
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
}
+
+#if (BLE_VENDOR_HCI_EN == TRUE)
+BOOLEAN btsnd_hcic_ble_clear_adv (void)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_CLEAR_ADV)) == NULL) {
+ return (FALSE);
+ }
+
+ pp = (UINT8 *)(p + 1);
+
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_ADV;
+ p->offset = 0;
+
+ UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_CLEAR_ADV);
+ UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CLEAR_ADV);
+
+ btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+
+BOOLEAN btsnd_hcic_ble_set_csa_support (UINT8 csa_select)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT)) == NULL) {
+ return (FALSE);
+ }
+
+ pp = (UINT8 *)(p + 1);
+
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT;
+ p->offset = 0;
+
+ UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_SET_CSA_SUPPORT);
+ UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT);
+ UINT8_TO_STREAM (pp, csa_select);
+
+ btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+
+BOOLEAN btsnd_hcic_ble_set_vendor_evt_mask (UINT32 evt_mask)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK)) == NULL) {
+ return (FALSE);
+ }
+
+ pp = (UINT8 *)(p + 1);
+
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK;
+ p->offset = 0;
+
+ UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_SET_EVT_MASK);
+ UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK);
+ UINT32_TO_STREAM (pp, evt_mask);
+
+ btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+#endif // #if (BLE_VENDOR_HCI_EN == TRUE)
#endif
+
+#if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+UINT8 btsnd_hcic_ble_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency,
+ uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing,
+ uint8_t encryption, uint8_t *broadcast_code)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci big create: big_handle %d, adv_handle %d, num_bis %d sdu_interval %d max_sdu %d max_transport_latency %d \
+ rtn %d phy %d packing %d framing %d encryption %d", big_handle, adv_handle, num_bis, sdu_interval, max_sdu,\
+ max_transport_latency, rtn, phy, packing, framing, encryption);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_CREATE_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_CREATE_BIG);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_CREATE_PARAMS);
+
+ UINT8_TO_STREAM(pp, big_handle);
+ UINT8_TO_STREAM(pp, adv_handle);
+ UINT8_TO_STREAM(pp, num_bis);
+ UINT24_TO_STREAM(pp, sdu_interval);
+ UINT16_TO_STREAM(pp, max_sdu);
+ UINT16_TO_STREAM(pp, max_transport_latency);
+ UINT8_TO_STREAM(pp, rtn);
+ UINT8_TO_STREAM(pp, phy);
+ UINT8_TO_STREAM(pp, packing);
+ UINT8_TO_STREAM(pp, framing);
+ UINT8_TO_STREAM(pp, encryption);
+ ARRAY_TO_STREAM(pp, broadcast_code, 16);
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+
+UINT8 btsnd_hcic_ble_big_create_test(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse,
+ uint16_t max_sdu, uint16_t max_pdu, uint8_t phy,
+ uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc,
+ uint8_t pto, uint8_t encryption, uint8_t *broadcast_code)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("%s big_handle %d, adv_handle %d, num_bis %d sdu_interval %d max_sdu %d max_pdu %d iso_interval %d \
+ nse %d phy %d packing %d framing %d bn %d irc %dencryption %d", __func__, big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_pdu, \
+ iso_interval, nse, phy, packing, framing, bn, irc, encryption);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_CREATE_TEST_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_CREATE_BIG_TEST);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_CREATE_TEST_PARAMS);
+
+ UINT8_TO_STREAM(pp, big_handle);
+ UINT8_TO_STREAM(pp, adv_handle);
+ UINT8_TO_STREAM(pp, num_bis);
+ UINT24_TO_STREAM(pp, sdu_interval);
+ UINT16_TO_STREAM(pp, iso_interval);
+ UINT8_TO_STREAM(pp, nse);
+ UINT16_TO_STREAM(pp, max_sdu);
+ UINT16_TO_STREAM(pp, max_pdu);
+ UINT8_TO_STREAM(pp, phy);
+ UINT8_TO_STREAM(pp, packing);
+ UINT8_TO_STREAM(pp, framing);
+ UINT8_TO_STREAM(pp, bn);
+ UINT8_TO_STREAM(pp, irc);
+ UINT8_TO_STREAM(pp, pto);
+ UINT8_TO_STREAM(pp, encryption);
+ ARRAY_TO_STREAM(pp, broadcast_code, 16);
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+
+UINT8 btsnd_hcic_ble_big_terminate(uint8_t big_handle, uint8_t reason)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("%s big_handle %d reason 0x%x", __func__, big_handle, reason);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_TERMINATE_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_TERMINATE_BIG);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_TERMINATE_PARAMS);
+
+ UINT8_TO_STREAM(pp, big_handle);
+ UINT8_TO_STREAM(pp, reason);
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+UINT8 btsnd_hcic_ble_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
+ uint8_t encryption, uint8_t *bc_code,
+ uint8_t mse, uint16_t big_sync_timeout,
+ uint8_t num_bis, uint8_t *bis)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("big sync create: big_handle %d sync_handle %d encryption %d mse %d big_sync_timeout %d", big_handle, sync_handle, encryption, mse, big_sync_timeout);
+
+ // for (uint8_t i = 0; i < num_bis; i++)
+ // {
+ // HCI_TRACE_ERROR("i %d bis %d", bis[i]);
+ // }
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_SYNC_CREATE_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_BIG_CREATE_SYNC);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_SYNC_CREATE_PARAMS);
+
+ UINT8_TO_STREAM(pp, big_handle);
+ UINT16_TO_STREAM(pp, sync_handle);
+ UINT8_TO_STREAM(pp, encryption);
+ ARRAY_TO_STREAM(pp, bc_code, 16);
+ UINT8_TO_STREAM(pp, mse);
+ UINT16_TO_STREAM(pp, big_sync_timeout);
+ UINT8_TO_STREAM(pp, num_bis);
+ ARRAY_TO_STREAM(pp, bis, num_bis);
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+
+UINT8 btsnd_hcic_ble_big_sync_terminate(uint8_t big_handle)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("%s big_handle %d", __func__, big_handle);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_BIG_SYNC_TERMINATE_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_BIG_TERMINATE_SYNC);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BIG_SYNC_TERMINATE_PARAMS);
+
+ UINT8_TO_STREAM(pp, big_handle);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+UINT8 btsnd_hcic_ble_iso_set_data_path(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt,
+ uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len,
+ uint8_t *codec_cfg)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set data path: conn_handle %d data_path_dir %d data_path_id %d coding_fmt %d company_id 0x%x vs_codec_id %d controller_delay %ld codec_len %d",
+ conn_handle, data_path_dir, data_path_id, coding_fmt, company_id, vs_codec_id, controller_delay, codec_len);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_SET_DATA_PATH_PARAMS + codec_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_SET_DATA_PATH);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_SET_DATA_PATH_PARAMS + codec_len);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT8_TO_STREAM(pp, data_path_dir);
+ UINT8_TO_STREAM(pp, data_path_id);
+ UINT8_TO_STREAM(pp, coding_fmt);
+ UINT16_TO_STREAM(pp, company_id);
+ UINT16_TO_STREAM(pp, vs_codec_id);
+ UINT24_TO_STREAM(pp, controller_delay);
+ UINT8_TO_STREAM(pp, codec_len);
+ if (codec_len && codec_cfg) {
+ ARRAY_TO_STREAM(pp, codec_cfg, codec_len);
+ }
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_iso_remove_data_path(uint16_t conn_handle, uint8_t data_path_dir)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci remove data path: conn_handle %d data_path_dir %d", conn_handle, data_path_dir);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_REMOVE_DATA_PATH_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_REMOVE_DATA_PATH);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_REMOVE_DATA_PATH_PARAMS);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT8_TO_STREAM(pp, data_path_dir);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_iso_read_tx_sync(uint16_t iso_hdl)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci read iso tx sync: iso_hdl %d", iso_hdl);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_READ_TX_SYNC_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_READ_TX_SYNC);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_READ_TX_SYNC_PARAMS);
+ // Bit_Number V1
+ UINT16_TO_STREAM(pp, iso_hdl);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+UINT8 btsnd_hcic_ble_iso_set_cig_params(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing,
+ uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, struct ble_hci_le_cis_params *cis_params)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set cig params: cig_id %d sdu_int_c_to_p %d sdu_int_p_to_c %d worse_case_SCA %d packing %d framing %d mtl_c_to_p %d mtl_p_to_c %d cis_cnt %d",
+ cig_id, sdu_int_c_to_p, sdu_int_p_to_c, worse_case_SCA, packing, framing, mtl_c_to_p, mtl_p_to_c, cis_cnt);
+ UINT8 cis_param_len = cis_cnt * 9;
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_SET_CIG_PARAMS + cis_param_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_SET_CIG_PARAMS);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_SET_CIG_PARAMS + cis_param_len);
+
+ UINT8_TO_STREAM(pp, cig_id);
+ UINT24_TO_STREAM(pp, sdu_int_c_to_p);
+ UINT24_TO_STREAM(pp, sdu_int_p_to_c);
+ UINT8_TO_STREAM(pp, worse_case_SCA);
+ UINT8_TO_STREAM(pp, packing);
+ UINT8_TO_STREAM(pp, framing);
+ UINT16_TO_STREAM(pp, mtl_c_to_p);
+ UINT16_TO_STREAM(pp, mtl_p_to_c);
+ UINT8_TO_STREAM(pp, cis_cnt);
+
+ for (uint8_t i = 0; i < cis_cnt; i++)
+ {
+ UINT8_TO_STREAM(pp, cis_params[i].cis_id);
+ UINT16_TO_STREAM(pp, cis_params[i].max_sdu_c_to_p);
+ UINT16_TO_STREAM(pp, cis_params[i].max_sdu_p_to_c);
+ UINT8_TO_STREAM(pp, cis_params[i].phy_c_to_p);
+ UINT8_TO_STREAM(pp, cis_params[i].phy_p_to_c);
+ UINT8_TO_STREAM(pp, cis_params[i].rtn_c_to_p);
+ UINT8_TO_STREAM(pp, cis_params[i].rtn_p_to_c);
+ }
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_iso_set_cig_params_test(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c,
+ uint16_t iso_interval, uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt,
+ struct ble_hci_le_cis_params_test *cis_params_test)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set cig params test: cig_id %d sdu_int_c_to_p %d sdu_int_p_to_c %d ft_c_to_p %d ft_p_to_c %d iso_interval %d worse_case_SCA %d packing %d framing %d cis_cnt %d",
+ cig_id, sdu_int_c_to_p, sdu_int_p_to_c, ft_c_to_p, ft_p_to_c, iso_interval, worse_case_SCA, packing, framing, cis_cnt);
+ UINT8 cis_param_len = cis_cnt * 14;
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_SET_CIG_TEST_PARAMS + cis_param_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_SET_CIG_PARAMS_TEST);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_SET_CIG_TEST_PARAMS + cis_param_len);
+
+ UINT8_TO_STREAM(pp, cig_id);
+ UINT24_TO_STREAM(pp, sdu_int_c_to_p);
+ UINT24_TO_STREAM(pp, sdu_int_p_to_c);
+ UINT8_TO_STREAM(pp, ft_c_to_p);
+ UINT8_TO_STREAM(pp, ft_p_to_c);
+ UINT16_TO_STREAM(pp, iso_interval);
+ UINT8_TO_STREAM(pp, worse_case_SCA);
+ UINT8_TO_STREAM(pp, packing);
+ UINT8_TO_STREAM(pp, framing);
+ UINT8_TO_STREAM(pp, cis_cnt);
+
+ for (uint8_t i = 0; i < cis_cnt; i++)
+ {
+ UINT8_TO_STREAM(pp, cis_params_test[i].cis_id);
+ UINT8_TO_STREAM(pp, cis_params_test[i].nse);
+ UINT16_TO_STREAM(pp, cis_params_test[i].max_sdu_c_to_p);
+ UINT16_TO_STREAM(pp, cis_params_test[i].max_sdu_p_to_c);
+ UINT16_TO_STREAM(pp, cis_params_test[i].max_pdu_c_to_p);
+ UINT16_TO_STREAM(pp, cis_params_test[i].max_pdu_p_to_c);
+ UINT8_TO_STREAM(pp, cis_params_test[i].phy_c_to_p);
+ UINT8_TO_STREAM(pp, cis_params_test[i].phy_p_to_c);
+ UINT8_TO_STREAM(pp, cis_params_test[i].bn_c_to_p);
+ UINT8_TO_STREAM(pp, cis_params_test[i].bn_p_to_c);
+ }
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_iso_create_cis(uint8_t cis_count, struct ble_hci_cis_hdls *cis_hdls)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci create cis: cig_id ", cis_count);
+ // for (uint8_t i = 0; i < cis_count; i++)
+ // {
+ // HCI_TRACE_ERROR("i %d cis_hdl %d acl_hdl %d", i, cis_hdls[i].cis_hdl, cis_hdls[i].acl_hdl);
+ // }
+
+ UINT8 cis_param_len = cis_count * 4;
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_CREATE_CIS_PARAMS + cis_param_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_CREATE_CIS);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_CREATE_CIS_PARAMS + cis_param_len);
+
+ UINT8_TO_STREAM(pp, cis_count);
+
+ for (uint8_t i = 0; i < cis_count; i++)
+ {
+ UINT16_TO_STREAM(pp, cis_hdls[i].cis_hdl);
+ UINT16_TO_STREAM(pp, cis_hdls[i].acl_hdl);
+ }
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+
+ return TRUE;
+}
+
+UINT8 btsnd_hcic_ble_iso_remove_cig(uint8_t cig_id)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci remove cig: cig_id %d", cig_id);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_REMOVE_CIG_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_REMOVE_CIG);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_REMOVE_CIG_PARAMS);
+
+ UINT8_TO_STREAM(pp, cig_id);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+UINT8 btsnd_hcic_ble_iso_accept_cis_req(uint16_t cis_handle)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci accept cis req: cis_handle %d", cis_handle);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_ACCEPT_CIS_REQ_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_ACCEPT_CIS_REQ);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_ACCEPT_CIS_REQ_PARAMS);
+
+ UINT16_TO_STREAM(pp, cis_handle);
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+
+ return TRUE;
+}
+
+UINT8 btsnd_hcic_ble_iso_reject_cis_req(uint16_t cis_handle, uint8_t reason)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci reject cis req: cis_handle %d reason %d", cis_handle, reason);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_REJECT_CIS_REQ_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_REJECT_CIS_REQ);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_REJECT_CIS_REQ_PARAMS);
+
+ UINT16_TO_STREAM(pp, cis_handle);
+ UINT8_TO_STREAM(pp, reason);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+UINT8 btsnd_hcic_ble_iso_read_iso_link_quality(uint16_t iso_handle)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci read iso link quality: cis_handle %d", iso_handle);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ISO_READ_LINK_QUALITY_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ISO_READ_ISO_LINK_QUALITY);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ISO_READ_LINK_QUALITY_PARAMS);
+
+ UINT16_TO_STREAM(pp, iso_handle);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+UINT8 btsnd_hcic_ble_set_connless_cte_trans_params(uint8_t adv_hdl, uint8_t cte_len, uint8_t cte_type,
+ uint8_t cte_cnt, uint8_t switching_pattern_len, uint8_t *antenna_ids)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set connless cte trans: adv_hdl %d cte_len %d cte_type %d cte_cnt %d", adv_hdl, cte_len, cte_type, cte_cnt);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS + switching_pattern_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_CTE_TRANS_PARAMS);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS + switching_pattern_len);
+
+ UINT8_TO_STREAM(pp, adv_hdl);
+ UINT8_TO_STREAM(pp, cte_len);
+ UINT8_TO_STREAM(pp, cte_type);
+ UINT8_TO_STREAM(pp, cte_cnt);
+ UINT8_TO_STREAM(pp, switching_pattern_len);
+ for (uint8_t i = 0; i < switching_pattern_len; i++)
+ {
+ UINT8_TO_STREAM(pp, antenna_ids[i]);
+ }
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_set_connless_cte_enable(uint8_t adv_hdl, uint8_t cte_en)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set connect cte enable: adv_hdl %d cte_en %d", adv_hdl, cte_en);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_CTE_TRANS_ENABLE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE);
+
+ UINT8_TO_STREAM(pp, adv_hdl);
+ UINT8_TO_STREAM(pp, cte_en);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_set_connless_iq_sampling_enable(uint16_t sync_hdl, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *antenna_ids)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci enable IQ sampling: sync_hdl %d sampling_en %d slot_dur %d", sync_hdl, sampling_en, slot_dur);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE + switching_pattern_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_IQ_SAMPLING_ENABLE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE + switching_pattern_len);
+
+ UINT16_TO_STREAM(pp, sync_hdl);
+ UINT8_TO_STREAM(pp, sampling_en);
+ UINT8_TO_STREAM(pp, slot_dur);
+ UINT8_TO_STREAM(pp, max_sampled_ctes);
+ UINT8_TO_STREAM(pp, switching_pattern_len);
+ for (uint8_t i = 0; i < switching_pattern_len; i++)
+ {
+ UINT8_TO_STREAM(pp, antenna_ids[i]);
+ }
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+UINT8 btsnd_hcic_ble_set_conn_cte_receive_params(uint16_t conn_hdl, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t switching_pattern_len, uint8_t *antenna_ids)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set connection cte receive params: conn_hdl %d sampling_en %d slot_dur %d", conn_hdl, sampling_en, slot_dur);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS + switching_pattern_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_RECEIVE_PARAMS);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS + switching_pattern_len);
+
+ UINT16_TO_STREAM(pp, conn_hdl);
+ UINT8_TO_STREAM(pp, sampling_en);
+ UINT8_TO_STREAM(pp, slot_dur);
+ UINT8_TO_STREAM(pp, switching_pattern_len);
+ for (uint8_t i = 0; i < switching_pattern_len; i++)
+ {
+ UINT8_TO_STREAM(pp, antenna_ids[i]);
+ }
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_set_conn_cte_trans_params(uint16_t conn_hdl, uint8_t cte_type, uint8_t switching_pattern_len, uint8_t *antenna_ids)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set connection cte trans params: conn_hdl %d cte_type %d len %d", conn_hdl, cte_type, switching_pattern_len);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS + switching_pattern_len);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_TRANS_PARAMS);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS + switching_pattern_len);
+
+ UINT16_TO_STREAM(pp, conn_hdl);
+ UINT8_TO_STREAM(pp, cte_type);
+ UINT8_TO_STREAM(pp, switching_pattern_len);
+ for (uint8_t i = 0; i < switching_pattern_len; i++)
+ {
+ UINT8_TO_STREAM(pp, antenna_ids[i]);
+ }
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_conn_cte_req_enable(uint16_t conn_hdl, uint8_t enable, uint16_t cte_req_int, uint8_t req_cte_len, uint8_t req_cte_type)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set connect cte request enable: conn_hdl %d enable %d cte_req_int %d req_cte_len %d req_cte_type %d", conn_hdl, enable, cte_req_int, req_cte_len, req_cte_type);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_REQ_ENABLE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE);
+
+ UINT16_TO_STREAM(pp, conn_hdl);
+ UINT8_TO_STREAM(pp, enable);
+ UINT16_TO_STREAM(pp, cte_req_int);
+ UINT8_TO_STREAM(pp, req_cte_len);
+ UINT8_TO_STREAM(pp, req_cte_type);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_conn_cte_rsp_enable(uint16_t conn_hdl, uint8_t enable)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set connect cte response enable: conn_hdl %d enable %d", conn_hdl, enable);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_RSP_ENABLE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE);
+
+ UINT16_TO_STREAM(pp, conn_hdl);
+ UINT8_TO_STREAM(pp, enable);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+UINT8 btsnd_hcic_ble_read_antenna_info(void)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci read antenna information");
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_ANT_INFO);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_READ_ANT_INFOR);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_ANT_INFO);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+UINT8 btsnd_hcic_ble_enh_read_trans_power_level(uint16_t conn_handle, uint8_t phy)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci enh read trans power level, conn_handle %d phy %d", conn_handle, phy);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_ENH_READ_TRANS_PWR_LEVEL);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_ENH_READ_TRANS_POWER_LEVEL);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ENH_READ_TRANS_PWR_LEVEL);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT8_TO_STREAM(pp, phy);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_read_remote_trans_power_level(uint16_t conn_handle, uint8_t phy)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci read remote trans power level, conn_handle %d phy %d", conn_handle, phy);
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_REMOTE_TRANS_PWR_LEVEL);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_READ_REMOTE_TRANS_POWER_LEVEL);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_REMOTE_TRANS_PWR_LEVEL);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT8_TO_STREAM(pp, phy);
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+
+ return TRUE;
+}
+
+UINT8 btsnd_hcic_ble_set_path_loss_rpt_params(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis,
+ uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set path loss rpt params, conn_handle %d high_threshold %d high_hysteresis %d low_threshold %d low_hysteresis %d min_time_spent %d",
+ conn_handle, high_threshold, high_hysteresis, low_threshold,
+ low_hysteresis, min_time_spent);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_PARAMS);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_PATH_LOSS_REPORTING_PARAMS);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_PARAMS);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT8_TO_STREAM(pp, high_threshold);
+ UINT8_TO_STREAM(pp, high_hysteresis);
+ UINT8_TO_STREAM(pp, low_threshold);
+ UINT8_TO_STREAM(pp, low_hysteresis);
+ UINT16_TO_STREAM(pp, min_time_spent);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_set_path_loss_rpt_enable(uint16_t conn_handle, uint8_t enable)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set path loss rpt en, conn_handle %d enable %d", conn_handle, enable);
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_ENABLE);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_PATH_LOSS_REPORTING_ENABLE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_ENABLE);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT8_TO_STREAM(pp, enable);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_set_trans_pwr_rpt_enable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set trans power rpt en, conn_handle %d local_enable %d remote_enable %d", conn_handle, local_enable, remote_enable);
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_TRANS_PWR_REPORTING_ENABLE);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_TRANS_POWER_REPORTING_ENABLE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_TRANS_PWR_REPORTING_ENABLE);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT8_TO_STREAM(pp, local_enable);
+ UINT8_TO_STREAM(pp, remote_enable);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+UINT8 btsnd_hcic_ble_set_default_subrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency,
+ UINT16 continuation_number, UINT16 supervision_timeout)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set default subrate, subrate_min %d subrate_max %d max_latency %d continuation_number %d supervision_timeout %d",
+ subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_DEFAULT_SUBRATE_PARAMS_LEN);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_DEFAULT_SUBRATE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_DEFAULT_SUBRATE_PARAMS_LEN);
+
+ UINT16_TO_STREAM(pp, subrate_min);
+ UINT16_TO_STREAM(pp, subrate_max);
+ UINT16_TO_STREAM(pp, max_latency);
+ UINT16_TO_STREAM(pp, continuation_number);
+ UINT16_TO_STREAM(pp, supervision_timeout);
+
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+UINT8 btsnd_hcic_ble_subrate_request(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency,
+ UINT16 continuation_number, UINT16 supervision_timeout)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci subrate req, conn_handle %d subrate_min %d subrate_max %d max_latency %d continuation_number %d supervision_timeout %d",
+ conn_handle, subrate_min, subrate_max, max_latency, continuation_number, supervision_timeout);
+
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SUBRATE_REQ_LENGTH_PARAMS_LEN);
+
+ pp = (UINT8 *)(p + 1);
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SUBRATE_REQUEST);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SUBRATE_REQ_LENGTH_PARAMS_LEN);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT16_TO_STREAM(pp, subrate_min);
+ UINT16_TO_STREAM(pp, subrate_max);
+ UINT16_TO_STREAM(pp, max_latency);
+ UINT16_TO_STREAM(pp, continuation_number);
+ UINT16_TO_STREAM(pp, supervision_timeout);
+
+ btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+UINT8 btsnd_hcic_ble_set_host_feature(uint16_t bit_num, uint8_t bit_val)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ HCI_TRACE_DEBUG("hci set host feature: bit_num %d bit_val %d", bit_num, bit_val);
+#if (BLE_FEAT_ISO_60_EN == TRUE)
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS_V2);
+#else
+ HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS);
+#endif // #if (BLE_FEAT_ISO_60_EN == TRUE)
+ pp = (UINT8 *)(p + 1);
+#if (BLE_FEAT_ISO_60_EN == TRUE)
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_HOST_FEATURE_V2);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS_V2);
+ // Bit_Number V1
+ UINT16_TO_STREAM(pp, bit_num);
+#else
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_HOST_FEATURE);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS);
+ // Bit_Number V1
+ UINT8_TO_STREAM(pp, bit_num);
+#endif // #if (BLE_FEAT_ISO_60_EN == TRUE)
+ UINT8_TO_STREAM(pp, bit_val);
+ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
diff --git a/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h b/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h
index 065f264f..088d11ab 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/a2d_sbc.h
@@ -30,7 +30,12 @@
/* the length of the SBC Media Payload header. */
#define A2D_SBC_MPL_HDR_LEN 1
-/* the LOSC of SBC media codec capabilitiy */
+/* CIE offset in the info byte sequence */
+#define A2D_SBC_CIE_OFF 3
+/* CIE length in the info byte sequence */
+#define A2D_SBC_CIE_LEN 4
+
+/* the LOSC of SBC media codec capability */
#define A2D_SBC_INFO_LEN 6
/* for Codec Specific Information Element */
diff --git a/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h b/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h
index f62c654f..60c0f26a 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h
@@ -10,6 +10,6 @@
#include "bt_common.h"
void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mode, UINT8 status);
-void btm_acl_disconnected(UINT16 handle, UINT8 reason);
+BOOLEAN btm_acl_disconnected(UINT16 handle, UINT8 reason);
#endif /* ACL_HCI_LINK_INTERFACE_H */
diff --git a/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h b/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h
index 42a1f855..00c16f49 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/avdt_api.h
@@ -519,6 +519,18 @@ extern UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs);
/*******************************************************************************
**
+** Function AVDT_UpdateCodecInfo
+**
+** Description Update codec capability for a stream endpoint.
+**
+**
+** Returns AVDT_SUCCESS if successful, otherwise error.
+**
+*******************************************************************************/
+extern UINT16 AVDT_UpdateCodecInfo(UINT8 handle, UINT8 num_codec, UINT8 *codec_info, UINT16 codec_info_len);
+
+/*******************************************************************************
+**
** Function AVDT_RemoveStream
**
** Description Remove a stream endpoint. This function is called when
diff --git a/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h b/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h
index 21f4bee5..2985c65c 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/avrc_api.h
@@ -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.
**
diff --git a/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h b/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h
index c90fa6cf..06f73c29 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/avrc_defs.h
@@ -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
diff --git a/lib/bt/host/bluedroid/stack/include/stack/bt_types.h b/lib/bt/host/bluedroid/stack/include/stack/bt_types.h
index 5d817632..4050b79d 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/bt_types.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/bt_types.h
@@ -486,6 +486,7 @@ typedef struct {
#define BLE_ADDR_RANDOM_ID 0x03
#define BLE_ADDR_TYPE_MAX BLE_ADDR_RANDOM_ID
#define BLE_ADDR_UNKNOWN_TYPE 0XFF
+#define BLE_ADDR_ANONYMOUS 0xFF
typedef UINT8 tBLE_ADDR_TYPE;
#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
diff --git a/lib/bt/host/bluedroid/stack/include/stack/btm_api.h b/lib/bt/host/bluedroid/stack/include/stack/btm_api.h
index 32420f75..3415df5d 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/btm_api.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/btm_api.h
@@ -75,6 +75,7 @@ enum {
BTM_SET_STATIC_RAND_ADDR_FAIL, /* 25 Command failed */
BTM_INVALID_STATIC_RAND_ADDR, /* 26 invalid static rand addr */
BTM_SEC_DEV_REC_REMOVED, /* 27 Device record relate to the bd_addr is removed */
+ BTM_HCI_ERROR = 128, /* 128 HCI error code from controller (0x80) */
};
typedef uint8_t tBTM_STATUS;
@@ -200,6 +201,8 @@ typedef void (tBTM_SET_LOCAL_PRIVACY_CBACK) (UINT8 status);
typedef void (tBTM_SET_RPA_TIMEOUT_CMPL_CBACK) (UINT8 status);
typedef void (tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK) (UINT8 status);
+
+typedef void (tBTM_BLE_VENDOR_HCI_EVT_CBACK) (UINT8 subevt_code, UINT8 param_len, UINT8 *params);
/*******************************
** Device Coexist status
********************************/
@@ -456,22 +459,22 @@ typedef enum {
#define BTM_COD_SERVICE_INFORMATION 0x8000
/* class of device field macros */
-#define BTM_COD_FORMAT_TYPE(u8, pd) {u8 = pd[2]&0x03;}
+#define BTM_COD_RESERVED_2(u8, pd) {u8 = pd[2]&0x03;}
#define BTM_COD_MINOR_CLASS(u8, pd) {u8 = pd[2]&0xFC;}
#define BTM_COD_MAJOR_CLASS(u8, pd) {u8 = pd[1]&0x1F;}
#define BTM_COD_SERVICE_CLASS(u16, pd) {u16 = pd[0]; u16<<=8; u16 += pd[1]&0xE0;}
/* to set the fields (assumes that format type is always 0) */
-#define FIELDS_TO_COD(pd, mn, mj, sv) {pd[2] = mn; pd[1] = \
- mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \
- pd[0] = (sv) >> 8;}
+#define FIELDS_TO_COD(pd, rs, mn, mj, sv) {pd[2] = (mn & BTM_COD_MINOR_CLASS_MASK) + (rs & BTM_COD_RESERVED_2_MASK); \
+ pd[1] = mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \
+ pd[0] = (sv) >> 8;}
/* the COD masks */
-#define BTM_COD_FORMAT_TYPE_MASK 0x03
#define BTM_COD_MINOR_CLASS_MASK 0xFC
#define BTM_COD_MAJOR_CLASS_MASK 0x1F
#define BTM_COD_SERVICE_CLASS_LO_B 0x00E0
#define BTM_COD_SERVICE_CLASS_MASK 0xFFE0
+#define BTM_COD_RESERVED_2_MASK 0x03
/* BTM service definitions
** Used for storing EIR data to bit mask
@@ -808,6 +811,16 @@ typedef struct {
BD_ADDR rem_bda;
} tBTM_RSSI_RESULTS;
+/* Structure returned with read channel map event (in tBTM_CMPL_CB callback function)
+** in response to BTM_ReadChannelMap call.
+*/
+typedef struct {
+ tBTM_STATUS status; /* BTM operation status */
+ UINT8 hci_status; /* HCI command complete status */
+ UINT8 channel_map[5]; /* Channel map (5 bytes) */
+ BD_ADDR rem_bda; /* Remote device Bluetooth address */
+} tBTM_BLE_CH_MAP_RESULTS;
+
/* Structure returned with read current TX power event (in tBTM_CMPL_CB callback function)
** in response to BTM_ReadTxPower call.
*/
@@ -1027,9 +1040,6 @@ typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc,
#define BTM_INVALID_SCO_INDEX 0xFFFF
#define BTM_INVALID_HCI_HANDLE 0xFFFF
-/* Define an invalid SCO disconnect reason */
-#define BTM_INVALID_SCO_DISC_REASON 0xFFFF
-
/* Define first active SCO index */
#define BTM_FIRST_ACTIVE_SCO_INDEX BTM_MAX_SCO_LINKS
@@ -3024,7 +3034,19 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr,
//extern
tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb);
-
+/*******************************************************************************
+**
+** Function BTM_ReadChannelMap
+**
+** Description This function is called to read the current channel map
+** for the given connection. The results are returned via
+** the callback (tBTM_BLE_CH_MAP_RESULTS).
+**
+** Returns BTM_CMD_STARTED if successfully initiated or error code
+**
+*******************************************************************************/
+tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb);
+#if (BLE_HOST_READ_TX_POWER_EN == TRUE)
/*******************************************************************************
**
** Function BTM_ReadTxPower
@@ -3045,10 +3067,13 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda,
tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb);
tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb);
+#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE)
void BTM_BleGetWhiteListSize(uint16_t *length);
-
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
+void BTM_BleGetPeriodicAdvListSize(uint8_t *size);
+#endif //#if (BLE_50_EXTEND_SYNC_EN == TRUE)
/*******************************************************************************
**
** Function BTM_ReadLinkQuality
@@ -3262,21 +3287,6 @@ UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx);
/*******************************************************************************
**
-** Function BTM_ReadScoDiscReason
-**
-** Description This function is returns the reason why an (e)SCO connection
-** has been removed. It contains the value until read, or until
-** another (e)SCO connection has disconnected.
-**
-** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
-**
-*******************************************************************************/
-//extern
-UINT16 BTM_ReadScoDiscReason (void);
-
-
-/*******************************************************************************
-**
** Function BTM_SetEScoMode
**
** Description This function sets up the negotiated parameters for SCO or
diff --git a/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h
index 1bea9908..7ec384ef 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/btm_ble_api.h
@@ -367,7 +367,6 @@ typedef UINT32 tBTM_BLE_AD_MASK;
#define BTM_BLE_AD_TYPE_MANU HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xff */
typedef UINT8 tBTM_BLE_AD_TYPE;
-#define BTM_BLE_LONG_ADV_MAX_LEN 249
/* Security settings used with L2CAP LE COC */
#define BTM_SEC_LE_LINK_ENCRYPTED 0x01
@@ -395,7 +394,9 @@ typedef UINT8 tBTM_BLE_ADV_TX_POWER;
/* adv tx power in dBm */
typedef struct {
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
UINT8 adv_inst_max; /* max adv instance supported in controller */
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
UINT8 rpa_offloading;
UINT16 tot_scan_results_strg;
UINT8 max_irk_list_sz;
@@ -499,6 +500,7 @@ typedef struct {
tBTM_BLE_ADV_TX_POWER tx_power;
} tBTM_BLE_ADV_PARAMS;
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
typedef struct {
UINT8 *p_sub_code; /* dynamic array to store sub code */
UINT8 *p_inst_id; /* dynamic array to store instance id */
@@ -530,6 +532,7 @@ typedef struct {
tBTM_BLE_MULTI_ADV_INST *p_adv_inst; /* dynamic array to store adv instance */
tBTM_BLE_MULTI_ADV_OPQ op_q;
} tBTM_BLE_MULTI_ADV_CB;
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
typedef UINT8 tGATT_IF;
@@ -810,15 +813,16 @@ typedef struct {
typedef struct {
UINT8 filter_policy;
- #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
+#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
UINT8 reports_disabled;
UINT8 filter_duplicates;
- #endif
+#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE)
UINT8 sid;
tBLE_ADDR_TYPE addr_type;
BD_ADDR addr;
UINT16 skip;
UINT16 sync_timeout;
+ UINT8 sync_cte_type;
} tBTM_BLE_Periodic_Sync_Params;
typedef struct {
@@ -944,6 +948,7 @@ typedef UINT8 tBTM_BLE_CONN_TYPE;
#define ADV_INFO_PRESENT 0x00
#define NO_ADV_INFO_PRESENT 0x01
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
typedef btgatt_track_adv_info_t tBTM_BLE_TRACK_ADV_DATA;
typedef void (tBTM_BLE_TRACK_ADV_CBACK)(tBTM_BLE_TRACK_ADV_DATA *p_track_adv_data);
@@ -961,6 +966,7 @@ enum {
};
typedef UINT8 tBTM_BLE_TRACK_ADV_ACTION;
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
#define BTM_BLE_MULTI_ADV_INVALID 0
@@ -1007,11 +1013,14 @@ typedef void (tBTM_START_STOP_ADV_CMPL_CBACK) (UINT8 status);
typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info);
typedef void (tBTM_CLEAR_ADV_CMPL_CBACK) (UINT8 status);
typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS status);
+typedef void (tBTM_SET_CSA_SUPPORT_CMPL_CBACK) (tBTM_STATUS status);
+typedef void (tBTM_SET_VENDOR_EVT_MASK_CBACK) (tBTM_STATUS status);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
#define BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT 1
#define BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT 2
#define BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT 3
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
#define BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT 4
#define BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT 5
#define BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT 6
@@ -1020,29 +1029,42 @@ typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS status);
#define BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT 9
#define BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT 10
#define BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT 11
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
#define BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT 12
#define BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT 13
#define BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT 14
#define BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT 15
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
#define BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT 16
#define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT 17
#define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT 18
#define BTM_BLE_5_GAP_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT 19
#define BTM_BLE_5_GAP_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT 20
#define BTM_BLE_5_GAP_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT 21
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
#define BTM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT 22
#define BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT 23
#define BTM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT 24
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
#define BTM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT 25
#define BTM_BLE_5_GAP_PHY_UPDATE_COMPLETE_EVT 26
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
#define BTM_BLE_5_GAP_EXT_ADV_REPORT_EVT 27
#define BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT 28
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
#define BTM_BLE_5_GAP_ADV_TERMINATED_EVT 29
#define BTM_BLE_5_GAP_SCAN_REQ_RECEIVED_EVT 30
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#define BTM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT 31
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
#define BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT 32
#define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT 33
#define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT 34
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#define BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT 35
#define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT 36
@@ -1051,9 +1073,76 @@ typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS status);
#define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT 39
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#define BTM_BLE_GAP_SET_PRIVACY_MODE_COMPLETE_EVT 40
-#define BTM_BLE_5_GAP_UNKNOWN_EVT 41
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#define BTM_BLE_GAP_ENH_READ_TRANS_POWER_LEVEL_EVT 41
+#define BTM_BLE_GAP_READ_REMOTE_TRANS_POWER_LEVEL_EVT 42
+#define BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_PARAMS_EVT 43
+#define BTM_BLE_GAP_SET_PATH_LOSS_REPORTING_ENABLE_EVT 44
+#define BTM_BLE_GAP_SET_TRANS_POWER_REPORTING_ENABLE_EVT 45
+#define BTM_BLE_GAP_PATH_LOSS_THRESHOLD_EVT 46
+#define BTM_BLE_GAP_TRANMIT_POWER_REPORTING_EVT 47
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#define BTM_BLE_GAP_SET_DEFAULT_SUBRATE_EVT 48
+#define BTM_BLE_GAP_SUBRATE_REQUEST_EVT 49
+#define BTM_BLE_GAP_SUBRATE_CHANGE_EVT 50
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#define BTM_BLE_GAP_SET_HOST_FEATURE_EVT 51
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#define BTM_BLE_5_GAP_UNKNOWN_EVT 52
typedef UINT8 tBTM_BLE_5_GAP_EVENT;
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#define BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT 1
+#define BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT 2
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT 3
+#define BTM_BLE_ISO_BIG_SYNC_LOST_EVT 4
+#define BTM_BLE_ISO_BIG_SYNC_TERMINATE_COMPLETE_EVT 5
+#define BTM_BLE_ISO_BIGINFO_ADV_REPORT_EVT 6
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define BTM_BLE_ISO_DATA_PATH_UPFATE_EVT 7
+#define BTM_BLE_ISO_READ_TX_SYNC_EVT 9
+#define BTM_BLE_ISO_READ_LINK_QUALITY_EVT 10
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#define BTM_BLE_ISO_SET_CIG_PARAMS_EVT 11
+#define BTM_BLE_ISO_CREATE_CIS_EVT 12
+#define BTM_BLE_ISO_REMOVE_CIG_EVT 13
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#define BTM_BLE_ISO_ACCEPT_CIS_REQ_EVT 14
+#define BTM_BLE_ISO_REJECT_CIS_REQ_EVT 15
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#define BTM_BLE_ISO_CIS_ESTABLISHED_EVT 16
+#define BTM_BLE_ISO_CIS_REQUEST_EVT 17
+#define BTM_BLE_ISO_CIS_DISCONNECTED_EVT 18
+#define BTM_BLE_ISO_UNKNOWN_EVT 19
+typedef UINT8 tBTM_BLE_ISO_EVENT;
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#define BTM_BLE_CTE_SET_TRANS_PARAMS_EVT 1
+#define BTM_BLE_CTE_SET_TRANS_ENABLE_EVT 2
+#define BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT 3
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT 4
+#define BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT 5
+#define BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT 6
+#define BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT 7
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define BTM_BLE_CTE_READ_ANT_INFOR_EVT 8
+#define BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT 9
+#define BTM_BLE_CTE_CONN_IQ_REPORT_EVT 10
+#define BTM_BLE_CTE_REQUEST_FAILED_EVT 11
+typedef UINT8 tBTM_BLE_CTE_EVENT;
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
#define BTM_BLE_EXT_ADV_DATA_COMPLETE 0x00
#define BTM_BLE_EXT_ADV_DATA_INCOMPLETE 0x01
#define BTM_BLE_EXT_ADV_DATA_TRUNCATED 0x02
@@ -1100,46 +1189,58 @@ typedef struct {
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_SET_PERF_PHY_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_EXT_ADV_SET_RAND_ADDR_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_EXT_ADV_SET_PARAMS_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_EXT_ADV_DATA_SET_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_EXT_ADV_SCAN_RSP_DATA_SET_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance_num;
+ UINT8 instance[10];
} tBTM_BLE_EXT_ADV_START_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_EXT_ADV_STOP_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_PERIOD_ADV_SET_PARAMS_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_PERIOD_ADV_DATA_SET_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_PERIOD_ADV_START_CMPL;
typedef struct {
UINT8 status;
+ UINT8 instance;
} tBTM_BLE_PERIOD_ADV_STOP_CMPL;
typedef struct {
@@ -1230,6 +1331,7 @@ typedef struct {
UINT16 sync_handle;
UINT8 tx_power;
INT8 rssi;
+ UINT8 cte_type;
tBTM_BLE_EXT_ADV_DATA_STATUS data_status;
UINT8 data_length;
UINT8 *data;
@@ -1295,39 +1397,409 @@ typedef struct {
} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV;
#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+ UINT8 phy;
+ INT8 cur_tx_pwr_level;
+ INT8 max_tx_pwr_level;
+} __attribute__((packed)) tBTM_BLE_ENH_TRANS_PWR_LEVEL_CMPL;
+
+typedef struct {
+ UINT8 status;
+} __attribute__((packed)) tBTM_BLE_REMOTE_TRANS_PWR_LEVEL_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_SET_PATH_LOSS_RPTING_PARAMS;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_SET_PATH_LOSS_RPTING_ENABLE;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_SET_TRANS_POWER_RPTING_ENABLE;
+
+typedef struct {
+ UINT16 conn_handle;
+ UINT8 cur_path_loss;
+ UINT8 zone_entered;
+} __attribute__((packed)) tBTM_BLE_PATH_LOSS_THRESHOLD_EVT;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+ UINT8 reason;
+ UINT8 phy;
+ INT8 tx_power_level;
+ UINT8 tx_power_level_flag;
+ INT8 delta;
+} __attribute__((packed)) tBTM_BLE_TRANS_POWER_REPORT_EVT;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+ UINT16 subrate_factor;
+ UINT16 peripheral_latency;
+ UINT16 continuation_number;
+ UINT16 supervision_timeout;
+} __attribute__((packed)) tBTM_BLE_SUBRATE_CHANGE_EVT;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+typedef struct {
+ UINT8 status;
+ UINT8 big_handle;
+ UINT32 big_sync_delay;
+ UINT32 transport_latency;
+ UINT8 phy;
+ UINT8 nse;
+ UINT8 bn;
+ UINT8 pto;
+ UINT8 irc;
+ UINT16 max_pdu;
+ UINT16 iso_interval;
+ UINT8 num_bis;
+ UINT16 bis_handle[BLE_ISO_BIS_MAX_COUNT];
+} tBTM_BLE_BIG_CREATE_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT8 big_handle;
+ UINT8 reason;
+} tBTM_BLE_BIG_TERMINATE_CMPL;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+typedef struct {
+ UINT8 status;
+ UINT8 big_handle;
+ UINT32 transport_latency_big;
+ UINT8 nse;
+ UINT8 bn;
+ UINT8 pto;
+ UINT8 irc;
+ UINT16 max_pdu;
+ UINT16 iso_interval;
+ uint8_t num_bis;
+ uint16_t bis_handle[BLE_ISO_BIS_MAX_COUNT];
+} tBTM_BLE_BIG_SYNC_ESTAB_CMPL;
+
+typedef struct {
+ UINT8 big_handle;
+ UINT8 reason;
+} tBTM_BLE_BIG_SYNC_LOST_EVT;
+
+typedef struct {
+ UINT16 sync_handle;
+ UINT8 num_bis;
+ UINT8 nse;
+ UINT16 iso_interval;
+ UINT8 bn;
+ UINT8 pto;
+ UINT8 irc;
+ UINT16 max_pdu;
+ UINT32 sdu_interval;
+ UINT32 max_sdu;
+ UINT8 phy;
+ UINT8 framing;
+ UINT8 encryption;
+} tBTM_BLE_BIGINFO_ADV_REPORT_EVT;
+
+typedef struct {
+ UINT8 status;
+ UINT16 big_hdl;
+} tBTM_BLE_BIG_SYNC_TERMINATE_EVT;
+
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+ UINT32 cig_sync_delay;
+ UINT32 cis_sync_delay;
+ UINT32 trans_lat_c_to_p;
+ UINT32 trans_lat_p_to_c;
+ UINT8 phy_c_to_p;
+ UINT8 phy_p_to_c;
+ UINT8 nse;
+ UINT8 bn_c_to_p;
+ UINT8 bn_p_to_c;
+ UINT8 ft_c_to_p;
+ UINT8 ft_p_to_c;
+ UINT16 max_pdu_c_to_p;
+ UINT16 max_pdu_p_to_c;
+ UINT16 iso_interval;
+#if (BLE_FEAT_ISO_60_EN == TRUE)
+ UINT32 sub_interval;
+ UINT16 max_sdu_c_to_p;
+ UINT16 max_sdu_p_to_c;
+ UINT32 sdu_int_c_to_p;
+ UINT32 sdu_int_p_to_c;
+ UINT8 framing;
+#endif // #if (BLE_FEAT_ISO_60_EN == TRUE)
+} tBTM_BLE_CIS_ESTABLISHED_CMPL;
+
+typedef struct {
+ UINT16 cis_handle;
+ UINT8 reason;
+} tBTM_BLE_CIS_DISCON_CMPL;
+
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+typedef struct {
+ UINT8 status;
+ UINT16 cis_handle;
+} tBTM_BLE_ISO_REJECT_CIS_REQ_EVT;
+
+
+typedef struct {
+ UINT16 acl_handle;
+ UINT16 cis_handle;
+ UINT8 cig_id;
+ UINT8 cis_id;
+} tBTM_BLE_CIS_REQUEST_CMPL;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+typedef enum {
+ BTM_BLE_ISO_DATA_PATH_UNKNOWN = 0,
+ BTM_BLE_ISO_DATA_PATH_SETUP = 1,
+ BTM_BLE_ISO_DATA_PATH_REMOVE = 2,
+ BTM_BLE_ISO_DATA_PATH_MAX,
+} tBTM_BLE_ISO_DATA_PATH_UPDATE_TYPE;
+
+typedef struct {
+ UINT8 status;
+ tBTM_BLE_ISO_DATA_PATH_UPDATE_TYPE op_type;
+ UINT16 conn_hdl;
+} tBTM_BLE_ISO_DATA_PATH_UPDATE_EVT;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_hdl;
+ UINT16 pkt_seq_num;
+ UINT32 tx_time_stamp;
+ UINT32 time_offset;
+} tBTM_BLE_ISO_READ_TX_SYNC_EVT;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_hdl;
+ UINT32 tx_unacked_pkts;
+ UINT32 tx_flushed_pkts;
+ UINT32 tx_last_subevt_pkts;
+ UINT32 retransmitted_pkts;
+ UINT32 crc_error_pkts;
+ UINT32 rx_unreceived_pkts;
+ UINT32 duplicate_pkts;
+} tBTM_BLE_ISO_READ_LINK_QUALITY_EVT;
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+typedef struct {
+ UINT8 status;
+ UINT8 cig_id;
+ UINT8 cis_count;
+ UINT16 conn_hdl[BLE_ISO_CIS_MAX_COUNT];
+} tBTM_BLE_ISO_SET_CIG_PARAMS_EVT;
+
+typedef struct {
+ UINT8 status;
+ UINT8 cig_id;
+} tBTM_BLE_ISO_REMOVE_CIG_EVT;
+
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+typedef union {
+ UINT8 status;
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+ tBTM_BLE_BIG_CREATE_CMPL btm_big_cmpl;
+ tBTM_BLE_BIG_TERMINATE_CMPL btm_big_term;
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ tBTM_BLE_BIG_SYNC_ESTAB_CMPL btm_big_sync_estab;
+ tBTM_BLE_BIG_SYNC_LOST_EVT btm_big_sync_lost;
+ tBTM_BLE_BIGINFO_ADV_REPORT_EVT btm_biginfo_report;
+ tBTM_BLE_BIG_SYNC_TERMINATE_EVT btm_big_sync_ter;
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+ tBTM_BLE_ISO_DATA_PATH_UPDATE_EVT btm_data_path_update;
+ tBTM_BLE_ISO_READ_TX_SYNC_EVT btm_read_tx_sync;
+ tBTM_BLE_ISO_READ_LINK_QUALITY_EVT btm_read_link_quality;
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+ tBTM_BLE_ISO_SET_CIG_PARAMS_EVT btm_set_cig_params;
+ tBTM_BLE_ISO_REMOVE_CIG_EVT btm_remove_cig;
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+ tBTM_BLE_ISO_REJECT_CIS_REQ_EVT btm_reject_cis_req;
+ tBTM_BLE_CIS_REQUEST_CMPL btm_cis_request_evt;
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+ tBTM_BLE_CIS_ESTABLISHED_CMPL btm_cis_established_evt;
+ tBTM_BLE_CIS_DISCON_CMPL btm_cis_disconnectd_evt;
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+} tBTM_BLE_ISO_CB_PARAMS;
+
+typedef void (*tBTM_BLE_ISO_CBACK)(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *params);
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+typedef struct {
+ UINT8 status;
+} __attribute__((packed)) tBTM_BLE_CTE_SET_TRANS_PARAMS_CMPL;
+
+typedef struct {
+ UINT8 status;
+} __attribute__((packed)) tBTM_BLE_CTE_SET_TRANS_EN_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT16 sync_handle;
+} __attribute__((packed)) tBTM_BLE_CTE_IQ_SAMP_EN_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_CTE_CONN_RECV_PARAMS_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_CTE_CONN_TRANS_PARAMS_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_CTE_CONN_REQ_ENABLE_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_CTE_CONN_RSP_ENABLE_CMPL;
+
+typedef struct {
+ UINT8 status;
+ UINT8 supported_switching_sampling_rates;
+ UINT8 num_ant;
+ UINT8 max_switching_pattern_len;
+ UINT8 max_cte_len;
+} __attribute__((packed)) tBTM_BLE_CTE_READ_ANT_INFOR_CMPL;
+
+typedef struct {
+ UINT16 sync_handle;
+ UINT8 channel_idx;
+ INT16 rssi;
+ UINT8 rssi_ant_id;
+ UINT8 cte_type;
+ UINT8 slot_dur;
+ UINT8 pkt_status;
+ UINT16 periodic_evt_counter;
+ UINT8 sample_count;
+ UINT8 i_sample[0x52];
+ UINT8 q_sample[0x52];
+} __attribute__((packed)) tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT;
+
+typedef struct {
+ UINT16 conn_handle;
+ UINT8 rx_phy;
+ UINT8 data_channel_idx;
+ INT16 rssi;
+ UINT8 rssi_ant_id;
+ UINT8 cte_type;
+ UINT8 slot_dur;
+ UINT8 pkt_status;
+ UINT16 conn_evt_counter;
+ UINT8 sample_count;
+ UINT8 i_sample[0x52];
+ UINT8 q_sample[0x52];
+} __attribute__((packed)) tBTM_BLE_CTE_CONN_IQ_REPORT_EVT;
+
+typedef struct {
+ UINT8 status;
+ UINT16 conn_handle;
+} __attribute__((packed)) tBTM_BLE_CTE_REQ_FAILED_EVT;
+
+typedef union {
+ UINT8 status;
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ tBTM_BLE_CTE_SET_TRANS_PARAMS_CMPL cte_trans_params_cmpl;
+ tBTM_BLE_CTE_SET_TRANS_EN_CMPL cte_trans_en_cmpl;
+ tBTM_BLE_CTE_IQ_SAMP_EN_CMPL cte_iq_samp_en_cmpl;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ tBTM_BLE_CTE_CONN_RECV_PARAMS_CMPL cte_recv_params_cmpl;
+ tBTM_BLE_CTE_CONN_TRANS_PARAMS_CMPL cte_conn_trans_params_cmpl;
+ tBTM_BLE_CTE_CONN_REQ_ENABLE_CMPL cte_conn_req_en_cmpl;
+ tBTM_BLE_CTE_CONN_RSP_ENABLE_CMPL cte_conn_rsp_en_cmpl;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ tBTM_BLE_CTE_READ_ANT_INFOR_CMPL cte_read_ant_infor_cmpl;
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+ tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT cte_connless_iq_rpt;
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+ tBTM_BLE_CTE_CONN_IQ_REPORT_EVT cte_conn_iq_rpt;
+ tBTM_BLE_CTE_REQ_FAILED_EVT cte_req_failed;
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+} tBTM_BLE_CTE_CB_PARAMS;
+
+typedef void (*tBTM_BLE_CTE_CBACK)(tBTM_BLE_CTE_EVENT event, tBTM_BLE_CTE_CB_PARAMS *params);
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
typedef union {
UINT8 status;
tBTM_BLE_READ_PHY_CMPL read_phy;
tBTM_BLE_SET_PREF_DEF_PHY_CMPL set_perf_def_phy;
tBTM_BLE_SET_PERF_PHY_CMPL set_perf_phy;
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
tBTM_BLE_EXT_ADV_SET_RAND_ADDR_CMPL set_ext_rand_addr;
tBTM_BLE_EXT_ADV_SET_PARAMS_CMPL set_params;
tBTM_BLE_EXT_ADV_DATA_SET_CMPL adv_data_set;
tBTM_BLE_EXT_ADV_SCAN_RSP_DATA_SET_CMPL scan_rsp_data_set;
tBTM_BLE_EXT_ADV_START_CMPL adv_start;
tBTM_BLE_EXT_ADV_STOP_CMPL adv_stop;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
+#if (BLE_50_PERIODIC_ADV_EN == TRUE)
tBTM_BLE_PERIOD_ADV_SET_PARAMS_CMPL per_adv_set_params;
tBTM_BLE_PERIOD_ADV_DATA_SET_CMPL per_adv_data_set;
tBTM_BLE_PERIOD_ADV_START_CMPL per_adv_start;
tBTM_BLE_PERIOD_ADV_STOP_CMPL per_adv_stop;
+#endif // #if (BLE_50_PERIODIC_ADV_EN == TRUE)
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
tBTM_BLE_PERIOD_ADV_SYNC_CREATE_CMPL per_adv_sync_create;
tBTM_BLE_PERIOD_ADV_SYNC_CANCEL_CMPL per_adv_sync_cancel;
tBTM_BLE_PERIOD_ADV_SYNC_TEMINAT_CMPL per_adv_sync_term;
tBTM_BLE_PERIOD_ADV_ADD_DEV_CMPL per_adv_add_dev;
tBTM_BLE_PERIOD_ADV_REMOVE_DEV_CMPL per_adv_remove_dev;
tBTM_BLE_PEROID_ADV_CLEAR_DEV_CMPL per_adv_clear_dev;
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
tBTM_BLE_SET_EXT_SCAN_PARAMS_CMPL ext_scan;
tBTM_BLE_EXT_SCAN_START_CMPL scan_start;
tBTM_BLE_EXT_SCAN_STOP_CMPL scan_stop;
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
tBTM_BLE_PREF_EXT_CONN_SET_PARAMS_CMPL ext_conn_set_params;
tBTM_BLE_PHY_UPDATE_CMPL phy_update;
+#if (BLE_50_EXTEND_SCAN_EN == TRUE)
tBTM_BLE_EXT_ADV_REPORT ext_adv_report;
+#endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE)
+#if (BLE_50_EXTEND_ADV_EN == TRUE)
tBTM_BLE_ADV_TERMINAT adv_term;
tBTM_BLE_SCAN_REQ_RECEIVED scan_req;
+#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
tBTM_BLE_CHANNEL_SEL_ALG channel_sel;
+#if (BLE_50_EXTEND_SYNC_EN == TRUE)
tBTM_PERIOD_ADV_REPORT period_adv_report;
tBTM_BLE_PERIOD_ADV_SYNC_LOST sync_lost;
tBTM_BLE_PERIOD_ADV_SYNC_ESTAB sync_estab;
+#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
tBTM_BLE_PERIOD_ADV_RECV_ENABLE_CMPL per_adv_recv_enable;
tBTM_BLE_PERIOD_ADV_SYNC_TRANS_CMPL per_adv_sync_trans;
@@ -1335,6 +1807,18 @@ typedef union {
tBTM_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS_CMPL set_past_params;
tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV past_recv;
#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+ tBTM_BLE_ENH_TRANS_PWR_LEVEL_CMPL enh_trans_pwr_level_cmpl;
+ tBTM_BLE_REMOTE_TRANS_PWR_LEVEL_CMPL remote_pwr_level_cmpl;
+ tBTM_BLE_SET_PATH_LOSS_RPTING_PARAMS path_loss_rpting_params;
+ tBTM_BLE_SET_PATH_LOSS_RPTING_ENABLE path_loss_rpting_enable;
+ tBTM_BLE_SET_TRANS_POWER_RPTING_ENABLE trans_pwr_rpting_enable;
+ tBTM_BLE_PATH_LOSS_THRESHOLD_EVT path_loss_thres_evt;
+ tBTM_BLE_TRANS_POWER_REPORT_EVT trans_pwr_report_evt;
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+ tBTM_BLE_SUBRATE_CHANGE_EVT subrate_change_evt;
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
} tBTM_BLE_5_GAP_CB_PARAMS;
typedef struct {
@@ -1370,6 +1854,7 @@ extern "C" {
*******************************************************************************/
void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb);
void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk_len_chane_cb);
+void BTM_BleRegisterVendorHciEventCallback(tBTM_BLE_VENDOR_HCI_EVT_CBACK *vendor_hci_evt_cb);
/*******************************************************************************
**
@@ -1413,23 +1898,6 @@ BOOLEAN BTM_SecAddBleKey (BD_ADDR bd_addr, tBTM_LE_KEY_VALUE *p_le_key,
/*******************************************************************************
**
-** Function BTM_BleSetAdvParams
-**
-** Description This function is called to set advertising parameters.
-**
-** Parameters: None.
-**
-** Returns void
-**
-*******************************************************************************/
-//extern
-tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max,
- tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP chnl_map);
-
-
-
-/*******************************************************************************
-**
** Function BTM_BleSetAdvParamsAll
**
** Description This function is called to set all of the advertising parameters.
@@ -1474,20 +1942,6 @@ tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask,
/*******************************************************************************
**
-** Function BTM_BleWriteLongAdvData
-**
-** Description This function is called to write long advertising data.
-**
-** Parameters: adv_data: long advertising data
-** adv_data_len: the length of long advertising data
-**
-** Returns void
-**
-*******************************************************************************/
-tBTM_STATUS BTM_BleWriteLongAdvData(uint8_t *adv_data, uint8_t adv_data_len);
-
-/*******************************************************************************
-**
** Function BTM_BleWriteAdvDataRaw
**
** Description This function is called to write raw advertising data.
@@ -1539,6 +1993,7 @@ void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max,
//extern
void BTM_BleObtainVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb);
+#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
/*******************************************************************************
**
** Function BTM_BleSetScanParams
@@ -1559,7 +2014,7 @@ void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval,
UINT32 scan_window, tBLE_SCAN_MODE scan_type,
tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback);
-
+#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE)
/*******************************************************************************
**
@@ -1658,6 +2113,7 @@ tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
//extern
tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value);
+#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleReadScanReports
@@ -1673,7 +2129,9 @@ tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value);
//extern
tBTM_STATUS BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode,
tBTM_BLE_REF_VALUE ref_value);
+#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE)
+#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleTrackAdvertiser
@@ -1689,6 +2147,7 @@ tBTM_STATUS BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode,
//extern
tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback,
tBTM_BLE_REF_VALUE ref_value);
+#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE)
/*******************************************************************************
**
@@ -2100,7 +2559,7 @@ void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback);
**
*******************************************************************************/
//extern
-UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length);
+UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT16 adv_data_len, UINT8 type, UINT8 *p_length);
/*******************************************************************************
**
@@ -2259,6 +2718,7 @@ BOOLEAN BTM_BleLocalPrivacyEnabled(void);
//extern
void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on);
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
** Function BTM_BleMaxMultiAdvInstanceCount
@@ -2270,6 +2730,7 @@ void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on);
*******************************************************************************/
//extern
UINT8 BTM_BleMaxMultiAdvInstanceCount(void);
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************
**
@@ -2450,6 +2911,7 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning (BD_ADDR bd_addr);
//extern
UINT8 BTM_BleGetSupportedKeySize (BD_ADDR bd_addr);
+#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
/*******************************************************************************/
/* Multi ADV API */
/*******************************************************************************
@@ -2522,6 +2984,8 @@ tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
//extern
tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id);
+#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE)
+
/*******************************************************************************
**
** Function BTM_BleAdvFilterParamSetup
@@ -2712,6 +3176,33 @@ BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type,
UINT8 privacy_mode,
tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_callback);
+/*******************************************************************************
+**
+** Function BTM_BleSetCsaSupport
+**
+** Description This function is called to set the ChSel field of Advertising or Initiating PDUs
+**
+** Parameters csa_select - Select LE Channel Selection Algorithm.
+** p_callback - Callback function to be called when the operation is completed.
+**
+** Returns TRUE if the operation was successful, otherwise FALSE.
+**
+*******************************************************************************/
+BOOLEAN BTM_BleSetCsaSupport (UINT8 csa_select, tBTM_SET_CSA_SUPPORT_CMPL_CBACK *p_callback);
+
+/*******************************************************************************
+**
+** Function BTM_BleSetVendorEventMask
+**
+** Description This function is called to set the vendor HCI event mask
+**
+** Parameters evt_mask - vendor HCI event mask.
+** p_callback - Callback function to be called when the operation is completed.
+**
+** Returns TRUE if the operation was successful, otherwise FALSE.
+**
+*******************************************************************************/
+BOOLEAN BTM_BleSetVendorEventMask(UINT32 evt_mask, tBTM_SET_VENDOR_EVT_MASK_CBACK *p_callback);
/*
#ifdef __cplusplus
}
@@ -2762,12 +3253,13 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params);
tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period);
void BTM_BleSetPreferExtenedConnParams(BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params);
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
void BTM_BleEnhancedReceiverTest(UINT8 rx_freq, UINT8 phy, UINT8 modulation_index, tBTM_CMPL_CB *p_cmd_cmpl_cback);
void BTM_BleEnhancedTransmitterTest(UINT8 tx_freq, UINT8 test_data_len, UINT8 packet_payload, UINT8 phy, tBTM_CMPL_CB *p_cmd_cmpl_cback);
-
-#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable);
@@ -2779,4 +3271,93 @@ void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8
void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type);
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+void BTM_BleIsoRegisterCallback(tBTM_BLE_ISO_CBACK cb);
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency,
+ uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing,
+ uint8_t encryption, uint8_t *broadcast_code);
+
+tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse,
+ uint16_t max_sdu, uint16_t max_pdu, uint8_t phy,
+ uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc,
+ uint8_t pto, uint8_t encryption, uint8_t *broadcast_code);
+
+tBTM_STATUS BTM_BleBigTerminate(UINT8 big_handle, UINT8 reason);
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle,
+ uint8_t encryption, uint8_t *bc_code,
+ uint8_t mse, uint16_t big_sync_timeout,
+ uint8_t num_bis, uint8_t *bis);
+
+tBTM_STATUS BTM_BleBigSyncTerminate(uint8_t big_handle);
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+tBTM_STATUS BTM_BleIsoSetDataPath(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt,
+ uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len,
+ uint8_t *codec_cfg);
+tBTM_STATUS BTM_BleIsoRemoveDataPath(uint16_t conn_handle, uint8_t data_path_dir);
+
+tBTM_STATUS BTM_BleIsoReadTxSync(uint16_t iso_hdl);
+tBTM_STATUS BTM_BleIsoReadLinkQuality(uint16_t iso_hdl);
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+tBTM_STATUS BTM_BleSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing,
+ uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, uint8_t *cis_params);
+tBTM_STATUS BTM_BleSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c, uint16_t iso_interval,
+ uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt, uint8_t *cis_params);
+tBTM_STATUS BTM_BleCreateCis(uint8_t cis_count, uint8_t *cis_hdls);
+tBTM_STATUS BTM_BleRemoveCig(uint8_t cig_id);
+#endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+tBTM_STATUS BTM_BleAcceptCisReq(uint16_t cis_handle);
+tBTM_STATUS BTM_BleRejectCisReq(uint16_t cis_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+#if (BLE_FEAT_ISO_CIG_EN == TRUE)
+tBTM_STATUS BTM_BleDisconCis(uint16_t cis_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE)
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+#if (BLE_FEAT_CTE_EN == TRUE)
+void BTM_BleCteRegisterCallback(tBTM_BLE_CTE_CBACK cb);
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids);
+tBTM_STATUS BTM_BleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en);
+tBTM_STATUS BTM_BleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids);
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+tBTM_STATUS BTM_BleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t switching_pattern_len, uint8_t *ant_ids);
+tBTM_STATUS BTM_BleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids);
+tBTM_STATUS BTM_BleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_int,
+ uint8_t req_cte_len, uint8_t req_cte_type);
+tBTM_STATUS BTM_BleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable);
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+
+tBTM_STATUS BTM_BleCteReadAntInfor(void);
+
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+void BTM_BleEnhReadTransPowerLevel(uint16_t conn_handle, uint8_t phy);
+void BTM_BleReadRemoteTransPwrLevel(uint16_t conn_handle, uint8_t phy);
+void BTM_BleSetPathLossRptParams(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis,
+ uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent);
+void BTM_BleSetPathLossRptEnable(uint16_t conn_handle, uint8_t enable);
+void BTM_BleSetTransPwrRptEnable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable);
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+void BTM_BleSetDefaultSubrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency,
+ UINT16 continuation_number, UINT16 supervision_timeout);
+
+void BTM_BleSubrateRequest(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max,
+ UINT16 max_latency, UINT16 continuation_number, UINT16 supervision_timeout);
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+tBTM_STATUS BTM_BleSetHostFeature(uint16_t bit_num, uint8_t bit_val);
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#endif
diff --git a/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h b/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h
index fa1ed498..7c208d8c 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/dyn_mem.h
@@ -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
@@ -53,6 +55,8 @@
#define SLIP_DYNAMIC_MEMORY TRUE
#define LLCP_DYNAMIC_MEMORY TRUE
#define BTC_SBC_DEC_DYNAMIC_MEMORY TRUE
+#define BTC_GAP_BT_DYNAMIC_MEMORY TRUE
+#define L2CAP_DYNAMIC_MEMORY TRUE
#else /* #if UC_BT_BLE_DYNAMIC_ENV_MEMORY */
#define BTU_DYNAMIC_MEMORY FALSE
@@ -79,6 +83,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
@@ -87,6 +93,8 @@
#define SLIP_DYNAMIC_MEMORY FALSE
#define LLCP_DYNAMIC_MEMORY FALSE
#define BTC_SBC_DEC_DYNAMIC_MEMORY FALSE
+#define BTC_GAP_BT_DYNAMIC_MEMORY FALSE
+#define L2CAP_DYNAMIC_MEMORY FALSE
#endif /* #if UC_BT_BLE_DYNAMIC_ENV_MEMORY */
@@ -191,6 +199,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
diff --git a/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h b/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h
index fed2ea9a..6c63db62 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/gatt_api.h
@@ -139,7 +139,7 @@ typedef UINT16 tGATT_DISCONN_REASON;
/* max length of an attribute value
*/
#ifndef GATT_MAX_ATTR_LEN
-#define GATT_MAX_ATTR_LEN 512
+#define GATT_MAX_ATTR_LEN GATT_MAX_MTU_SIZE
#endif
/* default GATT MTU size over LE link
diff --git a/lib/bt/host/bluedroid/stack/include/stack/goep_common.h b/lib/bt/host/bluedroid/stack/include/stack/goep_common.h
new file mode 100644
index 00000000..74cb3ca8
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/include/stack/goep_common.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "common/bt_target.h"
+
+/* GOEP Client or Server(not supported yet) API return code */
+#define GOEP_SUCCESS 0x00 /* Operation successful */
+#define GOEP_FAILURE 0x01 /* Operation failed */
+#define GOEP_NO_RESOURCES 0x02 /* Not enough resources */
+#define GOEP_BAD_HANDLE 0x04 /* Bad handle */
+#define GOEP_INVALID_PARAM 0x08 /* Invalid parameter */
+#define GOEP_INVALID_STATE 0x10 /* Operation not allow in current state */
+#define GOEP_CONGEST 0x20 /* Congest */
+#define GOEP_TL_ERROR 0x40 /* Lower transport layer error */
diff --git a/lib/bt/host/bluedroid/stack/include/stack/goepc_api.h b/lib/bt/host/bluedroid/stack/include/stack/goepc_api.h
new file mode 100644
index 00000000..f2b93f86
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/include/stack/goepc_api.h
@@ -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) */
diff --git a/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h b/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h
index 21b14881..23f9b3e6 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/hcidefs.h
@@ -357,8 +357,12 @@
#define HCI_BLE_READ_PHY (0x0030 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_DEFAULT_PHY (0x0031 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_PHY (0x0032 | HCI_GRP_BLE_CMDS)
+#endif
+#if (BLE_50_DTM_TEST_EN == TRUE)
#define HCI_BLE_ENH_RX_TEST (0x0033 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_ENH_TX_TEST (0x0034 | HCI_GRP_BLE_CMDS)
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
#define HCI_BLE_SET_ADV_RAND_ADDR (0x0035 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_EXT_ADV_PARAM (0x0036 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_EXT_ADV_DATA (0x0037 | HCI_GRP_BLE_CMDS)
@@ -386,6 +390,20 @@
#define HCI_BLE_WR_RF_PATH_COMPENSATION (0x004D | HCI_GRP_BLE_CMDS)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS)
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#define HCI_BLE_SET_CONNLESS_CTE_TRANS_PARAMS (0x0051 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_CONNLESS_CTE_TRANS_ENABLE (0x0052 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_CONNLESS_IQ_SAMPLING_ENABLE (0x0053 | HCI_GRP_BLE_CMDS)
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define HCI_BLE_SET_CONN_CTE_RECEIVE_PARAMS (0x0054 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_CONN_CTE_TRANS_PARAMS (0x0055 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_CONN_CTE_REQ_ENABLE (0x0056 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_CONN_CTE_RSP_ENABLE (0x0057 | HCI_GRP_BLE_CMDS)
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define HCI_BLE_READ_ANT_INFOR (0x0058 | HCI_GRP_BLE_CMDS)
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS)
@@ -393,6 +411,38 @@
#define HCI_BLE_SET_PAST_PARAMS (0x005C | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_DEFAULT_PAST_PARAMS (0x005D | HCI_GRP_BLE_CMDS)
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#define HCI_BLE_READ_BUFFER_SZIE_V2 (0x0060 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_READ_TX_SYNC (0x0061 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_SET_CIG_PARAMS (0x0062 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_SET_CIG_PARAMS_TEST (0x0063 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_CREATE_CIS (0x0064 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_REMOVE_CIG (0x0065 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_ACCEPT_CIS_REQ (0x0066 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_REJECT_CIS_REQ (0x0067 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_BIG (0x0068 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_BIG_TEST (0x0069 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_TERMINATE_BIG (0x006A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_BIG_CREATE_SYNC (0x006B | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_BIG_TERMINATE_SYNC (0x006C | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_SET_DATA_PATH (0x006E | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_REMOVE_DATA_PATH (0x006F | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_HOST_FEATURE (0x0074 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ISO_READ_ISO_LINK_QUALITY (0x0075 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_HOST_FEATURE_V2 (0x0097 | HCI_GRP_BLE_CMDS)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#define HCI_BLE_ENH_READ_TRANS_POWER_LEVEL (0x0076 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_REMOTE_TRANS_POWER_LEVEL (0x0077 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_PATH_LOSS_REPORTING_PARAMS (0x0078 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_PATH_LOSS_REPORTING_ENABLE (0x0079 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_TRANS_POWER_REPORTING_ENABLE (0x007A | HCI_GRP_BLE_CMDS)
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#define HCI_BLE_SET_DEFAULT_SUBRATE (0x007D | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SUBRATE_REQUEST (0x007E | HCI_GRP_BLE_CMDS)
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
// Vendor OGF define
#define HCI_VENDOR_OGF 0x3F
@@ -422,11 +472,20 @@
#define HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL 0x0A
#define HCI_SUBCODE_BLE_RD_STATIC_ADDR 0x0B
#define HCI_SUBCODE_BLE_CLEAR_ADV 0x0C
+#define HCI_SUBCODE_BLE_SET_CSA_SUPPORT 0x12
+#define HCI_SUBCODE_BLE_SET_VENDOR_EVT_MASK 0x16
#define HCI_SUBCODE_BLE_MAX 0x7F
//ESP BT subcode define
#define HCI_SUBCODE_BT_INIT 0x00
+#define HCI_SUBCODE_BT_WRITE_DM1_ENABLE 0x01
#define HCI_SUBCODE_BT_SET_MIN_ENC_KEY_SIZE 0x02
+#define HCI_SUBCODE_BT_CLK_UPD 0x03
+#define HCI_SUBCODE_BT_SET_AFH 0x07
+#define HCI_SUBCODE_BT_SET_EVT_MASK 0x08
+#define HCI_SUBCODE_BT_SET_AFH_REPORTING_MODE 0x09
+#define HCI_SUBCODE_BT_MASK_RMT_AFH_CH_CLASS 0x0A
+#define HCI_SUBCODE_BT_WR_AUTO_RATE_INIT_ENABLE 0x0B
#define HCI_SUBCODE_BT_MAX 0x7F
#define HCI_ESP_VENDOR_OPCODE_BUILD(ogf, group, subcode) ((ogf << 10) | (group <<7) | (subcode << 0))
@@ -460,16 +519,25 @@
#define HCI_BLE_ENERGY_INFO_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ENERGY_INFO)
/* Extended BLE Scan parameters OCF */
#define HCI_BLE_EXTENDED_SCAN_PARAMS_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_EXTENDED_SCAN_PARAMS)
-/* Long BLE Adv data OCF */
-#define HCI_VENDOR_BLE_LONG_ADV_DATA HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_LONG_ADV)
/* BLE update duplicate scan exceptional list */
#define HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST)
#define HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL)
#define HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL)
/* BLE clear legacy advertising */
#define HCI_VENDOR_BLE_CLEAR_ADV HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_CLEAR_ADV)
+/* BLE set CSA support */
+#define HCI_VENDOR_BLE_SET_CSA_SUPPORT HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_CSA_SUPPORT)
+/* BLE set vendor event mask */
+#define HCI_VENDOR_BLE_SET_EVT_MASK HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_VENDOR_EVT_MASK)
//ESP BT HCI CMD
-#define HCI_VENDOR_BT_SET_MIN_ENC_KEY_SIZE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_MIN_ENC_KEY_SIZE)
+#define HCI_VENDOR_BT_WRITE_DM1_ENABLE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_WRITE_DM1_ENABLE)
+#define HCI_VENDOR_BT_SET_MIN_ENC_KEY_SIZE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_MIN_ENC_KEY_SIZE)
+#define HCI_VENDOR_BT_CLK_UPD HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_CLK_UPD)
+#define HCI_VENDOR_BT_SET_AFH HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_AFH)
+#define HCI_VENDOR_BT_SET_EVT_MASK HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_EVT_MASK)
+#define HCI_VENDOR_BT_SET_AFH_REPORTING_MODE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_SET_AFH_REPORTING_MODE)
+#define HCI_VENDOR_BT_MASK_RMT_AFH_CH_CLASS HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_MASK_RMT_AFH_CH_CLASS)
+#define HCI_VENDOR_BT_WR_AUTO_RATE_INIT_ENABLE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BT, HCI_SUBCODE_BT_WR_AUTO_RATE_INIT_ENABLE)
/* subcode for multi adv feature */
#define BTM_BLE_MULTI_ADV_SET_PARAM 0x01
@@ -820,10 +888,48 @@
#define HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT 0x18
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_CTE_EN == TRUE)
+#define HCI_BLE_CONNLESS_IQ_REPORT_EVT 0x15
+#define HCI_BLE_CONN_IQ_REPORT_EVT 0x16
+#define HCI_BLE_CTE_REQUEST_FAILED_EVT 0x17
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_ISO_EN == TRUE)
+#define HCI_BLE_CIS_ESTABLISHED_V1_EVT 0x19
+#define HCI_BLE_CIS_REQUEST_EVT 0x1A
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#define HCI_BLE_BIG_CREATE_COMPLETE_EVT 0x1B
+#define HCI_BLE_BIG_TERMINATE_COMPLETE_EVT 0x1C
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define HCI_BLE_BIG_SYNC_ESTABLISHED_EVT 0x1D
+#define HCI_BLE_BIG_SYNC_LOST_EVT 0x1E
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define HCI_BLE_BIGINFO_ADV_REPORT_EVT 0x22
+#define HCI_BLE_CIS_ESTABLISHED_V2_EVT 0x2A
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#define HCI_BLE_PATH_LOSS_THRESHOLD_EVT 0x20
+#define HCI_BLE_TRANS_POWER_REPORTING_EVT 0x21
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#define HCI_BLE_SUBRATE_CHANGE_EVT 0x23
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
/* Definitions for LE Channel Map */
#define HCI_BLE_CHNL_MAP_SIZE 5
+#define HCI_VENDOR_SPECIFIC_EVT 0xFF /* Vendor specific events */
+#define HCI_VENDOR_LEGACY_REM_AUTH_EVT_SUBCODE 0x03
+#define HCI_VENDOR_AFH_CHG_EVT_SUBCODE 0x05
+#define HCI_VENDOR_CH_CLASSIFICATION_EVT_SUBCODE 0x06
+#define HCI_VENDOR_CH_CLASSIFICATION_REPORTING_MODE_EVT_SUBCODE 0x07
+
#define HCI_VENDOR_SPECIFIC_EVT 0xFF /* Vendor specific events */
+#define HCI_VSE_LE_SUBEVT_BASE 0xC0 /* BLE vendor event code base */
+#define HCI_VSE_LE_EVT_MAX 0xFF /* BLE vendor event code max */
#define HCI_NAP_TRACE_EVT 0xFF /* was define 0xFE, 0xFD, change to 0xFF
because conflict w/ TCI_EVT and per
specification compliant */
@@ -1871,42 +1977,50 @@ typedef struct {
#define HCI_PING_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_PING_OFF] & HCI_EXT_FEATURE_PING_MASK)
/*
-** LE features encoding - page 0 (the only page for now)
+** LE features encoding - page 0
*/
-/* LE Encryption */
+/* LE Encryption: bit 0 */
#define HCI_LE_FEATURE_LE_ENCRYPTION_MASK 0x01
#define HCI_LE_FEATURE_LE_ENCRYPTION_OFF 0
#define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK)
-/* Connection Parameters Request Procedure */
+/* Connection Parameters Request Procedure: bit 1 */
#define HCI_LE_FEATURE_CONN_PARAM_REQ_MASK 0x02
#define HCI_LE_FEATURE_CONN_PARAM_REQ_OFF 0
#define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) ((x)[HCI_LE_FEATURE_CONN_PARAM_REQ_OFF] & HCI_LE_FEATURE_CONN_PARAM_REQ_MASK)
-/* Extended Reject Indication */
+/* Extended Reject Indication: bit 2 */
#define HCI_LE_FEATURE_EXT_REJ_IND_MASK 0x04
#define HCI_LE_FEATURE_EXT_REJ_IND_OFF 0
#define HCI_LE_EXT_REJ_IND_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_REJ_IND_OFF] & HCI_LE_FEATURE_EXT_REJ_IND_MASK)
-/* Slave-initiated Features Exchange */
+/* Slave-initiated Features Exchange: bit 3 */
#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK 0x08
#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF 0
#define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x) ((x)[HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF] & HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK)
+/* LE Data Packet Length Extension: bit 5 */
+#define HCI_LE_FEATURE_DATA_LEN_EXT_MASK 0x20
+#define HCI_LE_FEATURE_DATA_LEN_EXT_OFF 0
+#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) ((x)[HCI_LE_FEATURE_DATA_LEN_EXT_OFF] & HCI_LE_FEATURE_DATA_LEN_EXT_MASK)
+
/* Enhanced privacy Feature: bit 6 */
#define HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK 0x40
#define HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF 0
#define HCI_LE_ENHANCED_PRIVACY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF] & HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK)
-/* Extended scanner filter policy : 7 */
+/* Extended scanner filter policy: bit 7 */
#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK 0x80
#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF 0
#define HCI_LE_EXT_SCAN_FILTER_POLICY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF] & HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK)
-/* Slave-initiated Features Exchange */
-#define HCI_LE_FEATURE_DATA_LEN_EXT_MASK 0x20
-#define HCI_LE_FEATURE_DATA_LEN_EXT_OFF 0
-#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) ((x)[HCI_LE_FEATURE_DATA_LEN_EXT_OFF] & HCI_LE_FEATURE_DATA_LEN_EXT_MASK)
+/*
+** LE features encoding - page 1
+*/
+/* LE Extended Advertising: bit 12 */
+#define HCI_LE_FEATURE_EXT_ADV_MASK 0x10
+#define HCI_LE_FEATURE_EXT_ADV_OFF 1
+#define HCI_LE_EXT_ADV_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_ADV_OFF] & HCI_LE_FEATURE_EXT_ADV_MASK)
/*
** Local Supported Commands encoding
diff --git a/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h
index 951e5b70..4ee07b4d 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/hcimsgs.h
@@ -759,12 +759,18 @@ void btsnd_hcic_vendor_spec_cmd (BT_HDR *buffer, UINT16 opcode,
#define HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL 2
#define HCIC_PARAM_SIZE_BLE_CLEAR_ADV 0
#define HCIC_PARAM_SIZE_SET_PRIVACY_MODE 8
+#define HCIC_PARAM_SIZE_BLE_SET_CSA_SUPPORT 1
+#define HCIC_PARAM_SIZE_BLE_SET_VENDOR_EVT_MASK 4
#if (BLE_50_FEATURE_SUPPORT == TRUE)
#define HCIC_PARAM_SIZE_BLE_READ_PHY 2
#define HCIC_PARAM_SIZE_BLE_SET_DEF_PHY 3
#define HCIC_PARAM_SIZE_BLE_SET_PHY 7
+#endif
+#if (BLE_50_DTM_TEST_EN == TRUE)
#define HCIC_PARAM_SIZE_ENH_RX_TEST 3
#define HCIC_PARAM_SIZE_ENH_TX_TEST 4
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
#define HCIC_PARAM_SIZE_EXT_RAND_ADDR 7
#define HCIC_PARAM_SIZE_EXT_ADV_SET_PARAMS 25
#define HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA 251
@@ -914,7 +920,14 @@ BOOLEAN btsnd_hcic_ble_set_rand_priv_addr_timeout (UINT16 rpa_timout);
BOOLEAN btsnd_hcic_ble_clear_adv(void);
+BOOLEAN btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode);
+
+BOOLEAN btsnd_hcic_ble_set_csa_support (UINT8 csa_select);
+
+BOOLEAN btsnd_hcic_ble_set_vendor_evt_mask (UINT32 evt_mask);
+
#endif /* BLE_INCLUDED */
+
#if (BLE_50_FEATURE_SUPPORT == TRUE)
typedef struct {
UINT8 scan_type;
@@ -957,14 +970,17 @@ UINT8 btsnd_hcic_ble_set_prefered_default_phy(UINT8 all_phys,
BOOLEAN btsnd_hcic_ble_set_phy(UINT16 conn_handle,
UINT8 all_phys, UINT8 tx_phys,
UINT8 rx_phys, UINT16 phy_options);
-
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+#if (BLE_50_DTM_TEST_EN == TRUE)
UINT8 btsnd_hcic_ble_enhand_rx_test(UINT8 rx_channel, UINT8 phy,
UINT8 modulation_idx);
UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len,
UINT8 packect,
UINT8 phy);
+#endif // #if (BLE_50_DTM_TEST_EN == TRUE)
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
UINT8 btsnd_hcic_ble_set_extend_rand_address(UINT8 adv_handle, BD_ADDR rand_addr);
UINT8 btsnd_hcic_ble_set_ext_adv_params(UINT8 adv_handle, UINT16 properties, UINT32 interval_min,
@@ -1018,7 +1034,7 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn);
BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 filter_policy, UINT8 adv_sid,
UINT8 adv_addr_type, BD_ADDR adv_addr,
- UINT16 sync_timeout, UINT8 unused);
+ UINT16 sync_timeout, UINT8 sync_cte_type);
UINT8 btsnd_hcic_ble_periodic_adv_create_sync_cancel(void);
@@ -1042,8 +1058,6 @@ UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
-UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode);
-
#define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4
#define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0
@@ -1069,4 +1083,164 @@ BOOLEAN btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UI
UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type);
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
+#if (BLE_FEAT_ISO_EN == TRUE)
+#define HCIC_PARAM_SIZE_ISO_READ_TX_SYNC_PARAMS 2
+#define HCIC_PARAM_SIZE_ISO_SET_CIG_PARAMS 15
+#define HCIC_PARAM_SIZE_ISO_SET_CIG_TEST_PARAMS 15
+#define HCIC_PARAM_SIZE_ISO_CREATE_CIS_PARAMS 1
+#define HCIC_PARAM_SIZE_ISO_REMOVE_CIG_PARAMS 1
+#define HCIC_PARAM_SIZE_ISO_ACCEPT_CIS_REQ_PARAMS 2
+#define HCIC_PARAM_SIZE_ISO_REJECT_CIS_REQ_PARAMS 3
+#define HCIC_PARAM_SIZE_ISO_READ_LINK_QUALITY_PARAMS 2
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#define HCIC_PARAM_SIZE_BIG_CREATE_PARAMS 31
+#define HCIC_PARAM_SIZE_BIG_CREATE_TEST_PARAMS 36
+#define HCIC_PARAM_SIZE_BIG_TERMINATE_PARAMS 2
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define HCIC_PARAM_SIZE_BIG_SYNC_CREATE_PARAMS 55
+#define HCIC_PARAM_SIZE_BIG_SYNC_TERMINATE_PARAMS 1
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+#define HCIC_PARAM_SIZE_ISO_SET_DATA_PATH_PARAMS 13
+#define HCIC_PARAM_SIZE_ISO_REMOVE_DATA_PATH_PARAMS 3
+
+#if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+struct ble_hci_le_cis_params {
+ uint8_t cis_id;
+ uint16_t max_sdu_c_to_p;
+ uint16_t max_sdu_p_to_c;
+ uint8_t phy_c_to_p;
+ uint8_t phy_p_to_c;
+ uint8_t rtn_c_to_p;
+ uint8_t rtn_p_to_c;
+} __attribute__((packed));
+struct ble_hci_le_cis_params_test {
+ uint8_t cis_id;
+ uint8_t nse;
+ uint16_t max_sdu_c_to_p;
+ uint16_t max_sdu_p_to_c;
+ uint16_t max_pdu_c_to_p;
+ uint16_t max_pdu_p_to_c;
+ uint8_t phy_c_to_p;
+ uint8_t phy_p_to_c;
+ uint8_t bn_c_to_p;
+ uint8_t bn_p_to_c;
+} __attribute__((packed));
+
+
+struct ble_hci_cis_hdls {
+ uint16_t cis_hdl;
+ uint16_t acl_hdl;
+}__attribute__((packed));
+
+UINT8 btsnd_hcic_ble_iso_set_cig_params(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t worse_case_SCA, uint8_t packing,
+ uint8_t framing, uint16_t mtl_c_to_p, uint16_t mtl_p_to_c, uint8_t cis_cnt, struct ble_hci_le_cis_params *cis_params);
+UINT8 btsnd_hcic_ble_iso_set_cig_params_test(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_t sdu_int_p_to_c, uint8_t ft_c_to_p, uint8_t ft_p_to_c,
+ uint16_t iso_interval, uint8_t worse_case_SCA, uint8_t packing, uint8_t framing, uint8_t cis_cnt,
+ struct ble_hci_le_cis_params_test *cis_params_test);
+UINT8 btsnd_hcic_ble_iso_create_cis(uint8_t cis_count, struct ble_hci_cis_hdls *cis_hdls);
+UINT8 btsnd_hcic_ble_iso_remove_cig(uint8_t cig_id);
+#endif // (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+UINT8 btsnd_hcic_ble_iso_accept_cis_req(uint16_t cis_handle);
+UINT8 btsnd_hcic_ble_iso_reject_cis_req(uint16_t cis_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+UINT8 btsnd_hcic_ble_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency,
+ uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing,
+ uint8_t encryption, uint8_t *broadcast_code);
+
+UINT8 btsnd_hcic_ble_big_create_test(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
+ uint32_t sdu_interval, uint16_t iso_interval, uint8_t nse,
+ uint16_t max_sdu, uint16_t max_pdu, uint8_t phy,
+ uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc,
+ uint8_t pto, uint8_t encryption, uint8_t *broadcast_code);
+
+UINT8 btsnd_hcic_ble_big_terminate(uint8_t big_handle, uint8_t reason);
+#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
+
+#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+UINT8 btsnd_hcic_ble_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
+ uint8_t encryption, uint8_t *bc_code,
+ uint8_t mse, uint16_t big_sync_timeout,
+ uint8_t num_bis, uint8_t *bis);
+
+UINT8 btsnd_hcic_ble_big_sync_terminate(uint8_t big_handle);
+#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
+
+UINT8 btsnd_hcic_ble_iso_set_data_path(uint16_t conn_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t coding_fmt,
+ uint16_t company_id, uint16_t vs_codec_id, uint32_t controller_delay, uint8_t codec_len,
+ uint8_t *codec_cfg);
+UINT8 btsnd_hcic_ble_iso_remove_data_path(uint16_t conn_handle, uint8_t data_path_dir);
+
+UINT8 btsnd_hcic_ble_iso_read_tx_sync(uint16_t iso_hdl);
+
+UINT8 btsnd_hcic_ble_iso_read_iso_link_quality(uint16_t iso_hdl);
+
+#endif // #if (BLE_FEAT_ISO_EN == TRUE)
+
+#if (BLE_FEAT_CTE_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#define HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS 5
+#define HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE 2
+#define HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE 6
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS 5
+#define HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS 4
+#define HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE 7
+#define HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE 3
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+#define HCIC_PARAM_SIZE_READ_ANT_INFO 0
+#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+UINT8 btsnd_hcic_ble_set_connless_cte_trans_params(uint8_t adv_hdl, uint8_t cte_len, uint8_t cte_type,
+ uint8_t cte_cnt, uint8_t switching_pattern_len, uint8_t *antenna_ids);
+UINT8 btsnd_hcic_ble_set_connless_cte_enable(uint8_t adv_hdl, uint8_t cte_en);
+UINT8 btsnd_hcic_ble_set_connless_iq_sampling_enable(uint16_t sync_hdl, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *antenna_ids);
+#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
+#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+UINT8 btsnd_hcic_ble_set_conn_cte_receive_params(uint16_t conn_hdl, uint8_t sampling_en, uint8_t slot_dur,
+ uint8_t switching_pattern_len, uint8_t *antenna_ids);
+UINT8 btsnd_hcic_ble_set_conn_cte_trans_params(uint16_t conn_hdl, uint8_t cte_type, uint8_t switching_pattern_len, uint8_t *antenna_ids);
+UINT8 btsnd_hcic_ble_conn_cte_req_enable(uint16_t conn_hdl, uint8_t enable, uint16_t cte_req_int, uint8_t req_cte_len, uint8_t req_cte_type);
+UINT8 btsnd_hcic_ble_conn_cte_rsp_enable(uint16_t conn_hdl, uint8_t enable);
+#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
+UINT8 btsnd_hcic_ble_read_antenna_info(void);
+#endif // #if (BLE_FEAT_CTE_EN == TRUE)
+
+#if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+#define HCIC_PARAM_SIZE_ENH_READ_TRANS_PWR_LEVEL 3
+#define HCIC_PARAM_SIZE_READ_REMOTE_TRANS_PWR_LEVEL 3
+#define HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_PARAMS 8
+#define HCIC_PARAM_SIZE_SET_PATH_LOSS_REPORTING_ENABLE 3
+#define HCIC_PARAM_SIZE_SET_TRANS_PWR_REPORTING_ENABLE 4
+
+UINT8 btsnd_hcic_ble_enh_read_trans_power_level(uint16_t conn_handle, uint8_t phy);
+UINT8 btsnd_hcic_ble_read_remote_trans_power_level(uint16_t conn_handle, uint8_t phy);
+UINT8 btsnd_hcic_ble_set_path_loss_rpt_params(uint16_t conn_handle, uint8_t high_threshold, uint8_t high_hysteresis,
+ uint8_t low_threshold, uint8_t low_hysteresis, uint16_t min_time_spent);
+UINT8 btsnd_hcic_ble_set_path_loss_rpt_enable(uint16_t conn_handle, uint8_t enable);
+UINT8 btsnd_hcic_ble_set_trans_pwr_rpt_enable(uint16_t conn_handle, uint8_t local_enable, uint8_t remote_enable);
+#endif // #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
+
+#if (BLE_FEAT_CONN_SUBRATING == TRUE)
+#define HCIC_PARAM_SIZE_SET_DEFAULT_SUBRATE_PARAMS_LEN 10
+#define HCIC_PARAM_SIZE_SUBRATE_REQ_LENGTH_PARAMS_LEN 12
+UINT8 btsnd_hcic_ble_set_default_subrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency,
+ UINT16 continuation_number, UINT16 supervision_timeout);
+
+UINT8 btsnd_hcic_ble_subrate_request(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency,
+ UINT16 continuation_number, UINT16 supervision_timeout);
+#endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE)
+
+#if (BLE_50_FEATURE_SUPPORT == TRUE)
+#define HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS 2
+#define HCIC_PARAM_SIZE_SET_HOST_FEATURE_PARAMS_V2 3
+UINT8 btsnd_hcic_ble_set_host_feature(uint16_t bit_num, uint8_t bit_val);
+#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
+
#endif
diff --git a/lib/bt/host/bluedroid/stack/include/stack/obex_api.h b/lib/bt/host/bluedroid/stack/include/stack/obex_api.h
new file mode 100644
index 00000000..d22cd33c
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/include/stack/obex_api.h
@@ -0,0 +1,271 @@
+/*
+ * 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 */
+
+/*
+* 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 scn; /* service channel number */
+ UINT16 sec_mask; /* security mask */
+ UINT16 pref_mtu; /* preferred mtu, limited by rfcomm mtu */
+ BD_ADDR addr; /* peer bluetooth device address */
+} tOBEX_OVER_RFCOMM_SVR;
+
+typedef struct
+{
+ UINT8 tl; /* transport type, OBEX_OVER_L2CAP or OBEX_OVER_RFCOMM */
+ union
+ {
+ tOBEX_OVER_L2CAP_SVR l2cap;
+ tOBEX_OVER_RFCOMM_SVR rfcomm;
+ };
+} 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) */
diff --git a/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h b/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h
index 70da3182..7075e8bb 100644
--- a/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h
+++ b/lib/bt/host/bluedroid/stack/include/stack/sdp_api.h
@@ -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.
diff --git a/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h
index 045fb10d..88eac86b 100644
--- a/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h
+++ b/lib/bt/host/bluedroid/stack/l2cap/include/l2c_int.h
@@ -65,7 +65,7 @@
#define L2CAP_WAIT_UNPARK_TOUT 2 /* 2 seconds */
#define L2CAP_LINK_INFO_RESP_TOUT 2 /* 2 seconds */
#define L2CAP_UPDATE_CONN_PARAM_TOUT 6 /* 6 seconds */
-#define L2CAP_BLE_LINK_CONNECT_TOUT BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT // configed in menuconfig
+#define L2CAP_BLE_LINK_CONNECT_TOUT BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT // configured in menuconfig
#define L2CAP_BLE_CONN_PARAM_UPD_TOUT 30 /* 30 seconds */
/* quick timer uses millisecond unit */
@@ -80,10 +80,10 @@
** the Bluetooth specification.
*/
typedef enum {
- CST_CLOSED, /* Channel is in clodes state */
+ CST_CLOSED, /* Channel is in closed state */
CST_ORIG_W4_SEC_COMP, /* Originator waits security clearence */
CST_TERM_W4_SEC_COMP, /* Acceptor waits security clearence */
- CST_W4_L2CAP_CONNECT_RSP, /* Waiting for peer conenct response */
+ CST_W4_L2CAP_CONNECT_RSP, /* Waiting for peer connect response */
CST_W4_L2CA_CONNECT_RSP, /* Waiting for upper layer connect rsp */
CST_CONFIG, /* Negotiating configuration */
CST_OPEN, /* Data transfer state */
@@ -208,8 +208,8 @@ typedef struct {
UINT32 controller_idle; /* # of times less than 2 packets in controller */
/* when the xmit window was closed */
UINT32 pkts_retransmitted; /* # of packets that were retransmitted */
- UINT32 retrans_touts; /* # of retransmission timouts */
- UINT32 xmit_ack_touts; /* # of xmit ack timouts */
+ UINT32 retrans_touts; /* # of retransmission timeouts */
+ UINT32 xmit_ack_touts; /* # of xmit ack timeouts */
#define L2CAP_ERTM_STATS_NUM_AVG 10
#define L2CAP_ERTM_STATS_AVG_NUM_SAMPLES 100
@@ -386,7 +386,7 @@ typedef struct t_l2c_linkcb {
tL2C_CCB *p_pending_ccb; /* ccb of waiting channel during link disconnect */
TIMER_LIST_ENT info_timer_entry; /* Timer entry for info resp timeout evt */
- TIMER_LIST_ENT upda_con_timer; /* Timer entry for update connection parametr */
+ TIMER_LIST_ENT upda_con_timer; /* Timer entry for update connection parameter */
BD_ADDR remote_bd_addr; /* The BD address of the remote */
UINT8 link_role; /* Master or slave */
@@ -599,7 +599,7 @@ extern BOOLEAN l2cu_start_post_bond_timer (UINT16 handle);
extern void l2cu_release_lcb (tL2C_LCB *p_lcb);
extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport);
extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle);
-extern uint8_t l2cu_plcb_active_count(void);
+extern uint8_t l2cu_ble_plcb_active_count(void);
extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding);
extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb);
diff --git a/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c
index 956a4b7f..3ce25ab9 100644
--- a/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c
+++ b/lib/bt/host/bluedroid/stack/l2cap/l2c_ble.c
@@ -111,7 +111,7 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
/* Do not remove lcb if an LE link is already up as a peripheral */
if (p_lcb != NULL &&
- !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(rem_bda))) {
+ !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_LE_ACL_IS_CONNECTED(rem_bda))) {
p_lcb->disc_reason = L2CAP_CONN_CANCEL;
l2cu_release_lcb (p_lcb);
}
@@ -242,7 +242,7 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
return (FALSE);
}
bool is_disable = (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE);
- if(l2cu_plcb_active_count() >1 && !(enable && is_disable)) {
+ if(l2cu_ble_plcb_active_count() >1 && !(enable && is_disable)) {
return FALSE;
}
@@ -376,6 +376,7 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency;
p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
p_lcb->updating_param_flag = false;
+ p_lcb->ble_addr_type = type;
/* If there are any preferred connection parameters, set them now */
if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
@@ -476,6 +477,7 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ
p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency;
p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
p_lcb->updating_param_flag = false;
+ p_lcb->ble_addr_type = type;
/* Tell BTM Acl management about the link */
p_dev_rec = btm_find_or_alloc_dev (bda);
@@ -900,6 +902,12 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
+ if (p_dev_rec->conn_params.scan_interval && p_dev_rec->conn_params.scan_interval != BTM_BLE_CONN_PARAM_UNDEF) {
+ scan_int = p_dev_rec->conn_params.scan_interval;
+ }
+ if (p_dev_rec->conn_params.scan_window && p_dev_rec->conn_params.scan_window != BTM_BLE_CONN_PARAM_UNDEF) {
+ scan_win = p_dev_rec->conn_params.scan_window;
+ }
peer_addr_type = p_lcb->ble_addr_type;
memcpy(peer_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
@@ -964,22 +972,24 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
}
if (!p_lcb->is_aux) {
- if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */
- scan_win, /* UINT16 scan_win */
- FALSE, /* UINT8 white_list */
- peer_addr_type, /* UINT8 addr_type_peer */
- peer_addr, /* BD_ADDR bda_peer */
- own_addr_type, /* UINT8 addr_type_own */
+ if (!btsnd_hcic_ble_create_ll_conn (scan_int, /* UINT16 scan_int */
+ scan_win, /* UINT16 scan_win */
+ FALSE, /* UINT8 white_list */
+ peer_addr_type, /* UINT8 addr_type_peer */
+ peer_addr, /* BD_ADDR bda_peer */
+ own_addr_type, /* UINT8 addr_type_own */
(UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
- p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* UINT16 conn_int_min */
+ p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* UINT16 conn_int_min */
(UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
- p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* UINT16 conn_int_max */
+ p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* UINT16 conn_int_max */
(UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
- p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */
+ p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */
(UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
- p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */
- BLE_CE_LEN_MIN, /* UINT16 min_len */
- BLE_CE_LEN_MIN)) { /* UINT16 max_len */
+ p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* UINT16 conn_timeout */
+ (UINT16) ((p_dev_rec->conn_params.min_ce_len != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.min_ce_len : BLE_CE_LEN_MIN), /* UINT16 min_ce_len */
+ (UINT16) ((p_dev_rec->conn_params.max_ce_len != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.max_ce_len : BLE_CE_LEN_MIN) /* UINT16 max_ce_len */)) {
l2cu_release_lcb (p_lcb);
L2CAP_TRACE_ERROR("initiate direct connection fail, no resources");
return (FALSE);
@@ -1063,11 +1073,11 @@ BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb)
L2CAP_TRACE_WARNING ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st);
btm_ble_enqueue_direct_conn_req(p_lcb);
-
+#if (tGATT_BG_CONN_DEV == TRUE)
if (conn_st == BLE_BG_CONN) {
btm_ble_suspend_bg_conn();
}
-
+#endif // #if (tGATT_BG_CONN_DEV == TRUE)
rt = TRUE;
}
return rt;
diff --git a/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c b/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c
index c3118fdd..1af7e8b3 100644
--- a/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c
+++ b/lib/bt/host/bluedroid/stack/l2cap/l2c_link.c
@@ -368,9 +368,11 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
BTM_Recovery_Pre_State();
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ #if (BLE_50_EXTEND_ADV_EN == TRUE)
if(btm_ble_inter_get() && reason == HCI_ERR_CONN_FAILED_ESTABLISHMENT) {
BTM_BleStartExtAdvRestart(handle);
}
+ #endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#endif ///BLE_INCLUDED == TRUE
status = FALSE;
@@ -478,24 +480,36 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
if (l2cu_create_conn(p_lcb, BT_TRANSPORT_LE)) {
btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
lcb_is_free = FALSE; /* still using this lcb */
+ } else {
+ L2CAP_TRACE_ERROR("master retry connect failed");
}
}
#endif // (GATTC_CONNECT_RETRY_EN == TRUE)
#if (BLE_50_FEATURE_SUPPORT == TRUE)
+ #if (BLE_50_EXTEND_ADV_EN == TRUE)
if(btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) {
p_lcb->retry_create_con ++;
L2CAP_TRACE_DEBUG("slave restart extend adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason);
- BTM_BleStartExtAdvRestart(handle);
+ tBTM_STATUS start_adv_status = BTM_BleStartExtAdvRestart(handle);
+ if (start_adv_status != BTM_SUCCESS) {
+ L2CAP_TRACE_ERROR("slave restart extend adv failed (err 0x%x)", start_adv_status);
+ }
}
+ #endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_42_FEATURE_SUPPORT == TRUE)
+ #if (BLE_42_ADV_EN == TRUE)
if(!btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) {
p_lcb->retry_create_con ++;
L2CAP_TRACE_DEBUG("slave resatrt adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason);
- btm_ble_start_adv();
+ tBTM_STATUS start_adv_status = btm_ble_start_adv();
+ if (start_adv_status != BTM_SUCCESS) {
+ L2CAP_TRACE_ERROR("slave resatrt adv failed (err 0x%x)", start_adv_status);
+ }
}
+ #endif // #if (BLE_42_ADV_EN == TRUE)
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
}
@@ -1078,7 +1092,9 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
p_lcb_cur = list_node(p_node);
if (p_lcb_cur == p_lcb) {
p_node = list_next(p_node);
- p_lcb = list_node(p_node);
+ if (p_node) {
+ p_lcb = list_node(p_node);
+ }
break;
}
}
diff --git a/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c
index 992d4b68..e4bf8a08 100644
--- a/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c
+++ b/lib/bt/host/bluedroid/stack/l2cap/l2c_utils.c
@@ -336,14 +336,14 @@ tL2C_LCB *l2cu_find_free_lcb (void)
return (NULL);
}
-uint8_t l2cu_plcb_active_count(void)
+uint8_t l2cu_ble_plcb_active_count(void)
{
list_node_t *p_node = NULL;
tL2C_LCB *p_lcb = NULL;
uint8_t active_count = 0;
for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
p_lcb = list_node(p_node);
- if (p_lcb && p_lcb->in_use) {
+ if (p_lcb && p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
active_count ++;
}
}
@@ -615,7 +615,7 @@ void l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status)
**
** Description Build and send an L2CAP "connection response neg" message
** to the peer. This function is called when there is no peer
-** CCB (non-existant PSM or no resources).
+** CCB (non-existent PSM or no resources).
**
** Returns void
**
@@ -1737,7 +1737,7 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb)
) {
l2cu_dequeue_ccb (p_ccb);
- /* Delink the CCB from the LCB */
+ /* Unlink the CCB from the LCB */
p_ccb->p_lcb = NULL;
}
@@ -1960,7 +1960,7 @@ tL2C_RCB *l2cu_find_ble_rcb_by_psm (UINT16 psm)
**
** Returns UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer,
** L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to
-** because parameters are unnacceptable from a specification
+** because parameters are unacceptable from a specification
** point of view.
** L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes
** between the two devices, and shall be closed.
@@ -2558,7 +2558,7 @@ BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_af
**
** Function l2cu_set_non_flushable_pbf
**
-** Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
+** Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supports
**
** Returns void
**
@@ -3328,7 +3328,7 @@ static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb)
for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY) && (!p_serve_ccb); i++ ) {
/* scan all channel within serving priority group until finding a channel to serve */
for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb) && (!p_serve_ccb); j++) {
- /* scaning from next serving channel */
+ /* scanning from next serving channel */
p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
if (!p_ccb) {
diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_int.h b/lib/bt/host/bluedroid/stack/obex/include/obex_int.h
new file mode 100644
index 00000000..28c4eab4
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/include/obex_int.h
@@ -0,0 +1,76 @@
+/*
+ * 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)
+
+#if (RFCOMM_INCLUDED == TRUE)
+#define OBEX_BT_HDR_MIN_OFFSET OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET /* should set to max value of all transport layer */
+#define OBEX_BT_HDR_RESERVE_LEN OBEX_TL_RFCOMM_BT_HDR_RESERVE_LEN /* should set to max value of all transport layer */
+#else
+#define OBEX_BT_HDR_MIN_OFFSET OBEX_TL_L2CAP_BT_HDR_OFFSET_MIN
+#define OBEX_BT_HDR_RESERVE_LEN OBEX_TL_L2CAP_BT_HDR_RESERVE_LEN
+#endif
+
+#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 */
+
+/* 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);
+void obex_tl_rfcomm_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) */
diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_tl.h b/lib/bt/host/bluedroid/stack/obex/include/obex_tl.h
new file mode 100644
index 00000000..9211b9b0
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/include/obex_tl.h
@@ -0,0 +1,97 @@
+/*
+ * 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 struct
+{
+ UINT8 scn; /* service channel number */
+ UINT16 sec_mask; /* security mask */
+ UINT16 pref_mtu; /* preferred mtu, limited by rfcomm mtu */
+ BD_ADDR addr; /* peer bluetooth device address */
+} tOBEX_TL_RFCOMM_SVR;
+
+typedef union
+{
+ tOBEX_TL_L2CAP_SVR l2cap;
+ tOBEX_TL_RFCOMM_SVR rfcomm;
+} 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) */
diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_tl_l2cap.h b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_l2cap.h
new file mode 100644
index 00000000..32667766
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_l2cap.h
@@ -0,0 +1,18 @@
+/*
+ * 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 /* equal to L2CAP_MIN_OFFSET */
+#define OBEX_TL_L2CAP_BT_HDR_RESERVE_LEN 0 /* not require any additional byte */
+
+tOBEX_TL_OPS *obex_tl_l2cap_ops_get(void);
+
+#endif /* #if (OBEX_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/stack/obex/include/obex_tl_rfcomm.h b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_rfcomm.h
new file mode 100644
index 00000000..61b9d295
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/include/obex_tl_rfcomm.h
@@ -0,0 +1,18 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "obex_tl.h"
+
+#if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE)
+
+#define OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET 18 /* RFCOMM_MIN_OFFSET + L2CAP_MIN_OFFSET */
+#define OBEX_TL_RFCOMM_BT_HDR_RESERVE_LEN 1 /* reserve 1 byte for rfcomm fcs */
+
+tOBEX_TL_OPS *obex_tl_rfcomm_ops_get(void);
+
+#endif /* #if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/stack/obex/obex_api.c b/lib/bt/host/bluedroid/stack/obex/obex_api.c
new file mode 100644
index 00000000..99276a93
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/obex_api.c
@@ -0,0 +1,776 @@
+/*
+ * 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"
+#include "obex_tl_rfcomm.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 if (server->tl == OBEX_OVER_RFCOMM) {
+ tl_server->rfcomm.scn = server->rfcomm.scn;
+ tl_server->rfcomm.sec_mask = server->rfcomm.sec_mask;
+ tl_server->rfcomm.pref_mtu = server->rfcomm.pref_mtu;
+ bdcpy(tl_server->rfcomm.addr, server->rfcomm.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;
+ UINT16_TO_BE_FIELD(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);
+ }
+#if (RFCOMM_INCLUDED == TRUE)
+ 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);
+ }
+#endif
+ 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 (RFCOMM_INCLUDED == TRUE)
+ if (obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit != NULL) {
+ obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit();
+ }
+#endif
+#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 + OBEX_BT_HDR_RESERVE_LEN;
+
+ 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 - OBEX_BT_HDR_RESERVE_LEN;
+ 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*/
+ UINT16_TO_BE_FIELD(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;
+ }
+
+ UINT16_TO_BE_FIELD(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 + OBEX_BT_HDR_RESERVE_LEN;
+
+ 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 - OBEX_BT_HDR_RESERVE_LEN;
+ 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 */
+ UINT16_TO_BE_FIELD(p_data, info->max_packet_length);
+ pkt_len += 4;
+ break;
+ default:
+ break;
+ }
+
+ UINT16_TO_BE_FIELD(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++;
+ UINT16_TO_BE_FIELD(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) {
+ return OBEX_INVALID_PARAM;
+ }
+
+ if ((data == NULL && data_len != 0) || (data != NULL && data_len == 0)) {
+ 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 */
+ UINT16_TO_BE_FIELD(p_start, header_len);
+ p_start+= 2;
+ }
+ if (data != NULL) {
+ /* store data */
+ memcpy(p_start, data, data_len);
+ }
+ pkt->len += header_len;
+ /* point to packet len */
+ p_data++;
+ UINT16_TO_BE_FIELD(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) */
diff --git a/lib/bt/host/bluedroid/stack/obex/obex_main.c b/lib/bt/host/bluedroid/stack/obex/obex_main.c
new file mode 100644
index 00000000..7810ff3c
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/obex_main.c
@@ -0,0 +1,216 @@
+/*
+ * 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);
+}
+
+void obex_tl_rfcomm_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg)
+{
+ obex_tl_evt_handler(OBEX_OVER_RFCOMM, evt, msg);
+}
+
+#endif /* #if (OBEX_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/stack/obex/obex_tl_l2cap.c b/lib/bt/host/bluedroid/stack/obex/obex_tl_l2cap.c
new file mode 100644
index 00000000..d509b4cf
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/obex_tl_l2cap.c
@@ -0,0 +1,811 @@
+/*
+ * 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;
+ }
+
+ if (p_ccb->initiator && find_scb_by_psm(p_ccb->vpsm) == NULL) {
+ L2CA_Deregister(p_ccb->vpsm);
+ }
+
+ 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) */
diff --git a/lib/bt/host/bluedroid/stack/obex/obex_tl_rfcomm.c b/lib/bt/host/bluedroid/stack/obex/obex_tl_rfcomm.c
new file mode 100644
index 00000000..ce7799c8
--- /dev/null
+++ b/lib/bt/host/bluedroid/stack/obex/obex_tl_rfcomm.c
@@ -0,0 +1,439 @@
+/*
+ * 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/port_api.h"
+#include "stack/btm_api.h"
+#include "stack/sdpdefs.h"
+#include "obex_tl.h"
+#include "obex_tl_rfcomm.h"
+
+#if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE)
+
+#define OBEX_TL_RFCOMM_NUM_CONN 4
+#define OBEX_TL_RFCOMM_NUM_SERVER 2
+
+#define OBEX_TL_RFCOMM_EVENT_MARK (PORT_EV_FC | PORT_EV_FCS)
+
+typedef struct {
+ UINT16 rfc_handle; /* rfcomm handle */
+ UINT16 mtu; /* rfcomm mtu */
+ BOOLEAN initiator; /* TRUE if is initiator, otherwise FALSE */
+ UINT8 scn; /* service channel number */
+ BD_ADDR addr; /* peer bluetooth device address */
+ UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, equal to handle */
+} tOBEX_TL_RFCOMM_CCB;
+
+typedef struct {
+ UINT16 rfc_handle; /* rfcomm handle */
+ UINT8 scn; /* service channel number */
+ UINT8 allocated; /* 0 if not allocated, otherwise, index + 1, handle of server will left shift 8 bits */
+} tOBEX_TL_RFCOMM_SCB;
+
+typedef struct {
+ tOBEX_TL_CBACK *callback; /* Upper layer callback */
+ tOBEX_TL_RFCOMM_CCB ccb[OBEX_TL_RFCOMM_NUM_CONN];
+ tOBEX_TL_RFCOMM_SCB scb[OBEX_TL_RFCOMM_NUM_SERVER];
+ UINT8 trace_level; /* trace level */
+} tOBEX_TL_RFCOMM_CB;
+
+#if OBEX_DYNAMIC_MEMORY == FALSE
+static tOBEX_TL_RFCOMM_CB obex_tl_rfcomm_cb;
+#else
+static tOBEX_TL_RFCOMM_CB *obex_tl_rfcomm_cb_ptr = NULL;
+#define obex_tl_rfcomm_cb (*obex_tl_rfcomm_cb_ptr)
+#endif
+
+static tOBEX_TL_RFCOMM_CCB *allocate_ccb(void)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = NULL;
+ for(int i = 0; i < OBEX_TL_RFCOMM_NUM_CONN; ++i) {
+ if (obex_tl_rfcomm_cb.ccb[i].allocated == 0) {
+ obex_tl_rfcomm_cb.ccb[i].allocated = i + 1;
+ p_ccb = &obex_tl_rfcomm_cb.ccb[i];
+ break;
+ }
+ }
+ return p_ccb;
+}
+
+static tOBEX_TL_RFCOMM_SCB *allocate_scb(void)
+{
+ tOBEX_TL_RFCOMM_SCB *p_scb = NULL;
+ for(int i = 0; i < OBEX_TL_RFCOMM_NUM_SERVER; ++i) {
+ if (obex_tl_rfcomm_cb.scb[i].allocated == 0) {
+ obex_tl_rfcomm_cb.scb[i].allocated = i + 1;
+ p_scb = &obex_tl_rfcomm_cb.scb[i];
+ break;
+ }
+ }
+ return p_scb;
+}
+
+static void free_ccb(tOBEX_TL_RFCOMM_CCB *p_ccb)
+{
+ memset(p_ccb, 0, sizeof(tOBEX_TL_RFCOMM_CCB));
+}
+
+static void free_scb(tOBEX_TL_RFCOMM_SCB *p_scb)
+{
+ memset(p_scb, 0, sizeof(tOBEX_TL_RFCOMM_SCB));
+}
+
+static tOBEX_TL_RFCOMM_CCB *find_ccb_by_handle(UINT16 handle)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = NULL;
+ if (handle > 0 && handle <= OBEX_TL_RFCOMM_NUM_CONN) {
+ if (obex_tl_rfcomm_cb.ccb[handle-1].allocated == handle) {
+ p_ccb = &obex_tl_rfcomm_cb.ccb[handle-1];
+ }
+ }
+ return p_ccb;
+}
+
+static tOBEX_TL_RFCOMM_CCB *find_ccb_by_rfc_handle(UINT16 rfc_handle)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = NULL;
+ for(int i = 0; i < OBEX_TL_RFCOMM_NUM_CONN; ++i) {
+ if (obex_tl_rfcomm_cb.ccb[i].allocated && obex_tl_rfcomm_cb.ccb[i].rfc_handle == rfc_handle) {
+ p_ccb = &obex_tl_rfcomm_cb.ccb[i];
+ break;
+ }
+ }
+ return p_ccb;
+}
+
+static tOBEX_TL_RFCOMM_SCB *find_scb_by_handle(UINT16 handle)
+{
+ tOBEX_TL_RFCOMM_SCB *p_scb = NULL;
+ handle = handle >> 8;
+ if (handle > 0 && handle <= OBEX_TL_RFCOMM_NUM_SERVER) {
+ if (obex_tl_rfcomm_cb.scb[handle-1].allocated == handle) {
+ p_scb = &obex_tl_rfcomm_cb.scb[handle-1];
+ }
+ }
+ return p_scb;
+}
+
+static tOBEX_TL_RFCOMM_SCB *find_scb_by_rfc_handle(UINT16 rfc_handle)
+{
+ tOBEX_TL_RFCOMM_SCB *p_scb = NULL;
+ for(int i = 0; i < OBEX_TL_RFCOMM_NUM_SERVER; ++i) {
+ if (obex_tl_rfcomm_cb.scb[i].allocated && obex_tl_rfcomm_cb.scb[i].rfc_handle == rfc_handle) {
+ p_scb = &obex_tl_rfcomm_cb.scb[i];
+ break;
+ }
+ }
+ return p_scb;
+}
+
+static tOBEX_TL_RFCOMM_SCB *find_scb_by_scn(UINT16 scn)
+{
+ tOBEX_TL_RFCOMM_SCB *p_scb = NULL;
+ for(int i = 0; i < OBEX_TL_RFCOMM_NUM_SERVER; ++i) {
+ if (obex_tl_rfcomm_cb.scb[i].allocated && obex_tl_rfcomm_cb.scb[i].scn == scn) {
+ p_scb = &obex_tl_rfcomm_cb.scb[i];
+ break;
+ }
+ }
+ return p_scb;
+}
+
+static void rfcomm_mgmt_event_handler(tOBEX_TL_RFCOMM_CCB *p_ccb, UINT32 code)
+{
+ tOBEX_TL_MSG msg = {0};
+ msg.any.hdl = p_ccb->allocated;
+ switch (code)
+ {
+ case PORT_SUCCESS:
+ /* event already handled, do nothing */
+ break;
+ default:
+ /* other event, disconnect */
+ obex_tl_rfcomm_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
+ free_ccb(p_ccb);
+ break;
+ }
+}
+
+static void rfcomm_client_mgmt_callback(UINT32 code, UINT16 rfc_handle, void* data)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_rfc_handle(rfc_handle);
+ if (p_ccb == NULL) {
+ OBEX_TL_RFCOMM_TRACE_DEBUG("No ccb to handle rfcomm event\n");
+ return;
+ }
+ /* connection opened, handle event here */
+ if (code == PORT_SUCCESS) {
+ assert(data != NULL);
+ tPORT_MGMT_CL_CALLBACK_ARG *cl_mgmt_cb_arg = (tPORT_MGMT_CL_CALLBACK_ARG *)data;
+ p_ccb->mtu = cl_mgmt_cb_arg->peer_mtu;
+
+ tOBEX_TL_MSG msg = {0};
+ msg.conn_open.hdl = p_ccb->allocated;
+ msg.conn_open.peer_mtu = p_ccb->mtu;
+ msg.conn_open.our_mtu = p_ccb->mtu;
+ obex_tl_rfcomm_cb.callback(OBEX_TL_CONN_OPEN_EVT, &msg);
+ }
+ rfcomm_mgmt_event_handler(p_ccb, code);
+}
+
+static void rfcomm_server_mgmt_callback(UINT32 code, UINT16 rfc_handle, void* data)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = NULL;
+ /* incoming connection, handle event here */
+ if (code == PORT_SUCCESS) {
+ assert(data != NULL);
+ tOBEX_TL_RFCOMM_SCB *p_scb = find_scb_by_rfc_handle(rfc_handle);
+ tPORT_MGMT_SR_CALLBACK_ARG *sr_mgmt_cb_arg = (tPORT_MGMT_SR_CALLBACK_ARG *)data;
+ if (p_scb == NULL) {
+ OBEX_TL_RFCOMM_TRACE_WARNING("No scb to this rfcomm connection\n");
+ /* tell rfcomm to reject this connection */
+ sr_mgmt_cb_arg->accept = FALSE;
+ return;
+ }
+
+ /* try to find p_ccb with this rfc_handle, we expect to get a NULL */
+ p_ccb = find_ccb_by_rfc_handle(rfc_handle);
+ if (p_ccb == NULL) {
+ p_ccb = allocate_ccb();
+ if (p_ccb == NULL) {
+ OBEX_TL_RFCOMM_TRACE_WARNING("can not allocate a ccb for new connection\n");
+ sr_mgmt_cb_arg->accept = FALSE;
+ return;
+ }
+ }
+ else {
+ OBEX_TL_RFCOMM_TRACE_WARNING("found duplicate rfcomm connection\n");
+ }
+
+ p_ccb->initiator = FALSE;
+ p_ccb->rfc_handle = rfc_handle;
+ p_ccb->scn = p_scb->scn;
+ p_ccb->mtu = sr_mgmt_cb_arg->peer_mtu;
+ /* get peer bd_addr */
+ PORT_CheckConnection(rfc_handle, FALSE, p_ccb->addr, NULL);
+
+ tOBEX_TL_MSG msg = {0};
+ msg.conn_income.hdl = p_ccb->allocated;
+ msg.conn_income.peer_mtu = p_ccb->mtu;
+ msg.conn_income.our_mtu = p_ccb->mtu;
+ msg.conn_income.svr_hdl = (p_scb->allocated << 8);
+ obex_tl_rfcomm_cb.callback(OBEX_TL_CONN_INCOME_EVT, &msg);
+ }
+ else {
+ /* other event, it means server is connected */
+ p_ccb = find_ccb_by_rfc_handle(rfc_handle);
+ if (p_ccb == NULL) {
+ OBEX_TL_RFCOMM_TRACE_DEBUG("No ccb to handle rfcomm event\n");
+ return;
+ }
+ }
+ rfcomm_mgmt_event_handler(p_ccb, code);
+}
+
+static int rfcomm_data_callback(UINT16 rfc_handle, UINT8 *p_buf, UINT16 len, int type)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_rfc_handle(rfc_handle);
+ if (p_ccb != NULL && type == DATA_CO_CALLBACK_TYPE_INCOMING) {
+ tOBEX_TL_MSG msg = {0};
+ msg.data.hdl = p_ccb->allocated;
+ msg.data.p_buf = (BT_HDR *)p_buf;
+ obex_tl_rfcomm_cb.callback(OBEX_TL_DATA_EVT, &msg);
+ PORT_FlowControl_GiveCredit(rfc_handle, TRUE, 1);
+ }
+ else if(p_buf != NULL) {
+ osi_free(p_buf);
+ }
+ return 1;
+}
+
+static void rfcomm_event_callback(UINT32 code, UINT16 rfc_handle)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_rfc_handle(rfc_handle);
+ if (p_ccb == NULL) {
+ OBEX_TL_RFCOMM_TRACE_WARNING("No ccb to handle rfcomm event\n");
+ return;
+ }
+
+ if (code & PORT_EV_FC) {
+ tOBEX_TL_MSG msg = {0};
+ msg.any.hdl = p_ccb->allocated;
+ if (code & PORT_EV_FCS) {
+ obex_tl_rfcomm_cb.callback(OBEX_TL_UNCONGEST_EVT, &msg);
+ }
+ else {
+ obex_tl_rfcomm_cb.callback(OBEX_TL_CONGEST_EVT, &msg);
+ }
+ }
+}
+
+void obex_tl_rfcomm_init(tOBEX_TL_CBACK *callback)
+{
+ assert(callback != NULL);
+#if (OBEX_DYNAMIC_MEMORY)
+ if (!obex_tl_rfcomm_cb_ptr) {
+ obex_tl_rfcomm_cb_ptr = (tOBEX_TL_RFCOMM_CB *)osi_malloc(sizeof(tOBEX_TL_RFCOMM_CB));
+ if (!obex_tl_rfcomm_cb_ptr) {
+ OBEX_TL_RFCOMM_TRACE_ERROR("OBEX over RFCOMM transport layer initialize failed, no memory\n");
+ assert(0);
+ }
+ }
+#endif /* #if (OBEX_DYNAMIC_MEMORY) */
+ memset(&obex_tl_rfcomm_cb, 0, sizeof(tOBEX_TL_RFCOMM_CB));
+ obex_tl_rfcomm_cb.callback = callback;
+ obex_tl_rfcomm_cb.trace_level = BT_TRACE_LEVEL_ERROR;
+}
+
+void obex_tl_rfcomm_deinit(void)
+{
+#if (OBEX_DYNAMIC_MEMORY)
+ if (obex_tl_rfcomm_cb_ptr) {
+ osi_free(obex_tl_rfcomm_cb_ptr);
+ obex_tl_rfcomm_cb_ptr = NULL;
+ }
+#endif /* #if (OBEX_DYNAMIC_MEMORY) */
+}
+
+UINT16 obex_tl_rfcomm_connect(tOBEX_TL_SVR_INFO *server)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = allocate_ccb();
+ if (p_ccb == NULL) {
+ return 0;
+ }
+
+ BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_OBEX, server->rfcomm.sec_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, server->rfcomm.scn);
+ if (RFCOMM_CreateConnection(UUID_PROTOCOL_OBEX, server->rfcomm.scn, FALSE, server->rfcomm.pref_mtu,
+ server->rfcomm.addr, &p_ccb->rfc_handle, rfcomm_client_mgmt_callback) != PORT_SUCCESS) {
+ free_ccb(p_ccb);
+ return 0;
+ }
+
+ /* set up data callback, event mask and event callback */
+ PORT_SetDataCOCallback(p_ccb->rfc_handle, rfcomm_data_callback);
+ PORT_SetEventMask(p_ccb->rfc_handle, OBEX_TL_RFCOMM_EVENT_MARK);
+ PORT_SetEventCallback(p_ccb->rfc_handle, rfcomm_event_callback);
+
+ bdcpy(p_ccb->addr, server->rfcomm.addr);
+ p_ccb->scn = server->rfcomm.scn;
+ p_ccb->initiator = TRUE;
+
+ return p_ccb->allocated;
+}
+
+void obex_tl_rfcomm_disconnect(UINT16 handle)
+{
+ tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_handle(handle);
+ if (p_ccb != NULL) {
+ RFCOMM_RemoveConnection(p_ccb->rfc_handle);
+ free_ccb(p_ccb);
+ }
+}
+
+UINT16 obex_tl_rfcomm_send(UINT16 handle, BT_HDR *p_buf)
+{
+ UINT16 ret = OBEX_TL_FAILED;
+ tOBEX_TL_RFCOMM_CCB *p_ccb = find_ccb_by_handle(handle);
+ do {
+ if (p_ccb == NULL) {
+ osi_free(p_buf);
+ break;
+ }
+
+ /* Can not send data size larger than MTU */
+ /* Offset should not smaller than OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET */
+ if (p_buf->len > p_ccb->mtu || p_buf->offset < OBEX_TL_RFCOMM_BT_HDR_MIN_OFFSET) {
+ osi_free(p_buf);
+ break;
+ }
+
+ if (PORT_Write(p_ccb->rfc_handle, p_buf) == PORT_SUCCESS) {
+ ret = OBEX_TL_SUCCESS;
+ }
+ } while (0);
+ return ret;
+}
+
+UINT16 obex_tl_rfcomm_bind(tOBEX_TL_SVR_INFO *server)
+{
+ tOBEX_TL_RFCOMM_SCB *p_scb = find_scb_by_scn(server->rfcomm.scn);
+ if (p_scb != NULL) {
+ /* scn already used */
+ return 0;
+ }
+
+ p_scb = allocate_scb();
+ if (p_scb == NULL) {
+ OBEX_TL_RFCOMM_TRACE_WARNING("Can not allocate scb, out of number\n");
+ return 0;
+ }
+
+ BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_OBEX, server->rfcomm.sec_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, server->rfcomm.scn);
+ if (RFCOMM_CreateConnection(UUID_PROTOCOL_OBEX, server->rfcomm.scn, TRUE, server->rfcomm.pref_mtu,
+ server->rfcomm.addr, &p_scb->rfc_handle, rfcomm_server_mgmt_callback) != PORT_SUCCESS) {
+ free_scb(p_scb);
+ return 0;
+ }
+
+ /* set up data callback, event mask and event callback */
+ PORT_SetDataCOCallback(p_scb->rfc_handle, rfcomm_data_callback);
+ PORT_SetEventMask(p_scb->rfc_handle, OBEX_TL_RFCOMM_EVENT_MARK);
+ PORT_SetEventCallback(p_scb->rfc_handle, rfcomm_event_callback);
+
+ p_scb->scn = server->rfcomm.scn;
+
+ /* left shift 8 bits as server handle, avoid confuse with connection handle */
+ return (p_scb->allocated << 8);
+}
+
+void obex_tl_rfcomm_unbind(UINT16 handle)
+{
+ tOBEX_TL_RFCOMM_SCB *p_scb = find_scb_by_handle(handle);
+ if (p_scb) {
+ tOBEX_TL_RFCOMM_CCB *p_ccb = NULL;
+ while ((p_ccb = find_ccb_by_rfc_handle(p_scb->rfc_handle)) != NULL) {
+ RFCOMM_RemoveConnection(p_ccb->rfc_handle);
+ tOBEX_TL_MSG msg = {0};
+ msg.any.hdl = p_ccb->allocated;
+ obex_tl_rfcomm_cb.callback(OBEX_TL_DIS_CONN_EVT, &msg);
+ free_ccb(p_ccb);
+ }
+ RFCOMM_RemoveServer(p_scb->rfc_handle);
+ free_scb(p_scb);
+ }
+}
+
+static tOBEX_TL_OPS obex_tl_rfcomm_ops = {
+ .init = obex_tl_rfcomm_init,
+ .deinit = obex_tl_rfcomm_deinit,
+ .connect = obex_tl_rfcomm_connect,
+ .disconnect = obex_tl_rfcomm_disconnect,
+ .bind = obex_tl_rfcomm_bind,
+ .unbind = obex_tl_rfcomm_unbind,
+ .send = obex_tl_rfcomm_send
+};
+
+/*******************************************************************************
+**
+** Function obex_tl_rfcomm_ops_get
+**
+** Description Get the operation function structure pointer of OBEX over
+** RFCOMM transport layer
+**
+** Returns Pointer to operation function structure
+**
+*******************************************************************************/
+tOBEX_TL_OPS *obex_tl_rfcomm_ops_get(void)
+{
+ return &obex_tl_rfcomm_ops;
+}
+
+#endif /* #if (OBEX_INCLUDED == TRUE && RFCOMM_INCLUDED == TRUE) */
diff --git a/lib/bt/host/bluedroid/stack/sdp/sdp_api.c b/lib/bt/host/bluedroid/stack/sdp/sdp_api.c
index 0103e4de..9b477a1c 100644
--- a/lib/bt/host/bluedroid/stack/sdp/sdp_api.c
+++ b/lib/bt/host/bluedroid/stack/sdp/sdp_api.c
@@ -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);
+}
/*******************************************************************************
**
diff --git a/lib/bt/host/bluedroid/stack/sdp/sdp_db.c b/lib/bt/host/bluedroid/stack/sdp/sdp_db.c
index a9b3daa4..60dd04a6 100644
--- a/lib/bt/host/bluedroid/stack/sdp/sdp_db.c
+++ b/lib/bt/host/bluedroid/stack/sdp/sdp_db.c
@@ -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;
}
diff --git a/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c b/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c
index d63b164d..31ab11f4 100644
--- a/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c
+++ b/lib/bt/host/bluedroid/stack/sdp/sdp_discovery.c
@@ -453,7 +453,7 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
}
}
- /* Now, ask for the next handle. Re-use the buffer we just got. */
+ /* Now, ask for the next handle. Reuse the buffer we just got. */
if (p_ccb->cur_handle < p_ccb->num_handles) {
BT_HDR *p_msg = (BT_HDR *) osi_malloc(SDP_DATA_BUF_SIZE);
UINT8 *p;
@@ -669,6 +669,7 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) {
SDP_TRACE_WARNING ("SDP - Wrong type: 0x%02x in attr_rsp\n", type);
+ sdp_disconnect (p_ccb, SDP_ILLEGAL_PARAMETER);
return;
}
p = sdpu_get_len_from_type (p, type, &seq_len);
diff --git a/lib/bt/host/bluedroid/stack/smp/smp_act.c b/lib/bt/host/bluedroid/stack/smp/smp_act.c
index 0e7dcd5b..43b2e476 100644
--- a/lib/bt/host/bluedroid/stack/smp/smp_act.c
+++ b/lib/bt/host/bluedroid/stack/smp/smp_act.c
@@ -1553,7 +1553,7 @@ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
}
/* Disable L2CAP connection parameter updates while bonding since
some peripherals are not able to revert to fast connection parameters
- during the start of service discovery. Connection paramter updates
+ during the start of service discovery. Connection parameter updates
get enabled again once service discovery completes. */
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
@@ -1648,6 +1648,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
/* slave calculates and sends local commitment */
smp_calculate_local_commitment(p_cb);
smp_send_commitment(p_cb, NULL);
+ /* Ensure the connection is still active */
+ if (smp_get_state() == SMP_STATE_IDLE) return;
/* slave has to wait for peer nonce */
smp_set_state(SMP_STATE_WAIT_NONCE);
} else { /* i.e. master */
@@ -1658,6 +1660,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
p_cb->selected_association_model);
p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM;
smp_send_rand(p_cb, NULL);
+ /* Ensure the connection is still active */
+ if (smp_get_state() == SMP_STATE_IDLE) return;
smp_set_state(SMP_STATE_WAIT_NONCE);
}
}
@@ -1672,6 +1676,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_COMM) {
/* master commitment is already received */
smp_send_commitment(p_cb, NULL);
+ /* Ensure the connection is still active */
+ if (smp_get_state() == SMP_STATE_IDLE) return;
smp_set_state(SMP_STATE_WAIT_NONCE);
}
}
@@ -1679,6 +1685,8 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
case SMP_MODEL_SEC_CONN_OOB:
if (p_cb->role == HCI_ROLE_MASTER) {
smp_send_rand(p_cb, NULL);
+ /* Ensure the connection is still active */
+ if (smp_get_state() == SMP_STATE_IDLE) return;
}
smp_set_state(SMP_STATE_WAIT_NONCE);
@@ -2002,7 +2010,7 @@ void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable)
SMP_TRACE_DEBUG("%s encr_enable=%d\n", __func__, encr_enable);
if (memcmp(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN) == 0) {
- /* encryption completed with STK, remmeber the key size now, could be overwite
+ /* encryption completed with STK, remember the key size now, could be overwrite
* when key exchange happens */
if (p_cb->loc_enc_size != 0 && encr_enable) {
/* update the link encryption key size if a SMP pairing just performed */
diff --git a/lib/bt/host/bluedroid/stack/smp/smp_utils.c b/lib/bt/host/bluedroid/stack/smp/smp_utils.c
index 2e9fac77..48ba6c0a 100644
--- a/lib/bt/host/bluedroid/stack/smp/smp_utils.c
+++ b/lib/bt/host/bluedroid/stack/smp/smp_utils.c
@@ -331,8 +331,7 @@ BOOLEAN smp_send_msg_to_L2CAP(BD_ADDR rem_bda, BT_HDR *p_toL2CAP)
if ((l2cap_ret = L2CA_SendFixedChnlData (fixed_cid, rem_bda, p_toL2CAP)) == L2CAP_DW_FAILED) {
smp_cb.total_tx_unacked -= 1;
- SMP_TRACE_ERROR("SMP failed to pass msg:0x%0x to L2CAP",
- *((UINT8 *)(p_toL2CAP + 1) + p_toL2CAP->offset));
+ SMP_TRACE_ERROR("SMP failed to pass msg to L2CAP");
return FALSE;
} else {
return TRUE;
@@ -1125,7 +1124,7 @@ BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb)
SMP_TRACE_DEBUG("%s for cmd code 0x%02x\n", __func__, p_cb->rcvd_cmd_code);
if (io_caps >= BTM_IO_CAP_MAX) {
- SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with IO Capabilty \
+ SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with IO Capability \
value (0x%02x) out of range).\n",
p_cb->rcvd_cmd_code, io_caps);
return FALSE;