Fork ESP-IDF's bluetooth component
i want better sbc encoding, and no cla will stop me
This commit is contained in:
@@ -0,0 +1,899 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
if(${target} STREQUAL "linux")
|
||||
return() # This component is not supported by the POSIX/Linux simulator
|
||||
endif()
|
||||
|
||||
# API headers that are used in the docs are also compiled
|
||||
# even if CONFIG_BT_ENABLED=n as long as CONFIG_IDF_DOC_BUILD=y
|
||||
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
set(target_specific_include_dirs include/esp32/include)
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
set(target_specific_include_dirs include/esp32c3/include)
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
set(target_specific_include_dirs include/esp32c3/include)
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||
set(target_specific_include_dirs include/esp32c2/include)
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C6)
|
||||
set(target_specific_include_dirs include/esp32c6/include)
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2)
|
||||
set(target_specific_include_dirs include/esp32h2/include)
|
||||
endif()
|
||||
|
||||
set(common_include_dirs
|
||||
common/api/include/api
|
||||
common/btc/profile/esp/blufi/include
|
||||
common/btc/profile/esp/include
|
||||
)
|
||||
|
||||
set(ble_mesh_include_dirs
|
||||
"esp_ble_mesh/common/include"
|
||||
"esp_ble_mesh/common/tinycrypt/include"
|
||||
"esp_ble_mesh/core"
|
||||
"esp_ble_mesh/core/include"
|
||||
"esp_ble_mesh/core/storage"
|
||||
"esp_ble_mesh/btc/include"
|
||||
"esp_ble_mesh/models/common/include"
|
||||
"esp_ble_mesh/models/client/include"
|
||||
"esp_ble_mesh/models/server/include"
|
||||
"esp_ble_mesh/api/core/include"
|
||||
"esp_ble_mesh/api/models/include"
|
||||
"esp_ble_mesh/api"
|
||||
"esp_ble_mesh/lib/include"
|
||||
"esp_ble_mesh/v1.1/api/core/include"
|
||||
"esp_ble_mesh/v1.1/api/models/include"
|
||||
"esp_ble_mesh/v1.1/btc/include"
|
||||
)
|
||||
|
||||
set(bluedroid_include_dirs host/bluedroid/api/include/api)
|
||||
|
||||
if(CONFIG_BT_CONTROLLER_ENABLED OR CONFIG_IDF_DOC_BUILD)
|
||||
set(nimble_hci_include_dirs host/nimble/esp-hci/include)
|
||||
endif()
|
||||
|
||||
if(CONFIG_IDF_DOC_BUILD)
|
||||
list(APPEND include_dirs
|
||||
${target_specific_include_dirs}
|
||||
${common_include_dirs}
|
||||
${ble_mesh_include_dirs}
|
||||
${bluedroid_include_dirs}
|
||||
${nimble_hci_include_dirs})
|
||||
endif()
|
||||
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
|
||||
set(srcs "")
|
||||
set(include_dirs "")
|
||||
set(ldfragments "linker.lf")
|
||||
if(CONFIG_BT_CONTROLLER_ENABLED)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
list(APPEND srcs "controller/esp32/bt.c"
|
||||
"controller/esp32/hli_api.c"
|
||||
"controller/esp32/hli_vectors.S")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
list(APPEND srcs "controller/esp32c3/bt.c")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
list(APPEND srcs "controller/esp32c3/bt.c")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||
list(APPEND srcs "controller/esp32c2/bt.c")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||
set(ldfragments "linker.lf.esp32c2")
|
||||
list(APPEND srcs "controller/esp32c2/bt.c")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C6)
|
||||
list(APPEND srcs "controller/esp32c6/bt.c")
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2)
|
||||
list(APPEND srcs "controller/esp32h2/bt.c")
|
||||
endif()
|
||||
|
||||
list(APPEND include_dirs ${target_specific_include_dirs})
|
||||
|
||||
endif()
|
||||
|
||||
# Common
|
||||
list(APPEND include_dirs common/osi/include)
|
||||
|
||||
list(APPEND priv_include_dirs
|
||||
common/btc/include
|
||||
common/include
|
||||
porting/mem/
|
||||
)
|
||||
list(APPEND include_dirs ${common_include_dirs})
|
||||
|
||||
list(APPEND srcs "common/btc/core/btc_alarm.c"
|
||||
"common/api/esp_blufi_api.c"
|
||||
"common/btc/core/btc_manage.c"
|
||||
"common/btc/core/btc_task.c"
|
||||
"common/btc/profile/esp/blufi/blufi_prf.c"
|
||||
"common/btc/profile/esp/blufi/blufi_protocol.c"
|
||||
"common/osi/alarm.c"
|
||||
"common/osi/allocator.c"
|
||||
"common/osi/buffer.c"
|
||||
"common/osi/config.c"
|
||||
"common/osi/fixed_queue.c"
|
||||
"common/osi/pkt_queue.c"
|
||||
"common/osi/fixed_pkt_queue.c"
|
||||
"common/osi/future.c"
|
||||
"common/osi/hash_functions.c"
|
||||
"common/osi/hash_map.c"
|
||||
"common/osi/list.c"
|
||||
"common/osi/mutex.c"
|
||||
"common/osi/thread.c"
|
||||
"common/osi/osi.c"
|
||||
"common/osi/semaphore.c"
|
||||
"porting/mem/bt_osi_mem.c"
|
||||
)
|
||||
|
||||
# Host Bluedroid
|
||||
if(CONFIG_BT_BLUEDROID_ENABLED)
|
||||
|
||||
list(APPEND priv_include_dirs
|
||||
host/bluedroid/bta/include
|
||||
host/bluedroid/bta/ar/include
|
||||
host/bluedroid/bta/av/include
|
||||
host/bluedroid/bta/dm/include
|
||||
host/bluedroid/bta/gatt/include
|
||||
host/bluedroid/bta/hf_ag/include
|
||||
host/bluedroid/bta/hf_client/include
|
||||
host/bluedroid/bta/hd/include
|
||||
host/bluedroid/bta/hh/include
|
||||
host/bluedroid/bta/jv/include
|
||||
host/bluedroid/bta/sdp/include
|
||||
host/bluedroid/bta/sys/include
|
||||
host/bluedroid/device/include
|
||||
host/bluedroid/hci/include
|
||||
host/bluedroid/external/sbc/decoder/include
|
||||
host/bluedroid/external/sbc/encoder/include
|
||||
host/bluedroid/external/sbc/plc/include
|
||||
host/bluedroid/btc/profile/esp/include
|
||||
host/bluedroid/btc/profile/std/a2dp/include
|
||||
host/bluedroid/btc/profile/std/include
|
||||
host/bluedroid/btc/include
|
||||
host/bluedroid/stack/btm/include
|
||||
host/bluedroid/stack/gap/include
|
||||
host/bluedroid/stack/gatt/include
|
||||
host/bluedroid/stack/hid/include
|
||||
host/bluedroid/stack/l2cap/include
|
||||
host/bluedroid/stack/sdp/include
|
||||
host/bluedroid/stack/smp/include
|
||||
host/bluedroid/stack/avct/include
|
||||
host/bluedroid/stack/avrc/include
|
||||
host/bluedroid/stack/avdt/include
|
||||
host/bluedroid/stack/a2dp/include
|
||||
host/bluedroid/stack/rfcomm/include
|
||||
host/bluedroid/stack/include
|
||||
host/bluedroid/common/include
|
||||
host/bluedroid/config/include)
|
||||
|
||||
list(APPEND include_dirs ${bluedroid_include_dirs})
|
||||
|
||||
list(APPEND srcs "host/bluedroid/api/esp_a2dp_api.c"
|
||||
"host/bluedroid/api/esp_avrc_api.c"
|
||||
"host/bluedroid/api/esp_bluedroid_hci.c"
|
||||
"host/bluedroid/api/esp_bt_device.c"
|
||||
"host/bluedroid/api/esp_bt_main.c"
|
||||
"host/bluedroid/api/esp_gap_ble_api.c"
|
||||
"host/bluedroid/api/esp_gap_bt_api.c"
|
||||
"host/bluedroid/api/esp_gatt_common_api.c"
|
||||
"host/bluedroid/api/esp_gattc_api.c"
|
||||
"host/bluedroid/api/esp_gatts_api.c"
|
||||
"host/bluedroid/api/esp_hidd_api.c"
|
||||
"host/bluedroid/api/esp_hidh_api.c"
|
||||
"host/bluedroid/api/esp_hf_ag_api.c"
|
||||
"host/bluedroid/api/esp_hf_client_api.c"
|
||||
"host/bluedroid/api/esp_spp_api.c"
|
||||
"host/bluedroid/api/esp_sdp_api.c"
|
||||
"host/bluedroid/api/esp_l2cap_bt_api.c"
|
||||
"host/bluedroid/bta/ar/bta_ar.c"
|
||||
"host/bluedroid/bta/av/bta_av_aact.c"
|
||||
"host/bluedroid/bta/av/bta_av_act.c"
|
||||
"host/bluedroid/bta/av/bta_av_api.c"
|
||||
"host/bluedroid/bta/av/bta_av_cfg.c"
|
||||
"host/bluedroid/bta/av/bta_av_ci.c"
|
||||
"host/bluedroid/bta/av/bta_av_main.c"
|
||||
"host/bluedroid/bta/av/bta_av_sbc.c"
|
||||
"host/bluedroid/bta/av/bta_av_ssm.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_act.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_api.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_cfg.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_ci.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_co.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_main.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_pm.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_sco.c"
|
||||
"host/bluedroid/bta/dm/bta_dm_qos.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatt_common.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_act.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_api.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_cache.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_ci.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_co.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_main.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_utils.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_act.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_api.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_co.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_main.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_utils.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_api.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_act.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_main.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_act.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_api.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_cfg.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_le.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_main.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_utils.c"
|
||||
"host/bluedroid/bta/jv/bta_jv_act.c"
|
||||
"host/bluedroid/bta/jv/bta_jv_api.c"
|
||||
"host/bluedroid/bta/jv/bta_jv_cfg.c"
|
||||
"host/bluedroid/bta/jv/bta_jv_main.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_act.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_api.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_at.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_cfg.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_cmd.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_main.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_rfc.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_sco.c"
|
||||
"host/bluedroid/bta/hf_ag/bta_ag_sdp.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_act.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_api.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_at.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_cmd.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_main.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_rfc.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_sco.c"
|
||||
"host/bluedroid/bta/hf_client/bta_hf_client_sdp.c"
|
||||
"host/bluedroid/bta/sdp/bta_sdp.c"
|
||||
"host/bluedroid/bta/sdp/bta_sdp_act.c"
|
||||
"host/bluedroid/bta/sdp/bta_sdp_api.c"
|
||||
"host/bluedroid/bta/sdp/bta_sdp_cfg.c"
|
||||
"host/bluedroid/bta/sys/bta_sys_conn.c"
|
||||
"host/bluedroid/bta/sys/bta_sys_main.c"
|
||||
"host/bluedroid/bta/sys/utl.c"
|
||||
"host/bluedroid/btc/core/btc_ble_storage.c"
|
||||
"host/bluedroid/btc/core/btc_config.c"
|
||||
"host/bluedroid/btc/core/btc_dev.c"
|
||||
"host/bluedroid/btc/core/btc_dm.c"
|
||||
"host/bluedroid/btc/core/btc_main.c"
|
||||
"host/bluedroid/btc/core/btc_profile_queue.c"
|
||||
"host/bluedroid/btc/core/btc_sec.c"
|
||||
"host/bluedroid/btc/core/btc_sm.c"
|
||||
"host/bluedroid/btc/core/btc_storage.c"
|
||||
"host/bluedroid/btc/core/btc_util.c"
|
||||
"host/bluedroid/btc/profile/std/a2dp/bta_av_co.c"
|
||||
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c"
|
||||
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c"
|
||||
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c"
|
||||
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c"
|
||||
"host/bluedroid/btc/profile/std/a2dp/btc_av.c"
|
||||
"host/bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
||||
"host/bluedroid/btc/profile/std/avrc/bta_avrc_co.c"
|
||||
"host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c"
|
||||
"host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c"
|
||||
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
||||
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
||||
"host/bluedroid/btc/profile/std/hid/btc_hd.c"
|
||||
"host/bluedroid/btc/profile/std/hid/btc_hh.c"
|
||||
"host/bluedroid/btc/profile/std/hid/bta_hh_co.c"
|
||||
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||
"host/bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
||||
"host/bluedroid/btc/profile/std/gap/bta_gap_bt_co.c"
|
||||
"host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c"
|
||||
"host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c"
|
||||
"host/bluedroid/btc/profile/std/gatt/btc_gattc.c"
|
||||
"host/bluedroid/btc/profile/std/gatt/btc_gatts.c"
|
||||
"host/bluedroid/btc/profile/std/spp/btc_spp.c"
|
||||
"host/bluedroid/btc/profile/std/sdp/btc_sdp.c"
|
||||
"host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c"
|
||||
"host/bluedroid/device/bdaddr.c"
|
||||
"host/bluedroid/device/controller.c"
|
||||
"host/bluedroid/device/interop.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/alloc.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/bitalloc-sbc.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/bitalloc.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/bitstream-decode.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/decoder-oina.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/decoder-private.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/dequant.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/framing-sbc.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/framing.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/oi_codec_version.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/synthesis-8-generated.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/synthesis-dct8.c"
|
||||
"host/bluedroid/external/sbc/decoder/srce/synthesis-sbc.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_analysis.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_dct.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_dct_coeffs.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_coeffs.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c"
|
||||
"host/bluedroid/external/sbc/encoder/srce/sbc_packing.c"
|
||||
"host/bluedroid/external/sbc/plc/sbc_plc.c"
|
||||
"host/bluedroid/hci/hci_audio.c"
|
||||
"host/bluedroid/hci/hci_hal_h4.c"
|
||||
"host/bluedroid/hci/hci_layer.c"
|
||||
"host/bluedroid/hci/hci_packet_factory.c"
|
||||
"host/bluedroid/hci/hci_packet_parser.c"
|
||||
"host/bluedroid/hci/packet_fragmenter.c"
|
||||
"host/bluedroid/main/bte_init.c"
|
||||
"host/bluedroid/main/bte_main.c"
|
||||
"host/bluedroid/stack/a2dp/a2d_api.c"
|
||||
"host/bluedroid/stack/a2dp/a2d_sbc.c"
|
||||
"host/bluedroid/stack/avct/avct_api.c"
|
||||
"host/bluedroid/stack/avct/avct_ccb.c"
|
||||
"host/bluedroid/stack/avct/avct_l2c.c"
|
||||
"host/bluedroid/stack/avct/avct_lcb.c"
|
||||
"host/bluedroid/stack/avct/avct_lcb_act.c"
|
||||
"host/bluedroid/stack/avdt/avdt_ad.c"
|
||||
"host/bluedroid/stack/avdt/avdt_api.c"
|
||||
"host/bluedroid/stack/avdt/avdt_ccb.c"
|
||||
"host/bluedroid/stack/avdt/avdt_ccb_act.c"
|
||||
"host/bluedroid/stack/avdt/avdt_l2c.c"
|
||||
"host/bluedroid/stack/avdt/avdt_msg.c"
|
||||
"host/bluedroid/stack/avdt/avdt_scb.c"
|
||||
"host/bluedroid/stack/avdt/avdt_scb_act.c"
|
||||
"host/bluedroid/stack/avrc/avrc_api.c"
|
||||
"host/bluedroid/stack/avrc/avrc_bld_ct.c"
|
||||
"host/bluedroid/stack/avrc/avrc_bld_tg.c"
|
||||
"host/bluedroid/stack/avrc/avrc_opt.c"
|
||||
"host/bluedroid/stack/avrc/avrc_pars_ct.c"
|
||||
"host/bluedroid/stack/avrc/avrc_pars_tg.c"
|
||||
"host/bluedroid/stack/avrc/avrc_sdp.c"
|
||||
"host/bluedroid/stack/avrc/avrc_utils.c"
|
||||
"host/bluedroid/stack/hid/hidd_api.c"
|
||||
"host/bluedroid/stack/hid/hidd_conn.c"
|
||||
"host/bluedroid/stack/hid/hidh_api.c"
|
||||
"host/bluedroid/stack/hid/hidh_conn.c"
|
||||
"host/bluedroid/stack/btm/btm_acl.c"
|
||||
"host/bluedroid/stack/btm/btm_ble.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_addr.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_adv_filter.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_batchscan.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_bgconn.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_cont_energy.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_gap.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_5_gap.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_multi_adv.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_privacy.c"
|
||||
"host/bluedroid/stack/btm/btm_dev.c"
|
||||
"host/bluedroid/stack/btm/btm_devctl.c"
|
||||
"host/bluedroid/stack/btm/btm_inq.c"
|
||||
"host/bluedroid/stack/btm/btm_main.c"
|
||||
"host/bluedroid/stack/btm/btm_pm.c"
|
||||
"host/bluedroid/stack/btm/btm_sco.c"
|
||||
"host/bluedroid/stack/btm/btm_sec.c"
|
||||
"host/bluedroid/stack/btu/btu_hcif.c"
|
||||
"host/bluedroid/stack/btu/btu_init.c"
|
||||
"host/bluedroid/stack/btu/btu_task.c"
|
||||
"host/bluedroid/stack/gap/gap_api.c"
|
||||
"host/bluedroid/stack/gap/gap_ble.c"
|
||||
"host/bluedroid/stack/gap/gap_conn.c"
|
||||
"host/bluedroid/stack/gap/gap_utils.c"
|
||||
"host/bluedroid/stack/gatt/att_protocol.c"
|
||||
"host/bluedroid/stack/gatt/gatt_api.c"
|
||||
"host/bluedroid/stack/gatt/gatt_attr.c"
|
||||
"host/bluedroid/stack/gatt/gatt_auth.c"
|
||||
"host/bluedroid/stack/gatt/gatt_cl.c"
|
||||
"host/bluedroid/stack/gatt/gatt_db.c"
|
||||
"host/bluedroid/stack/gatt/gatt_main.c"
|
||||
"host/bluedroid/stack/gatt/gatt_sr.c"
|
||||
"host/bluedroid/stack/gatt/gatt_sr_hash.c"
|
||||
"host/bluedroid/stack/gatt/gatt_utils.c"
|
||||
"host/bluedroid/stack/hcic/hciblecmds.c"
|
||||
"host/bluedroid/stack/hcic/hcicmds.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_api.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_ble.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_csm.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_fcr.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_link.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_main.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_ucd.c"
|
||||
"host/bluedroid/stack/l2cap/l2c_utils.c"
|
||||
"host/bluedroid/stack/l2cap/l2cap_client.c"
|
||||
"host/bluedroid/stack/rfcomm/port_api.c"
|
||||
"host/bluedroid/stack/rfcomm/port_rfc.c"
|
||||
"host/bluedroid/stack/rfcomm/port_utils.c"
|
||||
"host/bluedroid/stack/rfcomm/rfc_l2cap_if.c"
|
||||
"host/bluedroid/stack/rfcomm/rfc_mx_fsm.c"
|
||||
"host/bluedroid/stack/rfcomm/rfc_port_fsm.c"
|
||||
"host/bluedroid/stack/rfcomm/rfc_port_if.c"
|
||||
"host/bluedroid/stack/rfcomm/rfc_ts_frames.c"
|
||||
"host/bluedroid/stack/rfcomm/rfc_utils.c"
|
||||
"host/bluedroid/stack/sdp/sdp_api.c"
|
||||
"host/bluedroid/stack/sdp/sdp_db.c"
|
||||
"host/bluedroid/stack/sdp/sdp_discovery.c"
|
||||
"host/bluedroid/stack/sdp/sdp_main.c"
|
||||
"host/bluedroid/stack/sdp/sdp_server.c"
|
||||
"host/bluedroid/stack/sdp/sdp_utils.c"
|
||||
"host/bluedroid/stack/smp/aes.c"
|
||||
"host/bluedroid/stack/smp/p_256_curvepara.c"
|
||||
"host/bluedroid/stack/smp/p_256_ecc_pp.c"
|
||||
"host/bluedroid/stack/smp/p_256_multprecision.c"
|
||||
"host/bluedroid/stack/smp/smp_act.c"
|
||||
"host/bluedroid/stack/smp/smp_api.c"
|
||||
"host/bluedroid/stack/smp/smp_br_main.c"
|
||||
"host/bluedroid/stack/smp/smp_cmac.c"
|
||||
"host/bluedroid/stack/smp/smp_keys.c"
|
||||
"host/bluedroid/stack/smp/smp_l2c.c"
|
||||
"host/bluedroid/stack/smp/smp_main.c"
|
||||
"host/bluedroid/stack/smp/smp_utils.c"
|
||||
"host/bluedroid/config/stack_config.c")
|
||||
|
||||
|
||||
list(APPEND srcs "common/btc/profile/esp/blufi/bluedroid_host/esp_blufi.c")
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
list(APPEND srcs "esp_ble_mesh/core/bluedroid_host/adapter.c")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
list(APPEND include_dirs ${ble_mesh_include_dirs})
|
||||
|
||||
list(APPEND srcs "esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_common_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_ble.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_config_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_generic_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_health_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_prov.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/aes_decrypt.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/aes_encrypt.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/cbc_mode.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/ccm_mode.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/cmac_mode.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/ctr_mode.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/ctr_prng.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/ecc_dh.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/ecc_dsa.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/ecc_platform_specific.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/ecc.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/hmac_prng.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/hmac.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/sha256.c"
|
||||
"esp_ble_mesh/common/tinycrypt/src/utils.c"
|
||||
"esp_ble_mesh/common/atomic.c"
|
||||
"esp_ble_mesh/common/buf.c"
|
||||
"esp_ble_mesh/common/common.c"
|
||||
"esp_ble_mesh/common/kernel.c"
|
||||
"esp_ble_mesh/common/mutex.c"
|
||||
"esp_ble_mesh/common/timer.c"
|
||||
"esp_ble_mesh/common/utils.c"
|
||||
"esp_ble_mesh/core/storage/settings_nvs.c"
|
||||
"esp_ble_mesh/core/storage/settings_uid.c"
|
||||
"esp_ble_mesh/core/storage/settings.c"
|
||||
"esp_ble_mesh/core/access.c"
|
||||
"esp_ble_mesh/core/adv.c"
|
||||
"esp_ble_mesh/core/beacon.c"
|
||||
"esp_ble_mesh/core/cfg_cli.c"
|
||||
"esp_ble_mesh/core/cfg_srv.c"
|
||||
"esp_ble_mesh/core/crypto.c"
|
||||
"esp_ble_mesh/core/fast_prov.c"
|
||||
"esp_ble_mesh/core/friend.c"
|
||||
"esp_ble_mesh/core/health_cli.c"
|
||||
"esp_ble_mesh/core/health_srv.c"
|
||||
"esp_ble_mesh/core/heartbeat.c"
|
||||
"esp_ble_mesh/core/local.c"
|
||||
"esp_ble_mesh/core/lpn.c"
|
||||
"esp_ble_mesh/core/main.c"
|
||||
"esp_ble_mesh/core/net.c"
|
||||
"esp_ble_mesh/core/prov_common.c"
|
||||
"esp_ble_mesh/core/prov_node.c"
|
||||
"esp_ble_mesh/core/prov_pvnr.c"
|
||||
"esp_ble_mesh/core/proxy_client.c"
|
||||
"esp_ble_mesh/core/proxy_server.c"
|
||||
"esp_ble_mesh/core/pvnr_mgmt.c"
|
||||
"esp_ble_mesh/core/rpl.c"
|
||||
"esp_ble_mesh/core/scan.c"
|
||||
"esp_ble_mesh/core/test.c"
|
||||
"esp_ble_mesh/models/common/device_property.c"
|
||||
"esp_ble_mesh/models/common/model_common.c"
|
||||
"esp_ble_mesh/models/client/client_common.c"
|
||||
"esp_ble_mesh/models/client/generic_client.c"
|
||||
"esp_ble_mesh/models/client/lighting_client.c"
|
||||
"esp_ble_mesh/models/client/sensor_client.c"
|
||||
"esp_ble_mesh/models/client/time_scene_client.c"
|
||||
"esp_ble_mesh/models/server/generic_server.c"
|
||||
"esp_ble_mesh/models/server/lighting_server.c"
|
||||
"esp_ble_mesh/models/server/sensor_server.c"
|
||||
"esp_ble_mesh/models/server/server_common.c"
|
||||
"esp_ble_mesh/models/server/state_binding.c"
|
||||
"esp_ble_mesh/models/server/state_transition.c"
|
||||
"esp_ble_mesh/models/server/time_scene_server.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_agg_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_brc_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_cm_data_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_df_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_lcd_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_odp_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_prb_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_rpr_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_sar_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_srpl_model_api.c"
|
||||
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_mbt_model_api.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_mbt_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_prb_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c"
|
||||
"esp_ble_mesh/lib/ext.c")
|
||||
|
||||
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT)
|
||||
list(APPEND srcs "esp_ble_mesh/core/transport.enh.c")
|
||||
else()
|
||||
list(APPEND srcs "esp_ble_mesh/core/transport.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
|
||||
list(APPEND srcs
|
||||
"porting/npl/freertos/src/npl_os_freertos.c"
|
||||
"porting/nimble/src/os_msys_init.c"
|
||||
)
|
||||
|
||||
if(CONFIG_BT_CONTROLLER_DISABLED)
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/nimble/src/hal_uart.c"
|
||||
)
|
||||
endif()
|
||||
list(APPEND include_dirs
|
||||
porting/include
|
||||
porting/nimble/include
|
||||
porting/npl/freertos/include
|
||||
porting/transport/include
|
||||
)
|
||||
|
||||
if(CONFIG_BT_LE_HCI_INTERFACE_USE_UART)
|
||||
list(APPEND srcs
|
||||
"porting/transport/uart/hci_uart.c"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT (CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS OR CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS))
|
||||
list(APPEND include_dirs
|
||||
porting/ext/tinycrypt/include
|
||||
)
|
||||
list(APPEND srcs "porting/ext/tinycrypt/src/utils.c"
|
||||
"porting/ext/tinycrypt/src/sha256.c"
|
||||
"porting/ext/tinycrypt/src/ecc.c"
|
||||
"porting/ext/tinycrypt/src/ctr_prng.c"
|
||||
"porting/ext/tinycrypt/src/ctr_mode.c"
|
||||
"porting/ext/tinycrypt/src/aes_decrypt.c"
|
||||
"porting/ext/tinycrypt/src/aes_encrypt.c"
|
||||
"porting/ext/tinycrypt/src/ccm_mode.c"
|
||||
"porting/ext/tinycrypt/src/ecc_dsa.c"
|
||||
"porting/ext/tinycrypt/src/cmac_mode.c"
|
||||
"porting/ext/tinycrypt/src/ecc_dh.c"
|
||||
"porting/ext/tinycrypt/src/hmac_prng.c"
|
||||
"porting/ext/tinycrypt/src/ecc_platform_specific.c"
|
||||
"porting/ext/tinycrypt/src/hmac.c"
|
||||
"porting/ext/tinycrypt/src/cbc_mode.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_NIMBLE_ENABLED)
|
||||
|
||||
list(APPEND include_dirs
|
||||
|
||||
host/nimble/nimble/nimble/host/include
|
||||
host/nimble/nimble/nimble/include
|
||||
host/nimble/nimble/nimble/host/services/ans/include
|
||||
host/nimble/nimble/nimble/host/services/bas/include
|
||||
host/nimble/nimble/nimble/host/services/dis/include
|
||||
host/nimble/nimble/nimble/host/services/gap/include
|
||||
host/nimble/nimble/nimble/host/services/gatt/include
|
||||
host/nimble/nimble/nimble/host/services/hr/include
|
||||
host/nimble/nimble/nimble/host/services/htp/include
|
||||
host/nimble/nimble/nimble/host/services/ias/include
|
||||
host/nimble/nimble/nimble/host/services/ipss/include
|
||||
host/nimble/nimble/nimble/host/services/lls/include
|
||||
host/nimble/nimble/nimble/host/services/prox/include
|
||||
host/nimble/nimble/nimble/host/services/cts/include
|
||||
host/nimble/nimble/nimble/host/services/tps/include
|
||||
host/nimble/nimble/nimble/host/services/hid/include
|
||||
host/nimble/nimble/nimble/host/services/sps/include
|
||||
host/nimble/nimble/nimble/host/util/include
|
||||
host/nimble/nimble/nimble/host/store/ram/include
|
||||
host/nimble/nimble/nimble/host/store/config/include
|
||||
)
|
||||
|
||||
list(APPEND srcs "host/nimble/nimble/nimble/transport/src/transport.c"
|
||||
"host/nimble/nimble/nimble/host/util/src/addr.c"
|
||||
"host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c"
|
||||
"host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c"
|
||||
"host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c"
|
||||
"host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c"
|
||||
"host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c"
|
||||
"host/nimble/nimble/nimble/host/services/hr/src/ble_svc_hr.c"
|
||||
"host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c"
|
||||
"host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c"
|
||||
"host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c"
|
||||
"host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c"
|
||||
"host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c"
|
||||
"host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c"
|
||||
"host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c"
|
||||
"host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c"
|
||||
"host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_conn.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_store_util.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_sm.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_shutdown.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_l2cap_sig_cmd.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_id.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_att_svr.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gatts_lcl.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_ibeacon.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_atomic.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_sm_alg.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_stop.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_mqueue.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_periodic_sync.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_att.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_ead.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_aes_ccm.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gattc.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_store.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_sm_lgcy.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_cfg.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_att_clt.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_mbuf.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_att_cmd.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_log.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_eddystone.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_startup.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_l2cap_sig.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gap.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_sm_cmd.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_uuid.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_pvcy.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_flow.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_l2cap.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_sm_sc.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_misc.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gatts.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_adv.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_hci.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_hci_util.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_hs_resolv.c"
|
||||
"host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c"
|
||||
"host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c"
|
||||
"host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gattc_cache.c"
|
||||
"host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c"
|
||||
)
|
||||
|
||||
if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART)
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/nimble/transport/uart_ll/src/hci_uart.c"
|
||||
"host/nimble/nimble/nimble/transport/common/hci_h4/src/hci_h4.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/nimble/src/nimble_port.c"
|
||||
"host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c"
|
||||
"host/nimble/port/src/nvs_port.c"
|
||||
)
|
||||
list(APPEND include_dirs
|
||||
porting/include
|
||||
host/nimble/nimble/porting/nimble/include
|
||||
host/nimble/port/include
|
||||
host/nimble/nimble/nimble/transport/include
|
||||
)
|
||||
|
||||
if(CONFIG_BT_CONTROLLER_DISABLED)
|
||||
list(APPEND include_dirs
|
||||
host/nimble/nimble/nimble/transport/common/hci_h4/include
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/nimble/src/endian.c"
|
||||
"host/nimble/nimble/porting/nimble/src/os_mempool.c"
|
||||
"host/nimble/nimble/porting/nimble/src/mem.c"
|
||||
"host/nimble/nimble/porting/nimble/src/os_mbuf.c"
|
||||
"host/nimble/nimble/porting/nimble/src/os_msys_init.c"
|
||||
"host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c"
|
||||
)
|
||||
|
||||
if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART)
|
||||
list(APPEND srcs
|
||||
"host/nimble/nimble/porting/nimble/src/hal_uart.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND include_dirs
|
||||
host/nimble/nimble/porting/npl/freertos/include
|
||||
host/nimble/nimble/porting/nimble/include
|
||||
host/nimble/nimble/nimble/include
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE AND CONFIG_BT_CONTROLLER_ENABLED)
|
||||
list(APPEND srcs
|
||||
"host/nimble/esp-hci/src/esp_nimble_hci.c"
|
||||
)
|
||||
list(APPEND include_dirs ${nimble_hci_include_dirs})
|
||||
endif()
|
||||
|
||||
list(APPEND srcs
|
||||
"common/btc/profile/esp/blufi/nimble_host/esp_blufi.c")
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
list(APPEND srcs "esp_ble_mesh/core/nimble_host/adapter.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_NIMBLE_MESH)
|
||||
|
||||
list(APPEND include_dirs
|
||||
host/nimble/nimble/nimble/host/mesh/include
|
||||
host/nimble/nimble/nimble/host/include/host)
|
||||
|
||||
list(APPEND srcs "host/nimble/nimble/nimble/host/mesh/src/shell.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/friend.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/crypto.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/settings.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/adv.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/adv_ext.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/adv_legacy.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/model_srv.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/msg.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/beacon.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/glue.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/model_cli.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/transport.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/prov.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/mesh.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/access.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/cfg_srv.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/cfg_cli.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/light_model.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/health_cli.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/lpn.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/health_srv.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/testing.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/aes-ccm.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/app_keys.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/cdb.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/cfg.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/pb_adv.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/pb_gatt.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/pb_gatt_srv.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/prov_device.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/provisioner.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/heartbeat.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/rpl.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/subnet.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/proxy_msg.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/proxy_srv.c"
|
||||
"host/nimble/nimble/nimble/host/mesh/src/net.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
REQUIRES esp_timer esp_wifi
|
||||
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs
|
||||
LDFRAGMENTS "${ldfragments}")
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
target_link_directories(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32/esp32")
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u ld_include_hli_vectors_bt")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
target_link_directories(${COMPONENT_LIB} INTERFACE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32c3")
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
target_link_directories(${COMPONENT_LIB} INTERFACE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32s3")
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C2)
|
||||
add_prebuilt_library(libble_app "controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C6)
|
||||
add_prebuilt_library(libble_app "controller/lib_esp32c6/esp32c6-bt-lib/libble_app.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2)
|
||||
add_prebuilt_library(libble_app "controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
|
||||
endif()
|
||||
|
||||
set_source_files_properties(
|
||||
"host/bluedroid/bta/gatt/bta_gattc_act.c"
|
||||
"host/bluedroid/bta/gatt/bta_gattc_cache.c"
|
||||
"host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c"
|
||||
"host/bluedroid/btc/profile/std/gatt/btc_gatts.c"
|
||||
PROPERTIES COMPILE_FLAGS -Wno-address-of-packed-member)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
endif()
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32/libble_mesh.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32s3/libble_mesh.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C3)
|
||||
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32c3/libble_mesh.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32C6)
|
||||
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32c6/libble_mesh.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh)
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H2)
|
||||
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32h2/libble_mesh.a")
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_NIMBLE_MESH)
|
||||
set_source_files_properties("host/nimble/nimble/nimble/host/mesh/src/net.c"
|
||||
PROPERTIES COMPILE_FLAGS -Wno-type-limits)
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE AND CONFIG_BT_NIMBLE_ENABLED)
|
||||
# some variables in NimBLE are only used by asserts
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-unused-but-set-variable -Wno-unused-variable)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_EARLY_EXPANSION)
|
||||
set(jump_table_opts "-fjump-tables")
|
||||
if(NOT (CMAKE_C_COMPILER_ID MATCHES "Clang") )
|
||||
set(jump_table_opts "${jump_table_opts} -ftree-switch-conversion")
|
||||
endif()
|
||||
set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/host/bluedroid/bta/hf_ag/bta_ag_cmd.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||
PROPERTIES COMPILE_FLAGS "${jump_table_opts}")
|
||||
endif()
|
||||
@@ -0,0 +1,93 @@
|
||||
menu "Bluetooth"
|
||||
|
||||
config BT_ENABLED
|
||||
bool "Bluetooth"
|
||||
depends on !APP_NO_BLOBS
|
||||
help
|
||||
Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
|
||||
|
||||
choice BT_HOST
|
||||
prompt "Host"
|
||||
depends on BT_ENABLED
|
||||
default BT_BLUEDROID_ENABLED
|
||||
help
|
||||
This helps to choose Bluetooth host stack
|
||||
|
||||
config BT_BLUEDROID_ENABLED
|
||||
bool "Bluedroid - Dual-mode"
|
||||
help
|
||||
This option is recommended for classic Bluetooth or for dual-mode
|
||||
usecases
|
||||
|
||||
config BT_NIMBLE_ENABLED
|
||||
bool "NimBLE - BLE only"
|
||||
help
|
||||
This option is recommended for BLE only usecases to save on memory
|
||||
|
||||
config BT_CONTROLLER_ONLY
|
||||
depends on SOC_BT_SUPPORTED
|
||||
bool "Disabled"
|
||||
help
|
||||
This option is recommended when you want to communicate directly with the
|
||||
controller (without any host) or when you are using any other host stack
|
||||
not supported by Espressif (not mentioned here).
|
||||
|
||||
endchoice
|
||||
|
||||
choice BT_CONTROLLER
|
||||
prompt "Controller"
|
||||
depends on BT_ENABLED
|
||||
default BT_CONTROLLER_ENABLED
|
||||
help
|
||||
This helps to choose Bluetooth controller stack
|
||||
|
||||
config BT_CONTROLLER_ENABLED
|
||||
depends on SOC_BT_SUPPORTED
|
||||
bool "Enabled"
|
||||
help
|
||||
This option is recommended for Bluetooth controller usecases
|
||||
|
||||
config BT_CONTROLLER_DISABLED
|
||||
bool "Disabled"
|
||||
help
|
||||
This option is recommended for Bluetooth Host only usecases
|
||||
|
||||
endchoice
|
||||
|
||||
menu "Bluedroid Options"
|
||||
depends on BT_BLUEDROID_ENABLED
|
||||
source "$IDF_PATH/components/bt/host/bluedroid/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
menu "NimBLE Options"
|
||||
depends on BT_NIMBLE_ENABLED
|
||||
source "$IDF_PATH/components/bt/host/nimble/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
menu "Controller Options"
|
||||
depends on BT_CONTROLLER_ENABLED
|
||||
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
config BT_RELEASE_IRAM
|
||||
depends on BT_ENABLED && BT_LE_RELEASE_IRAM_SUPPORTED
|
||||
bool "Release Bluetooth text (READ DOCS FIRST)"
|
||||
default n
|
||||
help
|
||||
This option release Bluetooth text section and merge Bluetooth data, bss & text into
|
||||
a large free heap region when esp_bt_mem_release is called, total saving ~21kB or more of IRAM.
|
||||
ESP32-C2 only 3 configurable PMP entries available, rest of them are hard-coded.
|
||||
We cannot split the memory into 3 different regions (IRAM, BLE-IRAM, DRAM).
|
||||
So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT)
|
||||
|
||||
endmenu
|
||||
|
||||
menuconfig BLE_MESH
|
||||
bool "ESP BLE Mesh Support"
|
||||
depends on BT_ENABLED
|
||||
help
|
||||
This option enables ESP BLE Mesh support. The specific features that are
|
||||
available may depend on other features that have been enabled in the
|
||||
stack, such as Bluetooth Support, Bluedroid Support & GATT support.
|
||||
|
||||
source "$IDF_PATH/components/bt/esp_ble_mesh/Kconfig.in"
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include "esp_blufi_api.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "osi/future.h"
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
|
||||
{
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
if (callbacks == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_blufi_set_callbacks(callbacks);
|
||||
return (btc_profile_cb_set(BTC_PID_BLUFI, callbacks->event_cb) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_CFG_REPORT;
|
||||
arg.wifi_conn_report.opmode = opmode;
|
||||
arg.wifi_conn_report.sta_conn_state = sta_conn_state;
|
||||
arg.wifi_conn_report.softap_conn_num = softap_conn_num;
|
||||
arg.wifi_conn_report.extra_info = extra_info;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy,
|
||||
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_WIFI_LIST;
|
||||
arg.wifi_list.apCount = apCount;
|
||||
arg.wifi_list.list = list;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy,
|
||||
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_profile_init(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_INIT;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_profile_deinit(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_DEINIT;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
uint16_t esp_blufi_get_version(void)
|
||||
{
|
||||
return btc_blufi_get_version();
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_ERR_INFO;
|
||||
arg.blufi_err_infor.state = state;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
if(data == NULL || data_len == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_CUSTOM_DATA;
|
||||
arg.custom_data.data = data;
|
||||
arg.custom_data.data_len = data_len;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy,
|
||||
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif ///BLUFI_INCLUDED == TRUE
|
||||
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_BLUFI_API_H__
|
||||
#define __ESP_BLUFI_API_H__
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ESP_BLUFI_EVENT_INIT_FINISH = 0, /*<! When BLUFI init complete, this event happen */
|
||||
ESP_BLUFI_EVENT_DEINIT_FINISH, /*<! When BLUFI deinit complete, this event happen */
|
||||
ESP_BLUFI_EVENT_SET_WIFI_OPMODE, /*<! When Phone set ESP32 wifi operation mode(AP/STA/AP_STA), this event happen */
|
||||
ESP_BLUFI_EVENT_BLE_CONNECT, /*<! When Phone connect to ESP32 with BLE, this event happen */
|
||||
ESP_BLUFI_EVENT_BLE_DISCONNECT, /*<! When Phone disconnect with BLE, this event happen */
|
||||
ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP, /*<! When Phone request ESP32's STA connect to AP, this event happen */
|
||||
ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP, /*<! When Phone request ESP32's STA disconnect from AP, this event happen */
|
||||
ESP_BLUFI_EVENT_GET_WIFI_STATUS, /*<! When Phone get ESP32 wifi status, this event happen */
|
||||
ESP_BLUFI_EVENT_DEAUTHENTICATE_STA, /*<! When Phone deauthenticate sta from SOFTAP, this event happen */
|
||||
/* recv data */
|
||||
ESP_BLUFI_EVENT_RECV_STA_BSSID, /*<! When Phone send STA BSSID to ESP32 to connect, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_STA_SSID, /*<! When Phone send STA SSID to ESP32 to connect, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_STA_PASSWD, /*<! When Phone send STA PASSWORD to ESP32 to connect, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_SSID, /*<! When Phone send SOFTAP SSID to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD, /*<! When Phone send SOFTAP PASSWORD to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM, /*<! When Phone send SOFTAP max connection number to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE, /*<! When Phone send SOFTAP authentication mode to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL, /*<! When Phone send SOFTAP channel to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_USERNAME, /*<! When Phone send username to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_CA_CERT, /*<! When Phone send CA certificate to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_CLIENT_CERT, /*<! When Phone send Client certificate to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SERVER_CERT, /*<! When Phone send Server certificate to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY, /*<! When Phone send Client Private key to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY, /*<! When Phone send Server Private key to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE, /*<! When Phone send Disconnect key to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_GET_WIFI_LIST, /*<! When Phone send get wifi list command to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_REPORT_ERROR, /*<! When Blufi report error, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_CUSTOM_DATA, /*<! When Phone send custom data to ESP32, this event happen */
|
||||
} esp_blufi_cb_event_t;
|
||||
|
||||
/// BLUFI config status
|
||||
typedef enum {
|
||||
ESP_BLUFI_STA_CONN_SUCCESS = 0x00,
|
||||
ESP_BLUFI_STA_CONN_FAIL = 0x01,
|
||||
ESP_BLUFI_STA_CONNECTING = 0x02,
|
||||
ESP_BLUFI_STA_NO_IP = 0x03,
|
||||
} esp_blufi_sta_conn_state_t;
|
||||
|
||||
/// BLUFI init status
|
||||
typedef enum {
|
||||
ESP_BLUFI_INIT_OK = 0,
|
||||
ESP_BLUFI_INIT_FAILED,
|
||||
} esp_blufi_init_state_t;
|
||||
|
||||
/// BLUFI deinit status
|
||||
typedef enum {
|
||||
ESP_BLUFI_DEINIT_OK = 0,
|
||||
ESP_BLUFI_DEINIT_FAILED,
|
||||
} esp_blufi_deinit_state_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_BLUFI_SEQUENCE_ERROR = 0,
|
||||
ESP_BLUFI_CHECKSUM_ERROR,
|
||||
ESP_BLUFI_DECRYPT_ERROR,
|
||||
ESP_BLUFI_ENCRYPT_ERROR,
|
||||
ESP_BLUFI_INIT_SECURITY_ERROR,
|
||||
ESP_BLUFI_DH_MALLOC_ERROR,
|
||||
ESP_BLUFI_DH_PARAM_ERROR,
|
||||
ESP_BLUFI_READ_PARAM_ERROR,
|
||||
ESP_BLUFI_MAKE_PUBLIC_ERROR,
|
||||
ESP_BLUFI_DATA_FORMAT_ERROR,
|
||||
ESP_BLUFI_CALC_MD5_ERROR,
|
||||
ESP_BLUFI_WIFI_SCAN_FAIL,
|
||||
ESP_BLUFI_MSG_STATE_ERROR,
|
||||
} esp_blufi_error_state_t;
|
||||
|
||||
/**
|
||||
* @brief BLUFI extra information structure
|
||||
*/
|
||||
typedef struct {
|
||||
//station
|
||||
uint8_t sta_bssid[6]; /*!< BSSID of station interface */
|
||||
bool sta_bssid_set; /*!< is BSSID of station interface set */
|
||||
uint8_t *sta_ssid; /*!< SSID of station interface */
|
||||
int sta_ssid_len; /*!< length of SSID of station interface */
|
||||
uint8_t *sta_passwd; /*!< password of station interface */
|
||||
int sta_passwd_len; /*!< length of password of station interface */
|
||||
uint8_t *softap_ssid; /*!< SSID of softap interface */
|
||||
int softap_ssid_len; /*!< length of SSID of softap interface */
|
||||
uint8_t *softap_passwd; /*!< password of station interface */
|
||||
int softap_passwd_len; /*!< length of password of station interface */
|
||||
uint8_t softap_authmode; /*!< authentication mode of softap interface */
|
||||
bool softap_authmode_set; /*!< is authentication mode of softap interface set */
|
||||
uint8_t softap_max_conn_num; /*!< max connection number of softap interface */
|
||||
bool softap_max_conn_num_set; /*!< is max connection number of softap interface set */
|
||||
uint8_t softap_channel; /*!< channel of softap interface */
|
||||
bool softap_channel_set; /*!< is channel of softap interface set */
|
||||
uint8_t sta_max_conn_retry; /*!< max retry of sta establish connection */
|
||||
bool sta_max_conn_retry_set; /*!< is max retry of sta establish connection set */
|
||||
uint8_t sta_conn_end_reason; /*!< reason of sta connection end */
|
||||
bool sta_conn_end_reason_set; /*!< is reason of sta connection end set */
|
||||
int8_t sta_conn_rssi; /*!< rssi of sta connection */
|
||||
bool sta_conn_rssi_set; /*!< is rssi of sta connection set */
|
||||
} esp_blufi_extra_info_t;
|
||||
|
||||
/** @brief Description of an WiFi AP */
|
||||
typedef struct {
|
||||
uint8_t ssid[33]; /**< SSID of AP */
|
||||
int8_t rssi; /**< signal strength of AP */
|
||||
} esp_blufi_ap_record_t;
|
||||
|
||||
/// Bluetooth address length
|
||||
#define ESP_BLUFI_BD_ADDR_LEN 6
|
||||
/// Bluetooth device address
|
||||
typedef uint8_t esp_blufi_bd_addr_t[ESP_BLUFI_BD_ADDR_LEN];
|
||||
|
||||
/**
|
||||
* @brief BLUFI callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_INIT_FINISH
|
||||
*/
|
||||
struct blufi_init_finish_evt_param {
|
||||
esp_blufi_init_state_t state; /*!< Initial status */
|
||||
} init_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_DEINIT_FINISH
|
||||
*/
|
||||
struct blufi_deinit_finish_evt_param {
|
||||
esp_blufi_deinit_state_t state; /*!< De-initial status */
|
||||
} deinit_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_DEINIT_FINISH */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_SET_WIFI_MODE
|
||||
*/
|
||||
struct blufi_set_wifi_mode_evt_param {
|
||||
wifi_mode_t op_mode; /*!< Wifi operation mode */
|
||||
} wifi_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_CONNECT
|
||||
*/
|
||||
struct blufi_connect_evt_param {
|
||||
esp_blufi_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */
|
||||
uint8_t server_if; /*!< server interface */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} connect; /*!< Blufi callback param of ESP_BLUFI_EVENT_CONNECT */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_DISCONNECT
|
||||
*/
|
||||
struct blufi_disconnect_evt_param {
|
||||
esp_blufi_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */
|
||||
} disconnect; /*!< Blufi callback param of ESP_BLUFI_EVENT_DISCONNECT */
|
||||
|
||||
/* ESP_BLUFI_EVENT_REQ_WIFI_CONNECT */ /* No callback param */
|
||||
/* ESP_BLUFI_EVENT_REQ_WIFI_DISCONNECT */ /* No callback param */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_STA_BSSID
|
||||
*/
|
||||
struct blufi_recv_sta_bssid_evt_param {
|
||||
uint8_t bssid[6]; /*!< BSSID */
|
||||
} sta_bssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_BSSID */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_STA_SSID
|
||||
*/
|
||||
struct blufi_recv_sta_ssid_evt_param {
|
||||
uint8_t *ssid; /*!< SSID */
|
||||
int ssid_len; /*!< SSID length */
|
||||
} sta_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_SSID */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_STA_PASSWD
|
||||
*/
|
||||
struct blufi_recv_sta_passwd_evt_param {
|
||||
uint8_t *passwd; /*!< Password */
|
||||
int passwd_len; /*!< Password Length */
|
||||
} sta_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_PASSWD */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_SSID
|
||||
*/
|
||||
struct blufi_recv_softap_ssid_evt_param {
|
||||
uint8_t *ssid; /*!< SSID */
|
||||
int ssid_len; /*!< SSID length */
|
||||
} softap_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_SSID */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD
|
||||
*/
|
||||
struct blufi_recv_softap_passwd_evt_param {
|
||||
uint8_t *passwd; /*!< Password */
|
||||
int passwd_len; /*!< Password Length */
|
||||
} softap_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM
|
||||
*/
|
||||
struct blufi_recv_softap_max_conn_num_evt_param {
|
||||
int max_conn_num; /*!< SSID */
|
||||
} softap_max_conn_num; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE
|
||||
*/
|
||||
struct blufi_recv_softap_auth_mode_evt_param {
|
||||
wifi_auth_mode_t auth_mode; /*!< Authentication mode */
|
||||
} softap_auth_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL
|
||||
*/
|
||||
struct blufi_recv_softap_channel_evt_param {
|
||||
uint8_t channel; /*!< Authentication mode */
|
||||
} softap_channel; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_USERNAME
|
||||
*/
|
||||
struct blufi_recv_username_evt_param {
|
||||
uint8_t *name; /*!< Username point */
|
||||
int name_len; /*!< Username length */
|
||||
} username; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_USERNAME*/
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_CA_CERT
|
||||
*/
|
||||
struct blufi_recv_ca_evt_param {
|
||||
uint8_t *cert; /*!< CA certificate point */
|
||||
int cert_len; /*!< CA certificate length */
|
||||
} ca; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CA_CERT */
|
||||
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_CLIENT_CERT
|
||||
*/
|
||||
struct blufi_recv_client_cert_evt_param {
|
||||
uint8_t *cert; /*!< Client certificate point */
|
||||
int cert_len; /*!< Client certificate length */
|
||||
} client_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_CERT */
|
||||
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_SERVER_CERT
|
||||
*/
|
||||
struct blufi_recv_server_cert_evt_param {
|
||||
uint8_t *cert; /*!< Client certificate point */
|
||||
int cert_len; /*!< Client certificate length */
|
||||
} server_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_CERT */
|
||||
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY
|
||||
*/
|
||||
struct blufi_recv_client_pkey_evt_param {
|
||||
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */
|
||||
int pkey_len; /*!< Client Private key length */
|
||||
} client_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY */
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY
|
||||
*/
|
||||
struct blufi_recv_server_pkey_evt_param {
|
||||
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */
|
||||
int pkey_len; /*!< Client Private key length */
|
||||
} server_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY */
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_REPORT_ERROR
|
||||
*/
|
||||
struct blufi_get_error_evt_param {
|
||||
esp_blufi_error_state_t state; /*!< Blufi error state */
|
||||
} report_error; /*!< Blufi callback param of ESP_BLUFI_EVENT_REPORT_ERROR */
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_CUSTOM_DATA
|
||||
*/
|
||||
struct blufi_recv_custom_data_evt_param {
|
||||
uint8_t *data; /*!< Custom data */
|
||||
uint32_t data_len; /*!< Custom data Length */
|
||||
} custom_data; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CUSTOM_DATA */
|
||||
} esp_blufi_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief BLUFI event callback function type
|
||||
* @param event : Event type
|
||||
* @param param : Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (* esp_blufi_event_cb_t)(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
|
||||
|
||||
/* security function declare */
|
||||
|
||||
/**
|
||||
* @brief BLUFI negotiate data handler
|
||||
* @param data : data from phone
|
||||
* @param len : length of data from phone
|
||||
* @param output_data : data want to send to phone
|
||||
* @param output_len : length of data want to send to phone
|
||||
* @param need_free : output reporting if memory needs to be freed or not *
|
||||
*/
|
||||
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
|
||||
|
||||
/**
|
||||
* @brief BLUFI encrypt the data after negotiate a share key
|
||||
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
|
||||
* @param crypt_data : plain text and encrypted data, the encrypt function must support autochthonous encrypt
|
||||
* @param crypt_len : length of plain text
|
||||
* @return Nonnegative number is encrypted length, if error, return negative number;
|
||||
*/
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
|
||||
/**
|
||||
* @brief BLUFI decrypt the data after negotiate a share key
|
||||
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
|
||||
* @param crypt_data : encrypted data and plain text, the encrypt function must support autochthonous decrypt
|
||||
* @param crypt_len : length of encrypted text
|
||||
* @return Nonnegative number is decrypted length, if error, return negative number;
|
||||
*/
|
||||
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
|
||||
/**
|
||||
* @brief BLUFI checksum
|
||||
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
|
||||
* @param data : data need to checksum
|
||||
* @param len : length of data
|
||||
*/
|
||||
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len);
|
||||
|
||||
/**
|
||||
* @brief BLUFI callback functions type
|
||||
*/
|
||||
typedef struct {
|
||||
esp_blufi_event_cb_t event_cb; /*!< BLUFI event callback */
|
||||
esp_blufi_negotiate_data_handler_t negotiate_data_handler; /*!< BLUFI negotiate data function for negotiate share key */
|
||||
esp_blufi_encrypt_func_t encrypt_func; /*!< BLUFI encrypt data function with share key generated by negotiate_data_handler */
|
||||
esp_blufi_decrypt_func_t decrypt_func; /*!< BLUFI decrypt data function with share key generated by negotiate_data_handler */
|
||||
esp_blufi_checksum_func_t checksum_func; /*!< BLUFI check sum function (FCS) */
|
||||
} esp_blufi_callbacks_t;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to receive blufi callback event
|
||||
*
|
||||
* @param[in] callbacks: callback functions
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to initialize blufi_profile
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_profile_init(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to de-initialize blufi_profile
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_profile_deinit(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to send wifi connection report
|
||||
* @param opmode : wifi opmode
|
||||
* @param sta_conn_state : station is already in connection or not
|
||||
* @param softap_conn_num : softap connection number
|
||||
* @param extra_info : extra information, such as sta_ssid, softap_ssid and etc.
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to send wifi list
|
||||
* @param apCount : wifi list count
|
||||
* @param list : wifi list
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get BLUFI profile version
|
||||
*
|
||||
* @return Most 8bit significant is Great version, Least 8bit is Sub version
|
||||
*
|
||||
*/
|
||||
uint16_t esp_blufi_get_version(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to send blufi error information
|
||||
* @param state : error state
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state);
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to custom data
|
||||
* @param data : custom data value
|
||||
* @param data_len : the length of custom data
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLUFI_API_ */
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc/btc_alarm.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void btc_alarm_handler(btc_msg_t *msg)
|
||||
{
|
||||
btc_alarm_args_t *arg = (btc_alarm_args_t *)msg->arg;
|
||||
|
||||
BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act);
|
||||
|
||||
if (arg->cb) {
|
||||
arg->cb(arg->cb_data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include "btc/btc_task.h"
|
||||
#include "osi/thread.h"
|
||||
|
||||
#if BTC_DYNAMIC_MEMORY == FALSE
|
||||
void *btc_profile_cb_tab[BTC_PID_NUM] = {};
|
||||
#else
|
||||
void **btc_profile_cb_tab;
|
||||
#endif
|
||||
|
||||
void esp_profile_cb_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BTC_PID_NUM; i++) {
|
||||
btc_profile_cb_tab[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int btc_profile_cb_set(btc_pid_t profile_id, void *cb)
|
||||
{
|
||||
if (profile_id < 0 || profile_id >= BTC_PID_NUM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
btc_profile_cb_tab[profile_id] = cb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *btc_profile_cb_get(btc_pid_t profile_id)
|
||||
{
|
||||
if (profile_id < 0 || profile_id >= BTC_PID_NUM) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_profile_cb_tab[profile_id];
|
||||
}
|
||||
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "btc/btc_task.h"
|
||||
#include "osi/thread.h"
|
||||
#include "esp_log.h"
|
||||
#include "bt_common.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "btc/btc_alarm.h"
|
||||
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "blufi_int.h"
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "common/bt_target.h"
|
||||
#include "btc/btc_main.h"
|
||||
#include "btc/btc_dev.h"
|
||||
#include "btc_gatts.h"
|
||||
#include "btc_gattc.h"
|
||||
#include "btc_gatt_common.h"
|
||||
#include "btc_gap_ble.h"
|
||||
#include "btc/btc_dm.h"
|
||||
#include "bta/bta_gatt_api.h"
|
||||
#if CLASSIC_BT_INCLUDED
|
||||
#include "btc/btc_profile_queue.h"
|
||||
#if (BTC_GAP_BT_INCLUDED == TRUE)
|
||||
#include "btc_gap_bt.h"
|
||||
#endif /* BTC_GAP_BT_INCLUDED == TRUE */
|
||||
#if BTC_AV_INCLUDED
|
||||
#include "btc_av.h"
|
||||
#include "btc_avrc.h"
|
||||
#include "btc_av_co.h"
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
||||
#if (BTC_SPP_INCLUDED == TRUE)
|
||||
#include "btc_spp.h"
|
||||
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
||||
#if (BTC_L2CAP_INCLUDED == TRUE)
|
||||
#include "btc_l2cap.h"
|
||||
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
|
||||
#if (BTC_SDP_INCLUDED == TRUE)
|
||||
#include "btc_sdp.h"
|
||||
#endif /* #if (BTC_SDP_INCLUDED == TRUE) */
|
||||
#if BTC_HF_INCLUDED
|
||||
#include "btc_hf_ag.h"
|
||||
#endif/* #if BTC_HF_INCLUDED */
|
||||
#if BTC_HF_CLIENT_INCLUDED
|
||||
#include "btc_hf_client.h"
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#if BTC_HD_INCLUDED == TRUE
|
||||
#include "btc_hd.h"
|
||||
#endif /* BTC_HD_INCLUDED */
|
||||
#if BTC_HH_INCLUDED == TRUE
|
||||
#include "btc_hh.h"
|
||||
#endif /* BTC_HH_INCLUDED */
|
||||
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||
#endif
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
#include "btc_gap_ble.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH
|
||||
#include "btc_ble_mesh_ble.h"
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "btc_ble_mesh_health_model.h"
|
||||
#include "btc_ble_mesh_config_model.h"
|
||||
#include "btc_ble_mesh_agg_model.h"
|
||||
#include "btc_ble_mesh_brc_model.h"
|
||||
#include "btc_ble_mesh_df_model.h"
|
||||
#include "btc_ble_mesh_lcd_model.h"
|
||||
#include "btc_ble_mesh_odp_model.h"
|
||||
#include "btc_ble_mesh_prb_model.h"
|
||||
#include "btc_ble_mesh_rpr_model.h"
|
||||
#include "btc_ble_mesh_sar_model.h"
|
||||
#include "btc_ble_mesh_srpl_model.h"
|
||||
#include "btc_ble_mesh_generic_model.h"
|
||||
#include "btc_ble_mesh_lighting_model.h"
|
||||
#include "btc_ble_mesh_sensor_model.h"
|
||||
#include "btc_ble_mesh_time_scene_model.h"
|
||||
#include "btc_ble_mesh_mbt_model.h"
|
||||
#endif /* #if CONFIG_BLE_MESH */
|
||||
|
||||
#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
|
||||
#define BTC_TASK_STACK_SIZE (BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
|
||||
#define BTC_TASK_NAME "BTC_TASK"
|
||||
#define BTC_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 6)
|
||||
#define BTC_TASK_WORKQUEUE_NUM (2)
|
||||
#define BTC_TASK_WORKQUEUE0_LEN (0)
|
||||
#define BTC_TASK_WORKQUEUE1_LEN (5)
|
||||
|
||||
osi_thread_t *btc_thread;
|
||||
|
||||
static const btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
|
||||
[BTC_PID_DEV] = {btc_dev_call_handler, NULL },
|
||||
#if (GATTS_INCLUDED == TRUE)
|
||||
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
|
||||
#endif ///GATTS_INCLUDED == TRUE
|
||||
#if (GATTC_INCLUDED == TRUE)
|
||||
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
|
||||
#endif ///GATTC_INCLUDED == TRUE
|
||||
#if (GATTS_INCLUDED == TRUE || GATTC_INCLUDED == TRUE)
|
||||
[BTC_PID_GATT_COMMON] = {btc_gatt_com_call_handler, NULL },
|
||||
#endif //GATTC_INCLUDED == TRUE || GATTS_INCLUDED == TRUE
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
|
||||
#else
|
||||
[BTC_PID_GAP_BLE] = {NULL, NULL},
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
[BTC_PID_BLE_HID] = {NULL, NULL},
|
||||
[BTC_PID_SPPLIKE] = {NULL, NULL},
|
||||
[BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler },
|
||||
#endif
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
[BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler },
|
||||
#endif ///BLUFI_INCLUDED == TRUE
|
||||
[BTC_PID_ALARM] = {btc_alarm_handler, NULL },
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
#if CLASSIC_BT_INCLUDED
|
||||
#if (BTC_GAP_BT_INCLUDED == TRUE)
|
||||
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, btc_gap_bt_cb_handler },
|
||||
#endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
|
||||
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
|
||||
#if BTC_AV_INCLUDED
|
||||
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
|
||||
[BTC_PID_AVRC_CT] = {btc_avrc_ct_call_handler, NULL },
|
||||
[BTC_PID_AVRC_TG] = {btc_avrc_tg_call_handler, NULL },
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
||||
#if (BTC_SPP_INCLUDED == TRUE)
|
||||
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
|
||||
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
||||
#if (BTC_L2CAP_INCLUDED == TRUE)
|
||||
[BTC_PID_L2CAP] = {btc_l2cap_call_handler, btc_l2cap_cb_handler },
|
||||
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
|
||||
#if (BTC_SDP_INCLUDED == TRUE)
|
||||
[BTC_PID_SDP] = {btc_sdp_call_handler, btc_sdp_cb_handler },
|
||||
#endif /* #if (BTC_SDP_INCLUDED == TRUE) */
|
||||
#if BTC_HF_INCLUDED
|
||||
[BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler},
|
||||
#endif /* #if BTC_HF_INCLUDED */
|
||||
#if BTC_HF_CLIENT_INCLUDED
|
||||
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#if BTC_HD_INCLUDED
|
||||
[BTC_PID_HD] = {btc_hd_call_handler, btc_hd_cb_handler },
|
||||
#endif
|
||||
#if BTC_HH_INCLUDED
|
||||
[BTC_PID_HH] = {btc_hh_call_handler, btc_hh_cb_handler },
|
||||
#endif
|
||||
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH
|
||||
[BTC_PID_PROV] = {btc_ble_mesh_prov_call_handler, btc_ble_mesh_prov_cb_handler },
|
||||
[BTC_PID_MODEL] = {btc_ble_mesh_model_call_handler, btc_ble_mesh_model_cb_handler },
|
||||
#if CONFIG_BLE_MESH_HEALTH_CLI
|
||||
[BTC_PID_HEALTH_CLIENT] = {btc_ble_mesh_health_client_call_handler, btc_ble_mesh_health_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_HEALTH_CLI */
|
||||
#if CONFIG_BLE_MESH_HEALTH_SRV
|
||||
[BTC_PID_HEALTH_SERVER] = {btc_ble_mesh_health_server_call_handler, btc_ble_mesh_health_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_HEALTH_SRV */
|
||||
#if CONFIG_BLE_MESH_CFG_CLI
|
||||
[BTC_PID_CONFIG_CLIENT] = {btc_ble_mesh_config_client_call_handler, btc_ble_mesh_config_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_CFG_CLI */
|
||||
[BTC_PID_CONFIG_SERVER] = {NULL, btc_ble_mesh_config_server_cb_handler },
|
||||
#if CONFIG_BLE_MESH_AGG_CLI
|
||||
[BTC_PID_AGG_CLIENT] = {btc_ble_mesh_agg_client_call_handler, btc_ble_mesh_agg_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_AGG_CLI */
|
||||
#if CONFIG_BLE_MESH_AGG_SRV
|
||||
[BTC_PID_AGG_SERVER] = {NULL, btc_ble_mesh_agg_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_AGG_SRV */
|
||||
#if CONFIG_BLE_MESH_BRC_CLI
|
||||
[BTC_PID_BRC_CLIENT] = {btc_ble_mesh_brc_client_call_handler, btc_ble_mesh_brc_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_BRC_CLI */
|
||||
#if CONFIG_BLE_MESH_BRC_SRV
|
||||
[BTC_PID_BRC_SERVER] = {NULL, btc_ble_mesh_brc_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_BRC_SRV */
|
||||
#if CONFIG_BLE_MESH_DF_CLI
|
||||
[BTC_PID_DF_CLIENT] = {btc_ble_mesh_df_client_call_handler, btc_ble_mesh_df_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_DF_CLI */
|
||||
#if CONFIG_BLE_MESH_DF_SRV
|
||||
[BTC_PID_DF_SERVER] = {NULL, btc_ble_mesh_df_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_DF_SRV */
|
||||
#if CONFIG_BLE_MESH_LCD_CLI
|
||||
[BTC_PID_LCD_CLIENT] = {btc_ble_mesh_lcd_client_call_handler, btc_ble_mesh_lcd_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_LCD_CLI */
|
||||
#if CONFIG_BLE_MESH_LCD_SRV
|
||||
[BTC_PID_LCD_SERVER] = {NULL, btc_ble_mesh_lcd_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_LCD_SRV */
|
||||
#if CONFIG_BLE_MESH_ODP_CLI
|
||||
[BTC_PID_ODP_CLIENT] = {btc_ble_mesh_odp_client_call_handler, btc_ble_mesh_odp_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_ODP_CLI */
|
||||
#if CONFIG_BLE_MESH_ODP_SRV
|
||||
[BTC_PID_ODP_SERVER] = {NULL, btc_ble_mesh_odp_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_ODP_SRV */
|
||||
#if CONFIG_BLE_MESH_PRB_CLI
|
||||
[BTC_PID_PRB_CLIENT] = {btc_ble_mesh_prb_client_call_handler, btc_ble_mesh_prb_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_PRB_CLI */
|
||||
#if CONFIG_BLE_MESH_PRB_SRV
|
||||
[BTC_PID_PRB_SERVER] = {NULL, btc_ble_mesh_prb_server_cb_handler },
|
||||
#endif /*CONFIG_BLE_MESH_PRB_SRV*/
|
||||
#if CONFIG_BLE_MESH_RPR_CLI
|
||||
[BTC_PID_RPR_CLIENT] = {btc_ble_mesh_rpr_client_call_handler, btc_ble_mesh_rpr_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_RPR_CLI */
|
||||
#if CONFIG_BLE_MESH_RPR_SRV
|
||||
[BTC_PID_RPR_SERVER] = {NULL, btc_ble_mesh_rpr_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_RPR_SRV */
|
||||
#if CONFIG_BLE_MESH_SAR_CLI
|
||||
[BTC_PID_SAR_CLIENT] = {btc_ble_mesh_sar_client_call_handler, btc_ble_mesh_sar_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_SAR_CLI */
|
||||
#if CONFIG_BLE_MESH_SAR_SRV
|
||||
[BTC_PID_SAR_SERVER] = {NULL, btc_ble_mesh_sar_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_SAR_SRV */
|
||||
#if CONFIG_BLE_MESH_SRPL_CLI
|
||||
[BTC_PID_SRPL_CLIENT] = {btc_ble_mesh_srpl_client_call_handler, btc_ble_mesh_srpl_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_SRPL_CLI */
|
||||
#if CONFIG_BLE_MESH_SRPL_SRV
|
||||
[BTC_PID_SRPL_SERVER] = {NULL, btc_ble_mesh_srpl_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_SRPL_SRV */
|
||||
#if CONFIG_BLE_MESH_GENERIC_CLIENT
|
||||
[BTC_PID_GENERIC_CLIENT] = {btc_ble_mesh_generic_client_call_handler, btc_ble_mesh_generic_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_GENERIC_CLIENT */
|
||||
#if CONFIG_BLE_MESH_LIGHTING_CLIENT
|
||||
[BTC_PID_LIGHTING_CLIENT] = {btc_ble_mesh_lighting_client_call_handler, btc_ble_mesh_lighting_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_LIGHTING_CLIENT */
|
||||
#if CONFIG_BLE_MESH_SENSOR_CLI
|
||||
[BTC_PID_SENSOR_CLIENT] = {btc_ble_mesh_sensor_client_call_handler, btc_ble_mesh_sensor_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_SENSOR_CLI */
|
||||
#if CONFIG_BLE_MESH_TIME_SCENE_CLIENT
|
||||
[BTC_PID_TIME_SCENE_CLIENT] = {btc_ble_mesh_time_scene_client_call_handler, btc_ble_mesh_time_scene_client_cb_handler},
|
||||
#endif /* CONFIG_BLE_MESH_TIME_SCENE_CLIENT */
|
||||
#if CONFIG_BLE_MESH_GENERIC_SERVER
|
||||
[BTC_PID_GENERIC_SERVER] = {NULL, btc_ble_mesh_generic_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
|
||||
#if CONFIG_BLE_MESH_LIGHTING_SERVER
|
||||
[BTC_PID_LIGHTING_SERVER] = {NULL, btc_ble_mesh_lighting_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */
|
||||
#if CONFIG_BLE_MESH_SENSOR_SERVER
|
||||
[BTC_PID_SENSOR_SERVER] = {NULL, btc_ble_mesh_sensor_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_SENSOR_SERVER */
|
||||
#if CONFIG_BLE_MESH_TIME_SCENE_SERVER
|
||||
[BTC_PID_TIME_SCENE_SERVER] = {NULL, btc_ble_mesh_time_scene_server_cb_handler},
|
||||
#endif /* CONFIG_BLE_MESH_TIME_SCENE_SERVER */
|
||||
#if CONFIG_BLE_MESH_MBT_CLI
|
||||
[BTC_PID_MBT_CLIENT] = {btc_ble_mesh_mbt_client_call_handler, btc_ble_mesh_mbt_client_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_MBT_CLI */
|
||||
#if CONFIG_BLE_MESH_MBT_SRV
|
||||
[BTC_PID_MBT_SERVER] = {btc_ble_mesh_mbt_server_call_handler, btc_ble_mesh_mbt_server_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_MBT_SRV */
|
||||
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
|
||||
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
|
||||
#endif /* #if CONFIG_BLE_MESH */
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
**
|
||||
** Function btc_task
|
||||
**
|
||||
** Description Process profile Task Thread.
|
||||
******************************************************************************/
|
||||
static void btc_thread_handler(void *arg)
|
||||
{
|
||||
btc_msg_t *msg = (btc_msg_t *)arg;
|
||||
|
||||
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, msg->arg);
|
||||
switch (msg->sig) {
|
||||
case BTC_SIG_API_CALL:
|
||||
profile_tab[msg->pid].btc_call(msg);
|
||||
break;
|
||||
case BTC_SIG_API_CB:
|
||||
profile_tab[msg->pid].btc_cb(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
osi_free(msg);
|
||||
}
|
||||
|
||||
static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout)
|
||||
{
|
||||
if (osi_thread_post(btc_thread, btc_thread_handler, msg, 0, timeout) == false) {
|
||||
return BT_STATUS_BUSY;
|
||||
}
|
||||
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* transfer an message to another module in the different task.
|
||||
* @param msg message
|
||||
* @param arg paramter
|
||||
* @param arg_len length of paramter
|
||||
* @param copy_func deep copy function
|
||||
* @param free_func deep free function
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func,
|
||||
btc_arg_deep_free_t free_func)
|
||||
{
|
||||
btc_msg_t* lmsg;
|
||||
bt_status_t ret;
|
||||
// arg XOR arg_len
|
||||
if ((msg == NULL) || ((arg == NULL) == !(arg_len == 0))) {
|
||||
BTC_TRACE_WARNING("%s Invalid parameters\n", __func__);
|
||||
return BT_STATUS_PARM_INVALID;
|
||||
}
|
||||
|
||||
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
|
||||
|
||||
lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t) + arg_len);
|
||||
if (lmsg == NULL) {
|
||||
BTC_TRACE_WARNING("%s No memory\n", __func__);
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
memcpy(lmsg, msg, sizeof(btc_msg_t));
|
||||
if (arg) {
|
||||
memset(lmsg->arg, 0x00, arg_len); //important, avoid arg which have no length
|
||||
memcpy(lmsg->arg, arg, arg_len);
|
||||
if (copy_func) {
|
||||
copy_func(lmsg, lmsg->arg, arg);
|
||||
}
|
||||
}
|
||||
|
||||
ret = btc_task_post(lmsg, OSI_THREAD_MAX_TIMEOUT);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
if (copy_func && free_func) {
|
||||
free_func(lmsg);
|
||||
}
|
||||
osi_free(lmsg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* transfer an message to another module in tha same task.
|
||||
* @param msg message
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_inter_profile_call(btc_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
return BT_STATUS_PARM_INVALID;
|
||||
}
|
||||
|
||||
switch (msg->sig) {
|
||||
case BTC_SIG_API_CALL:
|
||||
profile_tab[msg->pid].btc_call(msg);
|
||||
break;
|
||||
case BTC_SIG_API_CB:
|
||||
profile_tab[msg->pid].btc_cb(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#if BTC_DYNAMIC_MEMORY
|
||||
|
||||
static void btc_deinit_mem(void) {
|
||||
if (btc_dm_cb_ptr) {
|
||||
osi_free(btc_dm_cb_ptr);
|
||||
btc_dm_cb_ptr = NULL;
|
||||
}
|
||||
|
||||
if (btc_profile_cb_tab) {
|
||||
osi_free(btc_profile_cb_tab);
|
||||
btc_profile_cb_tab = NULL;
|
||||
}
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
if (gl_bta_adv_data_ptr) {
|
||||
osi_free(gl_bta_adv_data_ptr);
|
||||
gl_bta_adv_data_ptr = NULL;
|
||||
}
|
||||
|
||||
if (gl_bta_scan_rsp_data_ptr) {
|
||||
osi_free(gl_bta_scan_rsp_data_ptr);
|
||||
gl_bta_scan_rsp_data_ptr = NULL;
|
||||
}
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
|
||||
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
|
||||
if (btc_creat_tab_env_ptr) {
|
||||
osi_free(btc_creat_tab_env_ptr);
|
||||
btc_creat_tab_env_ptr = NULL;
|
||||
}
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
if (blufi_env_ptr) {
|
||||
osi_free(blufi_env_ptr);
|
||||
blufi_env_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||
if (hf_client_local_param_ptr) {
|
||||
osi_free(hf_client_local_param_ptr);
|
||||
hf_client_local_param_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE
|
||||
if (btc_rc_cb_ptr) {
|
||||
osi_free(btc_rc_cb_ptr);
|
||||
btc_rc_cb_ptr = NULL;
|
||||
}
|
||||
if (bta_av_co_cb_ptr) {
|
||||
osi_free(bta_av_co_cb_ptr);
|
||||
bta_av_co_cb_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bt_status_t btc_init_mem(void) {
|
||||
if ((btc_dm_cb_ptr = (btc_dm_cb_t *)osi_malloc(sizeof(btc_dm_cb_t))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)btc_dm_cb_ptr, 0, sizeof(btc_dm_cb_t));
|
||||
|
||||
if ((btc_profile_cb_tab = (void **)osi_malloc(sizeof(void *) * BTC_PID_NUM)) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)btc_profile_cb_tab, 0, sizeof(void *) * BTC_PID_NUM);
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
if ((gl_bta_adv_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)gl_bta_adv_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA));
|
||||
|
||||
if ((gl_bta_scan_rsp_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)gl_bta_scan_rsp_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA));
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
|
||||
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
|
||||
if ((btc_creat_tab_env_ptr = (esp_btc_creat_tab_t *)osi_malloc(sizeof(esp_btc_creat_tab_t))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)btc_creat_tab_env_ptr, 0, sizeof(esp_btc_creat_tab_t));
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
if ((blufi_env_ptr = (tBLUFI_ENV *)osi_malloc(sizeof(tBLUFI_ENV))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)blufi_env_ptr, 0, sizeof(tBLUFI_ENV));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
|
||||
if ((hf_client_local_param_ptr = (hf_client_local_param_t *)osi_malloc(sizeof(hf_client_local_param_t))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)hf_client_local_param_ptr, 0, sizeof(hf_client_local_param_t));
|
||||
#endif
|
||||
|
||||
#if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE
|
||||
if ((btc_rc_cb_ptr = (btc_rc_cb_t *)osi_malloc(sizeof(btc_rc_cb_t))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)btc_rc_cb_ptr, 0, sizeof(btc_rc_cb_t));
|
||||
if ((bta_av_co_cb_ptr = (tBTA_AV_CO_CB *)osi_malloc(sizeof(tBTA_AV_CO_CB))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)bta_av_co_cb_ptr, 0, sizeof(tBTA_AV_CO_CB));
|
||||
#endif
|
||||
|
||||
return BT_STATUS_SUCCESS;
|
||||
|
||||
error_exit:;
|
||||
btc_deinit_mem();
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
#endif ///BTC_DYNAMIC_MEMORY
|
||||
|
||||
bt_status_t btc_init(void)
|
||||
{
|
||||
const size_t workqueue_len[] = {BTC_TASK_WORKQUEUE0_LEN, BTC_TASK_WORKQUEUE1_LEN};
|
||||
btc_thread = osi_thread_create(BTC_TASK_NAME, BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE,
|
||||
BTC_TASK_WORKQUEUE_NUM, workqueue_len);
|
||||
if (btc_thread == NULL) {
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
#if BTC_DYNAMIC_MEMORY
|
||||
if (btc_init_mem() != BT_STATUS_SUCCESS){
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
btc_gap_callback_init();
|
||||
btc_gap_ble_init();
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
btc_adv_list_init();
|
||||
#endif
|
||||
/* TODO: initial the profile_tab */
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void btc_deinit(void)
|
||||
{
|
||||
#if BTC_DYNAMIC_MEMORY
|
||||
btc_deinit_mem();
|
||||
#endif
|
||||
|
||||
osi_thread_free(btc_thread);
|
||||
btc_thread = NULL;
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
btc_gap_ble_deinit();
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
btc_adv_list_deinit();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool btc_check_queue_is_congest(void)
|
||||
{
|
||||
if (osi_thread_queue_wait_size(btc_thread, 0) >= BT_QUEUE_CONGEST_SIZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int get_btc_work_queue_size(void)
|
||||
{
|
||||
return osi_thread_queue_wait_size(btc_thread, 0);
|
||||
}
|
||||
|
||||
osi_thread_t *btc_get_current_thread(void)
|
||||
{
|
||||
return btc_thread;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __BTC_ALARM_H__
|
||||
#define __BTC_ALARM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "osi/alarm.h"
|
||||
|
||||
/* btc_alarm_args_t */
|
||||
typedef struct {
|
||||
osi_alarm_callback_t cb;
|
||||
void *cb_data;
|
||||
} btc_alarm_args_t;
|
||||
|
||||
void btc_alarm_handler(btc_msg_t *msg);
|
||||
|
||||
#endif /* __BTC_ALARM_H__ */
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __BTC_MANAGE_H__
|
||||
#define __BTC_MANAGE_H__
|
||||
|
||||
#include "btc/btc_task.h"
|
||||
|
||||
#if BTC_DYNAMIC_MEMORY == FALSE
|
||||
extern void *btc_profile_cb_tab[BTC_PID_NUM];
|
||||
#else
|
||||
extern void **btc_profile_cb_tab;
|
||||
#endif
|
||||
/* reset gatt callback table */
|
||||
void esp_profile_cb_reset(void);
|
||||
|
||||
int btc_profile_cb_set(btc_pid_t profile_id, void *cb);
|
||||
void *btc_profile_cb_get(btc_pid_t profile_id);
|
||||
|
||||
#endif /* __BTC_MANAGE_H__ */
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __BTC_TASK_H__
|
||||
#define __BTC_TASK_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bt_common.h"
|
||||
#include "osi/thread.h"
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "common/bt_target.h"
|
||||
#endif
|
||||
|
||||
typedef struct btc_msg {
|
||||
uint8_t sig; //event signal
|
||||
uint8_t aid; //application id
|
||||
uint8_t pid; //profile id
|
||||
uint8_t act; //profile action, defined in seprerate header files
|
||||
UINT8 arg[0]; //param for btc function or function param
|
||||
} btc_msg_t;
|
||||
|
||||
typedef struct btc_adv_packet {
|
||||
uint8_t addr[6];
|
||||
uint8_t addr_type;
|
||||
} btc_adv_packet_t;
|
||||
|
||||
typedef enum {
|
||||
BTC_SIG_API_CALL = 0, // APP TO STACK
|
||||
BTC_SIG_API_CB, // STACK TO APP
|
||||
BTC_SIG_NUM,
|
||||
} btc_sig_t; //btc message type
|
||||
|
||||
typedef enum {
|
||||
BTC_PID_MAIN_INIT = 0,
|
||||
BTC_PID_DEV,
|
||||
BTC_PID_GATTS,
|
||||
#if (GATTC_INCLUDED == TRUE)
|
||||
BTC_PID_GATTC,
|
||||
#endif ///GATTC_INCLUDED == TRUE
|
||||
BTC_PID_GATT_COMMON,
|
||||
BTC_PID_GAP_BLE,
|
||||
BTC_PID_BLE_HID,
|
||||
BTC_PID_SPPLIKE,
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
BTC_PID_BLUFI,
|
||||
#endif ///BLUFI_INCLUDED == TRUE
|
||||
BTC_PID_DM_SEC,
|
||||
BTC_PID_ALARM,
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
BTC_PID_GAP_BT,
|
||||
BTC_PID_PRF_QUE,
|
||||
BTC_PID_A2DP,
|
||||
BTC_PID_AVRC_CT,
|
||||
BTC_PID_AVRC_TG,
|
||||
BTC_PID_SPP,
|
||||
BTC_PID_HD,
|
||||
BTC_PID_HH,
|
||||
BTC_PID_L2CAP,
|
||||
BTC_PID_SDP,
|
||||
#if (BTC_HF_INCLUDED == TRUE)
|
||||
BTC_PID_HF,
|
||||
#endif /* BTC_HF_INCLUDED */
|
||||
#if (BTC_HF_CLIENT_INCLUDED == TRUE)
|
||||
BTC_PID_HF_CLIENT,
|
||||
#endif /* BTC_HF_CLIENT_INCLUDED */
|
||||
#endif /* CLASSIC_BT_INCLUDED */
|
||||
#if CONFIG_BLE_MESH
|
||||
BTC_PID_PROV,
|
||||
BTC_PID_MODEL,
|
||||
BTC_PID_HEALTH_CLIENT,
|
||||
BTC_PID_HEALTH_SERVER,
|
||||
BTC_PID_CONFIG_CLIENT,
|
||||
BTC_PID_CONFIG_SERVER,
|
||||
BTC_PID_AGG_CLIENT,
|
||||
BTC_PID_AGG_SERVER,
|
||||
BTC_PID_BRC_CLIENT,
|
||||
BTC_PID_BRC_SERVER,
|
||||
BTC_PID_DF_CLIENT,
|
||||
BTC_PID_DF_SERVER,
|
||||
BTC_PID_LCD_CLIENT,
|
||||
BTC_PID_LCD_SERVER,
|
||||
BTC_PID_ODP_CLIENT,
|
||||
BTC_PID_ODP_SERVER,
|
||||
BTC_PID_PRB_CLIENT,
|
||||
BTC_PID_PRB_SERVER,
|
||||
BTC_PID_RPR_CLIENT,
|
||||
BTC_PID_RPR_SERVER,
|
||||
BTC_PID_SAR_CLIENT,
|
||||
BTC_PID_SAR_SERVER,
|
||||
BTC_PID_SRPL_CLIENT,
|
||||
BTC_PID_SRPL_SERVER,
|
||||
BTC_PID_GENERIC_CLIENT,
|
||||
BTC_PID_LIGHTING_CLIENT,
|
||||
BTC_PID_SENSOR_CLIENT,
|
||||
BTC_PID_TIME_SCENE_CLIENT,
|
||||
BTC_PID_GENERIC_SERVER,
|
||||
BTC_PID_LIGHTING_SERVER,
|
||||
BTC_PID_SENSOR_SERVER,
|
||||
BTC_PID_TIME_SCENE_SERVER,
|
||||
BTC_PID_MBT_CLIENT,
|
||||
BTC_PID_MBT_SERVER,
|
||||
BTC_PID_BLE_MESH_BLE_COEX,
|
||||
#endif /* CONFIG_BLE_MESH */
|
||||
BTC_PID_NUM,
|
||||
} btc_pid_t; //btc profile id
|
||||
|
||||
typedef struct {
|
||||
void (* btc_call)(btc_msg_t *msg);
|
||||
void (* btc_cb)(btc_msg_t *msg);
|
||||
} btc_func_t;
|
||||
|
||||
typedef void (* btc_arg_deep_copy_t)(btc_msg_t *msg, void *dst, void *src);
|
||||
typedef void (* btc_arg_deep_free_t)(btc_msg_t *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* transfer an message to another module in the different task.
|
||||
* @param msg message
|
||||
* @param arg paramter
|
||||
* @param arg_len length of paramter
|
||||
* @param copy_func deep copy function
|
||||
* @param free_func deep free function
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func,
|
||||
btc_arg_deep_free_t free_func);
|
||||
|
||||
/**
|
||||
* transfer an message to another module in tha same task.
|
||||
* @param msg message
|
||||
* @return BT_STATUS_SUCCESS: success
|
||||
* others: fail
|
||||
*/
|
||||
bt_status_t btc_inter_profile_call(btc_msg_t *msg);
|
||||
|
||||
bt_status_t btc_init(void);
|
||||
void btc_deinit(void);
|
||||
bool btc_check_queue_is_congest(void);
|
||||
int get_btc_work_queue_size(void);
|
||||
|
||||
/**
|
||||
* get the BTC thread handle
|
||||
* @return NULL: fail
|
||||
* others: pointer of osi_thread structure of BTC
|
||||
*/
|
||||
osi_thread_t *btc_get_current_thread(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BTC_TASK_H__ */
|
||||
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "osi/allocator.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "blufi_int.h"
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_blufi_api.h"
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "common/bt_trace.h"
|
||||
#include "stack/bt_types.h"
|
||||
#include "stack/gatt_api.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "bta/bta_gatt_api.h"
|
||||
#include "bta_gatts_int.h"
|
||||
#include "btc_gatt_util.h"
|
||||
#include "btc_gatts.h"
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
#include "esp_gatt_common_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_blufi.h"
|
||||
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
|
||||
static uint8_t server_if;
|
||||
static uint16_t conn_id;
|
||||
static uint8_t blufi_service_uuid128[32] = {
|
||||
/* LSB <--------------------------------------------------------------------------------> MSB */
|
||||
//first uuid, 16bit, [12],[13] is the value
|
||||
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static esp_ble_adv_data_t blufi_adv_data = {
|
||||
.set_scan_rsp = false,
|
||||
.include_name = true,
|
||||
.include_txpower = true,
|
||||
.min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
|
||||
.max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
|
||||
.appearance = 0x00,
|
||||
.manufacturer_len = 0,
|
||||
.p_manufacturer_data = NULL,
|
||||
.service_data_len = 0,
|
||||
.p_service_data = NULL,
|
||||
.service_uuid_len = 16,
|
||||
.p_service_uuid = blufi_service_uuid128,
|
||||
.flag = 0x6,
|
||||
};
|
||||
|
||||
static esp_ble_adv_params_t blufi_adv_params = {
|
||||
.adv_int_min = 0x100,
|
||||
.adv_int_max = 0x100,
|
||||
.adv_type = ADV_TYPE_IND,
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
//.peer_addr =
|
||||
//.peer_addr_type =
|
||||
.channel_map = ADV_CHNL_ALL,
|
||||
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
||||
};
|
||||
|
||||
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
||||
esp_ble_gap_start_advertising(&blufi_adv_params);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// static functions declare
|
||||
static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data);
|
||||
|
||||
void blufi_create_service(void)
|
||||
{
|
||||
if (!blufi_env.enabled) {
|
||||
BTC_TRACE_ERROR("blufi service added error.");
|
||||
return;
|
||||
}
|
||||
|
||||
blufi_env.srvc_inst = 0x00;
|
||||
BTA_GATTS_CreateService(blufi_env.gatt_if, &blufi_srvc_uuid, blufi_env.srvc_inst, BLUFI_HDL_NUM, true);
|
||||
}
|
||||
|
||||
uint8_t esp_blufi_init(void)
|
||||
{
|
||||
|
||||
/* register the BLUFI profile to the BTA_GATTS module*/
|
||||
BTA_GATTS_AppRegister(&blufi_app_uuid, blufi_profile_cb);
|
||||
return GATT_SUCCESS;
|
||||
}
|
||||
|
||||
static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
{
|
||||
tBTA_GATTS_RSP rsp;
|
||||
BLUFI_TRACE_DEBUG("blufi profile cb event = %x\n", event);
|
||||
|
||||
switch (event) {
|
||||
case BTA_GATTS_REG_EVT:
|
||||
BLUFI_TRACE_DEBUG("REG: status %d, app_uuid %04x, gatt_if %d\n", p_data->reg_oper.status, p_data->reg_oper.uuid.uu.uuid16, p_data->reg_oper.server_if);
|
||||
|
||||
if (p_data->reg_oper.status != BTA_GATT_OK) {
|
||||
BLUFI_TRACE_ERROR("BLUFI profile register failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
blufi_env.gatt_if = p_data->reg_oper.server_if;
|
||||
blufi_env.enabled = true;
|
||||
|
||||
//create the blufi service to the service data base.
|
||||
if (p_data->reg_oper.uuid.uu.uuid16 == BLUFI_APP_UUID) {
|
||||
BLUFI_TRACE_DEBUG("%s %d\n", __func__, __LINE__);
|
||||
blufi_create_service();
|
||||
}
|
||||
break;
|
||||
case BTA_GATTS_DEREG_EVT: {
|
||||
esp_blufi_cb_param_t param;
|
||||
btc_msg_t msg;
|
||||
|
||||
BLUFI_TRACE_DEBUG("DEREG: status %d, gatt_if %d\n", p_data->reg_oper.status, p_data->reg_oper.server_if);
|
||||
|
||||
if (p_data->reg_oper.status != BTA_GATT_OK) {
|
||||
BLUFI_TRACE_ERROR("BLUFI profile unregister failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
blufi_env.enabled = false;
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_DEINIT_FINISH;
|
||||
param.deinit_finish.state = ESP_BLUFI_DEINIT_OK;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_READ_EVT:
|
||||
memset(&rsp, 0, sizeof(tBTA_GATTS_API_RSP));
|
||||
rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle;
|
||||
rsp.attr_value.len = 1;
|
||||
rsp.attr_value.value[0] = 0x00;
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
p_data->req_data.status, &rsp);
|
||||
break;
|
||||
case BTA_GATTS_WRITE_EVT: {
|
||||
if (p_data->req_data.p_data->write_req.is_prep) {
|
||||
tBTA_GATT_STATUS status = GATT_SUCCESS;
|
||||
|
||||
if (blufi_env.prepare_buf == NULL) {
|
||||
blufi_env.prepare_buf = osi_malloc(BLUFI_PREPAIR_BUF_MAX_SIZE);
|
||||
blufi_env.prepare_len = 0;
|
||||
if (blufi_env.prepare_buf == NULL) {
|
||||
BLUFI_TRACE_ERROR("Blufi prep no mem\n");
|
||||
status = GATT_NO_RESOURCES;
|
||||
}
|
||||
} else {
|
||||
if (p_data->req_data.p_data->write_req.offset > BLUFI_PREPAIR_BUF_MAX_SIZE) {
|
||||
status = GATT_INVALID_OFFSET;
|
||||
} else if ((p_data->req_data.p_data->write_req.offset + p_data->req_data.p_data->write_req.len) > BLUFI_PREPAIR_BUF_MAX_SIZE) {
|
||||
status = GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&rsp, 0, sizeof(tGATTS_RSP));
|
||||
rsp.attr_value.handle = p_data->req_data.p_data->write_req.handle;
|
||||
rsp.attr_value.len = p_data->req_data.p_data->write_req.len;
|
||||
rsp.attr_value.offset = p_data->req_data.p_data->write_req.offset;
|
||||
memcpy(rsp.attr_value.value, p_data->req_data.p_data->write_req.value, p_data->req_data.p_data->write_req.len);
|
||||
|
||||
BLUFI_TRACE_DEBUG("prep write, len=%d, offset=%d\n", p_data->req_data.p_data->write_req.len, p_data->req_data.p_data->write_req.offset);
|
||||
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
status, &rsp);
|
||||
|
||||
if (status != GATT_SUCCESS) {
|
||||
if (blufi_env.prepare_buf) {
|
||||
osi_free(blufi_env.prepare_buf);
|
||||
blufi_env.prepare_buf = NULL;
|
||||
blufi_env.prepare_len = 0;
|
||||
}
|
||||
BLUFI_TRACE_ERROR("write data error , error code 0x%x\n", status);
|
||||
return;
|
||||
}
|
||||
memcpy(blufi_env.prepare_buf + p_data->req_data.p_data->write_req.offset,
|
||||
p_data->req_data.p_data->write_req.value,
|
||||
p_data->req_data.p_data->write_req.len);
|
||||
blufi_env.prepare_len += p_data->req_data.p_data->write_req.len;
|
||||
|
||||
return;
|
||||
} else {
|
||||
BLUFI_TRACE_DEBUG("norm write, len=%d, offset=%d\n", p_data->req_data.p_data->write_req.len, p_data->req_data.p_data->write_req.offset);
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
p_data->req_data.status, NULL);
|
||||
}
|
||||
|
||||
if (p_data->req_data.p_data->write_req.handle == blufi_env.handle_char_p2e) {
|
||||
btc_blufi_recv_handler(&p_data->req_data.p_data->write_req.value[0],
|
||||
p_data->req_data.p_data->write_req.len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_EXEC_WRITE_EVT:
|
||||
BLUFI_TRACE_DEBUG("exec write exec %d\n", p_data->req_data.p_data->exec_write);
|
||||
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
GATT_SUCCESS, NULL);
|
||||
|
||||
if (blufi_env.prepare_buf && p_data->req_data.p_data->exec_write == GATT_PREP_WRITE_EXEC) {
|
||||
btc_blufi_recv_handler(blufi_env.prepare_buf, blufi_env.prepare_len);
|
||||
}
|
||||
|
||||
if (blufi_env.prepare_buf) {
|
||||
osi_free(blufi_env.prepare_buf);
|
||||
blufi_env.prepare_buf = NULL;
|
||||
blufi_env.prepare_len = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case BTA_GATTS_MTU_EVT:
|
||||
BLUFI_TRACE_DEBUG("MTU size %d\n", p_data->req_data.p_data->mtu);
|
||||
blufi_env.frag_size = (p_data->req_data.p_data->mtu < BLUFI_MAX_DATA_LEN ? p_data->req_data.p_data->mtu : BLUFI_MAX_DATA_LEN) - BLUFI_MTU_RESERVED_SIZE;
|
||||
break;
|
||||
case BTA_GATTS_CONF_EVT:
|
||||
BLUFI_TRACE_DEBUG("CONFIRM EVT\n");
|
||||
/* Nothing */
|
||||
break;
|
||||
case BTA_GATTS_CREATE_EVT:
|
||||
blufi_env.handle_srvc = p_data->create.service_id;
|
||||
|
||||
//add the frist blufi characteristic --> write characteristic
|
||||
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
|
||||
(GATT_PERM_WRITE),
|
||||
(GATT_CHAR_PROP_BIT_WRITE),
|
||||
NULL, NULL);
|
||||
break;
|
||||
case BTA_GATTS_ADD_CHAR_EVT:
|
||||
switch (p_data->add_result.char_uuid.uu.uuid16) {
|
||||
case BLUFI_CHAR_P2E_UUID: /* Phone to ESP32 */
|
||||
blufi_env.handle_char_p2e = p_data->add_result.attr_id;
|
||||
|
||||
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_e2p,
|
||||
(GATT_PERM_READ),
|
||||
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY),
|
||||
NULL, NULL);
|
||||
break;
|
||||
case BLUFI_CHAR_E2P_UUID: /* ESP32 to Phone */
|
||||
blufi_env.handle_char_e2p = p_data->add_result.attr_id;
|
||||
|
||||
BTA_GATTS_AddCharDescriptor (blufi_env.handle_srvc,
|
||||
(GATT_PERM_READ | GATT_PERM_WRITE),
|
||||
&blufi_descr_uuid_e2p,
|
||||
NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BTA_GATTS_ADD_CHAR_DESCR_EVT: {
|
||||
/* call init finish */
|
||||
esp_blufi_cb_param_t param;
|
||||
btc_msg_t msg;
|
||||
|
||||
blufi_env.handle_descr_e2p = p_data->add_result.attr_id;
|
||||
//start the blufi service after created
|
||||
BTA_GATTS_StartService(blufi_env.handle_srvc, BTA_GATT_TRANSPORT_LE);
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_INIT_FINISH;
|
||||
param.init_finish.state = ESP_BLUFI_INIT_OK;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_CONNECT_EVT: {
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
|
||||
//set the connection flag to true
|
||||
BLUFI_TRACE_API("\ndevice is connected "BT_BD_ADDR_STR", server_if=%d,reason=0x%x,connect_id=%d\n",
|
||||
BT_BD_ADDR_HEX(p_data->conn.remote_bda), p_data->conn.server_if,
|
||||
p_data->conn.reason, p_data->conn.conn_id);
|
||||
|
||||
memcpy(blufi_env.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN);
|
||||
blufi_env.conn_id = p_data->conn.conn_id;
|
||||
blufi_env.is_connected = true;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_BLE_CONNECT;
|
||||
memcpy(param.connect.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN);
|
||||
param.connect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id);
|
||||
conn_id = param.connect.conn_id;
|
||||
server_if = p_data->conn.server_if;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_DISCONNECT_EVT: {
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
|
||||
blufi_env.is_connected = false;
|
||||
//set the connection flag to true
|
||||
BLUFI_TRACE_API("\ndevice is disconnected "BT_BD_ADDR_STR", server_if=%d,reason=0x%x,connect_id=%d\n",
|
||||
BT_BD_ADDR_HEX(p_data->conn.remote_bda), p_data->conn.server_if,
|
||||
p_data->conn.reason, p_data->conn.conn_id);
|
||||
|
||||
memcpy(blufi_env.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN);
|
||||
blufi_env.conn_id = p_data->conn.conn_id;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
blufi_env.sec_mode = 0x0;
|
||||
blufi_env.offset = 0;
|
||||
|
||||
if (blufi_env.aggr_buf != NULL) {
|
||||
osi_free(blufi_env.aggr_buf);
|
||||
blufi_env.aggr_buf = NULL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_BLE_DISCONNECT;
|
||||
memcpy(param.disconnect.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_OPEN_EVT:
|
||||
break;
|
||||
case BTA_GATTS_CLOSE_EVT:
|
||||
break;
|
||||
case BTA_GATTS_CONGEST_EVT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_blufi_send_notify(void *arg)
|
||||
{
|
||||
struct pkt_info *pkts = (struct pkt_info *) arg;
|
||||
uint16_t conn_id = blufi_env.conn_id;
|
||||
uint16_t attr_id = blufi_env.handle_char_e2p;
|
||||
bool rsp = false;
|
||||
BTA_GATTS_HandleValueIndication(conn_id, attr_id, pkts->pkt_len,
|
||||
pkts->pkt, rsp);
|
||||
|
||||
}
|
||||
|
||||
void esp_blufi_deinit(void)
|
||||
{
|
||||
BTA_GATTS_StopService(blufi_env.handle_srvc);
|
||||
BTA_GATTS_DeleteService(blufi_env.handle_srvc);
|
||||
/* register the BLUFI profile to the BTA_GATTS module*/
|
||||
BTA_GATTS_AppDeregister(blufi_env.gatt_if);
|
||||
}
|
||||
|
||||
void esp_blufi_adv_start(void)
|
||||
{
|
||||
esp_ble_gap_set_device_name(BLUFI_DEVICE_NAME);
|
||||
esp_ble_gap_config_adv_data(&blufi_adv_data);
|
||||
}
|
||||
|
||||
void esp_blufi_adv_stop(void)
|
||||
{
|
||||
esp_ble_gap_stop_advertising();
|
||||
}
|
||||
|
||||
void esp_blufi_send_encap(void *arg)
|
||||
{
|
||||
struct blufi_hdr *hdr = (struct blufi_hdr *)arg;
|
||||
retry:
|
||||
if (blufi_env.is_connected == false) {
|
||||
BTC_TRACE_WARNING("%s ble connection is broken\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (esp_ble_get_cur_sendable_packets_num(BTC_GATT_GET_CONN_ID(blufi_env.conn_id)) > 0) {
|
||||
btc_blufi_send_notify((uint8_t *)hdr,
|
||||
((hdr->fc & BLUFI_FC_CHECK) ?
|
||||
hdr->data_len + sizeof(struct blufi_hdr) + 2 :
|
||||
hdr->data_len + sizeof(struct blufi_hdr)));
|
||||
} else {
|
||||
BTC_TRACE_WARNING("%s wait to send blufi custom data\n", __func__);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
|
||||
{
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CLOSE;
|
||||
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
void esp_blufi_disconnect()
|
||||
{
|
||||
int rc;
|
||||
rc = esp_blufi_close(server_if, conn_id);
|
||||
assert (rc == 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,901 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "osi/allocator.h"
|
||||
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc/btc_manage.h"
|
||||
|
||||
#include "blufi_int.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_blufi.h"
|
||||
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
|
||||
#if GATT_DYNAMIC_MEMORY == FALSE
|
||||
tBLUFI_ENV blufi_env;
|
||||
#else
|
||||
tBLUFI_ENV *blufi_env_ptr;
|
||||
#endif
|
||||
|
||||
// static functions declare
|
||||
static void btc_blufi_send_ack(uint8_t seq);
|
||||
|
||||
inline void btc_blufi_cb_to_app(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param)
|
||||
{
|
||||
esp_blufi_event_cb_t btc_blufi_cb = (esp_blufi_event_cb_t)btc_profile_cb_get(BTC_PID_BLUFI);
|
||||
if (btc_blufi_cb) {
|
||||
btc_blufi_cb(event, param);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t btc_blufi_profile_init(void)
|
||||
{
|
||||
esp_blufi_callbacks_t *store_p = blufi_env.cbs;
|
||||
|
||||
uint8_t rc;
|
||||
if (blufi_env.enabled) {
|
||||
BLUFI_TRACE_ERROR("BLUFI already initialized");
|
||||
return ESP_BLUFI_ERROR;
|
||||
}
|
||||
|
||||
memset(&blufi_env, 0x0, sizeof(blufi_env));
|
||||
blufi_env.cbs = store_p; /* if set callback prior, restore the point */
|
||||
blufi_env.frag_size = BLUFI_FRAG_DATA_DEFAULT_LEN;
|
||||
rc = esp_blufi_init();
|
||||
if(rc != 0 ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
return ESP_BLUFI_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8_t btc_blufi_profile_deinit(void)
|
||||
{
|
||||
if (!blufi_env.enabled) {
|
||||
BTC_TRACE_ERROR("BLUFI already de-initialized");
|
||||
return ESP_BLUFI_ERROR;
|
||||
}
|
||||
|
||||
esp_blufi_deinit();
|
||||
return ESP_BLUFI_SUCCESS;
|
||||
}
|
||||
|
||||
void btc_blufi_send_notify(uint8_t *pkt, int pkt_len)
|
||||
{
|
||||
struct pkt_info pkts;
|
||||
pkts.pkt = pkt;
|
||||
pkts.pkt_len = pkt_len;
|
||||
esp_blufi_send_notify(&pkts);
|
||||
}
|
||||
|
||||
void btc_blufi_report_error(esp_blufi_error_state_t state)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_REPORT_ERROR;
|
||||
esp_blufi_cb_param_t param;
|
||||
param.report_error.state = state;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
}
|
||||
|
||||
void btc_blufi_recv_handler(uint8_t *data, int len)
|
||||
{
|
||||
struct blufi_hdr *hdr = (struct blufi_hdr *)data;
|
||||
uint16_t checksum, checksum_pkt;
|
||||
int ret;
|
||||
|
||||
if (hdr->seq != blufi_env.recv_seq) {
|
||||
BTC_TRACE_ERROR("%s seq %d is not expect %d\n", __func__, hdr->seq, blufi_env.recv_seq + 1);
|
||||
btc_blufi_report_error(ESP_BLUFI_SEQUENCE_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
blufi_env.recv_seq++;
|
||||
|
||||
// first step, decrypt
|
||||
if (BLUFI_FC_IS_ENC(hdr->fc)
|
||||
&& (blufi_env.cbs && blufi_env.cbs->decrypt_func)) {
|
||||
ret = blufi_env.cbs->decrypt_func(hdr->seq, hdr->data, hdr->data_len);
|
||||
if (ret != hdr->data_len) { /* enc must be success and enc len must equal to plain len */
|
||||
BTC_TRACE_ERROR("%s decrypt error %d\n", __func__, ret);
|
||||
btc_blufi_report_error(ESP_BLUFI_DECRYPT_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// second step, check sum
|
||||
if (BLUFI_FC_IS_CHECK(hdr->fc)
|
||||
&& (blufi_env.cbs && blufi_env.cbs->checksum_func)) {
|
||||
checksum = blufi_env.cbs->checksum_func(hdr->seq, &hdr->seq, hdr->data_len + 2);
|
||||
checksum_pkt = hdr->data[hdr->data_len] | (((uint16_t) hdr->data[hdr->data_len + 1]) << 8);
|
||||
if (checksum != checksum_pkt) {
|
||||
BTC_TRACE_ERROR("%s checksum error %04x, pkt %04x\n", __func__, checksum, checksum_pkt);
|
||||
btc_blufi_report_error(ESP_BLUFI_CHECKSUM_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (BLUFI_FC_IS_REQ_ACK(hdr->fc)) {
|
||||
btc_blufi_send_ack(hdr->seq);
|
||||
}
|
||||
|
||||
if (BLUFI_FC_IS_FRAG(hdr->fc)) {
|
||||
if (blufi_env.offset == 0) {
|
||||
/*
|
||||
blufi_env.aggr_buf should be NULL if blufi_env.offset is 0.
|
||||
It is possible that the process of sending fragment packet
|
||||
has not been completed
|
||||
*/
|
||||
if (blufi_env.aggr_buf) {
|
||||
BTC_TRACE_ERROR("%s msg error, blufi_env.aggr_buf is not freed\n", __func__);
|
||||
btc_blufi_report_error(ESP_BLUFI_MSG_STATE_ERROR);
|
||||
return;
|
||||
}
|
||||
blufi_env.total_len = hdr->data[0] | (((uint16_t) hdr->data[1]) << 8);
|
||||
blufi_env.aggr_buf = osi_malloc(blufi_env.total_len);
|
||||
if (blufi_env.aggr_buf == NULL) {
|
||||
BTC_TRACE_ERROR("%s no mem, len %d\n", __func__, blufi_env.total_len);
|
||||
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (blufi_env.offset + hdr->data_len - 2 <= blufi_env.total_len){
|
||||
memcpy(blufi_env.aggr_buf + blufi_env.offset, hdr->data + 2, hdr->data_len - 2);
|
||||
blufi_env.offset += (hdr->data_len - 2);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s payload is longer than packet length, len %d \n", __func__, blufi_env.total_len);
|
||||
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (blufi_env.offset > 0) { /* if previous pkt is frag */
|
||||
/* blufi_env.aggr_buf should not be NULL */
|
||||
if (blufi_env.aggr_buf == NULL) {
|
||||
BTC_TRACE_ERROR("%s buffer is NULL\n", __func__);
|
||||
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR);
|
||||
return;
|
||||
}
|
||||
/* payload length should be equal to total_len */
|
||||
if ((blufi_env.offset + hdr->data_len) != blufi_env.total_len) {
|
||||
BTC_TRACE_ERROR("%s payload is longer than packet length, len %d \n", __func__, blufi_env.total_len);
|
||||
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
|
||||
return;
|
||||
}
|
||||
memcpy(blufi_env.aggr_buf + blufi_env.offset, hdr->data, hdr->data_len);
|
||||
|
||||
btc_blufi_protocol_handler(hdr->type, blufi_env.aggr_buf, blufi_env.total_len);
|
||||
blufi_env.offset = 0;
|
||||
osi_free(blufi_env.aggr_buf);
|
||||
blufi_env.aggr_buf = NULL;
|
||||
} else {
|
||||
btc_blufi_protocol_handler(hdr->type, hdr->data, hdr->data_len);
|
||||
blufi_env.offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void btc_blufi_send_encap(uint8_t type, uint8_t *data, int total_data_len)
|
||||
{
|
||||
struct blufi_hdr *hdr = NULL;
|
||||
int remain_len = total_data_len;
|
||||
uint16_t checksum;
|
||||
int ret;
|
||||
|
||||
if (blufi_env.is_connected == false) {
|
||||
BTC_TRACE_ERROR("blufi connection has been disconnected \n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (remain_len > 0) {
|
||||
if (remain_len > blufi_env.frag_size) {
|
||||
hdr = osi_malloc(sizeof(struct blufi_hdr) + 2 + blufi_env.frag_size + 2);
|
||||
if (hdr == NULL) {
|
||||
BTC_TRACE_ERROR("%s no mem\n", __func__);
|
||||
return;
|
||||
}
|
||||
hdr->fc = 0x0;
|
||||
hdr->data_len = blufi_env.frag_size + 2;
|
||||
hdr->data[0] = remain_len & 0xff;
|
||||
hdr->data[1] = (remain_len >> 8) & 0xff;
|
||||
memcpy(hdr->data + 2, &data[total_data_len - remain_len], blufi_env.frag_size); //copy first, easy for check sum
|
||||
hdr->fc |= BLUFI_FC_FRAG;
|
||||
} else {
|
||||
hdr = osi_malloc(sizeof(struct blufi_hdr) + remain_len + 2);
|
||||
if (hdr == NULL) {
|
||||
BTC_TRACE_ERROR("%s no mem\n", __func__);
|
||||
return;
|
||||
}
|
||||
hdr->fc = 0x0;
|
||||
hdr->data_len = remain_len;
|
||||
memcpy(hdr->data, &data[total_data_len - remain_len], hdr->data_len); //copy first, easy for check sum
|
||||
}
|
||||
|
||||
hdr->type = type;
|
||||
hdr->fc |= BLUFI_FC_DIR_E2P;
|
||||
hdr->seq = blufi_env.send_seq++;
|
||||
|
||||
if (BLUFI_TYPE_IS_CTRL(hdr->type)) {
|
||||
if ((blufi_env.sec_mode & BLUFI_CTRL_SEC_MODE_CHECK_MASK)
|
||||
&& (blufi_env.cbs && blufi_env.cbs->checksum_func)) {
|
||||
hdr->fc |= BLUFI_FC_CHECK;
|
||||
checksum = blufi_env.cbs->checksum_func(hdr->seq, &hdr->seq, hdr->data_len + 2);
|
||||
memcpy(&hdr->data[hdr->data_len], &checksum, 2);
|
||||
}
|
||||
} else if (!BLUFI_TYPE_IS_DATA_NEG(hdr->type) && !BLUFI_TYPE_IS_DATA_ERROR_INFO(hdr->type)) {
|
||||
if ((blufi_env.sec_mode & BLUFI_DATA_SEC_MODE_CHECK_MASK)
|
||||
&& (blufi_env.cbs && blufi_env.cbs->checksum_func)) {
|
||||
hdr->fc |= BLUFI_FC_CHECK;
|
||||
checksum = blufi_env.cbs->checksum_func(hdr->seq, &hdr->seq, hdr->data_len + 2);
|
||||
memcpy(&hdr->data[hdr->data_len], &checksum, 2);
|
||||
}
|
||||
|
||||
if ((blufi_env.sec_mode & BLUFI_DATA_SEC_MODE_ENC_MASK)
|
||||
&& (blufi_env.cbs && blufi_env.cbs->encrypt_func)) {
|
||||
ret = blufi_env.cbs->encrypt_func(hdr->seq, hdr->data, hdr->data_len);
|
||||
if (ret == hdr->data_len) { /* enc must be success and enc len must equal to plain len */
|
||||
hdr->fc |= BLUFI_FC_ENC;
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s encrypt error %d\n", __func__, ret);
|
||||
btc_blufi_report_error(ESP_BLUFI_ENCRYPT_ERROR);
|
||||
osi_free(hdr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hdr->fc & BLUFI_FC_FRAG) {
|
||||
remain_len -= (hdr->data_len - 2);
|
||||
} else {
|
||||
remain_len -= hdr->data_len;
|
||||
}
|
||||
|
||||
esp_blufi_send_encap(hdr);
|
||||
|
||||
osi_free(hdr);
|
||||
hdr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_blufi_wifi_conn_report(uint8_t opmode, uint8_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *info, int info_len)
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t *data;
|
||||
int data_len;
|
||||
uint8_t *p;
|
||||
|
||||
data_len = info_len + 3;
|
||||
p = data = osi_malloc(data_len);
|
||||
if (data == NULL) {
|
||||
BTC_TRACE_ERROR("%s no mem\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP);
|
||||
*p++ = opmode;
|
||||
*p++ = sta_conn_state;
|
||||
*p++ = softap_conn_num;
|
||||
|
||||
if (info) {
|
||||
if (info->sta_bssid_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID;
|
||||
*p++ = 6;
|
||||
memcpy(p, info->sta_bssid, 6);
|
||||
p += 6;
|
||||
}
|
||||
if (info->sta_ssid) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_SSID;
|
||||
*p++ = info->sta_ssid_len;
|
||||
memcpy(p, info->sta_ssid, info->sta_ssid_len);
|
||||
p += info->sta_ssid_len;
|
||||
}
|
||||
if (info->sta_passwd) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD;
|
||||
*p++ = info->sta_passwd_len;
|
||||
memcpy(p, info->sta_passwd, info->sta_passwd_len);
|
||||
p += info->sta_passwd_len;
|
||||
}
|
||||
if (info->softap_ssid) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID;
|
||||
*p++ = info->softap_ssid_len;
|
||||
memcpy(p, info->softap_ssid, info->softap_ssid_len);
|
||||
p += info->softap_ssid_len;
|
||||
}
|
||||
if (info->softap_passwd) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD;
|
||||
*p++ = info->softap_passwd_len;
|
||||
memcpy(p, info->softap_passwd, info->softap_passwd_len);
|
||||
p += info->softap_passwd_len;
|
||||
}
|
||||
if (info->softap_authmode_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE;
|
||||
*p++ = 1;
|
||||
*p++ = info->softap_authmode;
|
||||
}
|
||||
if (info->softap_max_conn_num_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM;
|
||||
*p++ = 1;
|
||||
*p++ = info->softap_max_conn_num;
|
||||
}
|
||||
if (info->softap_channel_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL;
|
||||
*p++ = 1;
|
||||
*p++ = info->softap_channel;
|
||||
}
|
||||
if (info->sta_max_conn_retry_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY;
|
||||
*p++ = 1;
|
||||
*p++ = info->sta_max_conn_retry;
|
||||
}
|
||||
if (info->sta_conn_end_reason_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON;
|
||||
*p++ = 1;
|
||||
*p++ = info->sta_conn_end_reason;
|
||||
}
|
||||
if (info->sta_conn_rssi_set) {
|
||||
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI;
|
||||
*p++ = 1;
|
||||
*p++ = info->sta_conn_rssi;
|
||||
}
|
||||
}
|
||||
if (p - data > data_len) {
|
||||
BTC_TRACE_ERROR("%s len error %d %d\n", __func__, (int)(p - data), data_len);
|
||||
}
|
||||
|
||||
btc_blufi_send_encap(type, data, data_len);
|
||||
osi_free(data);
|
||||
}
|
||||
|
||||
void btc_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t *data;
|
||||
int data_len;
|
||||
uint8_t *p;
|
||||
// malloc size: (len + RSSI + ssid buffer) * apCount;
|
||||
uint32_t malloc_size = (1 + 1 + sizeof(list->ssid)) * apCount;
|
||||
p = data = osi_malloc(malloc_size);
|
||||
if (data == NULL) {
|
||||
BTC_TRACE_ERROR("malloc error\n");
|
||||
return;
|
||||
}
|
||||
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST);
|
||||
for (int i = 0; i < apCount; ++i)
|
||||
{
|
||||
uint32_t len = strlen((const char *)list[i].ssid);
|
||||
data_len = (p - data);
|
||||
//current_len + ssid + rssi + total_len_value
|
||||
if((data_len + len + 1 + 1) > malloc_size) {
|
||||
BTC_TRACE_ERROR("%s len error", __func__);
|
||||
osi_free(data);
|
||||
return;
|
||||
}
|
||||
*p++ = len + 1; // length of ssid + rssi
|
||||
*p++ = list[i].rssi;
|
||||
memcpy(p, list[i].ssid, len);
|
||||
p = p + len;
|
||||
}
|
||||
data_len = (p - data);
|
||||
btc_blufi_send_encap(type, data, data_len);
|
||||
osi_free(data);
|
||||
}
|
||||
|
||||
static void btc_blufi_send_ack(uint8_t seq)
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t data;
|
||||
|
||||
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_CTRL, BLUFI_TYPE_CTRL_SUBTYPE_ACK);
|
||||
data = seq;
|
||||
|
||||
btc_blufi_send_encap(type, &data, 1);
|
||||
}
|
||||
static void btc_blufi_send_error_info(uint8_t state)
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t *data;
|
||||
int data_len;
|
||||
uint8_t *p;
|
||||
|
||||
data_len = 1;
|
||||
p = data = osi_malloc(data_len);
|
||||
if (data == NULL) {
|
||||
BTC_TRACE_ERROR("%s no mem\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO);
|
||||
*p++ = state;
|
||||
if (p - data > data_len) {
|
||||
BTC_TRACE_ERROR("%s len error %d %d\n", __func__, (int)(p - data), data_len);
|
||||
}
|
||||
|
||||
btc_blufi_send_encap(type, data, data_len);
|
||||
osi_free(data);
|
||||
}
|
||||
|
||||
static void btc_blufi_send_custom_data(uint8_t *value, uint32_t value_len)
|
||||
{
|
||||
if(value == NULL || value_len == 0) {
|
||||
BTC_TRACE_ERROR("%s value or value len error", __func__);
|
||||
return;
|
||||
}
|
||||
uint8_t *data = osi_malloc(value_len);
|
||||
if (data == NULL) {
|
||||
BTC_TRACE_ERROR("%s mem malloc error", __func__);
|
||||
return;
|
||||
}
|
||||
uint8_t type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA);
|
||||
memcpy(data, value, value_len);
|
||||
btc_blufi_send_encap(type, data, value_len);
|
||||
osi_free(data);
|
||||
}
|
||||
|
||||
void btc_blufi_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
esp_blufi_cb_param_t *dst = (esp_blufi_cb_param_t *) p_dest;
|
||||
esp_blufi_cb_param_t *src = (esp_blufi_cb_param_t *) p_src;
|
||||
|
||||
switch (msg->act) {
|
||||
case ESP_BLUFI_EVENT_RECV_STA_SSID:
|
||||
dst->sta_ssid.ssid = osi_malloc(src->sta_ssid.ssid_len);
|
||||
if (dst->sta_ssid.ssid == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->sta_ssid.ssid, src->sta_ssid.ssid, src->sta_ssid.ssid_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
|
||||
dst->sta_passwd.passwd = osi_malloc(src->sta_passwd.passwd_len);
|
||||
if (dst->sta_passwd.passwd == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->sta_passwd.passwd, src->sta_passwd.passwd, src->sta_passwd.passwd_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID:
|
||||
dst->softap_ssid.ssid = osi_malloc(src->softap_ssid.ssid_len);
|
||||
if (dst->softap_ssid.ssid == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->softap_ssid.ssid, src->softap_ssid.ssid, src->softap_ssid.ssid_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD:
|
||||
dst->softap_passwd.passwd = osi_malloc(src->softap_passwd.passwd_len);
|
||||
if (dst->softap_passwd.passwd == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->softap_passwd.passwd, src->softap_passwd.passwd, src->softap_passwd.passwd_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_USERNAME:
|
||||
dst->username.name = osi_malloc(src->username.name_len);
|
||||
if (dst->username.name == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->username.name, src->username.name, src->username.name_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CA_CERT:
|
||||
dst->ca.cert = osi_malloc(src->ca.cert_len);
|
||||
if (dst->ca.cert == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->ca.cert, src->ca.cert, src->ca.cert_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT:
|
||||
dst->client_cert.cert = osi_malloc(src->client_cert.cert_len);
|
||||
if (dst->client_cert.cert == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->client_cert.cert, src->client_cert.cert, src->client_cert.cert_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SERVER_CERT:
|
||||
dst->server_cert.cert = osi_malloc(src->server_cert.cert_len);
|
||||
if (dst->server_cert.cert == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->server_cert.cert, src->server_cert.cert, src->server_cert.cert_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY:
|
||||
dst->client_pkey.pkey = osi_malloc(src->client_pkey.pkey_len);
|
||||
if (dst->client_pkey.pkey == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->client_pkey.pkey, src->client_pkey.pkey, src->client_pkey.pkey_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY:
|
||||
dst->server_pkey.pkey = osi_malloc(src->server_pkey.pkey_len);
|
||||
if (dst->server_pkey.pkey == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
}
|
||||
memcpy(dst->server_pkey.pkey, src->server_pkey.pkey, src->server_pkey.pkey_len);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
|
||||
dst->custom_data.data = osi_malloc(src->custom_data.data_len);
|
||||
if (dst->custom_data.data == NULL) {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
memcpy(dst->custom_data.data, src->custom_data.data, src->custom_data.data_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_blufi_cb_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
esp_blufi_cb_param_t *param = (esp_blufi_cb_param_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case ESP_BLUFI_EVENT_RECV_STA_SSID:
|
||||
osi_free(param->sta_ssid.ssid);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
|
||||
osi_free(param->sta_passwd.passwd);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID:
|
||||
osi_free(param->softap_ssid.ssid);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD:
|
||||
osi_free(param->softap_passwd.passwd);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_USERNAME:
|
||||
osi_free(param->username.name);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CA_CERT:
|
||||
osi_free(param->ca.cert);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT:
|
||||
osi_free(param->client_cert.cert);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SERVER_CERT:
|
||||
osi_free(param->server_cert.cert);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY:
|
||||
osi_free(param->client_pkey.pkey);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY:
|
||||
osi_free(param->server_pkey.pkey);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
|
||||
osi_free(param->custom_data.data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_blufi_cb_handler(btc_msg_t *msg)
|
||||
{
|
||||
esp_blufi_cb_param_t *param = (esp_blufi_cb_param_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case ESP_BLUFI_EVENT_INIT_FINISH: {
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_INIT_FINISH, param);
|
||||
break;
|
||||
}
|
||||
case ESP_BLUFI_EVENT_DEINIT_FINISH: {
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_DEINIT_FINISH, param);
|
||||
break;
|
||||
}
|
||||
case ESP_BLUFI_EVENT_BLE_CONNECT:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_BLE_CONNECT, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_BLE_DISCONNECT:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_BLE_DISCONNECT, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_SET_WIFI_OPMODE:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_SET_WIFI_OPMODE, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP, NULL);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP, NULL);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_GET_WIFI_STATUS:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_GET_WIFI_STATUS, NULL);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_GET_WIFI_LIST:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_GET_WIFI_LIST, NULL);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_DEAUTHENTICATE_STA:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_DEAUTHENTICATE_STA, NULL);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_STA_BSSID:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_STA_BSSID, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_STA_SSID:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_STA_SSID, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_STA_PASSWD, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_SSID, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_USERNAME:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_USERNAME, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CA_CERT:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CA_CERT, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CLIENT_CERT, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SERVER_CERT:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SERVER_CERT, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_REPORT_ERROR:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_REPORT_ERROR, param);
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CUSTOM_DATA, param);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s UNKNOWN %d\n", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
|
||||
btc_blufi_cb_deep_free(msg);
|
||||
}
|
||||
|
||||
void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
btc_blufi_args_t *dst = (btc_blufi_args_t *) p_dest;
|
||||
btc_blufi_args_t *src = (btc_blufi_args_t *) p_src;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLUFI_ACT_SEND_CFG_REPORT: {
|
||||
esp_blufi_extra_info_t *src_info = src->wifi_conn_report.extra_info;
|
||||
dst->wifi_conn_report.extra_info_len = 0;
|
||||
dst->wifi_conn_report.extra_info = NULL;
|
||||
|
||||
if (src_info == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
dst->wifi_conn_report.extra_info = osi_calloc(sizeof(esp_blufi_extra_info_t));
|
||||
if (dst->wifi_conn_report.extra_info == NULL) {
|
||||
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (src_info->sta_bssid_set) {
|
||||
memcpy(dst->wifi_conn_report.extra_info->sta_bssid, src_info->sta_bssid, 6);
|
||||
dst->wifi_conn_report.extra_info->sta_bssid_set = src_info->sta_bssid_set;
|
||||
dst->wifi_conn_report.extra_info_len += (6 + 2);
|
||||
}
|
||||
if (src_info->sta_ssid) {
|
||||
dst->wifi_conn_report.extra_info->sta_ssid = osi_malloc(src_info->sta_ssid_len);
|
||||
if (dst->wifi_conn_report.extra_info->sta_ssid) {
|
||||
memcpy(dst->wifi_conn_report.extra_info->sta_ssid, src_info->sta_ssid, src_info->sta_ssid_len);
|
||||
dst->wifi_conn_report.extra_info->sta_ssid_len = src_info->sta_ssid_len;
|
||||
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->sta_ssid_len + 2);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (src_info->sta_passwd) {
|
||||
dst->wifi_conn_report.extra_info->sta_passwd = osi_malloc(src_info->sta_passwd_len);
|
||||
if (dst->wifi_conn_report.extra_info->sta_passwd) {
|
||||
memcpy(dst->wifi_conn_report.extra_info->sta_passwd, src_info->sta_passwd, src_info->sta_passwd_len);
|
||||
dst->wifi_conn_report.extra_info->sta_passwd_len = src_info->sta_passwd_len;
|
||||
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->sta_passwd_len + 2);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (src_info->softap_ssid) {
|
||||
dst->wifi_conn_report.extra_info->softap_ssid = osi_malloc(src_info->softap_ssid_len);
|
||||
if (dst->wifi_conn_report.extra_info->softap_ssid) {
|
||||
memcpy(dst->wifi_conn_report.extra_info->softap_ssid, src_info->softap_ssid, src_info->softap_ssid_len);
|
||||
dst->wifi_conn_report.extra_info->softap_ssid_len = src_info->softap_ssid_len;
|
||||
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->softap_ssid_len + 2);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (src_info->softap_passwd) {
|
||||
dst->wifi_conn_report.extra_info->softap_passwd = osi_malloc(src_info->softap_passwd_len);
|
||||
if (dst->wifi_conn_report.extra_info->softap_passwd) {
|
||||
memcpy(dst->wifi_conn_report.extra_info->softap_passwd, src_info->softap_passwd, src_info->softap_passwd_len);
|
||||
dst->wifi_conn_report.extra_info->softap_passwd_len = src_info->softap_passwd_len;
|
||||
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->softap_passwd_len + 2);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (src_info->softap_authmode_set) {
|
||||
dst->wifi_conn_report.extra_info->softap_authmode_set = src_info->softap_authmode_set;
|
||||
dst->wifi_conn_report.extra_info->softap_authmode = src_info->softap_authmode;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->softap_max_conn_num_set) {
|
||||
dst->wifi_conn_report.extra_info->softap_max_conn_num_set = src_info->softap_max_conn_num_set;
|
||||
dst->wifi_conn_report.extra_info->softap_max_conn_num = src_info->softap_max_conn_num;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->softap_channel_set) {
|
||||
dst->wifi_conn_report.extra_info->softap_channel_set = src_info->softap_channel_set;
|
||||
dst->wifi_conn_report.extra_info->softap_channel = src_info->softap_channel;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->sta_max_conn_retry_set) {
|
||||
dst->wifi_conn_report.extra_info->sta_max_conn_retry_set = src_info->sta_max_conn_retry_set;
|
||||
dst->wifi_conn_report.extra_info->sta_max_conn_retry = src_info->sta_max_conn_retry;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->sta_conn_end_reason_set) {
|
||||
dst->wifi_conn_report.extra_info->sta_conn_end_reason_set = src_info->sta_conn_end_reason_set;
|
||||
dst->wifi_conn_report.extra_info->sta_conn_end_reason = src_info->sta_conn_end_reason;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
if (src_info->sta_conn_rssi_set) {
|
||||
dst->wifi_conn_report.extra_info->sta_conn_rssi_set = src_info->sta_conn_rssi_set;
|
||||
dst->wifi_conn_report.extra_info->sta_conn_rssi = src_info->sta_conn_rssi;
|
||||
dst->wifi_conn_report.extra_info_len += (1 + 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{
|
||||
esp_blufi_ap_record_t *list = src->wifi_list.list;
|
||||
src->wifi_list.list = NULL;
|
||||
if (list == NULL || src->wifi_list.apCount <= 0) {
|
||||
break;
|
||||
}
|
||||
dst->wifi_list.list = (esp_blufi_ap_record_t *)osi_malloc(sizeof(esp_blufi_ap_record_t) * src->wifi_list.apCount);
|
||||
if (dst->wifi_list.list == NULL) {
|
||||
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__);
|
||||
break;
|
||||
}
|
||||
memcpy(dst->wifi_list.list, list, sizeof(esp_blufi_ap_record_t) * src->wifi_list.apCount);
|
||||
break;
|
||||
}
|
||||
case BTC_BLUFI_ACT_SEND_CUSTOM_DATA:{
|
||||
uint8_t *data = src->custom_data.data;
|
||||
if(data == NULL) {
|
||||
BTC_TRACE_ERROR("custom data is NULL\n");
|
||||
break;
|
||||
}
|
||||
dst->custom_data.data = osi_malloc(src->custom_data.data_len);
|
||||
if(dst->custom_data.data == NULL) {
|
||||
BTC_TRACE_ERROR("custom data malloc error\n");
|
||||
break;
|
||||
}
|
||||
memcpy(dst->custom_data.data, src->custom_data.data, src->custom_data.data_len);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_blufi_call_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
btc_blufi_args_t *arg = (btc_blufi_args_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLUFI_ACT_SEND_CFG_REPORT: {
|
||||
esp_blufi_extra_info_t *info = (esp_blufi_extra_info_t *)arg->wifi_conn_report.extra_info;
|
||||
|
||||
if (info == NULL) {
|
||||
return;
|
||||
}
|
||||
if (info->sta_ssid) {
|
||||
osi_free(info->sta_ssid);
|
||||
}
|
||||
if (info->sta_passwd) {
|
||||
osi_free(info->sta_passwd);
|
||||
}
|
||||
if (info->softap_ssid) {
|
||||
osi_free(info->softap_ssid);
|
||||
}
|
||||
if (info->softap_passwd) {
|
||||
osi_free(info->softap_passwd);
|
||||
}
|
||||
osi_free(info);
|
||||
break;
|
||||
}
|
||||
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{
|
||||
esp_blufi_ap_record_t *list = (esp_blufi_ap_record_t *)arg->wifi_list.list;
|
||||
if (list){
|
||||
osi_free(list);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BTC_BLUFI_ACT_SEND_CUSTOM_DATA:{
|
||||
uint8_t *data = arg->custom_data.data;
|
||||
if(data) {
|
||||
osi_free(data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_blufi_call_handler(btc_msg_t *msg)
|
||||
{
|
||||
btc_blufi_args_t *arg = (btc_blufi_args_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLUFI_ACT_INIT:
|
||||
btc_blufi_profile_init();
|
||||
break;
|
||||
case BTC_BLUFI_ACT_DEINIT:
|
||||
btc_blufi_profile_deinit();
|
||||
break;
|
||||
case BTC_BLUFI_ACT_SEND_CFG_REPORT:
|
||||
btc_blufi_wifi_conn_report(arg->wifi_conn_report.opmode,
|
||||
arg->wifi_conn_report.sta_conn_state,
|
||||
arg->wifi_conn_report.softap_conn_num,
|
||||
arg->wifi_conn_report.extra_info,
|
||||
arg->wifi_conn_report.extra_info_len);
|
||||
break;
|
||||
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{
|
||||
btc_blufi_send_wifi_list(arg->wifi_list.apCount, arg->wifi_list.list);
|
||||
break;
|
||||
}
|
||||
case BTC_BLUFI_ACT_SEND_ERR_INFO:
|
||||
btc_blufi_send_error_info(arg->blufi_err_infor.state);
|
||||
break;
|
||||
case BTC_BLUFI_ACT_SEND_CUSTOM_DATA:
|
||||
btc_blufi_send_custom_data(arg->custom_data.data, arg->custom_data.data_len);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s UNKNOWN %d\n", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
btc_blufi_call_deep_free(msg);
|
||||
}
|
||||
|
||||
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks)
|
||||
{
|
||||
blufi_env.cbs = callbacks;
|
||||
}
|
||||
|
||||
uint16_t btc_blufi_get_version(void)
|
||||
{
|
||||
return BTC_BLUFI_VERSION;
|
||||
}
|
||||
|
||||
#endif ///BLUFI_INCLUDED == TRUE
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc/btc_manage.h"
|
||||
|
||||
#include "blufi_int.h"
|
||||
|
||||
//#include "esp_wifi.h"
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
|
||||
void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
uint8_t *output_data = NULL;
|
||||
int output_len = 0;
|
||||
bool need_free = false;
|
||||
|
||||
switch (BLUFI_GET_TYPE(type)) {
|
||||
case BLUFI_TYPE_CTRL:
|
||||
switch (BLUFI_GET_SUBTYPE(type)) {
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_ACK:
|
||||
/* TODO: check sequence */
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE:
|
||||
blufi_env.sec_mode = data[0];
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_SET_WIFI_OPMODE;
|
||||
param.wifi_mode.op_mode = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_GET_WIFI_STATUS;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_DEAUTHENTICATE_STA;
|
||||
|
||||
btc_transfer_context(&msg, NULL, 0, NULL,NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION: {
|
||||
uint8_t type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION);
|
||||
uint8_t data[2];
|
||||
|
||||
data[0] = BTC_BLUFI_GREAT_VER;
|
||||
data[1] = BTC_BLUFI_SUB_VER;
|
||||
btc_blufi_send_encap(type, &data[0], sizeof(data));
|
||||
break;
|
||||
}
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_GET_WIFI_LIST;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s Unkown Ctrl pkt %02x\n", __func__, type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BLUFI_TYPE_DATA:
|
||||
switch (BLUFI_GET_SUBTYPE(type)) {
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_NEG:
|
||||
if (blufi_env.cbs && blufi_env.cbs->negotiate_data_handler) {
|
||||
blufi_env.cbs->negotiate_data_handler(data, len, &output_data, &output_len, &need_free);
|
||||
}
|
||||
|
||||
if (output_data && output_len > 0) {
|
||||
btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_NEG),
|
||||
output_data, output_len);
|
||||
}
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_STA_BSSID;
|
||||
memcpy(param.sta_bssid.bssid, &data[0], 6);
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_STA_SSID:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_STA_SSID;
|
||||
param.sta_ssid.ssid = &data[0];
|
||||
param.sta_ssid.ssid_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_STA_PASSWD;
|
||||
param.sta_passwd.passwd = &data[0];
|
||||
param.sta_passwd.passwd_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_SSID;
|
||||
param.softap_ssid.ssid = &data[0];
|
||||
param.softap_ssid.ssid_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD;
|
||||
param.softap_passwd.passwd = &data[0];
|
||||
param.softap_passwd.passwd_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM;
|
||||
param.softap_max_conn_num.max_conn_num = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE;
|
||||
param.softap_auth_mode.auth_mode = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL;
|
||||
param.softap_channel.channel = data[0];
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_USERNAME:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_USERNAME;
|
||||
param.username.name = &data[0];
|
||||
param.username.name_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CA:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_CA_CERT;
|
||||
param.ca.cert = &data[0];
|
||||
param.ca.cert_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_CLIENT_CERT;
|
||||
param.client_cert.cert = &data[0];
|
||||
param.client_cert.cert_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SERVER_CERT;
|
||||
param.client_cert.cert = &data[0];
|
||||
param.client_cert.cert_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY;
|
||||
param.client_pkey.pkey = &data[0];
|
||||
param.client_pkey.pkey_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY;
|
||||
param.client_pkey.pkey = &data[0];
|
||||
param.client_pkey.pkey_len = len;
|
||||
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
case BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA:
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_RECV_CUSTOM_DATA;
|
||||
param.custom_data.data = &data[0];
|
||||
param.custom_data.data_len = len;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s Unkown Ctrl pkt %02x\n", __func__, type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif ///BLUFI_INCLUDED == TRUE
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __BLUFI_INT_H__
|
||||
#define __BLUFI_INT_H__
|
||||
|
||||
#include "btc/btc_task.h"
|
||||
#include "esp_blufi_api.h"
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
|
||||
#define BTC_BLUFI_GREAT_VER 0x01 //Version + Subversion
|
||||
#define BTC_BLUFI_SUB_VER 0x03 //Version + Subversion
|
||||
#define BTC_BLUFI_VERSION ((BTC_BLUFI_GREAT_VER<<8)|BTC_BLUFI_SUB_VER) //Version + Subversion
|
||||
|
||||
typedef UINT8 tGATT_IF;
|
||||
/* service engine control block */
|
||||
typedef struct {
|
||||
/* Protocol reference */
|
||||
tGATT_IF gatt_if;
|
||||
UINT8 srvc_inst;
|
||||
UINT16 handle_srvc;
|
||||
UINT16 handle_char_p2e;
|
||||
UINT16 handle_char_e2p;
|
||||
UINT16 handle_descr_e2p;
|
||||
UINT16 conn_id;
|
||||
BOOLEAN is_connected;
|
||||
BD_ADDR remote_bda;
|
||||
UINT32 trans_id;
|
||||
UINT8 congest;
|
||||
UINT16 frag_size;
|
||||
#define BLUFI_PREPAIR_BUF_MAX_SIZE 1024
|
||||
uint8_t *prepare_buf;
|
||||
int prepare_len;
|
||||
/* Control reference */
|
||||
esp_blufi_callbacks_t *cbs;
|
||||
BOOLEAN enabled;
|
||||
uint8_t send_seq;
|
||||
uint8_t recv_seq;
|
||||
uint8_t sec_mode;
|
||||
uint8_t *aggr_buf;
|
||||
uint16_t total_len;
|
||||
uint16_t offset;
|
||||
} tBLUFI_ENV;
|
||||
|
||||
/* BLUFI protocol */
|
||||
struct blufi_hdr{
|
||||
uint8_t type;
|
||||
uint8_t fc;
|
||||
uint8_t seq;
|
||||
uint8_t data_len;
|
||||
uint8_t data[0];
|
||||
};
|
||||
typedef struct blufi_hdr blufi_hd_t;
|
||||
|
||||
struct blufi_frag_hdr {
|
||||
uint8_t type;
|
||||
uint8_t fc;
|
||||
uint8_t seq;
|
||||
uint8_t data_len;
|
||||
uint16_t total_len;
|
||||
uint8_t content[0];
|
||||
};
|
||||
typedef struct blufi_frag_hdr blufi_frag_hdr_t;
|
||||
|
||||
#if GATT_DYNAMIC_MEMORY == FALSE
|
||||
extern tBLUFI_ENV blufi_env;
|
||||
#else
|
||||
extern tBLUFI_ENV *blufi_env_ptr;
|
||||
#define blufi_env (*blufi_env_ptr)
|
||||
#endif
|
||||
|
||||
#define BLUFI_DATA_SEC_MODE_CHECK_MASK 0x01
|
||||
#define BLUFI_DATA_SEC_MODE_ENC_MASK 0x02
|
||||
#define BLUFI_CTRL_SEC_MODE_CHECK_MASK 0x10
|
||||
#define BLUFI_CTRL_SEC_MODE_ENC_MASK 0x20
|
||||
#define BLUFI_MAX_DATA_LEN 255
|
||||
|
||||
// packet type
|
||||
#define BLUFI_TYPE_MASK 0x03
|
||||
#define BLUFI_TYPE_SHIFT 0
|
||||
#define BLUFI_SUBTYPE_MASK 0xFC
|
||||
#define BLUFI_SUBTYPE_SHIFT 2
|
||||
|
||||
#define BLUFI_GET_TYPE(type) ((type) & BLUFI_TYPE_MASK)
|
||||
#define BLUFI_GET_SUBTYPE(type) (((type) & BLUFI_SUBTYPE_MASK) >>BLUFI_SUBTYPE_SHIFT)
|
||||
#define BLUFI_BUILD_TYPE(type, subtype) (((type) & BLUFI_TYPE_MASK) | ((subtype)<<BLUFI_SUBTYPE_SHIFT))
|
||||
|
||||
#define BLUFI_TYPE_CTRL 0x0
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_ACK 0x00
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE 0x01
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE 0x02
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP 0x03
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP 0x04
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS 0x05
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA 0x06
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION 0x07
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE 0x08
|
||||
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST 0x09
|
||||
|
||||
#define BLUFI_TYPE_DATA 0x1
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_NEG 0x00
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID 0x01
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_STA_SSID 0x02
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD 0x03
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID 0x04
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD 0x05
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM 0x06
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE 0x07
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL 0x08
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_USERNAME 0x09
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_CA 0x0a
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT 0x0b
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT 0x0c
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY 0x0d
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY 0x0e
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP 0x0f
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION 0x10
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST 0x11
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO 0x12
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA 0x13
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY 0x14
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON 0x15
|
||||
#define BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI 0x16
|
||||
#define BLUFI_TYPE_IS_CTRL(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_CTRL)
|
||||
#define BLUFI_TYPE_IS_DATA(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_DATA)
|
||||
|
||||
#define BLUFI_TYPE_IS_CTRL_ACK(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_ACK)
|
||||
#define BLUFI_TYPE_IS_CTRL_START_NEG(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_START_NEG)
|
||||
#define BLUFI_TYPE_IS_CTRL_STOP_NEG(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_STOP_NEG)
|
||||
#define BLUFI_TYPE_IS_CTRL_SET_WIFI_OPMODE(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE)
|
||||
#define BLUFI_TYPE_IS_CTRL_CONN_WIFI(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP)
|
||||
#define BLUFI_TYPE_IS_CTRL_DISCONN_WIFI(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP)
|
||||
#define BLUFI_TYPE_IS_CTRL_GET_WIFI_STATUS(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS)
|
||||
#define BLUFI_TYPE_IS_CTRL_DEAUTHENTICATE_STA(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA)
|
||||
#define BLUFI_TYPE_IS_CTRL_GET_VERSION(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION)
|
||||
|
||||
#define BLUFI_TYPE_IS_DATA_NEG(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_NEG)
|
||||
#define BLUFI_TYPE_IS_DATA_STA_BSSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID)
|
||||
#define BLUFI_TYPE_IS_DATA_STA_SSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_SSID)
|
||||
#define BLUFI_TYPE_IS_DATA_STA_PASSWD(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD)
|
||||
#define BLUFI_TYPE_IS_DATA_SOFTAP_SSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID)
|
||||
#define BLUFI_TYPE_IS_DATA_SOFTAP_PASSWD(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD)
|
||||
#define BLUFI_TYPE_IS_DATA_SOFTAP_MAX_CONN_NUM(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM)
|
||||
#define BLUFI_TYPE_IS_DATA_SOFTAP_AUTH_MODE(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE)
|
||||
#define BLUFI_TYPE_IS_DATA_SOFTAP_CHANNEL(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL)
|
||||
#define BLUFI_TYPE_IS_DATA_USERNAME(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_USERNAME)
|
||||
#define BLUFI_TYPE_IS_DATA_CA(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CA)
|
||||
#define BLUFI_TYPE_IS_DATA_CLEINT_CERT(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT)
|
||||
#define BLUFI_TYPE_IS_DATA_SERVER_CERT(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT)
|
||||
#define BLUFI_TYPE_IS_DATA_CLIENT_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY)
|
||||
#define BLUFI_TYPE_IS_DATA_SERVER_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY)
|
||||
#define BLUFI_TYPE_IS_DATA_ERROR_INFO(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO)
|
||||
|
||||
// packet frame control
|
||||
#define BLUFI_FC_ENC_MASK 0x01
|
||||
#define BLUFI_FC_CHECK_MASK 0x02
|
||||
#define BLUFI_FC_DIR_MASK 0x04
|
||||
#define BLUFI_FC_REQ_ACK_MASK 0x08
|
||||
#define BLUFI_FC_FRAG_MASK 0x10
|
||||
|
||||
#define BLUFI_FC_ENC 0x01
|
||||
#define BLUFI_FC_CHECK 0x02
|
||||
#define BLUFI_FC_DIR_P2E 0x00
|
||||
#define BLUFI_FC_DIR_E2P 0x04
|
||||
#define BLUFI_FC_REQ_ACK 0x08
|
||||
#define BLUFI_FC_FRAG 0x10
|
||||
|
||||
#define BLUFI_FC_IS_ENC(fc) ((fc) & BLUFI_FC_ENC_MASK)
|
||||
#define BLUFI_FC_IS_CHECK(fc) ((fc) & BLUFI_FC_CHECK_MASK)
|
||||
#define BLUFI_FC_IS_DIR_P2E(fc) ((fc) & BLUFI_FC_DIR_P2E_MASK)
|
||||
#define BLUFI_FC_IS_DIR_E2P(fc) (!((fc) & BLUFI_DIR_P2E_MASK))
|
||||
#define BLUFI_FC_IS_REQ_ACK(fc) ((fc) & BLUFI_FC_REQ_ACK_MASK)
|
||||
#define BLUFI_FC_IS_FRAG(fc) ((fc) & BLUFI_FC_FRAG_MASK)
|
||||
|
||||
/* default GATT MTU size over LE link
|
||||
*/
|
||||
#define GATT_DEF_BLE_MTU_SIZE 23
|
||||
/* BLUFI HEADER + TOTAL(REMAIN) LENGTH + CRC + L2CAP RESERVED */
|
||||
#define BLUFI_MTU_RESERVED_SIZE (sizeof(struct blufi_hdr) + 2 + 2 + 3)
|
||||
#define BLUFI_FRAG_DATA_DEFAULT_LEN (GATT_DEF_BLE_MTU_SIZE - BLUFI_MTU_RESERVED_SIZE)
|
||||
|
||||
//function declare
|
||||
void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len);
|
||||
|
||||
void btc_blufi_send_encap(uint8_t type, uint8_t *data, int data_len);
|
||||
|
||||
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks);
|
||||
|
||||
void btc_blufi_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
|
||||
void btc_blufi_cb_deep_free(btc_msg_t *msg);
|
||||
|
||||
#endif /* __BLUFI_INT_H__ */
|
||||
#endif ///BLUFI_INCLUDED == TRUE
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_BLUFI_H__
|
||||
#define __ESP_BLUFI_H__
|
||||
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "nimble/ble.h"
|
||||
#include "host/ble_gap.h"
|
||||
#include "modlog/modlog.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "esp_gap_ble_api.h"
|
||||
#endif
|
||||
|
||||
#define BLUFI_APP_UUID 0xFFFF
|
||||
#define BLUFI_DEVICE_NAME "BLUFI_DEVICE"
|
||||
|
||||
#ifdef CONFIG_BT_NIMBLE_ENABLED
|
||||
struct ble_hs_cfg;
|
||||
struct ble_gatt_register_ctxt;
|
||||
struct gatt_value {
|
||||
struct os_mbuf *buf;
|
||||
uint16_t val_handle;
|
||||
uint8_t type;
|
||||
void *ptr;
|
||||
};
|
||||
#define SERVER_MAX_VALUES 3
|
||||
#define MAX_VAL_SIZE 512
|
||||
extern struct gatt_value gatt_values[SERVER_MAX_VALUES];
|
||||
/* GATT server callback */
|
||||
void esp_blufi_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
|
||||
|
||||
/* Initialise gatt server */
|
||||
int esp_blufi_gatt_svr_init(void);
|
||||
void esp_blufi_btc_init(void);
|
||||
void esp_blufi_btc_deinit(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
/**
|
||||
* @brief Close a connection a remote device.
|
||||
*
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @param[in] conn_id: connection ID to be closed.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_close(uint8_t gatts_if, uint16_t conn_id);
|
||||
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
|
||||
#endif
|
||||
|
||||
/* Initialise blufi profile */
|
||||
uint8_t esp_blufi_init(void);
|
||||
|
||||
/* start advertising */
|
||||
void bleprph_advertise(void);
|
||||
|
||||
/* send notifications */
|
||||
void esp_blufi_send_notify(void *arg);
|
||||
|
||||
/* Deinitialise blufi */
|
||||
void esp_blufi_deinit(void);
|
||||
/* disconnect */
|
||||
void esp_blufi_disconnect(void);
|
||||
|
||||
/* Stop advertisement */
|
||||
void esp_blufi_adv_stop(void);
|
||||
|
||||
/* Start advertisement */
|
||||
void esp_blufi_adv_start(void);
|
||||
|
||||
void esp_blufi_send_encap(void *arg);
|
||||
|
||||
#ifdef CONFIG_BT_NIMBLE_ENABLED
|
||||
/**
|
||||
* @brief Handle gap event for BluFi.
|
||||
* This function can be called inside custom use gap event handler.
|
||||
* It provide minimal event management for BluFi purpose.
|
||||
*
|
||||
* @param[in] event The type of event being signalled.
|
||||
* @param[in] arg Application-specified argument. Currently unused
|
||||
* @return int 0 in case of success.
|
||||
* Other in case of failure.
|
||||
*/
|
||||
int esp_blufi_handle_gap_events(struct ble_gap_event *event, void *arg);
|
||||
#endif
|
||||
|
||||
#endif/* _ESP_BLUFI_ */
|
||||
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "blufi_int.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_err.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "esp_blufi.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "console/console.h"
|
||||
|
||||
/*nimBLE Host*/
|
||||
#include "nimble/nimble_port.h"
|
||||
#include "nimble/nimble_port_freertos.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/util/util.h"
|
||||
#include "host/ble_uuid.h"
|
||||
#include "host/ble_gatt.h"
|
||||
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
#include "services/gatt/ble_svc_gatt.h"
|
||||
|
||||
#if (BLUFI_INCLUDED == TRUE)
|
||||
|
||||
static uint8_t own_addr_type;
|
||||
|
||||
struct gatt_value gatt_values[SERVER_MAX_VALUES];
|
||||
const static char *TAG = "BLUFI_EXAMPLE";
|
||||
|
||||
enum {
|
||||
GATT_VALUE_TYPE_CHR,
|
||||
GATT_VALUE_TYPE_DSC,
|
||||
};
|
||||
|
||||
static int gatt_svr_access_cb(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt,
|
||||
void *arg);
|
||||
|
||||
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
|
||||
{
|
||||
/*** Service: Blufi */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = BLE_UUID16_DECLARE(BLUFI_SERVICE_UUID),
|
||||
.characteristics = (struct ble_gatt_chr_def[])
|
||||
{ {
|
||||
/*** Characteristic: P2E */
|
||||
.uuid = BLE_UUID16_DECLARE(BLUFI_CHAR_P2E_UUID),
|
||||
.access_cb = gatt_svr_access_cb,
|
||||
.flags = BLE_GATT_CHR_F_WRITE,
|
||||
.arg = &gatt_values[0],
|
||||
.val_handle = &gatt_values[0].val_handle,
|
||||
}, {
|
||||
/*** Characteristic: E2P */
|
||||
.uuid = BLE_UUID16_DECLARE(BLUFI_CHAR_E2P_UUID),
|
||||
.access_cb = gatt_svr_access_cb,
|
||||
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY,
|
||||
.arg = &gatt_values[1],
|
||||
.val_handle = &gatt_values[1].val_handle,
|
||||
}, {
|
||||
0, /* No more characteristics in this service. */
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
0, /* No more services. */
|
||||
},
|
||||
};
|
||||
|
||||
void esp_blufi_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
|
||||
{
|
||||
char buf[BLE_UUID_STR_LEN];
|
||||
switch (ctxt->op) {
|
||||
case BLE_GATT_REGISTER_OP_SVC:
|
||||
ESP_LOGI(TAG, "registered service %s with handle=%d",
|
||||
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
|
||||
ctxt->svc.handle);
|
||||
break;
|
||||
|
||||
case BLE_GATT_REGISTER_OP_CHR:
|
||||
ESP_LOGI(TAG, "registering characteristic %s with "
|
||||
"def_handle=%d val_handle=%d\n",
|
||||
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
|
||||
ctxt->chr.def_handle,
|
||||
ctxt->chr.val_handle);
|
||||
break;
|
||||
|
||||
case BLE_GATT_REGISTER_OP_DSC:
|
||||
ESP_LOGI(TAG, "registering descriptor %s with handle=%d",
|
||||
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
|
||||
ctxt->dsc.handle);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t write_value(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt,
|
||||
void *arg)
|
||||
{
|
||||
struct gatt_value *value = (struct gatt_value *)arg;
|
||||
uint16_t len;
|
||||
int rc;
|
||||
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
|
||||
if (ctxt->chr->flags & BLE_GATT_CHR_F_WRITE_AUTHOR) {
|
||||
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR;
|
||||
}
|
||||
} else {
|
||||
if (ctxt->dsc->att_flags & BLE_ATT_F_WRITE_AUTHOR) {
|
||||
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR;
|
||||
}
|
||||
}
|
||||
|
||||
btc_blufi_recv_handler(&ctxt->om->om_data[0], ctxt->om->om_len);
|
||||
rc = ble_hs_mbuf_to_flat(ctxt->om, value->buf->om_data,
|
||||
value->buf->om_len, &len);
|
||||
if (rc != 0) {
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
/* Maximum attribute value size is 512 bytes */
|
||||
assert(value->buf->om_len < MAX_VAL_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t read_value(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt,
|
||||
void *arg)
|
||||
{
|
||||
const struct gatt_value *value = (const struct gatt_value *) arg;
|
||||
char str[BLE_UUID_STR_LEN];
|
||||
int rc;
|
||||
|
||||
memset(str, '\0', sizeof(str));
|
||||
|
||||
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
|
||||
if (ctxt->chr->flags & BLE_GATT_CHR_F_READ_AUTHOR) {
|
||||
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR;
|
||||
}
|
||||
|
||||
ble_uuid_to_str(ctxt->chr->uuid, str);
|
||||
} else {
|
||||
if (ctxt->dsc->att_flags & BLE_ATT_F_READ_AUTHOR) {
|
||||
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR;
|
||||
}
|
||||
|
||||
ble_uuid_to_str(ctxt->dsc->uuid, str);
|
||||
}
|
||||
|
||||
rc = os_mbuf_append(ctxt->om, value->buf->om_data, value->buf->om_len);
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
static int gatt_svr_access_cb(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt,
|
||||
void *arg)
|
||||
{
|
||||
switch (ctxt->op) {
|
||||
case BLE_GATT_ACCESS_OP_READ_CHR:
|
||||
return read_value(conn_handle, attr_handle,
|
||||
ctxt, arg);
|
||||
case BLE_GATT_ACCESS_OP_WRITE_CHR:
|
||||
return write_value(conn_handle, attr_handle,
|
||||
ctxt, arg);
|
||||
default:
|
||||
assert(0);
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
/* Unknown characteristic; the nimble stack should not have called this
|
||||
* function.
|
||||
*/
|
||||
assert(0);
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
static void init_gatt_values(void)
|
||||
{
|
||||
int i = 0;
|
||||
const struct ble_gatt_svc_def *svc;
|
||||
const struct ble_gatt_chr_def *chr;
|
||||
const struct ble_gatt_dsc_def *dsc;
|
||||
|
||||
for (svc = gatt_svr_svcs; svc && svc->uuid; svc++) {
|
||||
for (chr = svc->characteristics; chr && chr->uuid; chr++) {
|
||||
assert(i < SERVER_MAX_VALUES);
|
||||
gatt_values[i].type = GATT_VALUE_TYPE_CHR;
|
||||
gatt_values[i].ptr = (void *)chr;
|
||||
gatt_values[i].buf = os_msys_get(0, 0);
|
||||
os_mbuf_extend(gatt_values[i].buf, 1);
|
||||
++i;
|
||||
|
||||
for (dsc = chr->descriptors; dsc && dsc->uuid; dsc++) {
|
||||
assert(i < SERVER_MAX_VALUES);
|
||||
gatt_values[i].type = GATT_VALUE_TYPE_DSC;
|
||||
gatt_values[i].ptr = (void *)dsc;
|
||||
gatt_values[i].buf = os_msys_get(0, 0);
|
||||
os_mbuf_extend(gatt_values[i].buf, 1);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int esp_blufi_gatt_svr_init(void)
|
||||
{
|
||||
int rc;
|
||||
ble_svc_gap_init();
|
||||
ble_svc_gatt_init();
|
||||
|
||||
rc = ble_gatts_count_cfg(gatt_svr_svcs);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_gatts_add_svcs(gatt_svr_svcs);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
init_gatt_values();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
esp_blufi_gap_event(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
struct ble_gap_conn_desc desc;
|
||||
int rc;
|
||||
|
||||
switch (event->type) {
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
/* A new connection was established or a connection attempt failed. */
|
||||
ESP_LOGI(TAG, "connection %s; status=%d",
|
||||
event->connect.status == 0 ? "established" : "failed",
|
||||
event->connect.status);
|
||||
if (event->connect.status == 0) {
|
||||
|
||||
blufi_env.is_connected = true;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_BLE_CONNECT;
|
||||
|
||||
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||
assert(rc == 0);
|
||||
memcpy(param.connect.remote_bda, desc.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN);
|
||||
|
||||
param.connect.conn_id = event->connect.conn_handle;
|
||||
/* save connection handle */
|
||||
blufi_env.conn_id = event->connect.conn_handle;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
}
|
||||
if (event->connect.status != 0) {
|
||||
/* Connection failed; resume advertising. */
|
||||
esp_blufi_adv_start();
|
||||
}
|
||||
return 0;
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
ESP_LOGI(TAG, "disconnect; reason=%d", event->disconnect.reason);
|
||||
memcpy(blufi_env.remote_bda, event->disconnect.conn.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN);
|
||||
blufi_env.is_connected = false;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
blufi_env.sec_mode = 0x0;
|
||||
blufi_env.offset = 0;
|
||||
|
||||
if (blufi_env.aggr_buf != NULL) {
|
||||
osi_free(blufi_env.aggr_buf);
|
||||
blufi_env.aggr_buf = NULL;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_BLE_DISCONNECT;
|
||||
memcpy(param.disconnect.remote_bda, event->disconnect.conn.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
|
||||
return 0;
|
||||
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||
/* The central has updated the connection parameters. */
|
||||
ESP_LOGI(TAG, "connection updated; status=%d",
|
||||
event->conn_update.status);
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||
ESP_LOGI(TAG, "advertise complete; reason=%d",
|
||||
event->adv_complete.reason);
|
||||
esp_blufi_adv_start();
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_SUBSCRIBE:
|
||||
ESP_LOGI(TAG, "subscribe event; conn_handle=%d attr_handle=%d "
|
||||
"reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
|
||||
event->subscribe.conn_handle,
|
||||
event->subscribe.attr_handle,
|
||||
event->subscribe.reason,
|
||||
event->subscribe.prev_notify,
|
||||
event->subscribe.cur_notify,
|
||||
event->subscribe.prev_indicate,
|
||||
event->subscribe.cur_indicate);
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_MTU:
|
||||
ESP_LOGI(TAG, "mtu update event; conn_handle=%d cid=%d mtu=%d",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.channel_id,
|
||||
event->mtu.value);
|
||||
blufi_env.frag_size = (event->mtu.value < BLUFI_MAX_DATA_LEN ? event->mtu.value : BLUFI_MAX_DATA_LEN) - BLUFI_MTU_RESERVED_SIZE;
|
||||
return 0;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void esp_blufi_adv_start(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ble_hs_util_ensure_addr(0);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Figure out address to use while advertising (no privacy for now) */
|
||||
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||
if (rc != 0) {
|
||||
ESP_LOGI(TAG, "error determining address type; rc=%d ", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Printing ADDR */
|
||||
uint8_t addr_val[6] = {0};
|
||||
rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL);
|
||||
|
||||
/* Begin advertising. */
|
||||
struct ble_gap_adv_params adv_params;
|
||||
struct ble_hs_adv_fields fields;
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* Set the advertisement data included in our advertisements:
|
||||
* o Flags (indicates advertisement type and other general info).
|
||||
* o Advertising tx power.
|
||||
* o Device name.
|
||||
* o 16-bit service UUIDs (alert notifications).
|
||||
*/
|
||||
|
||||
memset(&fields, 0, sizeof fields);
|
||||
|
||||
/* Advertise two flags:
|
||||
* o Discoverability in forthcoming advertisement (general)
|
||||
* o BLE-only (BR/EDR unsupported).
|
||||
*/
|
||||
fields.flags = BLE_HS_ADV_F_DISC_GEN |
|
||||
BLE_HS_ADV_F_BREDR_UNSUP;
|
||||
|
||||
/* Indicate that the TX power level field should be included; have the
|
||||
* stack fill this value automatically. This is done by assigning the
|
||||
* special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
|
||||
*/
|
||||
fields.tx_pwr_lvl_is_present = 1;
|
||||
fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
||||
|
||||
name = ble_svc_gap_device_name();
|
||||
fields.name = (uint8_t *)name;
|
||||
fields.name_len = strlen(name);
|
||||
fields.name_is_complete = 1;
|
||||
|
||||
fields.uuids16 = (ble_uuid16_t[]) {
|
||||
BLE_UUID16_INIT(BLUFI_APP_UUID)
|
||||
};
|
||||
fields.num_uuids16 = 1;
|
||||
fields.uuids16_is_complete = 1;
|
||||
rc = ble_gap_adv_set_fields(&fields);
|
||||
if (rc != 0) {
|
||||
ESP_LOGE(TAG, "error setting advertisement data; rc=%d", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin advertising. */
|
||||
memset(&adv_params, 0, sizeof adv_params);
|
||||
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||
rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER,
|
||||
&adv_params, esp_blufi_gap_event, NULL);
|
||||
if (rc != 0) {
|
||||
ESP_LOGE(TAG, "error enabling advertisement; rc=%d", rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t esp_blufi_init(void)
|
||||
{
|
||||
blufi_env.enabled = true;
|
||||
esp_blufi_cb_param_t param;
|
||||
param.init_finish.state = ESP_BLUFI_INIT_OK;
|
||||
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_INIT_FINISH, ¶m);
|
||||
return ESP_BLUFI_ERROR;
|
||||
}
|
||||
|
||||
void esp_blufi_deinit(void)
|
||||
{
|
||||
blufi_env.enabled = false;
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_DEINIT_FINISH;
|
||||
param.deinit_finish.state = ESP_BLUFI_DEINIT_OK;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
}
|
||||
|
||||
void esp_blufi_send_notify(void *arg)
|
||||
{
|
||||
struct pkt_info *pkts = (struct pkt_info *) arg;
|
||||
struct os_mbuf *om;
|
||||
om = ble_hs_mbuf_from_flat(pkts->pkt, pkts->pkt_len);
|
||||
if (om == NULL) {
|
||||
ESP_LOGE(TAG, "Error in allocating memory");
|
||||
return;
|
||||
}
|
||||
int rc = 0;
|
||||
rc = ble_gatts_notify_custom(blufi_env.conn_id, gatt_values[1].val_handle, om);
|
||||
if (rc != 0) {
|
||||
ESP_LOGE(TAG, "Error in sending notification");
|
||||
}
|
||||
}
|
||||
|
||||
void esp_blufi_disconnect(void)
|
||||
{
|
||||
ble_gap_terminate(blufi_env.conn_id, BLE_ERR_REM_USER_CONN_TERM);
|
||||
}
|
||||
|
||||
void esp_blufi_adv_stop(void) {}
|
||||
|
||||
void esp_blufi_send_encap(void *arg)
|
||||
{
|
||||
struct blufi_hdr *hdr = (struct blufi_hdr *)arg;
|
||||
if (blufi_env.is_connected == false) {
|
||||
BTC_TRACE_WARNING("%s ble connection is broken\n", __func__);
|
||||
return;
|
||||
}
|
||||
btc_blufi_send_notify((uint8_t *)hdr,
|
||||
((hdr->fc & BLUFI_FC_CHECK) ?
|
||||
hdr->data_len + sizeof(struct blufi_hdr) + 2 :
|
||||
hdr->data_len + sizeof(struct blufi_hdr)));
|
||||
}
|
||||
|
||||
void esp_blufi_btc_init(void)
|
||||
{
|
||||
int rc;
|
||||
rc = btc_init();
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void esp_blufi_btc_deinit(void)
|
||||
{
|
||||
btc_deinit();
|
||||
}
|
||||
|
||||
int esp_blufi_handle_gap_events(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
struct ble_gap_conn_desc desc;
|
||||
int rc;
|
||||
|
||||
if (event != NULL) {
|
||||
switch (event->type) {
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
if (event->connect.status == 0) {
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
|
||||
blufi_env.is_connected = true;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
blufi_env.conn_id = event->connect.conn_handle;
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_BLE_CONNECT;
|
||||
|
||||
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||
assert(rc == 0);
|
||||
memcpy(param.connect.remote_bda, desc.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN);
|
||||
|
||||
param.connect.conn_id = event->connect.conn_handle;
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
}
|
||||
return 0;
|
||||
case BLE_GAP_EVENT_DISCONNECT: {
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
|
||||
blufi_env.is_connected = false;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
blufi_env.sec_mode = 0x0;
|
||||
blufi_env.offset = 0;
|
||||
|
||||
memcpy(blufi_env.remote_bda,
|
||||
event->disconnect.conn.peer_id_addr.val,
|
||||
ESP_BLUFI_BD_ADDR_LEN);
|
||||
|
||||
if (blufi_env.aggr_buf != NULL) {
|
||||
osi_free(blufi_env.aggr_buf);
|
||||
blufi_env.aggr_buf = NULL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = ESP_BLUFI_EVENT_BLE_DISCONNECT;
|
||||
memcpy(param.disconnect.remote_bda,
|
||||
event->disconnect.conn.peer_id_addr.val,
|
||||
ESP_BLUFI_BD_ADDR_LEN);
|
||||
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case BLE_GAP_EVENT_MTU:
|
||||
blufi_env.frag_size = (event->mtu.value < BLUFI_MAX_DATA_LEN ? event->mtu.value :
|
||||
BLUFI_MAX_DATA_LEN) - BLUFI_MTU_RESERVED_SIZE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __BTC_BLUFI_PRF_H__
|
||||
#define __BTC_BLUFI_PRF_H__
|
||||
|
||||
#include "blufi_int.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "stack/gatt_api.h"
|
||||
#define ESP_BLUFI_ERROR GATT_ERROR
|
||||
#define ESP_BLUFI_SUCCESS GATT_SUCCESS
|
||||
#else
|
||||
#define ESP_BLUFI_ERROR 0x85
|
||||
#define ESP_BLUFI_SUCCESS 0x00
|
||||
#endif
|
||||
|
||||
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */
|
||||
//define the blufi serivce uuid
|
||||
#define BLUFI_SERVICE_UUID 0xFFFF
|
||||
//define the blufi Char uuid (PHONE to ESP32)
|
||||
#define BLUFI_CHAR_P2E_UUID 0xFF01
|
||||
//define the blufi Char uuid (ESP32 to PHONE)
|
||||
#define BLUFI_CHAR_E2P_UUID 0xFF02
|
||||
//define the blufi Descriptor uuid (ESP32 to PHONE)
|
||||
#define BLUFI_DESCR_E2P_UUID GATT_UUID_CHAR_CLIENT_CONFIG
|
||||
//define the blufi APP ID
|
||||
#define BLUFI_APP_UUID 0xFFFF
|
||||
|
||||
#define BLUFI_HDL_NUM 6
|
||||
|
||||
struct pkt_info{
|
||||
uint8_t *pkt;
|
||||
int pkt_len;
|
||||
};
|
||||
|
||||
static const tBT_UUID blufi_srvc_uuid = {LEN_UUID_16, {BLUFI_SERVICE_UUID}};
|
||||
static const tBT_UUID blufi_char_uuid_p2e = {LEN_UUID_16, {BLUFI_CHAR_P2E_UUID}};
|
||||
static const tBT_UUID blufi_char_uuid_e2p = {LEN_UUID_16, {BLUFI_CHAR_E2P_UUID}};
|
||||
static const tBT_UUID blufi_descr_uuid_e2p = {LEN_UUID_16, {BLUFI_DESCR_E2P_UUID}};
|
||||
static const tBT_UUID blufi_app_uuid = {LEN_UUID_16, {BLUFI_APP_UUID}};
|
||||
|
||||
typedef enum {
|
||||
BTC_BLUFI_ACT_INIT = 0,
|
||||
BTC_BLUFI_ACT_DEINIT,
|
||||
BTC_BLUFI_ACT_SEND_CFG_REPORT,
|
||||
BTC_BLUFI_ACT_SEND_WIFI_LIST,
|
||||
BTC_BLUFI_ACT_SEND_ERR_INFO,
|
||||
BTC_BLUFI_ACT_SEND_CUSTOM_DATA,
|
||||
} btc_blufi_act_t;
|
||||
|
||||
typedef union {
|
||||
struct blufi_cfg_report {
|
||||
wifi_mode_t opmode;
|
||||
esp_blufi_sta_conn_state_t sta_conn_state;
|
||||
uint8_t softap_conn_num;
|
||||
esp_blufi_extra_info_t *extra_info;
|
||||
int extra_info_len;
|
||||
} wifi_conn_report;
|
||||
/*
|
||||
BTC_BLUFI_ACT_SEND_WIFI_LIST
|
||||
*/
|
||||
struct blufi_wifi_list {
|
||||
uint16_t apCount;
|
||||
esp_blufi_ap_record_t *list;
|
||||
} wifi_list;
|
||||
/*
|
||||
BTC_BLUFI_ACT_SEND_ERR_INFO
|
||||
*/
|
||||
struct blufi_error_infor {
|
||||
esp_blufi_error_state_t state;
|
||||
} blufi_err_infor;
|
||||
/*
|
||||
BTC_BLUFI_ACT_SEND_CUSTOM_DATA
|
||||
*/
|
||||
struct blufi_custom_data {
|
||||
uint8_t *data;
|
||||
uint32_t data_len;
|
||||
} custom_data;
|
||||
} btc_blufi_args_t;
|
||||
|
||||
void btc_blufi_cb_to_app(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
|
||||
void btc_blufi_cb_handler(btc_msg_t *msg);
|
||||
void btc_blufi_call_handler(btc_msg_t *msg);
|
||||
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks);
|
||||
|
||||
void btc_blufi_recv_handler(uint8_t *data, int len);
|
||||
void btc_blufi_send_notify(uint8_t *pkt, int pkt_len);
|
||||
void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
void btc_blufi_call_deep_free(btc_msg_t *msg);
|
||||
|
||||
uint16_t btc_blufi_get_version(void);
|
||||
|
||||
#endif /* __BTC_BLUFI_PRF_H__ */
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BT_COMMON_H_
|
||||
#define _BT_COMMON_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include "bt_user_config.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
|
||||
|
||||
#if (UC_BT_BLUFI_ENABLE)
|
||||
#define BLUFI_INCLUDED TRUE
|
||||
#else
|
||||
#define BLUFI_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#define ESP_BLE_HOST_STATUS_ENABLED ESP_BLUEDROID_STATUS_ENABLED
|
||||
#define ESP_BLE_HOST_STATUS_CHECK(status) ESP_BLUEDROID_STATUS_CHECK(status)
|
||||
#else
|
||||
#define ESP_BLE_HOST_STATUS_ENABLED 0
|
||||
#define ESP_BLE_HOST_STATUS_CHECK(status) do {} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef BT_QUEUE_CONGEST_SIZE
|
||||
#define BT_QUEUE_CONGEST_SIZE 40
|
||||
#endif
|
||||
|
||||
#define BTC_INITIAL_TRACE_LEVEL UC_BT_LOG_BTC_TRACE_LEVEL
|
||||
#define OSI_INITIAL_TRACE_LEVEL UC_BT_LOG_OSI_TRACE_LEVEL
|
||||
#define BLUFI_INITIAL_TRACE_LEVEL UC_BT_LOG_BLUFI_TRACE_LEVEL
|
||||
|
||||
#if UC_BT_BLE_DYNAMIC_ENV_MEMORY
|
||||
#define BT_BLE_DYNAMIC_ENV_MEMORY TRUE
|
||||
#define BTC_DYNAMIC_MEMORY TRUE
|
||||
#else
|
||||
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
||||
#define BTC_DYNAMIC_MEMORY FALSE
|
||||
#endif
|
||||
|
||||
#if UC_BT_BLUEDROID_MEM_DEBUG
|
||||
#define HEAP_MEMORY_DEBUG TRUE
|
||||
#else
|
||||
#define HEAP_MEMORY_DEBUG FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BT_BLE_DYNAMIC_ENV_MEMORY
|
||||
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
||||
#endif
|
||||
|
||||
/* OS Configuration from User config (eg: sdkconfig) */
|
||||
#define TASK_PINNED_TO_CORE UC_TASK_PINNED_TO_CORE
|
||||
#define BT_TASK_MAX_PRIORITIES configMAX_PRIORITIES
|
||||
#define BT_BTC_TASK_STACK_SIZE UC_BTC_TASK_STACK_SIZE
|
||||
|
||||
/* Define trace levels */
|
||||
#define BT_TRACE_LEVEL_NONE UC_TRACE_LEVEL_NONE /* No trace messages to be generated */
|
||||
#define BT_TRACE_LEVEL_ERROR UC_TRACE_LEVEL_ERROR /* Error condition trace messages */
|
||||
#define BT_TRACE_LEVEL_WARNING UC_TRACE_LEVEL_WARNING /* Warning condition trace messages */
|
||||
#define BT_TRACE_LEVEL_API UC_TRACE_LEVEL_API /* API traces */
|
||||
#define BT_TRACE_LEVEL_EVENT UC_TRACE_LEVEL_EVENT /* Debug messages for events */
|
||||
#define BT_TRACE_LEVEL_DEBUG UC_TRACE_LEVEL_DEBUG /* Full debug messages */
|
||||
#define BT_TRACE_LEVEL_VERBOSE UC_TRACE_LEVEL_VERBOSE /* Verbose debug messages */
|
||||
|
||||
#define MAX_TRACE_LEVEL UC_TRACE_LEVEL_VERBOSE
|
||||
|
||||
#ifndef LOG_LOCAL_LEVEL
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#define LOG_LOCAL_LEVEL UC_LOG_DEFAULT_LEVEL
|
||||
#else
|
||||
#define LOG_LOCAL_LEVEL UC_BOOTLOADER_LOG_LEVEL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Mapping between ESP_LOG_LEVEL and BT_TRACE_LEVEL
|
||||
#if (LOG_LOCAL_LEVEL >= 4)
|
||||
#define LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL+1)
|
||||
#else
|
||||
#define LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL
|
||||
#endif
|
||||
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#define BT_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_INITIAL_TRACE_LEVEL, LOG_LOCAL_LEVEL_MAPPING) >= BT_TRACE_LEVEL_##LEVEL)
|
||||
|
||||
#define BT_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||
#define BT_PRINT_W(tag, format, ...) {esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||
#define BT_PRINT_I(tag, format, ...) {esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||
#define BT_PRINT_D(tag, format, ...) {esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||
#define BT_PRINT_V(tag, format, ...) {esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
|
||||
|
||||
|
||||
#if !UC_BT_STACK_NO_LOG
|
||||
/* define traces for BTC */
|
||||
#define BTC_TRACE_ERROR(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTC, ERROR)) BT_PRINT_E("BT_BTC", fmt, ## args);}
|
||||
#define BTC_TRACE_WARNING(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTC, WARNING)) BT_PRINT_W("BT_BTC", fmt, ## args);}
|
||||
#define BTC_TRACE_API(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTC,API)) BT_PRINT_I("BT_BTC", fmt, ## args);}
|
||||
#define BTC_TRACE_EVENT(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTC,EVENT)) BT_PRINT_D("BT_BTC", fmt, ## args);}
|
||||
#define BTC_TRACE_DEBUG(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTC,DEBUG)) BT_PRINT_D("BT_BTC", fmt, ## args);}
|
||||
#define BTC_TRACE_VERBOSE(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BTC,VERBOSE)) BT_PRINT_V("BT_BTC", fmt, ## args);}
|
||||
|
||||
/* define traces for OSI */
|
||||
#define OSI_TRACE_ERROR(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(OSI, ERROR)) BT_PRINT_E("BT_OSI", fmt, ## args);}
|
||||
#define OSI_TRACE_WARNING(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(OSI, WARNING)) BT_PRINT_W("BT_OSI", fmt, ## args);}
|
||||
#define OSI_TRACE_API(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(OSI,API)) BT_PRINT_I("BT_OSI", fmt, ## args);}
|
||||
#define OSI_TRACE_EVENT(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(OSI,EVENT)) BT_PRINT_D("BT_OSI", fmt, ## args);}
|
||||
#define OSI_TRACE_DEBUG(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(OSI,DEBUG)) BT_PRINT_D("BT_OSI", fmt, ## args);}
|
||||
#define OSI_TRACE_VERBOSE(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(OSI,VERBOSE)) BT_PRINT_V("BT_OSI", fmt, ## args);}
|
||||
|
||||
/* define traces for BLUFI */
|
||||
#define BLUFI_TRACE_ERROR(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BLUFI, ERROR)) BT_PRINT_E("BT_BLUFI", fmt, ## args);}
|
||||
#define BLUFI_TRACE_WARNING(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BLUFI, WARNING)) BT_PRINT_W("BT_BLUFI", fmt, ## args);}
|
||||
#define BLUFI_TRACE_API(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BLUFI,API)) BT_PRINT_I("BT_BLUFI", fmt, ## args);}
|
||||
#define BLUFI_TRACE_EVENT(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BLUFI,EVENT)) BT_PRINT_D("BT_BLUFI", fmt, ## args);}
|
||||
#define BLUFI_TRACE_DEBUG(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BLUFI,DEBUG)) BT_PRINT_D("BT_BLUFI", fmt, ## args);}
|
||||
#define BLUFI_TRACE_VERBOSE(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BLUFI,VERBOSE)) BT_PRINT_V("BT_BLUFI", fmt, ## args);}
|
||||
|
||||
#else
|
||||
|
||||
/* define traces for BTC */
|
||||
#define BTC_TRACE_ERROR(fmt, args...)
|
||||
#define BTC_TRACE_WARNING(fmt, args...)
|
||||
#define BTC_TRACE_API(fmt, args...)
|
||||
#define BTC_TRACE_EVENT(fmt, args...)
|
||||
#define BTC_TRACE_DEBUG(fmt, args...)
|
||||
#define BTC_TRACE_VERBOSE(fmt, args...)
|
||||
|
||||
/* define traces for OSI */
|
||||
#define OSI_TRACE_ERROR(fmt, args...)
|
||||
#define OSI_TRACE_WARNING(fmt, args...)
|
||||
#define OSI_TRACE_API(fmt, args...)
|
||||
#define OSI_TRACE_EVENT(fmt, args...)
|
||||
#define OSI_TRACE_DEBUG(fmt, args...)
|
||||
#define OSI_TRACE_VERBOSE(fmt, args...)
|
||||
|
||||
/* define traces for BLUFI */
|
||||
#define BLUFI_TRACE_ERROR(fmt, args...)
|
||||
#define BLUFI_TRACE_WARNING(fmt, args...)
|
||||
#define BLUFI_TRACE_API(fmt, args...)
|
||||
#define BLUFI_TRACE_EVENT(fmt, args...)
|
||||
#define BLUFI_TRACE_DEBUG(fmt, args...)
|
||||
#define BLUFI_TRACE_VERBOSE(fmt, args...)
|
||||
|
||||
#endif
|
||||
|
||||
/** Bluetooth Error Status */
|
||||
/** We need to build on this */
|
||||
|
||||
/* relate to ESP_BT_STATUS_xxx in esp_bt_defs.h */
|
||||
typedef enum {
|
||||
BT_STATUS_SUCCESS = 0,
|
||||
BT_STATUS_FAIL,
|
||||
BT_STATUS_NOT_READY,
|
||||
BT_STATUS_NOMEM,
|
||||
BT_STATUS_BUSY,
|
||||
BT_STATUS_DONE, /* request already completed */
|
||||
BT_STATUS_UNSUPPORTED,
|
||||
BT_STATUS_PARM_INVALID,
|
||||
BT_STATUS_UNHANDLED,
|
||||
BT_STATUS_AUTH_FAILURE,
|
||||
BT_STATUS_RMT_DEV_DOWN,
|
||||
BT_STATUS_AUTH_REJECTED,
|
||||
BT_STATUS_INVALID_STATIC_RAND_ADDR,
|
||||
BT_STATUS_PENDING,
|
||||
BT_STATUS_UNACCEPT_CONN_INTERVAL,
|
||||
BT_STATUS_PARAM_OUT_OF_RANGE,
|
||||
BT_STATUS_TIMEOUT,
|
||||
BT_STATUS_MEMORY_FULL,
|
||||
BT_STATUS_EIR_TOO_LARGE,
|
||||
} bt_status_t;
|
||||
|
||||
typedef uint8_t UINT8;
|
||||
typedef uint16_t UINT16;
|
||||
typedef uint32_t UINT32;
|
||||
typedef uint64_t UINT64;
|
||||
typedef bool BOOLEAN;
|
||||
/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */
|
||||
#define MAX_UUID_SIZE 16
|
||||
|
||||
typedef struct {
|
||||
#define LEN_UUID_16 2
|
||||
#define LEN_UUID_32 4
|
||||
#define LEN_UUID_128 16
|
||||
|
||||
UINT16 len;
|
||||
|
||||
union {
|
||||
UINT16 uuid16;
|
||||
UINT32 uuid32;
|
||||
UINT8 uuid128[MAX_UUID_SIZE];
|
||||
} uu;
|
||||
|
||||
} tBT_UUID;
|
||||
|
||||
/* Common Bluetooth field definitions */
|
||||
#define BD_ADDR_LEN 6 /* Device address length */
|
||||
typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */
|
||||
|
||||
#endif /* _BT_COMMON_H_ */
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __BT_USER_CONFIG_H__
|
||||
#define __BT_USER_CONFIG_H__
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define UC_TRACE_LEVEL_NONE 0 /* No trace messages to be generated */
|
||||
#define UC_TRACE_LEVEL_ERROR 1 /* Error condition trace messages */
|
||||
#define UC_TRACE_LEVEL_WARNING 2 /* Warning condition trace messages */
|
||||
#define UC_TRACE_LEVEL_API 3 /* API traces */
|
||||
#define UC_TRACE_LEVEL_EVENT 4 /* Debug messages for events */
|
||||
#define UC_TRACE_LEVEL_DEBUG 5 /* Full debug messages */
|
||||
#define UC_TRACE_LEVEL_VERBOSE 6 /* Verbose debug messages */
|
||||
|
||||
//DYNAMIC ENV ALLOCATOR
|
||||
#ifdef CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY
|
||||
#define UC_BT_BLE_DYNAMIC_ENV_MEMORY CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY
|
||||
#else
|
||||
#define UC_BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_STACK_NO_LOG
|
||||
#define UC_BT_STACK_NO_LOG CONFIG_BT_STACK_NO_LOG
|
||||
#else
|
||||
#define UC_BT_STACK_NO_LOG FALSE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_CONTROLLER_ENABLED
|
||||
#define UC_BT_CONTROLLER_INCLUDED TRUE
|
||||
#else
|
||||
#define UC_BT_CONTROLLER_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
/**********************************************************
|
||||
* Thread/Task reference
|
||||
**********************************************************/
|
||||
#ifdef CONFIG_BT_BLUEDROID_PINNED_TO_CORE
|
||||
#define UC_TASK_PINNED_TO_CORE (CONFIG_BT_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY)
|
||||
#else
|
||||
#define UC_TASK_PINNED_TO_CORE (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_BTC_TASK_STACK_SIZE
|
||||
#define UC_BTC_TASK_STACK_SIZE CONFIG_BT_BTC_TASK_STACK_SIZE
|
||||
#else
|
||||
#define UC_BTC_TASK_STACK_SIZE 4096
|
||||
#endif
|
||||
|
||||
/**********************************************************
|
||||
* Trace reference
|
||||
**********************************************************/
|
||||
|
||||
#ifdef CONFIG_LOG_DEFAULT_LEVEL
|
||||
#define UC_LOG_DEFAULT_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#else
|
||||
#define UC_LOG_DEFAULT_LEVEL 3
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_LOG_LEVEL
|
||||
#define UC_BOOTLOADER_LOG_LEVEL CONFIG_BOOTLOADER_LOG_LEVEL
|
||||
#else
|
||||
#define UC_BOOTLOADER_LOG_LEVEL 3
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LOG_BTC_TRACE_LEVEL
|
||||
#define UC_BT_LOG_BTC_TRACE_LEVEL CONFIG_BT_LOG_BTC_TRACE_LEVEL
|
||||
#else
|
||||
#define UC_BT_LOG_BTC_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LOG_OSI_TRACE_LEVEL
|
||||
#define UC_BT_LOG_OSI_TRACE_LEVEL CONFIG_BT_LOG_OSI_TRACE_LEVEL
|
||||
#else
|
||||
#define UC_BT_LOG_OSI_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LOG_BLUFI_TRACE_LEVEL
|
||||
#define UC_BT_LOG_BLUFI_TRACE_LEVEL CONFIG_BT_LOG_BLUFI_TRACE_LEVEL
|
||||
#else
|
||||
#define UC_BT_LOG_BLUFI_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||
#endif
|
||||
|
||||
//BLUFI
|
||||
#if defined(CONFIG_BT_BLE_BLUFI_ENABLE) || defined(CONFIG_BT_NIMBLE_BLUFI_ENABLE)
|
||||
#define UC_BT_BLUFI_ENABLE TRUE
|
||||
#else
|
||||
#define UC_BT_BLUFI_ENABLE FALSE
|
||||
#endif
|
||||
|
||||
//MEMORY DEBUG
|
||||
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
|
||||
#define UC_BT_BLUEDROID_MEM_DEBUG TRUE
|
||||
#else
|
||||
#define UC_BT_BLUEDROID_MEM_DEBUG FALSE
|
||||
#endif
|
||||
|
||||
#endif /* __BT_USER_CONFIG_H__ */
|
||||
@@ -0,0 +1,331 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "osi/alarm.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/list.h"
|
||||
#include "esp_timer.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc/btc_alarm.h"
|
||||
#include "osi/mutex.h"
|
||||
#include "bt_common.h"
|
||||
|
||||
typedef struct alarm_t {
|
||||
/* timer id point to here */
|
||||
esp_timer_handle_t alarm_hdl;
|
||||
osi_alarm_callback_t cb;
|
||||
void *cb_data;
|
||||
int64_t deadline_us;
|
||||
} osi_alarm_t;
|
||||
|
||||
enum {
|
||||
ALARM_STATE_IDLE,
|
||||
ALARM_STATE_OPEN,
|
||||
};
|
||||
|
||||
static osi_mutex_t alarm_mutex;
|
||||
static int alarm_state;
|
||||
|
||||
#if (BT_BLE_DYNAMIC_ENV_MEMORY == FALSE)
|
||||
static struct alarm_t alarm_cbs[ALARM_CBS_NUM];
|
||||
#else
|
||||
static struct alarm_t *alarm_cbs;
|
||||
#endif
|
||||
|
||||
static osi_alarm_err_t alarm_free(osi_alarm_t *alarm);
|
||||
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic);
|
||||
|
||||
int osi_alarm_create_mux(void)
|
||||
{
|
||||
if (alarm_state != ALARM_STATE_IDLE) {
|
||||
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state);
|
||||
return -1;
|
||||
}
|
||||
osi_mutex_new(&alarm_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int osi_alarm_delete_mux(void)
|
||||
{
|
||||
if (alarm_state != ALARM_STATE_IDLE) {
|
||||
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state);
|
||||
return -1;
|
||||
}
|
||||
osi_mutex_free(&alarm_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void osi_alarm_init(void)
|
||||
{
|
||||
assert(alarm_mutex != NULL);
|
||||
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (alarm_state != ALARM_STATE_IDLE) {
|
||||
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state);
|
||||
goto end;
|
||||
}
|
||||
#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
|
||||
if ((alarm_cbs = (osi_alarm_t *)osi_malloc(sizeof(osi_alarm_t) * ALARM_CBS_NUM)) == NULL) {
|
||||
OSI_TRACE_ERROR("%s, malloc failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(alarm_cbs, 0x00, sizeof(osi_alarm_t) * ALARM_CBS_NUM);
|
||||
alarm_state = ALARM_STATE_OPEN;
|
||||
|
||||
end:
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
}
|
||||
|
||||
void osi_alarm_deinit(void)
|
||||
{
|
||||
assert(alarm_mutex != NULL);
|
||||
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (alarm_state != ALARM_STATE_OPEN) {
|
||||
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ALARM_CBS_NUM; i++) {
|
||||
if (alarm_cbs[i].alarm_hdl != NULL) {
|
||||
alarm_free(&alarm_cbs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE)
|
||||
osi_free(alarm_cbs);
|
||||
alarm_cbs = NULL;
|
||||
#endif
|
||||
|
||||
alarm_state = ALARM_STATE_IDLE;
|
||||
|
||||
end:
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
}
|
||||
|
||||
static struct alarm_t *alarm_cbs_lookfor_available(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ALARM_CBS_NUM; i++) {
|
||||
if (alarm_cbs[i].alarm_hdl == NULL) { //available
|
||||
OSI_TRACE_DEBUG("%s %d %p\n", __func__, i, &alarm_cbs[i]);
|
||||
return &alarm_cbs[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void alarm_cb_handler(struct alarm_t *alarm)
|
||||
{
|
||||
OSI_TRACE_DEBUG("TimerID %p\n", alarm);
|
||||
if (alarm_state != ALARM_STATE_OPEN) {
|
||||
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state);
|
||||
return;
|
||||
}
|
||||
btc_msg_t msg = {0};
|
||||
btc_alarm_args_t arg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_ALARM;
|
||||
arg.cb = alarm->cb;
|
||||
arg.cb_data = alarm->cb_data;
|
||||
btc_transfer_context(&msg, &arg, sizeof(btc_alarm_args_t), NULL, NULL);
|
||||
}
|
||||
|
||||
osi_alarm_t *osi_alarm_new(const char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire)
|
||||
{
|
||||
assert(alarm_mutex != NULL);
|
||||
|
||||
struct alarm_t *timer_id = NULL;
|
||||
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (alarm_state != ALARM_STATE_OPEN) {
|
||||
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||
timer_id = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
timer_id = alarm_cbs_lookfor_available();
|
||||
|
||||
if (!timer_id) {
|
||||
OSI_TRACE_ERROR("%s alarm_cbs exhausted\n", __func__);
|
||||
timer_id = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
esp_timer_create_args_t tca = {0};
|
||||
tca.callback = (esp_timer_cb_t)alarm_cb_handler;
|
||||
tca.arg = timer_id;
|
||||
tca.dispatch_method = ESP_TIMER_TASK;
|
||||
tca.name = alarm_name;
|
||||
|
||||
timer_id->cb = callback;
|
||||
timer_id->cb_data = data;
|
||||
timer_id->deadline_us = 0;
|
||||
|
||||
esp_err_t stat = esp_timer_create(&tca, &timer_id->alarm_hdl);
|
||||
if (stat != ESP_OK) {
|
||||
OSI_TRACE_ERROR("%s failed to create timer, err 0x%x\n", __func__, stat);
|
||||
timer_id = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
return timer_id;
|
||||
}
|
||||
|
||||
static osi_alarm_err_t alarm_free(osi_alarm_t *alarm)
|
||||
{
|
||||
if (!alarm || alarm->alarm_hdl == NULL) {
|
||||
OSI_TRACE_ERROR("%s null\n", __func__);
|
||||
return OSI_ALARM_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_timer_stop(alarm->alarm_hdl);
|
||||
esp_err_t stat = esp_timer_delete(alarm->alarm_hdl);
|
||||
if (stat != ESP_OK) {
|
||||
OSI_TRACE_ERROR("%s failed to delete timer, err 0x%x\n", __func__, stat);
|
||||
return OSI_ALARM_ERR_FAIL;
|
||||
}
|
||||
|
||||
memset(alarm, 0, sizeof(osi_alarm_t));
|
||||
return OSI_ALARM_ERR_PASS;
|
||||
}
|
||||
|
||||
void osi_alarm_free(osi_alarm_t *alarm)
|
||||
{
|
||||
assert(alarm_mutex != NULL);
|
||||
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (alarm_state != ALARM_STATE_OPEN) {
|
||||
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||
goto end;
|
||||
}
|
||||
alarm_free(alarm);
|
||||
|
||||
end:
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic)
|
||||
{
|
||||
assert(alarm_mutex != NULL);
|
||||
|
||||
osi_alarm_err_t ret = OSI_ALARM_ERR_PASS;
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (alarm_state != ALARM_STATE_OPEN) {
|
||||
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||
ret = OSI_ALARM_ERR_INVALID_STATE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!alarm || alarm->alarm_hdl == NULL) {
|
||||
OSI_TRACE_ERROR("%s null\n", __func__);
|
||||
ret = OSI_ALARM_ERR_INVALID_ARG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
int64_t timeout_us = 1000 * (int64_t)timeout;
|
||||
esp_err_t stat;
|
||||
if (is_periodic) {
|
||||
stat = esp_timer_start_periodic(alarm->alarm_hdl, (uint64_t)timeout_us);
|
||||
} else {
|
||||
stat = esp_timer_start_once(alarm->alarm_hdl, (uint64_t)timeout_us);
|
||||
}
|
||||
if (stat != ESP_OK) {
|
||||
OSI_TRACE_ERROR("%s failed to start timer, err 0x%x\n", __func__, stat);
|
||||
ret = OSI_ALARM_ERR_FAIL;
|
||||
goto end;
|
||||
}
|
||||
alarm->deadline_us = is_periodic ? 0 : (timeout_us + esp_timer_get_time());
|
||||
|
||||
end:
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
|
||||
{
|
||||
return alarm_set(alarm, timeout, FALSE);
|
||||
}
|
||||
|
||||
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period)
|
||||
{
|
||||
return alarm_set(alarm, period, TRUE);
|
||||
}
|
||||
|
||||
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm)
|
||||
{
|
||||
int ret = OSI_ALARM_ERR_PASS;
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (alarm_state != ALARM_STATE_OPEN) {
|
||||
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||
ret = OSI_ALARM_ERR_INVALID_STATE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!alarm || alarm->alarm_hdl == NULL) {
|
||||
OSI_TRACE_ERROR("%s null\n", __func__);
|
||||
ret = OSI_ALARM_ERR_INVALID_ARG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
esp_err_t stat = esp_timer_stop(alarm->alarm_hdl);
|
||||
if (stat != ESP_OK) {
|
||||
OSI_TRACE_DEBUG("%s failed to stop timer, err 0x%x\n", __func__, stat);
|
||||
ret = OSI_ALARM_ERR_FAIL;
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm)
|
||||
{
|
||||
assert(alarm_mutex != NULL);
|
||||
int64_t dt_us = 0;
|
||||
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
dt_us = alarm->deadline_us - esp_timer_get_time();
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
|
||||
return (dt_us > 0) ? (period_ms_t)(dt_us / 1000) : 0;
|
||||
}
|
||||
|
||||
uint32_t osi_time_get_os_boottime_ms(void)
|
||||
{
|
||||
return (uint32_t)(esp_timer_get_time() / 1000);
|
||||
}
|
||||
|
||||
bool osi_alarm_is_active(osi_alarm_t *alarm)
|
||||
{
|
||||
assert(alarm != NULL);
|
||||
|
||||
if (alarm->alarm_hdl != NULL) {
|
||||
return esp_timer_is_active(alarm->alarm_hdl);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bt_common.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
extern void *pvPortZalloc(size_t size);
|
||||
extern void vPortFree(void *pv);
|
||||
|
||||
|
||||
#if HEAP_MEMORY_DEBUG
|
||||
|
||||
#define OSI_MEM_DBG_INFO_MAX 1024*3
|
||||
typedef struct {
|
||||
void *p;
|
||||
int size;
|
||||
const char *func;
|
||||
int line;
|
||||
} osi_mem_dbg_info_t;
|
||||
|
||||
static uint32_t mem_dbg_count = 0;
|
||||
static osi_mem_dbg_info_t mem_dbg_info[OSI_MEM_DBG_INFO_MAX];
|
||||
static uint32_t mem_dbg_current_size = 0;
|
||||
static uint32_t mem_dbg_max_size = 0;
|
||||
|
||||
#define OSI_MEM_DBG_MAX_SECTION_NUM 5
|
||||
typedef struct {
|
||||
bool used;
|
||||
uint32_t max_size;
|
||||
} osi_mem_dbg_max_size_section_t;
|
||||
static osi_mem_dbg_max_size_section_t mem_dbg_max_size_section[OSI_MEM_DBG_MAX_SECTION_NUM];
|
||||
|
||||
void osi_mem_dbg_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
mem_dbg_info[i].p = NULL;
|
||||
mem_dbg_info[i].size = 0;
|
||||
mem_dbg_info[i].func = NULL;
|
||||
mem_dbg_info[i].line = 0;
|
||||
}
|
||||
mem_dbg_count = 0;
|
||||
mem_dbg_current_size = 0;
|
||||
mem_dbg_max_size = 0;
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||
mem_dbg_max_size_section[i].used = false;
|
||||
mem_dbg_max_size_section[i].max_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void osi_mem_dbg_record(void *p, int size, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p || size == 0) {
|
||||
OSI_TRACE_ERROR("%s invalid !!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
if (mem_dbg_info[i].p == NULL) {
|
||||
mem_dbg_info[i].p = p;
|
||||
mem_dbg_info[i].size = size;
|
||||
mem_dbg_info[i].func = func;
|
||||
mem_dbg_info[i].line = line;
|
||||
mem_dbg_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= OSI_MEM_DBG_INFO_MAX) {
|
||||
OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
|
||||
mem_dbg_current_size += size;
|
||||
if(mem_dbg_max_size < mem_dbg_current_size) {
|
||||
mem_dbg_max_size = mem_dbg_current_size;
|
||||
}
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){
|
||||
if (mem_dbg_max_size_section[i].used) {
|
||||
if(mem_dbg_max_size_section[i].max_size < mem_dbg_current_size) {
|
||||
mem_dbg_max_size_section[i].max_size = mem_dbg_current_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void osi_mem_dbg_clean(void *p, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p) {
|
||||
OSI_TRACE_ERROR("%s invalid\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
if (mem_dbg_info[i].p == p) {
|
||||
mem_dbg_current_size -= mem_dbg_info[i].size;
|
||||
mem_dbg_info[i].p = NULL;
|
||||
mem_dbg_info[i].size = 0;
|
||||
mem_dbg_info[i].func = NULL;
|
||||
mem_dbg_info[i].line = 0;
|
||||
mem_dbg_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= OSI_MEM_DBG_INFO_MAX) {
|
||||
OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
}
|
||||
|
||||
void osi_mem_dbg_show(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
if (mem_dbg_info[i].p || mem_dbg_info[i].size != 0 ) {
|
||||
OSI_TRACE_ERROR("--> p %p, s %d, f %s, l %d\n", mem_dbg_info[i].p, mem_dbg_info[i].size, mem_dbg_info[i].func, mem_dbg_info[i].line);
|
||||
}
|
||||
}
|
||||
OSI_TRACE_ERROR("--> count %d\n", mem_dbg_count);
|
||||
OSI_TRACE_ERROR("--> size %dB\n--> max size %dB\n", mem_dbg_current_size, mem_dbg_max_size);
|
||||
}
|
||||
|
||||
uint32_t osi_mem_dbg_get_max_size(void)
|
||||
{
|
||||
return mem_dbg_max_size;
|
||||
}
|
||||
|
||||
uint32_t osi_mem_dbg_get_current_size(void)
|
||||
{
|
||||
return mem_dbg_current_size;
|
||||
}
|
||||
|
||||
void osi_men_dbg_set_section_start(uint8_t index)
|
||||
{
|
||||
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) {
|
||||
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mem_dbg_max_size_section[index].used) {
|
||||
OSI_TRACE_WARNING("This index(%d) has been started, restart it.\n", index);
|
||||
}
|
||||
|
||||
mem_dbg_max_size_section[index].used = true;
|
||||
mem_dbg_max_size_section[index].max_size = mem_dbg_current_size;
|
||||
}
|
||||
|
||||
void osi_men_dbg_set_section_end(uint8_t index)
|
||||
{
|
||||
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) {
|
||||
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mem_dbg_max_size_section[index].used) {
|
||||
OSI_TRACE_ERROR("This index(%d) has not been started.\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
mem_dbg_max_size_section[index].used = false;
|
||||
}
|
||||
|
||||
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index)
|
||||
{
|
||||
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM){
|
||||
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
|
||||
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mem_dbg_max_size_section[index].max_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *osi_strdup(const char *str)
|
||||
{
|
||||
size_t size = strlen(str) + 1; // + 1 for the null terminator
|
||||
char *new_string = (char *)osi_calloc(size);
|
||||
|
||||
if (!new_string) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(new_string, str, size);
|
||||
return new_string;
|
||||
}
|
||||
|
||||
void *osi_malloc_func(size_t size)
|
||||
{
|
||||
#if HEAP_MEMORY_DEBUG
|
||||
void *p;
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||
#else
|
||||
p = malloc(size);
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
||||
return p;
|
||||
#else
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||
#endif /* #if HEAP_MEMORY_DEBUG */
|
||||
}
|
||||
|
||||
void *osi_calloc_func(size_t size)
|
||||
{
|
||||
#if HEAP_MEMORY_DEBUG
|
||||
void *p;
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||
p = heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||
#else
|
||||
p = calloc(1, size);
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
||||
return p;
|
||||
#else
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||
return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
|
||||
#else
|
||||
return calloc(1, size);
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||
#endif /* #if HEAP_MEMORY_DEBUG */
|
||||
}
|
||||
|
||||
void osi_free_func(void *ptr)
|
||||
{
|
||||
#if HEAP_MEMORY_DEBUG
|
||||
osi_mem_dbg_clean(ptr, __func__, __LINE__);
|
||||
#endif
|
||||
free(ptr);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "bt_common.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/buffer.h"
|
||||
|
||||
struct buffer_t {
|
||||
buffer_t *root;
|
||||
size_t refcount;
|
||||
size_t length;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
buffer_t *buffer_new(size_t size)
|
||||
{
|
||||
assert(size > 0);
|
||||
|
||||
buffer_t *buffer = osi_malloc(sizeof(buffer_t) + size);
|
||||
if (!buffer) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate buffer of %zu bytes.", __func__, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer->root = buffer;
|
||||
buffer->refcount = 1;
|
||||
buffer->length = size;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
buffer_t *buffer_new_ref(const buffer_t *buf)
|
||||
{
|
||||
assert(buf != NULL);
|
||||
return buffer_new_slice(buf, buf->length);
|
||||
}
|
||||
|
||||
buffer_t *buffer_new_slice(const buffer_t *buf, size_t slice_size)
|
||||
{
|
||||
assert(buf != NULL);
|
||||
assert(slice_size > 0);
|
||||
assert(slice_size <= buf->length);
|
||||
|
||||
buffer_t *ret = osi_calloc(sizeof(buffer_t));
|
||||
if (!ret) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate new buffer for slice of length %zu.", __func__, slice_size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->root = buf->root;
|
||||
ret->refcount = SIZE_MAX;
|
||||
ret->length = slice_size;
|
||||
|
||||
++buf->root->refcount;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void buffer_free(buffer_t *buffer)
|
||||
{
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer->root != buffer) {
|
||||
// We're a leaf node. Delete the root node if we're the last referent.
|
||||
if (--buffer->root->refcount == 0) {
|
||||
osi_free(buffer->root);
|
||||
}
|
||||
osi_free(buffer);
|
||||
} else if (--buffer->refcount == 0) {
|
||||
// We're a root node. Roots are only deleted when their refcount goes to 0.
|
||||
osi_free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void *buffer_ptr(const buffer_t *buf)
|
||||
{
|
||||
assert(buf != NULL);
|
||||
return buf->root->data + buf->root->length - buf->length;
|
||||
}
|
||||
|
||||
size_t buffer_length(const buffer_t *buf)
|
||||
{
|
||||
assert(buf != NULL);
|
||||
return buf->length;
|
||||
}
|
||||
@@ -0,0 +1,740 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define LOG_TAG "bt_osi_config"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bt_common.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/config.h"
|
||||
#include "osi/list.h"
|
||||
|
||||
#define CONFIG_FILE_MAX_SIZE (1536)//1.5k
|
||||
#define CONFIG_FILE_DEFAULE_LENGTH (2048)
|
||||
#define CONFIG_KEY "bt_cfg_key"
|
||||
typedef struct {
|
||||
char *key;
|
||||
char *value;
|
||||
} entry_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
list_t *entries;
|
||||
} section_t;
|
||||
|
||||
struct config_t {
|
||||
list_t *sections;
|
||||
};
|
||||
|
||||
// Empty definition; this type is aliased to list_node_t.
|
||||
struct config_section_iter_t {};
|
||||
|
||||
static void config_parse(nvs_handle_t fp, config_t *config);
|
||||
|
||||
static section_t *section_new(const char *name);
|
||||
static void section_free(void *ptr);
|
||||
static section_t *section_find(const config_t *config, const char *section);
|
||||
|
||||
static entry_t *entry_new(const char *key, const char *value);
|
||||
static void entry_free(void *ptr);
|
||||
static entry_t *entry_find(const config_t *config, const char *section, const char *key);
|
||||
|
||||
config_t *config_new_empty(void)
|
||||
{
|
||||
config_t *config = osi_calloc(sizeof(config_t));
|
||||
if (!config) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate memory for config_t.\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
config->sections = list_new(section_free);
|
||||
if (!config->sections) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate list for sections.\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
error:;
|
||||
config_free(config);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config_t *config_new(const char *filename)
|
||||
{
|
||||
assert(filename != NULL);
|
||||
|
||||
config_t *config = config_new_empty();
|
||||
if (!config) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t err;
|
||||
nvs_handle_t fp;
|
||||
err = nvs_open(filename, NVS_READWRITE, &fp);
|
||||
if (err != ESP_OK) {
|
||||
if (err == ESP_ERR_NVS_NOT_INITIALIZED) {
|
||||
OSI_TRACE_ERROR("%s: NVS not initialized. "
|
||||
"Call nvs_flash_init before initializing bluetooth.", __func__);
|
||||
} else {
|
||||
OSI_TRACE_ERROR("%s unable to open NVS namespace '%s'\n", __func__, filename);
|
||||
}
|
||||
config_free(config);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config_parse(fp, config);
|
||||
nvs_close(fp);
|
||||
return config;
|
||||
}
|
||||
|
||||
void config_free(config_t *config)
|
||||
{
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_free(config->sections);
|
||||
osi_free(config);
|
||||
}
|
||||
|
||||
bool config_has_section(const config_t *config, const char *section)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
|
||||
return (section_find(config, section) != NULL);
|
||||
}
|
||||
|
||||
bool config_has_key(const config_t *config, const char *section, const char *key)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
return (entry_find(config, section, key) != NULL);
|
||||
}
|
||||
|
||||
bool config_has_key_in_section(config_t *config, const char *key, char *key_value)
|
||||
{
|
||||
OSI_TRACE_DEBUG("key = %s, value = %s", key, key_value);
|
||||
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
|
||||
const section_t *section = (const section_t *)list_node(node);
|
||||
|
||||
for (const list_node_t *node = list_begin(section->entries); node != list_end(section->entries); node = list_next(node)) {
|
||||
entry_t *entry = list_node(node);
|
||||
OSI_TRACE_DEBUG("entry->key = %s, entry->value = %s", entry->key, entry->value);
|
||||
if (!strcmp(entry->key, key) && !strcmp(entry->value, key_value)) {
|
||||
OSI_TRACE_DEBUG("%s, the irk aready in the flash.", __func__);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int config_get_int(const config_t *config, const char *section, const char *key, int def_value)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
entry_t *entry = entry_find(config, section, key);
|
||||
if (!entry) {
|
||||
return def_value;
|
||||
}
|
||||
|
||||
char *endptr;
|
||||
int ret = strtol(entry->value, &endptr, 0);
|
||||
return (*endptr == '\0') ? ret : def_value;
|
||||
}
|
||||
|
||||
bool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
entry_t *entry = entry_find(config, section, key);
|
||||
if (!entry) {
|
||||
return def_value;
|
||||
}
|
||||
|
||||
if (!strcmp(entry->value, "true")) {
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(entry->value, "false")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return def_value;
|
||||
}
|
||||
|
||||
const char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
entry_t *entry = entry_find(config, section, key);
|
||||
if (!entry) {
|
||||
return def_value;
|
||||
}
|
||||
|
||||
return entry->value;
|
||||
}
|
||||
|
||||
void config_set_int(config_t *config, const char *section, const char *key, int value)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
char value_str[32] = { 0 };
|
||||
sprintf(value_str, "%d", value);
|
||||
config_set_string(config, section, key, value_str, false);
|
||||
}
|
||||
|
||||
void config_set_bool(config_t *config, const char *section, const char *key, bool value)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
config_set_string(config, section, key, value ? "true" : "false", false);
|
||||
}
|
||||
|
||||
void config_set_string(config_t *config, const char *section, const char *key, const char *value, bool insert_back)
|
||||
{
|
||||
section_t *sec = section_find(config, section);
|
||||
if (!sec) {
|
||||
sec = section_new(section);
|
||||
if (insert_back) {
|
||||
list_append(config->sections, sec);
|
||||
} else {
|
||||
list_prepend(config->sections, sec);
|
||||
}
|
||||
}
|
||||
|
||||
for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) {
|
||||
entry_t *entry = list_node(node);
|
||||
if (!strcmp(entry->key, key)) {
|
||||
osi_free(entry->value);
|
||||
entry->value = osi_strdup(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entry_t *entry = entry_new(key, value);
|
||||
list_append(sec->entries, entry);
|
||||
}
|
||||
|
||||
bool config_remove_section(config_t *config, const char *section)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
|
||||
section_t *sec = section_find(config, section);
|
||||
if (!sec) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return list_remove(config->sections, sec);
|
||||
}
|
||||
|
||||
bool config_update_newest_section(config_t *config, const char *section)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
|
||||
list_node_t *first_node = list_begin(config->sections);
|
||||
if (first_node == NULL) {
|
||||
return false;
|
||||
}
|
||||
section_t *first_sec = list_node(first_node);
|
||||
if (strcmp(first_sec->name, section) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
|
||||
section_t *sec = list_node(node);
|
||||
if (strcmp(sec->name, section) == 0) {
|
||||
list_delete(config->sections, sec);
|
||||
list_prepend(config->sections, sec);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_remove_key(config_t *config, const char *section, const char *key)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(section != NULL);
|
||||
assert(key != NULL);
|
||||
bool ret;
|
||||
|
||||
section_t *sec = section_find(config, section);
|
||||
entry_t *entry = entry_find(config, section, key);
|
||||
if (!sec || !entry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = list_remove(sec->entries, entry);
|
||||
if (list_length(sec->entries) == 0) {
|
||||
OSI_TRACE_DEBUG("%s remove section name:%s",__func__, section);
|
||||
ret &= config_remove_section(config, section);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const config_section_node_t *config_section_begin(const config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
return (const config_section_node_t *)list_begin(config->sections);
|
||||
}
|
||||
|
||||
const config_section_node_t *config_section_end(const config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
return (const config_section_node_t *)list_end(config->sections);
|
||||
}
|
||||
|
||||
const config_section_node_t *config_section_next(const config_section_node_t *node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return (const config_section_node_t *)list_next((const list_node_t *)node);
|
||||
}
|
||||
|
||||
const char *config_section_name(const config_section_node_t *node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
const list_node_t *lnode = (const list_node_t *)node;
|
||||
const section_t *section = (const section_t *)list_node(lnode);
|
||||
return section->name;
|
||||
}
|
||||
|
||||
static int get_config_size(const config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
|
||||
int w_len = 0, total_size = 0;
|
||||
|
||||
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
|
||||
const section_t *section = (const section_t *)list_node(node);
|
||||
w_len = strlen(section->name) + strlen("[]\n");// format "[section->name]\n"
|
||||
total_size += w_len;
|
||||
|
||||
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) {
|
||||
const entry_t *entry = (const entry_t *)list_node(enode);
|
||||
w_len = strlen(entry->key) + strlen(entry->value) + strlen(" = \n");// format "entry->key = entry->value\n"
|
||||
total_size += w_len;
|
||||
}
|
||||
|
||||
// Only add a separating newline if there are more sections.
|
||||
if (list_next(node) != list_end(config->sections)) {
|
||||
total_size ++; //'\n'
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
total_size ++; //'\0'
|
||||
return total_size;
|
||||
}
|
||||
|
||||
static int get_config_size_from_flash(nvs_handle_t fp)
|
||||
{
|
||||
assert(fp != 0);
|
||||
|
||||
esp_err_t err;
|
||||
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||
char *keyname = osi_calloc(keyname_bufsz);
|
||||
if (!keyname){
|
||||
OSI_TRACE_ERROR("%s, malloc error\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
size_t length = CONFIG_FILE_DEFAULE_LENGTH;
|
||||
size_t total_length = 0;
|
||||
uint16_t i = 0;
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0);
|
||||
err = nvs_get_blob(fp, keyname, NULL, &length);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
osi_free(keyname);
|
||||
return 0;
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
OSI_TRACE_ERROR("%s, error %d\n", __func__, err);
|
||||
osi_free(keyname);
|
||||
return 0;
|
||||
}
|
||||
total_length += length;
|
||||
while (length == CONFIG_FILE_MAX_SIZE) {
|
||||
length = CONFIG_FILE_DEFAULE_LENGTH;
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, ++i);
|
||||
err = nvs_get_blob(fp, keyname, NULL, &length);
|
||||
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
OSI_TRACE_ERROR("%s, error %d\n", __func__, err);
|
||||
osi_free(keyname);
|
||||
return 0;
|
||||
}
|
||||
total_length += length;
|
||||
}
|
||||
osi_free(keyname);
|
||||
return total_length;
|
||||
}
|
||||
|
||||
bool config_save(const config_t *config, const char *filename)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(filename != NULL);
|
||||
assert(*filename != '\0');
|
||||
|
||||
esp_err_t err;
|
||||
int err_code = 0;
|
||||
nvs_handle_t fp;
|
||||
char *line = osi_calloc(1024);
|
||||
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||
char *keyname = osi_calloc(keyname_bufsz);
|
||||
int config_size = get_config_size(config);
|
||||
char *buf = osi_calloc(config_size);
|
||||
if (!line || !buf || !keyname) {
|
||||
err_code |= 0x01;
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = nvs_open(filename, NVS_READWRITE, &fp);
|
||||
if (err != ESP_OK) {
|
||||
if (err == ESP_ERR_NVS_NOT_INITIALIZED) {
|
||||
OSI_TRACE_ERROR("%s: NVS not initialized. "
|
||||
"Call nvs_flash_init before initializing bluetooth.", __func__);
|
||||
}
|
||||
err_code |= 0x02;
|
||||
goto error;
|
||||
}
|
||||
|
||||
int w_cnt, w_cnt_total = 0;
|
||||
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
|
||||
const section_t *section = (const section_t *)list_node(node);
|
||||
w_cnt = snprintf(line, 1024, "[%s]\n", section->name);
|
||||
if(w_cnt < 0) {
|
||||
OSI_TRACE_ERROR("snprintf error w_cnt %d.",w_cnt);
|
||||
err_code |= 0x10;
|
||||
goto error;
|
||||
}
|
||||
if(w_cnt_total + w_cnt > config_size) {
|
||||
OSI_TRACE_ERROR("%s, memcpy size (w_cnt + w_cnt_total = %d) is larger than buffer size (config_size = %d).", __func__, (w_cnt + w_cnt_total), config_size);
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
OSI_TRACE_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total);
|
||||
memcpy(buf + w_cnt_total, line, w_cnt);
|
||||
w_cnt_total += w_cnt;
|
||||
|
||||
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) {
|
||||
const entry_t *entry = (const entry_t *)list_node(enode);
|
||||
OSI_TRACE_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value);
|
||||
w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value);
|
||||
if(w_cnt < 0) {
|
||||
OSI_TRACE_ERROR("snprintf error w_cnt %d.",w_cnt);
|
||||
err_code |= 0x10;
|
||||
goto error;
|
||||
}
|
||||
if(w_cnt_total + w_cnt > config_size) {
|
||||
OSI_TRACE_ERROR("%s, memcpy size (w_cnt + w_cnt_total = %d) is larger than buffer size.(config_size = %d)", __func__, (w_cnt + w_cnt_total), config_size);
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
OSI_TRACE_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total);
|
||||
memcpy(buf + w_cnt_total, line, w_cnt);
|
||||
w_cnt_total += w_cnt;
|
||||
}
|
||||
|
||||
// Only add a separating newline if there are more sections.
|
||||
if (list_next(node) != list_end(config->sections)) {
|
||||
buf[w_cnt_total] = '\n';
|
||||
w_cnt_total += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[w_cnt_total] = '\0';
|
||||
if (w_cnt_total < CONFIG_FILE_MAX_SIZE) {
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0);
|
||||
err = nvs_set_blob(fp, keyname, buf, w_cnt_total);
|
||||
if (err != ESP_OK) {
|
||||
nvs_close(fp);
|
||||
err_code |= 0x04;
|
||||
goto error;
|
||||
}
|
||||
}else {
|
||||
int count = (w_cnt_total / CONFIG_FILE_MAX_SIZE);
|
||||
assert(count <= 0xFF);
|
||||
for (uint8_t i = 0; i <= count; i++)
|
||||
{
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, i);
|
||||
if (i == count) {
|
||||
err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, w_cnt_total - i*CONFIG_FILE_MAX_SIZE);
|
||||
OSI_TRACE_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, w_cnt_total - i*CONFIG_FILE_MAX_SIZE);
|
||||
}else {
|
||||
err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, CONFIG_FILE_MAX_SIZE);
|
||||
OSI_TRACE_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, CONFIG_FILE_MAX_SIZE);
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
nvs_close(fp);
|
||||
err_code |= 0x04;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = nvs_commit(fp);
|
||||
if (err != ESP_OK) {
|
||||
nvs_close(fp);
|
||||
err_code |= 0x08;
|
||||
goto error;
|
||||
}
|
||||
|
||||
nvs_close(fp);
|
||||
osi_free(line);
|
||||
osi_free(buf);
|
||||
osi_free(keyname);
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (buf) {
|
||||
osi_free(buf);
|
||||
}
|
||||
if (line) {
|
||||
osi_free(line);
|
||||
}
|
||||
if (keyname) {
|
||||
osi_free(keyname);
|
||||
}
|
||||
if (err_code) {
|
||||
OSI_TRACE_ERROR("%s, err_code: 0x%x\n", __func__, err_code);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static char *trim(char *str)
|
||||
{
|
||||
while (isspace((unsigned char)(*str))) {
|
||||
++str;
|
||||
}
|
||||
|
||||
if (!*str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
char *end_str = str + strlen(str) - 1;
|
||||
while (end_str > str && isspace((unsigned char)(*end_str))) {
|
||||
--end_str;
|
||||
}
|
||||
|
||||
end_str[1] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
static void config_parse(nvs_handle_t fp, config_t *config)
|
||||
{
|
||||
assert(fp != 0);
|
||||
assert(config != NULL);
|
||||
|
||||
esp_err_t err;
|
||||
int line_num = 0;
|
||||
int err_code = 0;
|
||||
uint16_t i = 0;
|
||||
size_t length = CONFIG_FILE_DEFAULE_LENGTH;
|
||||
size_t total_length = 0;
|
||||
char *line = osi_calloc(1024);
|
||||
char *section = osi_calloc(1024);
|
||||
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||
char *keyname = osi_calloc(keyname_bufsz);
|
||||
int buf_size = get_config_size_from_flash(fp);
|
||||
char *buf = NULL;
|
||||
|
||||
if(buf_size == 0) { //First use nvs
|
||||
goto error;
|
||||
}
|
||||
buf = osi_calloc(buf_size);
|
||||
if (!line || !section || !buf || !keyname) {
|
||||
err_code |= 0x01;
|
||||
goto error;
|
||||
}
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0);
|
||||
err = nvs_get_blob(fp, keyname, buf, &length);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
goto error;
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
err_code |= 0x02;
|
||||
goto error;
|
||||
}
|
||||
total_length += length;
|
||||
while (length == CONFIG_FILE_MAX_SIZE) {
|
||||
length = CONFIG_FILE_DEFAULE_LENGTH;
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, ++i);
|
||||
err = nvs_get_blob(fp, keyname, buf + CONFIG_FILE_MAX_SIZE * i, &length);
|
||||
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
err_code |= 0x02;
|
||||
goto error;
|
||||
}
|
||||
total_length += length;
|
||||
}
|
||||
char *p_line_end;
|
||||
char *p_line_bgn = buf;
|
||||
strcpy(section, CONFIG_DEFAULT_SECTION);
|
||||
|
||||
while ( (p_line_bgn < buf + total_length - 1) && (p_line_end = strchr(p_line_bgn, '\n'))) {
|
||||
|
||||
// get one line
|
||||
int line_len = p_line_end - p_line_bgn;
|
||||
if (line_len > 1023) {
|
||||
OSI_TRACE_WARNING("%s exceed max line length on line %d.\n", __func__, line_num);
|
||||
break;
|
||||
}
|
||||
memcpy(line, p_line_bgn, line_len);
|
||||
line[line_len] = '\0';
|
||||
p_line_bgn = p_line_end + 1;
|
||||
char *line_ptr = trim(line);
|
||||
++line_num;
|
||||
|
||||
// Skip blank and comment lines.
|
||||
if (*line_ptr == '\0' || *line_ptr == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*line_ptr == '[') {
|
||||
size_t len = strlen(line_ptr);
|
||||
if (line_ptr[len - 1] != ']') {
|
||||
OSI_TRACE_WARNING("%s unterminated section name on line %d.\n", __func__, line_num);
|
||||
continue;
|
||||
}
|
||||
strncpy(section, line_ptr + 1, len - 2);
|
||||
section[len - 2] = '\0';
|
||||
} else {
|
||||
char *split = strchr(line_ptr, '=');
|
||||
if (!split) {
|
||||
OSI_TRACE_DEBUG("%s no key/value separator found on line %d.\n", __func__, line_num);
|
||||
continue;
|
||||
}
|
||||
*split = '\0';
|
||||
config_set_string(config, section, trim(line_ptr), trim(split + 1), true);
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
if (buf) {
|
||||
osi_free(buf);
|
||||
}
|
||||
if (line) {
|
||||
osi_free(line);
|
||||
}
|
||||
if (section) {
|
||||
osi_free(section);
|
||||
}
|
||||
if (keyname) {
|
||||
osi_free(keyname);
|
||||
}
|
||||
if (err_code) {
|
||||
OSI_TRACE_ERROR("%s returned with err code: %d\n", __func__, err_code);
|
||||
}
|
||||
}
|
||||
|
||||
static section_t *section_new(const char *name)
|
||||
{
|
||||
section_t *section = osi_calloc(sizeof(section_t));
|
||||
if (!section) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
section->name = osi_strdup(name);
|
||||
section->entries = list_new(entry_free);
|
||||
return section;
|
||||
}
|
||||
|
||||
static void section_free(void *ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
section_t *section = ptr;
|
||||
osi_free(section->name);
|
||||
list_free(section->entries);
|
||||
osi_free(section);
|
||||
}
|
||||
|
||||
static section_t *section_find(const config_t *config, const char *section)
|
||||
{
|
||||
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
|
||||
section_t *sec = list_node(node);
|
||||
if (!strcmp(sec->name, section)) {
|
||||
return sec;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static entry_t *entry_new(const char *key, const char *value)
|
||||
{
|
||||
entry_t *entry = osi_calloc(sizeof(entry_t));
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry->key = osi_strdup(key);
|
||||
entry->value = osi_strdup(value);
|
||||
return entry;
|
||||
}
|
||||
|
||||
static void entry_free(void *ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry_t *entry = ptr;
|
||||
osi_free(entry->key);
|
||||
osi_free(entry->value);
|
||||
osi_free(entry);
|
||||
}
|
||||
|
||||
static entry_t *entry_find(const config_t *config, const char *section, const char *key)
|
||||
{
|
||||
section_t *sec = section_find(config, section);
|
||||
if (!sec) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) {
|
||||
entry_t *entry = list_node(node);
|
||||
if (!strcmp(entry->key, key)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/pkt_queue.h"
|
||||
#include "osi/fixed_pkt_queue.h"
|
||||
#include "osi/osi.h"
|
||||
#include "osi/semaphore.h"
|
||||
|
||||
typedef struct fixed_pkt_queue_t {
|
||||
struct pkt_queue *pkt_list;
|
||||
osi_sem_t enqueue_sem;
|
||||
osi_sem_t dequeue_sem;
|
||||
size_t capacity;
|
||||
fixed_pkt_queue_cb dequeue_ready;
|
||||
} fixed_pkt_queue_t;
|
||||
|
||||
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity)
|
||||
{
|
||||
fixed_pkt_queue_t *ret = osi_calloc(sizeof(fixed_pkt_queue_t));
|
||||
if (!ret) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret->capacity = capacity;
|
||||
ret->pkt_list = pkt_queue_create();
|
||||
if (!ret->pkt_list) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
osi_sem_new(&ret->enqueue_sem, capacity, capacity);
|
||||
if (!ret->enqueue_sem) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
osi_sem_new(&ret->dequeue_sem, capacity, 0);
|
||||
if (!ret->dequeue_sem) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
fixed_pkt_queue_free(ret, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
fixed_pkt_queue_unregister_dequeue(queue);
|
||||
|
||||
pkt_queue_destroy(queue->pkt_list, (pkt_queue_free_cb)free_cb);
|
||||
queue->pkt_list = NULL;
|
||||
|
||||
if (queue->enqueue_sem) {
|
||||
osi_sem_free(&queue->enqueue_sem);
|
||||
}
|
||||
if (queue->dequeue_sem) {
|
||||
osi_sem_free(&queue->dequeue_sem);
|
||||
}
|
||||
osi_free(queue);
|
||||
}
|
||||
|
||||
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return pkt_queue_is_empty(queue->pkt_list);
|
||||
}
|
||||
|
||||
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return pkt_queue_length(queue->pkt_list);
|
||||
}
|
||||
|
||||
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
|
||||
return queue->capacity;
|
||||
}
|
||||
|
||||
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
assert(queue != NULL);
|
||||
assert(linked_pkt != NULL);
|
||||
|
||||
if (osi_sem_take(&queue->enqueue_sem, timeout) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = pkt_queue_enqueue(queue->pkt_list, linked_pkt);
|
||||
|
||||
assert(ret == true);
|
||||
osi_sem_give(&queue->dequeue_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout)
|
||||
{
|
||||
pkt_linked_item_t *ret = NULL;
|
||||
|
||||
assert(queue != NULL);
|
||||
|
||||
if (osi_sem_take(&queue->dequeue_sem, timeout) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
ret = pkt_queue_dequeue(queue->pkt_list);
|
||||
|
||||
osi_sem_give(&queue->enqueue_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pkt_queue_try_peek_first(queue->pkt_list);
|
||||
}
|
||||
|
||||
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
assert(ready_cb != NULL);
|
||||
|
||||
queue->dequeue_ready = ready_cb;
|
||||
}
|
||||
|
||||
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
|
||||
queue->dequeue_ready = NULL;
|
||||
}
|
||||
|
||||
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
|
||||
if (queue->dequeue_ready) {
|
||||
queue->dequeue_ready(queue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/fixed_queue.h"
|
||||
#include "osi/list.h"
|
||||
#include "osi/osi.h"
|
||||
#include "osi/mutex.h"
|
||||
#include "osi/semaphore.h"
|
||||
|
||||
typedef struct fixed_queue_t {
|
||||
|
||||
list_t *list;
|
||||
osi_sem_t enqueue_sem;
|
||||
osi_sem_t dequeue_sem;
|
||||
osi_mutex_t lock;
|
||||
size_t capacity;
|
||||
|
||||
fixed_queue_cb dequeue_ready;
|
||||
} fixed_queue_t;
|
||||
|
||||
|
||||
fixed_queue_t *fixed_queue_new(size_t capacity)
|
||||
{
|
||||
fixed_queue_t *ret = osi_calloc(sizeof(fixed_queue_t));
|
||||
if (!ret) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
osi_mutex_new(&ret->lock);
|
||||
ret->capacity = capacity;
|
||||
|
||||
ret->list = list_new(NULL);
|
||||
if (!ret->list) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
osi_sem_new(&ret->enqueue_sem, capacity, capacity);
|
||||
if (!ret->enqueue_sem) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
osi_sem_new(&ret->dequeue_sem, capacity, 0);
|
||||
if (!ret->dequeue_sem) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
error:;
|
||||
fixed_queue_free(ret, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb)
|
||||
{
|
||||
const list_node_t *node;
|
||||
|
||||
if (queue == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
fixed_queue_unregister_dequeue(queue);
|
||||
|
||||
if (free_cb) {
|
||||
for (node = list_begin(queue->list); node != list_end(queue->list); node = list_next(node)) {
|
||||
free_cb(list_node(node));
|
||||
}
|
||||
}
|
||||
|
||||
list_free(queue->list);
|
||||
osi_sem_free(&queue->enqueue_sem);
|
||||
osi_sem_free(&queue->dequeue_sem);
|
||||
osi_mutex_free(&queue->lock);
|
||||
osi_free(queue);
|
||||
}
|
||||
|
||||
bool fixed_queue_is_empty(fixed_queue_t *queue)
|
||||
{
|
||||
bool is_empty = false;
|
||||
|
||||
if (queue == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
is_empty = list_is_empty(queue->list);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
size_t fixed_queue_length(fixed_queue_t *queue)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
length = list_length(queue->list);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
return length;
|
||||
}
|
||||
size_t fixed_queue_capacity(fixed_queue_t *queue)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
|
||||
return queue->capacity;
|
||||
}
|
||||
|
||||
bool fixed_queue_enqueue(fixed_queue_t *queue, void *data, uint32_t timeout)
|
||||
{
|
||||
bool status=false; //Flag whether enqueued success
|
||||
|
||||
assert(queue != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
if (osi_sem_take(&queue->enqueue_sem, timeout) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
status = list_append(queue->list, data); //Check whether enqueued success
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
if(status == true )
|
||||
osi_sem_give(&queue->dequeue_sem);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void *fixed_queue_dequeue(fixed_queue_t *queue, uint32_t timeout)
|
||||
{
|
||||
void *ret = NULL;
|
||||
|
||||
assert(queue != NULL);
|
||||
|
||||
if (osi_sem_take(&queue->dequeue_sem, timeout) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
ret = list_front(queue->list);
|
||||
list_remove(queue->list, ret);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
osi_sem_give(&queue->enqueue_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *fixed_queue_try_peek_first(fixed_queue_t *queue)
|
||||
{
|
||||
void *ret = NULL;
|
||||
|
||||
if (queue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
ret = list_is_empty(queue->list) ? NULL : list_front(queue->list);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *fixed_queue_try_peek_last(fixed_queue_t *queue)
|
||||
{
|
||||
void *ret = NULL;
|
||||
|
||||
if (queue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
ret = list_is_empty(queue->list) ? NULL : list_back(queue->list);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data)
|
||||
{
|
||||
bool removed = false;
|
||||
|
||||
if (queue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (list_contains(queue->list, data) &&
|
||||
osi_sem_take(&queue->dequeue_sem, 0) == 0) {
|
||||
removed = list_remove(queue->list, data);
|
||||
assert(removed);
|
||||
}
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
if (removed) {
|
||||
osi_sem_give(&queue->enqueue_sem);
|
||||
return data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_t *fixed_queue_get_list(fixed_queue_t *queue)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
|
||||
// NOTE: This function is not thread safe, and there is no point for
|
||||
// calling osi_mutex_lock() / osi_mutex_unlock()
|
||||
return queue->list;
|
||||
}
|
||||
|
||||
void fixed_queue_register_dequeue(fixed_queue_t *queue, fixed_queue_cb ready_cb)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
assert(ready_cb != NULL);
|
||||
|
||||
queue->dequeue_ready = ready_cb;
|
||||
}
|
||||
|
||||
void fixed_queue_unregister_dequeue(fixed_queue_t *queue)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
|
||||
queue->dequeue_ready = NULL;
|
||||
}
|
||||
|
||||
void fixed_queue_process(fixed_queue_t *queue)
|
||||
{
|
||||
assert(queue != NULL);
|
||||
|
||||
if (queue->dequeue_ready) {
|
||||
queue->dequeue_ready(queue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_common.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/future.h"
|
||||
#include "osi/osi.h"
|
||||
|
||||
void future_free(future_t *future);
|
||||
|
||||
future_t *future_new(void)
|
||||
{
|
||||
future_t *ret = osi_calloc(sizeof(future_t));
|
||||
if (!ret) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (osi_sem_new(&ret->semaphore, 1, 0) != 0) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate memory for the semaphore.", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret->ready_can_be_called = true;
|
||||
return ret;
|
||||
error:;
|
||||
future_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
future_t *future_new_immediate(void *value)
|
||||
{
|
||||
future_t *ret = osi_calloc(sizeof(future_t));
|
||||
if (!ret) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret->result = value;
|
||||
ret->ready_can_be_called = false;
|
||||
return ret;
|
||||
error:;
|
||||
future_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void future_ready(future_t *future, void *value)
|
||||
{
|
||||
assert(future != NULL);
|
||||
assert(future->ready_can_be_called);
|
||||
|
||||
future->ready_can_be_called = false;
|
||||
future->result = value;
|
||||
osi_sem_give(&future->semaphore);
|
||||
}
|
||||
|
||||
void *future_await(future_t *future)
|
||||
{
|
||||
assert(future != NULL);
|
||||
|
||||
// If the future is immediate, it will not have a semaphore
|
||||
if (future->semaphore) {
|
||||
osi_sem_take(&future->semaphore, OSI_SEM_MAX_TIMEOUT);
|
||||
}
|
||||
|
||||
void *result = future->result;
|
||||
future_free(future);
|
||||
return result;
|
||||
}
|
||||
|
||||
void future_free(future_t *future)
|
||||
{
|
||||
if (!future) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (future->semaphore) {
|
||||
osi_sem_free(&future->semaphore);
|
||||
}
|
||||
|
||||
osi_free(future);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "osi/hash_functions.h"
|
||||
|
||||
hash_index_t hash_function_naive(const void *key)
|
||||
{
|
||||
return (hash_index_t)key;
|
||||
}
|
||||
|
||||
hash_index_t hash_function_integer(const void *key)
|
||||
{
|
||||
return ((hash_index_t)key) * 2654435761;
|
||||
}
|
||||
|
||||
hash_index_t hash_function_pointer(const void *key)
|
||||
{
|
||||
return ((hash_index_t)key) * 2654435761;
|
||||
}
|
||||
|
||||
hash_index_t hash_function_string(const void *key)
|
||||
{
|
||||
hash_index_t hash = 5381;
|
||||
const char *name = (const char *)key;
|
||||
size_t string_len = strlen(name);
|
||||
for (size_t i = 0; i < string_len; ++i) {
|
||||
hash = ((hash << 5) + hash ) + name[i];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
void hash_function_blob(const unsigned char *s, unsigned int len, hash_key_t h)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
while (len--) {
|
||||
j = sizeof(hash_key_t)-1;
|
||||
|
||||
while (j) {
|
||||
h[j] = ((h[j] << 7) | (h[j-1] >> 1)) + h[j];
|
||||
--j;
|
||||
}
|
||||
|
||||
h[0] = (h[0] << 7) + h[0] + *s++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_common.h"
|
||||
#include "osi/list.h"
|
||||
#include "osi/hash_map.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
struct hash_map_t;
|
||||
|
||||
typedef struct hash_map_bucket_t {
|
||||
list_t *list;
|
||||
} hash_map_bucket_t;
|
||||
|
||||
typedef struct hash_map_t {
|
||||
hash_map_bucket_t *bucket;
|
||||
size_t num_bucket;
|
||||
size_t hash_size;
|
||||
hash_index_fn hash_fn;
|
||||
key_free_fn key_fn;
|
||||
data_free_fn data_fn;
|
||||
key_equality_fn keys_are_equal;
|
||||
} hash_map_t;
|
||||
|
||||
// Hidden constructor for list, only to be used by us.
|
||||
list_t *list_new_internal(list_free_cb callback);
|
||||
|
||||
static void bucket_free_(void *data);
|
||||
static bool default_key_equality(const void *x, const void *y);
|
||||
static hash_map_entry_t *find_bucket_entry_(list_t *hash_bucket_list,
|
||||
const void *key);
|
||||
|
||||
// Hidden constructor, only to be used by the allocation tracker. Behaves the same as
|
||||
// |hash_map_new|, except you get to specify the allocator.
|
||||
hash_map_t *hash_map_new_internal(
|
||||
size_t num_bucket,
|
||||
hash_index_fn hash_fn,
|
||||
key_free_fn key_fn,
|
||||
data_free_fn data_fn,
|
||||
key_equality_fn equality_fn)
|
||||
{
|
||||
assert(hash_fn != NULL);
|
||||
assert(num_bucket > 0);
|
||||
hash_map_t *hash_map = osi_calloc(sizeof(hash_map_t));
|
||||
if (hash_map == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash_map->hash_fn = hash_fn;
|
||||
hash_map->key_fn = key_fn;
|
||||
hash_map->data_fn = data_fn;
|
||||
hash_map->keys_are_equal = equality_fn ? equality_fn : default_key_equality;
|
||||
|
||||
hash_map->num_bucket = num_bucket;
|
||||
hash_map->bucket = osi_calloc(sizeof(hash_map_bucket_t) * num_bucket);
|
||||
if (hash_map->bucket == NULL) {
|
||||
osi_free(hash_map);
|
||||
return NULL;
|
||||
}
|
||||
return hash_map;
|
||||
}
|
||||
|
||||
hash_map_t *hash_map_new(
|
||||
size_t num_bucket,
|
||||
hash_index_fn hash_fn,
|
||||
key_free_fn key_fn,
|
||||
data_free_fn data_fn,
|
||||
key_equality_fn equality_fn)
|
||||
{
|
||||
return hash_map_new_internal(num_bucket, hash_fn, key_fn, data_fn, equality_fn);
|
||||
}
|
||||
|
||||
void hash_map_free(hash_map_t *hash_map)
|
||||
{
|
||||
if (hash_map == NULL) {
|
||||
return;
|
||||
}
|
||||
hash_map_clear(hash_map);
|
||||
osi_free(hash_map->bucket);
|
||||
osi_free(hash_map);
|
||||
}
|
||||
|
||||
/*
|
||||
bool hash_map_is_empty(const hash_map_t *hash_map) {
|
||||
assert(hash_map != NULL);
|
||||
return (hash_map->hash_size == 0);
|
||||
}
|
||||
|
||||
size_t hash_map_size(const hash_map_t *hash_map) {
|
||||
assert(hash_map != NULL);
|
||||
return hash_map->hash_size;
|
||||
}
|
||||
|
||||
size_t hash_map_num_buckets(const hash_map_t *hash_map) {
|
||||
assert(hash_map != NULL);
|
||||
return hash_map->num_bucket;
|
||||
}
|
||||
*/
|
||||
|
||||
bool hash_map_has_key(const hash_map_t *hash_map, const void *key)
|
||||
{
|
||||
assert(hash_map != NULL);
|
||||
|
||||
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket;
|
||||
list_t *hash_bucket_list = hash_map->bucket[hash_key].list;
|
||||
|
||||
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key);
|
||||
return (hash_map_entry != NULL);
|
||||
}
|
||||
|
||||
bool hash_map_set(hash_map_t *hash_map, const void *key, void *data)
|
||||
{
|
||||
assert(hash_map != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket;
|
||||
|
||||
if (hash_map->bucket[hash_key].list == NULL) {
|
||||
hash_map->bucket[hash_key].list = list_new_internal(bucket_free_);
|
||||
if (hash_map->bucket[hash_key].list == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
list_t *hash_bucket_list = hash_map->bucket[hash_key].list;
|
||||
|
||||
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key);
|
||||
|
||||
if (hash_map_entry) {
|
||||
// Calls hash_map callback to delete the hash_map_entry.
|
||||
bool rc = list_remove(hash_bucket_list, hash_map_entry);
|
||||
assert(rc == true);
|
||||
(void)rc;
|
||||
} else {
|
||||
hash_map->hash_size++;
|
||||
}
|
||||
hash_map_entry = osi_calloc(sizeof(hash_map_entry_t));
|
||||
if (hash_map_entry == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hash_map_entry->key = key;
|
||||
hash_map_entry->data = data;
|
||||
hash_map_entry->hash_map = hash_map;
|
||||
|
||||
return list_append(hash_bucket_list, hash_map_entry);
|
||||
}
|
||||
|
||||
bool hash_map_erase(hash_map_t *hash_map, const void *key)
|
||||
{
|
||||
assert(hash_map != NULL);
|
||||
|
||||
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket;
|
||||
list_t *hash_bucket_list = hash_map->bucket[hash_key].list;
|
||||
|
||||
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key);
|
||||
if (hash_map_entry == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hash_map->hash_size--;
|
||||
bool remove = list_remove(hash_bucket_list, hash_map_entry);
|
||||
if(list_is_empty(hash_map->bucket[hash_key].list)) {
|
||||
list_free(hash_map->bucket[hash_key].list);
|
||||
hash_map->bucket[hash_key].list = NULL;
|
||||
}
|
||||
|
||||
return remove;
|
||||
}
|
||||
|
||||
void *hash_map_get(const hash_map_t *hash_map, const void *key)
|
||||
{
|
||||
assert(hash_map != NULL);
|
||||
|
||||
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket;
|
||||
list_t *hash_bucket_list = hash_map->bucket[hash_key].list;
|
||||
|
||||
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key);
|
||||
if (hash_map_entry != NULL) {
|
||||
return hash_map_entry->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hash_map_clear(hash_map_t *hash_map)
|
||||
{
|
||||
assert(hash_map != NULL);
|
||||
|
||||
for (hash_index_t i = 0; i < hash_map->num_bucket; i++) {
|
||||
if (hash_map->bucket[i].list == NULL) {
|
||||
continue;
|
||||
}
|
||||
list_free(hash_map->bucket[i].list);
|
||||
hash_map->bucket[i].list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void hash_map_foreach(hash_map_t *hash_map, hash_map_iter_cb callback, void *context)
|
||||
{
|
||||
assert(hash_map != NULL);
|
||||
assert(callback != NULL);
|
||||
|
||||
for (hash_index_t i = 0; i < hash_map->num_bucket; ++i) {
|
||||
if (hash_map->bucket[i].list == NULL) {
|
||||
continue;
|
||||
}
|
||||
for (const list_node_t *iter = list_begin(hash_map->bucket[i].list);
|
||||
iter != list_end(hash_map->bucket[i].list);
|
||||
iter = list_next(iter)) {
|
||||
hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)list_node(iter);
|
||||
if (!callback(hash_map_entry, context)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bucket_free_(void *data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)data;
|
||||
const hash_map_t *hash_map = hash_map_entry->hash_map;
|
||||
|
||||
if (hash_map->key_fn) {
|
||||
hash_map->key_fn((void *)hash_map_entry->key);
|
||||
}
|
||||
if (hash_map->data_fn) {
|
||||
hash_map->data_fn(hash_map_entry->data);
|
||||
}
|
||||
osi_free(hash_map_entry);
|
||||
}
|
||||
|
||||
static hash_map_entry_t *find_bucket_entry_(list_t *hash_bucket_list,
|
||||
const void *key)
|
||||
{
|
||||
|
||||
if (hash_bucket_list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (const list_node_t *iter = list_begin(hash_bucket_list);
|
||||
iter != list_end(hash_bucket_list);
|
||||
iter = list_next(iter)) {
|
||||
hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)list_node(iter);
|
||||
if (hash_map_entry->hash_map->keys_are_equal(hash_map_entry->key, key)) {
|
||||
return hash_map_entry;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool default_key_equality(const void *x, const void *y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _ALARM_H_
|
||||
#define _ALARM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_timer.h"
|
||||
|
||||
typedef struct alarm_t osi_alarm_t;
|
||||
typedef uint64_t period_ms_t;
|
||||
typedef esp_timer_cb_t osi_alarm_callback_t;
|
||||
|
||||
typedef enum {
|
||||
OSI_ALARM_ERR_PASS = 0,
|
||||
OSI_ALARM_ERR_FAIL = -1,
|
||||
OSI_ALARM_ERR_INVALID_ARG = -2,
|
||||
OSI_ALARM_ERR_INVALID_STATE = -3,
|
||||
} osi_alarm_err_t;
|
||||
|
||||
#define ALARM_CBS_NUM 50
|
||||
#define ALARM_ID_BASE 1000
|
||||
|
||||
int osi_alarm_create_mux(void);
|
||||
int osi_alarm_delete_mux(void);
|
||||
void osi_alarm_init(void);
|
||||
void osi_alarm_deinit(void);
|
||||
|
||||
// Creates a new alarm object. The returned object must be freed by calling
|
||||
// |alarm_free|. Returns NULL on failure.
|
||||
osi_alarm_t *osi_alarm_new(const char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire);
|
||||
|
||||
// Frees an alarm object created by |alarm_new|. |alarm| may be NULL. If the
|
||||
// alarm is pending, it will be cancelled. It is not safe to call |alarm_free|
|
||||
// from inside the callback of |alarm|.
|
||||
void osi_alarm_free(osi_alarm_t *alarm);
|
||||
|
||||
// Sets an alarm to fire |cb| after the given |deadline|. Note that |deadline| is the
|
||||
// number of milliseconds relative to the current time. |data| is a context variable
|
||||
// for the callback and may be NULL. |cb| will be called back in the context of an
|
||||
// unspecified thread (i.e. it will not be called back in the same thread as the caller).
|
||||
// |alarm| and |cb| may not be NULL.
|
||||
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout);
|
||||
|
||||
// Sets an periodic alarm to fire |cb| each given |period|.
|
||||
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period);
|
||||
|
||||
// This function cancels the |alarm| if it was previously set. When this call
|
||||
// returns, the caller has a guarantee that the callback is not in progress and
|
||||
// will not be called if it hasn't already been called. This function is idempotent.
|
||||
// |alarm| may not be NULL.
|
||||
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm);
|
||||
|
||||
// Figure out how much time until next expiration.
|
||||
// Returns 0 if not armed. |alarm| may not be NULL.
|
||||
// only for oneshot alarm, not for periodic alarm
|
||||
// TODO: Remove this function once PM timers can be re-factored
|
||||
period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm);
|
||||
|
||||
// Alarm-related state cleanup
|
||||
//void alarm_cleanup(void);
|
||||
|
||||
uint32_t osi_time_get_os_boottime_ms(void);
|
||||
|
||||
// This function returns whether the given |alarm| is active or not.
|
||||
// Return true if active, false otherwise.
|
||||
bool osi_alarm_is_active(osi_alarm_t *alarm);
|
||||
|
||||
#endif /*_ALARM_H_*/
|
||||
@@ -0,0 +1,145 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _ALLOCATOR_H_
|
||||
#define _ALLOCATOR_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
char *osi_strdup(const char *str);
|
||||
|
||||
void *osi_malloc_func(size_t size);
|
||||
void *osi_calloc_func(size_t size);
|
||||
void osi_free_func(void *ptr);
|
||||
|
||||
#if HEAP_MEMORY_DEBUG
|
||||
|
||||
void osi_mem_dbg_init(void);
|
||||
void osi_mem_dbg_record(void *p, int size, const char *func, int line);
|
||||
void osi_mem_dbg_clean(void *p, const char *func, int line);
|
||||
void osi_mem_dbg_show(void);
|
||||
uint32_t osi_mem_dbg_get_max_size(void);
|
||||
uint32_t osi_mem_dbg_get_current_size(void);
|
||||
void osi_men_dbg_set_section_start(uint8_t index);
|
||||
void osi_men_dbg_set_section_end(uint8_t index);
|
||||
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index);
|
||||
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||
#define osi_malloc(size) \
|
||||
({ \
|
||||
void *p; \
|
||||
p = heap_caps_malloc_prefer(size, 2, \
|
||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
})
|
||||
|
||||
#define osi_calloc(size) \
|
||||
({ \
|
||||
void *p; \
|
||||
p = heap_caps_calloc_prefer(1, size, 2, \
|
||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
})
|
||||
|
||||
#else
|
||||
|
||||
#define osi_malloc(size) \
|
||||
({ \
|
||||
void *p; \
|
||||
p = malloc((size)); \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
})
|
||||
|
||||
#define osi_calloc(size) \
|
||||
({ \
|
||||
void *p; \
|
||||
p = calloc(1, (size)); \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
})
|
||||
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||
|
||||
|
||||
#if 0
|
||||
#define osi_malloc(size) \
|
||||
do { \
|
||||
void *p; \
|
||||
\
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
|
||||
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||
#else \
|
||||
p = malloc((size)); \
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
}while(0)
|
||||
|
||||
#define osi_calloc(size) \
|
||||
do { \
|
||||
void *p; \
|
||||
\
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
|
||||
p = heap_caps_calloc_prefer(1, size, 2, \
|
||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
||||
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||
#else \
|
||||
p = calloc(1, (size)); \
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define osi_free(ptr) \
|
||||
do { \
|
||||
void *tmp_point = (void *)(ptr); \
|
||||
osi_mem_dbg_clean(tmp_point, __func__, __LINE__); \
|
||||
free(tmp_point); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
|
||||
#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
|
||||
#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
|
||||
#else
|
||||
#define osi_malloc(size) malloc((size))
|
||||
#define osi_calloc(size) calloc(1, (size))
|
||||
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
|
||||
#define osi_free(p) free((p))
|
||||
|
||||
#endif /* HEAP_MEMORY_DEBUG */
|
||||
|
||||
#define FREE_AND_RESET(a) \
|
||||
do { \
|
||||
if (a) { \
|
||||
osi_free(a); \
|
||||
a = NULL; \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
|
||||
#endif /* _ALLOCATOR_H_ */
|
||||
@@ -0,0 +1,59 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _BUFFER_H_
|
||||
#define _BUFFER_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct buffer_t buffer_t;
|
||||
|
||||
// Returns a new buffer of |size| bytes. Returns NULL if a buffer could not be
|
||||
// allocated. |size| must be non-zero. The caller must release this buffer with
|
||||
// |buffer_free|.
|
||||
buffer_t *buffer_new(size_t size);
|
||||
|
||||
// Creates a new reference to the buffer |buf|. A reference is indistinguishable
|
||||
// from the original: writes to the original will be reflected in the reference
|
||||
// and vice versa. In other words, this function creates an alias to |buf|. The
|
||||
// caller must release the returned buffer with |buffer_free|. Note that releasing
|
||||
// the returned buffer does not release |buf|. |buf| must not be NULL.
|
||||
buffer_t *buffer_new_ref(const buffer_t *buf);
|
||||
|
||||
// Creates a new reference to the last |slice_size| bytes of |buf|. See
|
||||
// |buffer_new_ref| for a description of references. |slice_size| must be
|
||||
// greater than 0 and may be at most |buffer_length|
|
||||
// (0 < slice_size <= buffer_length). |buf| must not be NULL.
|
||||
buffer_t *buffer_new_slice(const buffer_t *buf, size_t slice_size);
|
||||
|
||||
// Frees a buffer object. |buf| may be NULL.
|
||||
void buffer_free(buffer_t *buf);
|
||||
|
||||
// Returns a pointer to a writeable memory region for |buf|. All references
|
||||
// and slices that share overlapping bytes will also be written to when
|
||||
// writing to the returned pointer. The caller may safely write up to
|
||||
// |buffer_length| consecutive bytes starting at the address returned by
|
||||
// this function. |buf| must not be NULL.
|
||||
void *buffer_ptr(const buffer_t *buf);
|
||||
|
||||
// Returns the length of the writeable memory region referred to by |buf|.
|
||||
// |buf| must not be NULL.
|
||||
size_t buffer_length(const buffer_t *buf);
|
||||
|
||||
#endif /*_BUFFER_H_*/
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
// This module implements a configuration parser. Clients can query the
|
||||
// contents of a configuration file through the interface provided here.
|
||||
// The current implementation is read-only; mutations are only kept in
|
||||
// memory. This parser supports the INI file format.
|
||||
|
||||
// Implementation notes:
|
||||
// - Key/value pairs that are not within a section are assumed to be under
|
||||
// the |CONFIG_DEFAULT_SECTION| section.
|
||||
// - Multiple sections with the same name will be merged as if they were in
|
||||
// a single section.
|
||||
// - Empty sections with no key/value pairs will be treated as if they do
|
||||
// not exist. In other words, |config_has_section| will return false for
|
||||
// empty sections.
|
||||
// - Duplicate keys in a section will overwrite previous values.
|
||||
// - All strings are case sensitive.
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// The default section name to use if a key/value pair is not defined within
|
||||
// a section.
|
||||
#define CONFIG_DEFAULT_SECTION "Global"
|
||||
|
||||
typedef struct config_t config_t;
|
||||
typedef struct config_section_node_t config_section_node_t;
|
||||
|
||||
// Creates a new config object with no entries (i.e. not backed by a file).
|
||||
// This function returns a config object or NULL on error. Clients must call
|
||||
// |config_free| on the returned handle when it is no longer required.
|
||||
config_t *config_new_empty(void);
|
||||
|
||||
// Loads the specified file and returns a handle to the config file. If there
|
||||
// was a problem loading the file or allocating memory, this function returns
|
||||
// NULL. Clients must call |config_free| on the returned handle when it is no
|
||||
// longer required. |filename| must not be NULL and must point to a readable
|
||||
// file on the filesystem.
|
||||
config_t *config_new(const char *filename);
|
||||
|
||||
// Frees resources associated with the config file. No further operations may
|
||||
// be performed on the |config| object after calling this function. |config|
|
||||
// may be NULL.
|
||||
void config_free(config_t *config);
|
||||
|
||||
// Returns true if the config file contains a section named |section|. If
|
||||
// the section has no key/value pairs in it, this function will return false.
|
||||
// |config| and |section| must not be NULL.
|
||||
bool config_has_section(const config_t *config, const char *section);
|
||||
|
||||
// Returns true if the config file has a key named |key| under |section|.
|
||||
// Returns false otherwise. |config|, |section|, and |key| must not be NULL.
|
||||
bool config_has_key(const config_t *config, const char *section, const char *key);
|
||||
|
||||
// Returns true if the config file has a key named |key| and the key_value.
|
||||
// Returns false otherwise. |config|, |key|, and |key_value| must not be NULL.
|
||||
bool config_has_key_in_section(config_t *config, const char *key, char *key_value);
|
||||
|
||||
// Returns the integral value for a given |key| in |section|. If |section|
|
||||
// or |key| do not exist, or the value cannot be fully converted to an integer,
|
||||
// this function returns |def_value|. |config|, |section|, and |key| must not
|
||||
// be NULL.
|
||||
int config_get_int(const config_t *config, const char *section, const char *key, int def_value);
|
||||
|
||||
// Returns the boolean value for a given |key| in |section|. If |section|
|
||||
// or |key| do not exist, or the value cannot be converted to a boolean, this
|
||||
// function returns |def_value|. |config|, |section|, and |key| must not be NULL.
|
||||
bool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value);
|
||||
|
||||
// Returns the string value for a given |key| in |section|. If |section| or
|
||||
// |key| do not exist, this function returns |def_value|. The returned string
|
||||
// is owned by the config module and must not be freed. |config|, |section|,
|
||||
// and |key| must not be NULL. |def_value| may be NULL.
|
||||
const char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value);
|
||||
|
||||
// Sets an integral value for the |key| in |section|. If |key| or |section| do
|
||||
// not already exist, this function creates them. |config|, |section|, and |key|
|
||||
// must not be NULL.
|
||||
void config_set_int(config_t *config, const char *section, const char *key, int value);
|
||||
|
||||
// Sets a boolean value for the |key| in |section|. If |key| or |section| do
|
||||
// not already exist, this function creates them. |config|, |section|, and |key|
|
||||
// must not be NULL.
|
||||
void config_set_bool(config_t *config, const char *section, const char *key, bool value);
|
||||
|
||||
// Sets a string value for the |key| in |section|. If |key| or |section| do
|
||||
// not already exist, this function creates them. |config|, |section|, |key|, and
|
||||
// |value| must not be NULL.
|
||||
void config_set_string(config_t *config, const char *section, const char *key, const char *value, bool insert_back);
|
||||
|
||||
// Removes |section| from the |config| (and, as a result, all keys in the section).
|
||||
// Returns true if |section| was found and removed from |config|, false otherwise.
|
||||
// Neither |config| nor |section| may be NULL.
|
||||
bool config_remove_section(config_t *config, const char *section);
|
||||
|
||||
// Updates |section| to be the first section in |config|. Return true if |section| is in
|
||||
// |config| and updated successfully, false otherwise.
|
||||
// Neither |config| nor |section| may be NULL.
|
||||
bool config_update_newest_section(config_t *config, const char *section);
|
||||
|
||||
// Removes one specific |key| residing in |section| of the |config|. Returns true
|
||||
// if the section and key were found and the key was removed, false otherwise.
|
||||
// None of |config|, |section|, or |key| may be NULL.
|
||||
bool config_remove_key(config_t *config, const char *section, const char *key);
|
||||
|
||||
// Returns an iterator to the first section in the config file. If there are no
|
||||
// sections, the iterator will equal the return value of |config_section_end|.
|
||||
// The returned pointer must be treated as an opaque handle and must not be freed.
|
||||
// The iterator is invalidated on any config mutating operation. |config| may not
|
||||
// be NULL.
|
||||
const config_section_node_t *config_section_begin(const config_t *config);
|
||||
|
||||
// Returns an iterator to one past the last section in the config file. It does not
|
||||
// represent a valid section, but can be used to determine if all sections have been
|
||||
// iterated over. The returned pointer must be treated as an opaque handle and must
|
||||
// not be freed and must not be iterated on (must not call |config_section_next| on
|
||||
// it). |config| may not be NULL.
|
||||
const config_section_node_t *config_section_end(const config_t *config);
|
||||
|
||||
// Moves |iter| to the next section. If there are no more sections, |iter| will
|
||||
// equal the value of |config_section_end|. |iter| may not be NULL and must be
|
||||
// a pointer returned by either |config_section_begin| or |config_section_next|.
|
||||
const config_section_node_t *config_section_next(const config_section_node_t *iter);
|
||||
|
||||
// Returns the name of the section referred to by |iter|. The returned pointer is
|
||||
// owned by the config module and must not be freed by the caller. The pointer will
|
||||
// remain valid until |config_free| is called. |iter| may not be NULL and must not
|
||||
// equal the value returned by |config_section_end|.
|
||||
const char *config_section_name(const config_section_node_t *iter);
|
||||
|
||||
// Saves |config| to a file given by |filename|. Note that this could be a destructive
|
||||
// operation: if |filename| already exists, it will be overwritten. The config
|
||||
// module does not preserve comments or formatting so if a config file was opened
|
||||
// with |config_new| and subsequently overwritten with |config_save|, all comments
|
||||
// and special formatting in the original file will be lost. Neither |config| nor
|
||||
// |filename| may be NULL.
|
||||
bool config_save(const config_t *config, const char *filename);
|
||||
|
||||
#endif /* #ifndef __CONFIG_H__ */
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _FIXED_PKT_QUEUE_H_
|
||||
#define _FIXED_PKT_QUEUE_H_
|
||||
|
||||
|
||||
#include "osi/pkt_queue.h"
|
||||
#include "osi/semaphore.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef FIXED_PKT_QUEUE_SIZE_MAX
|
||||
#define FIXED_PKT_QUEUE_SIZE_MAX 254
|
||||
#endif
|
||||
|
||||
#define FIXED_PKT_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
|
||||
|
||||
struct fixed_pkt_queue_t;
|
||||
|
||||
typedef struct fixed_pkt_queue_t fixed_pkt_queue_t;
|
||||
|
||||
typedef void (*fixed_pkt_queue_free_cb)(pkt_linked_item_t *data);
|
||||
typedef void (*fixed_pkt_queue_cb)(fixed_pkt_queue_t *queue);
|
||||
|
||||
// Creates a new fixed queue with the given |capacity|. If more elements than
|
||||
// |capacity| are added to the queue, the caller is blocked until space is
|
||||
// made available in the queue. Returns NULL on failure. The caller must free
|
||||
// the returned queue with |fixed_pkt_queue_free|.
|
||||
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity);
|
||||
|
||||
// Freeing a queue that is currently in use (i.e. has waiters
|
||||
// blocked on it) results in undefined behaviour.
|
||||
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb);
|
||||
|
||||
// Returns a value indicating whether the given |queue| is empty. If |queue|
|
||||
// is NULL, the return value is true.
|
||||
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue);
|
||||
|
||||
// Returns the length of the |queue|. If |queue| is NULL, the return value
|
||||
// is 0.
|
||||
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue);
|
||||
|
||||
// Returns the maximum number of elements this queue may hold. |queue| may
|
||||
// not be NULL.
|
||||
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue);
|
||||
|
||||
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
|
||||
// If enqueue failed, it will return false, otherwise return true
|
||||
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout);
|
||||
|
||||
// Dequeues the next element from |queue|. If the queue is currently empty,
|
||||
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
|
||||
// If dequeue failed, it will return NULL, otherwise return a point.
|
||||
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout);
|
||||
|
||||
// Returns the first element from |queue|, if present, without dequeuing it.
|
||||
// This function will never block the caller. Returns NULL if there are no
|
||||
// elements in the queue or |queue| is NULL.
|
||||
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue);
|
||||
|
||||
// Registers |queue| with |reactor| for dequeue operations. When there is an element
|
||||
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
|
||||
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
|
||||
// |context| may be NULL.
|
||||
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb);
|
||||
|
||||
// Unregisters the dequeue ready callback for |queue| from whichever reactor
|
||||
// it is registered with, if any. This function is idempotent.
|
||||
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue);
|
||||
|
||||
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,125 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _FIXED_QUEUE_H_
|
||||
#define _FIXED_QUEUE_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "osi/list.h"
|
||||
#include "osi/semaphore.h"
|
||||
|
||||
#ifndef QUEUE_SIZE_MAX
|
||||
#define QUEUE_SIZE_MAX 254
|
||||
#endif
|
||||
|
||||
#define FIXED_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
|
||||
|
||||
struct fixed_queue_t;
|
||||
|
||||
typedef struct fixed_queue_t fixed_queue_t;
|
||||
//typedef struct reactor_t reactor_t;
|
||||
|
||||
typedef void (*fixed_queue_free_cb)(void *data);
|
||||
typedef void (*fixed_queue_cb)(fixed_queue_t *queue);
|
||||
|
||||
// Creates a new fixed queue with the given |capacity|. If more elements than
|
||||
// |capacity| are added to the queue, the caller is blocked until space is
|
||||
// made available in the queue. Returns NULL on failure. The caller must free
|
||||
// the returned queue with |fixed_queue_free|.
|
||||
fixed_queue_t *fixed_queue_new(size_t capacity);
|
||||
|
||||
// Freeing a queue that is currently in use (i.e. has waiters
|
||||
// blocked on it) results in undefined behaviour.
|
||||
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb);
|
||||
|
||||
// Returns a value indicating whether the given |queue| is empty. If |queue|
|
||||
// is NULL, the return value is true.
|
||||
bool fixed_queue_is_empty(fixed_queue_t *queue);
|
||||
|
||||
// Returns the length of the |queue|. If |queue| is NULL, the return value
|
||||
// is 0.
|
||||
size_t fixed_queue_length(fixed_queue_t *queue);
|
||||
|
||||
// Returns the maximum number of elements this queue may hold. |queue| may
|
||||
// not be NULL.
|
||||
size_t fixed_queue_capacity(fixed_queue_t *queue);
|
||||
|
||||
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
|
||||
// If enqueue failed, it will return false, otherwise return true
|
||||
bool fixed_queue_enqueue(fixed_queue_t *queue, void *data, uint32_t timeout);
|
||||
|
||||
// Dequeues the next element from |queue|. If the queue is currently empty,
|
||||
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
|
||||
// If dequeue failed, it will return NULL, otherwise return a point.
|
||||
void *fixed_queue_dequeue(fixed_queue_t *queue, uint32_t timeout);
|
||||
|
||||
// Returns the first element from |queue|, if present, without dequeuing it.
|
||||
// This function will never block the caller. Returns NULL if there are no
|
||||
// elements in the queue or |queue| is NULL.
|
||||
void *fixed_queue_try_peek_first(fixed_queue_t *queue);
|
||||
|
||||
// Returns the last element from |queue|, if present, without dequeuing it.
|
||||
// This function will never block the caller. Returns NULL if there are no
|
||||
// elements in the queue or |queue| is NULL.
|
||||
void *fixed_queue_try_peek_last(fixed_queue_t *queue);
|
||||
|
||||
// Tries to remove a |data| element from the middle of the |queue|. This
|
||||
// function will never block the caller. If the queue is empty or NULL, this
|
||||
// function returns NULL immediately. |data| may not be NULL. If the |data|
|
||||
// element is found in the queue, a pointer to the removed data is returned,
|
||||
// otherwise NULL.
|
||||
void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data);
|
||||
|
||||
// Returns the iterateable list with all entries in the |queue|. This function
|
||||
// will never block the caller. |queue| may not be NULL.
|
||||
//
|
||||
// NOTE: The return result of this function is not thread safe: the list could
|
||||
// be modified by another thread, and the result would be unpredictable.
|
||||
// TODO: The usage of this function should be refactored, and the function
|
||||
// itself should be removed.
|
||||
list_t *fixed_queue_get_list(fixed_queue_t *queue);
|
||||
|
||||
// This function returns a valid file descriptor. Callers may perform one
|
||||
// operation on the fd: select(2). If |select| indicates that the file
|
||||
// descriptor is readable, the caller may call |fixed_queue_enqueue| without
|
||||
// blocking. The caller must not close the returned file descriptor. |queue|
|
||||
// may not be NULL.
|
||||
//int fixed_queue_get_enqueue_fd(const fixed_queue_t *queue);
|
||||
|
||||
// This function returns a valid file descriptor. Callers may perform one
|
||||
// operation on the fd: select(2). If |select| indicates that the file
|
||||
// descriptor is readable, the caller may call |fixed_queue_dequeue| without
|
||||
// blocking. The caller must not close the returned file descriptor. |queue|
|
||||
// may not be NULL.
|
||||
//int fixed_queue_get_dequeue_fd(const fixed_queue_t *queue);
|
||||
|
||||
// Registers |queue| with |reactor| for dequeue operations. When there is an element
|
||||
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
|
||||
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
|
||||
// |context| may be NULL.
|
||||
void fixed_queue_register_dequeue(fixed_queue_t *queue, fixed_queue_cb ready_cb);
|
||||
|
||||
// Unregisters the dequeue ready callback for |queue| from whichever reactor
|
||||
// it is registered with, if any. This function is idempotent.
|
||||
void fixed_queue_unregister_dequeue(fixed_queue_t *queue);
|
||||
|
||||
void fixed_queue_process(fixed_queue_t *queue);
|
||||
|
||||
list_t *fixed_queue_get_list(fixed_queue_t *queue);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __FUTURE_H__
|
||||
#define __FUTURE_H__
|
||||
|
||||
#include "osi/semaphore.h"
|
||||
|
||||
struct future {
|
||||
bool ready_can_be_called;
|
||||
osi_sem_t semaphore; // NULL semaphore means immediate future
|
||||
void *result;
|
||||
};
|
||||
typedef struct future future_t;
|
||||
|
||||
#define FUTURE_SUCCESS ((void *)1)
|
||||
#define FUTURE_FAIL ((void *)0)
|
||||
|
||||
// Constructs a new future_t object. Returns NULL on failure.
|
||||
future_t *future_new(void);
|
||||
|
||||
// Constructs a new future_t object with an immediate |value|. No waiting will
|
||||
// occur in the call to |future_await| because the value is already present.
|
||||
// Returns NULL on failure.
|
||||
future_t *future_new_immediate(void *value);
|
||||
|
||||
// Signals that the |future| is ready, passing |value| back to the context
|
||||
// waiting for the result. Must only be called once for every future.
|
||||
// |future| may not be NULL.
|
||||
void future_ready(future_t *future, void *value);
|
||||
|
||||
// Waits for the |future| to be ready. Returns the value set in |future_ready|.
|
||||
// Frees the future before return. |future| may not be NULL.
|
||||
void *future_await(future_t *async_result);
|
||||
|
||||
//Free the future if this "future" is not used
|
||||
void future_free(future_t *future);
|
||||
#endif /* __FUTURE_H__ */
|
||||
@@ -0,0 +1,37 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _HASH_FUNCTIONS_H_
|
||||
#define _HASH_FUNCTIONS_H_
|
||||
|
||||
#include "osi/hash_map.h"
|
||||
|
||||
typedef unsigned char hash_key_t[4];
|
||||
|
||||
hash_index_t hash_function_naive(const void *key);
|
||||
|
||||
hash_index_t hash_function_integer(const void *key);
|
||||
|
||||
// Hashes a pointer based only on its address value
|
||||
hash_index_t hash_function_pointer(const void *key);
|
||||
|
||||
hash_index_t hash_function_string(const void *key);
|
||||
|
||||
void hash_function_blob(const unsigned char *s, unsigned int len, hash_key_t h);
|
||||
|
||||
#endif /* _HASH_FUNCTIONS_H_ */
|
||||
@@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _HASH_MAP_H_
|
||||
#define _HASH_MAP_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct hash_map_t;
|
||||
typedef struct hash_map_t hash_map_t;
|
||||
|
||||
typedef struct hash_map_entry_t {
|
||||
const void *key;
|
||||
void *data;
|
||||
const hash_map_t *hash_map;
|
||||
} hash_map_entry_t;
|
||||
|
||||
typedef size_t hash_index_t;
|
||||
|
||||
// Takes a key structure and returns a hash value.
|
||||
typedef hash_index_t (*hash_index_fn)(const void *key);
|
||||
typedef bool (*hash_map_iter_cb)(hash_map_entry_t *hash_entry, void *context);
|
||||
|
||||
typedef bool (*key_equality_fn)(const void *x, const void *y);
|
||||
|
||||
typedef void (*key_free_fn)(void *data);
|
||||
typedef void (*data_free_fn)(void *data);
|
||||
|
||||
// Returns a new, empty hash_map. Returns NULL if not enough memory could be allocated
|
||||
// for the hash_map structure. The returned hash_map must be freed with |hash_map_free|.
|
||||
// The |num_bucket| specifies the number of hashable buckets for the map and must not
|
||||
// be zero. The |hash_fn| specifies a hash function to be used and must not be NULL.
|
||||
// The |key_fn| and |data_fn| are called whenever a hash_map element is removed from
|
||||
// the hash_map. They can be used to release resources held by the hash_map element,
|
||||
// e.g. memory or file descriptor. |key_fn| and |data_fn| may be NULL if no cleanup
|
||||
// is necessary on element removal. |equality_fn| is used to check for key equality.
|
||||
// If |equality_fn| is NULL, default pointer equality is used.
|
||||
hash_map_t *hash_map_new(
|
||||
size_t size,
|
||||
hash_index_fn hash_fn,
|
||||
key_free_fn key_fn,
|
||||
data_free_fn data_fn,
|
||||
key_equality_fn equality_fn);
|
||||
|
||||
// Frees the hash_map. This function accepts NULL as an argument, in which case it
|
||||
// behaves like a no-op.
|
||||
void hash_map_free(hash_map_t *hash_map);
|
||||
|
||||
// Returns true if the hash_map is empty (has no elements), false otherwise.
|
||||
// Note that a NULL |hash_map| is not the same as an empty |hash_map|. This function
|
||||
// does not accept a NULL |hash_map|.
|
||||
//bool hash_map_is_empty(const hash_map_t *hash_map);
|
||||
|
||||
// Returns the number of elements in the hash map. This function does not accept a
|
||||
// NULL |hash_map|.
|
||||
//size_t hash_map_size(const hash_map_t *hash_map);
|
||||
|
||||
// Returns the number of buckets in the hash map. This function does not accept a
|
||||
// NULL |hash_map|.
|
||||
//size_t hash_map_num_buckets(const hash_map_t *hash_map);
|
||||
|
||||
// Returns true if the hash_map has a valid entry for the presented key.
|
||||
// This function does not accept a NULL |hash_map|.
|
||||
bool hash_map_has_key(const hash_map_t *hash_map, const void *key);
|
||||
|
||||
// Returns the element indexed by |key| in the hash_map without removing it. |hash_map|
|
||||
// may not be NULL. Returns NULL if no entry indexed by |key|.
|
||||
void *hash_map_get(const hash_map_t *hash_map, const void *key);
|
||||
|
||||
// Sets the value |data| indexed by |key| into the |hash_map|. Neither |data| nor
|
||||
// |hash_map| may be NULL. This function does not make copies of |data| nor |key|
|
||||
// so the pointers must remain valid at least until the element is removed from the
|
||||
// hash_map or the hash_map is freed. Returns true if |data| could be set, false
|
||||
// otherwise (e.g. out of memory).
|
||||
bool hash_map_set(hash_map_t *hash_map, const void *key, void *data);
|
||||
|
||||
// Removes data indexed by |key| from the hash_map. |hash_map| may not be NULL.
|
||||
// If |key_fn| or |data_fn| functions were specified in |hash_map_new|, they
|
||||
// will be called back with |key| or |data| respectively. This function returns true
|
||||
// if |key| was found in the hash_map and removed, false otherwise.
|
||||
bool hash_map_erase(hash_map_t *hash_map, const void *key);
|
||||
|
||||
// Removes all elements in the hash_map. Calling this function will return the hash_map
|
||||
// to the same state it was in after |hash_map_new|. |hash_map| may not be NULL.
|
||||
void hash_map_clear(hash_map_t *hash_map);
|
||||
|
||||
// Iterates through the entire |hash_map| and calls |callback| for each data
|
||||
// element and passes through the |context| argument. If the hash_map is
|
||||
// empty, |callback| will never be called. It is not safe to mutate the
|
||||
// hash_map inside the callback. Neither |hash_map| nor |callback| may be NULL.
|
||||
// If |callback| returns false, the iteration loop will immediately exit.
|
||||
void hash_map_foreach(hash_map_t *hash_map, hash_map_iter_cb callback, void *context);
|
||||
|
||||
#endif /* _HASH_MAP_H_ */
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef _LIST_H_
|
||||
#define _LIST_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
struct list_node_t;
|
||||
typedef struct list_node_t list_node_t;
|
||||
|
||||
struct list_t;
|
||||
typedef struct list_t list_t;
|
||||
|
||||
typedef void (*list_free_cb)(void *data);
|
||||
typedef bool (*list_iter_cb)(void *data, void *context);
|
||||
|
||||
// Returns a new, empty list. Returns NULL if not enough memory could be allocated
|
||||
// for the list structure. The returned list must be freed with |list_free|. The
|
||||
// |callback| specifies a function to be called whenever a list element is removed
|
||||
// from the list. It can be used to release resources held by the list element, e.g.
|
||||
// memory or file descriptor. |callback| may be NULL if no cleanup is necessary on
|
||||
// element removal.
|
||||
list_t *list_new(list_free_cb callback);
|
||||
|
||||
|
||||
list_node_t *list_free_node(list_t *list, list_node_t *node);
|
||||
|
||||
// similar with list_free_node, this function doesn't free the node data
|
||||
list_node_t *list_delete_node(list_t *list, list_node_t *node);
|
||||
|
||||
// Frees the list. This function accepts NULL as an argument, in which case it
|
||||
// behaves like a no-op.
|
||||
void list_free(list_t *list);
|
||||
|
||||
// Returns true if |list| is empty (has no elements), false otherwise.
|
||||
// |list| may not be NULL.
|
||||
bool list_is_empty(const list_t *list);
|
||||
|
||||
// Returns true if the list contains |data|, false otherwise.
|
||||
// |list| may not be NULL.
|
||||
bool list_contains(const list_t *list, const void *data);
|
||||
|
||||
// Returns list_node which contains |data|, NULL otherwise.
|
||||
// |list| may not be NULL.
|
||||
list_node_t *list_get_node(const list_t *list, const void *data);
|
||||
|
||||
// Returns the length of the |list|. |list| may not be NULL.
|
||||
size_t list_length(const list_t *list);
|
||||
|
||||
// Returns the first element in the list without removing it. |list| may not
|
||||
// be NULL or empty.
|
||||
void *list_front(const list_t *list);
|
||||
|
||||
// Returns the last element in the list without removing it. |list| may not
|
||||
// be NULL or empty.
|
||||
void *list_back(const list_t *list);
|
||||
list_node_t *list_back_node(const list_t *list);
|
||||
|
||||
// Inserts |data| after |prev_node| in |list|. |data|, |list|, and |prev_node|
|
||||
// may not be NULL. This function does not make a copy of |data| so the pointer
|
||||
// must remain valid at least until the element is removed from the list or the
|
||||
// list is freed. Returns true if |data| could be inserted, false otherwise
|
||||
// (e.g. out of memory).
|
||||
bool list_insert_after(list_t *list, list_node_t *prev_node, void *data);
|
||||
|
||||
// Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL.
|
||||
// This function does not make a copy of |data| so the pointer must remain valid
|
||||
// at least until the element is removed from the list or the list is freed.
|
||||
// Returns true if |data| could be inserted, false otherwise (e.g. out of memory).
|
||||
bool list_prepend(list_t *list, void *data);
|
||||
|
||||
// Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL.
|
||||
// This function does not make a copy of |data| so the pointer must remain valid
|
||||
// at least until the element is removed from the list or the list is freed.
|
||||
// Returns true if |data| could be inserted, false otherwise (e.g. out of memory).
|
||||
bool list_append(list_t *list, void *data);
|
||||
|
||||
// Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data|
|
||||
// is inserted multiple times in the list, this function will only remove the first
|
||||
// instance. If a free function was specified in |list_new|, it will be called back
|
||||
// with |data|. This function returns true if |data| was found in the list and removed,
|
||||
// false otherwise.
|
||||
//list_node_t list_remove_node(list_t *list, list_node_t *prev_node, list_node_t *node);
|
||||
//list_node_t list_insert_node(list_t *list, list_node_t *prev_node, list_node_t *node);
|
||||
|
||||
bool list_remove(list_t *list, void *data);
|
||||
|
||||
// similar with list_remove, but do not free the node data
|
||||
bool list_delete(list_t *list, void *data);
|
||||
|
||||
// Removes all elements in the list. Calling this function will return the list to the
|
||||
// same state it was in after |list_new|. |list| may not be NULL.
|
||||
void list_clear(list_t *list);
|
||||
|
||||
// Iterates through the entire |list| and calls |callback| for each data element.
|
||||
// If the list is empty, |callback| will never be called. It is safe to mutate the
|
||||
// list inside the callback. If an element is added before the node being visited,
|
||||
// there will be no callback for the newly-inserted node. Neither |list| nor
|
||||
// |callback| may be NULL.
|
||||
list_node_t *list_foreach(const list_t *list, list_iter_cb callback, void *context);
|
||||
|
||||
// Returns an iterator to the first element in |list|. |list| may not be NULL.
|
||||
// The returned iterator is valid as long as it does not equal the value returned
|
||||
// by |list_end|.
|
||||
list_node_t *list_begin(const list_t *list);
|
||||
|
||||
// Returns an iterator that points past the end of the list. In other words,
|
||||
// this function returns the value of an invalid iterator for the given list.
|
||||
// When an iterator has the same value as what's returned by this function, you
|
||||
// may no longer call |list_next| with the iterator. |list| may not be NULL.
|
||||
list_node_t *list_end(const list_t *list);
|
||||
|
||||
// Given a valid iterator |node|, this function returns the next value for the
|
||||
// iterator. If the returned value equals the value returned by |list_end|, the
|
||||
// iterator has reached the end of the list and may no longer be used for any
|
||||
// purpose.
|
||||
list_node_t *list_next(const list_node_t *node);
|
||||
|
||||
// Returns the value stored at the location pointed to by the iterator |node|.
|
||||
// |node| must not equal the value returned by |list_end|.
|
||||
void *list_node(const list_node_t *node);
|
||||
|
||||
#endif /* _LIST_H_ */
|
||||
@@ -0,0 +1,52 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __MUTEX_H__
|
||||
#define __MUTEX_H__
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "osi/semaphore.h"
|
||||
|
||||
#define OSI_MUTEX_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
|
||||
|
||||
#define osi_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define osi_mutex_set_invalid( x ) ( ( *x ) = NULL )
|
||||
|
||||
typedef SemaphoreHandle_t osi_mutex_t;
|
||||
|
||||
int osi_mutex_new(osi_mutex_t *mutex);
|
||||
|
||||
int osi_mutex_lock(osi_mutex_t *mutex, uint32_t timeout);
|
||||
|
||||
void osi_mutex_unlock(osi_mutex_t *mutex);
|
||||
|
||||
void osi_mutex_free(osi_mutex_t *mutex);
|
||||
|
||||
/* Just for a global mutex */
|
||||
int osi_mutex_global_init(void);
|
||||
|
||||
void osi_mutex_global_deinit(void);
|
||||
|
||||
void osi_mutex_global_lock(void);
|
||||
|
||||
void osi_mutex_global_unlock(void);
|
||||
|
||||
#endif /* __MUTEX_H__ */
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
#ifndef _OSI_H_
|
||||
#define _OSI_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define UNUSED_ATTR __attribute__((unused))
|
||||
|
||||
#define CONCAT(a, b) a##b
|
||||
#define COMPILE_ASSERT(x)
|
||||
|
||||
int osi_init(void);
|
||||
void osi_deinit(void);
|
||||
|
||||
#endif /*_OSI_H_*/
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _PKT_LIST_H_
|
||||
#define _PKT_LIST_H_
|
||||
|
||||
#include "sys/queue.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct pkt_queue;
|
||||
|
||||
typedef struct pkt_linked_item {
|
||||
STAILQ_ENTRY(pkt_linked_item) next;
|
||||
uint8_t data[];
|
||||
} pkt_linked_item_t;
|
||||
|
||||
#define BT_PKT_LINKED_HDR_SIZE (sizeof (pkt_linked_item_t))
|
||||
|
||||
typedef void (*pkt_queue_free_cb)(pkt_linked_item_t *item);
|
||||
|
||||
/*
|
||||
* brief: create a pkt_queue instance. pkt_queue is a wrapper class of a FIFO implemented by single linked list.
|
||||
* The enqueue and dequeue operations of the FIFO are protected against race conditions of multiple tasks
|
||||
* return: NULL if not enough memory, otherwise a valid pointer
|
||||
*/
|
||||
struct pkt_queue *pkt_queue_create(void);
|
||||
|
||||
/*
|
||||
* brief: enqueue one item to the FIFO
|
||||
* param queue: pkt_queue instance created using pkt_queue_create
|
||||
* param item: the item to be enqueued to the FIFO
|
||||
* return: true if enqueued successfully, false when the arguments passed in are invalid
|
||||
*/
|
||||
bool pkt_queue_enqueue(struct pkt_queue *queue, pkt_linked_item_t *item);
|
||||
|
||||
/*
|
||||
* brief: dequeue one item for the FIFO
|
||||
* param queue: pkt_queue instance created using pkt_queue_create
|
||||
* return: pointer of type pkt_linked_item_t dequeued, NULL if the queue is empty or upon exception
|
||||
*/
|
||||
pkt_linked_item_t *pkt_queue_dequeue(struct pkt_queue *queue);
|
||||
|
||||
/*
|
||||
* brief: get the pointer of the first item from the FIFO but not get it dequeued
|
||||
* param queue: pkt_queue instance created using pkt_queue_create
|
||||
* return: pointer of the first item in the FIFO, NULL if the FIFO is empty
|
||||
*/
|
||||
pkt_linked_item_t *pkt_queue_try_peek_first(struct pkt_queue *queue);
|
||||
|
||||
/*
|
||||
* brief: retrieve the number of items existing in the FIFO
|
||||
* param queue: pkt_queue instance created using pkt_queue_create
|
||||
* return: total number of items in the FIFO
|
||||
*/
|
||||
size_t pkt_queue_length(const struct pkt_queue *queue);
|
||||
|
||||
/*
|
||||
* brief: retrieve the status whether the FIFO is empty
|
||||
* param queue: pkt_queue instance created using pkt_queue_create
|
||||
* return: false if the FIFO is not empty, otherwise true
|
||||
*/
|
||||
bool pkt_queue_is_empty(const struct pkt_queue *queue);
|
||||
|
||||
/*
|
||||
* brief: delete the item in the FIFO one by one
|
||||
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default
|
||||
*/
|
||||
void pkt_queue_flush(struct pkt_queue *queue, pkt_queue_free_cb free_cb);
|
||||
|
||||
/*
|
||||
* brief: delete the items in the FIFO and then destroy the pkt_queue instance.
|
||||
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default
|
||||
*/
|
||||
void pkt_queue_destroy(struct pkt_queue *queue, pkt_queue_free_cb free_cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __SEMAPHORE_H__
|
||||
#define __SEMAPHORE_H__
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#define OSI_SEM_MAX_TIMEOUT 0xffffffffUL
|
||||
|
||||
typedef SemaphoreHandle_t osi_sem_t;
|
||||
|
||||
#define osi_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define osi_sem_set_invalid( x ) ( ( *x ) = NULL )
|
||||
|
||||
int osi_sem_new(osi_sem_t *sem, uint32_t max_count, uint32_t init_count);
|
||||
|
||||
void osi_sem_free(osi_sem_t *sem);
|
||||
|
||||
int osi_sem_take(osi_sem_t *sem, uint32_t timeout);
|
||||
|
||||
void osi_sem_give(osi_sem_t *sem);
|
||||
|
||||
|
||||
#endif /* __SEMAPHORE_H__ */
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __THREAD_H__
|
||||
#define __THREAD_H__
|
||||
|
||||
#include "freertos/FreeRTOSConfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "osi/semaphore.h"
|
||||
#include "esp_task.h"
|
||||
#include "bt_common.h"
|
||||
|
||||
#define OSI_THREAD_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
|
||||
|
||||
struct osi_thread;
|
||||
struct osi_event;
|
||||
|
||||
typedef struct osi_thread osi_thread_t;
|
||||
|
||||
typedef void (*osi_thread_func_t)(void *context);
|
||||
|
||||
typedef enum {
|
||||
OSI_THREAD_CORE_0 = 0,
|
||||
OSI_THREAD_CORE_1,
|
||||
OSI_THREAD_CORE_AFFINITY,
|
||||
} osi_thread_core_t;
|
||||
|
||||
/*
|
||||
* brief: Create a thread or task
|
||||
* param name: thread name
|
||||
* param stack_size: thread stack size
|
||||
* param priority: thread priority
|
||||
* param core: the CPU core which this thread run, OSI_THREAD_CORE_AFFINITY means unspecific CPU core
|
||||
* param work_queue_num: speicify queue number, the queue[0] has highest priority, and the priority is decrease by index
|
||||
* return : if create successfully, return thread handler; otherwise return NULL.
|
||||
*/
|
||||
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[]);
|
||||
|
||||
/*
|
||||
* brief: Destroy a thread or task
|
||||
* param thread: point of thread handler
|
||||
*/
|
||||
void osi_thread_free(osi_thread_t *thread);
|
||||
|
||||
/*
|
||||
* brief: Post an msg to a thread and told the thread call the function
|
||||
* param thread: point of thread handler
|
||||
* param func: callback function that called by target thread
|
||||
* param context: argument of callback function
|
||||
* param queue_idx: the queue which the msg send to
|
||||
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
|
||||
* return : if post successfully, return true, otherwise return false
|
||||
*/
|
||||
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout);
|
||||
|
||||
/*
|
||||
* brief: Set the priority of thread
|
||||
* param thread: point of thread handler
|
||||
* param priority: priority
|
||||
* return : if set successfully, return true, otherwise return false
|
||||
*/
|
||||
bool osi_thread_set_priority(osi_thread_t *thread, int priority);
|
||||
|
||||
/* brief: Get thread name
|
||||
* param thread: point of thread handler
|
||||
* return: constant point of thread name
|
||||
*/
|
||||
const char *osi_thread_name(osi_thread_t *thread);
|
||||
|
||||
/* brief: Get the size of the specified queue
|
||||
* param thread: point of thread handler
|
||||
* param wq_idx: the queue index of the thread
|
||||
* return: queue size
|
||||
*/
|
||||
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
|
||||
|
||||
/*
|
||||
* brief: Create an osi_event struct and register the handler function and its argument
|
||||
* An osi_event is a kind of work that can be posted to the workqueue of osi_thread to process,
|
||||
* but the work can have at most one instance the thread workqueue before it is processed. This
|
||||
* allows the "single post, multiple data processing" jobs.
|
||||
* param func: the handler to process the job
|
||||
* param context: the argument to be passed to the handler function when the job is being processed
|
||||
* return: NULL if no memory, otherwise a valid struct pointer
|
||||
*/
|
||||
struct osi_event *osi_event_create(osi_thread_func_t func, void *context);
|
||||
|
||||
/*
|
||||
* brief: Bind an osi_event to a specific work queue for an osi_thread.
|
||||
* After binding is completed, a function call of API osi_thread_post_event will send a work
|
||||
* to the workqueue of the thread, with specified queue index.
|
||||
* param func: event: the pointer to osi_event that is created using osi_event_create
|
||||
* param thread: the pointer to osi_thread that is created using osi_thread_create
|
||||
* param queue_idx: the index of the workqueue of the specified osi_thread, with range starting from 0 to work_queue_num - 1
|
||||
* return: true if osi_event binds to the thread's workqueue successfully, otherwise false
|
||||
*/
|
||||
bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx);
|
||||
|
||||
/*
|
||||
* brief: Destroy the osi_event struct created by osi_event_create and free the allocated memory
|
||||
* param event: the pointer to osi_event
|
||||
*/
|
||||
void osi_event_delete(struct osi_event* event);
|
||||
|
||||
/*
|
||||
* brief: try sending a work to the binded thread's workqueue, so that it can be handled by the worker thread
|
||||
* param event: pointer to osi_event, created by osi_event_create
|
||||
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
|
||||
* return: true if the message is enqueued to the thread workqueue, otherwise failed
|
||||
* note: if the return value of function is false, it is the case that the workqueue of the thread is full, and users
|
||||
* are expected to post the event sometime later to get the work handled.
|
||||
*/
|
||||
bool osi_thread_post_event(struct osi_event *event, uint32_t timeout);
|
||||
|
||||
#endif /* __THREAD_H__ */
|
||||
@@ -0,0 +1,312 @@
|
||||
|
||||
#include "bt_common.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/list.h"
|
||||
#include "osi/osi.h"
|
||||
|
||||
struct list_node_t {
|
||||
struct list_node_t *next;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef struct list_t {
|
||||
list_node_t *head;
|
||||
list_node_t *tail;
|
||||
size_t length;
|
||||
list_free_cb free_cb;
|
||||
} list_t;
|
||||
|
||||
//static list_node_t *list_free_node_(list_t *list, list_node_t *node);
|
||||
|
||||
// Hidden constructor, only to be used by the hash map for the allocation tracker.
|
||||
// Behaves the same as |list_new|, except you get to specify the allocator.
|
||||
list_t *list_new_internal(list_free_cb callback)
|
||||
{
|
||||
list_t *list = (list_t *) osi_calloc(sizeof(list_t));
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->head = list->tail = NULL;
|
||||
list->length = 0;
|
||||
list->free_cb = callback;
|
||||
return list;
|
||||
}
|
||||
|
||||
list_t *list_new(list_free_cb callback)
|
||||
{
|
||||
return list_new_internal(callback);
|
||||
}
|
||||
|
||||
void list_free(list_t *list)
|
||||
{
|
||||
if (!list) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_clear(list);
|
||||
osi_free(list);
|
||||
}
|
||||
|
||||
bool list_is_empty(const list_t *list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
return (list->length == 0);
|
||||
}
|
||||
|
||||
bool list_contains(const list_t *list, const void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
for (const list_node_t *node = list_begin(list); node != list_end(list); node = list_next(node)) {
|
||||
if (list_node(node) == data) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
list_node_t *list_get_node(const list_t *list, const void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
list_node_t *p_node_ret = NULL;
|
||||
for (list_node_t *node = list_begin(list); node != list_end(list); node = list_next(node)) {
|
||||
if (list_node(node) == data) {
|
||||
p_node_ret = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return p_node_ret;
|
||||
}
|
||||
|
||||
size_t list_length(const list_t *list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
return list->length;
|
||||
}
|
||||
|
||||
void *list_front(const list_t *list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(!list_is_empty(list));
|
||||
|
||||
return list->head->data;
|
||||
}
|
||||
|
||||
void *list_back(const list_t *list) {
|
||||
assert(list != NULL);
|
||||
assert(!list_is_empty(list));
|
||||
|
||||
return list->tail->data;
|
||||
}
|
||||
|
||||
list_node_t *list_back_node(const list_t *list) {
|
||||
assert(list != NULL);
|
||||
assert(!list_is_empty(list));
|
||||
|
||||
return list->tail;
|
||||
}
|
||||
|
||||
bool list_insert_after(list_t *list, list_node_t *prev_node, void *data) {
|
||||
assert(list != NULL);
|
||||
assert(prev_node != NULL);
|
||||
assert(data != NULL);
|
||||
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t));
|
||||
if (!node) {
|
||||
OSI_TRACE_ERROR("%s osi_calloc failed.\n", __FUNCTION__ );
|
||||
return false;
|
||||
}
|
||||
node->next = prev_node->next;
|
||||
node->data = data;
|
||||
prev_node->next = node;
|
||||
if (list->tail == prev_node) {
|
||||
list->tail = node;
|
||||
}
|
||||
++list->length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool list_prepend(list_t *list, void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t));
|
||||
if (!node) {
|
||||
OSI_TRACE_ERROR("%s osi_calloc failed.\n", __FUNCTION__ );
|
||||
return false;
|
||||
}
|
||||
node->next = list->head;
|
||||
node->data = data;
|
||||
list->head = node;
|
||||
if (list->tail == NULL) {
|
||||
list->tail = list->head;
|
||||
}
|
||||
++list->length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool list_append(list_t *list, void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t));
|
||||
if (!node) {
|
||||
OSI_TRACE_ERROR("%s osi_calloc failed.\n", __FUNCTION__ );
|
||||
return false;
|
||||
}
|
||||
node->next = NULL;
|
||||
node->data = data;
|
||||
if (list->tail == NULL) {
|
||||
list->head = node;
|
||||
list->tail = node;
|
||||
} else {
|
||||
list->tail->next = node;
|
||||
list->tail = node;
|
||||
}
|
||||
++list->length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool list_remove(list_t *list, void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
if (list_is_empty(list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (list->head->data == data) {
|
||||
list_node_t *next = list_free_node(list, list->head);
|
||||
if (list->tail == list->head) {
|
||||
list->tail = next;
|
||||
}
|
||||
list->head = next;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (list_node_t *prev = list->head, *node = list->head->next; node; prev = node, node = node->next)
|
||||
if (node->data == data) {
|
||||
prev->next = list_free_node(list, node);
|
||||
if (list->tail == node) {
|
||||
list->tail = prev;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool list_delete(list_t *list, void *data)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
if (list_is_empty(list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (list->head->data == data) {
|
||||
list_node_t *next = list_delete_node(list, list->head);
|
||||
if (list->tail == list->head) {
|
||||
list->tail = next;
|
||||
}
|
||||
list->head = next;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (list_node_t *prev = list->head, *node = list->head->next; node; prev = node, node = node->next)
|
||||
if (node->data == data) {
|
||||
prev->next = list_delete_node(list, node);
|
||||
if (list->tail == node) {
|
||||
list->tail = prev;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void list_clear(list_t *list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
for (list_node_t *node = list->head; node; ) {
|
||||
node = list_free_node(list, node);
|
||||
}
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
list->length = 0;
|
||||
}
|
||||
|
||||
list_node_t *list_foreach(const list_t *list, list_iter_cb callback, void *context)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(callback != NULL);
|
||||
|
||||
for (list_node_t *node = list->head; node; ) {
|
||||
list_node_t *next = node->next;
|
||||
if (!callback(node->data, context)) {
|
||||
return node;
|
||||
}
|
||||
node = next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_node_t *list_begin(const list_t *list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
return list->head;
|
||||
}
|
||||
|
||||
list_node_t *list_end(UNUSED_ATTR const list_t *list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_node_t *list_next(const list_node_t *node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return node->next;
|
||||
}
|
||||
|
||||
void *list_node(const list_node_t *node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return node->data;
|
||||
}
|
||||
|
||||
list_node_t *list_free_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(node != NULL);
|
||||
|
||||
list_node_t *next = node->next;
|
||||
|
||||
if (list->free_cb) {
|
||||
list->free_cb(node->data);
|
||||
}
|
||||
osi_free(node);
|
||||
--list->length;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
// remove the element from list but do not free the node data
|
||||
list_node_t *list_delete_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(node != NULL);
|
||||
|
||||
list_node_t *next = node->next;
|
||||
|
||||
osi_free(node);
|
||||
--list->length;
|
||||
|
||||
return next;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "osi/mutex.h"
|
||||
|
||||
|
||||
/* static section */
|
||||
static osi_mutex_t gl_mutex; /* Recursive Type */
|
||||
|
||||
|
||||
/** Create a new mutex
|
||||
* @param mutex pointer to the mutex to create
|
||||
* @return a new mutex */
|
||||
int osi_mutex_new(osi_mutex_t *mutex)
|
||||
{
|
||||
int xReturn = -1;
|
||||
|
||||
*mutex = xSemaphoreCreateMutex();
|
||||
|
||||
if (*mutex != NULL) {
|
||||
xReturn = 0;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/** Lock a mutex
|
||||
* @param mutex the mutex to lock */
|
||||
int osi_mutex_lock(osi_mutex_t *mutex, uint32_t timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (timeout == OSI_MUTEX_MAX_TIMEOUT) {
|
||||
if (xSemaphoreTake(*mutex, portMAX_DELAY) != pdTRUE) {
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
if (xSemaphoreTake(*mutex, timeout / portTICK_PERIOD_MS) != pdTRUE) {
|
||||
ret = -2;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Unlock a mutex
|
||||
* @param mutex the mutex to unlock */
|
||||
void osi_mutex_unlock(osi_mutex_t *mutex)
|
||||
{
|
||||
xSemaphoreGive(*mutex);
|
||||
}
|
||||
|
||||
/** Delete a semaphore
|
||||
* @param mutex the mutex to delete */
|
||||
void osi_mutex_free(osi_mutex_t *mutex)
|
||||
{
|
||||
vSemaphoreDelete(*mutex);
|
||||
*mutex = NULL;
|
||||
}
|
||||
|
||||
int osi_mutex_global_init(void)
|
||||
{
|
||||
gl_mutex = xSemaphoreCreateRecursiveMutex();
|
||||
if (gl_mutex == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void osi_mutex_global_deinit(void)
|
||||
{
|
||||
vSemaphoreDelete(gl_mutex);
|
||||
}
|
||||
|
||||
void osi_mutex_global_lock(void)
|
||||
{
|
||||
xSemaphoreTakeRecursive(gl_mutex, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void osi_mutex_global_unlock(void)
|
||||
{
|
||||
xSemaphoreGiveRecursive(gl_mutex);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include "osi/osi.h"
|
||||
#include "osi/mutex.h"
|
||||
|
||||
int osi_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (osi_mutex_global_init() != 0) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void osi_deinit(void)
|
||||
{
|
||||
osi_mutex_global_deinit();
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "osi/pkt_queue.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/mutex.h"
|
||||
|
||||
|
||||
STAILQ_HEAD(pkt_queue_header, pkt_linked_item);
|
||||
|
||||
struct pkt_queue {
|
||||
osi_mutex_t lock;
|
||||
size_t length;
|
||||
struct pkt_queue_header header;
|
||||
} pkt_queue_t;
|
||||
|
||||
struct pkt_queue *pkt_queue_create(void)
|
||||
{
|
||||
struct pkt_queue *queue = calloc(1, sizeof(struct pkt_queue));
|
||||
if (queue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (osi_mutex_new(&queue->lock) != 0) {
|
||||
osi_free(queue);
|
||||
}
|
||||
struct pkt_queue_header *p = &queue->header;
|
||||
STAILQ_INIT(p);
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
static void pkt_queue_cleanup(struct pkt_queue *queue, pkt_queue_free_cb free_cb)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct pkt_queue_header *header = &queue->header;
|
||||
pkt_linked_item_t *item = STAILQ_FIRST(header);
|
||||
pkt_linked_item_t *tmp;
|
||||
|
||||
pkt_queue_free_cb free_func = (free_cb != NULL) ? free_cb : (pkt_queue_free_cb)osi_free_func;
|
||||
|
||||
while (item != NULL) {
|
||||
tmp = STAILQ_NEXT(item, next);
|
||||
free_func(item);
|
||||
item = tmp;
|
||||
queue->length--;
|
||||
}
|
||||
STAILQ_INIT(header);
|
||||
queue->length = 0;
|
||||
}
|
||||
|
||||
void pkt_queue_flush(struct pkt_queue *queue, pkt_queue_free_cb free_cb)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return;
|
||||
}
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
pkt_queue_cleanup(queue, free_cb);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
}
|
||||
|
||||
void pkt_queue_destroy(struct pkt_queue *queue, pkt_queue_free_cb free_cb)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return;
|
||||
}
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
pkt_queue_cleanup(queue, free_cb);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
osi_mutex_free(&queue->lock);
|
||||
osi_free(queue);
|
||||
}
|
||||
|
||||
pkt_linked_item_t *pkt_queue_dequeue(struct pkt_queue *queue)
|
||||
{
|
||||
if (queue == NULL || queue->length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pkt_linked_item *item;
|
||||
struct pkt_queue_header *header;
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
header = &queue->header;
|
||||
item = STAILQ_FIRST(header);
|
||||
if (item != NULL) {
|
||||
STAILQ_REMOVE_HEAD(header, next);
|
||||
if (queue->length > 0) {
|
||||
queue->length--;
|
||||
}
|
||||
}
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
bool pkt_queue_enqueue(struct pkt_queue *queue, pkt_linked_item_t *item)
|
||||
{
|
||||
if (queue == NULL || item == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct pkt_queue_header *header;
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
header = &queue->header;
|
||||
STAILQ_INSERT_TAIL(header, item, next);
|
||||
queue->length++;
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t pkt_queue_length(const struct pkt_queue *queue)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return queue->length;
|
||||
}
|
||||
|
||||
bool pkt_queue_is_empty(const struct pkt_queue *queue)
|
||||
{
|
||||
return pkt_queue_length(queue) == 0;
|
||||
}
|
||||
|
||||
pkt_linked_item_t *pkt_queue_try_peek_first(struct pkt_queue *queue)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pkt_queue_header *header = &queue->header;
|
||||
pkt_linked_item_t *item;
|
||||
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
item = STAILQ_FIRST(header);
|
||||
osi_mutex_unlock(&queue->lock);
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include "osi/semaphore.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
// Creates and returns a new semaphore. The "init_count" argument specifies
|
||||
// the initial state of the semaphore, "max_count" specifies the maximum value
|
||||
// that can be reached.
|
||||
int osi_sem_new(osi_sem_t *sem, uint32_t max_count, uint32_t init_count)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (sem) {
|
||||
*sem = xSemaphoreCreateCounting(max_count, init_count);
|
||||
if ((*sem) != NULL) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
// Give a semaphore
|
||||
void osi_sem_give(osi_sem_t *sem)
|
||||
{
|
||||
xSemaphoreGive(*sem);
|
||||
}
|
||||
|
||||
/*
|
||||
Blocks the thread while waiting for the semaphore to be
|
||||
signaled. If the "timeout" argument is non-zero, the thread should
|
||||
only be blocked for the specified time (measured in
|
||||
milliseconds).
|
||||
|
||||
*/
|
||||
int
|
||||
osi_sem_take(osi_sem_t *sem, uint32_t timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (timeout == OSI_SEM_MAX_TIMEOUT) {
|
||||
if (xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE) {
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
if (xSemaphoreTake(*sem, timeout / portTICK_PERIOD_MS) != pdTRUE) {
|
||||
ret = -2;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Deallocates a semaphore
|
||||
void osi_sem_free(osi_sem_t *sem)
|
||||
{
|
||||
vSemaphoreDelete(*sem);
|
||||
*sem = NULL;
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "osi/allocator.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "osi/semaphore.h"
|
||||
#include "osi/thread.h"
|
||||
#include "osi/mutex.h"
|
||||
|
||||
struct work_item {
|
||||
osi_thread_func_t func;
|
||||
void *context;
|
||||
};
|
||||
|
||||
struct work_queue {
|
||||
QueueHandle_t queue;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
struct osi_thread {
|
||||
TaskHandle_t thread_handle; /*!< Store the thread object */
|
||||
int thread_id; /*!< May for some OS, such as Linux */
|
||||
bool stop;
|
||||
uint8_t work_queue_num; /*!< Work queue number */
|
||||
struct work_queue **work_queues; /*!< Point to queue array, and the priority inverse array index */
|
||||
osi_sem_t work_sem;
|
||||
osi_sem_t stop_sem;
|
||||
};
|
||||
|
||||
struct osi_thread_start_arg {
|
||||
osi_thread_t *thread;
|
||||
osi_sem_t start_sem;
|
||||
int error;
|
||||
};
|
||||
|
||||
struct osi_event {
|
||||
struct work_item item;
|
||||
osi_mutex_t lock;
|
||||
uint16_t is_queued;
|
||||
uint16_t queue_idx;
|
||||
osi_thread_t *thread;
|
||||
};
|
||||
|
||||
static const size_t DEFAULT_WORK_QUEUE_CAPACITY = 100;
|
||||
|
||||
static struct work_queue *osi_work_queue_create(size_t capacity)
|
||||
{
|
||||
if (capacity == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct work_queue *wq = (struct work_queue *)osi_malloc(sizeof(struct work_queue));
|
||||
if (wq != NULL) {
|
||||
wq->queue = xQueueCreate(capacity, sizeof(struct work_item));
|
||||
if (wq->queue != 0) {
|
||||
wq->capacity = capacity;
|
||||
return wq;
|
||||
} else {
|
||||
osi_free(wq);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void osi_work_queue_delete(struct work_queue *wq)
|
||||
{
|
||||
if (wq != NULL) {
|
||||
if (wq->queue != 0) {
|
||||
vQueueDelete(wq->queue);
|
||||
}
|
||||
wq->queue = 0;
|
||||
wq->capacity = 0;
|
||||
osi_free(wq);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static bool osi_thead_work_queue_get(struct work_queue *wq, struct work_item *item)
|
||||
{
|
||||
assert (wq != NULL);
|
||||
assert (wq->queue != 0);
|
||||
assert (item != NULL);
|
||||
|
||||
if (pdTRUE == xQueueReceive(wq->queue, item, 0)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool osi_thead_work_queue_put(struct work_queue *wq, const struct work_item *item, uint32_t timeout)
|
||||
{
|
||||
assert (wq != NULL);
|
||||
assert (wq->queue != 0);
|
||||
assert (item != NULL);
|
||||
|
||||
bool ret = true;
|
||||
if (timeout == OSI_SEM_MAX_TIMEOUT) {
|
||||
if (xQueueSend(wq->queue, item, portMAX_DELAY) != pdTRUE) {
|
||||
ret = false;
|
||||
}
|
||||
} else {
|
||||
if (xQueueSend(wq->queue, item, timeout / portTICK_PERIOD_MS) != pdTRUE) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t osi_thead_work_queue_len(struct work_queue *wq)
|
||||
{
|
||||
assert (wq != NULL);
|
||||
assert (wq->queue != 0);
|
||||
assert (wq->capacity != 0);
|
||||
|
||||
size_t available_spaces = (size_t)uxQueueSpacesAvailable(wq->queue);
|
||||
|
||||
if (available_spaces <= wq->capacity) {
|
||||
return wq->capacity - available_spaces;
|
||||
} else {
|
||||
assert (0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void osi_thread_run(void *arg)
|
||||
{
|
||||
struct osi_thread_start_arg *start = (struct osi_thread_start_arg *)arg;
|
||||
osi_thread_t *thread = start->thread;
|
||||
|
||||
osi_sem_give(&start->start_sem);
|
||||
|
||||
while (1) {
|
||||
int idx = 0;
|
||||
|
||||
osi_sem_take(&thread->work_sem, OSI_SEM_MAX_TIMEOUT);
|
||||
|
||||
if (thread->stop) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct work_item item;
|
||||
while (!thread->stop && idx < thread->work_queue_num) {
|
||||
if (osi_thead_work_queue_get(thread->work_queues[idx], &item) == true) {
|
||||
item.func(item.context);
|
||||
idx = 0;
|
||||
continue;
|
||||
} else {
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thread->thread_handle = NULL;
|
||||
osi_sem_give(&thread->stop_sem);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static int osi_thread_join(osi_thread_t *thread, uint32_t wait_ms)
|
||||
{
|
||||
assert(thread != NULL);
|
||||
return osi_sem_take(&thread->stop_sem, wait_ms);
|
||||
}
|
||||
|
||||
static void osi_thread_stop(osi_thread_t *thread)
|
||||
{
|
||||
int ret;
|
||||
|
||||
assert(thread != NULL);
|
||||
|
||||
//stop the thread
|
||||
thread->stop = true;
|
||||
osi_sem_give(&thread->work_sem);
|
||||
|
||||
//join
|
||||
ret = osi_thread_join(thread, 1000); //wait 1000ms
|
||||
|
||||
//if join failed, delete the task here
|
||||
if (ret != 0 && thread->thread_handle) {
|
||||
vTaskDelete(thread->thread_handle);
|
||||
}
|
||||
}
|
||||
|
||||
//in linux, the stack_size, priority and core may not be set here, the code will be ignore the arguments
|
||||
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[])
|
||||
{
|
||||
int ret;
|
||||
struct osi_thread_start_arg start_arg = {0};
|
||||
|
||||
if (stack_size <= 0 ||
|
||||
core < OSI_THREAD_CORE_0 || core > OSI_THREAD_CORE_AFFINITY ||
|
||||
work_queue_num <= 0 || work_queue_len == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osi_thread_t *thread = (osi_thread_t *)osi_calloc(sizeof(osi_thread_t));
|
||||
if (thread == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
thread->stop = false;
|
||||
thread->work_queues = (struct work_queue **)osi_calloc(sizeof(struct work_queue *) * work_queue_num);
|
||||
if (thread->work_queues == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
thread->work_queue_num = work_queue_num;
|
||||
|
||||
for (int i = 0; i < thread->work_queue_num; i++) {
|
||||
size_t queue_len = work_queue_len[i] ? work_queue_len[i] : DEFAULT_WORK_QUEUE_CAPACITY;
|
||||
thread->work_queues[i] = osi_work_queue_create(queue_len);
|
||||
if (thread->work_queues[i] == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = osi_sem_new(&thread->work_sem, 1, 0);
|
||||
if (ret != 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
ret = osi_sem_new(&thread->stop_sem, 1, 0);
|
||||
if (ret != 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
start_arg.thread = thread;
|
||||
ret = osi_sem_new(&start_arg.start_sem, 1, 0);
|
||||
if (ret != 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (xTaskCreatePinnedToCore(osi_thread_run, name, stack_size, &start_arg, priority, &thread->thread_handle, core) != pdPASS) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
osi_sem_take(&start_arg.start_sem, OSI_SEM_MAX_TIMEOUT);
|
||||
osi_sem_free(&start_arg.start_sem);
|
||||
|
||||
return thread;
|
||||
|
||||
_err:
|
||||
|
||||
if (thread) {
|
||||
if (start_arg.start_sem) {
|
||||
osi_sem_free(&start_arg.start_sem);
|
||||
}
|
||||
|
||||
if (thread->thread_handle) {
|
||||
vTaskDelete(thread->thread_handle);
|
||||
}
|
||||
|
||||
for (int i = 0; i < thread->work_queue_num; i++) {
|
||||
if (thread->work_queues[i]) {
|
||||
osi_work_queue_delete(thread->work_queues[i]);
|
||||
}
|
||||
thread->work_queues[i] = NULL;
|
||||
}
|
||||
|
||||
if (thread->work_queues) {
|
||||
osi_free(thread->work_queues);
|
||||
thread->work_queues = NULL;
|
||||
}
|
||||
|
||||
if (thread->work_sem) {
|
||||
osi_sem_free(&thread->work_sem);
|
||||
}
|
||||
|
||||
if (thread->stop_sem) {
|
||||
osi_sem_free(&thread->stop_sem);
|
||||
}
|
||||
|
||||
osi_free(thread);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void osi_thread_free(osi_thread_t *thread)
|
||||
{
|
||||
if (!thread)
|
||||
return;
|
||||
|
||||
osi_thread_stop(thread);
|
||||
|
||||
for (int i = 0; i < thread->work_queue_num; i++) {
|
||||
if (thread->work_queues[i]) {
|
||||
osi_work_queue_delete(thread->work_queues[i]);
|
||||
thread->work_queues[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (thread->work_queues) {
|
||||
osi_free(thread->work_queues);
|
||||
thread->work_queues = NULL;
|
||||
}
|
||||
|
||||
if (thread->work_sem) {
|
||||
osi_sem_free(&thread->work_sem);
|
||||
}
|
||||
|
||||
if (thread->stop_sem) {
|
||||
osi_sem_free(&thread->stop_sem);
|
||||
}
|
||||
|
||||
|
||||
osi_free(thread);
|
||||
}
|
||||
|
||||
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout)
|
||||
{
|
||||
assert(thread != NULL);
|
||||
assert(func != NULL);
|
||||
|
||||
if (queue_idx >= thread->work_queue_num) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct work_item item;
|
||||
|
||||
item.func = func;
|
||||
item.context = context;
|
||||
|
||||
if (osi_thead_work_queue_put(thread->work_queues[queue_idx], &item, timeout) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
osi_sem_give(&thread->work_sem);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool osi_thread_set_priority(osi_thread_t *thread, int priority)
|
||||
{
|
||||
assert(thread != NULL);
|
||||
|
||||
vTaskPrioritySet(thread->thread_handle, priority);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *osi_thread_name(osi_thread_t *thread)
|
||||
{
|
||||
assert(thread != NULL);
|
||||
|
||||
return pcTaskGetName(thread->thread_handle);
|
||||
}
|
||||
|
||||
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx)
|
||||
{
|
||||
if (wq_idx < 0 || wq_idx >= thread->work_queue_num) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)(osi_thead_work_queue_len(thread->work_queues[wq_idx]));
|
||||
}
|
||||
|
||||
|
||||
struct osi_event *osi_event_create(osi_thread_func_t func, void *context)
|
||||
{
|
||||
struct osi_event *event = osi_calloc(sizeof(struct osi_event));
|
||||
if (event != NULL) {
|
||||
if (osi_mutex_new(&event->lock) == 0) {
|
||||
event->item.func = func;
|
||||
event->item.context = context;
|
||||
return event;
|
||||
}
|
||||
osi_free(event);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void osi_event_delete(struct osi_event* event)
|
||||
{
|
||||
if (event != NULL) {
|
||||
osi_mutex_free(&event->lock);
|
||||
memset(event, 0, sizeof(struct osi_event));
|
||||
osi_free(event);
|
||||
}
|
||||
}
|
||||
|
||||
bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx)
|
||||
{
|
||||
if (event == NULL || event->thread != NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (thread == NULL || queue_idx >= thread->work_queue_num) {
|
||||
return false;
|
||||
}
|
||||
|
||||
event->thread = thread;
|
||||
event->queue_idx = queue_idx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void osi_thread_generic_event_handler(void *context)
|
||||
{
|
||||
struct osi_event *event = (struct osi_event *)context;
|
||||
if (event != NULL && event->item.func != NULL) {
|
||||
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
event->is_queued = 0;
|
||||
osi_mutex_unlock(&event->lock);
|
||||
event->item.func(event->item.context);
|
||||
}
|
||||
}
|
||||
|
||||
bool osi_thread_post_event(struct osi_event *event, uint32_t timeout)
|
||||
{
|
||||
assert(event != NULL && event->thread != NULL);
|
||||
assert(event->queue_idx >= 0 && event->queue_idx < event->thread->work_queue_num);
|
||||
bool ret = false;
|
||||
if (event->is_queued == 0) {
|
||||
uint16_t acquire_cnt = 0;
|
||||
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
event->is_queued += 1;
|
||||
acquire_cnt = event->is_queued;
|
||||
osi_mutex_unlock(&event->lock);
|
||||
|
||||
if (acquire_cnt == 1) {
|
||||
ret = osi_thread_post(event->thread, osi_thread_generic_event_handler, event, event->queue_idx, timeout);
|
||||
if (!ret) {
|
||||
// clear "is_queued" when post failure, to allow for following event posts
|
||||
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
event->is_queued = 0;
|
||||
osi_mutex_unlock(&event->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,446 @@
|
||||
choice BTDM_CTRL_MODE
|
||||
prompt "Bluetooth controller mode (BR/EDR/BLE/DUALMODE)"
|
||||
help
|
||||
Specify the bluetooth controller mode (BR/EDR, BLE or dual mode).
|
||||
|
||||
config BTDM_CTRL_MODE_BLE_ONLY
|
||||
bool "BLE Only"
|
||||
|
||||
config BTDM_CTRL_MODE_BR_EDR_ONLY
|
||||
bool "BR/EDR Only"
|
||||
|
||||
config BTDM_CTRL_MODE_BTDM
|
||||
bool "Bluetooth Dual Mode"
|
||||
|
||||
endchoice
|
||||
|
||||
config BTDM_CTRL_BLE_MAX_CONN
|
||||
int "BLE Max Connections"
|
||||
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default 3
|
||||
range 1 9
|
||||
help
|
||||
BLE maximum connections of bluetooth controller.
|
||||
Each connection uses 1KB static DRAM whenever the BT controller is enabled.
|
||||
|
||||
config BTDM_CTRL_BR_EDR_MAX_ACL_CONN
|
||||
int "BR/EDR ACL Max Connections"
|
||||
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default 2
|
||||
range 1 7
|
||||
help
|
||||
BR/EDR ACL maximum connections of bluetooth controller.
|
||||
Each connection uses 1.2 KB DRAM whenever the BT controller is enabled.
|
||||
|
||||
config BTDM_CTRL_BR_EDR_MAX_SYNC_CONN
|
||||
int "BR/EDR Sync(SCO/eSCO) Max Connections"
|
||||
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default 0
|
||||
range 0 3
|
||||
help
|
||||
BR/EDR Synchronize maximum connections of bluetooth controller.
|
||||
Each connection uses 2 KB DRAM whenever the BT controller is enabled.
|
||||
|
||||
|
||||
|
||||
choice BTDM_CTRL_BR_EDR_SCO_DATA_PATH
|
||||
prompt "BR/EDR Sync(SCO/eSCO) default data path"
|
||||
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM
|
||||
help
|
||||
SCO data path, i.e. HCI or PCM.
|
||||
SCO data can be sent/received through HCI synchronous packets, or the data
|
||||
can be routed to on-chip PCM module on ESP32. PCM input/output signals can
|
||||
be "matrixed" to GPIOs. The default data path can also be set using API
|
||||
"esp_bredr_sco_datapath_set"
|
||||
|
||||
config BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI
|
||||
bool "HCI"
|
||||
config BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM
|
||||
bool "PCM"
|
||||
endchoice
|
||||
|
||||
config BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF
|
||||
int
|
||||
default 0 if BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI
|
||||
default 1 if BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM
|
||||
default 0
|
||||
|
||||
menuconfig BTDM_CTRL_PCM_ROLE_EDGE_CONFIG
|
||||
bool "PCM Signal Config (Role and Polar)"
|
||||
depends on BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM
|
||||
default y
|
||||
|
||||
choice BTDM_CTRL_PCM_ROLE
|
||||
prompt "PCM Role"
|
||||
depends on BTDM_CTRL_PCM_ROLE_EDGE_CONFIG
|
||||
help
|
||||
PCM role can be configured as PCM master or PCM slave
|
||||
|
||||
config BTDM_CTRL_PCM_ROLE_MASTER
|
||||
bool "PCM Master"
|
||||
config BTDM_CTRL_PCM_ROLE_SLAVE
|
||||
bool "PCM Slave"
|
||||
endchoice
|
||||
|
||||
choice BTDM_CTRL_PCM_POLAR
|
||||
prompt "PCM Polar"
|
||||
depends on BTDM_CTRL_PCM_ROLE_EDGE_CONFIG
|
||||
help
|
||||
PCM polarity can be configured as Falling Edge or Rising Edge
|
||||
|
||||
config BTDM_CTRL_PCM_POLAR_FALLING_EDGE
|
||||
bool "Falling Edge"
|
||||
config BTDM_CTRL_PCM_POLAR_RISING_EDGE
|
||||
bool "Rising Edge"
|
||||
endchoice
|
||||
|
||||
config BTDM_CTRL_PCM_ROLE_EFF
|
||||
int
|
||||
default 0 if BTDM_CTRL_PCM_ROLE_MASTER
|
||||
default 1 if BTDM_CTRL_PCM_ROLE_SLAVE
|
||||
default 0
|
||||
|
||||
config BTDM_CTRL_PCM_POLAR_EFF
|
||||
int
|
||||
default 0 if BTDM_CTRL_PCM_POLAR_FALLING_EDGE
|
||||
default 1 if BTDM_CTRL_PCM_POLAR_RISING_EDGE
|
||||
default 0
|
||||
|
||||
config BTDM_CTRL_AUTO_LATENCY
|
||||
bool "Auto latency"
|
||||
depends on BTDM_CTRL_MODE_BTDM
|
||||
default n
|
||||
help
|
||||
BLE auto latency, used to enhance classic BT performance
|
||||
while classic BT and BLE are enabled at the same time.
|
||||
|
||||
config BTDM_CTRL_AUTO_LATENCY_EFF
|
||||
bool
|
||||
default BTDM_CTRL_AUTO_LATENCY if BTDM_CTRL_MODE_BTDM
|
||||
default n
|
||||
|
||||
config BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT
|
||||
bool "Legacy Authentication Vendor Specific Event Enable"
|
||||
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default y
|
||||
help
|
||||
To protect from BIAS attack during Legacy authentication,
|
||||
Legacy authentication Vendor specific event should be enabled
|
||||
|
||||
config BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF
|
||||
bool
|
||||
default BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default 0
|
||||
|
||||
|
||||
config BTDM_CTRL_BLE_MAX_CONN_EFF
|
||||
int
|
||||
default BTDM_CTRL_BLE_MAX_CONN if BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default 0
|
||||
|
||||
config BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF
|
||||
int
|
||||
default BTDM_CTRL_BR_EDR_MAX_ACL_CONN if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default 0
|
||||
|
||||
config BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF
|
||||
int
|
||||
default BTDM_CTRL_BR_EDR_MAX_SYNC_CONN if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default 0
|
||||
|
||||
choice BTDM_CTRL_PINNED_TO_CORE_CHOICE
|
||||
prompt "The cpu core which bluetooth controller run"
|
||||
depends on !FREERTOS_UNICORE
|
||||
help
|
||||
Specify the cpu core to run bluetooth controller.
|
||||
Can not specify no-affinity.
|
||||
|
||||
config BTDM_CTRL_PINNED_TO_CORE_0
|
||||
bool "Core 0 (PRO CPU)"
|
||||
config BTDM_CTRL_PINNED_TO_CORE_1
|
||||
bool "Core 1 (APP CPU)"
|
||||
depends on !FREERTOS_UNICORE
|
||||
endchoice
|
||||
|
||||
config BTDM_CTRL_PINNED_TO_CORE
|
||||
int
|
||||
default 0 if BTDM_CTRL_PINNED_TO_CORE_0
|
||||
default 1 if BTDM_CTRL_PINNED_TO_CORE_1
|
||||
default 0
|
||||
|
||||
choice BTDM_CTRL_HCI_MODE_CHOICE
|
||||
prompt "HCI mode"
|
||||
help
|
||||
Speicify HCI mode as VHCI or UART(H4)
|
||||
|
||||
config BTDM_CTRL_HCI_MODE_VHCI
|
||||
bool "VHCI"
|
||||
help
|
||||
Normal option. Mostly, choose this VHCI when bluetooth host run on ESP32, too.
|
||||
|
||||
config BTDM_CTRL_HCI_MODE_UART_H4
|
||||
bool "UART(H4)"
|
||||
help
|
||||
If use external bluetooth host which run on other hardware and use UART as the HCI interface,
|
||||
choose this option.
|
||||
endchoice
|
||||
|
||||
menu "HCI UART(H4) Options"
|
||||
visible if BTDM_CTRL_HCI_MODE_UART_H4
|
||||
|
||||
config BTDM_CTRL_HCI_UART_NO
|
||||
int "UART Number for HCI"
|
||||
depends on BTDM_CTRL_HCI_MODE_UART_H4
|
||||
range 1 2
|
||||
default 1
|
||||
help
|
||||
Uart number for HCI. The available uart is UART1 and UART2.
|
||||
|
||||
config BTDM_CTRL_HCI_UART_BAUDRATE
|
||||
int "UART Baudrate for HCI"
|
||||
depends on BTDM_CTRL_HCI_MODE_UART_H4
|
||||
range 115200 921600
|
||||
default 921600
|
||||
help
|
||||
UART Baudrate for HCI. Please use standard baudrate.
|
||||
|
||||
config BTDM_CTRL_HCI_UART_FLOW_CTRL_EN
|
||||
bool "Enable UART flow control"
|
||||
depends on BTDM_CTRL_HCI_MODE_UART_H4
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
menu "MODEM SLEEP Options"
|
||||
config BTDM_CTRL_MODEM_SLEEP
|
||||
bool "Bluetooth modem sleep"
|
||||
default y
|
||||
help
|
||||
Enable/disable bluetooth controller low power mode.
|
||||
|
||||
choice BTDM_CTRL_MODEM_SLEEP_MODE
|
||||
prompt "Bluetooth Modem sleep mode"
|
||||
depends on BTDM_CTRL_MODEM_SLEEP
|
||||
help
|
||||
To select which strategy to use for modem sleep
|
||||
|
||||
config BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
|
||||
bool "ORIG Mode(sleep with low power clock)"
|
||||
help
|
||||
ORIG mode is a bluetooth sleep mode that can be used for dual mode controller. In this mode,
|
||||
bluetooth controller sleeps between BR/EDR frames and BLE events. A low power clock is used to
|
||||
maintain bluetooth reference clock.
|
||||
|
||||
config BTDM_CTRL_MODEM_SLEEP_MODE_EVED
|
||||
bool "EVED Mode(For internal test only)"
|
||||
help
|
||||
EVED mode is for BLE only and is only for internal test. Do not use it for production. this
|
||||
mode is not compatible with DFS nor light sleep
|
||||
endchoice
|
||||
|
||||
choice BTDM_CTRL_LOW_POWER_CLOCK
|
||||
prompt "Bluetooth low power clock"
|
||||
depends on BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
|
||||
help
|
||||
Select the low power clock source for bluetooth controller. Bluetooth low power clock is
|
||||
the clock source to maintain time in sleep mode.
|
||||
|
||||
- "Main crystal" option provides good accuracy and can support Dynamic Frequency Scaling
|
||||
to be used with Bluetooth modem sleep. Light sleep is not supported.
|
||||
- "External 32kHz crystal" option allows user to use a 32.768kHz crystal as Bluetooth low
|
||||
power clock. This option is allowed as long as External 32kHz crystal is configured as
|
||||
the system RTC clock source. This option provides good accuracy and supports Bluetooth
|
||||
modem sleep to be used alongside Dynamic Frequency Scaling or light sleep.
|
||||
|
||||
config BTDM_CTRL_LPCLK_SEL_MAIN_XTAL
|
||||
bool "Main crystal"
|
||||
help
|
||||
Main crystal can be used as low power clock for bluetooth modem sleep. If this option is
|
||||
selected, bluetooth modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, but
|
||||
cannot work when light sleep is enabled. Main crystal has a good performance in accuracy as
|
||||
the bluetooth low power clock source.
|
||||
|
||||
config BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
bool "External 32kHz crystal"
|
||||
depends on RTC_CLK_SRC_EXT_CRYS
|
||||
help
|
||||
External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency
|
||||
stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth
|
||||
modem sleep to be used with both DFS and light sleep.
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
choice BTDM_BLE_SLEEP_CLOCK_ACCURACY
|
||||
prompt "BLE Sleep Clock Accuracy"
|
||||
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default BTDM_BLE_DEFAULT_SCA_250PPM
|
||||
help
|
||||
BLE Sleep Clock Accuracy(SCA) for the local device is used to estimate window widening in BLE
|
||||
connection events. With a lower level of clock accuracy(e.g. 500ppm over 250ppm), the slave
|
||||
needs a larger RX window to synchronize with master in each anchor point, thus resulting in an
|
||||
increase of power consumption but a higher level of robustness in keeping connected. According
|
||||
to the requirements of Bluetooth Core specification 4.2, the worst-case accuracy of Classic
|
||||
Bluetooth low power oscialltor(LPO) is +/-250ppm in STANDBY and in low power modes such as
|
||||
sniff. For BLE the worst-case SCA is +/-500ppm.
|
||||
|
||||
- "151ppm to 250ppm" option is the default value for Bluetooth Dual mode
|
||||
- "251ppm to 500ppm" option can be used in BLE only mode when using external 32kHz crystal as
|
||||
low power clock. This option is provided in case that BLE sleep clock has a lower level of
|
||||
accuracy, or other error sources contribute to the inaccurate timing during sleep.
|
||||
|
||||
config BTDM_BLE_DEFAULT_SCA_500PPM
|
||||
bool "251ppm to 500ppm"
|
||||
depends on BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL && BTDM_CTRL_MODE_BLE_ONLY
|
||||
config BTDM_BLE_DEFAULT_SCA_250PPM
|
||||
bool "151ppm to 250ppm"
|
||||
endchoice
|
||||
config BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF
|
||||
int
|
||||
default 0 if BTDM_BLE_DEFAULT_SCA_500PPM
|
||||
default 1 if BTDM_BLE_DEFAULT_SCA_250PPM
|
||||
default 1
|
||||
|
||||
config BTDM_BLE_SCAN_DUPL
|
||||
bool "BLE Scan Duplicate Options"
|
||||
depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY)
|
||||
default y
|
||||
help
|
||||
This select enables parameters setting of BLE scan duplicate.
|
||||
|
||||
choice BTDM_SCAN_DUPL_TYPE
|
||||
prompt "Scan Duplicate Type"
|
||||
default BTDM_SCAN_DUPL_TYPE_DEVICE
|
||||
depends on BTDM_BLE_SCAN_DUPL
|
||||
help
|
||||
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use
|
||||
advertiser address filtering. The adv packet of the same address is only allowed to be reported once.
|
||||
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising
|
||||
data and device address filtering. All different adv packets with the same address are allowed to be
|
||||
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data
|
||||
filtering. All same advertising data only allow to be reported once even though they are from
|
||||
different devices.
|
||||
|
||||
config BTDM_SCAN_DUPL_TYPE_DEVICE
|
||||
bool "Scan Duplicate By Device Address"
|
||||
help
|
||||
This way is to use advertiser address filtering. The adv packet of the same address is only
|
||||
allowed to be reported once
|
||||
|
||||
config BTDM_SCAN_DUPL_TYPE_DATA
|
||||
bool "Scan Duplicate By Advertising Data"
|
||||
help
|
||||
This way is to use advertising data filtering. All same advertising data only allow to be reported
|
||||
once even though they are from different devices.
|
||||
|
||||
config BTDM_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
bool "Scan Duplicate By Device Address And Advertising Data"
|
||||
help
|
||||
This way is to use advertising data and device address filtering. All different adv packets with
|
||||
the same address are allowed to be reported.
|
||||
endchoice
|
||||
|
||||
config BTDM_SCAN_DUPL_TYPE
|
||||
int
|
||||
depends on BTDM_BLE_SCAN_DUPL
|
||||
default 0 if BTDM_SCAN_DUPL_TYPE_DEVICE
|
||||
default 1 if BTDM_SCAN_DUPL_TYPE_DATA
|
||||
default 2 if BTDM_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
default 0
|
||||
|
||||
config BTDM_SCAN_DUPL_CACHE_SIZE
|
||||
int "Maximum number of devices in scan duplicate filter"
|
||||
depends on BTDM_BLE_SCAN_DUPL
|
||||
range 10 1000
|
||||
default 100
|
||||
help
|
||||
Maximum number of devices which can be recorded in scan duplicate filter.
|
||||
When the maximum amount of device in the filter is reached, the oldest device will be refreshed.
|
||||
|
||||
config BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD
|
||||
int "Duplicate scan list refresh period (seconds)"
|
||||
depends on BTDM_BLE_SCAN_DUPL
|
||||
range 0 1000
|
||||
default 0
|
||||
help
|
||||
If the period value is non-zero, the controller will periodically clear the device information
|
||||
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared
|
||||
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the
|
||||
Host in advertising report events.
|
||||
There are two scenarios where the ADV packet will be repeatedly reported:
|
||||
1. The duplicate scan cache is full, the controller will delete the oldest device information and
|
||||
add new device information.
|
||||
2. When the refresh period is up, the controller will clear all device information and start filtering
|
||||
again.
|
||||
|
||||
config BTDM_BLE_MESH_SCAN_DUPL_EN
|
||||
bool "Special duplicate scan mechanism for BLE Mesh scan"
|
||||
depends on BTDM_BLE_SCAN_DUPL
|
||||
default n
|
||||
help
|
||||
This enables the BLE scan duplicate for special BLE Mesh scan.
|
||||
|
||||
config BTDM_MESH_DUPL_SCAN_CACHE_SIZE
|
||||
int "Maximum number of Mesh adv packets in scan duplicate filter"
|
||||
depends on BTDM_BLE_MESH_SCAN_DUPL_EN
|
||||
range 10 1000
|
||||
default 100
|
||||
help
|
||||
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
|
||||
When the maximum amount of device in the filter is reached, the cache will be refreshed.
|
||||
|
||||
config BTDM_CTRL_FULL_SCAN_SUPPORTED
|
||||
bool "BLE full scan feature supported"
|
||||
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM
|
||||
default y
|
||||
help
|
||||
The full scan function is mainly used to provide BLE scan performance.
|
||||
This is required for scenes with high scan performance requirements, such as BLE Mesh scenes.
|
||||
|
||||
config BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
bool "BLE adv report flow control supported"
|
||||
depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY)
|
||||
default y
|
||||
help
|
||||
The function is mainly used to enable flow control for advertising reports. When it is enabled,
|
||||
advertising reports will be discarded by the controller if the number of unprocessed advertising
|
||||
reports exceeds the size of BLE adv report flow control.
|
||||
|
||||
config BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM
|
||||
int "BLE adv report flow control number"
|
||||
depends on BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 50 1000
|
||||
default 100
|
||||
help
|
||||
The number of unprocessed advertising report that Bluedroid can save.If you set
|
||||
`BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost.
|
||||
If you set `BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, Bluedroid may cache a
|
||||
lot of adv packets and this may cause system memory run out. For example, if you set
|
||||
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set
|
||||
`BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv
|
||||
packets as fast as possible, otherwise it will cause adv packets lost.
|
||||
|
||||
config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
int "BLE adv lost event threshold value"
|
||||
depends on BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 1 1000
|
||||
default 20
|
||||
help
|
||||
When adv report flow control is enabled, The ADV lost event will be generated when the number
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
|
||||
config BTDM_RESERVE_DRAM
|
||||
hex
|
||||
default 0xdb5c if BT_ENABLED
|
||||
default 0
|
||||
|
||||
config BTDM_CTRL_HLI
|
||||
bool "High level interrupt"
|
||||
depends on BT_ENABLED
|
||||
default y
|
||||
help
|
||||
Using Level 4 interrupt for Bluetooth.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "xtensa/core-macros.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "hli_api.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
#define HLI_MAX_HANDLERS 4
|
||||
|
||||
typedef struct {
|
||||
intr_handler_t handler;
|
||||
void* arg;
|
||||
uint32_t intr_reg;
|
||||
uint32_t intr_mask;
|
||||
} hli_handler_info_t;
|
||||
|
||||
typedef struct {
|
||||
#define CUSTOMER_TYPE_REQUEST (0)
|
||||
#define CUSTOMER_TYPE_RELEASE (1)
|
||||
struct {
|
||||
uint32_t cb_type;
|
||||
union {
|
||||
int (* request)(uint32_t, uint32_t, uint32_t);
|
||||
int (* release)(uint32_t);
|
||||
} cb;
|
||||
} customer_cb;
|
||||
uint32_t arg0, arg1, arg2;
|
||||
} customer_swisr_t;
|
||||
|
||||
static void IRAM_ATTR customer_swisr_handle(customer_swisr_t *cus_swisr)
|
||||
{
|
||||
if (cus_swisr->customer_cb.cb_type == CUSTOMER_TYPE_REQUEST) {
|
||||
if (cus_swisr->customer_cb.cb.request != NULL) {
|
||||
cus_swisr->customer_cb.cb.request(cus_swisr->arg0, cus_swisr->arg1, cus_swisr->arg2);
|
||||
}
|
||||
} else if(cus_swisr->customer_cb.cb_type == CUSTOMER_TYPE_RELEASE) {
|
||||
if (cus_swisr->customer_cb.cb.release != NULL) {
|
||||
cus_swisr->customer_cb.cb.release(cus_swisr->arg0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DRAM_ATTR hli_handler_info_t s_hli_handlers[HLI_MAX_HANDLERS];
|
||||
|
||||
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask)
|
||||
{
|
||||
for (hli_handler_info_t* hip = s_hli_handlers;
|
||||
hip < s_hli_handlers + HLI_MAX_HANDLERS;
|
||||
++hip) {
|
||||
if (hip->handler == NULL) {
|
||||
hip->arg = arg;
|
||||
hip->intr_reg = intr_reg;
|
||||
hip->intr_mask = intr_mask;
|
||||
hip->handler = handler; /* set last, indicates the entry as valid */
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
void IRAM_ATTR hli_c_handler(void)
|
||||
{
|
||||
bool handled = false;
|
||||
/* Iterate over registered interrupt handlers,
|
||||
* and check if the expected mask is present in the interrupt status register.
|
||||
*/
|
||||
for (hli_handler_info_t* hip = s_hli_handlers;
|
||||
hip < s_hli_handlers + HLI_MAX_HANDLERS;
|
||||
++hip) {
|
||||
if (hip->handler == NULL) {
|
||||
continue;
|
||||
}
|
||||
uint32_t reg = hip->intr_reg;
|
||||
uint32_t val;
|
||||
if (reg == 0) { /* special case for CPU internal interrupts */
|
||||
val = XTHAL_GET_INTERRUPT();
|
||||
} else {
|
||||
/* "reg" might not be in DPORT, but this will work in any case */
|
||||
val = DPORT_REG_READ(reg);
|
||||
}
|
||||
if ((val & hip->intr_mask) != 0) {
|
||||
handled = true;
|
||||
(*hip->handler)(hip->arg);
|
||||
}
|
||||
}
|
||||
if (!handled) {
|
||||
/* no handler found, it is OK in this case. */
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR hli_intr_disable(void)
|
||||
{
|
||||
/* disable level 4 and below */
|
||||
return XTOS_SET_INTLEVEL(XCHAL_DEBUGLEVEL - 2);
|
||||
}
|
||||
|
||||
void IRAM_ATTR hli_intr_restore(uint32_t state)
|
||||
{
|
||||
XTOS_RESTORE_JUST_INTLEVEL(state);
|
||||
}
|
||||
|
||||
#define HLI_META_QUEUE_SIZE 16
|
||||
#define HLI_QUEUE_MAX_ELEM_SIZE 32
|
||||
#define HLI_QUEUE_SW_INT_NUM 29
|
||||
|
||||
#define HLI_QUEUE_FLAG_SEMAPHORE BIT(0)
|
||||
#define HLI_QUEUE_FLAG_CUSTOMER BIT(1)
|
||||
|
||||
static DRAM_ATTR struct hli_queue_t *s_meta_queue_ptr = NULL;
|
||||
static intr_handle_t ret_handle;
|
||||
|
||||
static inline char* IRAM_ATTR wrap_ptr(hli_queue_handle_t queue, char *ptr)
|
||||
{
|
||||
return (ptr == queue->bufend) ? queue->buf : ptr;
|
||||
}
|
||||
|
||||
static inline bool IRAM_ATTR queue_empty(hli_queue_handle_t queue)
|
||||
{
|
||||
return queue->begin == queue->end;
|
||||
}
|
||||
|
||||
static inline bool IRAM_ATTR queue_full(hli_queue_handle_t queue)
|
||||
{
|
||||
return wrap_ptr(queue, queue->end + queue->elem_size) == queue->begin;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR queue_isr_handler(void* arg)
|
||||
{
|
||||
int do_yield = pdFALSE;
|
||||
XTHAL_SET_INTCLEAR(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
hli_queue_handle_t queue;
|
||||
|
||||
while (hli_queue_get(s_meta_queue_ptr, &queue)) {
|
||||
static DRAM_ATTR char scratch[HLI_QUEUE_MAX_ELEM_SIZE];
|
||||
while (hli_queue_get(queue, scratch)) {
|
||||
int res = pdPASS;
|
||||
if ((queue->flags & HLI_QUEUE_FLAG_CUSTOMER) != 0) {
|
||||
customer_swisr_handle((customer_swisr_t *)scratch);
|
||||
} else if ((queue->flags & HLI_QUEUE_FLAG_SEMAPHORE) != 0) {
|
||||
res = xSemaphoreGiveFromISR((SemaphoreHandle_t) queue->downstream, &do_yield);
|
||||
} else {
|
||||
res = xQueueSendFromISR(queue->downstream, scratch, &do_yield);
|
||||
}
|
||||
if (res == pdFAIL) {
|
||||
/* Failed to send to downstream queue, it is OK in this case. */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (do_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify the level 3 handler that an element is added to the given hli queue.
|
||||
* Do this by placing the queue handle onto s_meta_queue, and raising a SW interrupt.
|
||||
*
|
||||
* This function must be called with HL interrupts disabled!
|
||||
*/
|
||||
static void IRAM_ATTR queue_signal(hli_queue_handle_t queue)
|
||||
{
|
||||
/* See if the queue is already in s_meta_queue, before adding */
|
||||
bool found = false;
|
||||
const hli_queue_handle_t *end = (hli_queue_handle_t*) s_meta_queue_ptr->end;
|
||||
hli_queue_handle_t *item = (hli_queue_handle_t*) s_meta_queue_ptr->begin;
|
||||
for (;item != end; item = (hli_queue_handle_t*) wrap_ptr(s_meta_queue_ptr, (char*) (item + 1))) {
|
||||
if (*item == queue) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
bool res = hli_queue_put(s_meta_queue_ptr, &queue);
|
||||
if (!res) {
|
||||
esp_rom_printf(DRAM_STR("Fatal error in queue_signal: s_meta_queue full\n"));
|
||||
abort();
|
||||
}
|
||||
XTHAL_SET_INTSET(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
}
|
||||
}
|
||||
|
||||
static void queue_init(hli_queue_handle_t queue, size_t buf_size, size_t elem_size, QueueHandle_t downstream)
|
||||
{
|
||||
queue->elem_size = elem_size;
|
||||
queue->begin = queue->buf;
|
||||
queue->end = queue->buf;
|
||||
queue->bufend = queue->buf + buf_size;
|
||||
queue->downstream = downstream;
|
||||
queue->flags = 0;
|
||||
}
|
||||
|
||||
void hli_queue_setup(void)
|
||||
{
|
||||
if (s_meta_queue_ptr == NULL) {
|
||||
s_meta_queue_ptr = hli_queue_create(HLI_META_QUEUE_SIZE, sizeof(void*), NULL);
|
||||
ESP_ERROR_CHECK(esp_intr_alloc(ETS_INTERNAL_SW1_INTR_SOURCE, ESP_INTR_FLAG_IRAM, queue_isr_handler, NULL, &ret_handle));
|
||||
xt_ints_on(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
}
|
||||
}
|
||||
|
||||
void hli_queue_shutdown(void)
|
||||
{
|
||||
if (s_meta_queue_ptr != NULL) {
|
||||
hli_queue_delete(s_meta_queue_ptr);
|
||||
s_meta_queue_ptr = NULL;
|
||||
esp_intr_free(ret_handle);
|
||||
xt_ints_off(BIT(HLI_QUEUE_SW_INT_NUM));
|
||||
}
|
||||
}
|
||||
|
||||
hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream)
|
||||
{
|
||||
const size_t buf_elem = nelem + 1;
|
||||
if (elem_size > HLI_QUEUE_MAX_ELEM_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
size_t buf_size = buf_elem * elem_size;
|
||||
hli_queue_handle_t res = (hli_queue_handle_t) heap_caps_malloc(sizeof(struct hli_queue_t) + buf_size,
|
||||
MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
queue_init(res, buf_size, elem_size, downstream);
|
||||
return res;
|
||||
}
|
||||
|
||||
hli_queue_handle_t hli_customer_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream)
|
||||
{
|
||||
hli_queue_handle_t res = hli_queue_create(nelem, elem_size, (QueueHandle_t) downstream);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
res->flags |= HLI_QUEUE_FLAG_CUSTOMER;
|
||||
return res;
|
||||
}
|
||||
|
||||
hli_queue_handle_t hli_semaphore_create(size_t max_count, SemaphoreHandle_t downstream)
|
||||
{
|
||||
const size_t elem_size = 1;
|
||||
hli_queue_handle_t res = hli_queue_create(max_count, elem_size, (QueueHandle_t) downstream);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
res->flags |= HLI_QUEUE_FLAG_SEMAPHORE;
|
||||
return res;
|
||||
}
|
||||
|
||||
void hli_queue_delete(hli_queue_handle_t queue)
|
||||
{
|
||||
free(queue);
|
||||
}
|
||||
|
||||
bool IRAM_ATTR hli_queue_get(hli_queue_handle_t queue, void* out)
|
||||
{
|
||||
uint32_t int_state = hli_intr_disable();
|
||||
bool res = false;
|
||||
if (!queue_empty(queue)) {
|
||||
memcpy(out, queue->begin, queue->elem_size);
|
||||
queue->begin = wrap_ptr(queue, queue->begin + queue->elem_size);
|
||||
res = true;
|
||||
}
|
||||
hli_intr_restore(int_state);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IRAM_ATTR hli_queue_put(hli_queue_handle_t queue, const void* data)
|
||||
{
|
||||
uint32_t int_state = hli_intr_disable();
|
||||
bool res = false;
|
||||
bool was_empty = queue_empty(queue);
|
||||
if (!queue_full(queue)) {
|
||||
memcpy(queue->end, data, queue->elem_size);
|
||||
queue->end = wrap_ptr(queue, queue->end + queue->elem_size);
|
||||
if (was_empty && queue != s_meta_queue_ptr) {
|
||||
queue_signal(queue);
|
||||
}
|
||||
res = true;
|
||||
}
|
||||
hli_intr_restore(int_state);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IRAM_ATTR hli_semaphore_give(hli_queue_handle_t queue)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
return hli_queue_put(queue, &data);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
|
||||
/*** Queues ***/
|
||||
|
||||
struct hli_queue_t
|
||||
{
|
||||
size_t elem_size;
|
||||
char* begin;
|
||||
char* end;
|
||||
const char* bufend;
|
||||
QueueHandle_t downstream;
|
||||
int flags;
|
||||
char buf[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Register a high level interrupt function
|
||||
*
|
||||
* @param handler interrupt handler function
|
||||
* @param arg argument to pass to the interrupt handler
|
||||
* @param intr_reg address of the peripheral register containing the interrupt status,
|
||||
* or value 0 to get the status from CPU INTERRUPT register
|
||||
* @param intr_mask mask of the interrupt, in the interrupt status register
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if too many handlers are registered
|
||||
*/
|
||||
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask);
|
||||
|
||||
/**
|
||||
* @brief Mask all interrupts (including high level ones) on the current CPU
|
||||
*
|
||||
* @return uint32_t interrupt status, pass it to hli_intr_restore
|
||||
*/
|
||||
uint32_t hli_intr_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Re-enable interrupts
|
||||
*
|
||||
* @param state value returned by hli_intr_disable
|
||||
*/
|
||||
void hli_intr_restore(uint32_t state);
|
||||
|
||||
/**
|
||||
* @brief Type of a hli queue
|
||||
*/
|
||||
typedef struct hli_queue_t* hli_queue_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize hli_queue module. Must be called once before using hli queue APIs.
|
||||
*/
|
||||
void hli_queue_setup(void);
|
||||
|
||||
/**
|
||||
* @brief Shutdown hli_queue module.
|
||||
*/
|
||||
void hli_queue_shutdown(void);
|
||||
|
||||
/**
|
||||
* @brief Create a hli queue, wrapping a FreeRTOS queue
|
||||
*
|
||||
* This queue can be used from high level interrupts,
|
||||
* but **ONLY ON THE CPU WHERE hli_queue_setup WAS CALLED**. Values sent to this
|
||||
* queue are automatically forwarded to "downstream" FreeRTOS queue using a level 3
|
||||
* software interrupt.
|
||||
*
|
||||
* @param nelem number of elements in the queue
|
||||
* @param elem_size size of one element; must match element size of a downstream queue
|
||||
* @param downstream FreeRTOS queue to send the values to
|
||||
* @return hli_queue_handle_t handle of the created queue, or NULL on failure
|
||||
*/
|
||||
hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream);
|
||||
|
||||
/**
|
||||
* @brief Create a customer hli queue, wrapping a FreeRTOS queue
|
||||
*
|
||||
* This queue can be used from high level interrupts,
|
||||
* but **ONLY ON THE CPU WHERE hli_queue_setup WAS CALLED**. Values sent to this
|
||||
* queue are automatically forwarded to "downstream" FreeRTOS queue using a level 3
|
||||
* software interrupt.
|
||||
*
|
||||
* @param nelem number of elements in the queue
|
||||
* @param elem_size size of one element; must match element size of a downstream queue
|
||||
* @param downstream FreeRTOS queue to send the values to
|
||||
* @return hli_queue_handle_t handle of the created queue, or NULL on failure
|
||||
*/
|
||||
hli_queue_handle_t hli_customer_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream);
|
||||
|
||||
/**
|
||||
* @brief Create a hli queue, wrapping a FreeRTOS semaphore
|
||||
*
|
||||
* See notes on hli_queue_create.
|
||||
*
|
||||
* @param max_count maximum semaphore count
|
||||
* @param downstream FreeRTOS semaphore to forward the calls to
|
||||
* @return hli_queue_handle_t handle of the created queue, or NULL on failure
|
||||
*/
|
||||
hli_queue_handle_t hli_semaphore_create(size_t max_count, SemaphoreHandle_t downstream);
|
||||
|
||||
/**
|
||||
* @brief Delete a hli queue
|
||||
*
|
||||
* Make sure noone is using the queue before deleting it.
|
||||
*
|
||||
* @param queue handle returned by hli_queue_create or hli_semaphore_create
|
||||
*/
|
||||
void hli_queue_delete(hli_queue_handle_t queue);
|
||||
|
||||
/**
|
||||
* @brief Get one element from a hli queue
|
||||
*
|
||||
* Usually not used, values get sent to a downstream FreeRTOS queue automatically.
|
||||
* However if downstream queue is NULL, this API can be used to get values from a hli queue.
|
||||
*
|
||||
* @param queue handle of a queue
|
||||
* @param out pointer where to store the element
|
||||
* @return true if the element was successfully read from the queue
|
||||
*/
|
||||
bool hli_queue_get(hli_queue_handle_t queue, void* out);
|
||||
|
||||
/**
|
||||
* @brief Put one element into a hli queue
|
||||
*
|
||||
* This puts copies an element into the queue and raises a software interrupt (level 3).
|
||||
* In the interrupt, the value is copied to a FreeRTOS "downstream" queue.
|
||||
*
|
||||
* Note that if the value does not fit into a downstream queue, no error is returned,
|
||||
* and the value is lost.
|
||||
*
|
||||
* @param queue handle of a queue
|
||||
* @param data pointer to the element to be sent
|
||||
* @return true if data was placed into the hli queue successfully
|
||||
*/
|
||||
bool hli_queue_put(hli_queue_handle_t queue, const void* data);
|
||||
|
||||
/**
|
||||
* @brief "Give" a semaphore wrapped by a hli queue
|
||||
*
|
||||
* @param queue handle returned by hli_semaphore_create
|
||||
* @return true if the event was sent to a hli queue successfully
|
||||
*/
|
||||
bool hli_semaphore_give(hli_queue_handle_t queue);
|
||||
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <xtensa/coreasm.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
#include "xtensa_context.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
|
||||
#if CONFIG_BTDM_CTRL_HLI
|
||||
|
||||
/* Interrupt stack size, for C code.
|
||||
* TODO: reduce and make configurable.
|
||||
*/
|
||||
#define L4_INTR_STACK_SIZE 4096
|
||||
|
||||
/* Save area for the CPU state:
|
||||
* - 64 words for the general purpose registers
|
||||
* - 7 words for some of the special registers:
|
||||
* - WINDOWBASE, WINDOWSTART — only WINDOWSTART is truly needed
|
||||
* - SAR, LBEG, LEND, LCOUNT — since the C code might use these
|
||||
* - EPC1 — since the C code might cause window overflow exceptions
|
||||
* This is not laid out as standard exception frame structure
|
||||
* for simplicity of the save/restore code.
|
||||
*/
|
||||
#define REG_FILE_SIZE (64 * 4)
|
||||
#define SPECREG_OFFSET REG_FILE_SIZE
|
||||
#define SPECREG_SIZE (7 * 4)
|
||||
#define REG_SAVE_AREA_SIZE (SPECREG_OFFSET + SPECREG_SIZE)
|
||||
|
||||
.data
|
||||
_l4_intr_stack:
|
||||
.space L4_INTR_STACK_SIZE
|
||||
_l4_save_ctx:
|
||||
.space REG_SAVE_AREA_SIZE
|
||||
|
||||
.section .iram1,"ax"
|
||||
.global xt_highint4
|
||||
.type xt_highint4,@function
|
||||
.align 4
|
||||
|
||||
xt_highint4:
|
||||
|
||||
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
|
||||
/*
|
||||
Here, Timer2 is used to count a little time(50us).
|
||||
The subsequent dram0 write operation is blocked due to live lock, which will
|
||||
cause timer2 to timeout and trigger a level 5 interrupt.
|
||||
*/
|
||||
rsr.ccount a0
|
||||
addmi a0, a0, (CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ*50)
|
||||
wsr a0, CCOMPARE2
|
||||
|
||||
/* Enable Timer 2 interrupt */
|
||||
rsr a0, INTENABLE
|
||||
extui a0, a0, 16, 1
|
||||
bnez a0, 1f
|
||||
movi a0, 0
|
||||
xsr a0, INTENABLE /* disable all interrupts */
|
||||
/* And a0 with (1 << 16) for Timer 2 interrupt mask */
|
||||
addmi a0, a0, (1<<14)
|
||||
addmi a0, a0, (1<<14)
|
||||
addmi a0, a0, (1<<14)
|
||||
addmi a0, a0, (1<<14)
|
||||
wsr a0, INTENABLE /* Enable Timer 2 */
|
||||
1:
|
||||
#endif
|
||||
|
||||
movi a0, _l4_save_ctx
|
||||
/* save 4 lower registers */
|
||||
s32i a1, a0, 4
|
||||
s32i a2, a0, 8
|
||||
s32i a3, a0, 12
|
||||
rsr a2, EXCSAVE_4 /* holds the value of a0 */
|
||||
s32i a2, a0, 0
|
||||
|
||||
/* Save special registers */
|
||||
addi a0, a0, SPECREG_OFFSET
|
||||
rsr a2, WINDOWBASE
|
||||
s32i a2, a0, 0
|
||||
rsr a2, WINDOWSTART
|
||||
s32i a2, a0, 4
|
||||
rsr a2, SAR
|
||||
s32i a2, a0, 8
|
||||
rsr a2, LBEG
|
||||
s32i a2, a0, 12
|
||||
rsr a2, LEND
|
||||
s32i a2, a0, 16
|
||||
rsr a2, LCOUNT
|
||||
s32i a2, a0, 20
|
||||
rsr a2, EPC1
|
||||
s32i a2, a0, 24
|
||||
|
||||
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
|
||||
movi a0, 0
|
||||
xsr a0, INTENABLE /* disable all interrupts */
|
||||
movi a2, ~(1<<16)
|
||||
and a0, a2, a0
|
||||
wsr a0, INTENABLE
|
||||
#endif
|
||||
|
||||
/* disable exception mode, window overflow */
|
||||
movi a0, PS_INTLEVEL(5) | PS_EXCM
|
||||
wsr a0, PS
|
||||
rsync
|
||||
|
||||
/* Save the remaining physical registers.
|
||||
* 4 registers are already saved, which leaves 60 registers to save.
|
||||
* (FIXME: consider the case when the CPU is configured with physical 32 registers)
|
||||
* These 60 registers are saved in 5 iterations, 12 registers at a time.
|
||||
*/
|
||||
movi a1, 5
|
||||
movi a3, _l4_save_ctx + 4 * 4
|
||||
|
||||
/* This is repeated 5 times, each time the window is shifted by 12 registers.
|
||||
* We come here with a1 = downcounter, a3 = save pointer, a2 and a0 unused.
|
||||
*/
|
||||
1:
|
||||
s32i a4, a3, 0
|
||||
s32i a5, a3, 4
|
||||
s32i a6, a3, 8
|
||||
s32i a7, a3, 12
|
||||
s32i a8, a3, 16
|
||||
s32i a9, a3, 20
|
||||
s32i a10, a3, 24
|
||||
s32i a11, a3, 28
|
||||
s32i a12, a3, 32
|
||||
s32i a13, a3, 36
|
||||
s32i a14, a3, 40
|
||||
s32i a15, a3, 44
|
||||
|
||||
/* We are about to rotate the window, so that a12-a15 will become the new a0-a3.
|
||||
* Copy a0-a3 to a12-15 to still have access to these values.
|
||||
* At the same time we can decrement the counter and adjust the save area pointer
|
||||
*/
|
||||
|
||||
/* a0 is constant (_l4_save_ctx), no need to copy */
|
||||
addi a13, a1, -1 /* copy and decrement the downcounter */
|
||||
/* a2 is scratch so no need to copy */
|
||||
addi a15, a3, 48 /* copy and adjust the save area pointer */
|
||||
beqz a13, 2f /* have saved all registers ? */
|
||||
rotw 3 /* rotate the window and go back */
|
||||
j 1b
|
||||
|
||||
/* the loop is complete */
|
||||
2:
|
||||
rotw 4 /* this brings us back to the original window */
|
||||
/* a0 still points to _l4_save_ctx */
|
||||
|
||||
/* Can clear WINDOWSTART now, all registers are saved */
|
||||
rsr a2, WINDOWBASE
|
||||
/* WINDOWSTART = (1 << WINDOWBASE) */
|
||||
movi a3, 1
|
||||
ssl a2
|
||||
sll a3, a3
|
||||
wsr a3, WINDOWSTART
|
||||
|
||||
_highint4_stack_switch:
|
||||
movi a0, 0
|
||||
movi sp, _l4_intr_stack + L4_INTR_STACK_SIZE - 16
|
||||
s32e a0, sp, -12 /* For GDB: set null SP */
|
||||
s32e a0, sp, -16 /* For GDB: set null PC */
|
||||
movi a0, _highint4_stack_switch /* For GDB: cosmetics, for the frame where stack switch happened */
|
||||
|
||||
/* Set up PS for C, disable all interrupts except NMI and debug, and clear EXCM. */
|
||||
movi a6, PS_INTLEVEL(4) | PS_UM | PS_WOE
|
||||
wsr a6, PS
|
||||
rsync
|
||||
|
||||
/* Call C handler */
|
||||
mov a6, sp
|
||||
call4 hli_c_handler
|
||||
|
||||
l32e sp, sp, -12 /* switch back to the original stack */
|
||||
|
||||
/* Done with C handler; re-enable exception mode, disabling window overflow */
|
||||
movi a2, PS_INTLEVEL(5) | PS_EXCM /* TOCHECK */
|
||||
wsr a2, PS
|
||||
rsync
|
||||
|
||||
/* Restore the special registers.
|
||||
* WINDOWSTART will be restored near the end.
|
||||
*/
|
||||
movi a0, _l4_save_ctx + SPECREG_OFFSET
|
||||
l32i a2, a0, 8
|
||||
wsr a2, SAR
|
||||
l32i a2, a0, 12
|
||||
wsr a2, LBEG
|
||||
l32i a2, a0, 16
|
||||
wsr a2, LEND
|
||||
l32i a2, a0, 20
|
||||
wsr a2, LCOUNT
|
||||
l32i a2, a0, 24
|
||||
wsr a2, EPC1
|
||||
|
||||
/* Restoring the physical registers.
|
||||
* This is the reverse to the saving process above.
|
||||
*/
|
||||
|
||||
/* Rotate back to the final window, then start loading 12 registers at a time,
|
||||
* in 5 iterations.
|
||||
* Again, a1 is the downcounter and a3 is the save area pointer.
|
||||
* After each rotation, a1 and a3 are copied from a13 and a15.
|
||||
* To simplify the loop, we put the initial values into a13 and a15.
|
||||
*/
|
||||
rotw -4
|
||||
movi a15, _l4_save_ctx + 64 * 4 /* point to the end of the save area */
|
||||
movi a13, 5
|
||||
|
||||
1:
|
||||
/* Copy a1 and a3 from their previous location,
|
||||
* at the same time decrementing and adjusting the save area pointer.
|
||||
*/
|
||||
addi a1, a13, -1
|
||||
addi a3, a15, -48
|
||||
|
||||
/* Load 12 registers */
|
||||
l32i a4, a3, 0
|
||||
l32i a5, a3, 4
|
||||
l32i a6, a3, 8
|
||||
l32i a7, a3, 12
|
||||
l32i a8, a3, 16
|
||||
l32i a9, a3, 20
|
||||
l32i a10, a3, 24
|
||||
l32i a11, a3, 28 /* ensure PS and EPC written */
|
||||
l32i a12, a3, 32
|
||||
l32i a13, a3, 36
|
||||
l32i a14, a3, 40
|
||||
l32i a15, a3, 44
|
||||
|
||||
/* Done with the loop? */
|
||||
beqz a1, 2f
|
||||
/* If no, rotate the window and repeat */
|
||||
rotw -3
|
||||
j 1b
|
||||
|
||||
2:
|
||||
/* Done with the loop. Only 4 registers (a0-a3 in the original window) remain
|
||||
* to be restored. Also need to restore WINDOWSTART, since all the general
|
||||
* registers are now in place.
|
||||
*/
|
||||
movi a0, _l4_save_ctx
|
||||
|
||||
l32i a2, a0, SPECREG_OFFSET + 4
|
||||
wsr a2, WINDOWSTART
|
||||
|
||||
l32i a1, a0, 4
|
||||
l32i a2, a0, 8
|
||||
l32i a3, a0, 12
|
||||
rsr a0, EXCSAVE_4 /* holds the value of a0 before the interrupt handler */
|
||||
|
||||
/* Return from the interrupt, restoring PS from EPS_4 */
|
||||
rfi 4
|
||||
|
||||
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||
|
||||
/* The linker has no reason to link in this file; all symbols it exports are already defined
|
||||
(weakly!) in the default int handler. Define a symbol here so we can use it to have the
|
||||
linker inspect this anyway. */
|
||||
|
||||
.global ld_include_hli_vectors_bt
|
||||
ld_include_hli_vectors_bt:
|
||||
@@ -0,0 +1,466 @@
|
||||
|
||||
menu "HCI Config"
|
||||
|
||||
choice BT_LE_HCI_INTERFACE
|
||||
prompt "Select HCI interface"
|
||||
default BT_LE_HCI_INTERFACE_USE_RAM
|
||||
|
||||
config BT_LE_HCI_INTERFACE_USE_RAM
|
||||
bool "ram"
|
||||
help
|
||||
Use RAM as HCI interface
|
||||
config BT_LE_HCI_INTERFACE_USE_UART
|
||||
bool "uart"
|
||||
help
|
||||
Use UART as HCI interface
|
||||
endchoice
|
||||
|
||||
config BT_LE_HCI_UART_PORT
|
||||
int "HCI UART port"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 1
|
||||
help
|
||||
Set the port number of HCI UART
|
||||
|
||||
config BT_LE_HCI_UART_FLOWCTRL
|
||||
bool "HCI uart Hardware Flow ctrl"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default n
|
||||
|
||||
config BT_LE_HCI_UART_TX_PIN
|
||||
int "HCI uart Tx gpio"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 19
|
||||
|
||||
config BT_LE_HCI_UART_RX_PIN
|
||||
int "HCI uart Rx gpio"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 10
|
||||
|
||||
config BT_LE_HCI_UART_RTS_PIN
|
||||
int "HCI uart RTS gpio"
|
||||
depends on BT_LE_HCI_UART_FLOWCTRL
|
||||
default 4
|
||||
|
||||
config BT_LE_HCI_UART_CTS_PIN
|
||||
int "HCI uart CTS gpio"
|
||||
depends on BT_LE_HCI_UART_FLOWCTRL
|
||||
default 5
|
||||
|
||||
config BT_LE_HCI_UART_BAUD
|
||||
int "HCI uart baudrate"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 921600
|
||||
help
|
||||
HCI uart baud rate 115200 ~ 1000000
|
||||
|
||||
choice BT_LE_HCI_UART_PARITY
|
||||
prompt "select uart parity"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default BT_LE_HCI_UART_UART_PARITY_DISABLE
|
||||
|
||||
config BT_LE_HCI_UART_UART_PARITY_DISABLE
|
||||
bool "PARITY_DISABLE"
|
||||
help
|
||||
UART_PARITY_DISABLE
|
||||
config BT_LE_HCI_UART_UART_PARITY_EVEN
|
||||
bool "PARITY_EVEN"
|
||||
help
|
||||
UART_PARITY_EVEN
|
||||
config BT_LE_HCI_UART_UART_PARITY_ODD
|
||||
bool "PARITY_ODD"
|
||||
help
|
||||
UART_PARITY_ODD
|
||||
endchoice
|
||||
|
||||
config BT_LE_HCI_UART_TASK_STACK_SIZE
|
||||
int "HCI uart task stack size"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 1000
|
||||
help
|
||||
Set the size of uart task stack
|
||||
endmenu
|
||||
|
||||
config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
|
||||
bool
|
||||
default y
|
||||
help
|
||||
Enable NPL porting for controller.
|
||||
|
||||
|
||||
menuconfig BT_LE_50_FEATURE_SUPPORT
|
||||
bool "Enable BLE 5 feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE 5 feature
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_2M_PHY
|
||||
bool "Enable 2M Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable 2M-PHY
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
bool "Enable coded Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable coded-PHY
|
||||
|
||||
config BT_LE_EXT_ADV
|
||||
bool "Enable extended advertising"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable this option to do extended advertising. Extended advertising
|
||||
will be supported from BLE 5.0 onwards.
|
||||
|
||||
if BT_LE_EXT_ADV
|
||||
config BT_LE_MAX_EXT_ADV_INSTANCES
|
||||
int "Maximum number of extended advertising instances."
|
||||
range 0 4
|
||||
default 1
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Change this option to set maximum number of extended advertising
|
||||
instances. Minimum there is always one instance of
|
||||
advertising. Enter how many more advertising instances you
|
||||
want.
|
||||
Each extended advertising instance will take about 0.5k DRAM.
|
||||
|
||||
config BT_LE_EXT_ADV_MAX_SIZE
|
||||
int "Maximum length of the advertising data."
|
||||
range 0 1650
|
||||
default 1650
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Defines the length of the extended adv data. The value should not
|
||||
exceed 1650.
|
||||
|
||||
config BT_LE_ENABLE_PERIODIC_ADV
|
||||
bool "Enable periodic advertisement."
|
||||
default y
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Enable this option to start periodic advertisement.
|
||||
|
||||
config BT_LE_PERIODIC_ADV_SYNC_TRANSFER
|
||||
bool "Enable Transer Sync Events"
|
||||
depends on BT_LE_ENABLE_PERIODIC_ADV
|
||||
default y
|
||||
help
|
||||
This enables controller transfer periodic sync events to host
|
||||
|
||||
endif
|
||||
|
||||
config BT_LE_MAX_PERIODIC_SYNCS
|
||||
int "Maximum number of periodic advertising syncs"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
|
||||
range 0 3
|
||||
default 1 if BT_LE_ENABLE_PERIODIC_ADV
|
||||
default 0
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic sync
|
||||
connections. This should be less than maximum connections allowed by
|
||||
controller.
|
||||
|
||||
config BT_LE_MAX_PERIODIC_ADVERTISER_LIST
|
||||
int "Maximum number of periodic advertiser list"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
range 1 5
|
||||
default 5
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic advertiser list.
|
||||
|
||||
menu "Memory Settings"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_COUNT
|
||||
int "MSYS_1 Block Count"
|
||||
default 12
|
||||
help
|
||||
MSYS is a system level mbuf registry. For prepare write & prepare
|
||||
responses MBUFs are allocated out of msys_1 pool. For NIMBLE_MESH
|
||||
enabled cases, this block count is increased by 8 than user defined
|
||||
count.
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_SIZE
|
||||
int "MSYS_1 Block Size"
|
||||
default 256
|
||||
help
|
||||
Dynamic memory size of block 1
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_COUNT
|
||||
int "MSYS_2 Block Count"
|
||||
default 24
|
||||
help
|
||||
Dynamic memory count
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_SIZE
|
||||
int "MSYS_2 Block Size"
|
||||
default 320
|
||||
help
|
||||
Dynamic memory size of block 2
|
||||
|
||||
config BT_LE_ACL_BUF_COUNT
|
||||
int "ACL Buffer count"
|
||||
default 10
|
||||
help
|
||||
The number of ACL data buffers.
|
||||
|
||||
config BT_LE_ACL_BUF_SIZE
|
||||
int "ACL Buffer size"
|
||||
default 517
|
||||
help
|
||||
This is the maximum size of the data portion of HCI ACL data packets.
|
||||
It does not include the HCI data header (of 4 bytes)
|
||||
|
||||
config BT_LE_HCI_EVT_BUF_SIZE
|
||||
int "HCI Event Buffer size"
|
||||
default 257 if BT_LE_EXT_ADV
|
||||
default 70
|
||||
help
|
||||
This is the size of each HCI event buffer in bytes. In case of
|
||||
extended advertising, packets can be fragmented. 257 bytes is the
|
||||
maximum size of a packet.
|
||||
|
||||
config BT_LE_HCI_EVT_HI_BUF_COUNT
|
||||
int "High Priority HCI Event Buffer count"
|
||||
default 30
|
||||
help
|
||||
This is the high priority HCI events' buffer size. High-priority
|
||||
event buffers are for everything except advertising reports. If there
|
||||
are no free high-priority event buffers then host will try to allocate a
|
||||
low-priority buffer instead
|
||||
|
||||
config BT_LE_HCI_EVT_LO_BUF_COUNT
|
||||
int "Low Priority HCI Event Buffer count"
|
||||
default 8
|
||||
help
|
||||
This is the low priority HCI events' buffer size. Low-priority event
|
||||
buffers are only used for advertising reports. If there are no free
|
||||
low-priority event buffers, then an incoming advertising report will
|
||||
get dropped
|
||||
endmenu
|
||||
|
||||
config BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
int "Controller task stack size"
|
||||
default 5120 if BLE_MESH
|
||||
default 4096
|
||||
help
|
||||
This configures stack size of NimBLE controller task
|
||||
|
||||
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
|
||||
bool "Controller log enable"
|
||||
default n
|
||||
help
|
||||
Enable controller log
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
|
||||
bool "enable controller log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable controller log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
|
||||
bool "enable HCI log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable hci log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
|
||||
bool "Controller log dump mode only"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Only operate in dump mode
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF1_SIZE
|
||||
int "size of the first BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the first BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF2_SIZE
|
||||
int "size of the second BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 1024
|
||||
help
|
||||
Configure the size of the second BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_HCI_BUF_SIZE
|
||||
int "size of the BLE HCI LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the BLE HCI LOG buffer.
|
||||
|
||||
config BT_LE_LL_RESOLV_LIST_SIZE
|
||||
int "BLE LL Resolving list size"
|
||||
range 1 5
|
||||
default 4
|
||||
help
|
||||
Configure the size of resolving list used in link layer.
|
||||
|
||||
menuconfig BT_LE_SECURITY_ENABLE
|
||||
bool "Enable BLE SM feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE sm feature
|
||||
|
||||
config BT_LE_SM_LEGACY
|
||||
bool "Security manager legacy pairing"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager legacy pairing
|
||||
|
||||
config BT_LE_SM_SC
|
||||
bool "Security manager secure connections (4.2)"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager secure connections
|
||||
|
||||
config BT_LE_SM_SC_DEBUG_KEYS
|
||||
bool "Use predefined public-private key pair"
|
||||
default n
|
||||
depends on BT_LE_SECURITY_ENABLE && BT_LE_SM_SC
|
||||
help
|
||||
If this option is enabled, SM uses predefined DH key pair as described
|
||||
in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to
|
||||
decrypt air traffic easily and thus should only be used for debugging.
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_ENCRYPTION
|
||||
bool "Enable LE encryption"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable encryption connection
|
||||
|
||||
config BT_LE_CRYPTO_STACK_MBEDTLS
|
||||
bool "Override TinyCrypt with mbedTLS for crypto computations"
|
||||
default y
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
select MBEDTLS_ECP_RESTARTABLE
|
||||
select MBEDTLS_CMAC_C
|
||||
help
|
||||
Enable this option to choose mbedTLS instead of TinyCrypt for crypto
|
||||
computations.
|
||||
|
||||
config BT_LE_WHITELIST_SIZE
|
||||
int "BLE white list size"
|
||||
range 1 15
|
||||
default 12
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
help
|
||||
BLE list size
|
||||
|
||||
config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
int "BLE duplicate scan list count"
|
||||
range 1 100
|
||||
default 20
|
||||
help
|
||||
config the max count of duplicate scan list
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
|
||||
config BT_LE_MAX_CONNECTIONS
|
||||
int "Maximum number of concurrent connections"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
range 1 2
|
||||
default 2
|
||||
help
|
||||
Defines maximum number of concurrent BLE connections. For ESP32, user
|
||||
is expected to configure BTDM_CTRL_BLE_MAX_CONN from controller menu
|
||||
along with this option. Similarly for ESP32-C3 or ESP32-S3, user is expected to
|
||||
configure BT_CTRL_BLE_MAX_ACT from controller menu.
|
||||
Each connection will take about 1k DRAM.
|
||||
|
||||
choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM
|
||||
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection"
|
||||
default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
depends on ESP_COEX_SW_COEXIST_ENABLE
|
||||
help
|
||||
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to
|
||||
better avoid dramatic performance deterioration of Wi-Fi.
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
bool "Force Enable"
|
||||
help
|
||||
Always enable the limitation on max tx/rx time for Coded-PHY connection
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
bool "Force Disable"
|
||||
help
|
||||
Disable the limitation on max tx/rx time for Coded-PHY connection
|
||||
endchoice
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
int
|
||||
default 0 if !ESP_COEX_SW_COEXIST_ENABLE
|
||||
default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
|
||||
config BT_LE_SLEEP_ENABLE
|
||||
bool "Enable BLE sleep"
|
||||
default n
|
||||
help
|
||||
Enable BLE sleep
|
||||
|
||||
config BT_LE_USE_ESP_TIMER
|
||||
bool "Use Esp Timer for callout"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
bool "BLE adv report flow control supported"
|
||||
default y
|
||||
help
|
||||
The function is mainly used to enable flow control for advertising reports. When it is enabled,
|
||||
advertising reports will be discarded by the controller if the number of unprocessed advertising
|
||||
reports exceeds the size of BLE adv report flow control.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM
|
||||
int "BLE adv report flow control number"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 50 1000
|
||||
default 100
|
||||
help
|
||||
The number of unprocessed advertising report that bluetooth host can save.If you set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a
|
||||
lot of adv packets and this may cause system memory run out. For example, if you set
|
||||
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv
|
||||
packets as fast as possible, otherwise it will cause adv packets lost.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
int "BLE adv lost event threshold value"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 1 1000
|
||||
default 20
|
||||
help
|
||||
When adv report flow control is enabled, The ADV lost event will be generated when the number
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
config BT_LE_RELEASE_IRAM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_BT_CFG_H__
|
||||
#define __ESP_BT_CFG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "syscfg/syscfg.h"
|
||||
#endif
|
||||
|
||||
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (2)
|
||||
#else
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (1)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS)
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES)
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)
|
||||
#if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT)
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (2)
|
||||
#else
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_CONNECTIONS)
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS (CONFIG_BT_LE_MAX_CONNECTIONS)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS (2)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_ACL_BUF_SIZE)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE (CONFIG_BT_LE_ACL_BUF_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE (255)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_ACL_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT (CONFIG_BT_LE_ACL_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT (24)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_BUF_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (CONFIG_BT_LE_HCI_EVT_BUF_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (70)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_EXT_ADV_MAX_SIZE)
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (CONFIG_BT_LE_EXT_ADV_MAX_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (31)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES)
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_WHITELIST_SIZE)
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (CONFIG_BT_LE_WHITELIST_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (12)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (30)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8)
|
||||
#endif
|
||||
#if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT)
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#else
|
||||
#define HCI_UART_EN 0 // hci ram mode
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#else
|
||||
#define NIMBLE_SLEEP_ENABLE 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_BT_LE_TX_CCA_ENABLED
|
||||
#define DEFAULT_BT_LE_TX_CCA_ENABLED (CONFIG_BT_LE_TX_CCA_ENABLED)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_TX_CCA_ENABLED (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LE_CCA_RSSI_THRESH
|
||||
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (CONFIG_BT_LE_CCA_RSSI_THRESH)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (50)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N DEFAULT_BT_LE_EXT_ADV_MAX_SIZE
|
||||
|
||||
|
||||
#if HCI_UART_EN
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (CONFIG_BT_LE_HCI_UART_TX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (CONFIG_BT_LE_HCI_UART_RX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (CONFIG_BT_LE_HCI_UART_PORT)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (CONFIG_BT_LE_HCI_UART_BAUD)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0)
|
||||
#endif
|
||||
|
||||
/* Unchanged configuration */
|
||||
|
||||
#define BLE_LL_CTRL_PROC_TIMEOUT_MS_N (40000) /* ms */
|
||||
|
||||
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS_N (1)
|
||||
|
||||
#define BLE_LL_SCHED_ADV_MAX_USECS_N (852)
|
||||
|
||||
#define BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N (502)
|
||||
|
||||
#define BLE_LL_SCHED_MAX_ADV_PDU_USECS_N (376)
|
||||
|
||||
#define BLE_LL_SUB_VERS_NR_N (0x0000)
|
||||
|
||||
#define BLE_LL_JITTER_USECS_N (16)
|
||||
|
||||
#define BLE_PHY_MAX_PWR_DBM_N (10)
|
||||
|
||||
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000)
|
||||
|
||||
#ifdef CONFIG_XTAL_FREQ_26
|
||||
#define RTC_FREQ_N (40000) /* in Hz */
|
||||
#else
|
||||
#define RTC_FREQ_N (32000) /* in Hz */
|
||||
#endif // CONFIG_XTAL_FREQ_26
|
||||
|
||||
#define BLE_LL_TX_PWR_DBM_N (9)
|
||||
|
||||
|
||||
#define RUN_BQB_TEST (0)
|
||||
#define RUN_QA_TEST (0)
|
||||
#define NIMBLE_DISABLE_SCAN_BACKOFF (0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_CFG_H__ */
|
||||
@@ -0,0 +1,477 @@
|
||||
config BT_CTRL_MODE_EFF
|
||||
int
|
||||
default 1
|
||||
|
||||
config BT_CTRL_BLE_MAX_ACT
|
||||
int "BLE Max Instances"
|
||||
default 6
|
||||
range 1 10
|
||||
help
|
||||
BLE maximum activities of bluetooth controller,both of connections,
|
||||
scan , sync and adv(periodic adv, multi-adv). Each instance needs to
|
||||
consume 828 bytes, you can save RAM by modifying the instance value
|
||||
according to actual needs.
|
||||
|
||||
config BT_CTRL_BLE_MAX_ACT_EFF
|
||||
int
|
||||
default BT_CTRL_BLE_MAX_ACT
|
||||
default 0
|
||||
|
||||
config BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB
|
||||
int "BLE static ACL TX buffer numbers"
|
||||
range 0 12
|
||||
default 0
|
||||
help
|
||||
BLE ACL buffer have two methods to be allocated. One is persistent allocating
|
||||
(alloate when controller initialise, never free until controller de-initialise)
|
||||
another is dynamically allocating (allocate before TX and free after TX).
|
||||
|
||||
choice BT_CTRL_PINNED_TO_CORE_CHOICE
|
||||
prompt "The cpu core which bluetooth controller run"
|
||||
depends on !FREERTOS_UNICORE
|
||||
help
|
||||
Specify the cpu core to run bluetooth controller.
|
||||
Can not specify no-affinity.
|
||||
|
||||
config BT_CTRL_PINNED_TO_CORE_0
|
||||
bool "Core 0 (PRO CPU)"
|
||||
config BT_CTRL_PINNED_TO_CORE_1
|
||||
bool "Core 1 (APP CPU)"
|
||||
depends on !FREERTOS_UNICORE
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_PINNED_TO_CORE
|
||||
int
|
||||
default 0 if BT_CTRL_PINNED_TO_CORE_0
|
||||
default 1 if BT_CTRL_PINNED_TO_CORE_1
|
||||
default 0
|
||||
|
||||
choice BT_CTRL_HCI_MODE_CHOICE
|
||||
prompt "HCI mode"
|
||||
help
|
||||
Specify HCI mode as VHCI or UART(H4)
|
||||
|
||||
config BT_CTRL_HCI_MODE_VHCI
|
||||
bool "VHCI"
|
||||
help
|
||||
Normal option. Mostly, choose this VHCI when bluetooth host run on ESP32S3 or ESP32C3.
|
||||
|
||||
config BT_CTRL_HCI_MODE_UART_H4
|
||||
bool "UART(H4)"
|
||||
help
|
||||
If use external bluetooth host which run on other hardware and use UART as the HCI interface,
|
||||
choose this option.
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_HCI_TL
|
||||
int
|
||||
default 0 if BT_CTRL_HCI_MODE_UART_H4
|
||||
default 1 if BT_CTRL_HCI_M0DE_VHCI
|
||||
default 1
|
||||
help
|
||||
HCI mode as VHCI or UART(H4)
|
||||
|
||||
config BT_CTRL_ADV_DUP_FILT_MAX
|
||||
int "The maxinum number of 5.0 extend duplicate scan filter"
|
||||
range 1 500
|
||||
default 30
|
||||
help
|
||||
The maxinum number of suplicate scan filter
|
||||
|
||||
choice BT_BLE_CCA_MODE
|
||||
prompt "BLE CCA mode"
|
||||
default BT_BLE_CCA_MODE_NONE
|
||||
help
|
||||
Define BT BLE CCA mode
|
||||
|
||||
config BT_BLE_CCA_MODE_NONE
|
||||
bool "NONE"
|
||||
config BT_BLE_CCA_MODE_HW
|
||||
bool "Hardware"
|
||||
config BT_BLE_CCA_MODE_SW
|
||||
bool "Software"
|
||||
endchoice
|
||||
|
||||
config BT_BLE_CCA_MODE
|
||||
int
|
||||
default 0 if BT_BLE_CCA_MODE_NONE
|
||||
default 1 if BT_BLE_CCA_MODE_HW
|
||||
default 2 if BT_BLE_CCA_MODE_SW
|
||||
|
||||
config BT_CTRL_HW_CCA_VAL
|
||||
int "CCA threshold value"
|
||||
range 20 100
|
||||
default 20
|
||||
help
|
||||
It is the threshold value of HW CCA, if the value is 30, it means CCA threshold is -30 dBm.
|
||||
|
||||
config BT_CTRL_HW_CCA_EFF
|
||||
int
|
||||
default 1 if BT_CTRL_HW_CCA
|
||||
default 0
|
||||
help
|
||||
If other devices are sending packets in the air and the signal is strong,
|
||||
the packet hw to be sent this time is cancelled.
|
||||
|
||||
choice BT_CTRL_CE_LENGTH_TYPE
|
||||
prompt "Connection event length determination method"
|
||||
help
|
||||
Specify connection event length determination
|
||||
|
||||
config BT_CTRL_CE_LENGTH_TYPE_ORIG
|
||||
bool "ORIGINAL"
|
||||
config BT_CTRL_CE_LENGTH_TYPE_CE
|
||||
bool "Use CE parameter for HCI command"
|
||||
config BT_CTRL_CE_LENGTH_TYPE_SD
|
||||
bool "Use Espressif self-defined method"
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_CE_LENGTH_TYPE_EFF
|
||||
int
|
||||
default 0 if BT_CTRL_CE_LENGTH_TYPE_ORIG
|
||||
default 1 if BT_CTRL_CE_LENGTH_TYPE_CE
|
||||
default 2 if BT_CTRL_CE_LENGTH_TYPE_SD
|
||||
|
||||
choice BT_CTRL_TX_ANTENNA_INDEX
|
||||
prompt "default Tx anntena used"
|
||||
help
|
||||
Specify default Tx antenna used for bluetooth
|
||||
|
||||
config BT_CTRL_TX_ANTENNA_INDEX_0
|
||||
bool "Antenna 0"
|
||||
config BT_CTRL_TX_ANTENNA_INDEX_1
|
||||
bool "Antenna 1"
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_TX_ANTENNA_INDEX_EFF
|
||||
int
|
||||
default 0 if BT_CTRL_TX_ANTENNA_INDEX_0
|
||||
default 1 if BT_CTRL_TX_ANTENNA_INDEX_1
|
||||
|
||||
choice BT_CTRL_RX_ANTENNA_INDEX
|
||||
prompt "default Rx anntena used"
|
||||
help
|
||||
Specify default Rx antenna used for bluetooth
|
||||
|
||||
config BT_CTRL_RX_ANTENNA_INDEX_0
|
||||
bool "Antenna 0"
|
||||
config BT_CTRL_RX_ANTENNA_INDEX_1
|
||||
bool "Antenna 1"
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_RX_ANTENNA_INDEX_EFF
|
||||
int
|
||||
default 0 if BT_CTRL_RX_ANTENNA_INDEX_0
|
||||
default 1 if BT_CTRL_RX_ANTENNA_INDEX_1
|
||||
|
||||
choice BT_CTRL_DFT_TX_POWER_LEVEL
|
||||
prompt "BLE default Tx power level"
|
||||
default BT_CTRL_DFT_TX_POWER_LEVEL_P9
|
||||
help
|
||||
Specify default Tx power level
|
||||
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N24
|
||||
bool "-24dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N21
|
||||
bool "-21dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N18
|
||||
bool "-18dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N15
|
||||
bool "-15dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N12
|
||||
bool "-12dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N9
|
||||
bool "-9dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N6
|
||||
bool "-6dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N3
|
||||
bool "-3dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_N0
|
||||
bool "0dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P3
|
||||
bool "+3dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P6
|
||||
bool "+6dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P9
|
||||
bool "+9dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P12
|
||||
bool "+12dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P15
|
||||
bool "+15dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P18
|
||||
bool "+18dBm"
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_P21
|
||||
bool "+21dBm"
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_DFT_TX_POWER_LEVEL_EFF
|
||||
int
|
||||
default 0 if BT_CTRL_DFT_TX_POWER_LEVEL_N24
|
||||
default 1 if BT_CTRL_DFT_TX_POWER_LEVEL_N21
|
||||
default 2 if BT_CTRL_DFT_TX_POWER_LEVEL_N18
|
||||
default 3 if BT_CTRL_DFT_TX_POWER_LEVEL_N15
|
||||
default 4 if BT_CTRL_DFT_TX_POWER_LEVEL_N12
|
||||
default 5 if BT_CTRL_DFT_TX_POWER_LEVEL_N9
|
||||
default 6 if BT_CTRL_DFT_TX_POWER_LEVEL_N6
|
||||
default 7 if BT_CTRL_DFT_TX_POWER_LEVEL_N3
|
||||
default 8 if BT_CTRL_DFT_TX_POWER_LEVEL_N0
|
||||
default 9 if BT_CTRL_DFT_TX_POWER_LEVEL_P3
|
||||
default 10 if BT_CTRL_DFT_TX_POWER_LEVEL_P6
|
||||
default 11 if BT_CTRL_DFT_TX_POWER_LEVEL_P9
|
||||
default 12 if BT_CTRL_DFT_TX_POWER_LEVEL_P12
|
||||
default 13 if BT_CTRL_DFT_TX_POWER_LEVEL_P15
|
||||
default 14 if BT_CTRL_DFT_TX_POWER_LEVEL_P18
|
||||
default 15 if BT_CTRL_DFT_TX_POWER_LEVEL_P21
|
||||
default 0
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
bool "BLE adv report flow control supported"
|
||||
default y
|
||||
help
|
||||
The function is mainly used to enable flow control for advertising reports. When it is enabled,
|
||||
advertising reports will be discarded by the controller if the number of unprocessed advertising
|
||||
reports exceeds the size of BLE adv report flow control.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM
|
||||
int "BLE adv report flow control number"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 50 1000
|
||||
default 100
|
||||
help
|
||||
The number of unprocessed advertising report that bluetooth host can save.If you set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a
|
||||
lot of adv packets and this may cause system memory run out. For example, if you set
|
||||
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv
|
||||
packets as fast as possible, otherwise it will cause adv packets lost.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
int "BLE adv lost event threshold value"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 1 1000
|
||||
default 20
|
||||
help
|
||||
When adv report flow control is enabled, The ADV lost event will be generated when the number
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
config BT_CTRL_BLE_SCAN_DUPL
|
||||
bool "BLE Scan Duplicate Options"
|
||||
default y
|
||||
help
|
||||
This select enables parameters setting of BLE scan duplicate.
|
||||
|
||||
choice BT_CTRL_SCAN_DUPL_TYPE
|
||||
prompt "Scan Duplicate Type"
|
||||
default BT_CTRL_SCAN_DUPL_TYPE_DEVICE
|
||||
depends on BT_CTRL_BLE_SCAN_DUPL
|
||||
help
|
||||
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use
|
||||
advertiser address filtering. The adv packet of the same address is only allowed to be reported once.
|
||||
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising
|
||||
data and device address filtering. All different adv packets with the same address are allowed to be
|
||||
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data
|
||||
filtering. All same advertising data only allow to be reported once even though they are from
|
||||
different devices.
|
||||
|
||||
config BT_CTRL_SCAN_DUPL_TYPE_DEVICE
|
||||
bool "Scan Duplicate By Device Address"
|
||||
help
|
||||
Advertising packets with the same address, address type, and advertising type are reported once.
|
||||
|
||||
config BT_CTRL_SCAN_DUPL_TYPE_DATA
|
||||
bool "Scan Duplicate By Advertising Data"
|
||||
help
|
||||
Advertising packets with identical advertising data, address type, and advertising type
|
||||
are reported only once, even if they originate from different devices.
|
||||
|
||||
config BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
bool "Scan Duplicate By Device Address And Advertising Data"
|
||||
help
|
||||
Advertising packets with the same address, advertising data, address type,
|
||||
and advertising type are reported only once.
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_SCAN_DUPL_TYPE
|
||||
int
|
||||
depends on BT_CTRL_BLE_SCAN_DUPL
|
||||
default 0 if BT_CTRL_SCAN_DUPL_TYPE_DEVICE
|
||||
default 1 if BT_CTRL_SCAN_DUPL_TYPE_DATA
|
||||
default 2 if BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
default 0
|
||||
|
||||
config BT_CTRL_SCAN_DUPL_CACHE_SIZE
|
||||
int "Maximum number of devices in scan duplicate filter"
|
||||
depends on BT_CTRL_BLE_SCAN_DUPL
|
||||
range 10 1000
|
||||
default 100
|
||||
help
|
||||
Maximum number of devices which can be recorded in scan duplicate filter.
|
||||
When the maximum amount of device in the filter is reached, the cache will be refreshed.
|
||||
|
||||
config BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD
|
||||
int "Duplicate scan list refresh period (seconds)"
|
||||
depends on BT_CTRL_BLE_SCAN_DUPL
|
||||
range 0 1000
|
||||
default 0
|
||||
help
|
||||
If the period value is non-zero, the controller will periodically clear the device information
|
||||
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared
|
||||
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the
|
||||
Host in advertising report events.
|
||||
There are two scenarios where the ADV packet will be repeatedly reported:
|
||||
1. The duplicate scan cache is full, the controller will delete the oldest device information and
|
||||
add new device information.
|
||||
2. When the refresh period is up, the controller will clear all device information and start filtering
|
||||
again.
|
||||
|
||||
config BT_CTRL_BLE_MESH_SCAN_DUPL_EN
|
||||
bool "Special duplicate scan mechanism for BLE Mesh scan"
|
||||
depends on BT_CTRL_BLE_SCAN_DUPL
|
||||
default n
|
||||
help
|
||||
This enables the BLE scan duplicate for special BLE Mesh scan.
|
||||
|
||||
config BT_CTRL_MESH_DUPL_SCAN_CACHE_SIZE
|
||||
int "Maximum number of Mesh adv packets in scan duplicate filter"
|
||||
depends on BT_CTRL_BLE_MESH_SCAN_DUPL_EN
|
||||
range 10 1000
|
||||
default 100
|
||||
help
|
||||
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
|
||||
When the maximum amount of device in the filter is reached, the cache will be refreshed.
|
||||
|
||||
choice BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM
|
||||
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection"
|
||||
default BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
depends on ESP_COEX_SW_COEXIST_ENABLE
|
||||
help
|
||||
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to
|
||||
better avoid dramatic performance deterioration of Wi-Fi.
|
||||
|
||||
config BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
bool "Force Enable"
|
||||
help
|
||||
Always enable the limitation on max tx/rx time for Coded-PHY connection
|
||||
|
||||
config BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
bool "Force Disable"
|
||||
help
|
||||
Disable the limitation on max tx/rx time for Coded-PHY connection
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
int
|
||||
default 0 if !ESP_COEX_SW_COEXIST_ENABLE
|
||||
default 1 if BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
default 0 if BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
|
||||
menu "MODEM SLEEP Options"
|
||||
visible if BT_ENABLED
|
||||
|
||||
config BT_CTRL_MODEM_SLEEP
|
||||
bool "Bluetooth modem sleep"
|
||||
depends on !BT_CTRL_HCI_MODE_UART_H4
|
||||
default n
|
||||
help
|
||||
Enable/disable bluetooth controller low power mode.
|
||||
Modem sleep is not supported to be used with UART HCI.
|
||||
|
||||
config BT_CTRL_MODEM_SLEEP_MODE_1
|
||||
bool "Bluetooth Modem sleep Mode 1"
|
||||
depends on BT_CTRL_MODEM_SLEEP
|
||||
default y
|
||||
help
|
||||
Mode 1 is the currently supported sleep mode. In this mode,
|
||||
bluetooth controller sleeps between and BLE events. A low
|
||||
power clock is used to maintain bluetooth reference clock.
|
||||
|
||||
choice BT_CTRL_LOW_POWER_CLOCK
|
||||
prompt "Bluetooth low power clock"
|
||||
depends on BT_CTRL_MODEM_SLEEP_MODE_1
|
||||
help
|
||||
Select the low power clock source for bluetooth controller
|
||||
|
||||
config BT_CTRL_LPCLK_SEL_MAIN_XTAL
|
||||
bool "Main crystal"
|
||||
help
|
||||
Main crystal can be used as low power clock for bluetooth modem sleep. If this option is
|
||||
selected, bluetooth modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, and
|
||||
bluetooth can work under light sleep enabled. Main crystal has a relatively better performance
|
||||
than other bluetooth low power clock sources.
|
||||
config BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
bool "External 32kHz crystal"
|
||||
depends on RTC_CLK_SRC_EXT_CRYS
|
||||
help
|
||||
External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency
|
||||
stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth
|
||||
modem sleep to be used with both DFS and light sleep.
|
||||
|
||||
config BT_CTRL_LPCLK_SEL_RTC_SLOW
|
||||
bool "Internal 150kHz RC oscillator"
|
||||
depends on RTC_CLK_SRC_INT_RC
|
||||
help
|
||||
Internal 150kHz RC oscillator. The accuracy of this clock is a lot larger than 500ppm which is required
|
||||
in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.
|
||||
endchoice
|
||||
|
||||
config BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
|
||||
bool "power up main XTAL during light sleep"
|
||||
depends on (BT_CTRL_LPCLK_SEL_MAIN_XTAL || BT_CTRL_LPCLK_SEL_EXT_32K_XTAL) && FREERTOS_USE_TICKLESS_IDLE
|
||||
default n
|
||||
help
|
||||
If this option is selected, the main crystal will power up during light sleep when the low power clock
|
||||
selects an external 32kHz crystal but the external 32kHz crystal does not exist or the low power clock
|
||||
selects the main crystal.
|
||||
|
||||
endmenu
|
||||
|
||||
config BT_CTRL_SLEEP_MODE_EFF
|
||||
int
|
||||
default 1 if BT_CTRL_MODEM_SLEEP_MODE_1
|
||||
default 0
|
||||
|
||||
config BT_CTRL_SLEEP_CLOCK_EFF
|
||||
int
|
||||
default 1 if BT_CTRL_LPCLK_SEL_MAIN_XTAL
|
||||
default 2 if BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
||||
default 3 if BT_CTRL_LPCLK_SEL_RTC_SLOW
|
||||
|
||||
default 0
|
||||
|
||||
config BT_CTRL_HCI_TL_EFF
|
||||
int
|
||||
default 0 if BT_CTRL_HCI_MODE_UART_H4
|
||||
default 1 if BT_CTRL_HCI_M0DE_VHCI
|
||||
default 1
|
||||
|
||||
config BT_CTRL_AGC_RECORRECT_EN
|
||||
bool "Enable HW AGC recorrect"
|
||||
default n
|
||||
help
|
||||
Enable uncoded phy AGC recorrect
|
||||
|
||||
config BT_CTRL_CODED_AGC_RECORRECT_EN
|
||||
bool "Enable coded phy AGC recorrect"
|
||||
depends on BT_CTRL_AGC_RECORRECT_EN
|
||||
default n
|
||||
help
|
||||
Enable coded phy AGC recorrect
|
||||
|
||||
config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX
|
||||
bool "Disable active scan backoff"
|
||||
default n
|
||||
help
|
||||
Disable active scan backoff. The bluetooth spec requires that scanners should run a backoff procedure to
|
||||
minimize collision of scan request PDUs from nultiple scanners. If scan backoff is disabled, in active
|
||||
scanning, scan request PDU will be sent every time when HW receives scannable ADV PDU.
|
||||
|
||||
config BT_BLE_ADV_DATA_LENGTH_ZERO_AUX
|
||||
bool "Enable aux packet when ext adv data length is zero"
|
||||
default n
|
||||
help
|
||||
When this option is enabled, auxiliary packets will be present in the events of
|
||||
'Non-Connectable and Non-Scannable' regardless of whether the advertising length is 0.
|
||||
If this option is not enabled, auxiliary packets will only be present when the advertising length is not 0.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,564 @@
|
||||
|
||||
menu "HCI Config"
|
||||
|
||||
choice BT_LE_HCI_INTERFACE
|
||||
prompt "Select HCI interface"
|
||||
default BT_LE_HCI_INTERFACE_USE_RAM
|
||||
|
||||
config BT_LE_HCI_INTERFACE_USE_RAM
|
||||
bool "ram"
|
||||
help
|
||||
Use RAM as HCI interface
|
||||
config BT_LE_HCI_INTERFACE_USE_UART
|
||||
bool "uart"
|
||||
help
|
||||
Use UART as HCI interface
|
||||
endchoice
|
||||
|
||||
config BT_LE_HCI_UART_PORT
|
||||
int "HCI UART port"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 1
|
||||
help
|
||||
Set the port number of HCI UART
|
||||
|
||||
config BT_LE_HCI_UART_FLOWCTRL
|
||||
bool "HCI uart Hardware Flow ctrl"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default n
|
||||
|
||||
config BT_LE_HCI_UART_TX_PIN
|
||||
int "HCI uart Tx gpio"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 19
|
||||
|
||||
config BT_LE_HCI_UART_RX_PIN
|
||||
int "HCI uart Rx gpio"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 10
|
||||
|
||||
config BT_LE_HCI_UART_RTS_PIN
|
||||
int "HCI uart RTS gpio"
|
||||
depends on BT_LE_HCI_UART_FLOWCTRL
|
||||
default 4
|
||||
|
||||
config BT_LE_HCI_UART_CTS_PIN
|
||||
int "HCI uart CTS gpio"
|
||||
depends on BT_LE_HCI_UART_FLOWCTRL
|
||||
default 5
|
||||
|
||||
config BT_LE_HCI_UART_BAUD
|
||||
int "HCI uart baudrate"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 921600
|
||||
help
|
||||
HCI uart baud rate 115200 ~ 1000000
|
||||
|
||||
choice BT_LE_HCI_UART_PARITY
|
||||
prompt "select uart parity"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default BT_LE_HCI_UART_UART_PARITY_DISABLE
|
||||
|
||||
config BT_LE_HCI_UART_UART_PARITY_DISABLE
|
||||
bool "PARITY_DISABLE"
|
||||
help
|
||||
UART_PARITY_DISABLE
|
||||
config BT_LE_HCI_UART_UART_PARITY_EVEN
|
||||
bool "PARITY_EVEN"
|
||||
help
|
||||
UART_PARITY_EVEN
|
||||
config BT_LE_HCI_UART_UART_PARITY_ODD
|
||||
bool "PARITY_ODD"
|
||||
help
|
||||
UART_PARITY_ODD
|
||||
endchoice
|
||||
|
||||
config BT_LE_HCI_UART_TASK_STACK_SIZE
|
||||
int "HCI uart task stack size"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 1000
|
||||
help
|
||||
Set the size of uart task stack
|
||||
endmenu
|
||||
|
||||
config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
|
||||
bool
|
||||
default y
|
||||
help
|
||||
Enable NPL porting for controller.
|
||||
|
||||
|
||||
menuconfig BT_LE_50_FEATURE_SUPPORT
|
||||
bool "Enable BLE 5 feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE 5 feature
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_2M_PHY
|
||||
bool "Enable 2M Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable 2M-PHY
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
bool "Enable coded Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable coded-PHY
|
||||
|
||||
config BT_LE_EXT_ADV
|
||||
bool "Enable extended advertising"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable this option to do extended advertising. Extended advertising
|
||||
will be supported from BLE 5.0 onwards.
|
||||
|
||||
if BT_LE_EXT_ADV
|
||||
config BT_LE_MAX_EXT_ADV_INSTANCES
|
||||
int "Maximum number of extended advertising instances."
|
||||
range 0 4
|
||||
default 1
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Change this option to set maximum number of extended advertising
|
||||
instances. Minimum there is always one instance of
|
||||
advertising. Enter how many more advertising instances you
|
||||
want.
|
||||
Each extended advertising instance will take about 0.5k DRAM.
|
||||
|
||||
config BT_LE_EXT_ADV_MAX_SIZE
|
||||
int "Maximum length of the advertising data."
|
||||
range 0 1650
|
||||
default 1650
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Defines the length of the extended adv data. The value should not
|
||||
exceed 1650.
|
||||
|
||||
config BT_LE_ENABLE_PERIODIC_ADV
|
||||
bool "Enable periodic advertisement."
|
||||
default y
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Enable this option to start periodic advertisement.
|
||||
|
||||
config BT_LE_PERIODIC_ADV_SYNC_TRANSFER
|
||||
bool "Enable Transer Sync Events"
|
||||
depends on BT_LE_ENABLE_PERIODIC_ADV
|
||||
default y
|
||||
help
|
||||
This enables controller transfer periodic sync events to host
|
||||
|
||||
endif
|
||||
|
||||
config BT_LE_MAX_PERIODIC_SYNCS
|
||||
int "Maximum number of periodic advertising syncs"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
|
||||
range 0 8
|
||||
default 1 if BT_LE_ENABLE_PERIODIC_ADV
|
||||
default 0
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic sync
|
||||
connections. This should be less than maximum connections allowed by
|
||||
controller.
|
||||
|
||||
config BT_LE_MAX_PERIODIC_ADVERTISER_LIST
|
||||
int "Maximum number of periodic advertiser list"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
range 1 5
|
||||
default 5
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic advertiser list.
|
||||
|
||||
config BT_LE_POWER_CONTROL_ENABLED
|
||||
bool "Enable controller support for BLE Power Control"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED && IDF_TARGET_ESP32C6
|
||||
default n
|
||||
help
|
||||
Set this option to enable the Power Control feature on controller
|
||||
|
||||
menu "Memory Settings"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_COUNT
|
||||
int "MSYS_1 Block Count"
|
||||
default 12
|
||||
help
|
||||
MSYS is a system level mbuf registry. For prepare write & prepare
|
||||
responses MBUFs are allocated out of msys_1 pool. For NIMBLE_MESH
|
||||
enabled cases, this block count is increased by 8 than user defined
|
||||
count.
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_SIZE
|
||||
int "MSYS_1 Block Size"
|
||||
default 256
|
||||
help
|
||||
Dynamic memory size of block 1
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_COUNT
|
||||
int "MSYS_2 Block Count"
|
||||
default 24
|
||||
help
|
||||
Dynamic memory count
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_SIZE
|
||||
int "MSYS_2 Block Size"
|
||||
default 320
|
||||
help
|
||||
Dynamic memory size of block 2
|
||||
|
||||
config BT_LE_MSYS_BUF_FROM_HEAP
|
||||
bool "Get Msys Mbuf from heap"
|
||||
default y
|
||||
depends on BT_LE_MSYS_INIT_IN_CONTROLLER
|
||||
help
|
||||
This option sets the source of the shared msys mbuf memory between
|
||||
the Host and the Controller. Allocate the memory from the heap if
|
||||
this option is sets, from the mempool otherwise.
|
||||
|
||||
config BT_LE_ACL_BUF_COUNT
|
||||
int "ACL Buffer count"
|
||||
default 10
|
||||
help
|
||||
The number of ACL data buffers.
|
||||
|
||||
config BT_LE_ACL_BUF_SIZE
|
||||
int "ACL Buffer size"
|
||||
default 517
|
||||
help
|
||||
This is the maximum size of the data portion of HCI ACL data packets.
|
||||
It does not include the HCI data header (of 4 bytes)
|
||||
|
||||
config BT_LE_HCI_EVT_BUF_SIZE
|
||||
int "HCI Event Buffer size"
|
||||
default 257 if BT_LE_EXT_ADV
|
||||
default 70
|
||||
help
|
||||
This is the size of each HCI event buffer in bytes. In case of
|
||||
extended advertising, packets can be fragmented. 257 bytes is the
|
||||
maximum size of a packet.
|
||||
|
||||
config BT_LE_HCI_EVT_HI_BUF_COUNT
|
||||
int "High Priority HCI Event Buffer count"
|
||||
default 30
|
||||
help
|
||||
This is the high priority HCI events' buffer size. High-priority
|
||||
event buffers are for everything except advertising reports. If there
|
||||
are no free high-priority event buffers then host will try to allocate a
|
||||
low-priority buffer instead
|
||||
|
||||
config BT_LE_HCI_EVT_LO_BUF_COUNT
|
||||
int "Low Priority HCI Event Buffer count"
|
||||
default 8
|
||||
help
|
||||
This is the low priority HCI events' buffer size. Low-priority event
|
||||
buffers are only used for advertising reports. If there are no free
|
||||
low-priority event buffers, then an incoming advertising report will
|
||||
get dropped
|
||||
endmenu
|
||||
|
||||
config BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
int "Controller task stack size"
|
||||
default 5120 if BLE_MESH
|
||||
default 4096
|
||||
help
|
||||
This configures stack size of NimBLE controller task
|
||||
|
||||
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
|
||||
bool "Controller log enable"
|
||||
default n
|
||||
help
|
||||
Enable controller log
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
|
||||
bool "enable controller log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable controller log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
|
||||
bool "enable HCI log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable hci log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
|
||||
bool "Controller log dump mode only"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Only operate in dump mode
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF1_SIZE
|
||||
int "size of the first BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the first BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF2_SIZE
|
||||
int "size of the second BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 1024
|
||||
help
|
||||
Configure the size of the second BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_HCI_BUF_SIZE
|
||||
int "size of the BLE HCI LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the BLE HCI LOG buffer.
|
||||
|
||||
config BT_LE_LL_RESOLV_LIST_SIZE
|
||||
int "BLE LL Resolving list size"
|
||||
range 1 5
|
||||
default 4
|
||||
help
|
||||
Configure the size of resolving list used in link layer.
|
||||
|
||||
menuconfig BT_LE_SECURITY_ENABLE
|
||||
bool "Enable BLE SM feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE sm feature
|
||||
|
||||
config BT_LE_SM_LEGACY
|
||||
bool "Security manager legacy pairing"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager legacy pairing
|
||||
|
||||
config BT_LE_SM_SC
|
||||
bool "Security manager secure connections (4.2)"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager secure connections
|
||||
|
||||
config BT_LE_SM_SC_DEBUG_KEYS
|
||||
bool "Use predefined public-private key pair"
|
||||
default n
|
||||
depends on BT_LE_SECURITY_ENABLE && BT_LE_SM_SC
|
||||
help
|
||||
If this option is enabled, SM uses predefined DH key pair as described
|
||||
in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to
|
||||
decrypt air traffic easily and thus should only be used for debugging.
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_ENCRYPTION
|
||||
bool "Enable LE encryption"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable encryption connection
|
||||
|
||||
config BT_LE_CRYPTO_STACK_MBEDTLS
|
||||
bool "Override TinyCrypt with mbedTLS for crypto computations"
|
||||
default y
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
select MBEDTLS_ECP_RESTARTABLE
|
||||
select MBEDTLS_CMAC_C
|
||||
help
|
||||
Enable this option to choose mbedTLS instead of TinyCrypt for crypto
|
||||
computations.
|
||||
|
||||
config BT_LE_WHITELIST_SIZE
|
||||
int "BLE white list size"
|
||||
range 1 15
|
||||
default 12
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
help
|
||||
BLE list size
|
||||
|
||||
config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
int "BLE duplicate scan list count"
|
||||
range 5 100
|
||||
default 20
|
||||
help
|
||||
config the max count of duplicate scan list
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
|
||||
config BT_LE_MAX_CONNECTIONS
|
||||
int "Maximum number of concurrent connections"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
range 1 70
|
||||
default 3
|
||||
help
|
||||
Defines maximum number of concurrent BLE connections. For ESP32, user
|
||||
is expected to configure BTDM_CTRL_BLE_MAX_CONN from controller menu
|
||||
along with this option. Similarly for ESP32-C3 or ESP32-S3, user is expected to
|
||||
configure BT_CTRL_BLE_MAX_ACT from controller menu.
|
||||
Each connection will take about 1k DRAM.
|
||||
|
||||
choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM
|
||||
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection"
|
||||
default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
depends on ESP_COEX_SW_COEXIST_ENABLE
|
||||
help
|
||||
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to
|
||||
better avoid dramatic performance deterioration of Wi-Fi.
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
bool "Force Enable"
|
||||
help
|
||||
Always enable the limitation on max tx/rx time for Coded-PHY connection
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
bool "Force Disable"
|
||||
help
|
||||
Disable the limitation on max tx/rx time for Coded-PHY connection
|
||||
endchoice
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
int
|
||||
default 0 if !ESP_COEX_SW_COEXIST_ENABLE
|
||||
default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
|
||||
config BT_LE_SLEEP_ENABLE
|
||||
bool "Enable BLE sleep"
|
||||
default n
|
||||
help
|
||||
Enable BLE sleep
|
||||
|
||||
choice BT_LE_LP_CLK_SRC
|
||||
prompt "BLE low power clock source"
|
||||
default BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
config BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
bool "Use main XTAL as RTC clock source"
|
||||
help
|
||||
User main XTAL as RTC clock source.
|
||||
This option is recommended if external 32.768k XTAL is not available.
|
||||
Using the external 32.768 kHz XTAL will have lower current consumption
|
||||
in light sleep compared to using the main XTAL.
|
||||
|
||||
config BT_LE_LP_CLK_SRC_DEFAULT
|
||||
bool "Use system RTC slow clock source"
|
||||
help
|
||||
Use the same slow clock source as system RTC
|
||||
Using any clock source other than external 32.768 kHz XTAL supports only
|
||||
legacy ADV and SCAN due to low clock accuracy.
|
||||
|
||||
endchoice
|
||||
|
||||
config BT_LE_USE_ESP_TIMER
|
||||
bool "Enable Esp Timer for Callout"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Set this option to use Esp Timer which has higher priority timer
|
||||
instead of FreeRTOS timer
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
bool "BLE adv report flow control supported"
|
||||
default y
|
||||
help
|
||||
The function is mainly used to enable flow control for advertising reports. When it is enabled,
|
||||
advertising reports will be discarded by the controller if the number of unprocessed advertising
|
||||
reports exceeds the size of BLE adv report flow control.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM
|
||||
int "BLE adv report flow control number"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 50 1000
|
||||
default 100
|
||||
help
|
||||
The number of unprocessed advertising report that bluetooth host can save.If you set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a
|
||||
lot of adv packets and this may cause system memory run out. For example, if you set
|
||||
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv
|
||||
packets as fast as possible, otherwise it will cause adv packets lost.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
int "BLE adv lost event threshold value"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 1 1000
|
||||
default 20
|
||||
help
|
||||
When adv report flow control is enabled, The ADV lost event will be generated when the number
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
config BT_LE_SCAN_DUPL
|
||||
bool "BLE Scan Duplicate Options"
|
||||
default y
|
||||
help
|
||||
This select enables parameters setting of BLE scan duplicate.
|
||||
|
||||
choice BT_LE_SCAN_DUPL_TYPE
|
||||
prompt "Scan Duplicate Type"
|
||||
default BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
help
|
||||
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use
|
||||
advertiser address filtering. The adv packet of the same address is only allowed to be reported once.
|
||||
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising
|
||||
data and device address filtering. All different adv packets with the same address are allowed to be
|
||||
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data
|
||||
filtering. All same advertising data only allow to be reported once even though they are from
|
||||
different devices.
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
bool "Scan Duplicate By Device Address"
|
||||
help
|
||||
This way is to use advertiser address filtering. The adv packet of the same address is only
|
||||
allowed to be reported once
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DATA
|
||||
bool "Scan Duplicate By Advertising Data"
|
||||
help
|
||||
This way is to use advertising data filtering. All same advertising data only allow to be reported
|
||||
once even though they are from different devices.
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
bool "Scan Duplicate By Device Address And Advertising Data"
|
||||
help
|
||||
This way is to use advertising data and device address filtering. All different adv packets with
|
||||
the same address are allowed to be reported.
|
||||
endchoice
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE
|
||||
int
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
default 0 if BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
default 1 if BT_LE_SCAN_DUPL_TYPE_DATA
|
||||
default 2 if BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
default 0
|
||||
|
||||
config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD
|
||||
int "Duplicate scan list refresh period (seconds)"
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
range 0 1000
|
||||
default 0
|
||||
help
|
||||
If the period value is non-zero, the controller will periodically clear the device information
|
||||
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared
|
||||
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the
|
||||
Host in advertising report events.
|
||||
There are two scenarios where the ADV packet will be repeatedly reported:
|
||||
1. The duplicate scan cache is full, the controller will delete the oldest device information and
|
||||
add new device information.
|
||||
2. When the refresh period is up, the controller will clear all device information and start filtering
|
||||
again.
|
||||
|
||||
config BT_LE_MSYS_INIT_IN_CONTROLLER
|
||||
bool "Msys Mbuf Init in Controller"
|
||||
default y
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_BT_CFG_H__
|
||||
#define __ESP_BT_CFG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "syscfg/syscfg.h"
|
||||
#endif
|
||||
|
||||
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (2)
|
||||
#else
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (1)
|
||||
#endif
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS)
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES)
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL)
|
||||
#if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT)
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
|
||||
#endif
|
||||
#else
|
||||
|
||||
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (2)
|
||||
#else
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_CONNECTIONS)
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS (CONFIG_BT_LE_MAX_CONNECTIONS)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS (2)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_ACL_BUF_SIZE)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE (CONFIG_BT_LE_ACL_BUF_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE (255)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_ACL_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT (CONFIG_BT_LE_ACL_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT (24)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_BUF_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (CONFIG_BT_LE_HCI_EVT_BUF_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (70)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_EXT_ADV_MAX_SIZE)
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (CONFIG_BT_LE_EXT_ADV_MAX_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (31)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES)
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_WHITELIST_SIZE)
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (CONFIG_BT_LE_WHITELIST_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (12)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (30)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_POWER_CONTROL_ENABLED)
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (CONFIG_BT_LE_POWER_CONTROL_ENABLED)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0)
|
||||
#endif
|
||||
#if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT)
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#else
|
||||
#define HCI_UART_EN 0 // hci ram mode
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#else
|
||||
#define NIMBLE_SLEEP_ENABLE 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_BT_LE_TX_CCA_ENABLED
|
||||
#define DEFAULT_BT_LE_TX_CCA_ENABLED (CONFIG_BT_LE_TX_CCA_ENABLED)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_TX_CCA_ENABLED (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LE_CCA_RSSI_THRESH
|
||||
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (CONFIG_BT_LE_CCA_RSSI_THRESH)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (50)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N DEFAULT_BT_LE_EXT_ADV_MAX_SIZE
|
||||
|
||||
|
||||
#if HCI_UART_EN
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (CONFIG_BT_LE_HCI_UART_TX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (CONFIG_BT_LE_HCI_UART_RX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (CONFIG_BT_LE_HCI_UART_PORT)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (CONFIG_BT_LE_HCI_UART_BAUD)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0)
|
||||
#endif
|
||||
|
||||
/* Unchanged configuration */
|
||||
|
||||
#define BLE_LL_CTRL_PROC_TIMEOUT_MS_N (40000) /* ms */
|
||||
|
||||
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS_N (1)
|
||||
|
||||
#define BLE_LL_SCHED_ADV_MAX_USECS_N (852)
|
||||
|
||||
#define BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N (502)
|
||||
|
||||
#define BLE_LL_SCHED_MAX_ADV_PDU_USECS_N (376)
|
||||
|
||||
#define BLE_LL_SUB_VERS_NR_N (0x0000)
|
||||
|
||||
#define BLE_LL_JITTER_USECS_N (16)
|
||||
|
||||
#define BLE_PHY_MAX_PWR_DBM_N (10)
|
||||
|
||||
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000)
|
||||
|
||||
#define RTC_FREQ_N (32768) /* in Hz */
|
||||
|
||||
#define BLE_LL_TX_PWR_DBM_N (9)
|
||||
|
||||
|
||||
#define RUN_BQB_TEST (0)
|
||||
#define RUN_QA_TEST (0)
|
||||
#define NIMBLE_DISABLE_SCAN_BACKOFF (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_CFG_H__ */
|
||||
@@ -0,0 +1,556 @@
|
||||
|
||||
menu "HCI Config"
|
||||
|
||||
choice BT_LE_HCI_INTERFACE
|
||||
prompt "Select HCI interface"
|
||||
default BT_LE_HCI_INTERFACE_USE_RAM
|
||||
|
||||
config BT_LE_HCI_INTERFACE_USE_RAM
|
||||
bool "ram"
|
||||
help
|
||||
Use RAM as HCI interface
|
||||
config BT_LE_HCI_INTERFACE_USE_UART
|
||||
bool "uart"
|
||||
help
|
||||
Use UART as HCI interface
|
||||
endchoice
|
||||
|
||||
config BT_LE_HCI_UART_PORT
|
||||
int "HCI UART port"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 1
|
||||
help
|
||||
Set the port number of HCI UART
|
||||
|
||||
config BT_LE_HCI_UART_FLOWCTRL
|
||||
bool "HCI uart Hardware Flow ctrl"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default n
|
||||
|
||||
config BT_LE_HCI_UART_TX_PIN
|
||||
int "HCI uart Tx gpio"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 19
|
||||
|
||||
config BT_LE_HCI_UART_RX_PIN
|
||||
int "HCI uart Rx gpio"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 10
|
||||
|
||||
config BT_LE_HCI_UART_RTS_PIN
|
||||
int "HCI uart RTS gpio"
|
||||
depends on BT_LE_HCI_UART_FLOWCTRL
|
||||
default 4
|
||||
|
||||
config BT_LE_HCI_UART_CTS_PIN
|
||||
int "HCI uart CTS gpio"
|
||||
depends on BT_LE_HCI_UART_FLOWCTRL
|
||||
default 5
|
||||
|
||||
config BT_LE_HCI_UART_BAUD
|
||||
int "HCI uart baudrate"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 921600
|
||||
help
|
||||
HCI uart baud rate 115200 ~ 1000000
|
||||
|
||||
choice BT_LE_HCI_UART_PARITY
|
||||
prompt "select uart parity"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default BT_LE_HCI_UART_UART_PARITY_DISABLE
|
||||
|
||||
config BT_LE_HCI_UART_UART_PARITY_DISABLE
|
||||
bool "PARITY_DISABLE"
|
||||
help
|
||||
UART_PARITY_DISABLE
|
||||
config BT_LE_HCI_UART_UART_PARITY_EVEN
|
||||
bool "PARITY_EVEN"
|
||||
help
|
||||
UART_PARITY_EVEN
|
||||
config BT_LE_HCI_UART_UART_PARITY_ODD
|
||||
bool "PARITY_ODD"
|
||||
help
|
||||
UART_PARITY_ODD
|
||||
endchoice
|
||||
|
||||
config BT_LE_HCI_UART_TASK_STACK_SIZE
|
||||
int "HCI uart task stack size"
|
||||
depends on BT_LE_HCI_INTERFACE_USE_UART
|
||||
default 1000
|
||||
help
|
||||
Set the size of uart task stack
|
||||
endmenu
|
||||
|
||||
config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
|
||||
bool
|
||||
default y
|
||||
help
|
||||
Enable NPL porting for controller.
|
||||
|
||||
|
||||
menuconfig BT_LE_50_FEATURE_SUPPORT
|
||||
bool "Enable BLE 5 feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE 5 feature
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_2M_PHY
|
||||
bool "Enable 2M Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable 2M-PHY
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
bool "Enable coded Phy"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable coded-PHY
|
||||
|
||||
config BT_LE_EXT_ADV
|
||||
bool "Enable extended advertising"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable this option to do extended advertising. Extended advertising
|
||||
will be supported from BLE 5.0 onwards.
|
||||
|
||||
if BT_LE_EXT_ADV
|
||||
config BT_LE_MAX_EXT_ADV_INSTANCES
|
||||
int "Maximum number of extended advertising instances."
|
||||
range 0 4
|
||||
default 1
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Change this option to set maximum number of extended advertising
|
||||
instances. Minimum there is always one instance of
|
||||
advertising. Enter how many more advertising instances you
|
||||
want.
|
||||
Each extended advertising instance will take about 0.5k DRAM.
|
||||
|
||||
config BT_LE_EXT_ADV_MAX_SIZE
|
||||
int "Maximum length of the advertising data."
|
||||
range 0 1650
|
||||
default 1650
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Defines the length of the extended adv data. The value should not
|
||||
exceed 1650.
|
||||
|
||||
config BT_LE_ENABLE_PERIODIC_ADV
|
||||
bool "Enable periodic advertisement."
|
||||
default y
|
||||
depends on BT_LE_EXT_ADV
|
||||
help
|
||||
Enable this option to start periodic advertisement.
|
||||
|
||||
config BT_LE_PERIODIC_ADV_SYNC_TRANSFER
|
||||
bool "Enable Transer Sync Events"
|
||||
depends on BT_LE_ENABLE_PERIODIC_ADV
|
||||
default y
|
||||
help
|
||||
This enables controller transfer periodic sync events to host
|
||||
|
||||
endif
|
||||
|
||||
config BT_LE_MAX_PERIODIC_SYNCS
|
||||
int "Maximum number of periodic advertising syncs"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
|
||||
range 0 8
|
||||
default 1 if BT_LE_ENABLE_PERIODIC_ADV
|
||||
default 0
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic sync
|
||||
connections. This should be less than maximum connections allowed by
|
||||
controller.
|
||||
|
||||
config BT_LE_MAX_PERIODIC_ADVERTISER_LIST
|
||||
int "Maximum number of periodic advertiser list"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
range 1 5
|
||||
default 5
|
||||
help
|
||||
Set this option to set the upper limit for number of periodic advertiser list.
|
||||
|
||||
config BT_LE_POWER_CONTROL_ENABLED
|
||||
bool "Enable controller support for BLE Power Control"
|
||||
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
|
||||
default n
|
||||
help
|
||||
Set this option to enable the Power Control feature on controller
|
||||
|
||||
menu "Memory Settings"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_COUNT
|
||||
int "MSYS_1 Block Count"
|
||||
default 12
|
||||
help
|
||||
MSYS is a system level mbuf registry. For prepare write & prepare
|
||||
responses MBUFs are allocated out of msys_1 pool. For NIMBLE_MESH
|
||||
enabled cases, this block count is increased by 8 than user defined
|
||||
count.
|
||||
|
||||
config BT_LE_MSYS_1_BLOCK_SIZE
|
||||
int "MSYS_1 Block Size"
|
||||
default 256
|
||||
help
|
||||
Dynamic memory size of block 1
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_COUNT
|
||||
int "MSYS_2 Block Count"
|
||||
default 24
|
||||
help
|
||||
Dynamic memory count
|
||||
|
||||
config BT_LE_MSYS_2_BLOCK_SIZE
|
||||
int "MSYS_2 Block Size"
|
||||
default 320
|
||||
help
|
||||
Dynamic memory size of block 2
|
||||
|
||||
config BT_LE_ACL_BUF_COUNT
|
||||
int "ACL Buffer count"
|
||||
default 10
|
||||
help
|
||||
The number of ACL data buffers.
|
||||
|
||||
config BT_LE_ACL_BUF_SIZE
|
||||
int "ACL Buffer size"
|
||||
default 517
|
||||
help
|
||||
This is the maximum size of the data portion of HCI ACL data packets.
|
||||
It does not include the HCI data header (of 4 bytes)
|
||||
|
||||
config BT_LE_HCI_EVT_BUF_SIZE
|
||||
int "HCI Event Buffer size"
|
||||
default 257 if BT_LE_EXT_ADV
|
||||
default 70
|
||||
help
|
||||
This is the size of each HCI event buffer in bytes. In case of
|
||||
extended advertising, packets can be fragmented. 257 bytes is the
|
||||
maximum size of a packet.
|
||||
|
||||
config BT_LE_HCI_EVT_HI_BUF_COUNT
|
||||
int "High Priority HCI Event Buffer count"
|
||||
default 30
|
||||
help
|
||||
This is the high priority HCI events' buffer size. High-priority
|
||||
event buffers are for everything except advertising reports. If there
|
||||
are no free high-priority event buffers then host will try to allocate a
|
||||
low-priority buffer instead
|
||||
|
||||
config BT_LE_HCI_EVT_LO_BUF_COUNT
|
||||
int "Low Priority HCI Event Buffer count"
|
||||
default 8
|
||||
help
|
||||
This is the low priority HCI events' buffer size. Low-priority event
|
||||
buffers are only used for advertising reports. If there are no free
|
||||
low-priority event buffers, then an incoming advertising report will
|
||||
get dropped
|
||||
endmenu
|
||||
|
||||
config BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
int "Controller task stack size"
|
||||
default 5120 if BLE_MESH
|
||||
default 4096
|
||||
help
|
||||
This configures stack size of NimBLE controller task
|
||||
|
||||
menuconfig BT_LE_CONTROLLER_LOG_ENABLED
|
||||
bool "Controller log enable"
|
||||
default n
|
||||
help
|
||||
Enable controller log
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED
|
||||
bool "enable controller log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable controller log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_HCI_ENABLED
|
||||
bool "enable HCI log module"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable hci log module
|
||||
|
||||
config BT_LE_CONTROLLER_LOG_DUMP_ONLY
|
||||
bool "Controller log dump mode only"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default y
|
||||
help
|
||||
Only operate in dump mode
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF1_SIZE
|
||||
int "size of the first BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the first BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_CTRL_BUF2_SIZE
|
||||
int "size of the second BLE controller LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 1024
|
||||
help
|
||||
Configure the size of the second BLE controller LOG buffer.
|
||||
|
||||
config BT_LE_LOG_HCI_BUF_SIZE
|
||||
int "size of the BLE HCI LOG buffer"
|
||||
depends on BT_LE_CONTROLLER_LOG_ENABLED
|
||||
default 4096
|
||||
help
|
||||
Configure the size of the BLE HCI LOG buffer.
|
||||
|
||||
config BT_LE_LL_RESOLV_LIST_SIZE
|
||||
int "BLE LL Resolving list size"
|
||||
range 1 5
|
||||
default 4
|
||||
help
|
||||
Configure the size of resolving list used in link layer.
|
||||
|
||||
menuconfig BT_LE_SECURITY_ENABLE
|
||||
bool "Enable BLE SM feature"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Enable BLE sm feature
|
||||
|
||||
config BT_LE_SM_LEGACY
|
||||
bool "Security manager legacy pairing"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager legacy pairing
|
||||
|
||||
config BT_LE_SM_SC
|
||||
bool "Security manager secure connections (4.2)"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable security manager secure connections
|
||||
|
||||
config BT_LE_SM_SC_DEBUG_KEYS
|
||||
bool "Use predefined public-private key pair"
|
||||
default n
|
||||
depends on BT_LE_SECURITY_ENABLE && BT_LE_SM_SC
|
||||
help
|
||||
If this option is enabled, SM uses predefined DH key pair as described
|
||||
in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to
|
||||
decrypt air traffic easily and thus should only be used for debugging.
|
||||
|
||||
config BT_LE_LL_CFG_FEAT_LE_ENCRYPTION
|
||||
bool "Enable LE encryption"
|
||||
depends on BT_LE_SECURITY_ENABLE
|
||||
default y
|
||||
help
|
||||
Enable encryption connection
|
||||
|
||||
config BT_LE_CRYPTO_STACK_MBEDTLS
|
||||
bool "Override TinyCrypt with mbedTLS for crypto computations"
|
||||
default y
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
select MBEDTLS_ECP_RESTARTABLE
|
||||
select MBEDTLS_CMAC_C
|
||||
help
|
||||
Enable this option to choose mbedTLS instead of TinyCrypt for crypto
|
||||
computations.
|
||||
|
||||
config BT_LE_WHITELIST_SIZE
|
||||
int "BLE white list size"
|
||||
range 1 15
|
||||
default 12
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
||||
help
|
||||
BLE list size
|
||||
|
||||
config BT_LE_LL_DUP_SCAN_LIST_COUNT
|
||||
int "BLE duplicate scan list count"
|
||||
range 5 100
|
||||
default 20
|
||||
help
|
||||
config the max count of duplicate scan list
|
||||
|
||||
config BT_LE_LL_SCA
|
||||
int "BLE Sleep clock accuracy"
|
||||
range 0 500
|
||||
default 60
|
||||
help
|
||||
Sleep clock accuracy of our device (in ppm)
|
||||
|
||||
config BT_LE_MAX_CONNECTIONS
|
||||
int "Maximum number of concurrent connections"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
range 1 35
|
||||
default 3
|
||||
help
|
||||
Defines maximum number of concurrent BLE connections. For ESP32, user
|
||||
is expected to configure BTDM_CTRL_BLE_MAX_CONN from controller menu
|
||||
along with this option. Similarly for ESP32-C3 or ESP32-S3, user is expected to
|
||||
configure BT_CTRL_BLE_MAX_ACT from controller menu.
|
||||
Each connection will take about 1k DRAM.
|
||||
|
||||
choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM
|
||||
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection"
|
||||
default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
depends on ESP_COEX_SW_COEXIST_ENABLE
|
||||
help
|
||||
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to
|
||||
better avoid dramatic performance deterioration of Wi-Fi.
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
bool "Force Enable"
|
||||
help
|
||||
Always enable the limitation on max tx/rx time for Coded-PHY connection
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
bool "Force Disable"
|
||||
help
|
||||
Disable the limitation on max tx/rx time for Coded-PHY connection
|
||||
endchoice
|
||||
|
||||
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
int
|
||||
default 0 if !ESP_COEX_SW_COEXIST_ENABLE
|
||||
default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN
|
||||
default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS
|
||||
|
||||
config BT_LE_SLEEP_ENABLE
|
||||
bool "Enable BLE sleep"
|
||||
default n
|
||||
help
|
||||
Enable BLE sleep
|
||||
|
||||
choice BT_LE_LP_CLK_SRC
|
||||
prompt "BLE low power clock source"
|
||||
default BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
config BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
bool "Use main XTAL as RTC clock source"
|
||||
help
|
||||
User main XTAL as RTC clock source.
|
||||
This option is recommended if external 32.768k XTAL is not available.
|
||||
Using the external 32.768 kHz XTAL will have lower current consumption
|
||||
in light sleep compared to using the main XTAL.
|
||||
|
||||
config BT_LE_LP_CLK_SRC_DEFAULT
|
||||
bool "Use system RTC slow clock source"
|
||||
help
|
||||
Use the same slow clock source as system RTC
|
||||
Using any clock source other than external 32.768 kHz XTAL supports only
|
||||
legacy ADV and SCAN due to low clock accuracy.
|
||||
|
||||
endchoice
|
||||
|
||||
config BT_LE_USE_ESP_TIMER
|
||||
bool "Enable Esp Timer for Callout"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
default y
|
||||
help
|
||||
Set this option to use Esp Timer which has higher priority timer
|
||||
instead of FreeRTOS timer
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
bool "BLE adv report flow control supported"
|
||||
default y
|
||||
help
|
||||
The function is mainly used to enable flow control for advertising reports. When it is enabled,
|
||||
advertising reports will be discarded by the controller if the number of unprocessed advertising
|
||||
reports exceeds the size of BLE adv report flow control.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM
|
||||
int "BLE adv report flow control number"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 50 1000
|
||||
default 100
|
||||
help
|
||||
The number of unprocessed advertising report that bluetooth host can save.If you set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a
|
||||
lot of adv packets and this may cause system memory run out. For example, if you set
|
||||
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set
|
||||
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv
|
||||
packets as fast as possible, otherwise it will cause adv packets lost.
|
||||
|
||||
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
int "BLE adv lost event threshold value"
|
||||
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
range 1 1000
|
||||
default 20
|
||||
help
|
||||
When adv report flow control is enabled, The ADV lost event will be generated when the number
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
config BT_LE_SCAN_DUPL
|
||||
bool "BLE Scan Duplicate Options"
|
||||
default y
|
||||
help
|
||||
This select enables parameters setting of BLE scan duplicate.
|
||||
|
||||
choice BT_LE_SCAN_DUPL_TYPE
|
||||
prompt "Scan Duplicate Type"
|
||||
default BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
help
|
||||
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use
|
||||
advertiser address filtering. The adv packet of the same address is only allowed to be reported once.
|
||||
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising
|
||||
data and device address filtering. All different adv packets with the same address are allowed to be
|
||||
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data
|
||||
filtering. All same advertising data only allow to be reported once even though they are from
|
||||
different devices.
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
bool "Scan Duplicate By Device Address"
|
||||
help
|
||||
This way is to use advertiser address filtering. The adv packet of the same address is only
|
||||
allowed to be reported once
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DATA
|
||||
bool "Scan Duplicate By Advertising Data"
|
||||
help
|
||||
This way is to use advertising data filtering. All same advertising data only allow to be reported
|
||||
once even though they are from different devices.
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
bool "Scan Duplicate By Device Address And Advertising Data"
|
||||
help
|
||||
This way is to use advertising data and device address filtering. All different adv packets with
|
||||
the same address are allowed to be reported.
|
||||
endchoice
|
||||
|
||||
config BT_LE_SCAN_DUPL_TYPE
|
||||
int
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
default 0 if BT_LE_SCAN_DUPL_TYPE_DEVICE
|
||||
default 1 if BT_LE_SCAN_DUPL_TYPE_DATA
|
||||
default 2 if BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
default 0
|
||||
|
||||
config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD
|
||||
int "Duplicate scan list refresh period (seconds)"
|
||||
depends on BT_LE_SCAN_DUPL
|
||||
range 0 1000
|
||||
default 0
|
||||
help
|
||||
If the period value is non-zero, the controller will periodically clear the device information
|
||||
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared
|
||||
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the
|
||||
Host in advertising report events.
|
||||
There are two scenarios where the ADV packet will be repeatedly reported:
|
||||
1. The duplicate scan cache is full, the controller will delete the oldest device information and
|
||||
add new device information.
|
||||
2. When the refresh period is up, the controller will clear all device information and start filtering
|
||||
again.
|
||||
|
||||
config BT_LE_MSYS_INIT_IN_CONTROLLER
|
||||
bool
|
||||
default y
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_BT_CFG_H__
|
||||
#define __ESP_BT_CFG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "syscfg/syscfg.h"
|
||||
#endif
|
||||
|
||||
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
#if CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (2)
|
||||
#else
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (1)
|
||||
#endif
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS)
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES)
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL)
|
||||
#if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT)
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
|
||||
#endif
|
||||
#else
|
||||
|
||||
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (2)
|
||||
#else
|
||||
#define BLE_LL_SCAN_PHY_NUMBER_N (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_CONNECTIONS)
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS (CONFIG_BT_LE_MAX_CONNECTIONS)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_CONNECTIONS (2)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_ACL_BUF_SIZE)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE (CONFIG_BT_LE_ACL_BUF_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ACL_BUF_SIZE (255)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_ACL_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT (CONFIG_BT_LE_ACL_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_ACL_BUF_COUNT (24)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_BUF_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (CONFIG_BT_LE_HCI_EVT_BUF_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (70)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_EXT_ADV_MAX_SIZE)
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (CONFIG_BT_LE_EXT_ADV_MAX_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (31)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES)
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_WHITELIST_SIZE)
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (CONFIG_BT_LE_WHITELIST_SIZE)
|
||||
#else
|
||||
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (12)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (30)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT)
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_POWER_CONTROL_ENABLED)
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (CONFIG_BT_LE_POWER_CONTROL_ENABLED)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT)
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF
|
||||
|
||||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART
|
||||
#else
|
||||
#define HCI_UART_EN 0 // hci ram mode
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE
|
||||
#else
|
||||
#define NIMBLE_SLEEP_ENABLE 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_BT_LE_TX_CCA_ENABLED
|
||||
#define DEFAULT_BT_LE_TX_CCA_ENABLED (CONFIG_BT_LE_TX_CCA_ENABLED)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_TX_CCA_ENABLED (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LE_CCA_RSSI_THRESH
|
||||
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (CONFIG_BT_LE_CCA_RSSI_THRESH)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (50)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N DEFAULT_BT_LE_EXT_ADV_MAX_SIZE
|
||||
|
||||
|
||||
#if HCI_UART_EN
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (CONFIG_BT_LE_HCI_UART_TX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (CONFIG_BT_LE_HCI_UART_RX_PIN)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (CONFIG_BT_LE_HCI_UART_PORT)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (CONFIG_BT_LE_HCI_UART_BAUD)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE)
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0)
|
||||
#else
|
||||
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PORT (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_BAUD (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_PARITY (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0)
|
||||
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0)
|
||||
#endif
|
||||
|
||||
/* Unchanged configuration */
|
||||
|
||||
#define BLE_LL_CTRL_PROC_TIMEOUT_MS_N (40000) /* ms */
|
||||
|
||||
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS_N (1)
|
||||
|
||||
#define BLE_LL_SCHED_ADV_MAX_USECS_N (852)
|
||||
|
||||
#define BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N (502)
|
||||
|
||||
#define BLE_LL_SCHED_MAX_ADV_PDU_USECS_N (376)
|
||||
|
||||
#define BLE_LL_SUB_VERS_NR_N (0x0000)
|
||||
|
||||
#define BLE_LL_JITTER_USECS_N (16)
|
||||
|
||||
#define BLE_PHY_MAX_PWR_DBM_N (10)
|
||||
|
||||
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000)
|
||||
|
||||
#define RTC_FREQ_N (32768) /* in Hz */
|
||||
|
||||
#define BLE_LL_TX_PWR_DBM_N (9)
|
||||
|
||||
|
||||
#define RUN_BQB_TEST (0)
|
||||
#define RUN_QA_TEST (0)
|
||||
#define NIMBLE_DISABLE_SCAN_BACKOFF (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_CFG_H__ */
|
||||
@@ -0,0 +1 @@
|
||||
source "$IDF_PATH/components/bt/controller/esp32c3/Kconfig.in"
|
||||
@@ -0,0 +1,30 @@
|
||||
stages:
|
||||
- deploy
|
||||
|
||||
push_master_to_github:
|
||||
stage: deploy
|
||||
tags:
|
||||
- internet
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+/
|
||||
# when: on_success
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
variables:
|
||||
GIT_DEPTH: 0
|
||||
script:
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $GH_PUSH_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
- git remote add github git@github.com:espressif/esp32-bt-lib.git
|
||||
# Ref: esp-idf tools/ci/push_to_github.sh
|
||||
- |
|
||||
if [ -n "${CI_COMMIT_TAG}" ]; then
|
||||
git push github "${CI_COMMIT_TAG}"
|
||||
else
|
||||
git push github "${CI_COMMIT_SHA}:refs/heads/${CI_COMMIT_REF_NAME}"
|
||||
fi
|
||||
Executable
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
ESP32 BT/BLE Stack Libraries
|
||||
====================
|
||||
|
||||
This repository contains binary libraries supporting the ESP32 RF subsystems. It is used as a submodule within `Espressif IoT Development Framework`_ (ESP-IDF).
|
||||
|
||||
Files in this repository are Copyright (C) 2015-2016 Espressif Systems.
|
||||
|
||||
These binary libraries are provided under the same license as the parent esp-idf project - the Apache License 2.0 as provided in the file LICENSE. (The license text refers to this as "Object" form.)
|
||||
|
||||
.. _Espressif IoT Development Framework: https://github.com/espressif/esp-idf
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
Apache Mynewt NimBLE
|
||||
Copyright 2015-2021 The Apache Software Foundation
|
||||
Modifications Copyright 2017-2022 Espressif Systems (Shanghai) CO., LTD.
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
Portions of this software were developed at
|
||||
Runtime Inc, copyright 2015.
|
||||
@@ -0,0 +1 @@
|
||||
This software includes portions of code derived from mynewt-nimble project. See [NOTICE](NOTICE) file for details.
|
||||
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
stages:
|
||||
- deploy
|
||||
|
||||
push_master_to_github:
|
||||
stage: deploy
|
||||
tags:
|
||||
- internet
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
# when: on_success
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
variables:
|
||||
GIT_STRATEGY: clone
|
||||
GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master
|
||||
script:
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $GH_PUSH_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
- git remote add github git@github.com:espressif/esp32c3-bt-lib.git
|
||||
# What the next line of script does: goes through the list of refs for all branches we push to github,
|
||||
# generates a snippet of shell which is evaluated. The snippet checks CI_BUILD_REF against the SHA
|
||||
# (aka objectname) at tip of each branch, and if any SHAs match then it checks out the local branch
|
||||
# and then pushes that ref to a corresponding github branch
|
||||
#
|
||||
# NB: In gitlab 9.x, CI_BUILD_REF was deprecated. New name is CI_COMMIT_REF. If below command suddenly
|
||||
# generates bash syntax errors, this is probably why.
|
||||
- eval $(git for-each-ref --shell bash --format 'if [ $CI_BUILD_REF == %(objectname) ]; then git checkout -B %(refname:strip=3); git push --follow-tags github %(refname:strip=3); fi;' $GITHUB_PUSH_REFS)
|
||||
Executable
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,10 @@
|
||||
ESP32-C3 and ESP32-S3 BLE Stack Libraries
|
||||
=========================================
|
||||
|
||||
This repository contains binary libraries supporting the ESP32C3 and ESP32S3 RF subsystems. It is used as a submodule within `Espressif IoT Development Framework`_ (ESP-IDF).
|
||||
|
||||
Files in this repository are Copyright (C) 2021 Espressif Systems.
|
||||
|
||||
These binary libraries are provided under the same license as the parent esp-idf project - the Apache License 2.0 as provided in the file LICENSE. (The license text refers to this as "Object" form.)
|
||||
|
||||
.. _Espressif IoT Development Framework: https://github.com/espressif/esp-idf
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
Apache Mynewt NimBLE
|
||||
Copyright 2015-2021 The Apache Software Foundation
|
||||
Modifications Copyright 2017-2023 Espressif Systems (Shanghai) CO., LTD.
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
Portions of this software were developed at
|
||||
Runtime Inc, copyright 2015.
|
||||
@@ -0,0 +1 @@
|
||||
This software includes portions of code derived from mynewt-nimble project. See [NOTICE](NOTICE) file for details.
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
Apache Mynewt NimBLE
|
||||
Copyright 2015-2022 The Apache Software Foundation
|
||||
Modifications Copyright 2017-2023 Espressif Systems (Shanghai) CO., LTD.
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
Portions of this software were developed at
|
||||
Runtime Inc, copyright 2015.
|
||||
@@ -0,0 +1 @@
|
||||
This software includes portions of code derived from mynewt-nimble project. See [NOTICE](NOTICE) file for details.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
# ESP-BLE-MESH Component
|
||||
|
||||
This is Espressif Bluetooth Low Energy Mesh component folder.
|
||||
|
||||
This component is a part of Espressif IoT Development Framework (ESP-IDF). For the latest documentation please refer to [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/index.html).
|
||||
|
||||
The ESP-BLE-MESH networking enables many-to-many (m:m) device communications and is optimized for creating large-scale device networks.
|
||||
|
||||
|
||||
### [ESP-BLE-MESH Documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp-ble-mesh/ble-mesh-index.html)
|
||||
|
||||
- [Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp-ble-mesh/ble-mesh-index.html#getting-started-with-esp-ble-mesh)
|
||||
- [Architecture](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp-ble-mesh/ble-mesh-architecture.html)
|
||||
- [Feature List](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp-ble-mesh/ble-mesh-feature-list.html)
|
||||
- [FAQ](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp-ble-mesh/ble-mesh-faq.html)
|
||||
- [API Reference](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/bluetooth/esp-ble-mesh.html)
|
||||
|
||||
|
||||
### [ESP-BLE-MESH Examples](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/esp_ble_mesh)
|
||||
|
||||
- Refer to **ESP-BLE-MESH Examples** of [Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp-ble-mesh/ble-mesh-index.html#getting-started-with-esp-ble-mesh) for the tutorials of ESP BLE Mesh examples.
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_ble.h"
|
||||
#include "esp_ble_mesh_ble_api.h"
|
||||
|
||||
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
|
||||
esp_err_t esp_ble_mesh_register_ble_callback(esp_ble_mesh_ble_cb_t callback)
|
||||
{
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
return (btc_profile_cb_set(BTC_PID_BLE_MESH_BLE_COEX, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
|
||||
|
||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||
esp_err_t esp_ble_mesh_start_ble_advertising(const esp_ble_mesh_ble_adv_param_t *param,
|
||||
const esp_ble_mesh_ble_adv_data_t *data)
|
||||
{
|
||||
btc_ble_mesh_ble_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (param == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
|
||||
msg.act = BTC_BLE_MESH_ACT_START_BLE_ADV;
|
||||
|
||||
memcpy(&arg.start_ble_adv.param, param, sizeof(esp_ble_mesh_ble_adv_param_t));
|
||||
if (data) {
|
||||
memcpy(&arg.start_ble_adv.data, data, sizeof(esp_ble_mesh_ble_adv_data_t));
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_stop_ble_advertising(uint8_t index)
|
||||
{
|
||||
btc_ble_mesh_ble_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (index >= CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
|
||||
msg.act = BTC_BLE_MESH_ACT_STOP_BLE_ADV;
|
||||
|
||||
arg.stop_ble_adv.index = index;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
||||
|
||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
|
||||
esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param)
|
||||
{
|
||||
btc_ble_mesh_ble_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
|
||||
msg.act = BTC_BLE_MESH_ACT_START_BLE_SCAN;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_stop_ble_scanning(void)
|
||||
{
|
||||
btc_ble_mesh_ble_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
|
||||
msg.act = BTC_BLE_MESH_ACT_STOP_BLE_SCAN;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
SemaphoreHandle_t semaphore = NULL;
|
||||
btc_msg_t msg = {0};
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (prov == NULL || comp == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
ret = bt_mesh_host_init();
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create a semaphore
|
||||
if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) {
|
||||
BT_ERR("Failed to create semaphore");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
arg.mesh_init.prov = prov;
|
||||
arg.mesh_init.comp = comp;
|
||||
/* Transport semaphore pointer to BTC layer, and will give the semaphore in the BTC task */
|
||||
arg.mesh_init.semaphore = semaphore;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_MESH_INIT;
|
||||
|
||||
if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) != BT_STATUS_SUCCESS) {
|
||||
vSemaphoreDelete(semaphore);
|
||||
BT_ERR("Failed to start mesh init");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Take the Semaphore, wait BLE Mesh initialization to finish. */
|
||||
xSemaphoreTake(semaphore, portMAX_DELAY);
|
||||
/* Don't forget to delete the semaphore at the end. */
|
||||
vSemaphoreDelete(semaphore);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_DEINIT
|
||||
esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
SemaphoreHandle_t semaphore = NULL;
|
||||
btc_msg_t msg = {0};
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (param == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
// Create a semaphore
|
||||
if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) {
|
||||
BT_ERR("Failed to create semaphore");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
arg.mesh_deinit.param.erase_flash = param->erase_flash;
|
||||
/* Transport semaphore pointer to BTC layer, and will give the semaphore in the BTC task */
|
||||
arg.mesh_deinit.semaphore = semaphore;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_DEINIT_MESH;
|
||||
|
||||
if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) != BT_STATUS_SUCCESS) {
|
||||
vSemaphoreDelete(semaphore);
|
||||
BT_ERR("Failed to start mesh deinit");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Take the Semaphore, wait BLE Mesh de-initialization to finish. */
|
||||
xSemaphoreTake(semaphore, portMAX_DELAY);
|
||||
/* Don't forget to delete the semaphore at the end. */
|
||||
vSemaphoreDelete(semaphore);
|
||||
|
||||
ret = bt_mesh_host_deinit();
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DEINIT */
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model)
|
||||
{
|
||||
if (model == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_model_pub_period_get(model);
|
||||
}
|
||||
|
||||
uint16_t esp_ble_mesh_get_primary_element_address(void)
|
||||
{
|
||||
return btc_ble_mesh_get_primary_addr();
|
||||
}
|
||||
|
||||
uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model,
|
||||
uint16_t group_addr)
|
||||
{
|
||||
if (model == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_model_find_group(model, group_addr);
|
||||
}
|
||||
|
||||
esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr)
|
||||
{
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_elem_find(element_addr);
|
||||
}
|
||||
|
||||
uint8_t esp_ble_mesh_get_element_count(void)
|
||||
{
|
||||
return btc_ble_mesh_elem_count();
|
||||
}
|
||||
|
||||
esp_ble_mesh_model_t *esp_ble_mesh_find_vendor_model(const esp_ble_mesh_elem_t *element,
|
||||
uint16_t company_id, uint16_t model_id)
|
||||
{
|
||||
if (element == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_model_find_vnd(element, company_id, model_id);
|
||||
}
|
||||
|
||||
esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(const esp_ble_mesh_elem_t *element,
|
||||
uint16_t model_id)
|
||||
{
|
||||
if (element == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_model_find(element, model_id);
|
||||
}
|
||||
|
||||
const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void)
|
||||
{
|
||||
return btc_ble_mesh_comp_get();
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_model_subscribe_group_addr(uint16_t element_addr, uint16_t company_id,
|
||||
uint16_t model_id, uint16_t group_addr)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr) ||
|
||||
!ESP_BLE_MESH_ADDR_IS_GROUP(group_addr)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_MODEL_SUBSCRIBE_GROUP_ADDR;
|
||||
|
||||
arg.model_sub_group_addr.element_addr = element_addr;
|
||||
arg.model_sub_group_addr.company_id = company_id;
|
||||
arg.model_sub_group_addr.model_id = model_id;
|
||||
arg.model_sub_group_addr.group_addr = group_addr;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_model_unsubscribe_group_addr(uint16_t element_addr, uint16_t company_id,
|
||||
uint16_t model_id, uint16_t group_addr)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr) ||
|
||||
!ESP_BLE_MESH_ADDR_IS_GROUP(group_addr)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_MODEL_UNSUBSCRIBE_GROUP_ADDR;
|
||||
|
||||
arg.model_unsub_group_addr.element_addr = element_addr;
|
||||
arg.model_unsub_group_addr.company_id = company_id;
|
||||
arg.model_unsub_group_addr.model_id = model_id;
|
||||
arg.model_unsub_group_addr.group_addr = group_addr;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_DF_SRV
|
||||
esp_err_t esp_ble_mesh_enable_directed_forwarding(uint16_t net_idx, bool directed_forwarding,
|
||||
bool directed_forwarding_relay)
|
||||
{
|
||||
return btc_ble_mesh_enable_directed_forwarding(net_idx, directed_forwarding,
|
||||
directed_forwarding_relay);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DF_SRV */
|
||||
|
||||
#if CONFIG_BLE_MESH_NODE
|
||||
|
||||
const uint8_t *esp_ble_mesh_node_get_local_net_key(uint16_t net_idx)
|
||||
{
|
||||
return btc_ble_mesh_node_get_local_net_key(net_idx);
|
||||
}
|
||||
|
||||
const uint8_t *esp_ble_mesh_node_get_local_app_key(uint16_t app_idx)
|
||||
{
|
||||
return btc_ble_mesh_node_get_local_app_key(app_idx);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (net_key == NULL || net_idx > 0xFFF) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_NET_KEY;
|
||||
|
||||
arg.node_add_local_net_key.net_idx = net_idx;
|
||||
memcpy(arg.node_add_local_net_key.net_key, net_key, 16);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (app_key == NULL || net_idx > 0xFFF || app_idx > 0xFFF) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_APP_KEY;
|
||||
|
||||
arg.node_add_local_app_key.net_idx = net_idx;
|
||||
arg.node_add_local_app_key.app_idx = app_idx;
|
||||
memcpy(arg.node_add_local_app_key.app_key, app_key, 16);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_bind_app_key_to_local_model(uint16_t element_addr, uint16_t company_id,
|
||||
uint16_t model_id, uint16_t app_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr) || app_idx > 0xFFF) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_NODE_BIND_APP_KEY_TO_MODEL;
|
||||
|
||||
arg.node_local_mod_app_bind.element_addr = element_addr;
|
||||
arg.node_local_mod_app_bind.model_id = model_id;
|
||||
arg.node_local_mod_app_bind.company_id = company_id;
|
||||
arg.node_local_mod_app_bind.app_idx = app_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLE_MESH_NODE */
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
esp_err_t esp_ble_mesh_lpn_enable(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_LPN_ENABLE;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_lpn_disable(bool force)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_LPN_DISABLE;
|
||||
|
||||
arg.lpn_disable.force = force;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_lpn_poll(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_LPN_POLL;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
@@ -0,0 +1,853 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "esp_ble_mesh_networking_api.h"
|
||||
|
||||
#define ESP_BLE_MESH_TX_SDU_MAX ((CONFIG_BLE_MESH_ADV_BUF_COUNT - 3) * 12)
|
||||
|
||||
static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
|
||||
esp_ble_mesh_msg_ctx_t *ctx,
|
||||
uint32_t opcode,
|
||||
btc_ble_mesh_model_act_t act,
|
||||
uint16_t length, uint8_t *data,
|
||||
int32_t msg_timeout, bool need_rsp,
|
||||
esp_ble_mesh_dev_role_t device_role)
|
||||
{
|
||||
btc_ble_mesh_model_args_t arg = {0};
|
||||
uint8_t op_len = 0, mic_len = 0;
|
||||
uint8_t *msg_data = NULL;
|
||||
btc_msg_t msg = {0};
|
||||
esp_err_t status = ESP_OK;
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
if (ctx && ctx->addr == ESP_BLE_MESH_ADDR_UNASSIGNED) {
|
||||
BT_ERR("Invalid destination address 0x0000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* When data is NULL, it is mandatory to set length to 0 to prevent users from misinterpreting parameters. */
|
||||
if (data == NULL) {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if (opcode < 0x100) {
|
||||
op_len = 1;
|
||||
} else if (opcode < 0x10000) {
|
||||
op_len = 2;
|
||||
} else {
|
||||
op_len = 3;
|
||||
}
|
||||
|
||||
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||
if (op_len + length > model->pub->msg->size) {
|
||||
BT_ERR("Too small publication msg size %d", model->pub->msg->size);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||
/* When "send_rel" is true and "send_szmic" is 1, 8-octets TransMIC will
|
||||
* be used, otherwise 4-octets TransMIC will be used.
|
||||
*/
|
||||
mic_len = (model->pub->send_rel && model->pub->send_szmic) ?
|
||||
ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT;
|
||||
} else {
|
||||
/* When the message is tagged with the send-segmented tag and "send_szmic"
|
||||
* is 1, 8-octets TransMIC will be used, otherwise 4-octets TransMIC will
|
||||
* be used.
|
||||
*/
|
||||
mic_len = ((ctx->send_tag & ESP_BLE_MESH_TAG_SEND_SEGMENTED) && ctx->send_szmic) ?
|
||||
ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT;
|
||||
}
|
||||
|
||||
if (op_len + length + mic_len > MIN(ESP_BLE_MESH_SDU_MAX_LEN, ESP_BLE_MESH_TX_SDU_MAX)) {
|
||||
BT_ERR("Too large data length %d", length);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||
bt_mesh_model_msg_init(model->pub->msg, opcode);
|
||||
net_buf_simple_add_mem(model->pub->msg, data, length);
|
||||
} else {
|
||||
msg_data = (uint8_t *)bt_mesh_malloc(op_len + length);
|
||||
if (msg_data == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
esp_ble_mesh_model_msg_opcode_init(msg_data, opcode);
|
||||
memcpy(msg_data + op_len, data, length);
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MODEL;
|
||||
msg.act = act;
|
||||
|
||||
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||
arg.model_publish.model = model;
|
||||
} else {
|
||||
arg.model_send.model = model;
|
||||
arg.model_send.ctx = ctx;
|
||||
arg.model_send.need_rsp = need_rsp;
|
||||
arg.model_send.opcode = opcode;
|
||||
arg.model_send.length = op_len + length;
|
||||
arg.model_send.data = msg_data;
|
||||
arg.model_send.msg_timeout = msg_timeout;
|
||||
}
|
||||
|
||||
status = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_model_args_t), btc_ble_mesh_model_arg_deep_copy,
|
||||
btc_ble_mesh_model_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
|
||||
bt_mesh_free(msg_data);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb_t callback)
|
||||
{
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
return (btc_profile_cb_set(BTC_PID_MODEL, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_model_msg_opcode_init(uint8_t *data, uint32_t opcode)
|
||||
{
|
||||
uint16_t val = 0;
|
||||
|
||||
if (data == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (opcode < 0x100) {
|
||||
/* 1-byte OpCode */
|
||||
data[0] = opcode & 0xff;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (opcode < 0x10000) {
|
||||
/* 2-byte OpCode, big endian */
|
||||
val = sys_cpu_to_be16 (opcode);
|
||||
memcpy(data, &val, 2);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* 3-byte OpCode, note that little endian for the least 2 bytes(Company ID) of opcode */
|
||||
data[0] = (opcode >> 16) & 0xff;
|
||||
val = sys_cpu_to_le16(opcode & 0xffff);
|
||||
memcpy(&data[1], &val, 2);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model)
|
||||
{
|
||||
if (model == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
return btc_ble_mesh_client_model_init(model);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_DEINIT
|
||||
esp_err_t esp_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model)
|
||||
{
|
||||
if (model == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
return btc_ble_mesh_client_model_deinit(model);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DEINIT */
|
||||
|
||||
esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model,
|
||||
esp_ble_mesh_msg_ctx_t *ctx,
|
||||
uint32_t opcode,
|
||||
uint16_t length, uint8_t *data)
|
||||
{
|
||||
if (model == NULL || ctx == NULL ||
|
||||
ctx->net_idx == ESP_BLE_MESH_KEY_UNUSED ||
|
||||
ctx->app_idx == ESP_BLE_MESH_KEY_UNUSED) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ble_mesh_model_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
|
||||
length, data, 0, false, ROLE_NODE);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model,
|
||||
esp_ble_mesh_msg_ctx_t *ctx,
|
||||
uint32_t opcode,
|
||||
uint16_t length, uint8_t *data,
|
||||
int32_t msg_timeout, bool need_rsp,
|
||||
esp_ble_mesh_dev_role_t device_role)
|
||||
{
|
||||
if (model == NULL || ctx == NULL ||
|
||||
ctx->net_idx == ESP_BLE_MESH_KEY_UNUSED ||
|
||||
ctx->app_idx == ESP_BLE_MESH_KEY_UNUSED) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ble_mesh_model_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND,
|
||||
length, data, msg_timeout, need_rsp, device_role);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcode,
|
||||
uint16_t length, uint8_t *data,
|
||||
esp_ble_mesh_dev_role_t device_role)
|
||||
{
|
||||
if (model == NULL || model->pub == NULL || model->pub->msg == NULL ||
|
||||
model->pub->publish_addr == ESP_BLE_MESH_ADDR_UNASSIGNED) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ble_mesh_model_send_msg(model, NULL, opcode, BTC_BLE_MESH_ACT_MODEL_PUBLISH,
|
||||
length, data, 0, false, device_role);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_SERVER_MODEL
|
||||
esp_err_t esp_ble_mesh_server_model_update_state(esp_ble_mesh_model_t *model,
|
||||
esp_ble_mesh_server_state_type_t type,
|
||||
esp_ble_mesh_server_state_value_t *value)
|
||||
{
|
||||
btc_ble_mesh_model_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!model || !value || type >= ESP_BLE_MESH_SERVER_MODEL_STATE_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
arg.model_update_state.model = model;
|
||||
arg.model_update_state.type = type;
|
||||
arg.model_update_state.value = value;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MODEL;
|
||||
msg.act = BTC_BLE_MESH_ACT_SERVER_MODEL_UPDATE_STATE;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_model_args_t), btc_ble_mesh_model_arg_deep_copy,
|
||||
btc_ble_mesh_model_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_SERVER_MODEL */
|
||||
|
||||
esp_err_t esp_ble_mesh_node_local_reset(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_NODE_RESET;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_PROVISIONER
|
||||
esp_err_t esp_ble_mesh_provisioner_set_node_name(uint16_t index, const char *name)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_NODE_NAME;
|
||||
|
||||
arg.set_node_name.index = index;
|
||||
memset(arg.set_node_name.name, 0, sizeof(arg.set_node_name.name));
|
||||
strncpy(arg.set_node_name.name, name, ESP_BLE_MESH_NODE_NAME_MAX_LEN);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
const char *esp_ble_mesh_provisioner_get_node_name(uint16_t index)
|
||||
{
|
||||
return bt_mesh_provisioner_get_node_name(index);
|
||||
}
|
||||
|
||||
uint16_t esp_ble_mesh_provisioner_get_node_index(const char *name)
|
||||
{
|
||||
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
|
||||
return ESP_BLE_MESH_INVALID_NODE_INDEX;
|
||||
}
|
||||
|
||||
return bt_mesh_provisioner_get_node_index(name);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_store_node_comp_data(uint16_t unicast_addr,
|
||||
uint8_t *data, uint16_t length)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(unicast_addr) || !data || length <= 14) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_STORE_NODE_COMP_DATA;
|
||||
|
||||
arg.store_node_comp_data.unicast_addr = unicast_addr;
|
||||
arg.store_node_comp_data.length = length;
|
||||
arg.store_node_comp_data.data = data;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), btc_ble_mesh_prov_arg_deep_copy,
|
||||
btc_ble_mesh_prov_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_with_uuid(const uint8_t uuid[16])
|
||||
{
|
||||
if (!uuid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_provisioner_get_node_with_uuid(uuid);
|
||||
}
|
||||
|
||||
esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_with_addr(uint16_t unicast_addr)
|
||||
{
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(unicast_addr)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_provisioner_get_node_with_addr(unicast_addr);
|
||||
}
|
||||
|
||||
esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_with_name(const char *name)
|
||||
{
|
||||
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_provisioner_get_node_with_name(name);
|
||||
}
|
||||
|
||||
uint16_t esp_ble_mesh_provisioner_get_prov_node_count(void)
|
||||
{
|
||||
return btc_ble_mesh_provisioner_get_prov_node_count();
|
||||
}
|
||||
|
||||
const esp_ble_mesh_node_t **esp_ble_mesh_provisioner_get_node_table_entry(void)
|
||||
{
|
||||
return btc_ble_mesh_provisioner_get_node_table_entry();
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_delete_node_with_uuid(const uint8_t uuid[16])
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!uuid) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_UUID;
|
||||
|
||||
memcpy(arg.delete_node_with_uuid.uuid, uuid, 16);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_delete_node_with_addr(uint16_t unicast_addr)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(unicast_addr)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_ADDR;
|
||||
|
||||
arg.delete_node_with_addr.unicast_addr = unicast_addr;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16],
|
||||
uint16_t net_idx, uint16_t app_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_APP_KEY;
|
||||
|
||||
arg.add_local_app_key.net_idx = net_idx;
|
||||
arg.add_local_app_key.app_idx = app_idx;
|
||||
if (app_key) {
|
||||
memcpy(arg.add_local_app_key.app_key, app_key, 16);
|
||||
} else {
|
||||
bzero(arg.add_local_app_key.app_key, 16);
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_update_local_app_key(const uint8_t app_key[16],
|
||||
uint16_t net_idx, uint16_t app_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (app_key == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_UPDATE_LOCAL_APP_KEY;
|
||||
|
||||
memcpy(arg.update_local_app_key.app_key, app_key, 16);
|
||||
arg.update_local_app_key.net_idx = net_idx;
|
||||
arg.update_local_app_key.app_idx = app_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
const uint8_t *esp_ble_mesh_provisioner_get_local_app_key(uint16_t net_idx, uint16_t app_idx)
|
||||
{
|
||||
return bt_mesh_provisioner_local_app_key_get(net_idx, app_idx);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_bind_app_key_to_local_model(uint16_t element_addr, uint16_t app_idx,
|
||||
uint16_t model_id, uint16_t company_id)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_BIND_LOCAL_MOD_APP;
|
||||
|
||||
arg.local_mod_app_bind.elem_addr = element_addr;
|
||||
arg.local_mod_app_bind.app_idx = app_idx;
|
||||
arg.local_mod_app_bind.model_id = model_id;
|
||||
arg.local_mod_app_bind.cid = company_id;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (net_idx == ESP_BLE_MESH_KEY_PRIMARY) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY;
|
||||
|
||||
arg.add_local_net_key.net_idx = net_idx;
|
||||
if (net_key) {
|
||||
memcpy(arg.add_local_net_key.net_key, net_key, 16);
|
||||
} else {
|
||||
bzero(arg.add_local_net_key.net_key, 16);
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_update_local_net_key(const uint8_t net_key[16], uint16_t net_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (net_key == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_UPDATE_LOCAL_NET_KEY;
|
||||
|
||||
memcpy(arg.update_local_net_key.net_key, net_key, 16);
|
||||
arg.update_local_net_key.net_idx = net_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx)
|
||||
{
|
||||
return bt_mesh_provisioner_net_key_get(net_idx);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_PROVISIONER_RECV_HB
|
||||
esp_err_t esp_ble_mesh_provisioner_recv_heartbeat(bool enable)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ENABLE_HEARTBEAT_RECV;
|
||||
|
||||
arg.enable_heartbeat_recv.enable = enable;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_type(uint8_t type)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (type > ESP_BLE_MESH_HEARTBEAT_FILTER_REJECTLIST) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE;
|
||||
|
||||
arg.set_heartbeat_filter_type.type = type;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, esp_ble_mesh_heartbeat_filter_info_t *info)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (op > ESP_BLE_MESH_HEARTBEAT_FILTER_REMOVE || info == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_src) &&
|
||||
!ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_dst) &&
|
||||
!ESP_BLE_MESH_ADDR_IS_GROUP(info->hb_dst)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_INFO;
|
||||
|
||||
arg.set_heartbeat_filter_info.op = op;
|
||||
arg.set_heartbeat_filter_info.hb_src = info->hb_src;
|
||||
arg.set_heartbeat_filter_info.hb_dst = info->hb_dst;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */
|
||||
|
||||
#if CONFIG_BLE_MESH_SETTINGS
|
||||
esp_err_t esp_ble_mesh_provisioner_direct_erase_settings(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DIRECT_ERASE_SETTINGS;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_SETTINGS */
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
|
||||
esp_err_t esp_ble_mesh_provisioner_open_settings_with_index(uint8_t index)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_INDEX;
|
||||
|
||||
arg.open_settings_with_index.index = index;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_open_settings_with_uid(const char *uid)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_UID;
|
||||
|
||||
strncpy(arg.open_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_close_settings_with_index(uint8_t index, bool erase)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX;
|
||||
|
||||
arg.close_settings_with_index.index = index;
|
||||
arg.close_settings_with_index.erase = erase;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_close_settings_with_uid(const char *uid, bool erase)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_UID;
|
||||
|
||||
strncpy(arg.close_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE);
|
||||
arg.close_settings_with_uid.erase = erase;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_delete_settings_with_index(uint8_t index)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_INDEX;
|
||||
|
||||
arg.delete_settings_with_index.index = index;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_delete_settings_with_uid(const char *uid)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_UID;
|
||||
|
||||
strncpy(arg.delete_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
const char *esp_ble_mesh_provisioner_get_settings_uid(uint8_t index)
|
||||
{
|
||||
if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_provisioner_get_settings_uid(index);
|
||||
}
|
||||
|
||||
uint8_t esp_ble_mesh_provisioner_get_settings_index(const char *uid)
|
||||
{
|
||||
if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) {
|
||||
return ESP_BLE_MESH_INVALID_SETTINGS_IDX;
|
||||
}
|
||||
|
||||
return btc_ble_mesh_provisioner_get_settings_index(uid);
|
||||
}
|
||||
|
||||
uint8_t esp_ble_mesh_provisioner_get_free_settings_count(void)
|
||||
{
|
||||
return btc_ble_mesh_provisioner_get_free_settings_count();
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */
|
||||
|
||||
#if CONFIG_BLE_MESH_CERT_BASED_PROV
|
||||
esp_err_t esp_ble_mesh_provisioner_send_prov_records_get(uint16_t link_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SEND_PROV_RECORDS_GET;
|
||||
|
||||
arg.send_prov_records_get.link_idx = link_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_send_prov_record_req(uint16_t link_idx, uint16_t record_id,
|
||||
uint16_t frag_offset, uint16_t max_size)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (record_id >= ESP_BLE_MESH_PROV_RECORD_MAX_ID) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SEND_PROV_RECORD_REQUEST;
|
||||
|
||||
arg.send_prov_record_req.link_idx = link_idx;
|
||||
arg.send_prov_record_req.record_id = record_id;
|
||||
arg.send_prov_record_req.frag_offset = frag_offset;
|
||||
arg.send_prov_record_req.max_size = max_size;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_send_prov_invite(uint16_t link_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SEND_PROV_INVITE;
|
||||
|
||||
arg.send_prov_invite.link_idx = link_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_send_link_close(uint16_t link_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SEND_LINK_CLOSE;
|
||||
|
||||
arg.send_link_close.link_idx = link_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_CERT_BASED_PROV */
|
||||
#endif /* CONFIG_BLE_MESH_PROVISIONER */
|
||||
|
||||
#if CONFIG_BLE_MESH_FAST_PROV
|
||||
const uint8_t *esp_ble_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx)
|
||||
{
|
||||
return bt_mesh_get_fast_prov_app_key(net_idx, app_idx);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_FAST_PROV */
|
||||
@@ -0,0 +1,530 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "esp_ble_mesh_provisioning_api.h"
|
||||
|
||||
#define MAX_PROV_LINK_IDX (CONFIG_BLE_MESH_PBA_SAME_TIME + CONFIG_BLE_MESH_PBG_SAME_TIME)
|
||||
#define MAX_OOB_INPUT_NUM 0x5F5E0FF /* Decimal: 99999999 */
|
||||
|
||||
esp_err_t esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb_t callback)
|
||||
{
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
return (btc_profile_cb_set(BTC_PID_PROV, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
bool esp_ble_mesh_node_is_provisioned(void)
|
||||
{
|
||||
return bt_mesh_is_provisioned();
|
||||
}
|
||||
|
||||
static bool prov_bearers_valid(esp_ble_mesh_prov_bearer_t bearers)
|
||||
{
|
||||
if ((!(bearers & (ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT))) ||
|
||||
(IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
|
||||
!IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
|
||||
!(bearers & ESP_BLE_MESH_PROV_ADV)) ||
|
||||
(!IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
|
||||
IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
|
||||
!(bearers & ESP_BLE_MESH_PROV_GATT))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_prov_enable(esp_ble_mesh_prov_bearer_t bearers)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (prov_bearers_valid(bearers) == false) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROV_ENABLE;
|
||||
arg.node_prov_enable.bearers = bearers;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_prov_disable(esp_ble_mesh_prov_bearer_t bearers)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (prov_bearers_valid(bearers) == false) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROV_DISABLE;
|
||||
arg.node_prov_disable.bearers = bearers;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_set_oob_pub_key(uint8_t pub_key_x[32], uint8_t pub_key_y[32],
|
||||
uint8_t private_key[32])
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!pub_key_x || !pub_key_y || !private_key) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_SET_OOB_PUB_KEY;
|
||||
|
||||
memcpy(arg.set_oob_pub_key.pub_key_x, pub_key_x, 32);
|
||||
memcpy(arg.set_oob_pub_key.pub_key_y, pub_key_y, 32);
|
||||
memcpy(arg.set_oob_pub_key.private_key, private_key, 32);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_input_number(uint32_t number)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (number > MAX_OOB_INPUT_NUM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_INPUT_NUMBER;
|
||||
arg.input_number.number = number;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_node_input_string(const char *string)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!string || strlen(string) > ESP_BLE_MESH_PROV_INPUT_OOB_MAX_LEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_INPUT_STRING;
|
||||
|
||||
arg.input_string.string[sizeof(arg.input_string.string) - 1] = 0;
|
||||
strncpy(arg.input_string.string, string, sizeof(arg.input_string.string) - 1);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!name || strlen(name) > ESP_BLE_MESH_DEVICE_NAME_MAX_LEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_SET_DEVICE_NAME;
|
||||
|
||||
arg.set_device_name.name[sizeof(arg.set_device_name.name) - 1] = 0;
|
||||
strncpy(arg.set_device_name.name, name, sizeof(arg.set_device_name.name) - 1);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_PROVISIONER
|
||||
esp_err_t esp_ble_mesh_provisioner_read_oob_pub_key(uint8_t link_idx, uint8_t pub_key_x[32],
|
||||
uint8_t pub_key_y[32])
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!pub_key_x || !pub_key_y || link_idx >= MAX_PROV_LINK_IDX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_READ_OOB_PUB_KEY;
|
||||
|
||||
arg.provisioner_read_oob_pub_key.link_idx = link_idx;
|
||||
memcpy(arg.provisioner_read_oob_pub_key.pub_key_x, pub_key_x, 32);
|
||||
memcpy(arg.provisioner_read_oob_pub_key.pub_key_y, pub_key_y, 32);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!string || strlen(string) > ESP_BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN ||
|
||||
link_idx >= MAX_PROV_LINK_IDX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_INPUT_STR;
|
||||
|
||||
arg.provisioner_input_str.string[sizeof(arg.provisioner_input_str.string) - 1] = 0;
|
||||
strncpy(arg.provisioner_input_str.string, string, sizeof(arg.provisioner_input_str.string) - 1);
|
||||
arg.provisioner_input_str.link_idx = link_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_input_number(uint32_t number, uint8_t link_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (number > MAX_OOB_INPUT_NUM || link_idx >= MAX_PROV_LINK_IDX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_INPUT_NUM;
|
||||
|
||||
arg.provisioner_input_num.number = number;
|
||||
arg.provisioner_input_num.link_idx = link_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_prov_enable(esp_ble_mesh_prov_bearer_t bearers)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (prov_bearers_valid(bearers) == false) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ENABLE;
|
||||
|
||||
arg.provisioner_enable.bearers = bearers;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_prov_disable(esp_ble_mesh_prov_bearer_t bearers)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (prov_bearers_valid(bearers) == false) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DISABLE;
|
||||
|
||||
arg.provisioner_disable.bearers = bearers;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t *add_dev,
|
||||
esp_ble_mesh_dev_add_flag_t flags)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (add_dev == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DEV_ADD;
|
||||
|
||||
arg.provisioner_dev_add.add_dev.addr_type = add_dev->addr_type;
|
||||
arg.provisioner_dev_add.add_dev.oob_info = add_dev->oob_info;
|
||||
arg.provisioner_dev_add.add_dev.bearer = add_dev->bearer;
|
||||
memcpy(arg.provisioner_dev_add.add_dev.addr, add_dev->addr, sizeof(esp_ble_mesh_bd_addr_t));
|
||||
memcpy(arg.provisioner_dev_add.add_dev.uuid, add_dev->uuid, 16);
|
||||
arg.provisioner_dev_add.flags = flags;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16],
|
||||
esp_ble_mesh_bd_addr_t addr,
|
||||
esp_ble_mesh_addr_type_t addr_type,
|
||||
esp_ble_mesh_prov_bearer_t bearer,
|
||||
uint16_t oob_info, uint16_t unicast_addr)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (uuid == NULL || (bearer == ESP_BLE_MESH_PROV_GATT && (addr == NULL ||
|
||||
addr_type > ESP_BLE_MESH_ADDR_TYPE_RANDOM)) ||
|
||||
(bearer != ESP_BLE_MESH_PROV_ADV && bearer != ESP_BLE_MESH_PROV_GATT) ||
|
||||
!ESP_BLE_MESH_ADDR_IS_UNICAST(unicast_addr)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_PROV_DEV_WITH_ADDR;
|
||||
|
||||
memcpy(arg.provisioner_prov_dev_with_addr.uuid, uuid, 16);
|
||||
if (addr) {
|
||||
memcpy(arg.provisioner_prov_dev_with_addr.addr, addr, BD_ADDR_LEN);
|
||||
arg.provisioner_prov_dev_with_addr.addr_type = addr_type;
|
||||
}
|
||||
arg.provisioner_prov_dev_with_addr.bearer = bearer;
|
||||
arg.provisioner_prov_dev_with_addr.oob_info = oob_info;
|
||||
arg.provisioner_prov_dev_with_addr.unicast_addr = unicast_addr;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_dev)
|
||||
{
|
||||
uint8_t val = DEL_DEV_ADDR_FLAG | DEL_DEV_UUID_FLAG;
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (del_dev == NULL || (__builtin_popcount(del_dev->flag & val) != 1)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DEV_DEL;
|
||||
|
||||
arg.provisioner_dev_del.del_dev.flag = del_dev->flag;
|
||||
if (del_dev->flag & DEL_DEV_ADDR_FLAG) {
|
||||
arg.provisioner_dev_del.del_dev.addr_type = del_dev->addr_type;
|
||||
memcpy(arg.provisioner_dev_del.del_dev.addr, del_dev->addr, sizeof(esp_ble_mesh_bd_addr_t));
|
||||
} else if (del_dev->flag & DEL_DEV_UUID_FLAG) {
|
||||
memcpy(arg.provisioner_dev_del.del_dev.uuid, del_dev->uuid, 16);
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, uint8_t match_len,
|
||||
uint8_t offset, bool prov_after_match)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (match_len + offset > ESP_BLE_MESH_OCTET16_LEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_DEV_UUID_MATCH;
|
||||
|
||||
if (match_len && match_val) {
|
||||
memcpy(arg.set_dev_uuid_match.match_val, match_val, match_len);
|
||||
}
|
||||
arg.set_dev_uuid_match.match_len = match_len;
|
||||
arg.set_dev_uuid_match.offset = offset;
|
||||
arg.set_dev_uuid_match.prov_after_match = prov_after_match;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_info_t *prov_data_info)
|
||||
{
|
||||
uint8_t val = PROV_DATA_NET_IDX_FLAG | PROV_DATA_FLAGS_FLAG | PROV_DATA_IV_INDEX_FLAG;
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (prov_data_info == NULL || (__builtin_popcount(prov_data_info->flag & val) != 1)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_PROV_DATA_INFO;
|
||||
|
||||
arg.set_prov_data_info.prov_data.flag = prov_data_info->flag;
|
||||
if (prov_data_info->flag & PROV_DATA_NET_IDX_FLAG) {
|
||||
arg.set_prov_data_info.prov_data.net_idx = prov_data_info->net_idx;
|
||||
} else if (prov_data_info->flag & PROV_DATA_FLAGS_FLAG) {
|
||||
arg.set_prov_data_info.prov_data.flags = prov_data_info->flags;
|
||||
} else if (prov_data_info->flag & PROV_DATA_IV_INDEX_FLAG) {
|
||||
arg.set_prov_data_info.prov_data.iv_index = prov_data_info->iv_index;
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_set_static_oob_value(const uint8_t *value, uint8_t length)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (value == NULL || length == 0 || length > 16) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_STATIC_OOB_VAL;
|
||||
|
||||
arg.set_static_oob_val.length = length;
|
||||
memcpy(arg.set_static_oob_val.value, value, length);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_provisioner_set_primary_elem_addr(uint16_t addr)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(addr)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_PRIMARY_ELEM_ADDR;
|
||||
|
||||
arg.set_primary_elem_addr.addr = addr;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_PROVISIONER */
|
||||
|
||||
/* The following APIs are for fast provisioning */
|
||||
|
||||
#if CONFIG_BLE_MESH_FAST_PROV
|
||||
esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_prov_info)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (fast_prov_info == NULL || (fast_prov_info->offset +
|
||||
fast_prov_info->match_len > ESP_BLE_MESH_OCTET16_LEN)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO;
|
||||
|
||||
arg.set_fast_prov_info.unicast_min = fast_prov_info->unicast_min;
|
||||
arg.set_fast_prov_info.unicast_max = fast_prov_info->unicast_max;
|
||||
arg.set_fast_prov_info.net_idx = fast_prov_info->net_idx;
|
||||
arg.set_fast_prov_info.flags = fast_prov_info->flags;
|
||||
arg.set_fast_prov_info.iv_index = fast_prov_info->iv_index;
|
||||
arg.set_fast_prov_info.offset = fast_prov_info->offset;
|
||||
arg.set_fast_prov_info.match_len = fast_prov_info->match_len;
|
||||
if (fast_prov_info->match_len) {
|
||||
memcpy(arg.set_fast_prov_info.match_val, fast_prov_info->match_val, fast_prov_info->match_len);
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_set_fast_prov_action(esp_ble_mesh_fast_prov_action_t action)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (action >= FAST_PROV_ACT_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION;
|
||||
|
||||
arg.set_fast_prov_action.action = action;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_FAST_PROV */
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
#include "esp_ble_mesh_local_data_operation_api.h"
|
||||
#include "esp_ble_mesh_proxy_api.h"
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_identity_enable(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_IDENTITY_ENABLE;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_gatt_enable(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_GATT_ENABLE;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_gatt_disable(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_GATT_DISABLE;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_PRB_SRV
|
||||
esp_err_t esp_ble_mesh_private_proxy_identity_enable(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PRIVATE_PROXY_IDENTITY_ENABLE;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_private_proxy_identity_disable(void)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PRIVATE_PROXY_IDENTITY_DISABLE;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_PRB_SRV */
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_client_connect(esp_ble_mesh_bd_addr_t addr,
|
||||
esp_ble_mesh_addr_type_t addr_type,
|
||||
uint16_t net_idx)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!addr || addr_type > ESP_BLE_MESH_ADDR_TYPE_RANDOM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_CONNECT;
|
||||
|
||||
memcpy(arg.proxy_client_connect.addr, addr, BD_ADDR_LEN);
|
||||
arg.proxy_client_connect.addr_type = addr_type;
|
||||
arg.proxy_client_connect.net_idx = net_idx;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_client_disconnect(uint8_t conn_handle)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_DISCONNECT;
|
||||
|
||||
arg.proxy_client_disconnect.conn_handle = conn_handle;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_client_set_filter_type(uint8_t conn_handle, uint16_t net_idx,
|
||||
esp_ble_mesh_proxy_filter_type_t filter_type)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (filter_type > PROXY_FILTER_BLACKLIST) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_SET_FILTER_TYPE;
|
||||
|
||||
arg.proxy_client_set_filter_type.conn_handle = conn_handle;
|
||||
arg.proxy_client_set_filter_type.net_idx = net_idx;
|
||||
arg.proxy_client_set_filter_type.filter_type = filter_type;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_client_add_filter_addr(uint8_t conn_handle, uint16_t net_idx,
|
||||
uint16_t *addr, uint16_t addr_num)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!addr || addr_num == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_ADD_FILTER_ADDR;
|
||||
|
||||
arg.proxy_client_add_filter_addr.conn_handle = conn_handle;
|
||||
arg.proxy_client_add_filter_addr.net_idx = net_idx;
|
||||
arg.proxy_client_add_filter_addr.addr_num = addr_num;
|
||||
arg.proxy_client_add_filter_addr.addr = addr;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), btc_ble_mesh_prov_arg_deep_copy,
|
||||
btc_ble_mesh_prov_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_mesh_proxy_client_remove_filter_addr(uint8_t conn_handle, uint16_t net_idx,
|
||||
uint16_t *addr, uint16_t addr_num)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (!addr || addr_num == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR;
|
||||
|
||||
arg.proxy_client_remove_filter_addr.conn_handle = conn_handle;
|
||||
arg.proxy_client_remove_filter_addr.net_idx = net_idx;
|
||||
arg.proxy_client_remove_filter_addr.addr_num = addr_num;
|
||||
arg.proxy_client_remove_filter_addr.addr = addr;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), btc_ble_mesh_prov_arg_deep_copy,
|
||||
btc_ble_mesh_prov_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_DF_CLI
|
||||
esp_err_t esp_ble_mesh_proxy_client_directed_proxy_set(uint8_t conn_handle, uint16_t net_idx,
|
||||
uint8_t use_directed)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (use_directed > ESP_BLE_MESH_PROXY_CLI_DIRECTED_FORWARDING_ENABLE) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_DIRECTED_PROXY_SET;
|
||||
|
||||
arg.proxy_client_directed_proxy_set.conn_handle = conn_handle;
|
||||
arg.proxy_client_directed_proxy_set.net_idx = net_idx;
|
||||
arg.proxy_client_directed_proxy_set.use_directed = use_directed;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), btc_ble_mesh_prov_arg_deep_copy, btc_ble_mesh_prov_arg_deep_free)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_DF_CLI */
|
||||
|
||||
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
|
||||
esp_err_t esp_ble_mesh_proxy_client_send_solic_pdu(uint8_t net_idx, uint16_t ssrc, uint16_t dst)
|
||||
{
|
||||
btc_ble_mesh_prov_args_t arg = {0};
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
if (esp_ble_mesh_find_element(ssrc) == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_PROV;
|
||||
msg.act = BTC_BLE_MESH_ACT_PROXY_CLIENT_SEND_SOLIC_PDU;
|
||||
|
||||
arg.proxy_client_send_solic_pdu.net_idx = net_idx;
|
||||
arg.proxy_client_send_solic_pdu.ssrc = ssrc;
|
||||
arg.proxy_client_send_solic_pdu.dst = dst;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_BLE_MESH_BLE_API_H_
|
||||
#define _ESP_BLE_MESH_BLE_API_H_
|
||||
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** This enum value is the event of BLE operations */
|
||||
typedef enum {
|
||||
ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT, /*!< Start BLE advertising completion event */
|
||||
ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT, /*!< Stop BLE advertising completion event */
|
||||
ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT, /*!< Start BLE scanning completion event */
|
||||
ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT, /*!< Stop BLE scanning completion event */
|
||||
ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT, /*!< Scanning BLE advertising packets event */
|
||||
ESP_BLE_MESH_BLE_EVT_MAX,
|
||||
} esp_ble_mesh_ble_cb_event_t;
|
||||
|
||||
/** BLE operation callback parameters */
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT
|
||||
*/
|
||||
struct {
|
||||
int err_code; /*!< Indicate the result of starting BLE advertising */
|
||||
uint8_t index; /*!< Index of the BLE advertising */
|
||||
} start_ble_advertising_comp; /*!< Event parameters of ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT */
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT
|
||||
*/
|
||||
struct {
|
||||
int err_code; /*!< Indicate the result of stopping BLE advertising */
|
||||
uint8_t index; /*!< Index of the BLE advertising */
|
||||
} stop_ble_advertising_comp; /*!< Event parameters of ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT */
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT
|
||||
*/
|
||||
struct {
|
||||
int err_code; /*!< Indicate the result of starting BLE scanning */
|
||||
} start_ble_scan_comp; /*!< Event parameters of ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT */
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT
|
||||
*/
|
||||
struct {
|
||||
int err_code; /*!< Indicate the result of stopping BLE scanning */
|
||||
} stop_ble_scan_comp; /*!< Event parameters of ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT */
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT
|
||||
*/
|
||||
struct {
|
||||
uint8_t addr[6]; /*!< Device address */
|
||||
uint8_t addr_type; /*!< Device address type */
|
||||
uint8_t adv_type; /*!< Advertising data type */
|
||||
uint8_t *data; /*!< Advertising data */
|
||||
uint16_t length; /*!< Advertising data length */
|
||||
int8_t rssi; /*!< RSSI of the advertising packet */
|
||||
} scan_ble_adv_pkt; /*!< Event parameters of ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT */
|
||||
} esp_ble_mesh_ble_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief BLE scanning callback function type
|
||||
*
|
||||
* @param event: BLE scanning callback event type
|
||||
* @param param: BLE scanning callback parameter
|
||||
*/
|
||||
typedef void (* esp_ble_mesh_ble_cb_t)(esp_ble_mesh_ble_cb_event_t event,
|
||||
esp_ble_mesh_ble_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief Register BLE scanning callback.
|
||||
*
|
||||
* @param[in] callback: Pointer to the BLE scanning callback function.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_register_ble_callback(esp_ble_mesh_ble_cb_t callback);
|
||||
|
||||
/** Count for sending BLE advertising packet infinitely */
|
||||
#define ESP_BLE_MESH_BLE_ADV_INFINITE 0xFFFF
|
||||
|
||||
/*!< This enum value is the priority of BLE advertising packet */
|
||||
typedef enum {
|
||||
ESP_BLE_MESH_BLE_ADV_PRIO_LOW,
|
||||
ESP_BLE_MESH_BLE_ADV_PRIO_HIGH,
|
||||
} esp_ble_mesh_ble_adv_priority_t;
|
||||
|
||||
/** Context of BLE advertising parameters. */
|
||||
typedef struct {
|
||||
uint16_t interval; /*!< BLE advertising interval */
|
||||
uint8_t adv_type; /*!< BLE advertising type */
|
||||
uint8_t own_addr_type; /*!< Own address type */
|
||||
uint8_t peer_addr_type; /*!< Peer address type */
|
||||
uint8_t peer_addr[BD_ADDR_LEN]; /*!< Peer address */
|
||||
uint16_t duration; /*!< Duration is milliseconds */
|
||||
uint16_t period; /*!< Period in milliseconds */
|
||||
uint16_t count; /*!< Number of advertising duration */
|
||||
uint8_t priority:2; /*!< Priority of BLE advertising packet */
|
||||
} esp_ble_mesh_ble_adv_param_t;
|
||||
|
||||
/** Context of BLE advertising data. */
|
||||
typedef struct {
|
||||
uint8_t adv_data_len; /*!< Advertising data length */
|
||||
uint8_t adv_data[31]; /*!< Advertising data */
|
||||
uint8_t scan_rsp_data_len; /*!< Scan response data length */
|
||||
uint8_t scan_rsp_data[31]; /*!< Scan response data */
|
||||
} esp_ble_mesh_ble_adv_data_t;
|
||||
|
||||
/**
|
||||
* @brief This function is called to start BLE advertising with the corresponding data
|
||||
* and parameters while BLE Mesh is working at the same time.
|
||||
*
|
||||
* @note 1. When this function is called, the BLE advertising packet will be posted to
|
||||
* the BLE mesh adv queue in the mesh stack and waited to be sent.
|
||||
* 2. In the BLE advertising parameters, the "duration" means the time used for
|
||||
* sending the BLE advertising packet each time, it shall not be smaller than the
|
||||
* advertising interval. When the packet is sent successfully, it will be posted
|
||||
* to the adv queue again after the "period" time if the "count" is bigger than 0.
|
||||
* The "count" means how many durations the packet will be sent after it is sent
|
||||
* successfully for the first time. And if the "count" is set to 0xFFFF, which
|
||||
* means the packet will be sent infinitely.
|
||||
* 3. The "priority" means the priority of BLE advertising packet compared with
|
||||
* BLE Mesh packets. Currently two options (i.e. low/high) are provided. If the
|
||||
* "priority" is high, the BLE advertising packet will be posted to the front of
|
||||
* adv queue. Otherwise it will be posted to the back of adv queue.
|
||||
*
|
||||
* @param[in] param: Pointer to the BLE advertising parameters
|
||||
* @param[in] data: Pointer to the BLE advertising data and scan response data
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_start_ble_advertising(const esp_ble_mesh_ble_adv_param_t *param,
|
||||
const esp_ble_mesh_ble_adv_data_t *data);
|
||||
|
||||
/**
|
||||
* @brief This function is called to stop BLE advertising with the corresponding index.
|
||||
*
|
||||
* @param[in] index: Index of BLE advertising
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_stop_ble_advertising(uint8_t index);
|
||||
|
||||
/** Context of BLE scanning parameters. */
|
||||
typedef struct {
|
||||
uint32_t duration; /*!< Duration used to scan normal BLE advertising packets */
|
||||
} esp_ble_mesh_ble_scan_param_t;
|
||||
|
||||
/**
|
||||
* @brief This function is called to start scanning normal BLE advertising packets
|
||||
* and notifying the packets to the application layer.
|
||||
*
|
||||
* @param[in] param: Pointer to the BLE scanning parameters
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to stop notifying normal BLE advertising packets
|
||||
* to the application layer.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_stop_ble_scanning(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLE_MESH_BLE_API_H_ */
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_BLE_MESH_COMMON_API_H_
|
||||
#define _ESP_BLE_MESH_COMMON_API_H_
|
||||
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize BLE Mesh module.
|
||||
* This API initializes provisioning capabilities and composition data information.
|
||||
*
|
||||
* @note After calling this API, the device needs to call esp_ble_mesh_prov_enable()
|
||||
* to enable provisioning functionality again.
|
||||
*
|
||||
* @param[in] prov: Pointer to the device provisioning capabilities. This pointer must
|
||||
* remain valid during the lifetime of the BLE Mesh device.
|
||||
* @param[in] comp: Pointer to the device composition data information. This pointer
|
||||
* must remain valid during the lifetime of the BLE Mesh device.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp);
|
||||
|
||||
/**
|
||||
* @brief De-initialize BLE Mesh module.
|
||||
*
|
||||
* @note This function shall be invoked after esp_ble_mesh_client_model_deinit().
|
||||
*
|
||||
* @param[in] param: Pointer to the structure of BLE Mesh deinit parameters.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLE_MESH_COMMON_API_H_ */
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
|
||||
#define _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
|
||||
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the model publish period, the unit is ms.
|
||||
*
|
||||
* @param[in] model: Model instance pointer.
|
||||
*
|
||||
* @return Publish period value on success, 0 or (negative) error code from errno.h on failure.
|
||||
*
|
||||
*/
|
||||
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model);
|
||||
|
||||
/**
|
||||
* @brief Get the address of the primary element.
|
||||
*
|
||||
* @return Address of the primary element on success, or
|
||||
* ESP_BLE_MESH_ADDR_UNASSIGNED on failure which means the device has not been provisioned.
|
||||
*
|
||||
*/
|
||||
uint16_t esp_ble_mesh_get_primary_element_address(void);
|
||||
|
||||
/**
|
||||
* @brief Check if the model has subscribed to the given group address.
|
||||
* Note: E.g., once a status message is received and the destination address
|
||||
* is a group address, the model uses this API to check if it is successfully subscribed
|
||||
* to the given group address.
|
||||
*
|
||||
* @param[in] model: Pointer to the model.
|
||||
* @param[in] group_addr: Group address.
|
||||
*
|
||||
* @return Pointer to the group address within the Subscription List of the model on success, or
|
||||
* NULL on failure which means the model has not subscribed to the given group address.
|
||||
* Note: With the pointer to the group address returned, you can reset the group address
|
||||
* to 0x0000 in order to unsubscribe the model from the group.
|
||||
*
|
||||
*/
|
||||
uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model,
|
||||
uint16_t group_addr);
|
||||
|
||||
/**
|
||||
* @brief Find the BLE Mesh element pointer via the element address.
|
||||
*
|
||||
* @param[in] element_addr: Element address.
|
||||
*
|
||||
* @return Pointer to the element on success, or NULL on failure.
|
||||
*
|
||||
*/
|
||||
esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr);
|
||||
|
||||
/**
|
||||
* @brief Get the number of elements that have been registered.
|
||||
*
|
||||
* @return Number of elements.
|
||||
*
|
||||
*/
|
||||
uint8_t esp_ble_mesh_get_element_count(void);
|
||||
|
||||
/**
|
||||
* @brief Find the Vendor specific model with the given element,
|
||||
* the company ID and the Vendor Model ID.
|
||||
*
|
||||
* @param[in] element: Element to which the model belongs.
|
||||
* @param[in] company_id: A 16-bit company identifier assigned by the Bluetooth SIG.
|
||||
* @param[in] model_id: A 16-bit vendor-assigned model identifier.
|
||||
*
|
||||
* @return Pointer to the Vendor Model on success, or NULL on failure which means the Vendor Model is not found.
|
||||
*
|
||||
*/
|
||||
esp_ble_mesh_model_t *esp_ble_mesh_find_vendor_model(const esp_ble_mesh_elem_t *element,
|
||||
uint16_t company_id, uint16_t model_id);
|
||||
|
||||
/**
|
||||
* @brief Find the SIG model with the given element and Model id.
|
||||
*
|
||||
* @param[in] element: Element to which the model belongs.
|
||||
* @param[in] model_id: SIG model identifier.
|
||||
*
|
||||
* @return Pointer to the SIG Model on success, or NULL on failure which means the SIG Model is not found.
|
||||
*
|
||||
*/
|
||||
esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(const esp_ble_mesh_elem_t *element,
|
||||
uint16_t model_id);
|
||||
|
||||
/**
|
||||
* @brief Get the Composition data which has been registered.
|
||||
*
|
||||
* @return Pointer to the Composition data on success, or NULL on failure which means the Composition data is not initialized.
|
||||
*
|
||||
*/
|
||||
const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void);
|
||||
|
||||
/**
|
||||
* @brief A local model of node or Provisioner subscribes a group address.
|
||||
*
|
||||
* @note This function shall not be invoked before node is provisioned or Provisioner is enabled.
|
||||
*
|
||||
* @param[in] element_addr: Unicast address of the element to which the model belongs.
|
||||
* @param[in] company_id: A 16-bit company identifier.
|
||||
* @param[in] model_id: A 16-bit model identifier.
|
||||
* @param[in] group_addr: The group address to be subscribed.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_model_subscribe_group_addr(uint16_t element_addr, uint16_t company_id,
|
||||
uint16_t model_id, uint16_t group_addr);
|
||||
|
||||
/**
|
||||
* @brief A local model of node or Provisioner unsubscribes a group address.
|
||||
*
|
||||
* @note This function shall not be invoked before node is provisioned or Provisioner is enabled.
|
||||
*
|
||||
* @param[in] element_addr: Unicast address of the element to which the model belongs.
|
||||
* @param[in] company_id: A 16-bit company identifier.
|
||||
* @param[in] model_id: A 16-bit model identifier.
|
||||
* @param[in] group_addr: The subscribed group address.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_model_unsubscribe_group_addr(uint16_t element_addr, uint16_t company_id,
|
||||
uint16_t model_id, uint16_t group_addr);
|
||||
|
||||
/**
|
||||
* @brief This function is called by Node to get the local NetKey.
|
||||
*
|
||||
* @param[in] net_idx: NetKey index.
|
||||
*
|
||||
* @return NetKey on success, or NULL on failure.
|
||||
*
|
||||
*/
|
||||
const uint8_t *esp_ble_mesh_node_get_local_net_key(uint16_t net_idx);
|
||||
|
||||
/**
|
||||
* @brief This function is called by Node to get the local AppKey.
|
||||
*
|
||||
* @param[in] app_idx: AppKey index.
|
||||
*
|
||||
* @return AppKey on success, or NULL on failure.
|
||||
*
|
||||
*/
|
||||
const uint8_t *esp_ble_mesh_node_get_local_app_key(uint16_t app_idx);
|
||||
|
||||
/**
|
||||
* @brief This function is called by Node to add a local NetKey.
|
||||
*
|
||||
* @param[in] net_key: NetKey to be added.
|
||||
* @param[in] net_idx: NetKey Index.
|
||||
*
|
||||
* @note This function can only be called after the device is provisioned.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_node_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx);
|
||||
|
||||
/**
|
||||
* @brief This function is called by Node to add a local AppKey.
|
||||
*
|
||||
* @param[in] app_key: AppKey to be added.
|
||||
* @param[in] net_idx: NetKey Index.
|
||||
* @param[in] app_idx: AppKey Index.
|
||||
*
|
||||
* @note The net_idx must be an existing one.
|
||||
* This function can only be called after the device is provisioned.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_node_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx);
|
||||
|
||||
/**
|
||||
* @brief This function is called by Node to bind AppKey to model locally.
|
||||
*
|
||||
* @param[in] element_addr: Node local element address
|
||||
* @param[in] company_id: Node local company id
|
||||
* @param[in] model_id: Node local model id
|
||||
* @param[in] app_idx: Node local appkey index
|
||||
*
|
||||
* @note If going to bind app_key with local vendor model, the company_id
|
||||
* shall be set to 0xFFFF.
|
||||
* This function can only be called after the device is provisioned.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_mesh_node_bind_app_key_to_local_model(uint16_t element_addr, uint16_t company_id,
|
||||
uint16_t model_id, uint16_t app_idx);
|
||||
|
||||
/**
|
||||
* @brief This function used to enable directed forwarding and directed forwarding relay on self.
|
||||
*
|
||||
* @param[in] net_idx: NetKey Index.
|
||||
* @param[in] directed_forwarding: Enable or Disable directed forwarding.
|
||||
* @param[in] directed_forwarding_relay: Enable or Disable directed forwarding relay.
|
||||
*
|
||||
* @note If the directed forwarding was set to disable, the directed forwarding relay
|
||||
* must also be set to disable.
|
||||
*
|
||||
* @return ESP_OK on success or error code otherwise.
|
||||
*
|
||||
*/
|
||||
#if CONFIG_BLE_MESH_DF_SRV
|
||||
esp_err_t esp_ble_mesh_enable_directed_forwarding(uint16_t net_idx, bool directed_forwarding,
|
||||
bool directed_forwarding_relay);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user