From c8e79a926620e48830778714cfe4b2ea2453fcaf Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 25 Jul 2025 13:33:07 +1000 Subject: Update forked idf components --- lib/bt/host/nimble/Kconfig.in | 659 ++++-- lib/bt/host/nimble/esp-hci/src/esp_nimble_hci.c | 72 +- lib/bt/host/nimble/nimble/.travis.yml | 156 -- lib/bt/host/nimble/nimble/apps/blecent/src/main.c | 2 +- .../host/nimble/nimble/apps/bttester/src/atomic.h | 405 ---- .../nimble/nimble/apps/bttester/src/bttester.h | 1321 ------------ lib/bt/host/nimble/nimble/apps/bttester/src/gap.c | 1775 --------------- .../host/nimble/nimble/apps/bttester/src/gatt_cl.c | 1483 ------------- lib/bt/host/nimble/nimble/apps/bttester/src/glue.c | 129 -- lib/bt/host/nimble/nimble/apps/bttester/src/glue.h | 63 - .../host/nimble/nimble/apps/bttester/src/l2cap.c | 765 ------- lib/bt/host/nimble/nimble/apps/bttester/src/mesh.c | 993 --------- .../controller/include/controller/ble_ll_plna.h | 45 - .../controller/include/controller/ble_ll_test.h | 35 - .../nimble/nimble/controller/src/ble_ll_supp_cmd.c | 649 ------ .../nimble/controller/test/src/ble_ll_csa2_test.h | 27 - .../nimble/nimble/drivers/nrf52/include/ble/xcvr.h | 52 - .../nimble/nimble/drivers/nrf52/src/ble_hw.c | 511 ----- .../nimble/nimble/drivers/nrf52/src/ble_phy.c | 2257 -------------------- .../nimble/drivers/nrf52/src/ble_phy_trace.c | 44 - .../nimble/nimble/nimble/drivers/nrf52/syscfg.yml | 72 - .../nimble/drivers/nrf5340/include/ble/xcvr.h | 50 - .../nimble/nimble/drivers/nrf5340/src/ble_hw.c | 471 ---- .../nimble/nimble/drivers/nrf5340/src/ble_phy.c | 2038 ------------------ .../nimble/drivers/nrf5340/src/ble_phy_trace.c | 45 - .../nimble/nimble/drivers/nrf5340/syscfg.yml | 62 - .../nimble/nimble/drivers/plna/sky66112/pkg.yml | 31 - .../nimble/drivers/plna/sky66112/src/sky66112.c | 117 - .../nimble/nimble/drivers/plna/sky66112/syscfg.yml | 66 - .../nimble/nimble/host/include/host/ble_att.h | 9 +- .../nimble/nimble/host/include/host/ble_ead.h | 2 - .../nimble/nimble/host/include/host/ble_esp_gap.h | 38 + .../nimble/host/include/host/ble_esp_gattc_cache.h | 255 +++ .../nimble/nimble/host/include/host/ble_gap.h | 732 ++++++- .../nimble/nimble/host/include/host/ble_gatt.h | 87 +- .../nimble/nimble/host/include/host/ble_hs.h | 31 + .../nimble/nimble/host/include/host/ble_hs_adv.h | 28 +- .../nimble/nimble/host/include/host/ble_hs_pvcy.h | 2 +- .../nimble/nimble/host/include/host/ble_store.h | 34 + .../host/nimble/nimble/nimble/host/mesh/src/adv.c | 2 +- .../nimble/nimble/nimble/host/mesh/src/pb_adv.c | 13 +- .../nimble/nimble/host/mesh/src/prov_device.c | 4 +- lib/bt/host/nimble/nimble/nimble/host/pkg.yml | 3 + .../ans/include/services/ans/ble_svc_ans.h | 7 + .../nimble/host/services/ans/src/ble_svc_ans.c | 10 + .../bas/include/services/bas/ble_svc_bas.h | 8 + .../nimble/host/services/bas/src/ble_svc_bas.c | 2 + .../nimble/host/services/bleuart/src/bleuart.c | 2 + .../cte/include/services/cte/ble_svc_cte.h | 44 + .../nimble/nimble/nimble/host/services/cte/pkg.yml | 34 + .../nimble/host/services/cte/src/ble_svc_cte.c | 573 +++++ .../nimble/nimble/host/services/cte/syscfg.yml | 23 + .../cts/include/services/cts/ble_svc_cts.h | 8 + .../nimble/host/services/cts/src/ble_svc_cts.c | 3 +- .../dis/include/services/dis/ble_svc_dis.h | 34 + .../nimble/host/services/dis/src/ble_svc_dis.c | 53 + .../gap/include/services/gap/ble_svc_gap.h | 3 + .../nimble/host/services/gap/src/ble_svc_gap.c | 69 + .../gatt/include/services/gatt/ble_svc_gatt.h | 10 +- .../nimble/host/services/gatt/src/ble_svc_gatt.c | 24 + .../hid/include/services/hid/ble_svc_hid.h | 10 + .../nimble/host/services/hid/src/ble_svc_hid.c | 43 +- .../services/hr/include/services/hr/ble_svc_hr.h | 8 + .../nimble/host/services/hr/src/ble_svc_hr.c | 2 + .../htp/include/services/htp/ble_svc_htp.h | 8 + .../nimble/host/services/htp/src/ble_svc_htp.c | 2 + .../ias/include/services/ias/ble_svc_ias.h | 7 + .../nimble/host/services/ias/src/ble_svc_ias.c | 2 + .../nimble/host/services/ipss/src/ble_svc_ipss.c | 2 + .../nimble/host/services/lls/src/ble_svc_lls.c | 4 + .../prox/include/services/prox/ble_svc_prox.h | 8 + .../nimble/host/services/prox/src/ble_svc_prox.c | 2 + .../sps/include/services/sps/ble_svc_sps.h | 13 +- .../nimble/host/services/sps/src/ble_svc_sps.c | 15 +- .../tps/include/services/tps/ble_svc_tps.h | 7 + .../nimble/host/services/tps/src/ble_svc_tps.c | 2 + .../nimble/nimble/nimble/host/src/ble_aes_ccm.c | 23 +- .../host/nimble/nimble/nimble/host/src/ble_att.c | 238 ++- .../nimble/nimble/nimble/host/src/ble_att_clt.c | 184 +- .../nimble/nimble/nimble/host/src/ble_att_cmd.c | 55 +- .../nimble/nimble/host/src/ble_att_cmd_priv.h | 25 +- .../nimble/nimble/nimble/host/src/ble_att_priv.h | 115 +- .../nimble/nimble/nimble/host/src/ble_att_svr.c | 339 ++- .../host/nimble/nimble/nimble/host/src/ble_ead.c | 27 +- .../host/nimble/nimble/nimble/host/src/ble_eatt.c | 605 ++++++ .../nimble/nimble/nimble/host/src/ble_eatt_priv.h | 58 + .../host/nimble/nimble/nimble/host/src/ble_gap.c | 1815 ++++++++++++++-- .../nimble/nimble/nimble/host/src/ble_gap_priv.h | 17 + .../nimble/nimble/nimble/host/src/ble_gatt_priv.h | 46 +- .../host/nimble/nimble/nimble/host/src/ble_gattc.c | 1024 ++++++++- .../nimble/nimble/host/src/ble_gattc_cache.c | 77 +- .../nimble/nimble/host/src/ble_gattc_cache_conn.c | 886 +++++++- .../nimble/nimble/host/src/ble_gattc_cache_priv.h | 146 +- .../host/nimble/nimble/nimble/host/src/ble_gatts.c | 124 +- lib/bt/host/nimble/nimble/nimble/host/src/ble_hs.c | 57 +- .../nimble/nimble/nimble/host/src/ble_hs_adv.c | 37 + .../nimble/nimble/host/src/ble_hs_adv_priv.h | 2 - .../nimble/nimble/nimble/host/src/ble_hs_cfg.c | 4 + .../nimble/nimble/nimble/host/src/ble_hs_conn.c | 20 +- .../nimble/nimble/host/src/ble_hs_conn_priv.h | 7 + .../nimble/nimble/nimble/host/src/ble_hs_hci.c | 257 ++- .../nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c | 2 +- .../nimble/nimble/nimble/host/src/ble_hs_hci_evt.c | 333 ++- .../nimble/nimble/host/src/ble_hs_hci_priv.h | 6 + .../host/nimble/nimble/nimble/host/src/ble_hs_id.c | 2 + .../nimble/nimble/nimble/host/src/ble_hs_priv.h | 1 + .../nimble/nimble/nimble/host/src/ble_hs_pvcy.c | 4 +- .../nimble/nimble/nimble/host/src/ble_hs_resolv.c | 14 +- .../nimble/nimble/nimble/host/src/ble_hs_startup.c | 80 +- .../host/nimble/nimble/nimble/host/src/ble_l2cap.c | 28 +- .../nimble/nimble/nimble/host/src/ble_l2cap_coc.c | 6 +- .../nimble/nimble/nimble/host/src/ble_l2cap_priv.h | 15 + .../nimble/nimble/nimble/host/src/ble_l2cap_sig.c | 38 +- .../nimble/nimble/host/src/ble_l2cap_sig_priv.h | 4 +- lib/bt/host/nimble/nimble/nimble/host/src/ble_sm.c | 214 +- .../nimble/nimble/nimble/host/src/ble_sm_alg.c | 28 +- .../nimble/nimble/nimble/host/src/ble_sm_cmd.c | 6 +- .../host/nimble/nimble/nimble/host/src/ble_store.c | 62 +- .../nimble/nimble/nimble/host/src/ble_store_util.c | 9 + .../host/store/config/src/ble_store_config.c | 150 +- .../host/store/config/src/ble_store_config_conf.c | 39 + .../host/store/config/src/ble_store_config_priv.h | 6 + .../nimble/host/store/config/src/ble_store_nvs.c | 80 +- .../nimble/host/store/ram/src/ble_store_ram.c | 132 +- lib/bt/host/nimble/nimble/nimble/host/syscfg.yml | 37 + .../nimble/nimble/host/test/src/ble_att_clt_test.c | 53 +- .../nimble/nimble/host/test/src/ble_att_svr_test.c | 27 +- .../nimble/host/test/src/ble_gatt_conn_test.c | 36 + .../nimble/host/test/src/ble_gatt_disc_c_test.c | 32 +- .../nimble/host/test/src/ble_gatt_disc_d_test.c | 24 +- .../nimble/host/test/src/ble_gatt_disc_s_test.c | 52 +- .../nimble/host/test/src/ble_gatt_find_s_test.c | 37 +- .../nimble/host/test/src/ble_gatt_read_test.c | 44 +- .../nimble/host/test/src/ble_gatt_write_test.c | 73 +- .../nimble/nimble/host/test/src/ble_hs_pvcy_test.c | 6 +- .../nimble/nimble/host/test/src/ble_hs_test_util.c | 9 +- .../nimble/nimble/host/test/src/ble_hs_test_util.h | 6 +- .../nimble/host/test/src/ble_hs_test_util_hci.c | 13 + .../nimble/nimble/host/test/src/ble_os_test.c | 2 +- .../host/nimble/nimble/nimble/host/test/syscfg.yml | 1 + .../host/nimble/nimble/nimble/include/nimble/ble.h | 1 + .../nimble/nimble/include/nimble/hci_common.h | 288 ++- .../nimble/nimble/include/nimble/nimble_opt_auto.h | 4 + .../transport/dialog_cmac/cmac_driver/diag/pkg.yml | 28 - .../dialog_cmac/cmac_driver/diag/src/cmac_diag.c | 66 - .../cmac_driver/include/cmac_driver/cmac_diag.h | 34 - .../cmac_driver/include/cmac_driver/cmac_host.h | 35 - .../cmac_driver/include/cmac_driver/cmac_shared.h | 194 -- .../transport/dialog_cmac/cmac_driver/pkg.yml | 39 - .../cmac_driver/scripts/build_libcmac.sh | 45 - .../cmac_driver/scripts/create_cmac_bin.sh | 31 - .../dialog_cmac/cmac_driver/src/cmac_host.c | 375 ---- .../dialog_cmac/cmac_driver/src/cmac_mbox.c | 174 -- .../dialog_cmac/cmac_driver/src/cmac_rand.c | 145 -- .../dialog_cmac/cmac_driver/src/cmac_shared.c | 96 - .../transport/dialog_cmac/cmac_driver/syscfg.yml | 104 - .../nimble/transport/esp_ipc/src/hci_esp_ipc.c | 71 + .../esp_ipc_legacy/src/hci_esp_ipc_legacy.c | 39 + .../nimble/transport/include/nimble/transport.h | 158 +- .../transport/include/nimble/transport_impl.h | 2 + .../nimble/nimble/transport/nrf5340/syscfg.yml | 20 - .../nimble/nimble/transport/uart_ll/src/hci_uart.c | 10 + .../porting/examples/linux/include/logcfg/logcfg.h | 7 + .../porting/examples/linux/include/syscfg/syscfg.h | 24 + .../examples/linux_blemesh/include/logcfg/logcfg.h | 7 + .../examples/linux_blemesh/include/syscfg/syscfg.h | 24 + .../porting/examples/nuttx/include/syscfg/syscfg.h | 4 + .../nimble/porting/nimble/include/hal/hal_uart.h | 5 + .../nimble/porting/nimble/include/logcfg/logcfg.h | 7 + .../nimble/nimble/porting/nimble/include/os/os.h | 8 - .../nimble/porting/nimble/include/syscfg/syscfg.h | 24 + .../nimble/nimble/porting/nimble/src/hal_uart.c | 8 + .../nimble/nimble/porting/nimble/src/nimble_port.c | 13 +- .../nimble/nimble/porting/nimble/src/os_mbuf.c | 14 + .../nimble/nimble/porting/nimble/src/os_mempool.c | 1 + .../freertos/include/nimble/nimble_port_freertos.h | 1 + .../porting/npl/freertos/src/npl_os_freertos.c | 38 +- .../porting/npl/riot/include/logcfg/logcfg.h | 7 + .../npl/riot/include/npl_syscfg/npl_sycfg.h | 1991 ++++++++++++++++- .../porting/npl/riot/include/syscfg/syscfg.h | 24 + lib/bt/host/nimble/nimble/sbom.yml | 2 +- lib/bt/host/nimble/port/include/esp_nimble_cfg.h | 272 ++- 182 files changed, 12436 insertions(+), 16580 deletions(-) delete mode 100644 lib/bt/host/nimble/nimble/.travis.yml delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/atomic.h delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/bttester.h delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/gap.c delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/gatt_cl.c delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/glue.c delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/glue.h delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/l2cap.c delete mode 100644 lib/bt/host/nimble/nimble/apps/bttester/src/mesh.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_plna.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_test.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/controller/src/ble_ll_supp_cmd.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/controller/test/src/ble_ll_csa2_test.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf52/include/ble/xcvr.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_hw.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy_trace.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf52/syscfg.yml delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/include/ble/xcvr.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_hw.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy_trace.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/syscfg.yml delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/pkg.yml delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/src/sky66112.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/syscfg.yml create mode 100644 lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gattc_cache.h create mode 100644 lib/bt/host/nimble/nimble/nimble/host/services/cte/include/services/cte/ble_svc_cte.h create mode 100644 lib/bt/host/nimble/nimble/nimble/host/services/cte/pkg.yml create mode 100644 lib/bt/host/nimble/nimble/nimble/host/services/cte/src/ble_svc_cte.c create mode 100644 lib/bt/host/nimble/nimble/nimble/host/services/cte/syscfg.yml create mode 100644 lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt.c create mode 100644 lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt_priv.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/pkg.yml delete mode 100755 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh delete mode 100755 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml create mode 100644 lib/bt/host/nimble/nimble/nimble/transport/esp_ipc/src/hci_esp_ipc.c create mode 100644 lib/bt/host/nimble/nimble/nimble/transport/esp_ipc_legacy/src/hci_esp_ipc_legacy.c delete mode 100644 lib/bt/host/nimble/nimble/nimble/transport/nrf5340/syscfg.yml mode change 120000 => 100644 lib/bt/host/nimble/nimble/porting/npl/riot/include/npl_syscfg/npl_sycfg.h (limited to 'lib/bt/host/nimble') diff --git a/lib/bt/host/nimble/Kconfig.in b/lib/bt/host/nimble/Kconfig.in index d02293a8..3ea05578 100644 --- a/lib/bt/host/nimble/Kconfig.in +++ b/lib/bt/host/nimble/Kconfig.in @@ -65,7 +65,7 @@ config BT_NIMBLE_LOG_LEVEL config BT_NIMBLE_MAX_CONNECTIONS int "Maximum number of concurrent connections" range 1 2 if IDF_TARGET_ESP32C2 - range 1 70 if IDF_TARGET_ESP32C6 + range 1 70 if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61 range 1 35 if IDF_TARGET_ESP32H2 range 1 9 default 2 if IDF_TARGET_ESP32C2 @@ -100,6 +100,14 @@ config BT_NIMBLE_L2CAP_COC_MAX_NUM help Defines maximum number of BLE Connection Oriented Channels. When set to (0), BLE COC is not compiled in +config BT_NIMBLE_L2CAP_ENHANCED_COC + bool "L2CAP Enhanced Connection Oriented Channel" + depends on BT_NIMBLE_ENABLED && (BT_NIMBLE_L2CAP_COC_MAX_NUM >= 1) + default 0 + help + Enable Enhanced Credit Based Flow Control Mode + + choice BT_NIMBLE_PINNED_TO_CORE_CHOICE prompt "The CPU core on which NimBLE host will run" depends on BT_NIMBLE_ENABLED && !FREERTOS_UNICORE @@ -148,7 +156,7 @@ config BT_NIMBLE_ROLE_BROADCASTER depends on BT_NIMBLE_ENABLED default y help - Enables broadcaster role + Enables broadcaster role config BT_NIMBLE_ROLE_OBSERVER bool "Enable BLE Observer role" @@ -157,6 +165,20 @@ config BT_NIMBLE_ROLE_OBSERVER help Enables observer role +config BT_NIMBLE_GATT_CLIENT + bool "Enable BLE GATT Client support" + depends on BT_NIMBLE_ROLE_CENTRAL + default y + help + Enables support for GATT Client + +config BT_NIMBLE_GATT_SERVER + bool "Enable BLE GATT Server support" + depends on BT_NIMBLE_ROLE_PERIPHERAL + default y + help + Enables support for GATT Server + config BT_NIMBLE_NVS_PERSIST bool "Persist the BLE Bonding keys in NVS" depends on BT_NIMBLE_ENABLED @@ -164,6 +186,16 @@ config BT_NIMBLE_NVS_PERSIST help Enable this flag to make bonding persistent across device reboots +config BT_NIMBLE_SMP_ID_RESET + bool "Reset device identity when all bonding records are deleted" + default n + help + There are tracking risks associated with using a fixed or static IRK. + If enabled this option, NimBLE will assign a new randomly-generated IRK + when all pairing and bonding records are deleted. This would decrease the ability + of a previously paired peer to be used to determine whether a device + with which it previously shared an IRK is within range. + menuconfig BT_NIMBLE_SECURITY_ENABLE bool "Enable BLE SM feature" depends on BT_NIMBLE_ENABLED @@ -212,6 +244,20 @@ config BT_NIMBLE_SM_LVL 3. Authenticated pairing with encryption 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key. +config BT_NIMBLE_SM_SC_ONLY + int "Enable Secure Connections Only Mode" + depends on BT_NIMBLE_SECURITY_ENABLE + default 0 + help + Enable Secure Connections Only Mode + +config BT_NIMBLE_PRINT_ERR_NAME + bool "Enable feature to print Error description" + depends on BT_NIMBLE_ENABLED + default y + help + Enable feature to give useful explanation for HCI errors + config BT_NIMBLE_DEBUG bool "Enable extra runtime asserts and host debugging" default n @@ -249,6 +295,13 @@ config BT_NIMBLE_ATT_PREFERRED_MTU This is the default value of ATT MTU indicated by the device during an ATT MTU exchange. This value can be changed using API ble_att_set_preferred_mtu() +config BT_NIMBLE_ATT_MAX_PREP_ENTRIES + int "Max Prepare write entries" + depends on BT_NIMBLE_ENABLED + default 64 + help + This is the default value of ATT Maximum prepare entries + config BT_NIMBLE_SVC_GAP_APPEARANCE hex "External appearance of the device" depends on BT_NIMBLE_ENABLED @@ -359,7 +412,7 @@ config BT_NIMBLE_GATT_MAX_PROCS config BT_NIMBLE_HS_FLOW_CTRL bool "Enable Host Flow control" - depends on BT_NIMBLE_ENABLED + depends on BT_NIMBLE_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER default y if IDF_TARGET_ESP32 default n help @@ -534,6 +587,16 @@ config BT_NIMBLE_MAX_CONN_REATTEMPT help Defines maximum number of connection reattempts. +config BT_NIMBLE_HANDLE_REPEAT_PAIRING_DELETION + bool "Enable stack handling of repeat pairing" + default n + depends on BT_NIMBLE_ENABLED + help + Use this option to let stack internally handle the request for repeat pairing. + Enabling this option will delete the pairing of the device and stack will NOT post any event + to application. If this option is disabled, application will get BLE_GAP_EVENT_REPEAT_PAIRING + event. + menuconfig BT_NIMBLE_50_FEATURE_SUPPORT bool "Enable BLE 5 feature" depends on BT_NIMBLE_ENABLED && (SOC_BLE_50_SUPPORTED || !BT_CONTROLLER_ENABLED) @@ -541,111 +604,162 @@ menuconfig BT_NIMBLE_50_FEATURE_SUPPORT help Enable BLE 5 feature -config BT_NIMBLE_LL_CFG_FEAT_LE_2M_PHY - bool "Enable 2M Phy" - depends on BT_NIMBLE_50_FEATURE_SUPPORT - default y - help - Enable 2M-PHY - -config BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY - bool "Enable coded Phy" - depends on BT_NIMBLE_50_FEATURE_SUPPORT - default y - help - Enable coded-PHY - -config BT_NIMBLE_EXT_ADV - bool "Enable extended advertising" - depends on BT_NIMBLE_50_FEATURE_SUPPORT - default n - help - Enable this option to do extended advertising. Extended advertising - will be supported from BLE 5.0 onwards. +if BT_NIMBLE_50_FEATURE_SUPPORT + config BT_NIMBLE_LL_CFG_FEAT_LE_2M_PHY + bool "Enable 2M Phy" + depends on BT_NIMBLE_50_FEATURE_SUPPORT + default y + help + Enable 2M-PHY -if BT_NIMBLE_EXT_ADV - config BT_NIMBLE_MAX_EXT_ADV_INSTANCES - int "Maximum number of extended advertising instances." - range 0 4 - default 1 if BT_NIMBLE_EXT_ADV - default 0 - depends on BT_NIMBLE_EXT_ADV + config BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY + bool "Enable coded Phy" + depends on BT_NIMBLE_50_FEATURE_SUPPORT + default y 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. - For ESP32C2, ESP32C6 and ESP32H2, each extended advertising instance - will take about 0.5k DRAM. - - config BT_NIMBLE_EXT_ADV_MAX_SIZE - int "Maximum length of the advertising data." - range 0 1650 - default 1650 if BT_NIMBLE_EXT_ADV - default 0 - depends on BT_NIMBLE_EXT_ADV + Enable coded-PHY + + config BT_NIMBLE_EXT_ADV + bool "Enable extended advertising" + depends on BT_NIMBLE_50_FEATURE_SUPPORT + default n help - Defines the length of the extended adv data. The value should not - exceed 1650. + Enable this option to do extended advertising. Extended advertising + will be supported from BLE 5.0 onwards. - config BT_NIMBLE_ENABLE_PERIODIC_ADV - bool "Enable periodic advertisement." + if BT_NIMBLE_EXT_ADV + config BT_NIMBLE_EXT_ADV_V2 + bool "Enable support for extended adv v2" + default n + depends on BT_NIMBLE_EXT_ADV + help + Enable this option to use Extended Adv V2 command instead of V1. + + config BT_NIMBLE_MAX_EXT_ADV_INSTANCES + int "Maximum number of extended advertising instances." + range 0 4 + default 1 if BT_NIMBLE_EXT_ADV + default 0 + depends on BT_NIMBLE_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. + For ESP32C2, ESP32C6 and ESP32H2, each extended advertising instance + will take about 0.5k DRAM. + + config BT_NIMBLE_EXT_ADV_MAX_SIZE + int "Maximum length of the advertising data." + range 0 1650 + default 1650 if BT_NIMBLE_EXT_ADV + default 0 + depends on BT_NIMBLE_EXT_ADV + help + Defines the length of the extended adv data. The value should not + exceed 1650. + + config BT_NIMBLE_ENABLE_PERIODIC_ADV + bool "Enable periodic advertisement." + default y + depends on BT_NIMBLE_EXT_ADV + help + Enable this option to start periodic advertisement. + + config BT_NIMBLE_PERIODIC_ADV_ENH + bool "Periodic adv enhancements(adi support)" + depends on BT_NIMBLE_ENABLE_PERIODIC_ADV && SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED + help + Enable the periodic advertising enhancements + + config BT_NIMBLE_PERIODIC_ADV_SYNC_TRANSFER + bool "Enable Transfer Sync Events" + depends on BT_NIMBLE_ENABLE_PERIODIC_ADV + default y + help + This enables controller transfer periodic sync events to host + + config BT_NIMBLE_PERIODIC_ADV_WITH_RESPONSES + bool "Enable Periodic Advertisement with Response (EXPERIMENTAL)" + depends on BT_NIMBLE_ENABLE_PERIODIC_ADV + default n + help + This enables controller PAwR (Periodic Advertisement with Response). + endif + + config BT_NIMBLE_EXT_SCAN + bool "Enable extended scanning" + depends on BT_NIMBLE_50_FEATURE_SUPPORT && BT_NIMBLE_ROLE_OBSERVER default y - depends on BT_NIMBLE_EXT_ADV help - Enable this option to start periodic advertisement. + Enable this option to do extended scanning. - config BT_NIMBLE_PERIODIC_ADV_SYNC_TRANSFER - bool "Enable Transfer Sync Events" - depends on BT_NIMBLE_ENABLE_PERIODIC_ADV + config BT_NIMBLE_ENABLE_PERIODIC_SYNC + bool "Enable periodic sync" default y + depends on BT_NIMBLE_EXT_SCAN help - This enables controller transfer periodic sync events to host -endif - -config BT_NIMBLE_MAX_PERIODIC_SYNCS - int "Maximum number of periodic advertising syncs" - depends on BT_NIMBLE_50_FEATURE_SUPPORT - range 0 3 if IDF_TARGET_ESP32C2 - range 0 8 - default 1 if BT_NIMBLE_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_NIMBLE_MAX_PERIODIC_ADVERTISER_LIST - int "Maximum number of periodic advertiser list" - depends on BT_NIMBLE_50_FEATURE_SUPPORT && SOC_ESP_NIMBLE_CONTROLLER - range 1 5 - default 5 if BT_NIMBLE_50_FEATURE_SUPPORT - help - Set this option to set the upper limit for number of periodic advertiser list. + Enable this option to receive periodic advertisement. + + if BT_NIMBLE_ENABLE_PERIODIC_SYNC + config BT_NIMBLE_MAX_PERIODIC_SYNCS + int "Maximum number of periodic advertising syncs" + range 0 3 if IDF_TARGET_ESP32C2 + range 0 8 + default 1 if BT_NIMBLE_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_NIMBLE_MAX_PERIODIC_ADVERTISER_LIST + int "Maximum number of periodic advertiser list" + depends on SOC_ESP_NIMBLE_CONTROLLER + range 1 5 + default 5 if BT_NIMBLE_50_FEATURE_SUPPORT + help + Set this option to set the upper limit for number of periodic advertiser list. + endif -config BT_NIMBLE_BLE_POWER_CONTROL - bool "Enable support for BLE Power Control" - depends on BT_NIMBLE_50_FEATURE_SUPPORT && SOC_BLE_POWER_CONTROL_SUPPORTED - default n - help - Set this option to enable the Power Control feature + config BT_NIMBLE_BLE_POWER_CONTROL + bool "Enable support for BLE Power Control" + depends on BT_NIMBLE_50_FEATURE_SUPPORT && SOC_BLE_POWER_CONTROL_SUPPORTED + default n + help + Set this option to enable the Power Control feature -config BT_NIMBLE_PERIODIC_ADV_ENH - bool "Periodic adv enhancements(adi support)" - depends on BT_NIMBLE_ENABLE_PERIODIC_ADV && BT_NIMBLE_50_FEATURE_SUPPORT && SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED - help - Enable the periodic advertising enhancements + config BT_NIMBLE_AOA_AOD + bool "Direction Finding" + depends on BT_NIMBLE_50_FEATURE_SUPPORT && (BT_CONTROLLER_DISABLED || SOC_BLE_CTE_SUPPORTED) + default n + help + Enable support for Connectionless and Connection Oriented Direction Finding +endif menuconfig BT_NIMBLE_GATT_CACHING bool "Enable GATT caching" - depends on BT_NIMBLE_ENABLED && BT_NIMBLE_50_FEATURE_SUPPORT + depends on BT_NIMBLE_ENABLED select BT_NIMBLE_DYNAMIC_SERVICE help Enable GATT caching +config BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + bool "Include services in GATT caching" + depends on BT_NIMBLE_GATT_CACHING + default n + help + Enable this option to include *included services* (e.g., services referenced by other services) + in the GATT database cache. Disabling this will skip caching of included service entries. +config BT_NIMBLE_INCL_SVC_DISCOVERY + bool "Enable Included service discovery" + default y if BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + default n + help + Enable this option to start discovery for included service. config BT_NIMBLE_GATT_CACHING_MAX_CONNS int "Maximum connections to be cached" depends on BT_NIMBLE_GATT_CACHING - default 1 + default BT_NIMBLE_MAX_CONNECTIONS help Set this option to set the upper limit on number of connections to be cached. config BT_NIMBLE_GATT_CACHING_MAX_SVCS @@ -654,6 +768,12 @@ config BT_NIMBLE_GATT_CACHING_MAX_SVCS default 64 help Set this option to set the upper limit on number of services per connection to be cached. +config BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS + int "Maximum number of included services per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of included services per connection to be cached. config BT_NIMBLE_GATT_CACHING_MAX_CHRS int "Maximum number of characteristics per connection" depends on BT_NIMBLE_GATT_CACHING @@ -666,14 +786,22 @@ config BT_NIMBLE_GATT_CACHING_MAX_DSCS default 64 help Set this option to set the upper limit on number of descriptors per connection to be cached. +config BT_NIMBLE_GATT_CACHING_DISABLE_AUTO + bool "Do not start discovery procedure automatically upon receiving Out of Sync" + depends on BT_NIMBLE_GATT_CACHING + default n + help + When client receives ATT out-of-sync error message, it will not automatically start the discovery procedure + to correct the invalid cache. config BT_NIMBLE_WHITELIST_SIZE int "BLE white list size" depends on BT_NIMBLE_ENABLED + range 1 31 if SOC_ESP_NIMBLE_CONTROLLER range 1 15 default 12 help - BLE list size + BLE list size config BT_NIMBLE_TEST_THROUGHPUT_TEST bool "Throughput Test Mode enable" @@ -707,8 +835,172 @@ config BT_NIMBLE_BLE_GATT_BLOB_TRANSFER This option is used when data to be sent is more than 512 bytes. For peripheral role, BT_NIMBLE_MSYS_1_BLOCK_COUNT needs to be increased according to the need. -menu "GAP Service" +menu "BLE Services" + depends on BT_NIMBLE_GATT_SERVER + + config BT_NIMBLE_PROX_SERVICE + bool "Proximity service" + default y + help + Enable Proximity Service support + + config BT_NIMBLE_ANS_SERVICE + bool "Alert Notification service" + default y + help + Enable Alert Notification Service support + + config BT_NIMBLE_CTS_SERVICE + bool "Current Time Service" + default y + help + Enable Current Time Service support + + config BT_NIMBLE_HTP_SERVICE + bool "Health Thermometer service" + default y + help + Enable Health Thermometer Service support + + config BT_NIMBLE_IPSS_SERVICE + bool "Internet Protocol Support service" + default y + help + Enable Internet Protocol Service support + + config BT_NIMBLE_TPS_SERVICE + bool "Tx Power service" + default y + help + Enable Tx Power Service support + + config BT_NIMBLE_IAS_SERVICE + bool "Immediate Alert service" + default y + help + Enable Immediate Alert Service support + + config BT_NIMBLE_LLS_SERVICE + bool "Link Loss service" + default y + help + Enable Link Loss Service support + + config BT_NIMBLE_SPS_SERVICE + bool "Serial Port service" + default y + help + Enable Serial Port Service support + + config BT_NIMBLE_HR_SERVICE + bool "Heart Rate service" + default y + help + Enable HeartRate Service support + + menuconfig BT_NIMBLE_HID_SERVICE + bool "HID service" + default n + help + Enable HID service support + + config BT_NIMBLE_SVC_HID_MAX_INSTANCES + depends on BT_NIMBLE_HID_SERVICE + int "Maximum HID service instances" + default 2 + help + Defines maximum number of HID service instances + + config BT_NIMBLE_SVC_HID_MAX_RPTS + depends on BT_NIMBLE_HID_SERVICE + int "Maximum HID Report characteristics per service instance" + default 3 + help + Defines maximum number of report characteristics per service instance + + menuconfig BT_NIMBLE_BAS_SERVICE + bool "Battery service" + default y + help + Enable Battery service support + + config BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY + depends on BT_NIMBLE_BAS_SERVICE + bool "BAS Battery Level NOTIFY permission" + help + Enable/Disable notifications on BAS Battery Level Characteristic + + menuconfig BT_NIMBLE_DIS_SERVICE + bool "DIS service" + default y + help + Enable DIS service support + + config BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME + depends on BT_NIMBLE_DIS_SERVICE + bool "Manufacturer Name" + default n + help + Enable the DIS characteristic Manufacturer Name String characteristic + + config BT_NIMBLE_SVC_DIS_SERIAL_NUMBER + depends on BT_NIMBLE_DIS_SERVICE + bool "Serial Number" + default n + help + Enable the DIS Serial Number characteristic + + config BT_NIMBLE_SVC_DIS_HARDWARE_REVISION + depends on BT_NIMBLE_DIS_SERVICE + bool "Hardware Revision" + default n + help + Enable the DIS Hardware Revision characteristic + + config BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION + depends on BT_NIMBLE_DIS_SERVICE + bool "Firmware Revision" + default n + help + Enable the DIS Firmware Revision characteristic + + config BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION + depends on BT_NIMBLE_DIS_SERVICE + bool "Software Revision" + default n + help + Enable the DIS Software Revision characteristic + + config BT_NIMBLE_SVC_DIS_SYSTEM_ID + depends on BT_NIMBLE_DIS_SERVICE + bool "System ID" + default n + help + Enable the DIS System ID characteristic + + config BT_NIMBLE_SVC_DIS_PNP_ID + depends on BT_NIMBLE_DIS_SERVICE + bool "PnP ID" + default n + help + Enable the DIS PnP ID characteristic + + config BT_NIMBLE_SVC_DIS_INCLUDED + depends on BT_NIMBLE_DIS_SERVICE + bool "DIS as an Included Service" + default n + help + Use DIS as an included service + + menuconfig BT_NIMBLE_GAP_SERVICE + bool "GAP Service" + default y + help + Enable GAP Service support + menu "GAP Appearance write permissions" + depends on BT_NIMBLE_GAP_SERVICE + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE bool "Write" default n @@ -718,14 +1010,12 @@ menu "GAP Service" config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC depends on BT_NIMBLE_SVC_GAP_APPEAR_WRITE bool "Write with encryption" - default n help Enable write with encryption permission (BLE_GATT_CHR_F_WRITE_ENC) config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN depends on BT_NIMBLE_SVC_GAP_APPEAR_WRITE bool "Write with authentication" - default n help Enable write with authentication permission (BLE_GATT_CHR_F_WRITE_AUTHEN) @@ -735,48 +1025,49 @@ menu "GAP Service" default n help Enable write with authorisation permission (BLE_GATT_CHR_F_WRITE_AUTHOR) - endmenu - config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM - int - default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE - default 8 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE - - config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC - int - default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC - default 4096 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC - - config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN - int - default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN - default 8192 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN - - config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR - int - default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHOR - default 16384 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHOR + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE + default 8 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC + default 4096 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN + default 8192 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHOR + default 16384 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHOR + endmenu choice BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION prompt "GAP Characteristic - Central Address Resolution" + depends on BT_NIMBLE_GAP_SERVICE default BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP help - Weather or not Central Address Resolution characteristic is supported on - the device, and if supported, weather or not Central Address Resolution - is supported. + Weather or not Central Address Resolution characteristic is supported on + the device, and if supported, weather or not Central Address Resolution + is supported. - - Central Address Resolution characteristic not supported - - Central Address Resolution not supported - - Central Address Resolution supported + - Central Address Resolution characteristic not supported + - Central Address Resolution not supported + - Central Address Resolution supported - config BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP - bool "Characteristic not supported" + config BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP + bool "Characteristic not supported" - config BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP - bool "Central Address Resolution not supported" + config BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP + bool "Central Address Resolution not supported" - config BT_NIMBLE_SVC_GAP_CAR_SUPP - bool "Central Address Resolution supported" + config BT_NIMBLE_SVC_GAP_CAR_SUPP + bool "Central Address Resolution supported" endchoice config BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION @@ -785,7 +1076,9 @@ menu "GAP Service" default 0 if BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP default 1 if BT_NIMBLE_SVC_GAP_CAR_SUPP + menu "GAP device name write permissions" + depends on BT_NIMBLE_GAP_SERVICE config BT_NIMBLE_SVC_GAP_NAME_WRITE bool "Write" default n @@ -814,6 +1107,40 @@ menu "GAP Service" Enable write with authorisation permission (BLE_GATT_CHR_F_WRITE_AUTHOR) endmenu + menu "PPCP settings" + depends on BT_NIMBLE_GAP_SERVICE + config BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL + int "PPCP Connection Interval Max (Unit: 1.25 ms)" + depends on BT_NIMBLE_ROLE_PERIPHERAL && BT_NIMBLE_GAP_SERVICE + default 0 + help + Peripheral Preferred Connection Parameter: Connection Interval maximum value + Interval Max = value * 1.25 ms + + config BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL + int "PPCP Connection Interval Min (Unit: 1.25 ms)" + depends on BT_NIMBLE_ROLE_PERIPHERAL && BT_NIMBLE_GAP_SERVICE + default 0 + help + Peripheral Preferred Connection Parameter: Connection Interval minimum value + Interval Min = value * 1.25 ms + + config BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY + int "PPCP Slave Latency" + depends on BT_NIMBLE_GAP_SERVICE + default 0 + help + Peripheral Preferred Connection Parameter: Slave Latency + + config BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO + int "PPCP Supervision Timeout (Uint: 10 ms)" + depends on BT_NIMBLE_GAP_SERVICE + default 0 + help + Peripheral Preferred Connection Parameter: Supervision Timeout + Timeout = Value * 10 ms + endmenu + config BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM int default 0 if !BT_NIMBLE_SVC_GAP_NAME_WRITE @@ -834,58 +1161,18 @@ menu "GAP Service" default 0 if !BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHOR default 16384 if BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHOR - config BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL - int "PPCP Connection Interval Max (Unit: 1.25 ms)" - depends on BT_NIMBLE_ROLE_PERIPHERAL - default 0 - help - Peripheral Preferred Connection Parameter: Connection Interval maximum value - Interval Max = value * 1.25 ms - - config BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL - int "PPCP Connection Interval Min (Unit: 1.25 ms)" - depends on BT_NIMBLE_ROLE_PERIPHERAL - default 0 - help - Peripheral Preferred Connection Parameter: Connection Interval minimum value - Interval Min = value * 1.25 ms - - config BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY - int "PPCP Slave Latency" - default 0 - help - Peripheral Preferred Connection Parameter: Slave Latency - - config BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO - int "PPCP Supervision Timeout (Uint: 10 ms)" - default 0 - help - Peripheral Preferred Connection Parameter: Supervision Timeout - Timeout = Value * 10 ms - -endmenu - -menu "BLE Services" - menuconfig BT_NIMBLE_HID_SERVICE - bool "HID service" - depends on BT_NIMBLE_ENABLED + config BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL + bool "LE GATT Security Level Characteristic" default n help - Enable HID service support + Enable the LE GATT Security Level Characteristic - config BT_NIMBLE_SVC_HID_MAX_INSTANCES - depends on BT_NIMBLE_HID_SERVICE - int "Maximum HID service instances" - default 2 + config BT_NIMBLE_SVC_GAP_RPA_ONLY + bool "Resolvable Private Address Only characteristic" + default n help - Defines maximum number of HID service instances + Enable the Resolvable Private Address Only characteristic - config BT_NIMBLE_SVC_HID_MAX_RPTS - depends on BT_NIMBLE_HID_SERVICE - int "Maximum HID Report characteristics per service instance" - default 3 - help - Defines maximum number of report characteristics per service instance endmenu config BT_NIMBLE_VS_SUPPORT @@ -906,7 +1193,6 @@ config BT_NIMBLE_OPTIMIZE_MULTI_CONN config BT_NIMBLE_ENC_ADV_DATA bool "Encrypted Advertising Data" - select BT_NIMBLE_EXT_ADV help This option is used to enable encrypted advertising data. @@ -923,6 +1209,12 @@ config BT_NIMBLE_HIGH_DUTY_ADV_ITVL help This enable BLE high duty advertising interval feature +config BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN + bool "Allow Connections with scanning in progress" + depends on BT_NIMBLE_ENABLED && !(IDF_TARGET_ESP32C2) + help + This enables support for user to initiate a new connection with scan in progress + config BT_NIMBLE_HOST_QUEUE_CONG_CHECK bool "BLE queue congestion check" depends on BT_NIMBLE_ENABLED @@ -932,6 +1224,15 @@ config BT_NIMBLE_HOST_QUEUE_CONG_CHECK or application layer handling adv packets is slow, it will cause the controller memory to run out. if enabled, adv packets will be lost when host queue is congested. +config BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT + bool "Gatt-proc preemption protect check" + depends on BT_NIMBLE_ENABLED + default n + help + When BLE and Wireless protocol/IEEE 802.15.4 operate in coexistence, BLE preemption + can disrupt the GATT context,causing the service discovery callback to not be invoked. + A temporary list is maintained to preserve the GATT context and use it in case of preemption. + menu "Host-controller Transport" config BT_NIMBLE_TRANSPORT_UART bool "Enable Uart Transport" @@ -1048,3 +1349,17 @@ menu "Host-controller Transport" help UART HCI CTS pin endmenu + +config BT_NIMBLE_EATT_CHAN_NUM + int "Maximum number of EATT channels" + default 0 + depends on BT_NIMBLE_ENABLED + help + Defines the number of channels EATT bearers can use + +config BT_NIMBLE_SUBRATE + bool "Enable Subrate Change" + default n + depends on BT_NIMBLE_ENABLED + help + Enable connection subrate change feature diff --git a/lib/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/lib/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index 605b8312..59e574ec 100644 --- a/lib/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/lib/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,6 +21,12 @@ #include "freertos/semphr.h" #include "esp_compiler.h" #include "soc/soc_caps.h" +#include "bt_common.h" +#include "hci_log/bt_hci_log.h" + +#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED #define NIMBLE_VHCI_TIMEOUT_MS 2000 #define BLE_HCI_EVENT_HDR_LEN (2) @@ -61,6 +67,16 @@ void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, ble_hci_rx_acl_hs_arg = acl_arg; } +void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(data[0], &data[1], len - 1); +#endif +#if (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len); +#endif // (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + esp_vhci_host_send_packet(data, len); +} int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) { @@ -75,7 +91,7 @@ int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) } if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { - esp_vhci_host_send_packet(cmd, len); + esp_vhci_host_send_packet_wrapper(cmd, len); } else { rc = BLE_HS_ETIMEOUT_HCI; } @@ -112,7 +128,7 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) len += OS_MBUF_PKTLEN(om); if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { - esp_vhci_host_send_packet(data, len); + esp_vhci_host_send_packet_wrapper(data, len); } else { rc = BLE_HS_ETIMEOUT_HCI; } @@ -154,14 +170,14 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len) m = ble_transport_alloc_acl_from_ll(); if (!m) { - ESP_LOGD(TAG,"Failed to allocate buffer, retrying "); + esp_rom_printf("Failed to allocate buffer, retrying "); /* Give some time to free buffer and try again */ vTaskDelay(1); } }while(!m); if ((rc = os_mbuf_append(m, data, len)) != 0) { - ESP_LOGE(TAG, "%s failed to os_mbuf_append; rc = %d", __func__, rc); + esp_rom_printf("%s failed to os_mbuf_append; rc = %d", __func__, rc); os_mbuf_free_chain(m); return; } @@ -181,14 +197,49 @@ static void controller_rcv_pkt_ready(void) } } +static void dummy_controller_rcv_pkt_ready(void) +{ + /* Dummy function */ +} + +void bt_record_hci_data(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + if ((data[0] == BLE_HCI_UART_H4_EVT) && (data[1] == BLE_HCI_EVCODE_LE_META) && ((data[3] == BLE_HCI_LE_SUBEV_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) + || (data[3] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT))) { + bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2); + } else { + uint8_t data_type; + if (data[0] == HCI_LOG_DATA_TYPE_ISO_DATA) { + data_type = HCI_LOG_DATA_TYPE_ISO_DATA; + } else { + data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + } + bt_hci_log_record_hci_data(data_type, &data[1], len - 1); + } +#endif // (BT_HCI_LOG_INCLUDED == TRUE) +} + +static int dummy_host_rcv_pkt(uint8_t *data, uint16_t len) +{ + /* Dummy function */ + return 0; +} + /* * @brief: BT controller callback function, to transfer data packet to the host */ static int host_rcv_pkt(uint8_t *data, uint16_t len) { +#if (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM, data, len); +#endif // (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + + bt_record_hci_data(data, len); + if(!ble_hs_enabled_state) { /* If host is not enabled, drop the packet */ - ESP_LOGE(TAG, "Host not enabled. Dropping the packet!"); + esp_rom_printf("Host not enabled. Dropping the packet!"); return 0; } @@ -201,7 +252,7 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) assert(totlen <= UINT8_MAX + BLE_HCI_EVENT_HDR_LEN); if (totlen > MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)) { - ESP_LOGE(TAG, "Received HCI data length at host (%d) exceeds maximum configured HCI event buffer size (%d).", + esp_rom_printf("Received HCI data length at host (%d) exceeds maximum configured HCI event buffer size (%d).", totlen, MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)); ble_hs_sched_reset(BLE_HS_ECONTROLLER); return 0; @@ -240,6 +291,11 @@ static const esp_vhci_host_callback_t vhci_host_cb = { .notify_host_recv = host_rcv_pkt, }; +static const esp_vhci_host_callback_t dummy_vhci_host_cb = { + .notify_host_send_available = dummy_controller_rcv_pkt_ready, + .notify_host_recv = dummy_host_rcv_pkt, +}; + extern void ble_transport_init(void); extern esp_err_t ble_buf_alloc(void); @@ -289,6 +345,8 @@ esp_err_t esp_nimble_hci_deinit(void) } ble_transport_deinit(); + esp_vhci_host_register_callback(&dummy_vhci_host_cb); + ble_buf_free(); #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) diff --git a/lib/bt/host/nimble/nimble/.travis.yml b/lib/bt/host/nimble/nimble/.travis.yml deleted file mode 100644 index d3dd9742..00000000 --- a/lib/bt/host/nimble/nimble/.travis.yml +++ /dev/null @@ -1,156 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -language: go - -dist: bionic - -_addons: &addon_conf - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-multilib - - gcc-7-multilib - - g++-multilib - -go: - - "1.16" - -git: - depth: false - -matrix: - allow_failures: - - env: - - TEST=BUILD_PORTS - - VM_AMOUNT=1 - - TARGET_SET=1 - include: - # Style checking - - os: linux - language: python - python: - - "3.5" - addons: - apt: - packages: - - "python3-pip" - env: - - TEST=STYLE - - DEBUG=1 - - # newt build - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=1 - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=2 - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=3 - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=4 - - # newt test all (Linux) - - os: linux - addons: *addon_conf - env: - - TEST=TEST_ALL - - VM_AMOUNT=2 - - TARGET_SET=1 - - os: linux - addons: *addon_conf - env: - - TEST=TEST_ALL - - VM_AMOUNT=2 - - TARGET_SET=2 - - # ports - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_PORTS - - VM_AMOUNT=1 - - TARGET_SET=1 - - - os: windows - env: - - TEST=BUILD_TARGETS_WINDOWS - - VM_AMOUNT=1 - - TARGET_SET=1 - -before_install: - - printenv - - export GOPATH=$HOME/gopath - - go version - -install: - - git clone https://github.com/JuulLabs-OSS/mynewt-travis-ci $HOME/ci - - chmod +x $HOME/ci/*.sh - - | - if [ "${TEST}" == "STYLE" ]; then - pip3 install requests - else - $HOME/ci/${TRAVIS_OS_NAME}_travis_install.sh - fi - -before_script: - - | - if [ "${TEST}" == "STYLE" ]; then - $HOME/ci/install_uncrustify.sh - else - newt version - gcc --version - if [ "${TEST}" != "TEST_ALL" ]; then arm-none-eabi-gcc --version; fi - cp -R $HOME/ci/mynewt-nimble-project.yml project.yml - mkdir -p targets - cp -R $HOME/ci/mynewt-nimble-targets targets - $HOME/ci/prepare_test.sh $VM_AMOUNT - mkdir -p repos && pushd repos/ - git clone --depth=1 https://github.com/apache/mynewt-core apache-mynewt-core - git clone --depth=1 https://github.com/JuulLabs-OSS/mcuboot mcuboot - git clone --depth=1 https://github.com/apache/mynewt-mcumgr apache-mynewt-mcumgr - popd - fi - -script: - - | - if [ "${TEST}" == "STYLE" ]; then - python3 $HOME/ci/check_style.py - else - $HOME/ci/run_test.sh - fi - -cache: - directories: - - $HOME/TOOLCHAIN - - $HOME/Library/Caches/Homebrew diff --git a/lib/bt/host/nimble/nimble/apps/blecent/src/main.c b/lib/bt/host/nimble/nimble/apps/blecent/src/main.c index f794937e..a88e9234 100644 --- a/lib/bt/host/nimble/nimble/apps/blecent/src/main.c +++ b/lib/bt/host/nimble/nimble/apps/blecent/src/main.c @@ -216,7 +216,7 @@ static void blecent_scan(void) { uint8_t own_addr_type; - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int rc; /* Figure out address to use while advertising (no privacy for now) */ diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/atomic.h b/lib/bt/host/nimble/nimble/apps/bttester/src/atomic.h deleted file mode 100644 index 66283e9a..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/atomic.h +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* atomic operations */ - -/* - * Copyright (c) 1997-2015, Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __ATOMIC_H__ -#define __ATOMIC_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef int atomic_t; -typedef atomic_t atomic_val_t; - -/** - * @defgroup atomic_apis Atomic Services APIs - * @ingroup kernel_apis - * @{ - */ - -/** - * @brief Atomic compare-and-set. - * - * This routine performs an atomic compare-and-set on @a target. If the current - * value of @a target equals @a old_value, @a target is set to @a new_value. - * If the current value of @a target does not equal @a old_value, @a target - * is left unchanged. - * - * @param target Address of atomic variable. - * @param old_value Original value to compare against. - * @param new_value New value to store. - * @return 1 if @a new_value is written, 0 otherwise. - */ -static inline int atomic_cas(atomic_t *target, atomic_val_t old_value, - atomic_val_t new_value) -{ - return __atomic_compare_exchange_n(target, &old_value, new_value, - 0, __ATOMIC_SEQ_CST, - __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic addition. - * - * This routine performs an atomic addition on @a target. - * - * @param target Address of atomic variable. - * @param value Value to add. - * - * @return Previous value of @a target. - */ -static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic subtraction. - * - * This routine performs an atomic subtraction on @a target. - * - * @param target Address of atomic variable. - * @param value Value to subtract. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic increment. - * - * This routine performs an atomic increment by 1 on @a target. - * - * @param target Address of atomic variable. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_inc(atomic_t *target) -{ - return atomic_add(target, 1); -} - -/** - * - * @brief Atomic decrement. - * - * This routine performs an atomic decrement by 1 on @a target. - * - * @param target Address of atomic variable. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_dec(atomic_t *target) -{ - return atomic_sub(target, 1); -} - -/** - * - * @brief Atomic get. - * - * This routine performs an atomic read on @a target. - * - * @param target Address of atomic variable. - * - * @return Value of @a target. - */ - -static inline atomic_val_t atomic_get(const atomic_t *target) -{ - return __atomic_load_n(target, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic get-and-set. - * - * This routine atomically sets @a target to @a value and returns - * the previous value of @a target. - * - * @param target Address of atomic variable. - * @param value Value to write to @a target. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) -{ - /* This builtin, as described by Intel, is not a traditional - * test-and-set operation, but rather an atomic exchange operation. It - * writes value into *ptr, and returns the previous contents of *ptr. - */ - return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic clear. - * - * This routine atomically sets @a target to zero and returns its previous - * value. (Hence, it is equivalent to atomic_set(target, 0).) - * - * @param target Address of atomic variable. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_clear(atomic_t *target) -{ - return atomic_set(target, 0); -} - -/** - * - * @brief Atomic bitwise inclusive OR. - * - * This routine atomically sets @a target to the bitwise inclusive OR of - * @a target and @a value. - * - * @param target Address of atomic variable. - * @param value Value to OR. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic bitwise exclusive OR (XOR). - * - * This routine atomically sets @a target to the bitwise exclusive OR (XOR) of - * @a target and @a value. - * - * @param target Address of atomic variable. - * @param value Value to XOR - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic bitwise AND. - * - * This routine atomically sets @a target to the bitwise AND of @a target - * and @a value. - * - * @param target Address of atomic variable. - * @param value Value to AND. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic bitwise NAND. - * - * This routine atomically sets @a target to the bitwise NAND of @a target - * and @a value. (This operation is equivalent to target = ~(target & value).) - * - * @param target Address of atomic variable. - * @param value Value to NAND. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST); -} - - /** - * @brief Initialize an atomic variable. - * - * This macro can be used to initialize an atomic variable. For example, - * @code atomic_t my_var = ATOMIC_INIT(75); @endcode - * - * @param i Value to assign to atomic variable. - */ -#define ATOMIC_INIT(i) (i) - - /** - * @cond INTERNAL_HIDDEN - */ - -#define ATOMIC_BITS (sizeof(atomic_val_t) * 8) -#define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1))) -#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS)) - - /** - * INTERNAL_HIDDEN @endcond - */ - - /** - * @brief Define an array of atomic variables. - * - * This macro defines an array of atomic variables containing at least - * @a num_bits bits. - * - * @note - * If used from file scope, the bits of the array are initialized to zero; - * if used from within a function, the bits are left uninitialized. - * - * @param name Name of array of atomic variables. - * @param num_bits Number of bits needed. - */ -#define ATOMIC_DEFINE(name, num_bits) \ - atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] - - /** - * @brief Atomically test a bit. - * - * This routine tests whether bit number @a bit of @a target is set or not. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ - static inline int - atomic_test_bit(const atomic_t *target, int bit) - { - atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit)); - - return (1 & (val >> (bit & (ATOMIC_BITS - 1)))); - } - - /** - * @brief Atomically test and clear a bit. - * - * Atomically clear bit number @a bit of @a target and return its old value. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ - static inline int - atomic_test_and_clear_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); - atomic_val_t old; - - old = atomic_and(ATOMIC_ELEM(target, bit), ~mask); - - return (old & mask) != 0; - } - - /** - * @brief Atomically set a bit. - * - * Atomically set bit number @a bit of @a target and return its old value. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ - static inline int - atomic_test_and_set_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); - atomic_val_t old; - - old = atomic_or(ATOMIC_ELEM(target, bit), mask); - - return (old & mask) != 0; - } - - /** - * @brief Atomically clear a bit. - * - * Atomically clear bit number @a bit of @a target. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return N/A - */ - static inline void - atomic_clear_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); - - atomic_and(ATOMIC_ELEM(target, bit), ~mask); - } - - /** - * @brief Atomically set a bit. - * - * Atomically set bit number @a bit of @a target. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return N/A - */ - static inline void - atomic_set_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); - - atomic_or(ATOMIC_ELEM(target, bit), mask); - } - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ATOMIC_H__ */ diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/bttester.h b/lib/bt/host/nimble/nimble/apps/bttester/src/bttester.h deleted file mode 100644 index 641db8bd..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/bttester.h +++ /dev/null @@ -1,1321 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* bttester.h - Bluetooth tester headers */ - -/* - * Copyright (C) 2021 Codecoup - * Copyright (c) 2015-2016 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __BTTESTER_H__ -#define __BTTESTER_H__ - -#include "syscfg/syscfg.h" -#include "host/ble_gatt.h" - -#if MYNEWT_VAL(BLE_MESH) -#include "mesh/glue.h" -#else -#include "glue.h" -#endif - -#define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX) -#define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) - -#define BTP_INDEX_NONE 0xff - -#define BTP_SERVICE_ID_CORE 0 -#define BTP_SERVICE_ID_GAP 1 -#define BTP_SERVICE_ID_GATT 2 -#define BTP_SERVICE_ID_L2CAP 3 -#define BTP_SERVICE_ID_MESH 4 -#define BTP_SERVICE_ID_GATTC 6 - -#define BTP_STATUS_SUCCESS 0x00 -#define BTP_STATUS_FAILED 0x01 -#define BTP_STATUS_UNKNOWN_CMD 0x02 -#define BTP_STATUS_NOT_READY 0x03 - -#define SYS_LOG_DBG(fmt, ...) \ - if (MYNEWT_VAL(BTTESTER_DEBUG)) { \ - console_printf("[DBG] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); \ - } -#define SYS_LOG_INF(fmt, ...) console_printf("[INF] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); -#define SYS_LOG_ERR(fmt, ...) console_printf("[WRN] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); - -#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG -#define SYS_LOG_DOMAIN "bttester" - -#define sys_cpu_to_le32 htole32 -#define sys_le32_to_cpu le32toh -#define sys_cpu_to_le16 htole16 - -struct btp_hdr { - uint8_t service; - uint8_t opcode; - uint8_t index; - uint16_t len; - uint8_t data[0]; -} __packed; - -#define BTP_STATUS 0x00 -struct btp_status { - uint8_t code; -} __packed; - -/* Core Service */ -#define CORE_READ_SUPPORTED_COMMANDS 0x01 -struct core_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define CORE_READ_SUPPORTED_SERVICES 0x02 -struct core_read_supported_services_rp { - uint8_t data[0]; -} __packed; - -#define CORE_REGISTER_SERVICE 0x03 -struct core_register_service_cmd { - uint8_t id; -} __packed; - -#define CORE_UNREGISTER_SERVICE 0x04 -struct core_unregister_service_cmd { - uint8_t id; -} __packed; - -/* events */ -#define CORE_EV_IUT_READY 0x80 - -/* GAP Service */ -/* commands */ -#define GAP_READ_SUPPORTED_COMMANDS 0x01 -struct gap_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define GAP_READ_CONTROLLER_INDEX_LIST 0x02 -struct gap_read_controller_index_list_rp { - uint8_t num; - uint8_t index[0]; -} __packed; - -#define GAP_SETTINGS_POWERED 0 -#define GAP_SETTINGS_CONNECTABLE 1 -#define GAP_SETTINGS_FAST_CONNECTABLE 2 -#define GAP_SETTINGS_DISCOVERABLE 3 -#define GAP_SETTINGS_BONDABLE 4 -#define GAP_SETTINGS_LINK_SEC_3 5 -#define GAP_SETTINGS_SSP 6 -#define GAP_SETTINGS_BREDR 7 -#define GAP_SETTINGS_HS 8 -#define GAP_SETTINGS_LE 9 -#define GAP_SETTINGS_ADVERTISING 10 -#define GAP_SETTINGS_SC 11 -#define GAP_SETTINGS_DEBUG_KEYS 12 -#define GAP_SETTINGS_PRIVACY 13 -#define GAP_SETTINGS_CONTROLLER_CONFIG 14 -#define GAP_SETTINGS_STATIC_ADDRESS 15 - -#define GAP_READ_CONTROLLER_INFO 0x03 -struct gap_read_controller_info_rp { - uint8_t address[6]; - uint32_t supported_settings; - uint32_t current_settings; - uint8_t cod[3]; - uint8_t name[249]; - uint8_t short_name[11]; -} __packed; - -#define GAP_RESET 0x04 -struct gap_reset_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_POWERED 0x05 -struct gap_set_powered_cmd { - uint8_t powered; -} __packed; -struct gap_set_powered_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_CONNECTABLE 0x06 -struct gap_set_connectable_cmd { - uint8_t connectable; -} __packed; -struct gap_set_connectable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_FAST_CONNECTABLE 0x07 -struct gap_set_fast_connectable_cmd { - uint8_t fast_connectable; -} __packed; -struct gap_set_fast_connectable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_NON_DISCOVERABLE 0x00 -#define GAP_GENERAL_DISCOVERABLE 0x01 -#define GAP_LIMITED_DISCOVERABLE 0x02 - -#define GAP_SET_DISCOVERABLE 0x08 -struct gap_set_discoverable_cmd { - uint8_t discoverable; -} __packed; -struct gap_set_discoverable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_BONDABLE 0x09 -struct gap_set_bondable_cmd { - uint8_t bondable; -} __packed; -struct gap_set_bondable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_START_ADVERTISING 0x0a -struct gap_start_advertising_cmd { - uint8_t adv_data_len; - uint8_t scan_rsp_len; - uint8_t adv_data[0]; - uint8_t scan_rsp[0]; -} __packed; -struct gap_start_advertising_rp { - uint32_t current_settings; -} __packed; - -#define GAP_STOP_ADVERTISING 0x0b -struct gap_stop_advertising_rp { - uint32_t current_settings; -} __packed; - -#define GAP_DISCOVERY_FLAG_LE 0x01 -#define GAP_DISCOVERY_FLAG_BREDR 0x02 -#define GAP_DISCOVERY_FLAG_LIMITED 0x04 -#define GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN 0x08 -#define GAP_DISCOVERY_FLAG_LE_OBSERVE 0x10 - -#define GAP_START_DISCOVERY 0x0c -struct gap_start_discovery_cmd { - uint8_t flags; -} __packed; - -#define GAP_STOP_DISCOVERY 0x0d - -#define GAP_CONNECT 0x0e -struct gap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_DISCONNECT 0x0f -struct gap_disconnect_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_IO_CAP_DISPLAY_ONLY 0 -#define GAP_IO_CAP_DISPLAY_YESNO 1 -#define GAP_IO_CAP_KEYBOARD_ONLY 2 -#define GAP_IO_CAP_NO_INPUT_OUTPUT 3 -#define GAP_IO_CAP_KEYBOARD_DISPLAY 4 - -#define GAP_SET_IO_CAP 0x10 -struct gap_set_io_cap_cmd { - uint8_t io_cap; -} __packed; - -#define GAP_PAIR 0x11 -struct gap_pair_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_UNPAIR 0x12 -struct gap_unpair_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_PASSKEY_ENTRY 0x13 -struct gap_passkey_entry_cmd { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; -} __packed; - -#define GAP_PASSKEY_CONFIRM 0x14 -struct gap_passkey_confirm_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t match; -} __packed; - -#define GAP_START_DIRECT_ADV 0x15 -struct gap_start_direct_adv_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t high_duty; -} __packed; - -#define GAP_CONN_PARAM_UPDATE 0x16 -struct gap_conn_param_update_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; -} __packed; - -#define GAP_PAIRING_CONSENT_RSP 0x17 -struct gap_pairing_consent_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t consent; -} __packed; - -#define GAP_OOB_LEGACY_SET_DATA 0x18 -struct gap_oob_legacy_set_data_cmd { - uint8_t oob_data[16]; -} __packed; - -#define GAP_OOB_SC_GET_LOCAL_DATA 0x19 -struct gap_oob_sc_get_local_data_rp { - uint8_t r[16]; - uint8_t c[16]; -} __packed; - -#define GAP_OOB_SC_SET_REMOTE_DATA 0x1a -struct gap_oob_sc_set_remote_data_cmd { - uint8_t r[16]; - uint8_t c[16]; -} __packed; - -#define GAP_SET_MITM 0x1b -struct gap_set_mitm_cmd { - uint8_t mitm; -} __packed; - -#define GAP_SET_FILTER_ACCEPT_LIST 0x1c -struct gap_set_filter_accept_list_cmd { - uint8_t list_len; - ble_addr_t addrs[]; -} __packed; -/* events */ -#define GAP_EV_NEW_SETTINGS 0x80 -struct gap_new_settings_ev { - uint32_t current_settings; -} __packed; - -#define GAP_DEVICE_FOUND_FLAG_RSSI 0x01 -#define GAP_DEVICE_FOUND_FLAG_AD 0x02 -#define GAP_DEVICE_FOUND_FLAG_SD 0x04 - -#define GAP_EV_DEVICE_FOUND 0x81 -struct gap_device_found_ev { - uint8_t address_type; - uint8_t address[6]; - int8_t rssi; - uint8_t flags; - uint16_t eir_data_len; - uint8_t eir_data[0]; -} __packed; - -#define GAP_EV_DEVICE_CONNECTED 0x82 -struct gap_device_connected_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; -} __packed; - -#define GAP_EV_DEVICE_DISCONNECTED 0x83 -struct gap_device_disconnected_ev { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_EV_PASSKEY_DISPLAY 0x84 -struct gap_passkey_display_ev { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; -} __packed; - -#define GAP_EV_PASSKEY_ENTRY_REQ 0x85 -struct gap_passkey_entry_req_ev { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_EV_PASSKEY_CONFIRM_REQ 0x86 -struct gap_passkey_confirm_req_ev { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; -} __packed; - -#define GAP_EV_IDENTITY_RESOLVED 0x87 -struct gap_identity_resolved_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t identity_address_type; - uint8_t identity_address[6]; -} __packed; - -#define GAP_EV_CONN_PARAM_UPDATE 0x88 -struct gap_conn_param_update_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; -} __packed; - -#define GAP_EV_SEC_LEVEL_CHANGED 0x89 -struct gap_sec_level_changed_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t level; -} __packed; - -#define GAP_EV_PAIRING_CONSENT_REQ 0x8a -struct gap_pairing_consent_req_ev { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -/* GATT Service */ -/* commands */ -#define GATT_READ_SUPPORTED_COMMANDS 0x01 -struct gatt_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define GATT_SERVICE_PRIMARY 0x00 -#define GATT_SERVICE_SECONDARY 0x01 - -#define GATT_ADD_SERVICE 0x02 -struct gatt_add_service_cmd { - uint8_t type; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_add_service_rp { - uint16_t svc_id; -} __packed; - -#define GATT_ADD_CHARACTERISTIC 0x03 -struct gatt_add_characteristic_cmd { - uint16_t svc_id; - uint8_t properties; - uint8_t permissions; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_add_characteristic_rp { - uint16_t char_id; -} __packed; - -#define GATT_ADD_DESCRIPTOR 0x04 -struct gatt_add_descriptor_cmd { - uint16_t char_id; - uint8_t permissions; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_add_descriptor_rp { - uint16_t desc_id; -} __packed; - -#define GATT_ADD_INCLUDED_SERVICE 0x05 -struct gatt_add_included_service_cmd { - uint16_t svc_id; -} __packed; -struct gatt_add_included_service_rp { - uint16_t included_service_id; -} __packed; - -#define GATT_SET_VALUE 0x06 - struct gatt_set_value_cmd { - uint16_t attr_id; - uint16_t len; - uint8_t value[0]; -} __packed; - -#define GATT_START_SERVER 0x07 -struct gatt_start_server_rp { - uint16_t db_attr_off; - uint8_t db_attr_cnt; -} __packed; - -#define GATT_SET_ENC_KEY_SIZE 0x09 -struct gatt_set_enc_key_size_cmd { - uint16_t attr_id; - uint8_t key_size; -} __packed; - -/* Gatt Client */ -struct gatt_service { - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -struct gatt_included { - uint16_t included_handle; - struct gatt_service service; -} __packed; - -struct gatt_read_uuid_chr { - uint16_t handle; - uint8_t data[0]; -} __packed; - -struct gatt_characteristic { - uint16_t characteristic_handle; - uint16_t value_handle; - uint8_t properties; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -struct gatt_descriptor { - uint16_t descriptor_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATT_EXCHANGE_MTU 0x0a - -#define GATT_DISC_ALL_PRIM_SVCS 0x0b -struct gatt_disc_all_prim_svcs_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; -struct gatt_disc_all_prim_svcs_rp { - uint8_t services_count; - struct gatt_service services[0]; -} __packed; - -#define GATT_DISC_PRIM_UUID 0x0c -struct gatt_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_disc_prim_uuid_rp { - uint8_t services_count; - struct gatt_service services[0]; -} __packed; - -#define GATT_FIND_INCLUDED 0x0d -struct gatt_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; -struct gatt_find_included_rp { - uint8_t services_count; - struct gatt_included included[0]; -} __packed; - -#define GATT_DISC_ALL_CHRC 0x0e -struct gatt_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; -struct gatt_disc_chrc_rp { - uint8_t characteristics_count; - struct gatt_characteristic characteristics[0]; -} __packed; - -#define GATT_DISC_CHRC_UUID 0x0f -struct gatt_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATT_DISC_ALL_DESC 0x10 -struct gatt_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; -struct gatt_disc_all_desc_rp { - uint8_t descriptors_count; - struct gatt_descriptor descriptors[0]; -} __packed; - -#define GATT_READ 0x11 -struct gatt_read_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; -} __packed; -struct gatt_read_rp { - uint8_t att_response; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_READ_UUID 0x12 -struct gatt_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATT_READ_LONG 0x13 -struct gatt_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; -} __packed; - -#define GATT_READ_MULTIPLE 0x14 -struct gatt_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t handles_count; - uint16_t handles[0]; -} __packed; - -#define GATT_WRITE_WITHOUT_RSP 0x15 -struct gatt_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_SIGNED_WRITE_WITHOUT_RSP 0x16 -struct gatt_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_WRITE 0x17 -struct gatt_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_WRITE_LONG 0x18 -struct gatt_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_RELIABLE_WRITE 0x19 -struct gatt_reliable_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_CFG_NOTIFY 0x1a -#define GATT_CFG_INDICATE 0x1b -struct gatt_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t enable; - uint16_t ccc_handle; -} __packed; - -#define GATT_GET_ATTRIBUTES 0x1c -struct gatt_get_attributes_cmd { - uint16_t start_handle; - uint16_t end_handle; - uint8_t type_length; - uint8_t type[0]; -} __packed; -struct gatt_get_attributes_rp { - uint8_t attrs_count; - uint8_t attrs[0]; -} __packed; -struct gatt_attr { - uint16_t handle; - uint8_t permission; - uint8_t type_length; - uint8_t type[0]; -} __packed; - -#define GATT_GET_ATTRIBUTE_VALUE 0x1d -struct gatt_get_attribute_value_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; -} __packed; -struct gatt_get_attribute_value_rp { - uint8_t att_response; - uint16_t value_length; - uint8_t value[0]; -} __packed; - -#define GATT_CHANGE_DATABASE 0x1e -struct gatt_change_database { - uint16_t start_handle; - uint16_t end_handle; - uint8_t visibility; -} __packed; - -/* GATT events */ -#define GATT_EV_NOTIFICATION 0x80 -struct gatt_notification_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t type; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_EV_ATTR_VALUE_CHANGED 0x81 -struct gatt_attr_value_changed_ev { - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -static inline void tester_set_bit(uint8_t *addr, unsigned int bit) -{ - uint8_t *p = addr + (bit / 8); - - *p |= BIT(bit % 8); -} - -static inline uint8_t tester_test_bit(const uint8_t *addr, unsigned int bit) -{ - const uint8_t *p = addr + (bit / 8); - - return *p & BIT(bit % 8); -} - -/* L2CAP Service */ -/* commands */ -#define L2CAP_READ_SUPPORTED_COMMANDS 0x01 -struct l2cap_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define L2CAP_CONNECT_OPT_ECFC 0x01 -#define L2CAP_CONNECT_OPT_HOLD_CREDIT 0x02 - -#define L2CAP_CONNECT 0x02 -struct l2cap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t psm; - uint16_t mtu; - uint8_t num; - uint8_t options; -} __packed; - -struct l2cap_connect_rp { - uint8_t num; - uint8_t chan_ids[0]; -} __packed; - -#define L2CAP_DISCONNECT 0x03 -struct l2cap_disconnect_cmd { - uint8_t chan_id; -} __packed; - -#define L2CAP_SEND_DATA 0x04 -struct l2cap_send_data_cmd { - uint8_t chan_id; - uint16_t data_len; - uint8_t data[]; -} __packed; - -#define L2CAP_TRANSPORT_BREDR 0x00 -#define L2CAP_TRANSPORT_LE 0x01 - -#define L2CAP_LISTEN 0x05 -struct l2cap_listen_cmd { - uint16_t psm; - uint8_t transport; - uint16_t mtu; - uint16_t response; -} __packed; - -#define L2CAP_ACCEPT_CONNECTION 0x06 -struct l2cap_accept_connection_cmd { - uint8_t chan_id; - uint16_t result; -} __packed; - -#define L2CAP_RECONFIGURE 0x07 -struct l2cap_reconfigure_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t mtu; - uint8_t num; - uint8_t idxs[]; -} __packed; - -#define L2CAP_CREDITS 0x08 -struct l2cap_credits_cmd { - uint8_t chan_id; -} __packed; - -/* events */ -#define L2CAP_EV_CONNECTION_REQ 0x80 -struct l2cap_connection_req_ev { - uint8_t chan_id; - uint16_t psm; - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define L2CAP_EV_CONNECTED 0x81 -struct l2cap_connected_ev { - uint8_t chan_id; - uint16_t psm; - uint16_t peer_mtu; - uint16_t peer_mps; - uint16_t our_mtu; - uint16_t our_mps; - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define L2CAP_EV_DISCONNECTED 0x82 -struct l2cap_disconnected_ev { - uint16_t result; - uint8_t chan_id; - uint16_t psm; - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define L2CAP_EV_DATA_RECEIVED 0x83 -struct l2cap_data_received_ev { - uint8_t chan_id; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define L2CAP_EV_RECONFIGURED 0x84 -struct l2cap_reconfigured_ev { - uint8_t chan_id; - uint16_t peer_mtu; - uint16_t peer_mps; - uint16_t our_mtu; - uint16_t our_mps; -} __packed; - -/* MESH Service */ -/* commands */ -#define MESH_READ_SUPPORTED_COMMANDS 0x01 -struct mesh_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define MESH_OUT_BLINK BIT(0) -#define MESH_OUT_BEEP BIT(1) -#define MESH_OUT_VIBRATE BIT(2) -#define MESH_OUT_DISPLAY_NUMBER BIT(3) -#define MESH_OUT_DISPLAY_STRING BIT(4) - -#define MESH_IN_PUSH BIT(0) -#define MESH_IN_TWIST BIT(1) -#define MESH_IN_ENTER_NUMBER BIT(2) -#define MESH_IN_ENTER_STRING BIT(3) - -#define MESH_CONFIG_PROVISIONING 0x02 -struct mesh_config_provisioning_cmd { - uint8_t uuid[16]; - uint8_t static_auth[16]; - uint8_t out_size; - uint16_t out_actions; - uint8_t in_size; - uint16_t in_actions; -} __packed; - -#define MESH_PROVISION_NODE 0x03 -struct mesh_provision_node_cmd { - uint8_t net_key[16]; - uint16_t net_key_idx; - uint8_t flags; - uint32_t iv_index; - uint32_t seq_num; - uint16_t addr; - uint8_t dev_key[16]; -} __packed; - -#define MESH_INIT 0x04 -#define MESH_RESET 0x05 -#define MESH_INPUT_NUMBER 0x06 -struct mesh_input_number_cmd { - uint32_t number; -} __packed; - -#define MESH_INPUT_STRING 0x07 -struct mesh_input_string_cmd { - uint8_t string_len; - uint8_t string[0]; -} __packed; - -#define MESH_IVU_TEST_MODE 0x08 -struct mesh_ivu_test_mode_cmd { - uint8_t enable; -} __packed; - -#define MESH_IVU_TOGGLE_STATE 0x09 - -#define MESH_NET_SEND 0x0a -struct mesh_net_send_cmd { - uint8_t ttl; - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; -} __packed; - -#define MESH_HEALTH_GENERATE_FAULTS 0x0b -struct mesh_health_generate_faults_rp { - uint8_t test_id; - uint8_t cur_faults_count; - uint8_t reg_faults_count; - uint8_t current_faults[0]; - uint8_t registered_faults[0]; -} __packed; - -#define MESH_HEALTH_CLEAR_FAULTS 0x0c - -#define MESH_LPN 0x0d -struct mesh_lpn_set_cmd { - uint8_t enable; -} __packed; - -#define MESH_LPN_POLL 0x0e - -#define MESH_MODEL_SEND 0x0f -struct mesh_model_send_cmd { - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; -} __packed; - -#define MESH_LPN_SUBSCRIBE 0x10 -struct mesh_lpn_subscribe_cmd { - uint16_t address; -} __packed; - -#define MESH_LPN_UNSUBSCRIBE 0x11 -struct mesh_lpn_unsubscribe_cmd { - uint16_t address; -} __packed; - -#define MESH_RPL_CLEAR 0x12 -#define MESH_PROXY_IDENTITY 0x13 - -/* events */ -#define MESH_EV_OUT_NUMBER_ACTION 0x80 -struct mesh_out_number_action_ev { - uint16_t action; - uint32_t number; -} __packed; - -#define MESH_EV_OUT_STRING_ACTION 0x81 -struct mesh_out_string_action_ev { - uint8_t string_len; - uint8_t string[0]; -} __packed; - -#define MESH_EV_IN_ACTION 0x82 -struct mesh_in_action_ev { - uint16_t action; - uint8_t size; -} __packed; - -#define MESH_EV_PROVISIONED 0x83 - -#define MESH_PROV_BEARER_PB_ADV 0x00 -#define MESH_PROV_BEARER_PB_GATT 0x01 -#define MESH_EV_PROV_LINK_OPEN 0x84 -struct mesh_prov_link_open_ev { - uint8_t bearer; -} __packed; - -#define MESH_EV_PROV_LINK_CLOSED 0x85 -struct mesh_prov_link_closed_ev { - uint8_t bearer; -} __packed; - -#define MESH_EV_NET_RECV 0x86 -struct mesh_net_recv_ev { - uint8_t ttl; - uint8_t ctl; - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; -} __packed; - -#define MESH_EV_INVALID_BEARER 0x87 -struct mesh_invalid_bearer_ev { - uint8_t opcode; -} __packed; - -#define MESH_EV_INCOMP_TIMER_EXP 0x88 - -#define MESH_EV_LPN_ESTABLISHED 0x8b -struct mesh_lpn_established_ev { - uint16_t net_idx; - uint16_t friend_addr; - uint8_t queue_size; - uint8_t recv_win; -} __packed; - -#define MESH_EV_LPN_TERMINATED 0x8c -struct mesh_lpn_terminated_ev { - uint16_t net_idx; - uint16_t friend_addr; -} __packed; - -#define MESH_EV_LPN_POLLED 0x8d -struct mesh_lpn_polled_ev { - uint16_t net_idx; - uint16_t friend_addr; - uint8_t retry; -} __packed; - -void tester_init(void); -void tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status); -void tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, - size_t len); -void tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, - struct os_mbuf *buf); - -uint8_t tester_init_gap(void); -uint8_t tester_unregister_gap(void); -void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -uint8_t tester_init_gatt(void); -uint8_t tester_unregister_gatt(void); -void tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -void tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, - uint8_t indication, struct os_mbuf *om); -int tester_gatt_subscribe_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t reason, - uint8_t prev_notify, uint8_t cur_notify, - uint8_t prev_indicate, uint8_t cur_indicate); - -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) -uint8_t tester_init_l2cap(void); -uint8_t tester_unregister_l2cap(void); -void tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -#endif - -#if MYNEWT_VAL(BLE_MESH) -uint8_t tester_init_mesh(void); -uint8_t tester_unregister_mesh(void); -void tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len); -#endif /* MYNEWT_VAL(BLE_MESH) */ - -void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); -int gatt_svr_init(void); - -/* GATT Client Service */ -/* commands */ -#define GATTC_READ_SUPPORTED_COMMANDS 0x01 -struct gattc_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define GATTC_EXCHANGE_MTU 0x02 - -#define GATTC_DISC_ALL_PRIM_SVCS 0x03 -struct gattc_disc_all_prim_svcs_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GATTC_DISC_PRIM_UUID 0x04 -struct gattc_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATTC_FIND_INCLUDED 0x05 -struct gattc_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; - -#define GATTC_DISC_ALL_CHRC 0x06 -struct gattc_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; - -#define GATTC_DISC_CHRC_UUID 0x07 -struct gattc_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATTC_DISC_ALL_DESC 0x08 -struct gattc_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; - -#define GATTC_READ 0x09 -struct gattc_read_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; -} __packed; - -#define GATTC_READ_UUID 0x0a -struct gattc_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gattc_read_uuid_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint16_t data_length; - uint8_t value_length; - uint8_t data[0]; -} __packed; - -#define GATTC_READ_LONG 0x0b -struct gattc_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; -} __packed; - -#define GATTC_READ_MULTIPLE 0x0c -struct gattc_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t handles_count; - uint16_t handles[0]; -} __packed; - -#define GATTC_WRITE_WITHOUT_RSP 0x0d -struct gattc_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_SIGNED_WRITE_WITHOUT_RSP 0x0e -struct gattc_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_WRITE 0x0f -struct gattc_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_WRITE_LONG 0x10 -struct gattc_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_RELIABLE_WRITE 0x11 -struct gattc_reliable_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_CFG_NOTIFY 0x12 -#define GATTC_CFG_INDICATE 0x13 -struct gattc_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t enable; - uint16_t ccc_handle; -} __packed; - -/* events */ -#define GATTC_EV_MTU_EXCHANGED 0x80 -struct gattc_exchange_mtu_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t mtu; -} __packed; - -#define GATTC_DISC_ALL_PRIM_RP 0x81 -struct gattc_disc_prim_svcs_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t services_count; - uint8_t data[0]; -} __packed; - -#define GATTC_DISC_PRIM_UUID_RP 0x82 - -#define GATTC_FIND_INCLUDED_RP 0x83 -struct gattc_find_included_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t services_count; - struct gatt_included included[0]; -} __packed; - -#define GATTC_DISC_ALL_CHRC_RP 0x84 -#define GATTC_DISC_CHRC_UUID_RP 0x85 -struct gattc_disc_chrc_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t characteristics_count; - struct gatt_characteristic characteristics[0]; -} __packed; - -#define GATTC_DISC_ALL_DESC_RP 0x86 -struct gattc_disc_all_desc_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t descriptors_count; - struct gatt_descriptor descriptors[0]; -} __packed; - -#define GATTC_READ_RP 0x87 -#define GATTC_READ_UUID_RP 0x88 -#define GATTC_READ_LONG_RP 0x89 -#define GATTC_READ_MULTIPLE_RP 0x8a -struct gattc_read_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_WRITE_RP 0x8b -struct gattc_write_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; -} __packed; -#define GATTC_WRITE_LONG_RP 0x8c -#define GATTC_RELIABLE_WRITE_RP 0x8d -#define GATTC_RELIABLE_WRITE_RP 0x8d -#define GATTC_CFG_NOTIFY_RP 0x8e -#define GATTC_CFG_INDICATE_RP 0x8f -struct subscribe_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; -} __packed; - -#define GATTC_EV_NOTIFICATION_RXED 0x90 -struct gattc_notification_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t type; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#endif /* __BTTESTER_H__ */ diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/gap.c b/lib/bt/host/nimble/nimble/apps/bttester/src/gap.c deleted file mode 100644 index 74b956b9..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/gap.c +++ /dev/null @@ -1,1775 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* gap.c - Bluetooth GAP Tester */ - -/* - * Copyright (c) 2015-2016 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "host/ble_gap.h" -#include "host/util/util.h" -#include "console/console.h" - -#include "../../../nimble/host/src/ble_hs_pvcy_priv.h" -#include "../../../nimble/host/src/ble_hs_hci_priv.h" -#include "../../../nimble/host/src/ble_sm_priv.h" - -#include "bttester.h" - -#define CONTROLLER_INDEX 0 -#define CONTROLLER_NAME "btp_tester" - -#define BLE_AD_DISCOV_MASK (BLE_HS_ADV_F_DISC_LTD | BLE_HS_ADV_F_DISC_GEN) -#define ADV_BUF_LEN (sizeof(struct gap_device_found_ev) + 2 * 31) - -/* parameter values to reject in CPUP if all match the pattern */ -#define REJECT_INTERVAL_MIN 0x0C80 -#define REJECT_INTERVAL_MAX 0x0C80 -#define REJECT_LATENCY 0x0000 -#define REJECT_SUPERVISION_TIMEOUT 0x0C80 - -const uint8_t irk[16] = { - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, -}; - -static uint8_t oob[16]; -static struct ble_sm_sc_oob_data oob_data_local; -static struct ble_sm_sc_oob_data oob_data_remote; - -static uint16_t current_settings; -uint8_t own_addr_type; -static ble_addr_t peer_id_addr; -static ble_addr_t peer_ota_addr; -static bool encrypted = false; - -static struct os_callout update_params_co; -static struct gap_conn_param_update_cmd update_params; - -static struct os_callout connected_ev_co; -static struct gap_device_connected_ev connected_ev; -#define CONNECTED_EV_DELAY_MS(itvl) 8 * BLE_HCI_CONN_ITVL * itvl / 1000 -static int connection_attempts; -#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) -static int64_t advertising_start; -static struct os_callout bttester_nrpa_rotate_timer; -#endif - -static const struct ble_gap_conn_params dflt_conn_params = { - .scan_itvl = 0x0010, - .scan_window = 0x0010, - .itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN, - .itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX, - .latency = 0, - .supervision_timeout = 0x0100, - .min_ce_len = 0x0010, - .max_ce_len = 0x0300, -}; - -static void conn_param_update(struct os_event *ev); - - -static int gap_conn_find_by_addr(const ble_addr_t *dev_addr, - struct ble_gap_conn_desc *out_desc) -{ - ble_addr_t addr = *dev_addr; - - if (memcmp(BLE_ADDR_ANY, &peer_id_addr, 6) == 0) { - return ble_gap_conn_find_by_addr(&addr, out_desc); - } - - if (BLE_ADDR_IS_RPA(&addr)) { - if(ble_addr_cmp(&peer_ota_addr, &addr) != 0) { - return -1; - } - - return ble_gap_conn_find_by_addr(&addr, out_desc); - } else { - if(ble_addr_cmp(&peer_id_addr, &addr) != 0) { - return -1; - } - - if (BLE_ADDR_IS_RPA(&peer_ota_addr)) { - /* Change addr type to ID addr */ - addr.type |= 2; - } - - return ble_gap_conn_find_by_addr(&addr, out_desc); - } -} - -static int gap_event_cb(struct ble_gap_event *event, void *arg); - -static void supported_commands(uint8_t *data, uint16_t len) -{ - uint8_t cmds[3]; - struct gap_read_supported_commands_rp *rp = (void *) &cmds; - - SYS_LOG_DBG(""); - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, GAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GAP_READ_CONTROLLER_INDEX_LIST); - tester_set_bit(cmds, GAP_READ_CONTROLLER_INFO); - tester_set_bit(cmds, GAP_SET_CONNECTABLE); - tester_set_bit(cmds, GAP_SET_DISCOVERABLE); - tester_set_bit(cmds, GAP_SET_BONDABLE); - tester_set_bit(cmds, GAP_START_ADVERTISING); - tester_set_bit(cmds, GAP_STOP_ADVERTISING); - tester_set_bit(cmds, GAP_START_DISCOVERY); - tester_set_bit(cmds, GAP_STOP_DISCOVERY); - tester_set_bit(cmds, GAP_CONNECT); - tester_set_bit(cmds, GAP_DISCONNECT); - tester_set_bit(cmds, GAP_SET_IO_CAP); - tester_set_bit(cmds, GAP_PAIR); - tester_set_bit(cmds, GAP_UNPAIR); - tester_set_bit(cmds, GAP_PASSKEY_ENTRY); - tester_set_bit(cmds, GAP_PASSKEY_CONFIRM); - tester_set_bit(cmds, GAP_START_DIRECT_ADV); - tester_set_bit(cmds, GAP_CONN_PARAM_UPDATE); - tester_set_bit(cmds, GAP_OOB_LEGACY_SET_DATA); - tester_set_bit(cmds, GAP_OOB_SC_GET_LOCAL_DATA); - tester_set_bit(cmds, GAP_OOB_SC_SET_REMOTE_DATA); - tester_set_bit(cmds, GAP_SET_MITM); - - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); -} - -static void controller_index_list(uint8_t *data, uint16_t len) -{ - struct gap_read_controller_index_list_rp *rp; - uint8_t buf[sizeof(*rp) + 1]; - - SYS_LOG_DBG(""); - - rp = (void *) buf; - - rp->num = 1; - rp->index[0] = CONTROLLER_INDEX; - - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INDEX_LIST, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); -} - -static void controller_info(uint8_t *data, uint16_t len) -{ - struct gap_read_controller_info_rp rp; - uint32_t supported_settings = 0; - ble_addr_t addr; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_hs_pvcy_set_our_irk(irk); - assert(rc == 0); - - memset(&rp, 0, sizeof(rp)); - - /* Make sure we have proper identity address set (public preferred) */ - rc = ble_hs_util_ensure_addr(1); - assert(rc == 0); - rc = ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); - assert(rc == 0); - - if (MYNEWT_VAL(BTTESTER_PRIVACY_MODE)) { - if (MYNEWT_VAL(BTTESTER_USE_NRPA)) { - own_addr_type = BLE_OWN_ADDR_RANDOM; - rc = ble_hs_id_gen_rnd(1, &addr); - assert(rc == 0); - rc = ble_hs_id_set_rnd(addr.val); - assert(rc == 0); - } else { - own_addr_type = BLE_OWN_ADDR_RPA_RANDOM_DEFAULT; - } - current_settings |= BIT(GAP_SETTINGS_PRIVACY); - supported_settings |= BIT(GAP_SETTINGS_PRIVACY); - memcpy(rp.address, addr.val, sizeof(rp.address)); - } else { - rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp.address, NULL); - if (rc) { - own_addr_type = BLE_OWN_ADDR_RANDOM; - memcpy(rp.address, addr.val, sizeof(rp.address)); - supported_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); - current_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); - } else { - own_addr_type = BLE_OWN_ADDR_PUBLIC; - } - } - - supported_settings |= BIT(GAP_SETTINGS_POWERED); - supported_settings |= BIT(GAP_SETTINGS_CONNECTABLE); - supported_settings |= BIT(GAP_SETTINGS_BONDABLE); - supported_settings |= BIT(GAP_SETTINGS_LE); - supported_settings |= BIT(GAP_SETTINGS_ADVERTISING); - supported_settings |= BIT(GAP_SETTINGS_SC); - - if (ble_hs_cfg.sm_bonding) { - current_settings |= BIT(GAP_SETTINGS_BONDABLE); - } - if (ble_hs_cfg.sm_sc) { - current_settings |= BIT(GAP_SETTINGS_SC); - } - - rp.supported_settings = sys_cpu_to_le32(supported_settings); - rp.current_settings = sys_cpu_to_le32(current_settings); - - memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME)); - - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INFO, - CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); -} - -static struct ble_gap_adv_params adv_params = { - .conn_mode = BLE_GAP_CONN_MODE_NON, - .disc_mode = BLE_GAP_DISC_MODE_NON, -}; - -#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) -static void rotate_nrpa_cb(struct os_event *ev) -{ - int rc; - ble_addr_t addr; - int32_t duration_ms = BLE_HS_FOREVER; - int32_t remaining_time; - os_time_t remaining_ticks; - - if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { - duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); - } - - ble_gap_adv_stop(); - rc = ble_hs_id_gen_rnd(1, &addr); - assert(rc == 0); - rc = ble_hs_id_set_rnd(addr.val); - assert(rc == 0); - - ble_gap_adv_start(own_addr_type, NULL, duration_ms, - &adv_params, gap_event_cb, NULL); - - remaining_time = os_get_uptime_usec() - advertising_start; - if (remaining_time > 0) { - advertising_start = os_get_uptime_usec(); - os_time_ms_to_ticks(remaining_time, &remaining_ticks); - os_callout_reset(&bttester_nrpa_rotate_timer, - remaining_ticks); - } -} -#endif - -static void set_connectable(uint8_t *data, uint16_t len) -{ - const struct gap_set_connectable_cmd *cmd = (void *) data; - struct gap_set_connectable_rp rp; - - SYS_LOG_DBG(""); - - if (cmd->connectable) { - current_settings |= BIT(GAP_SETTINGS_CONNECTABLE); - adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; - } else { - current_settings &= ~BIT(GAP_SETTINGS_CONNECTABLE); - adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; - } - - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_CONNECTABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); -} - -static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP; - -static void set_discoverable(uint8_t *data, uint16_t len) -{ - const struct gap_set_discoverable_cmd *cmd = (void *) data; - struct gap_set_discoverable_rp rp; - - SYS_LOG_DBG(""); - - switch (cmd->discoverable) { - case GAP_NON_DISCOVERABLE: - ad_flags &= ~(BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_DISC_LTD); - adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; - current_settings &= ~BIT(GAP_SETTINGS_DISCOVERABLE); - break; - case GAP_GENERAL_DISCOVERABLE: - ad_flags &= ~BLE_HS_ADV_F_DISC_LTD; - ad_flags |= BLE_HS_ADV_F_DISC_GEN; - adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; - current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); - break; - case GAP_LIMITED_DISCOVERABLE: - ad_flags &= ~BLE_HS_ADV_F_DISC_GEN; - ad_flags |= BLE_HS_ADV_F_DISC_LTD; - adv_params.disc_mode = BLE_GAP_DISC_MODE_LTD; - current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); - break; - default: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; - } - - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); -} - -static void set_bondable(const uint8_t *data, uint16_t len) -{ - const struct gap_set_bondable_cmd *cmd = (void *) data; - struct gap_set_bondable_rp rp; - - SYS_LOG_DBG(""); - - ble_hs_cfg.sm_bonding = cmd->bondable; - if (ble_hs_cfg.sm_bonding) { - current_settings |= BIT(GAP_SETTINGS_BONDABLE); - } else { - current_settings &= ~BIT(GAP_SETTINGS_BONDABLE); - } - - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_BONDABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); -} - -static struct bt_data ad[10] = { - BT_DATA(BLE_HS_ADV_TYPE_FLAGS, &ad_flags, sizeof(ad_flags)), -}; -static struct bt_data sd[10]; - -static int set_ad(const struct bt_data *ad, size_t ad_len, - uint8_t *buf, uint8_t *buf_len) -{ - int i; - - for (i = 0; i < ad_len; i++) { - buf[(*buf_len)++] = ad[i].data_len + 1; - buf[(*buf_len)++] = ad[i].type; - - memcpy(&buf[*buf_len], ad[i].data, - ad[i].data_len); - *buf_len += ad[i].data_len; - } - - return 0; -} - -static void start_advertising(const uint8_t *data, uint16_t len) -{ - const struct gap_start_advertising_cmd *cmd = (void *) data; - struct gap_start_advertising_rp rp; - int32_t duration_ms = BLE_HS_FOREVER; - uint8_t buf[BLE_HS_ADV_MAX_SZ]; - uint8_t buf_len = 0; - uint8_t adv_len, sd_len; - int err; - - int i; - - SYS_LOG_DBG(""); - - for (i = 0, adv_len = 1; i < cmd->adv_data_len; adv_len++) { - if (adv_len >= ARRAY_SIZE(ad)) { - SYS_LOG_ERR("ad[] Out of memory"); - goto fail; - } - - ad[adv_len].type = cmd->adv_data[i++]; - ad[adv_len].data_len = cmd->adv_data[i++]; - ad[adv_len].data = &cmd->adv_data[i]; - i += ad[adv_len].data_len; - } - - for (i = 0, sd_len = 0; i < cmd->scan_rsp_len; sd_len++) { - if (sd_len >= ARRAY_SIZE(sd)) { - SYS_LOG_ERR("sd[] Out of memory"); - goto fail; - } - - sd[sd_len].type = cmd->scan_rsp[i++]; - sd[sd_len].data_len = cmd->scan_rsp[i++]; - sd[sd_len].data = &cmd->scan_rsp[i]; - i += sd[sd_len].data_len; - } - - err = set_ad(ad, adv_len, buf, &buf_len); - if (err) { - goto fail; - } - - err = ble_gap_adv_set_data(buf, buf_len); - if (err != 0) { - goto fail; - } - - if (sd_len) { - buf_len = 0; - - err = set_ad(sd, sd_len, buf, &buf_len); - if (err) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - - err = ble_gap_adv_rsp_set_data(buf, buf_len); - if (err != 0) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - } - - if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { - duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); - } - -#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) - if (MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT) < duration_ms / 1000) { - advertising_start = os_get_uptime_usec(); - os_callout_reset(&bttester_nrpa_rotate_timer, - OS_TICKS_PER_SEC * MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT)); - } -#endif - err = ble_gap_adv_start(own_addr_type, NULL, duration_ms, - &adv_params, gap_event_cb, NULL); - if (err) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - - current_settings |= BIT(GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); - return; -fail: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, - BTP_STATUS_FAILED); -} - -static void stop_advertising(const uint8_t *data, uint16_t len) -{ - struct gap_stop_advertising_rp rp; - - SYS_LOG_DBG(""); - - if (ble_gap_adv_stop() != 0) { - tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; - } - - current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); -} - -static uint8_t get_ad_flags(const uint8_t *data, uint8_t data_len) -{ - uint8_t len, i; - - /* Parse advertisement to get flags */ - for (i = 0; i < data_len; i += len - 1) { - len = data[i++]; - if (!len) { - break; - } - - /* Check if field length is correct */ - if (len > (data_len - i) || (data_len - i) < 1) { - break; - } - - switch (data[i++]) { - case BLE_HS_ADV_TYPE_FLAGS: - return data[i]; - default: - break; - } - } - - return 0; -} - -static uint8_t discovery_flags; -static struct os_mbuf *adv_buf; - -static void store_adv(const ble_addr_t *addr, int8_t rssi, - const uint8_t *data, uint8_t len) -{ - struct gap_device_found_ev *ev; - - /* cleanup */ - net_buf_simple_init(adv_buf, 0); - - ev = net_buf_simple_add(adv_buf, sizeof(*ev)); - - memcpy(ev->address, addr->val, sizeof(ev->address)); - ev->address_type = addr->type; - ev->rssi = rssi; - ev->flags = GAP_DEVICE_FOUND_FLAG_AD | GAP_DEVICE_FOUND_FLAG_RSSI; - ev->eir_data_len = len; - memcpy(net_buf_simple_add(adv_buf, len), data, len); -} - -static void device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, - const uint8_t *data, uint8_t len) -{ - struct gap_device_found_ev *ev; - ble_addr_t a; - - /* if General/Limited Discovery - parse Advertising data to get flags */ - if (!(discovery_flags & GAP_DISCOVERY_FLAG_LE_OBSERVE) && - (evtype != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)) { - uint8_t flags = get_ad_flags(data, len); - - /* ignore non-discoverable devices */ - if (!(flags & BLE_AD_DISCOV_MASK)) { - SYS_LOG_DBG("Non discoverable, skipping"); - return; - } - - /* if Limited Discovery - ignore general discoverable devices */ - if ((discovery_flags & GAP_DISCOVERY_FLAG_LIMITED) && - !(flags & BLE_HS_ADV_F_DISC_LTD)) { - SYS_LOG_DBG("General discoverable, skipping"); - return; - } - } - - /* attach Scan Response data */ - if (evtype == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { - /* skip if there is no pending advertisement */ - if (!adv_buf->om_len) { - SYS_LOG_INF("No pending advertisement, skipping"); - return; - } - - ev = (void *) adv_buf->om_data; - a.type = ev->address_type; - memcpy(a.val, ev->address, sizeof(a.val)); - - /* - * in general, the Scan Response comes right after the - * Advertisement, but if not if send stored event and ignore - * this one - */ - if (ble_addr_cmp(addr, &a)) { - SYS_LOG_INF("Address does not match, skipping"); - goto done; - } - - ev->eir_data_len += len; - ev->flags |= GAP_DEVICE_FOUND_FLAG_SD; - - memcpy(net_buf_simple_add(adv_buf, len), data, len); - - goto done; - } - - /* - * if there is another pending advertisement, send it and store the - * current one - */ - if (adv_buf->om_len) { - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, - CONTROLLER_INDEX, adv_buf->om_data, - adv_buf->om_len); - } - - store_adv(addr, rssi, data, len); - - /* if Active Scan and scannable event - wait for Scan Response */ - if ((discovery_flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) && - (evtype == BLE_HCI_ADV_RPT_EVTYPE_ADV_IND || - evtype == BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND)) { - SYS_LOG_DBG("Waiting for scan response"); - return; - } -done: - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, - CONTROLLER_INDEX, adv_buf->om_data, adv_buf->om_len); -} - -static int discovery_cb(struct ble_gap_event *event, void *arg) -{ - if (event->type == BLE_GAP_EVENT_DISC) { - device_found(&event->disc.addr, event->disc.rssi, - event->disc.event_type, event->disc.data, - event->disc.length_data); - } - - return 0; -} - -static void start_discovery(const uint8_t *data, uint16_t len) -{ - const struct gap_start_discovery_cmd *cmd = (void *) data; - struct ble_gap_disc_params params = {0}; - uint8_t status; - - SYS_LOG_DBG(""); - - /* only LE scan is supported */ - if (cmd->flags & GAP_DISCOVERY_FLAG_BREDR) { - status = BTP_STATUS_FAILED; - goto reply; - } - - params.passive = (cmd->flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) == 0; - params.limited = (cmd->flags & GAP_DISCOVERY_FLAG_LIMITED) > 0; - params.filter_duplicates = 1; - - if (ble_gap_disc(own_addr_type, BLE_HS_FOREVER, - ¶ms, discovery_cb, NULL) != 0) { - status = BTP_STATUS_FAILED; - goto reply; - } - - net_buf_simple_init(adv_buf, 0); - discovery_flags = cmd->flags; - - status = BTP_STATUS_SUCCESS; -reply: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DISCOVERY, CONTROLLER_INDEX, - status); -} - -static void stop_discovery(const uint8_t *data, uint16_t len) -{ - uint8_t status = BTP_STATUS_SUCCESS; - - SYS_LOG_DBG(""); - - if (ble_gap_disc_cancel() != 0) { - status = BTP_STATUS_FAILED; - } - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_DISCOVERY, CONTROLLER_INDEX, - status); -} - - -/* Bluetooth Core Spec v5.1 | Section 10.7.1 - * If a privacy-enabled Peripheral, that has a stored bond, - * receives a resolvable private address, the Host may resolve - * the resolvable private address [...] - * If the resolution is successful, the Host may accept the connection. - * If the resolution procedure fails, then the Host shall disconnect - * with the error code "Authentication failure" [...] - */ -static void periph_privacy(struct ble_gap_conn_desc desc) -{ -#if !MYNEWT_VAL(BTTESTER_PRIVACY_MODE) - return; -#endif - int count; - - SYS_LOG_DBG(""); - - ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count); - if (count > 0 && BLE_ADDR_IS_RPA(&desc.peer_id_addr)) { - SYS_LOG_DBG("Authentication failure, disconnecting"); - ble_gap_terminate(desc.conn_handle, BLE_ERR_AUTH_FAIL); - } -} - -static void device_connected_ev_send(struct os_event *ev) -{ - struct ble_gap_conn_desc desc; - int rc; - - SYS_LOG_DBG(""); - - rc = gap_conn_find_by_addr((ble_addr_t *)&connected_ev, &desc); - if (rc) { - tester_rsp(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; - } - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, (uint8_t *) &connected_ev, - sizeof(connected_ev)); - - periph_privacy(desc); -} - -static void le_connected(uint16_t conn_handle, int status) -{ - struct ble_gap_conn_desc desc; - ble_addr_t *addr; - int rc; - - SYS_LOG_DBG(""); - - if (status != 0) { - return; - } - - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } - - peer_id_addr = desc.peer_id_addr; - peer_ota_addr = desc.peer_ota_addr; - - addr = &desc.peer_id_addr; - - memcpy(connected_ev.address, addr->val, sizeof(connected_ev.address)); - connected_ev.address_type = addr->type; - connected_ev.conn_itvl = desc.conn_itvl; - connected_ev.conn_latency = desc.conn_latency; - connected_ev.supervision_timeout = desc.supervision_timeout; - -#if MYNEWT_VAL(BTTESTER_CONN_RETRY) - os_callout_reset(&connected_ev_co, - os_time_ms_to_ticks32( - CONNECTED_EV_DELAY_MS(desc.conn_itvl))); -#else - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, (uint8_t *) &connected_ev, - sizeof(connected_ev)); -#endif -} - -static void le_disconnected(struct ble_gap_conn_desc *conn, int reason) -{ - struct gap_device_disconnected_ev ev; - ble_addr_t *addr = &conn->peer_ota_addr; - - SYS_LOG_DBG(""); - -#if MYNEWT_VAL(BTTESTER_CONN_RETRY) - int rc; - - if ((reason == BLE_HS_HCI_ERR(BLE_ERR_CONN_ESTABLISHMENT)) && - os_callout_queued(&connected_ev_co)) { - if (connection_attempts < MYNEWT_VAL(BTTESTER_CONN_RETRY)) { - os_callout_stop(&connected_ev_co); - - /* try connecting again */ - rc = ble_gap_connect(own_addr_type, addr, 0, - &dflt_conn_params, gap_event_cb, - NULL); - - if (rc == 0) { - connection_attempts++; - return; - } - } - } else if (os_callout_queued(&connected_ev_co)) { - os_callout_stop(&connected_ev_co); - return; - } -#endif - - connection_attempts = 0; - memset(&connected_ev, 0, sizeof(connected_ev)); - - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_DISCONNECTED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void auth_passkey_oob(uint16_t conn_handle) -{ - struct ble_gap_conn_desc desc; - struct ble_sm_io pk; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } - - memcpy(pk.oob, oob, sizeof(oob)); - pk.action = BLE_SM_IOACT_OOB; - - rc = ble_sm_inject_io(conn_handle, &pk); - assert(rc == 0); -} - -static void auth_passkey_display(uint16_t conn_handle, unsigned int passkey) -{ - struct ble_gap_conn_desc desc; - struct gap_passkey_display_ev ev; - ble_addr_t *addr; - struct ble_sm_io pk; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } - - rc = ble_hs_hci_util_rand(&pk.passkey, sizeof(pk.passkey)); - assert(rc == 0); - /* Max value is 999999 */ - pk.passkey %= 1000000; - pk.action = BLE_SM_IOACT_DISP; - - rc = ble_sm_inject_io(conn_handle, &pk); - assert(rc == 0); - - addr = &desc.peer_ota_addr; - - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; - ev.passkey = sys_cpu_to_le32(pk.passkey); - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_DISPLAY, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void auth_passkey_entry(uint16_t conn_handle) -{ - struct ble_gap_conn_desc desc; - struct gap_passkey_entry_req_ev ev; - ble_addr_t *addr; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } - - addr = &desc.peer_ota_addr; - - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_ENTRY_REQ, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) -{ - struct ble_gap_conn_desc desc; - struct gap_passkey_confirm_req_ev ev; - ble_addr_t *addr; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } - - addr = &desc.peer_ota_addr; - - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; - ev.passkey = sys_cpu_to_le32(passkey); - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_CONFIRM_REQ, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void auth_passkey_oob_sc(uint16_t conn_handle) -{ - int rc; - struct ble_sm_io pk; - - SYS_LOG_DBG(""); - - memset(&pk, 0, sizeof(pk)); - - pk.oob_sc_data.local = &oob_data_local; - - if (ble_hs_cfg.sm_oob_data_flag) { - pk.oob_sc_data.remote = &oob_data_remote; - } - - pk.action = BLE_SM_IOACT_OOB_SC; - rc = ble_sm_inject_io(conn_handle, &pk); - if (rc != 0) { - console_printf("error providing oob; rc=%d\n", rc); - } -} - -static void le_passkey_action(uint16_t conn_handle, - struct ble_gap_passkey_params *params) -{ - SYS_LOG_DBG(""); - - switch (params->action) { - case BLE_SM_IOACT_NONE: - break; - case BLE_SM_IOACT_OOB: - auth_passkey_oob(conn_handle); - break; - case BLE_SM_IOACT_INPUT: - auth_passkey_entry(conn_handle); - break; - case BLE_SM_IOACT_DISP: - auth_passkey_display(conn_handle, params->numcmp); - break; - case BLE_SM_IOACT_NUMCMP: - auth_passkey_numcmp(conn_handle, params->numcmp); - break; - case BLE_SM_IOACT_OOB_SC: - auth_passkey_oob_sc(conn_handle); - break; - default: - assert(0); - } -} - -static void le_identity_resolved(uint16_t conn_handle) -{ - struct ble_gap_conn_desc desc; - struct gap_identity_resolved_ev ev; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } - - peer_id_addr = desc.peer_id_addr; - peer_ota_addr = desc.peer_ota_addr; - - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, sizeof(ev.address)); - - ev.identity_address_type = desc.peer_id_addr.type; - memcpy(ev.identity_address, desc.peer_id_addr.val, - sizeof(ev.identity_address)); - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_IDENTITY_RESOLVED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void le_conn_param_update(struct ble_gap_conn_desc *desc) -{ - struct gap_conn_param_update_ev ev; - - SYS_LOG_DBG(""); - - ev.address_type = desc->peer_ota_addr.type; - memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); - - ev.conn_itvl = desc->conn_itvl; - ev.conn_latency = desc->conn_latency; - ev.supervision_timeout = desc->supervision_timeout; - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void le_encryption_changed(struct ble_gap_conn_desc *desc) -{ - struct gap_sec_level_changed_ev ev; - - SYS_LOG_DBG(""); - - encrypted = (bool) desc->sec_state.encrypted; - - ev.address_type = desc->peer_ota_addr.type; - memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); - ev.level = 0; - - if (desc->sec_state.encrypted) { - if (desc->sec_state.authenticated) { - if (desc->sec_state.key_size == 16) { - ev.level = 3; - } else { - ev.level = 2; - } - } else { - ev.level = 1; - } - } - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_LEVEL_CHANGED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void print_bytes(const uint8_t *bytes, int len) -{ - int i; - - for (i = 0; i < len; i++) { - console_printf("%s0x%02x", i != 0 ? ":" : "", bytes[i]); - } -} - -static void print_mbuf(const struct os_mbuf *om) -{ - int colon; - - colon = 0; - while (om != NULL) { - if (colon) { - console_printf(":"); - } else { - colon = 1; - } - print_bytes(om->om_data, om->om_len); - om = SLIST_NEXT(om, om_next); - } -} - -static void print_addr(const void *addr) -{ - const uint8_t *u8p; - - u8p = addr; - console_printf("%02x:%02x:%02x:%02x:%02x:%02x", - u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); -} - -static void print_conn_desc(const struct ble_gap_conn_desc *desc) -{ - console_printf("handle=%d our_ota_addr_type=%d our_ota_addr=", - desc->conn_handle, desc->our_ota_addr.type); - print_addr(desc->our_ota_addr.val); - console_printf(" our_id_addr_type=%d our_id_addr=", - desc->our_id_addr.type); - print_addr(desc->our_id_addr.val); - console_printf(" peer_ota_addr_type=%d peer_ota_addr=", - desc->peer_ota_addr.type); - print_addr(desc->peer_ota_addr.val); - console_printf(" peer_id_addr_type=%d peer_id_addr=", - desc->peer_id_addr.type); - print_addr(desc->peer_id_addr.val); - console_printf(" conn_itvl=%d conn_latency=%d supervision_timeout=%d " - "key_sz=%d encrypted=%d authenticated=%d bonded=%d\n", - desc->conn_itvl, desc->conn_latency, - desc->supervision_timeout, - desc->sec_state.key_size, - desc->sec_state.encrypted, - desc->sec_state.authenticated, - desc->sec_state.bonded); -} - -static void adv_complete(void) -{ - struct gap_new_settings_ev ev; - - current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); - ev.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX, - (uint8_t *) &ev, sizeof(ev)); -} - -static int gap_event_cb(struct ble_gap_event *event, void *arg) -{ - struct ble_gap_conn_desc desc; - int rc; - - switch (event->type) { - case BLE_GAP_EVENT_ADV_COMPLETE: - console_printf("advertising complete; reason=%d\n", - event->adv_complete.reason); - break; - case BLE_GAP_EVENT_CONNECT: - console_printf("connection %s; status=%d ", - event->connect.status == 0 ? "established" : "failed", - event->connect.status); - if (event->connect.status == 0) { - rc = ble_gap_conn_find(event->connect.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - } - - if (desc.role == BLE_GAP_ROLE_SLAVE) { - adv_complete(); - } - - le_connected(event->connect.conn_handle, - event->connect.status); - break; - case BLE_GAP_EVENT_DISCONNECT: - console_printf("disconnect; reason=%d ", event->disconnect.reason); - print_conn_desc(&event->disconnect.conn); - le_disconnected(&event->disconnect.conn, - event->disconnect.reason); - break; - case BLE_GAP_EVENT_ENC_CHANGE: - console_printf("encryption change event; status=%d ", event->enc_change.status); - rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - le_encryption_changed(&desc); - break; - case BLE_GAP_EVENT_PASSKEY_ACTION: - console_printf("passkey action event; action=%d", - event->passkey.params.action); - if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { - console_printf(" numcmp=%lu", - (unsigned long)event->passkey.params.numcmp); - } - console_printf("\n"); - le_passkey_action(event->passkey.conn_handle, - &event->passkey.params); - break; - case BLE_GAP_EVENT_IDENTITY_RESOLVED: - console_printf("identity resolved "); - rc = ble_gap_conn_find(event->identity_resolved.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - le_identity_resolved(event->identity_resolved.conn_handle); - break; - case BLE_GAP_EVENT_NOTIFY_RX: - console_printf("notification rx event; attr_handle=%d indication=%d " - "len=%d data=", - event->notify_rx.attr_handle, - event->notify_rx.indication, - OS_MBUF_PKTLEN(event->notify_rx.om)); - - print_mbuf(event->notify_rx.om); - console_printf("\n"); - tester_gattc_notify_rx_ev(event->notify_rx.conn_handle, - event->notify_rx.attr_handle, - event->notify_rx.indication, - event->notify_rx.om); - break; - case BLE_GAP_EVENT_SUBSCRIBE: - console_printf("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); - tester_gatt_subscribe_ev(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); - break; - case BLE_GAP_EVENT_REPEAT_PAIRING: - console_printf("repeat pairing event; conn_handle=%d " - "cur_key_sz=%d cur_auth=%d cur_sc=%d " - "new_key_sz=%d new_auth=%d new_sc=%d " - "new_bonding=%d\n", - event->repeat_pairing.conn_handle, - event->repeat_pairing.cur_key_size, - event->repeat_pairing.cur_authenticated, - event->repeat_pairing.cur_sc, - event->repeat_pairing.new_key_size, - event->repeat_pairing.new_authenticated, - event->repeat_pairing.new_sc, - event->repeat_pairing.new_bonding); - rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); - assert(rc == 0); - rc = ble_store_util_delete_peer(&desc.peer_id_addr); - assert(rc == 0); - return BLE_GAP_REPEAT_PAIRING_RETRY; - case BLE_GAP_EVENT_CONN_UPDATE: - console_printf("connection update event; status=%d ", - event->conn_update.status); - rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - le_conn_param_update(&desc); - break; - case BLE_GAP_EVENT_CONN_UPDATE_REQ: - console_printf("connection update request event; " - "conn_handle=%d itvl_min=%d itvl_max=%d " - "latency=%d supervision_timoeut=%d " - "min_ce_len=%d max_ce_len=%d\n", - event->conn_update_req.conn_handle, - event->conn_update_req.peer_params->itvl_min, - event->conn_update_req.peer_params->itvl_max, - event->conn_update_req.peer_params->latency, - event->conn_update_req.peer_params->supervision_timeout, - event->conn_update_req.peer_params->min_ce_len, - event->conn_update_req.peer_params->max_ce_len); - - *event->conn_update_req.self_params = - *event->conn_update_req.peer_params; - break; - case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: - console_printf("connection update request event; " - "conn_handle=%d itvl_min=%d itvl_max=%d " - "latency=%d supervision_timoeut=%d " - "min_ce_len=%d max_ce_len=%d\n", - event->conn_update_req.conn_handle, - event->conn_update_req.peer_params->itvl_min, - event->conn_update_req.peer_params->itvl_max, - event->conn_update_req.peer_params->latency, - event->conn_update_req.peer_params->supervision_timeout, - event->conn_update_req.peer_params->min_ce_len, - event->conn_update_req.peer_params->max_ce_len); - if (event->conn_update_req.peer_params->itvl_min == REJECT_INTERVAL_MIN && - event->conn_update_req.peer_params->itvl_max == REJECT_INTERVAL_MAX && - event->conn_update_req.peer_params->latency == REJECT_LATENCY && - event->conn_update_req.peer_params->supervision_timeout == REJECT_SUPERVISION_TIMEOUT) { - return EINVAL; - } - - default: - break; - } - - return 0; -} - -static void connect(const uint8_t *data, uint16_t len) -{ - uint8_t status = BTP_STATUS_SUCCESS; - ble_addr_t *addr = (ble_addr_t *) data; - - SYS_LOG_DBG(""); - - if (ble_addr_cmp(BLE_ADDR_ANY, addr) == 0) { - addr = NULL; - } - - if (ble_gap_connect(own_addr_type, addr, 0, - &dflt_conn_params, gap_event_cb, NULL)) { - status = BTP_STATUS_FAILED; - } - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONNECT, CONTROLLER_INDEX, status); -} - -static void disconnect(const uint8_t *data, uint16_t len) -{ - struct ble_gap_conn_desc desc; - uint8_t status; - int rc; - - SYS_LOG_DBG(""); - - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gap_terminate(desc.conn_handle, BLE_ERR_REM_USER_CONN_TERM)) { - status = BTP_STATUS_FAILED; - } else { - status = BTP_STATUS_SUCCESS; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_DISCONNECT, CONTROLLER_INDEX, - status); -} - -static void set_io_cap(const uint8_t *data, uint16_t len) -{ - const struct gap_set_io_cap_cmd *cmd = (void *) data; - uint8_t status; - - SYS_LOG_DBG(""); - - switch (cmd->io_cap) { - case GAP_IO_CAP_DISPLAY_ONLY: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY; - ble_hs_cfg.sm_mitm = 1; - break; - case GAP_IO_CAP_KEYBOARD_DISPLAY: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_DISP; - ble_hs_cfg.sm_mitm = 1; - break; - case GAP_IO_CAP_NO_INPUT_OUTPUT: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO; - ble_hs_cfg.sm_mitm = 0; - break; - case GAP_IO_CAP_KEYBOARD_ONLY: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_ONLY; - ble_hs_cfg.sm_mitm = 1; - break; - case GAP_IO_CAP_DISPLAY_YESNO: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_YES_NO; - ble_hs_cfg.sm_mitm = 1; - break; - default: - status = BTP_STATUS_FAILED; - goto rsp; - } - - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_IO_CAP, CONTROLLER_INDEX, - status); -} - -static void pair(const uint8_t *data, uint16_t len) -{ - struct ble_gap_conn_desc desc; - uint8_t status; - int rc; - - SYS_LOG_DBG(""); - - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gap_security_initiate(desc.conn_handle)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status); -} - -static void unpair(const uint8_t *data, uint16_t len) -{ - uint8_t status; - int err; - - SYS_LOG_DBG(""); - - err = ble_gap_unpair((ble_addr_t *) data); - status = (uint8_t) (err != 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_UNPAIR, CONTROLLER_INDEX, status); -} - -static void passkey_entry(const uint8_t *data, uint16_t len) -{ - const struct gap_passkey_entry_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; - struct ble_sm_io pk; - uint8_t status; - int rc; - - SYS_LOG_DBG(""); - - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - pk.action = BLE_SM_IOACT_INPUT; - pk.passkey = sys_le32_to_cpu(cmd->passkey); - - rc = ble_sm_inject_io(desc.conn_handle, &pk); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_ENTRY, CONTROLLER_INDEX, - status); -} - -static void passkey_confirm(const uint8_t *data, uint16_t len) -{ - const struct gap_passkey_confirm_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; - struct ble_sm_io pk; - uint8_t status; - int rc; - - SYS_LOG_DBG(""); - - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - pk.action = BLE_SM_IOACT_NUMCMP; - pk.numcmp_accept = cmd->match; - - rc = ble_sm_inject_io(desc.conn_handle, &pk); - if (rc) { - console_printf("sm inject io failed"); - status = BTP_STATUS_FAILED; - goto rsp; - } - - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_CONFIRM, CONTROLLER_INDEX, - status); -} - -static void start_direct_adv(const uint8_t *data, uint16_t len) -{ - const struct gap_start_direct_adv_cmd *cmd = (void *) data; - struct gap_start_advertising_rp rp; - static struct ble_gap_adv_params adv_params = { - .conn_mode = BLE_GAP_CONN_MODE_DIR, - }; - int err; - - SYS_LOG_DBG(""); - - adv_params.high_duty_cycle = cmd->high_duty; - - err = ble_gap_adv_start(own_addr_type, (ble_addr_t *)data, - BLE_HS_FOREVER, &adv_params, - gap_event_cb, NULL); - if (err) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - - current_settings |= BIT(GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); - return; -fail: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, - BTP_STATUS_FAILED); -} - -static void conn_param_update_cb(uint16_t conn_handle, int status, void *arg) -{ - console_printf("conn param update complete; conn_handle=%d status=%d\n", - conn_handle, status); -} - -static int conn_param_update_slave(uint16_t conn_handle, - const struct gap_conn_param_update_cmd *cmd) -{ - int rc; - struct ble_l2cap_sig_update_params params; - - params.itvl_min = cmd->conn_itvl_min; - params.itvl_max = cmd->conn_itvl_max; - params.slave_latency = cmd->conn_latency; - params.timeout_multiplier = cmd->supervision_timeout; - - rc = ble_l2cap_sig_update(conn_handle, ¶ms, - conn_param_update_cb, NULL); - if (rc) { - SYS_LOG_ERR("Failed to send update params: rc=%d", rc); - } - - return 0; -} - -static int conn_param_update_master(uint16_t conn_handle, - const struct gap_conn_param_update_cmd *cmd) -{ - int rc; - struct ble_gap_upd_params params; - - params.itvl_min = cmd->conn_itvl_min; - params.itvl_max = cmd->conn_itvl_max; - params.latency = cmd->conn_latency; - params.supervision_timeout = cmd->supervision_timeout; - params.min_ce_len = 0; - params.max_ce_len = 0; - rc = ble_gap_update_params(conn_handle, ¶ms); - if (rc) { - SYS_LOG_ERR("Failed to send update params: rc=%d", rc); - } - - return rc; -} - -static void conn_param_update(struct os_event *ev) -{ - struct ble_gap_conn_desc desc; - int rc; - - SYS_LOG_DBG(""); - - rc = gap_conn_find_by_addr((ble_addr_t *)&update_params, &desc); - if (rc) { - goto rsp; - } - - if ((desc.conn_itvl >= update_params.conn_itvl_min) && - (desc.conn_itvl <= update_params.conn_itvl_max) && - (desc.conn_latency == update_params.conn_latency) && - (desc.supervision_timeout == update_params.supervision_timeout)) { - goto rsp; - } - - if (desc.role == BLE_GAP_ROLE_MASTER) { - rc = conn_param_update_master(desc.conn_handle, &update_params); - } else { - rc = conn_param_update_slave(desc.conn_handle, &update_params); - } - - if (rc == 0) { - return; - } - -rsp: - SYS_LOG_ERR("Conn param update fail; rc=%d", rc); -} - -static void conn_param_update_async(const uint8_t *data, uint16_t len) -{ - const struct gap_conn_param_update_cmd *cmd = (void *) data; - update_params = *cmd; - - os_callout_reset(&update_params_co, 0); - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); -} - -static void oob_legacy_set_data(const uint8_t *data, uint16_t len) -{ - const struct gap_oob_legacy_set_data_cmd *cmd = (void *) data; - - ble_hs_cfg.sm_oob_data_flag = 1; - memcpy(oob, cmd->oob_data, sizeof(oob)); - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_LEGACY_SET_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); -} - -static void oob_sc_get_local_data(const uint8_t *data, uint16_t len) -{ - struct gap_oob_sc_get_local_data_rp rp; - - memcpy(rp.r, oob_data_local.r, 16); - memcpy(rp.c, oob_data_local.c, 16); - - tester_send(BTP_SERVICE_ID_GAP, GAP_OOB_SC_GET_LOCAL_DATA, - CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); -} - -static void oob_sc_set_remote_data(const uint8_t *data, uint16_t len) -{ - const struct gap_oob_sc_set_remote_data_cmd *cmd = (void *) data; - - ble_hs_cfg.sm_oob_data_flag = 1; - memcpy(oob_data_remote.r, cmd->r, 16); - memcpy(oob_data_remote.c, cmd->c, 16); - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_SC_SET_REMOTE_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); -} - -static void set_mitm(const uint8_t *data, uint16_t len) -{ - const struct gap_set_mitm_cmd *cmd = (void *) data; - - ble_hs_cfg.sm_mitm = cmd->mitm; - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_MITM, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); -} - -static void set_filter_accept_list(const uint8_t *data, uint16_t len) -{ - uint8_t status = BTP_STATUS_SUCCESS; - struct gap_set_filter_accept_list_cmd *tmp = - (struct gap_set_filter_accept_list_cmd *) data; - - SYS_LOG_DBG(""); - - /* - * Check if the nb of bytes received matches the len of addrs list. - * Then set the filter accept list. - */ - if (((len - sizeof(tmp->list_len))/sizeof(ble_addr_t) != - tmp->list_len) || ble_gap_wl_set(tmp->addrs, tmp->list_len)) { - status = BTP_STATUS_FAILED; - } - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_FILTER_ACCEPT_LIST, - CONTROLLER_INDEX, status); -} - -void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) -{ - switch (opcode) { - case GAP_READ_SUPPORTED_COMMANDS: - case GAP_READ_CONTROLLER_INDEX_LIST: - if (index != BTP_INDEX_NONE){ - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_FAILED); - return; - } - break; - default: - if (index != CONTROLLER_INDEX){ - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_FAILED); - return; - } - break; - } - - switch (opcode) { - case GAP_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case GAP_READ_CONTROLLER_INDEX_LIST: - controller_index_list(data, len); - return; - case GAP_READ_CONTROLLER_INFO: - controller_info(data, len); - return; - case GAP_SET_CONNECTABLE: - set_connectable(data, len); - return; - case GAP_SET_DISCOVERABLE: - set_discoverable(data, len); - return; - case GAP_SET_BONDABLE: - set_bondable(data, len); - return; - case GAP_START_ADVERTISING: - start_advertising(data, len); - return; - case GAP_STOP_ADVERTISING: - stop_advertising(data, len); - return; - case GAP_START_DISCOVERY: - start_discovery(data, len); - return; - case GAP_STOP_DISCOVERY: - stop_discovery(data, len); - return; - case GAP_CONNECT: - connect(data, len); - return; - case GAP_DISCONNECT: - disconnect(data, len); - return; - case GAP_SET_IO_CAP: - set_io_cap(data, len); - return; - case GAP_PAIR: - pair(data, len); - return; - case GAP_UNPAIR: - unpair(data, len); - return; - case GAP_PASSKEY_ENTRY: - passkey_entry(data, len); - return; - case GAP_PASSKEY_CONFIRM: - passkey_confirm(data, len); - return; - case GAP_START_DIRECT_ADV: - start_direct_adv(data, len); - return; - case GAP_CONN_PARAM_UPDATE: - conn_param_update_async(data, len); - return; - case GAP_OOB_LEGACY_SET_DATA: - oob_legacy_set_data(data, len); - return; - case GAP_OOB_SC_GET_LOCAL_DATA: - oob_sc_get_local_data(data, len); - return; - case GAP_OOB_SC_SET_REMOTE_DATA: - oob_sc_set_remote_data(data, len); - return; - case GAP_SET_MITM: - set_mitm(data, len); - return; - case GAP_SET_FILTER_ACCEPT_LIST: - set_filter_accept_list(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } -} - -static void tester_init_gap_cb(int err) -{ - if (err) { - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, - BTP_INDEX_NONE, BTP_STATUS_FAILED); - return; - } - - current_settings = 0; - current_settings |= BIT(GAP_SETTINGS_POWERED); - current_settings |= BIT(GAP_SETTINGS_LE); - - os_callout_init(&update_params_co, os_eventq_dflt_get(), - conn_param_update, NULL); - - os_callout_init(&connected_ev_co, os_eventq_dflt_get(), - device_connected_ev_send, NULL); - - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE, - BTP_STATUS_SUCCESS); -} - -uint8_t tester_init_gap(void) -{ -#if MYNEWT_VAL(BLE_SM_SC) - int rc; - - rc = ble_sm_sc_oob_generate_data(&oob_data_local); - if (rc) { - console_printf("Error: generating oob data; reason=%d\n", rc); - return BTP_STATUS_FAILED; - } -#endif -#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) - os_callout_init(&bttester_nrpa_rotate_timer, os_eventq_dflt_get(), - rotate_nrpa_cb, NULL); -#endif - adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN); - - tester_init_gap_cb(BTP_STATUS_SUCCESS); - return BTP_STATUS_SUCCESS; -} - -uint8_t tester_unregister_gap(void) -{ - return BTP_STATUS_SUCCESS; -} diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/gatt_cl.c b/lib/bt/host/nimble/nimble/apps/bttester/src/gatt_cl.c deleted file mode 100644 index c551bb17..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/gatt_cl.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include - -#include "host/ble_gap.h" -#include "host/ble_gatt.h" -#include "console/console.h" -#include "services/gatt/ble_svc_gatt.h" -#include "../../../nimble/host/src/ble_att_priv.h" -#include "../../../nimble/host/src/ble_gatt_priv.h" - -#include "bttester.h" - -#define CONTROLLER_INDEX 0 -#define MAX_BUFFER_SIZE 2048 - -/* Convert UUID from BTP command to bt_uuid */ -static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len, - ble_uuid_any_t *bt_uuid) -{ - uint16_t le16; - - switch (len) { - case 0x02: /* UUID 16 */ - bt_uuid->u.type = BLE_UUID_TYPE_16; - memcpy(&le16, uuid, sizeof(le16)); - BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); - break; - case 0x10: /* UUID 128*/ - bt_uuid->u.type = BLE_UUID_TYPE_128; - memcpy(BLE_UUID128(bt_uuid)->value, uuid, 16); - break; - default: - return BTP_STATUS_FAILED; - } - return BTP_STATUS_SUCCESS; -} - -/* - * gatt_buf - cache used by a gatt client (to cache data read/discovered) - * and gatt server (to store attribute user_data). - * It is not intended to be used by client and server at the same time. - */ -static struct { - uint16_t len; - uint8_t buf[MAX_BUFFER_SIZE]; - uint16_t cnt; -} gatt_buf; -static struct bt_gatt_subscribe_params { - uint16_t ccc_handle; - uint16_t value; - uint16_t value_handle; -} subscribe_params; - -static void *gatt_buf_add(const void *data, size_t len) -{ - void *ptr = gatt_buf.buf + gatt_buf.len; - - if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) { - return NULL; - } - - if (data) { - memcpy(ptr, data, len); - } else { - (void) memset(ptr, 0, len); - } - - gatt_buf.len += len; - - SYS_LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE); - - return ptr; -} - -static void *gatt_buf_reserve(size_t len) -{ - return gatt_buf_add(NULL, len); -} - -static void gatt_buf_clear(void) -{ - (void) memset(&gatt_buf, 0, sizeof(gatt_buf)); -} - -static void discover_destroy(void) -{ - gatt_buf_clear(); -} - -static void read_destroy() -{ - gatt_buf_clear(); -} - -static int tester_mtu_exchanged_ev(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t mtu, void *arg) -{ - struct gattc_exchange_mtu_ev *ev; - struct ble_gap_conn_desc conn; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - goto fail; - } - - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); - - addr = &conn.peer_ota_addr; - - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); - - ev->mtu = mtu; - - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_MTU_EXCHANGED, - CONTROLLER_INDEX, buf); -fail: - os_mbuf_free_chain(buf); - return 0; -} - -static void exchange_mtu(uint8_t *data, uint16_t len) -{ - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gattc_exchange_mtu(conn.conn_handle, tester_mtu_exchanged_ev, NULL)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_EXCHANGE_MTU, - CONTROLLER_INDEX, status); -} - -static int disc_prim_svcs_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_svc *gatt_svc, void *arg) -{ - struct gattc_disc_prim_svcs_rp *rp; - struct ble_gap_conn_desc conn; - struct gatt_service *service; - const ble_uuid_any_t *uuid; - const ble_addr_t *addr; - uint8_t uuid_length; - struct os_mbuf *buf = os_msys_get(0, 0); - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->services_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->services_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_svc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - service = gatt_buf_reserve(sizeof(*service) + uuid_length); - if (!service) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); - service->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(service->uuid, &u16, uuid_length); - } else { - memcpy(service->uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - gatt_buf.cnt++; - -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void disc_all_prim_svcs(uint8_t *data, uint16_t len) -{ - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_svcs_cb, - (void *) GATTC_DISC_ALL_PRIM_RP)) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_PRIM_SVCS, - CONTROLLER_INDEX, status); -} - -static void disc_prim_uuid(uint8_t *data, uint16_t len) -{ - const struct gattc_disc_prim_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, - &uuid.u, disc_prim_svcs_cb, - (void *) GATTC_DISC_PRIM_UUID_RP)) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_PRIM_UUID, CONTROLLER_INDEX, - status); -} - -static int find_included_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_svc *gatt_svc, void *arg) -{ - struct gattc_find_included_rp *rp; - struct gatt_included *included; - const ble_uuid_any_t *uuid; - int service_handle = (int) arg; - uint8_t uuid_length; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - SYS_LOG_DBG(""); - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->services_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->services_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_svc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - included = gatt_buf_reserve(sizeof(*included) + uuid_length); - if (!included) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - included->included_handle = sys_cpu_to_le16(service_handle + 1 + - rp->services_count); - included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); - included->service.uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(included->service.uuid, &u16, uuid_length); - } else { - memcpy(included->service.uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - gatt_buf.cnt++; - -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void find_included(uint8_t *data, uint16_t len) -{ - const struct gattc_find_included_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - int service_handle_arg; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - service_handle_arg = start_handle; - - if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, - find_included_cb, - (void *) service_handle_arg)) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED, CONTROLLER_INDEX, - status); -} - -static int disc_chrc_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_chr *gatt_chr, void *arg) -{ - struct gattc_disc_chrc_rp *rp; - struct gatt_characteristic *chrc; - const ble_uuid_any_t *uuid; - uint8_t uuid_length; - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - if (ble_gap_conn_find(conn_handle, &conn)) { - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->characteristics_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->characteristics_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_chr->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length); - if (!chrc) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); - chrc->properties = gatt_chr->properties; - chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); - chrc->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(chrc->uuid, &u16, uuid_length); - } else { - memcpy(chrc->uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - gatt_buf.cnt++; -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void disc_all_chrc(uint8_t *data, uint16_t len) -{ - const struct gattc_disc_all_chrc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - SYS_LOG_DBG("Conn find rsped"); - status = BTP_STATUS_FAILED; - goto rsp; - } - - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - - rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, - disc_chrc_cb, (void *) GATTC_DISC_ALL_CHRC_RP); - if (rc) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_CHRC, CONTROLLER_INDEX, - status); -} - -static void disc_chrc_uuid(uint8_t *data, uint16_t len) -{ - const struct gattc_disc_chrc_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - - rc = ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, - end_handle, &uuid.u, disc_chrc_cb, - (void *) GATTC_DISC_CHRC_UUID_RP); - if (rc) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_CHRC_UUID, CONTROLLER_INDEX, - status); -} - -static int disc_all_desc_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t chr_val_handle, - const struct ble_gatt_dsc *gatt_dsc, - void *arg) -{ - struct gattc_disc_all_desc_rp *rp; - struct gatt_descriptor *dsc; - const ble_uuid_any_t *uuid; - uint8_t uuid_length; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->descriptors_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->descriptors_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_dsc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); - if (!dsc) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); - dsc->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(dsc->uuid, &u16, uuid_length); - } else { - memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); - } - - gatt_buf.cnt++; - -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void disc_all_desc(uint8_t *data, uint16_t len) -{ - const struct gattc_disc_all_desc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; - end_handle = sys_le16_to_cpu(cmd->end_handle); - - rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, end_handle, - disc_all_desc_cb, (void *) GATTC_DISC_ALL_DESC); - - SYS_LOG_DBG("rc=%d", rc); - - if (rc) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC, CONTROLLER_INDEX, - status); -} - -static int read_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) -{ - struct gattc_read_rp *rp; - uint8_t opcode = (uint8_t) (int) arg; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - SYS_LOG_DBG("status=%d", error->status); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->status = (uint8_t) BLE_HS_ATT_ERR(error->status); - rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (!gatt_buf_add(attr->om->om_data, attr->om->om_len)) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - rp->status = 0; - rp->data_length = attr->om->om_len; - os_mbuf_appendfrom(buf, attr->om, 0, os_mbuf_len(attr->om)); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void read(uint8_t *data, uint16_t len) -{ - const struct gattc_read_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - /* Clear buffer */ - read_destroy(); - - if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - read_cb, (void *) GATTC_READ_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ, CONTROLLER_INDEX, - status); -} - -static int read_uuid_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) -{ - struct gattc_read_uuid_rp *rp; - struct gatt_read_uuid_chr *chr; - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - static uint16_t attr_len; - - SYS_LOG_DBG("status=%d", error->status); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->data_length = gatt_buf.len; - rp->value_length = attr_len; - rp->status = 0; - os_mbuf_append(buf, gatt_buf.buf+1, gatt_buf.len-1); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (error->status == 0) { - attr_len = attr->om->om_len; - } - - if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - chr = gatt_buf_reserve(sizeof(*chr) + attr->om->om_len); - if (!chr) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - chr->handle = sys_cpu_to_be16(attr->handle); - memcpy(chr->data, attr->om->om_data, attr->om->om_len); - -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void read_uuid(uint8_t *data, uint16_t len) -{ - const struct gattc_read_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - /* Clear buffer */ - read_destroy(); - - if (ble_gattc_read_by_uuid(conn.conn_handle, - sys_le16_to_cpu(cmd->start_handle), - sys_le16_to_cpu(cmd->end_handle), &uuid.u, - read_uuid_cb, (void *) GATTC_READ_UUID_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_UUID, CONTROLLER_INDEX, - status); -} - -static int read_long_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) -{ - struct gattc_read_rp *rp;; - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG("status=%d", error->status); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->data_length = gatt_buf.len; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - rp->data_length += attr->om->om_len; - -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void read_long(uint8_t *data, uint16_t len) -{ - const struct gattc_read_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - /* Clear buffer */ - read_destroy(); - - if (ble_gattc_read_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), - read_long_cb, (void *) GATTC_READ_LONG_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_LONG, CONTROLLER_INDEX, - status); -} - -static void read_multiple(uint8_t *data, uint16_t len) -{ - const struct gattc_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc, i; - - SYS_LOG_DBG(""); - - for (i = 0; i < ARRAY_SIZE(handles); i++) { - handles[i] = sys_le16_to_cpu(cmd->handles[i]); - } - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - /* Clear buffer */ - read_destroy(); - - if (ble_gattc_read_mult(conn.conn_handle, handles, - cmd->handles_count, read_cb, (void *) GATTC_READ_MULTIPLE_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_MULTIPLE, CONTROLLER_INDEX, - status); -} - -static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) -{ - const struct gattc_write_without_rsp_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gattc_write_no_rsp_flat(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), cmd->data, - sys_le16_to_cpu(cmd->data_length))) { - status = BTP_STATUS_FAILED; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); -} - -static int write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) -{ - struct gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; - uint8_t opcode = (uint8_t) (int) arg; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void write(uint8_t *data, uint16_t len) -{ - const struct gattc_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - cmd->data, sys_le16_to_cpu(cmd->data_length), - write_cb, (void *) GATTC_WRITE_RP)) { - status = BTP_STATUS_FAILED; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE, CONTROLLER_INDEX, - status); -} - -static void write_long(uint8_t *data, uint16_t len) -{ - const struct gattc_write_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - struct os_mbuf *om = NULL; - uint8_t status = BTP_STATUS_SUCCESS; - int rc = 0; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - goto fail; - } - - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); - if (!om) { - SYS_LOG_ERR("Insufficient resources"); - status = BTP_STATUS_FAILED; - goto fail; - } - - rc = ble_gattc_write_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), - om, write_cb, - (void *) GATTC_WRITE_LONG_RP); - if (rc) { - status = BTP_STATUS_FAILED; - } else { - goto rsp; - } - -fail: - SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); - os_mbuf_free_chain(om); -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, - status); -} - -static int reliable_write_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attrs, - uint8_t num_attrs, - void *arg) -{ - struct gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_RELIABLE_WRITE_RP, - CONTROLLER_INDEX, buf); -free: - os_mbuf_free_chain(buf); - return rc; -} - -static void reliable_write(uint8_t *data, uint16_t len) -{ - const struct gattc_reliable_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - struct ble_gatt_attr attr; - struct os_mbuf *om = NULL; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto fail; - } - - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); - /* This is required, because Nimble checks if - * the data is longer than offset - */ - if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { - status = BTP_STATUS_FAILED; - goto fail; - } - - attr.handle = sys_le16_to_cpu(cmd->handle); - attr.offset = sys_le16_to_cpu(cmd->offset); - attr.om = om; - - if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, - reliable_write_cb, NULL)) { - status = BTP_STATUS_FAILED; - goto fail; - } else { - goto rsp; - } - -fail: - os_mbuf_free_chain(om); -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, - status); -} - -static int subscribe_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attrs, - void *arg) -{ - struct subscribe_rp *rp; - uint8_t err = (uint8_t) error->status; - uint8_t opcode = (uint8_t) (int) arg; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); -free: - os_mbuf_free_chain(buf); - return rc; -} - -static int enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, - uint16_t value) -{ - uint32_t opcode; - - SYS_LOG_DBG(""); - - opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP : GATTC_CFG_INDICATE_RP); - - if (ble_gattc_write_flat(conn_handle, ccc_handle, - &value, sizeof(value), subscribe_cb, (void *) opcode)) { - return -EINVAL; - } - - subscribe_params.ccc_handle = value; - - return 0; -} - -static int disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) -{ - uint16_t value = 0x00; - uint32_t opcode; - - SYS_LOG_DBG(""); - - opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP : GATTC_CFG_INDICATE_RP); - - /* Fail if CCC handle doesn't match */ - if (ccc_handle != subscribe_params.ccc_handle) { - SYS_LOG_ERR("CCC handle doesn't match"); - return -EINVAL; - } - - if (ble_gattc_write_flat(conn_handle, ccc_handle, - &value, sizeof(value), subscribe_cb, (void *) opcode)) { - return -EINVAL; - } - - subscribe_params.ccc_handle = 0; - return 0; -} - -static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) -{ - const struct gattc_cfg_notify_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (cmd->enable) { - uint16_t value; - - if (op == GATTC_CFG_NOTIFY) { - value = 0x0001; - } else { - value = 0x0002; - } - - if (enable_subscription(conn.conn_handle, - ccc_handle, value) != 0) { - status = BTP_STATUS_FAILED; - goto rsp; - } - } else { - if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { - status = BTP_STATUS_FAILED; - } else { - status = BTP_STATUS_SUCCESS; - } - } - -rsp: - SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); - - tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); -} - -int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, - uint8_t indication, struct os_mbuf *om) -{ - struct gattc_notification_ev *ev; - struct ble_gap_conn_desc conn; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - - SYS_LOG_DBG(""); - - if (!subscribe_params.ccc_handle) { - goto fail; - } - - if (ble_gap_conn_find(conn_handle, &conn)) { - goto fail; - } - - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); - - addr = &conn.peer_ota_addr; - - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); - ev->type = (uint8_t) (indication ? 0x02 : 0x01); - ev->handle = sys_cpu_to_le16(attr_handle); - ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); - os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); - - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_NOTIFICATION_RXED, - CONTROLLER_INDEX, buf); - -fail: - os_mbuf_free_chain(buf); - return 0; -} - -static void supported_commands(uint8_t *data, uint16_t len) -{ - uint8_t cmds[3]; - struct gatt_read_supported_commands_rp *rp = (void *) cmds; - - SYS_LOG_DBG(""); - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, GATTC_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GATTC_EXCHANGE_MTU); - tester_set_bit(cmds, GATTC_DISC_ALL_PRIM_SVCS); - tester_set_bit(cmds, GATTC_DISC_PRIM_UUID); - tester_set_bit(cmds, GATTC_FIND_INCLUDED); - tester_set_bit(cmds, GATTC_DISC_ALL_CHRC); - tester_set_bit(cmds, GATTC_DISC_CHRC_UUID); - tester_set_bit(cmds, GATTC_DISC_ALL_DESC); - tester_set_bit(cmds, GATTC_READ); - tester_set_bit(cmds, GATTC_READ_UUID); - tester_set_bit(cmds, GATTC_READ_LONG); - tester_set_bit(cmds, GATTC_READ_MULTIPLE); - tester_set_bit(cmds, GATTC_WRITE_WITHOUT_RSP); -#if 0 - tester_set_bit(cmds, GATTC_SIGNED_WRITE_WITHOUT_RSP); -#endif - tester_set_bit(cmds, GATTC_WRITE); - tester_set_bit(cmds, GATTC_WRITE_LONG); - tester_set_bit(cmds, GATTC_RELIABLE_WRITE); - tester_set_bit(cmds, GATTC_CFG_NOTIFY); - tester_set_bit(cmds, GATTC_CFG_INDICATE); - - tester_send(BTP_SERVICE_ID_GATTC, GATTC_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); -} - -void tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) -{ - switch (opcode) { - case GATTC_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case GATTC_EXCHANGE_MTU: - exchange_mtu(data, len); - return; - case GATTC_DISC_ALL_PRIM_SVCS: - disc_all_prim_svcs(data, len); - return; - case GATTC_DISC_PRIM_UUID: - disc_prim_uuid(data, len); - return; - case GATTC_FIND_INCLUDED: - find_included(data, len); - return; - case GATTC_DISC_ALL_CHRC: - disc_all_chrc(data, len); - return; - case GATTC_DISC_CHRC_UUID: - disc_chrc_uuid(data, len); - return; - case GATTC_DISC_ALL_DESC: - disc_all_desc(data, len); - return; - case GATTC_READ: - read(data, len); - return; - case GATTC_READ_UUID: - read_uuid(data, len); - return; - case GATTC_READ_LONG: - read_long(data, len); - return; - case GATTC_READ_MULTIPLE: - read_multiple(data, len); - return; - case GATTC_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, false); - return; -#if 0 - case GATTC_SIGNED_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, true); - return; -#endif - case GATTC_WRITE: - write(data, len); - return; - case GATTC_WRITE_LONG: - write_long(data, len); - return; - case GATTC_RELIABLE_WRITE: - reliable_write(data, len); - return; - case GATTC_CFG_NOTIFY: - case GATTC_CFG_INDICATE: - config_subscription(data, len, opcode); - return; - default: - tester_rsp(BTP_SERVICE_ID_GATTC, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } -} \ No newline at end of file diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/glue.c b/lib/bt/host/nimble/nimble/apps/bttester/src/glue.c deleted file mode 100644 index 3e606062..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/glue.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include "syscfg/syscfg.h" - -#if !MYNEWT_VAL(BLE_MESH) -#include -#include -#include "os/os.h" -#include "os/os_mbuf.h" -#include "glue.h" - - -#define ASSERT_NOT_CHAIN(om) assert(SLIST_NEXT(om, om_next) == NULL) - -const char *bt_hex(const void *buf, size_t len) -{ - static const char hex[] = "0123456789abcdef"; - static char hexbufs[4][137]; - static uint8_t curbuf; - const uint8_t *b = buf; - char *str; - int i; - - str = hexbufs[curbuf++]; - curbuf %= ARRAY_SIZE(hexbufs); - - len = min(len, (sizeof(hexbufs[0]) - 1) / 2); - - for (i = 0; i < len; i++) { - str[i * 2] = hex[b[i] >> 4]; - str[i * 2 + 1] = hex[b[i] & 0xf]; - } - - str[i * 2] = '\0'; - - return str; -} - -struct os_mbuf * NET_BUF_SIMPLE(uint16_t size) -{ - struct os_mbuf *buf; - - buf = os_msys_get(size, 0); - assert(buf); - - return buf; -} - -/* This is by purpose */ -void net_buf_simple_init(struct os_mbuf *buf, - size_t reserve_head) -{ - /* This is called in Zephyr after init. - * Note in Mynewt case we don't care abour reserved head*/ - buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + reserve_head; - buf->om_len = 0; -} - -void -net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val) -{ - val = htole16(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); -} - -void -net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val) -{ - val = htobe16(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); -} - -void -net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val) -{ - val = htobe32(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); -} - -void -net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val) -{ - os_mbuf_append(om, &val, 1); - ASSERT_NOT_CHAIN(om); -} - -void* -net_buf_simple_add(struct os_mbuf *om, uint8_t len) -{ - void * tmp; - - tmp = os_mbuf_extend(om, len); - ASSERT_NOT_CHAIN(om); - - return tmp; -} - -uint8_t * -net_buf_simple_push(struct os_mbuf *om, uint8_t len) -{ - uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; - - assert(headroom >= len); - om->om_data -= len; - om->om_len += len; - - return om->om_data; -} -#endif diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/glue.h b/lib/bt/host/nimble/nimble/apps/bttester/src/glue.h deleted file mode 100644 index 65085601..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/glue.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef __GLUE_H__ -#define __GLUE_H__ - -#include "os/endian.h" - -#define uint8_t uint8_t -#define int8_t int8_t -#define uint16_t uint16_t -#define uint32_t uint32_t -#define int32_t int32_t - -#ifndef BIT -#define BIT(n) (1UL << (n)) -#endif - -#define __packed __attribute__((__packed__)) - -#define sys_le16_to_cpu le16toh - -struct bt_data { - uint8_t type; - uint8_t data_len; - const uint8_t *data; -}; - -#define BT_DATA(_type, _data, _data_len) \ - { \ - .type = (_type), \ - .data_len = (_data_len), \ - .data = (const uint8_t *)(_data), \ - } - -struct os_mbuf * NET_BUF_SIMPLE(uint16_t size); -void net_buf_simple_init(struct os_mbuf *buf, size_t reserve_head); -void net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val); -void net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val); -void *net_buf_simple_add(struct os_mbuf *om, uint8_t len); -uint8_t *net_buf_simple_push(struct os_mbuf *om, uint8_t len); - -#define net_buf_simple_add_mem(a,b,c) os_mbuf_append(a,b,c) - -const char *bt_hex(const void *buf, size_t len); - -#endif /* __GLUE_H__ */ diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/l2cap.c b/lib/bt/host/nimble/nimble/apps/bttester/src/l2cap.c deleted file mode 100644 index 7890e7cc..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/l2cap.c +++ /dev/null @@ -1,765 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* l2cap.c - Bluetooth L2CAP Tester */ - -/* - * Copyright (c) 2016 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "syscfg/syscfg.h" - -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - -#include "console/console.h" -#include "host/ble_gap.h" -#include "host/ble_l2cap.h" - -#include "../../../nimble/host/src/ble_l2cap_priv.h" - -#include "bttester.h" - -#define CONTROLLER_INDEX 0 -#define CHANNELS MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) -#define TESTER_COC_MTU MYNEWT_VAL(BTTESTER_L2CAP_COC_MTU) -#define TESTER_COC_BUF_COUNT (3 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)) - -static os_membuf_t tester_sdu_coc_mem[ - OS_MEMPOOL_SIZE(TESTER_COC_BUF_COUNT, TESTER_COC_MTU) -]; - -struct os_mbuf_pool sdu_os_mbuf_pool; -static struct os_mempool sdu_coc_mbuf_mempool; -static bool hold_credit = false; - -static struct channel { - uint8_t chan_id; /* Internal number that identifies L2CAP channel. */ - uint8_t state; - struct ble_l2cap_chan *chan; -} channels[CHANNELS]; - -static uint8_t recv_cb_buf[TESTER_COC_MTU + sizeof(struct l2cap_data_received_ev)]; - -static struct channel *get_free_channel(void) -{ - uint8_t i; - struct channel *chan; - - for (i = 0; i < CHANNELS; i++) { - if (channels[i].state) { - continue; - } - - chan = &channels[i]; - chan->chan_id = i; - - return chan; - } - - return NULL; -} - -struct channel *find_channel(struct ble_l2cap_chan *chan) -{ - int i; - - for (i = 0; i < CHANNELS; ++i) { - if (channels[i].chan == chan) { - return &channels[i]; - } - } - - return NULL; -} - -struct channel *get_channel(uint8_t chan_id) -{ - if (chan_id >= CHANNELS) { - return NULL; - } - - return &channels[chan_id]; -} - -static void -tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu) -{ - SYS_LOG_DBG("LE CoC SDU received, chan: 0x%08lx, data len %d", - (uint32_t) chan, OS_MBUF_PKTLEN(sdu)); - - os_mbuf_free_chain(sdu); - if (!hold_credit) { - sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - assert(sdu != NULL); - - - ble_l2cap_recv_ready(chan, sdu); - } -} - -static void recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct os_mbuf *buf, void *arg) -{ - struct l2cap_data_received_ev *ev = (void *) recv_cb_buf; - struct channel *channel = find_channel(chan); - assert(channel != NULL); - - ev->chan_id = channel->chan_id; - ev->data_length = OS_MBUF_PKTLEN(buf); - - if (ev->data_length > TESTER_COC_MTU) { - SYS_LOG_ERR("Too large sdu received, truncating data"); - ev->data_length = TESTER_COC_MTU; - } - os_mbuf_copydata(buf, 0, ev->data_length, ev->data); - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED, - CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length); - - tester_l2cap_coc_recv(chan, buf); -} - -static void unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - int status, void *arg) -{ - if (status) { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - } else { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); - } -} - -static void reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct ble_l2cap_chan_info *chan_info, - int status) -{ - struct l2cap_reconfigured_ev ev; - struct channel *channel; - - if (status != 0) { - return; - } - - channel = find_channel(chan); - assert(channel != NULL); - - ev.chan_id = channel->chan_id; - ev.peer_mtu = chan_info->peer_coc_mtu; - ev.peer_mps = chan_info->peer_l2cap_mtu; - ev.our_mtu = chan_info->our_coc_mtu; - ev.our_mps = chan_info->our_l2cap_mtu; - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_RECONFIGURED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct ble_l2cap_chan_info *chan_info, void *arg) -{ - struct l2cap_connected_ev ev; - struct ble_gap_conn_desc desc; - struct channel *channel = find_channel(chan); - - if (channel == NULL) { - channel = get_free_channel(); - } - - ev.chan_id = channel->chan_id; - ev.psm = chan_info->psm; - ev.peer_mtu = chan_info->peer_coc_mtu; - ev.peer_mps = chan_info->peer_l2cap_mtu; - ev.our_mtu = chan_info->our_coc_mtu; - ev.our_mps = chan_info->our_l2cap_mtu; - channel->state = 1; - channel->chan = chan; - - if (!ble_gap_conn_find(conn_handle, &desc)) { - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, - sizeof(ev.address)); - } - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX, - (uint8_t *) &ev, sizeof(ev)); -} - -static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct ble_l2cap_chan_info *chan_info, void *arg) -{ - struct l2cap_disconnected_ev ev; - struct ble_gap_conn_desc desc; - struct channel *channel; - - memset(&ev, 0, sizeof(struct l2cap_disconnected_ev)); - - channel = find_channel(chan); - assert(channel != NULL); - - channel->state = 0; - channel->chan = chan; - ev.chan_id = channel->chan_id; - ev.psm = chan_info->psm; - - if (!ble_gap_conn_find(conn_handle, &desc)) { - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, - sizeof(ev.address)); - } - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static int accept_cb(uint16_t conn_handle, uint16_t peer_mtu, - struct ble_l2cap_chan *chan) -{ - struct os_mbuf *sdu_rx; - - SYS_LOG_DBG("LE CoC accepting, chan: 0x%08lx, peer_mtu %d", - (uint32_t) chan, peer_mtu); - - sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (!sdu_rx) { - return BLE_HS_ENOMEM; - } - - ble_l2cap_recv_ready(chan, sdu_rx); - - return 0; -} - -static int -tester_l2cap_event(struct ble_l2cap_event *event, void *arg) -{ - struct ble_l2cap_chan_info chan_info; - int accept_response; - struct ble_gap_conn_desc conn; - - switch (event->type) { - case BLE_L2CAP_EVENT_COC_CONNECTED: - if (ble_l2cap_get_chan_info(event->connect.chan, &chan_info)) { - assert(0); - } - - if (event->connect.status) { - console_printf("LE COC error: %d\n", event->connect.status); - return 0; - } - - console_printf("LE COC connected, conn: %d, chan: 0x%08lx, " - "psm: 0x%02x, scid: 0x%04x, dcid: 0x%04x, " - "our_mps: %d, our_mtu: %d, peer_mps: %d, " - "peer_mtu: %d\n", event->connect.conn_handle, - (uint32_t) event->connect.chan, chan_info.psm, - chan_info.scid, chan_info.dcid, - chan_info.our_l2cap_mtu, chan_info.our_coc_mtu, - chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu); - - connected_cb(event->connect.conn_handle, - event->connect.chan, &chan_info, arg); - - return 0; - case BLE_L2CAP_EVENT_COC_DISCONNECTED: - if (ble_l2cap_get_chan_info(event->disconnect.chan, - &chan_info)) { - assert(0); - } - console_printf("LE CoC disconnected, chan: 0x%08lx\n", - (uint32_t) event->disconnect.chan); - - disconnected_cb(event->disconnect.conn_handle, - event->disconnect.chan, &chan_info, arg); - return 0; - case BLE_L2CAP_EVENT_COC_ACCEPT: - ble_l2cap_get_chan_info(event->accept.chan, &chan_info); - if (chan_info.psm == 0x00F2) { - /* TSPX_psm_authentication_required */ - ble_gap_conn_find(event->accept.conn_handle, &conn); - if (!conn.sec_state.authenticated) { - return BLE_HS_EAUTHEN; - } - } else if (chan_info.psm == 0x00F3) { - /* TSPX_psm_authorization_required */ - ble_gap_conn_find(event->accept.conn_handle, &conn); - if (!conn.sec_state.encrypted) { - return BLE_HS_EAUTHOR; - } - return BLE_HS_EAUTHOR; - } else if (chan_info.psm == 0x00F4) { - /* TSPX_psm_encryption_key_size_required */ - ble_gap_conn_find(event->accept.conn_handle, &conn); - if (conn.sec_state.key_size < 16) { - return BLE_HS_EENCRYPT_KEY_SZ; - } - } - - accept_response = POINTER_TO_INT(arg); - if (accept_response) { - return accept_response; - } - - console_printf("LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n", - (uint32_t) event->accept.chan, - event->accept.conn_handle, - event->accept.peer_sdu_size); - - return accept_cb(event->accept.conn_handle, - event->accept.peer_sdu_size, - event->accept.chan); - - case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: - console_printf("LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n", - (uint32_t) event->receive.chan, - event->receive.conn_handle, - OS_MBUF_PKTLEN(event->receive.sdu_rx)); - - recv_cb(event->receive.conn_handle, event->receive.chan, - event->receive.sdu_rx, arg); - return 0; - case BLE_L2CAP_EVENT_COC_TX_UNSTALLED: - console_printf("LE CoC tx unstalled, chan: 0x%08lx, handle: %u, status: %d\n", - (uint32_t) event->tx_unstalled.chan, - event->tx_unstalled.conn_handle, - event->tx_unstalled.status); - - unstalled_cb(event->tx_unstalled.conn_handle, - event->tx_unstalled.chan, - event->tx_unstalled.status, arg); - return 0; - case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED: - if (ble_l2cap_get_chan_info(event->reconfigured.chan, - &chan_info)) { - assert(0); - } - console_printf("LE CoC reconfigure completed status 0x%02x, " - "chan: 0x%08lx\n", event->reconfigured.status, - (uint32_t) event->reconfigured.chan); - - if (event->reconfigured.status == 0) { - console_printf("\t our_mps: %d our_mtu %d\n", - chan_info.our_l2cap_mtu, chan_info.our_coc_mtu); - } - - reconfigured_ev(event->reconfigured.conn_handle, - event->reconfigured.chan, - &chan_info, - event->reconfigured.status); - return 0; - case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED: - if (ble_l2cap_get_chan_info(event->reconfigured.chan, - &chan_info)) { - assert(0); - } - console_printf("LE CoC peer reconfigured status 0x%02x, " - "chan: 0x%08lx\n", event->reconfigured.status, - (uint32_t) event->reconfigured.chan); - - if (event->reconfigured.status == 0) { - console_printf("\t peer_mps: %d peer_mtu %d\n", - chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu); - } - - reconfigured_ev(event->reconfigured.conn_handle, - event->reconfigured.chan, - &chan_info, - event->reconfigured.status); - return 0; - default: - return 0; - } -} - -static void connect(uint8_t *data, uint16_t len) -{ - const struct l2cap_connect_cmd *cmd = (void *) data; - uint8_t rp_buf[sizeof(struct l2cap_connect_rp) + cmd->num]; - struct l2cap_connect_rp *rp = (void *) rp_buf; - struct ble_gap_conn_desc desc; - struct channel *chan; - struct os_mbuf *sdu_rx[cmd->num]; - ble_addr_t *addr = (void *) data; - uint16_t mtu = htole16(cmd->mtu); - int rc; - int i, j; - bool ecfc = cmd->options & L2CAP_CONNECT_OPT_ECFC; - hold_credit = cmd->options & L2CAP_CONNECT_OPT_HOLD_CREDIT; - - SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6)); - - if (mtu == 0 || mtu > TESTER_COC_MTU) { - mtu = TESTER_COC_MTU; - } - - rc = ble_gap_conn_find_by_addr(addr, &desc); - if (rc) { - SYS_LOG_ERR("GAP conn find failed"); - goto fail; - } - - rp->num = cmd->num; - - for (i = 0; i < cmd->num; i++) { - chan = get_free_channel(); - if (!chan) { - SYS_LOG_ERR("No free channels"); - goto fail; - } - /* temporarily mark channel as used to select next one */ - chan->state = 1; - - rp->chan_ids[i] = chan->chan_id; - - sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (sdu_rx[i] == NULL) { - SYS_LOG_ERR("Failed to alloc buf"); - goto fail; - } - } - - /* mark selected channels as unused again */ - for (i = 0; i < cmd->num; i++) { - for (j = 0; j < CHANNELS; j++) { - if (rp->chan_ids[i] == channels[j].chan_id) { - channels[j].state = 0; - } - } - } - - if (cmd->num == 1 && !ecfc) { - rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm), - mtu, sdu_rx[0], - tester_l2cap_event, NULL); - } else if (ecfc) { - rc = ble_l2cap_enhanced_connect(desc.conn_handle, - htole16(cmd->psm), mtu, - cmd->num, sdu_rx, - tester_l2cap_event, NULL); - } else { - SYS_LOG_ERR("Invalid 'num' parameter value"); - goto fail; - } - - if (rc) { - SYS_LOG_ERR("L2CAP connect failed\n"); - goto fail; - } - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, - (uint8_t *) rp, sizeof(rp_buf)); - - return; - -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, - BTP_STATUS_FAILED); -} - -static void disconnect(const uint8_t *data, uint16_t len) -{ - const struct l2cap_disconnect_cmd *cmd = (void *) data; - struct channel *chan; - uint8_t status; - int err; - - SYS_LOG_DBG(""); - - chan = get_channel(cmd->chan_id); - assert(chan != NULL); - - err = ble_l2cap_disconnect(chan->chan); - if (err) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_DISCONNECT, CONTROLLER_INDEX, - status); -} - -static void send_data(const uint8_t *data, uint16_t len) -{ - const struct l2cap_send_data_cmd *cmd = (void *) data; - struct os_mbuf *sdu_tx = NULL; - int rc; - uint16_t data_len = sys_le16_to_cpu(cmd->data_len); - struct channel *chan = get_channel(cmd->chan_id); - - SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id); - - if (!chan) { - SYS_LOG_ERR("Invalid channel\n"); - goto fail; - } - - /* FIXME: For now, fail if data length exceeds buffer length */ - if (data_len > TESTER_COC_MTU) { - SYS_LOG_ERR("Data length exceeds buffer length"); - goto fail; - } - - sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (sdu_tx == NULL) { - SYS_LOG_ERR("No memory in the test sdu pool\n"); - goto fail; - } - - os_mbuf_append(sdu_tx, cmd->data, data_len); - - /* ble_l2cap_send takes ownership of the sdu */ - rc = ble_l2cap_send(chan->chan, sdu_tx); - if (rc == 0 || rc == BLE_HS_ESTALLED) { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return; - } - - SYS_LOG_ERR("Unable to send data: %d", rc); - os_mbuf_free_chain(sdu_tx); - -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, - BTP_STATUS_FAILED); -} - -static int -l2cap_coc_err2hs_err(uint16_t coc_err) -{ - switch (coc_err) { - case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM: - return BLE_HS_ENOTSUP; - case BLE_L2CAP_COC_ERR_NO_RESOURCES: - return BLE_HS_ENOMEM; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN: - return BLE_HS_EAUTHEN; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR: - return BLE_HS_EAUTHOR; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC: - return BLE_HS_EENCRYPT; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ: - return BLE_HS_EENCRYPT_KEY_SZ; - case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS: - return BLE_HS_EINVAL; - default: - return 0; - } -} - -static int -l2cap_btp_listen_err2coc_err(uint16_t coc_err) -{ - switch (coc_err) { - case 0x01: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN; - case 0x02: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR; - case 0x03: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ; - case 0x04: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC; - default: - return 0; - } -} - -static void listen(const uint8_t *data, uint16_t len) -{ - const struct l2cap_listen_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); - uint16_t rsp = htole16(cmd->response); - int rc; - - SYS_LOG_DBG(""); - - if (mtu == 0 || mtu > TESTER_COC_MTU) { - mtu = TESTER_COC_MTU; - } - - rsp = l2cap_btp_listen_err2coc_err(rsp); - rsp = l2cap_coc_err2hs_err(rsp); - - /* TODO: Handle cmd->transport flag */ - rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event, - INT_TO_POINTER(rsp)); - if (rc) { - goto fail; - } - - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return; - -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, - BTP_STATUS_FAILED); -} - -static void credits(uint8_t *data, uint16_t len) -{ - const struct l2cap_credits_cmd *cmd = (void *)data; - struct os_mbuf *sdu; - int rc; - - struct channel *channel = get_channel(cmd->chan_id); - if (channel == NULL) { - goto fail; - } - - sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (sdu == NULL) { - os_mbuf_free_chain(sdu); - goto fail; - } - - rc = ble_l2cap_recv_ready(channel->chan, sdu); - if (rc != 0) { - goto fail; - } - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CREDITS, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return; -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CREDITS, CONTROLLER_INDEX, - BTP_STATUS_FAILED); -} - -static void reconfigure(const uint8_t *data, uint16_t len) -{ - const struct l2cap_reconfigure_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); - struct ble_gap_conn_desc desc; - ble_addr_t *addr = (void *) data; - struct ble_l2cap_chan *chans[cmd->num]; - struct channel *channel; - int rc; - int i; - - SYS_LOG_DBG(""); - - if (mtu == 0 || mtu > TESTER_COC_MTU) { - mtu = TESTER_COC_MTU; - } - - rc = ble_gap_conn_find_by_addr(addr, &desc); - if (rc) { - SYS_LOG_ERR("GAP conn find failed"); - goto fail; - } - - for (i = 0; i < cmd->num; ++i) { - channel = get_channel(cmd->idxs[i]); - if (channel == NULL) { - goto fail; - } - chans[i] = channel->chan; - } - - rc = ble_l2cap_reconfig(chans, cmd->num, mtu); - if (rc) { - goto fail; - } - - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return; - -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, - BTP_STATUS_FAILED); -} - -static void supported_commands(uint8_t *data, uint16_t len) -{ - uint8_t cmds[1]; - struct l2cap_read_supported_commands_rp *rp = (void *) cmds; - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, L2CAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, L2CAP_CONNECT); - tester_set_bit(cmds, L2CAP_DISCONNECT); - tester_set_bit(cmds, L2CAP_LISTEN); - tester_set_bit(cmds, L2CAP_SEND_DATA); - tester_set_bit(cmds, L2CAP_RECONFIGURE); - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); -} - -void tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) -{ - switch (opcode) { - case L2CAP_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case L2CAP_CONNECT: - connect(data, len); - return; - case L2CAP_DISCONNECT: - disconnect(data, len); - return; - case L2CAP_SEND_DATA: - send_data(data, len); - return; - case L2CAP_LISTEN: - listen(data, len); - return; - case L2CAP_RECONFIGURE: - reconfigure(data, len); - return; - case L2CAP_CREDITS: - credits(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } -} - -uint8_t tester_init_l2cap(void) -{ - int rc; - - /* For testing we want to support all the available channels */ - rc = os_mempool_init(&sdu_coc_mbuf_mempool, TESTER_COC_BUF_COUNT, - TESTER_COC_MTU, tester_sdu_coc_mem, - "tester_coc_sdu_pool"); - assert(rc == 0); - - rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool, - TESTER_COC_MTU, TESTER_COC_BUF_COUNT); - assert(rc == 0); - - return BTP_STATUS_SUCCESS; -} - -uint8_t tester_unregister_l2cap(void) -{ - return BTP_STATUS_SUCCESS; -} - -#endif diff --git a/lib/bt/host/nimble/nimble/apps/bttester/src/mesh.c b/lib/bt/host/nimble/nimble/apps/bttester/src/mesh.c deleted file mode 100644 index 46bf7699..00000000 --- a/lib/bt/host/nimble/nimble/apps/bttester/src/mesh.c +++ /dev/null @@ -1,993 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* mesh.c - Bluetooth Mesh Tester */ - -/* - * Copyright (c) 2017 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "syscfg/syscfg.h" - -#if MYNEWT_VAL(BLE_MESH) - -#include - -#include "mesh/mesh.h" -#include "mesh/glue.h" -#include "mesh/testing.h" -#include "console/console.h" - -#include "bttester.h" - -extern uint8_t own_addr_type; - -#define CONTROLLER_INDEX 0 -#define CID_LOCAL 0x0002 - -/* Health server data */ -#define CUR_FAULTS_MAX 4 -#define HEALTH_TEST_ID 0x00 - -static uint8_t cur_faults[CUR_FAULTS_MAX]; -static uint8_t reg_faults[CUR_FAULTS_MAX * 2]; - -/* Provision node data */ -static uint8_t net_key[16]; -static uint16_t net_key_idx; -static uint8_t flags; -static uint32_t iv_index; -static uint16_t addr; -static uint8_t dev_key[16]; -static uint8_t input_size; - -/* Configured provisioning data */ -static uint8_t dev_uuid[16]; -static uint8_t static_auth[16]; - -/* Vendor Model data */ -#define VND_MODEL_ID_1 0x1234 - -/* Model send data */ -#define MODEL_BOUNDS_MAX 2 - -static struct model_data { - struct bt_mesh_model *model; - uint16_t addr; - uint16_t appkey_idx; -} model_bound[MODEL_BOUNDS_MAX]; - -static struct { - uint16_t local; - uint16_t dst; - uint16_t net_idx; -} net = { - .local = BT_MESH_ADDR_UNASSIGNED, - .dst = BT_MESH_ADDR_UNASSIGNED, -}; - -static void supported_commands(uint8_t *data, uint16_t len) -{ - struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); - - net_buf_simple_init(buf, 0); - - /* 1st octet */ - memset(net_buf_simple_add(buf, 1), 0, 1); - tester_set_bit(buf->om_data, MESH_READ_SUPPORTED_COMMANDS); - tester_set_bit(buf->om_data, MESH_CONFIG_PROVISIONING); - tester_set_bit(buf->om_data, MESH_PROVISION_NODE); - tester_set_bit(buf->om_data, MESH_INIT); - tester_set_bit(buf->om_data, MESH_RESET); - tester_set_bit(buf->om_data, MESH_INPUT_NUMBER); - tester_set_bit(buf->om_data, MESH_INPUT_STRING); - /* 2nd octet */ - tester_set_bit(buf->om_data, MESH_IVU_TEST_MODE); - tester_set_bit(buf->om_data, MESH_IVU_TOGGLE_STATE); - tester_set_bit(buf->om_data, MESH_NET_SEND); - tester_set_bit(buf->om_data, MESH_HEALTH_GENERATE_FAULTS); - tester_set_bit(buf->om_data, MESH_HEALTH_CLEAR_FAULTS); - tester_set_bit(buf->om_data, MESH_LPN); - tester_set_bit(buf->om_data, MESH_LPN_POLL); - tester_set_bit(buf->om_data, MESH_MODEL_SEND); - /* 3rd octet */ - memset(net_buf_simple_add(buf, 1), 0, 1); -#if MYNEWT_VAL(BLE_MESH_TESTING) - tester_set_bit(buf->om_data, MESH_LPN_SUBSCRIBE); - tester_set_bit(buf->om_data, MESH_LPN_UNSUBSCRIBE); - tester_set_bit(buf->om_data, MESH_RPL_CLEAR); -#endif /* CONFIG_BT_TESTING */ - tester_set_bit(buf->om_data, MESH_PROXY_IDENTITY); - - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, buf); -} - -static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count) -{ - uint8_t i, limit = *count; - - for (i = 0, *count = 0; i < faults_size && *count < limit; i++) { - if (faults[i]) { - *dst++ = faults[i]; - (*count)++; - } - } -} - -static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, - uint16_t *company_id, uint8_t *faults, uint8_t *fault_count) -{ - SYS_LOG_DBG(""); - - *test_id = HEALTH_TEST_ID; - *company_id = CID_LOCAL; - - get_faults(cur_faults, sizeof(cur_faults), faults, fault_count); - - return 0; -} - -static int fault_get_reg(struct bt_mesh_model *model, uint16_t company_id, - uint8_t *test_id, uint8_t *faults, uint8_t *fault_count) -{ - SYS_LOG_DBG("company_id 0x%04x", company_id); - - if (company_id != CID_LOCAL) { - return -EINVAL; - } - - *test_id = HEALTH_TEST_ID; - - get_faults(reg_faults, sizeof(reg_faults), faults, fault_count); - - return 0; -} - -static int fault_clear(struct bt_mesh_model *model, uint16_t company_id) -{ - SYS_LOG_DBG("company_id 0x%04x", company_id); - - if (company_id != CID_LOCAL) { - return -EINVAL; - } - - memset(reg_faults, 0, sizeof(reg_faults)); - - return 0; -} - -static int fault_test(struct bt_mesh_model *model, uint8_t test_id, - uint16_t company_id) -{ - SYS_LOG_DBG("test_id 0x%02x company_id 0x%04x", test_id, company_id); - - if (company_id != CID_LOCAL || test_id != HEALTH_TEST_ID) { - return -EINVAL; - } - - return 0; -} - -static const struct bt_mesh_health_srv_cb health_srv_cb = { - .fault_get_cur = fault_get_cur, - .fault_get_reg = fault_get_reg, - .fault_clear = fault_clear, - .fault_test = fault_test, -}; - -static struct bt_mesh_health_srv health_srv = { - .cb = &health_srv_cb, -}; - -static struct bt_mesh_model_pub health_pub; - -static void -health_pub_init(void) -{ - health_pub.msg = BT_MESH_HEALTH_FAULT_MSG(CUR_FAULTS_MAX); -} - -static struct bt_mesh_cfg_cli cfg_cli = { -}; - -void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) -{ - size_t i; - - if (!fault_count) { - SYS_LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x: " - "no faults", test_id, cid); - return; - } - - SYS_LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu: ", - test_id, cid, fault_count); - - for (i = 0; i < fault_count; i++) { - SYS_LOG_DBG("0x%02x", faults[i]); - } -} - -static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr, - uint8_t test_id, uint16_t cid, uint8_t *faults, - size_t fault_count) -{ - SYS_LOG_DBG("Health Current Status from 0x%04x", addr); - show_faults(test_id, cid, faults, fault_count); -} - -static struct bt_mesh_health_cli health_cli = { - .current_status = health_current_status, -}; - -static struct bt_mesh_model root_models[] = { - BT_MESH_MODEL_CFG_SRV, - BT_MESH_MODEL_CFG_CLI(&cfg_cli), - BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), - BT_MESH_MODEL_HEALTH_CLI(&health_cli), -}; - -static struct bt_mesh_model vnd_models[] = { - BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL, - NULL), -}; - -static struct bt_mesh_elem elements[] = { - BT_MESH_ELEM(0, root_models, vnd_models), -}; - -static void link_open(bt_mesh_prov_bearer_t bearer) -{ - struct mesh_prov_link_open_ev ev; - - SYS_LOG_DBG("bearer 0x%02x", bearer); - - switch (bearer) { - case BT_MESH_PROV_ADV: - ev.bearer = MESH_PROV_BEARER_PB_ADV; - break; - case BT_MESH_PROV_GATT: - ev.bearer = MESH_PROV_BEARER_PB_GATT; - break; - default: - SYS_LOG_ERR("Invalid bearer"); - - return; - } - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_OPEN, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void link_close(bt_mesh_prov_bearer_t bearer) -{ - struct mesh_prov_link_closed_ev ev; - - SYS_LOG_DBG("bearer 0x%02x", bearer); - - switch (bearer) { - case BT_MESH_PROV_ADV: - ev.bearer = MESH_PROV_BEARER_PB_ADV; - break; - case BT_MESH_PROV_GATT: - ev.bearer = MESH_PROV_BEARER_PB_GATT; - break; - default: - SYS_LOG_ERR("Invalid bearer"); - - return; - } - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_CLOSED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static int output_number(bt_mesh_output_action_t action, uint32_t number) -{ - struct mesh_out_number_action_ev ev; - - SYS_LOG_DBG("action 0x%04x number 0x%08lx", action, number); - - ev.action = sys_cpu_to_le16(action); - ev.number = sys_cpu_to_le32(number); - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_OUT_NUMBER_ACTION, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); - - return 0; -} - -static int output_string(const char *str) -{ - struct mesh_out_string_action_ev *ev; - struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); - - SYS_LOG_DBG("str %s", str); - - net_buf_simple_init(buf, 0); - - ev = net_buf_simple_add(buf, sizeof(*ev)); - ev->string_len = strlen(str); - - net_buf_simple_add_mem(buf, str, ev->string_len); - - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_OUT_STRING_ACTION, - CONTROLLER_INDEX, buf); - - os_mbuf_free_chain(buf); - return 0; -} - -static int input(bt_mesh_input_action_t action, uint8_t size) -{ - struct mesh_in_action_ev ev; - - SYS_LOG_DBG("action 0x%04x number 0x%02x", action, size); - - input_size = size; - - ev.action = sys_cpu_to_le16(action); - ev.size = size; - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_IN_ACTION, CONTROLLER_INDEX, - (uint8_t *) &ev, sizeof(ev)); - - return 0; -} - -static uint8_t vnd_app_key[16]; -static uint16_t vnd_app_key_idx = 0x000f; - -static void prov_complete(uint16_t net_idx, uint16_t addr) -{ - SYS_LOG_DBG("net_idx 0x%04x addr 0x%04x", net_idx, addr); - - net.net_idx = net_idx, - net.local = addr; - net.dst = addr; - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROVISIONED, CONTROLLER_INDEX, - NULL, 0); -} - -static void prov_reset(void) -{ - SYS_LOG_DBG(""); - - bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); -} - -static const struct bt_mesh_comp comp = { - .cid = CID_LOCAL, - .elem = elements, - .elem_count = ARRAY_SIZE(elements), -}; - -static struct bt_mesh_prov prov = { - .uuid = dev_uuid, - .static_val = static_auth, - .static_val_len = sizeof(static_auth), - .output_number = output_number, - .output_string = output_string, - .input = input, - .link_open = link_open, - .link_close = link_close, - .complete = prov_complete, - .reset = prov_reset, -}; - -static void config_prov(uint8_t *data, uint16_t len) -{ - const struct mesh_config_provisioning_cmd *cmd = (void *) data; - - SYS_LOG_DBG(""); - - memcpy(dev_uuid, cmd->uuid, sizeof(dev_uuid)); - memcpy(static_auth, cmd->static_auth, sizeof(static_auth)); - - prov.output_size = cmd->out_size; - prov.output_actions = sys_le16_to_cpu(cmd->out_actions); - prov.input_size = cmd->in_size; - prov.input_actions = sys_le16_to_cpu(cmd->in_actions); - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_CONFIG_PROVISIONING, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); -} - -static void provision_node(uint8_t *data, uint16_t len) -{ - const struct mesh_provision_node_cmd *cmd = (void *) data; - - SYS_LOG_DBG(""); - - memcpy(dev_key, cmd->dev_key, sizeof(dev_key)); - memcpy(net_key, cmd->net_key, sizeof(net_key)); - - addr = sys_le16_to_cpu(cmd->addr); - flags = cmd->flags; - iv_index = sys_le32_to_cpu(cmd->iv_index); - net_key_idx = sys_le16_to_cpu(cmd->net_key_idx); - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROVISION_NODE, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); -} - -static void init(uint8_t *data, uint16_t len) -{ - uint8_t status = BTP_STATUS_SUCCESS; - int err; - - SYS_LOG_DBG(""); - - err = bt_mesh_init(own_addr_type, &prov, &comp); - if (err) { - status = BTP_STATUS_FAILED; - - goto rsp; - } - - if (addr) { - err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, - addr, dev_key); - if (err) { - status = BTP_STATUS_FAILED; - } - } else { - err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); - if (err) { - status = BTP_STATUS_FAILED; - } - } - -rsp: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INIT, CONTROLLER_INDEX, - status); -} - -static void reset(uint8_t *data, uint16_t len) -{ - SYS_LOG_DBG(""); - - bt_mesh_reset(); - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_RESET, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); -} - -static void input_number(uint8_t *data, uint16_t len) -{ - const struct mesh_input_number_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; - uint32_t number; - int err; - - number = sys_le32_to_cpu(cmd->number); - - SYS_LOG_DBG("number 0x%04lx", number); - - err = bt_mesh_input_number(number); - if (err) { - status = BTP_STATUS_FAILED; - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_NUMBER, CONTROLLER_INDEX, - status); -} - -static void input_string(uint8_t *data, uint16_t len) -{ - const struct mesh_input_string_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; - uint8_t str_auth[16]; - int err; - - SYS_LOG_DBG(""); - - if (cmd->string_len > sizeof(str_auth)) { - SYS_LOG_ERR("Too long input (%u chars required)", input_size); - status = BTP_STATUS_FAILED; - goto rsp; - } else if (cmd->string_len < input_size) { - SYS_LOG_ERR("Too short input (%u chars required)", input_size); - status = BTP_STATUS_FAILED; - goto rsp; - } - - strncpy((char *)str_auth, (char *)cmd->string, cmd->string_len); - - err = bt_mesh_input_string((char *)str_auth); - if (err) { - status = BTP_STATUS_FAILED; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_STRING, CONTROLLER_INDEX, - status); -} - -static void ivu_test_mode(uint8_t *data, uint16_t len) -{ - const struct mesh_ivu_test_mode_cmd *cmd = (void *) data; - - SYS_LOG_DBG("enable 0x%02x", cmd->enable); - - bt_mesh_iv_update_test(cmd->enable ? true : false); - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TEST_MODE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); -} - -static void ivu_toggle_state(uint8_t *data, uint16_t len) -{ - bool result; - - SYS_LOG_DBG(""); - - result = bt_mesh_iv_update(); - if (!result) { - SYS_LOG_ERR("Failed to toggle the IV Update state"); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TOGGLE_STATE, CONTROLLER_INDEX, - result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED); -} - -static void lpn(uint8_t *data, uint16_t len) -{ - struct mesh_lpn_set_cmd *cmd = (void *) data; - bool enable; - int err; - - SYS_LOG_DBG("enable 0x%02x", cmd->enable); - - enable = cmd->enable ? true : false; - err = bt_mesh_lpn_set(enable); - if (err) { - SYS_LOG_ERR("Failed to toggle LPN (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); -} - -static void lpn_poll(uint8_t *data, uint16_t len) -{ - int err; - - SYS_LOG_DBG(""); - - err = bt_mesh_lpn_poll(); - if (err) { - SYS_LOG_ERR("Failed to send poll msg (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_POLL, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); -} - -static void net_send(uint8_t *data, uint16_t len) -{ - struct mesh_net_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .app_idx = vnd_app_key_idx, - .addr = sys_le16_to_cpu(cmd->dst), - .send_ttl = cmd->ttl, - }; - int err; - - SYS_LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl, - ctx.addr, cmd->payload_len); - - if (!bt_mesh_app_key_exists(vnd_app_key_idx)) { - (void)bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx, - vnd_app_key); - vnd_models[0].keys[0] = vnd_app_key_idx; - } - - net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); - - err = bt_mesh_model_send(&vnd_models[0], &ctx, msg, NULL, NULL); - if (err) { - SYS_LOG_ERR("Failed to send (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_NET_SEND, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - - os_mbuf_free_chain(msg); -} - -static void health_generate_faults(uint8_t *data, uint16_t len) -{ - struct mesh_health_generate_faults_rp *rp; - struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + - sizeof(reg_faults)); - uint8_t some_faults[] = { 0x01, 0x02, 0x03, 0xff, 0x06 }; - uint8_t cur_faults_count, reg_faults_count; - - rp = net_buf_simple_add(buf, sizeof(*rp)); - - cur_faults_count = min(sizeof(cur_faults), sizeof(some_faults)); - memcpy(cur_faults, some_faults, cur_faults_count); - net_buf_simple_add_mem(buf, cur_faults, cur_faults_count); - rp->cur_faults_count = cur_faults_count; - - reg_faults_count = min(sizeof(reg_faults), sizeof(some_faults)); - memcpy(reg_faults, some_faults, reg_faults_count); - net_buf_simple_add_mem(buf, reg_faults, reg_faults_count); - rp->reg_faults_count = reg_faults_count; - - bt_mesh_fault_update(&elements[0]); - - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_HEALTH_GENERATE_FAULTS, - CONTROLLER_INDEX, buf); -} - -static void health_clear_faults(uint8_t *data, uint16_t len) -{ - SYS_LOG_DBG(""); - - memset(cur_faults, 0, sizeof(cur_faults)); - memset(reg_faults, 0, sizeof(reg_faults)); - - bt_mesh_fault_update(&elements[0]); - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_HEALTH_CLEAR_FAULTS, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); -} - -static void model_send(uint8_t *data, uint16_t len) -{ - struct mesh_model_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .app_idx = BT_MESH_KEY_DEV, - .addr = sys_le16_to_cpu(cmd->dst), - .send_ttl = BT_MESH_TTL_DEFAULT, - }; - struct bt_mesh_model *model = NULL; - int err, i; - uint16_t src = sys_le16_to_cpu(cmd->src); - - /* Lookup source address */ - for (i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (bt_mesh_model_elem(model_bound[i].model)->addr == src) { - model = model_bound[i].model; - ctx.app_idx = model_bound[i].appkey_idx; - - break; - } - } - - if (!model) { - SYS_LOG_ERR("Model not found"); - err = -EINVAL; - - goto fail; - } - - SYS_LOG_DBG("src 0x%04x dst 0x%04x model %p payload_len %d", src, - ctx.addr, model, cmd->payload_len); - - net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); - - err = bt_mesh_model_send(model, &ctx, msg, NULL, NULL); - if (err) { - SYS_LOG_ERR("Failed to send (err %d)", err); - } - -fail: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_MODEL_SEND, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - - os_mbuf_free_chain(msg); -} - -#if MYNEWT_VAL(BLE_MESH_TESTING) -static void lpn_subscribe(uint8_t *data, uint16_t len) -{ - struct mesh_lpn_subscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); - int err; - - SYS_LOG_DBG("address 0x%04x", address); - - err = bt_test_mesh_lpn_group_add(address); - if (err) { - SYS_LOG_ERR("Failed to subscribe (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_SUBSCRIBE, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); -} - -static void lpn_unsubscribe(uint8_t *data, uint16_t len) -{ - struct mesh_lpn_unsubscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); - int err; - - SYS_LOG_DBG("address 0x%04x", address); - - err = bt_test_mesh_lpn_group_remove(&address, 1); - if (err) { - SYS_LOG_ERR("Failed to unsubscribe (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_UNSUBSCRIBE, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); -} - -static void rpl_clear(uint8_t *data, uint16_t len) -{ - int err; - - SYS_LOG_DBG(""); - - err = bt_test_mesh_rpl_clear(); - if (err) { - SYS_LOG_ERR("Failed to clear RPL (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_RPL_CLEAR, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); -} -#endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ - -static void proxy_identity_enable(uint8_t *data, uint16_t len) -{ - int err; - - SYS_LOG_DBG(""); - - err = bt_mesh_proxy_identity_enable(); - if (err) { - SYS_LOG_ERR("Failed to enable proxy identity (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROXY_IDENTITY, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); -} - -void tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) -{ - switch (opcode) { - case MESH_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - break; - case MESH_CONFIG_PROVISIONING: - config_prov(data, len); - break; - case MESH_PROVISION_NODE: - provision_node(data, len); - break; - case MESH_INIT: - init(data, len); - break; - case MESH_RESET: - reset(data, len); - break; - case MESH_INPUT_NUMBER: - input_number(data, len); - break; - case MESH_INPUT_STRING: - input_string(data, len); - break; - case MESH_IVU_TEST_MODE: - ivu_test_mode(data, len); - break; - case MESH_IVU_TOGGLE_STATE: - ivu_toggle_state(data, len); - break; - case MESH_LPN: - lpn(data, len); - break; - case MESH_LPN_POLL: - lpn_poll(data, len); - break; - case MESH_NET_SEND: - net_send(data, len); - break; - case MESH_HEALTH_GENERATE_FAULTS: - health_generate_faults(data, len); - break; - case MESH_HEALTH_CLEAR_FAULTS: - health_clear_faults(data, len); - break; - case MESH_MODEL_SEND: - model_send(data, len); - break; -#if MYNEWT_VAL(BLE_MESH_TESTING) - case MESH_LPN_SUBSCRIBE: - lpn_subscribe(data, len); - break; - case MESH_LPN_UNSUBSCRIBE: - lpn_unsubscribe(data, len); - break; - case MESH_RPL_CLEAR: - rpl_clear(data, len); - break; -#endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ - case MESH_PROXY_IDENTITY: - proxy_identity_enable(data, len); - break; - default: - tester_rsp(BTP_SERVICE_ID_MESH, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - break; - } -} - -void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, - size_t payload_len) -{ - struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX); - struct mesh_net_recv_ev *ev; - - SYS_LOG_DBG("ttl 0x%02x ctl 0x%02x src 0x%04x dst 0x%04x " - "payload_len %d", ttl, ctl, src, dst, payload_len); - - if (payload_len > net_buf_simple_tailroom(buf)) { - SYS_LOG_ERR("Payload size exceeds buffer size"); - - goto done; - } - - ev = net_buf_simple_add(buf, sizeof(*ev)); - ev->ttl = ttl; - ev->ctl = ctl; - ev->src = sys_cpu_to_le16(src); - ev->dst = sys_cpu_to_le16(dst); - ev->payload_len = payload_len; - net_buf_simple_add_mem(buf, payload, payload_len); - - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_NET_RECV, CONTROLLER_INDEX, - buf); -done: - os_mbuf_free_chain(buf); -} - -static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model, - uint16_t key_idx) -{ - int i; - - SYS_LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p", - addr, key_idx, model); - - for (i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (!model_bound[i].model) { - model_bound[i].model = model; - model_bound[i].addr = addr; - model_bound[i].appkey_idx = key_idx; - - return; - } - } - - SYS_LOG_ERR("model_bound is full"); -} - -static void model_unbound_cb(uint16_t addr, struct bt_mesh_model *model, - uint16_t key_idx) -{ - int i; - - SYS_LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p", - addr, key_idx, model); - - for (i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (model_bound[i].model == model) { - model_bound[i].model = NULL; - model_bound[i].addr = 0x0000; - model_bound[i].appkey_idx = BT_MESH_KEY_UNUSED; - - return; - } - } - - SYS_LOG_INF("model not found"); -} - -static void invalid_bearer_cb(uint8_t opcode) -{ - struct mesh_invalid_bearer_ev ev = { - .opcode = opcode, - }; - - SYS_LOG_DBG("opcode 0x%02x", opcode); - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INVALID_BEARER, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void incomp_timer_exp_cb(void) -{ - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INCOMP_TIMER_EXP, - CONTROLLER_INDEX, NULL, 0); -} - -static struct bt_test_cb bt_test_cb = { - .mesh_net_recv = net_recv_ev, - .mesh_model_bound = model_bound_cb, - .mesh_model_unbound = model_unbound_cb, - .mesh_prov_invalid_bearer = invalid_bearer_cb, - .mesh_trans_incomp_timer_exp = incomp_timer_exp_cb, -}; - -static void lpn_established(uint16_t friend_addr) -{ - - struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - struct mesh_lpn_established_ev ev = { lpn->sub->net_idx, friend_addr, lpn->queue_size, - lpn->recv_win }; - - SYS_LOG_DBG("Friendship (as LPN) established with " - "Friend 0x%04x Queue Size %d Receive Window %d", - friend_addr, lpn->queue_size, lpn->recv_win); - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_ESTABLISHED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -static void lpn_terminated(uint16_t friend_addr) -{ - struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - struct mesh_lpn_terminated_ev ev = { lpn->sub->net_idx, friend_addr }; - - SYS_LOG_DBG("Friendship (as LPN) lost with Friend " - "0x%04x", friend_addr); - - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_TERMINATED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); -} - -void lpn_cb(uint16_t friend_addr, bool established) -{ - if (established) { - lpn_established(friend_addr); - } else { - lpn_terminated(friend_addr); - } -} - -uint8_t tester_init_mesh(void) -{ - health_pub_init(); - - if (IS_ENABLED(CONFIG_BT_TESTING)) { - bt_mesh_lpn_set_cb(lpn_cb); - bt_test_cb_register(&bt_test_cb); - } - - return BTP_STATUS_SUCCESS; -} - -uint8_t tester_unregister_mesh(void) -{ - return BTP_STATUS_SUCCESS; -} - -#endif /* MYNEWT_VAL(BLE_MESH) */ diff --git a/lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_plna.h b/lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_plna.h deleted file mode 100644 index c4fb65ea..00000000 --- a/lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_plna.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_BLE_LL_PLNA_ -#define H_BLE_LL_PLNA_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "syscfg/syscfg.h" - -#if MYNEWT_VAL(BLE_LL_PA) -void ble_ll_plna_pa_init(void); -void ble_ll_plna_pa_enable(void); -void ble_ll_plna_pa_disable(void); -#endif - -#if MYNEWT_VAL(BLE_LL_LNA) -void ble_ll_plna_lna_init(void); -void ble_ll_plna_lna_enable(void); -void ble_ll_plna_lna_disable(void); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_LL_PLNA_ */ diff --git a/lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_test.h b/lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_test.h deleted file mode 100644 index 32984c6b..00000000 --- a/lib/bt/host/nimble/nimble/nimble/controller/include/controller/ble_ll_test.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_LL_TEST_ -#define H_LL_TEST_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ble_ll_csa2_test_all(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/controller/src/ble_ll_supp_cmd.c b/lib/bt/host/nimble/nimble/nimble/controller/src/ble_ll_supp_cmd.c deleted file mode 100644 index 1c408fbf..00000000 --- a/lib/bt/host/nimble/nimble/nimble/controller/src/ble_ll_supp_cmd.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include "nimble/ble.h" -#include "nimble/nimble_opt.h" -#include "nimble/hci_common.h" -#include "controller/ble_ll.h" -#include "controller/ble_ll_hci.h" - -/* Octet 0 */ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_DISCONNECT (1 << 5) -#else -#define BLE_SUPP_CMD_DISCONNECT (0 << 5) -#endif -#define BLE_LL_SUPP_CMD_OCTET_0 (BLE_SUPP_CMD_DISCONNECT) - -/* Octet 2*/ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_READ_REM_VER_INFO (1 << 7) -#else -#define BLE_SUPP_CMD_READ_REM_VER_INFO (0 << 7) -#endif -#define BLE_LL_SUPP_CMD_OCTET_2 (BLE_SUPP_CMD_READ_REM_VER_INFO) - -/* Octet 5 */ -#define BLE_SUPP_CMD_SET_EVENT_MASK (1 << 6) -#define BLE_SUPP_CMD_RESET (1 << 7) -#define BLE_LL_SUPP_CMD_OCTET_5 \ -( \ - BLE_SUPP_CMD_SET_EVENT_MASK | \ - BLE_SUPP_CMD_RESET \ -) - -/* Octet 10 */ -#define BLE_SUPP_CMD_RD_TX_PWR (0 << 2) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) -#define BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW (1 << 5) -#define BLE_SUPP_CMD_HOST_BUFFER_SIZE (1 << 6) -#define BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS (1 << 7) -#else -#define BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW (0 << 5) -#define BLE_SUPP_CMD_HOST_BUFFER_SIZE (0 << 6) -#define BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS (0 << 7) -#endif -#define BLE_LL_SUPP_CMD_OCTET_10 \ -( \ - BLE_SUPP_CMD_RD_TX_PWR | \ - BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW | \ - BLE_SUPP_CMD_HOST_BUFFER_SIZE | \ - BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS \ -) - -/* Octet 14 */ -#define BLE_SUPP_CMD_RD_LOC_VER (1 << 3) -#define BLE_SUPP_CMD_RD_LOC_SUPP_FEAT (1 << 5) -#define BLE_LL_SUPP_CMD_OCTET_14 \ -( \ - BLE_SUPP_CMD_RD_LOC_VER | \ - BLE_SUPP_CMD_RD_LOC_SUPP_FEAT \ -) - -/* Octet 15 */ -#define BLE_SUPP_CMD_RD_BD_ADDR (1 << 1) - -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_RD_RSSI (1 << 5) -#else -#define BLE_SUPP_CMD_RD_RSSI (0 << 5) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_15 \ -( \ - BLE_SUPP_CMD_RD_BD_ADDR | \ - BLE_SUPP_CMD_RD_RSSI \ -) - -/* Octet 25 */ -#define BLE_SUPP_CMD_LE_SET_EV_MASK (1 << 0) -#define BLE_SUPP_CMD_LE_RD_BUF_SIZE (1 << 1) -#define BLE_SUPP_CMD_LE_RD_LOC_FEAT (1 << 2) -#define BLE_SUPP_CMD_LE_SET_RAND_ADDR (1 << 4) -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_ADV_PARAMS (1 << 5) -#define BLE_SUPP_CMD_LE_SET_ADV_TX_PWR (1 << 6) -#define BLE_SUPP_CMD_LE_SET_ADV_DATA (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_ADV_PARAMS (0 << 5) -#define BLE_SUPP_CMD_LE_SET_ADV_TX_PWR (0 << 6) -#define BLE_SUPP_CMD_LE_SET_ADV_DATA (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_25 \ -( \ - BLE_SUPP_CMD_LE_SET_EV_MASK | \ - BLE_SUPP_CMD_LE_RD_BUF_SIZE | \ - BLE_SUPP_CMD_LE_RD_LOC_FEAT | \ - BLE_SUPP_CMD_LE_SET_RAND_ADDR | \ - BLE_SUPP_CMD_LE_SET_ADV_PARAMS | \ - BLE_SUPP_CMD_LE_SET_ADV_TX_PWR | \ - BLE_SUPP_CMD_LE_SET_ADV_DATA \ -) - -/* Octet 26 */ -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA (1 << 0) -#define BLE_SUPP_CMD_LE_SET_ADV_ENABLE (1 << 1) -#else -#define BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA (0 << 0) -#define BLE_SUPP_CMD_LE_SET_ADV_ENABLE (0 << 1) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_SET_SCAN_PARAMS (1 << 2) -#define BLE_SUPP_CMD_LE_SET_SCAN_ENABLE (1 << 3) -#else -#define BLE_SUPP_CMD_LE_SET_SCAN_PARAMS (0 << 2) -#define BLE_SUPP_CMD_LE_SET_SCAN_ENABLE (0 << 3) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_CREATE_CONN (1 << 4) -#define BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL (1 << 5) -#else -#define BLE_SUPP_CMD_LE_CREATE_CONN (0 << 4) -#define BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL (0 << 5) - -#endif -#define BLE_SUPP_CMD_LE_RD_WHITELIST_SIZE (1 << 6) -#define BLE_SUPP_CMD_LE_CLR_WHITELIST (1 << 7) - -#define BLE_LL_SUPP_CMD_OCTET_26 \ -( \ - BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA | \ - BLE_SUPP_CMD_LE_SET_ADV_ENABLE | \ - BLE_SUPP_CMD_LE_SET_SCAN_PARAMS | \ - BLE_SUPP_CMD_LE_SET_SCAN_ENABLE | \ - BLE_SUPP_CMD_LE_CREATE_CONN | \ - BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL | \ - BLE_SUPP_CMD_LE_RD_WHITELIST_SIZE | \ - BLE_SUPP_CMD_LE_CLR_WHITELIST \ -) - -/* Octet 27 */ -#define BLE_SUPP_CMD_LE_ADD_DEV_WHITELIST (1 << 0) -#define BLE_SUPP_CMD_LE_RMV_DEV_WHITELIST (1 << 1) -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_CONN_UPDATE (1 << 2) -#else -#define BLE_SUPP_CMD_LE_CONN_UPDATE (0 << 2) -#endif -#define BLE_SUPP_CMD_LE_SET_HOST_CHAN_CLASS (1 << 3) -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_RD_CHAN_MAP (1 << 4) -#define BLE_SUPP_CMD_LE_RD_REM_USED_FEAT (1 << 5) -#else -#define BLE_SUPP_CMD_LE_RD_CHAN_MAP (0 << 4) -#define BLE_SUPP_CMD_LE_RD_REM_USED_FEAT (0 << 5) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -#define BLE_SUPP_CMD_LE_ENCRYPT (1 << 6) -#else -#define BLE_SUPP_CMD_LE_ENCRYPT (0 << 6) -#endif -#define BLE_SUPP_CMD_LE_RAND (1 << 7) - -#define BLE_LL_SUPP_CMD_OCTET_27 \ -( \ - BLE_SUPP_CMD_LE_ENCRYPT | \ - BLE_SUPP_CMD_LE_RAND | \ - BLE_SUPP_CMD_LE_ADD_DEV_WHITELIST | \ - BLE_SUPP_CMD_LE_RMV_DEV_WHITELIST | \ - BLE_SUPP_CMD_LE_CONN_UPDATE | \ - BLE_SUPP_CMD_LE_SET_HOST_CHAN_CLASS | \ - BLE_SUPP_CMD_LE_RD_CHAN_MAP | \ - BLE_SUPP_CMD_LE_RD_REM_USED_FEAT \ -) - -/* Octet 28 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_START_ENCRYPT (1 << 0) -#else -#define BLE_SUPP_CMD_LE_START_ENCRYPT (0 << 0) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (1 << 1) -#define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (1 << 2) -#else -#define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (0 << 1) -#define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (0 << 2) -#endif -#else -#define BLE_SUPP_CMD_LE_START_ENCRYPT (0 << 0) -#define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (0 << 1) -#define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (0 << 2) -#endif -#define BLE_SUPP_CMD_LE_READ_SUPP_STATES (1 << 3) - -#if MYNEWT_VAL(BLE_LL_DTM) -#define BLE_SUPP_CMD_LE_RX_TEST (1 << 4) -#define BLE_SUPP_CMD_LE_TX_TEST (1 << 5) -#define BLE_SUPP_CMD_LE_TEST_END (1 << 6) - -#else -#define BLE_SUPP_CMD_LE_RX_TEST (0 << 4) -#define BLE_SUPP_CMD_LE_TX_TEST (0 << 5) -#define BLE_SUPP_CMD_LE_TEST_END (0 << 6) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_28 \ -( \ - BLE_SUPP_CMD_LE_START_ENCRYPT | \ - BLE_SUPP_CMD_LE_LTK_REQ_REPLY | \ - BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY | \ - BLE_SUPP_CMD_LE_READ_SUPP_STATES | \ - BLE_SUPP_CMD_LE_RX_TEST | \ - BLE_SUPP_CMD_LE_TX_TEST | \ - BLE_SUPP_CMD_LE_TEST_END \ -) - -/* Octet 33 */ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_REM_CONN_PRR (1 << 4) -#define BLE_SUPP_CMD_LE_REM_CONN_PRNR (1 << 5) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) -#define BLE_SUPP_CMD_LE_SET_DATALEN (1 << 6) -#define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_DATALEN (0 << 6) -#define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (0 << 7) -#endif -#else -#define BLE_SUPP_CMD_LE_REM_CONN_PRR (0 << 4) -#define BLE_SUPP_CMD_LE_REM_CONN_PRNR (0 << 5) -#define BLE_SUPP_CMD_LE_SET_DATALEN (0 << 6) -#define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (0 << 7) -#endif - - -#define BLE_LL_SUPP_CMD_OCTET_33 \ -( \ - BLE_SUPP_CMD_LE_REM_CONN_PRR | \ - BLE_SUPP_CMD_LE_REM_CONN_PRNR | \ - BLE_SUPP_CMD_LE_SET_DATALEN | \ - BLE_SUPP_CMD_LE_RD_SUGG_DATALEN \ -) - -/* Octet 34 */ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) -#define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (1 << 0) -#else -#define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (0 << 0) -#endif -#else -#define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (0 << 0) -#endif -#define BLE_SUPP_CMD_LE_READ_LOCAL_P256_PK (0 << 1) -#define BLE_SUPP_CMD_LE_GENERATE_DH_KEY (0 << 2) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -#define BLE_SUPP_CMD_LE_ADD_RESOLV_LIST (1 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_RESOLV_LIST (1 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_RESOLV_LIST (1 << 5) -#define BLE_SUPP_CMD_LE_RD_RESOLV_SIZE (1 << 6) -#define BLE_SUPP_CMD_LE_RD_PEER_RESV_ADDR (1 << 7) -#else -#define BLE_SUPP_CMD_LE_ADD_RESOLV_LIST (0 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_RESOLV_LIST (0 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_RESOLV_LIST (0 << 5) -#define BLE_SUPP_CMD_LE_RD_RESOLV_SIZE (0 << 6) -#define BLE_SUPP_CMD_LE_RD_PEER_RESV_ADDR (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_34 \ -( \ - BLE_SUPP_CMD_LE_WR_SUGG_DATALEN | \ - BLE_SUPP_CMD_LE_READ_LOCAL_P256_PK | \ - BLE_SUPP_CMD_LE_GENERATE_DH_KEY | \ - BLE_SUPP_CMD_LE_ADD_RESOLV_LIST | \ - BLE_SUPP_CMD_LE_REMOVE_RESOLV_LIST | \ - BLE_SUPP_CMD_LE_CLEAR_RESOLV_LIST | \ - BLE_SUPP_CMD_LE_RD_RESOLV_SIZE | \ - BLE_SUPP_CMD_LE_RD_PEER_RESV_ADDR \ -) - -/* Octet 35 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -#define BLE_SUPP_CMD_LE_RD_LOCAL_RESV_ADDR (1 << 0) -#define BLE_SUPP_CMD_LE_SET_ADDR_RES_EN (1 << 1) -#define BLE_SUPP_CMD_LE_SET_RESV_ADDR_TMO (1 << 2) -#else -#define BLE_SUPP_CMD_LE_RD_LOCAL_RESV_ADDR (0 << 0) -#define BLE_SUPP_CMD_LE_SET_ADDR_RES_EN (0 << 1) -#define BLE_SUPP_CMD_LE_SET_RESV_ADDR_TMO (0 << 2) -#endif -#define BLE_SUPP_CMD_LE_RD_MAX_DATALEN (1 << 3) -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_READ_PHY (1 << 4) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (1 << 5) -#define BLE_SUPP_CMD_LE_SET_PHY (1 << 6) -#else -#define BLE_SUPP_CMD_LE_READ_PHY (0 << 4) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (0 << 5) -#define BLE_SUPP_CMD_LE_SET_PHY (0 << 6) -#endif -#else -#define BLE_SUPP_CMD_LE_READ_PHY (0 << 4) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (0 << 5) -#define BLE_SUPP_CMD_LE_SET_PHY (0 << 6) -#endif - -#if MYNEWT_VAL(BLE_LL_DTM) -#define BLE_SUPP_CMD_LE_ENHANCED_RX_TEST (1 << 7) -#else -#define BLE_SUPP_CMD_LE_ENHANCED_RX_TEST (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_35 \ -( \ - BLE_SUPP_CMD_LE_RD_LOCAL_RESV_ADDR | \ - BLE_SUPP_CMD_LE_SET_ADDR_RES_EN | \ - BLE_SUPP_CMD_LE_SET_RESV_ADDR_TMO | \ - BLE_SUPP_CMD_LE_RD_MAX_DATALEN | \ - BLE_SUPP_CMD_LE_READ_PHY | \ - BLE_SUPP_CMD_LE_SET_DEFAULT_PHY | \ - BLE_SUPP_CMD_LE_SET_PHY | \ - BLE_SUPP_CMD_LE_ENHANCED_RX_TEST \ -) - -/* Octet 36 */ -#if MYNEWT_VAL(BLE_LL_DTM) -#define BLE_SUPP_CMD_LE_ENHANCED_TX_TEST (1 << 0) -#else -#define BLE_SUPP_CMD_LE_ENHANCED_TX_TEST (0 << 0) -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_ADVS_RAND_ADDR (1 << 1) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_PARAM (1 << 2) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_DATA (1 << 3) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_RSP (1 << 4) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_ENABLE (1 << 5) -#define BLE_SUPP_CMD_LE_RD_MAX_ADV_DATA_LEN (1 << 6) -#define BLE_SUPP_CMD_LE_RD_NUM_SUPP_ADVS (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_ADVS_RAND_ADDR (0 << 1) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_PARAM (0 << 2) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_DATA (0 << 3) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_RSP (0 << 4) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_ENABLE (0 << 5) -#define BLE_SUPP_CMD_LE_RD_MAX_ADV_DATA_LEN (0 << 6) -#define BLE_SUPP_CMD_LE_RD_NUM_SUPP_ADVS (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_36 \ -( \ - BLE_SUPP_CMD_LE_ENHANCED_TX_TEST | \ - BLE_SUPP_CMD_LE_SET_ADVS_RAND_ADDR | \ - BLE_SUPP_CMD_LE_SET_EXT_ADV_PARAM | \ - BLE_SUPP_CMD_LE_SET_EXT_ADV_DATA | \ - BLE_SUPP_CMD_LE_SET_EXT_SCAN_RSP | \ - BLE_SUPP_CMD_LE_SET_EXT_ADV_ENABLE | \ - BLE_SUPP_CMD_LE_RD_MAX_ADV_DATA_LEN | \ - BLE_SUPP_CMD_LE_RD_NUM_SUPP_ADVS \ -) - -/* Octet 37 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_REMOVE_ADVS (1 << 0) -#define BLE_SUPP_CMD_LE_CLEAR_ADVS (1 << 1) -#else -#define BLE_SUPP_CMD_LE_REMOVE_ADVS (0 << 0) -#define BLE_SUPP_CMD_LE_CLEAR_ADVS (0 << 1) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_PADV_PARAM (1 << 2) -#define BLE_SUPP_CMD_LE_SET_PADV_DATA (1 << 3) -#define BLE_SUPP_CMD_LE_SET_PADV_ENABLE (1 << 4) -#else -#define BLE_SUPP_CMD_LE_SET_PADV_PARAM (0 << 2) -#define BLE_SUPP_CMD_LE_SET_PADV_DATA (0 << 3) -#define BLE_SUPP_CMD_LE_SET_PADV_ENABLE (0 << 4) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (1 << 5) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (1 << 6) -#else -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (0 << 5) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (0 << 6) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (1 << 7) -#else -#define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (0 << 7) -#endif -#else -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (0 << 5) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (0 << 6) -#define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_37 \ -( \ - BLE_SUPP_CMD_LE_REMOVE_ADVS | \ - BLE_SUPP_CMD_LE_CLEAR_ADVS | \ - BLE_SUPP_CMD_LE_SET_PADV_PARAM | \ - BLE_SUPP_CMD_LE_SET_PADV_DATA | \ - BLE_SUPP_CMD_LE_SET_PADV_ENABLE | \ - BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM | \ - BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE | \ - BLE_SUPP_CMD_LE_EXT_CREATE_CONN \ -) - -/* Octet 38 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC (1 << 0) -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC_C (1 << 1) -#define BLE_SUPP_CMD_LE_PADV_TERMINATE_SYNC (1 << 2) -#define BLE_SUPP_CMD_LE_ADD_PADV_LIST (1 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_PADV_LIST (1 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_PADV_LIST (1 << 5) -#define BLE_SUPP_CMD_LE_RD_PADV_LIST_SIZE (1 << 6) -#else -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC (0 << 0) -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC_C (0 << 1) -#define BLE_SUPP_CMD_LE_PADV_TERMINATE_SYNC (0 << 2) -#define BLE_SUPP_CMD_LE_ADD_PADV_LIST (0 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_PADV_LIST (0 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_PADV_LIST (0 << 5) -#define BLE_SUPP_CMD_LE_RD_PADV_LIST_SIZE (0 << 6) -#endif -#define BLE_SUPP_CMD_LE_RD_TX_POWER (1 << 7) - -#define BLE_LL_SUPP_CMD_OCTET_38 \ -( \ - BLE_SUPP_CMD_LE_PADV_CREATE_SYNC | \ - BLE_SUPP_CMD_LE_PADV_CREATE_SYNC_C | \ - BLE_SUPP_CMD_LE_PADV_TERMINATE_SYNC | \ - BLE_SUPP_CMD_LE_ADD_PADV_LIST | \ - BLE_SUPP_CMD_LE_REMOVE_PADV_LIST | \ - BLE_SUPP_CMD_LE_CLEAR_PADV_LIST | \ - BLE_SUPP_CMD_LE_RD_PADV_LIST_SIZE | \ - BLE_SUPP_CMD_LE_RD_TX_POWER \ -) - -/* Octet 39 */ -#define BLE_SUPP_CMD_LE_RD_RF_PATH_COMP (1 << 0) -#define BLE_SUPP_CMD_LE_WR_RF_PATH_COMP (1 << 1) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -#define BLE_SUPP_CMD_LE_SET_PRIVACY_MODE (1 << 2) -#else -#define BLE_SUPP_CMD_LE_SET_PRIVACY_MODE (0 << 2) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_39 \ -( \ - BLE_SUPP_CMD_LE_RD_RF_PATH_COMP | \ - BLE_SUPP_CMD_LE_WR_RF_PATH_COMP | \ - BLE_SUPP_CMD_LE_SET_PRIVACY_MODE \ -) - -/* Octet 40 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_VERSION) >= 51 && \ - MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (1 << 5) -#else -#define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (0 << 5) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (1 << 6) -#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (1 << 7) -#else -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (0 << 6) -#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_40 \ -( \ - BLE_SUPP_CMD_LE_PADV_RECV_ENABLE | \ - BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER | \ - BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER \ -) - -/* Octet 41 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS (1 << 0) -#define BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS (1 << 1) -#else -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS (0 << 0) -#define BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS (0 << 1) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) -#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (1 << 5) -#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (1 << 6) -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (1 << 7) -#else -#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (0 << 5) -#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (0 << 6) -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_41 \ -( \ - BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS | \ - BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS | \ - BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 | \ - BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC | \ - BLE_SUPP_CMD_LE_SET_CIG_PARAM \ -) - -/* Octet 42 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (1 << 0) -#define BLE_SUPP_CMD_LE_CREATE_CIS (1 << 1) -#define BLE_SUPP_CMD_LE_REMOVE_CIG (1 << 2) -#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (1 << 3) -#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (1 << 4) -#define BLE_SUPP_CMD_LE_CREATE_BIG (1 << 5) -#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (1 << 6) -#define BLE_SUPP_CMD_LE_TERMINATE_BIG (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (0 << 0) -#define BLE_SUPP_CMD_LE_CREATE_CIS (0 << 1) -#define BLE_SUPP_CMD_LE_REMOVE_CIG (0 << 2) -#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (0 << 3) -#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (0 << 4) -#define BLE_SUPP_CMD_LE_CREATE_BIG (0 << 5) -#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (0 << 6) -#define BLE_SUPP_CMD_LE_TERMINATE_BIG (0 << 7) -#endif -#define BLE_LL_SUPP_CMD_OCTET_42 \ -( \ - BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST | \ - BLE_SUPP_CMD_LE_CREATE_CIS | \ - BLE_SUPP_CMD_LE_REMOVE_CIG | \ - BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ | \ - BLE_SUPP_CMD_LE_REJECT_CIS_REQ | \ - BLE_SUPP_CMD_LE_CREATE_BIG | \ - BLE_SUPP_CMD_LE_CREATE_BIG_TEST | \ - BLE_SUPP_CMD_LE_TERMINATE_BIG \ -) - -/* Octet 43 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) -#define BLE_SUPP_CMD_LE_REQUEST_PEER_SCA (1 << 2) -#else -#define BLE_SUPP_CMD_LE_REQUEST_PEER_SCA (0 << 0) -#endif -#define BLE_LL_SUPP_CMD_OCTET_43 \ -( \ - BLE_SUPP_CMD_LE_REQUEST_PEER_SCA \ -) - -/* Octet 44 */ -#if MYNEWT_VAL(BLE_VERSION) >= 52 -#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (1 << 1) -#else -#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (0 << 1) -#endif -#define BLE_LL_SUPP_CMD_OCTET_44 \ -( \ - BLE_SUPP_CMD_LE_SET_HOST_FEATURE \ -) - -/* Octet 46 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE (1 << 0) -#define BLE_SUPP_CMD_LE_SUBRATE_REQ (1 << 1) -#else -#define BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE (0 << 0) -#define BLE_SUPP_CMD_LE_SUBRATE_REQ (0 << 1) -#endif -#define BLE_LL_SUPP_CMD_OCTET_46 \ -( \ - BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE | \ - BLE_SUPP_CMD_LE_SUBRATE_REQ \ -) - -/* Defines the array of supported commands */ -const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN] = -{ - BLE_LL_SUPP_CMD_OCTET_0, /* Octet 0 */ - 0, - BLE_LL_SUPP_CMD_OCTET_2, /* Octet 2 */ - 0, - 0, - BLE_LL_SUPP_CMD_OCTET_5, - 0, - 0, - 0, /* Octet 8 */ - 0, - BLE_LL_SUPP_CMD_OCTET_10, - 0, - 0, - 0, - BLE_LL_SUPP_CMD_OCTET_14, - BLE_LL_SUPP_CMD_OCTET_15, - 0, /* Octet 16 */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, /* Octet 24 */ - BLE_LL_SUPP_CMD_OCTET_25, - BLE_LL_SUPP_CMD_OCTET_26, - BLE_LL_SUPP_CMD_OCTET_27, - BLE_LL_SUPP_CMD_OCTET_28, - 0, - 0, - 0, - 0, /* Octet 32 */ - BLE_LL_SUPP_CMD_OCTET_33, - BLE_LL_SUPP_CMD_OCTET_34, - BLE_LL_SUPP_CMD_OCTET_35, - BLE_LL_SUPP_CMD_OCTET_36, - BLE_LL_SUPP_CMD_OCTET_37, - BLE_LL_SUPP_CMD_OCTET_38, - BLE_LL_SUPP_CMD_OCTET_39, - BLE_LL_SUPP_CMD_OCTET_40, /* Octet 40 */ - BLE_LL_SUPP_CMD_OCTET_41, - BLE_LL_SUPP_CMD_OCTET_42, - BLE_LL_SUPP_CMD_OCTET_43, - BLE_LL_SUPP_CMD_OCTET_44, - 0, - BLE_LL_SUPP_CMD_OCTET_46, -}; diff --git a/lib/bt/host/nimble/nimble/nimble/controller/test/src/ble_ll_csa2_test.h b/lib/bt/host/nimble/nimble/nimble/controller/test/src/ble_ll_csa2_test.h deleted file mode 100644 index 5bcc142b..00000000 --- a/lib/bt/host/nimble/nimble/nimble/controller/test/src/ble_ll_csa2_test.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_BLE_LL_CSA2_TEST_ -#define H_BLE_LL_CSA2_TEST_ - -#include "testutil/testutil.h" - -TEST_SUITE_DECL(ble_ll_csa2_test_suite); - -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/include/ble/xcvr.h b/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/include/ble/xcvr.h deleted file mode 100644 index 757bb80f..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/include/ble/xcvr.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_BLE_XCVR_ -#define H_BLE_XCVR_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define XCVR_RX_RADIO_RAMPUP_USECS (40) -#define XCVR_TX_RADIO_RAMPUP_USECS (40) - -/* - * NOTE: we have to account for the RTC output compare issue. We want it to be - * 5 ticks. - */ -#define XCVR_PROC_DELAY_USECS (153) -#define XCVR_RX_START_DELAY_USECS (XCVR_RX_RADIO_RAMPUP_USECS) -#define XCVR_TX_START_DELAY_USECS (XCVR_TX_RADIO_RAMPUP_USECS) -#define XCVR_TX_SCHED_DELAY_USECS \ - (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) -#define XCVR_RX_SCHED_DELAY_USECS \ - (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) - -/* - * Define HW whitelist size. This is the total possible whitelist size; - * not necessarily the size that will be used (may be smaller) - */ -#define BLE_HW_WHITE_LIST_SIZE (8) - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_XCVR_ */ diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_hw.c b/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_hw.c deleted file mode 100644 index ef4c28b0..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_hw.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include "syscfg/syscfg.h" -#include "os/os.h" -#include "ble/xcvr.h" -#include "nimble/ble.h" -#include "nimble/nimble_opt.h" -#include "nrfx.h" -#include "controller/ble_hw.h" -#if MYNEWT -#include "mcu/cmsis_nvic.h" -#else -#include "core_cm4.h" -#include -#endif -#include "os/os_trace_api.h" -#include -#include "hal/nrf_ecb.h" - -/* Total number of resolving list elements */ -#define BLE_HW_RESOLV_LIST_SIZE (16) - -/* We use this to keep track of which entries are set to valid addresses */ -static uint8_t g_ble_hw_whitelist_mask; - -/* Random number generator isr callback */ -ble_rng_isr_cb_t g_ble_rng_isr_cb; - -#if BABBLESIM -extern void tm_tick(void); -#endif - -/* If LL privacy is enabled, allocate memory for AAR */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - -/* The NRF51 supports up to 16 IRK entries */ -#if (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE) < 16) -#define NRF_IRK_LIST_ENTRIES (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)) -#else -#define NRF_IRK_LIST_ENTRIES (16) -#endif - -/* NOTE: each entry is 16 bytes long. */ -uint32_t g_nrf_irk_list[NRF_IRK_LIST_ENTRIES * 4]; - -/* Current number of IRK entries */ -uint8_t g_nrf_num_irks; - -#endif - -/* Returns public device address or -1 if not present */ -int -ble_hw_get_public_addr(ble_addr_t *addr) -{ - uint32_t addr_high; - uint32_t addr_low; - -#if MYNEWT_VAL(BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR) - /* - * The BMD-345 modules are preprogrammed from the factory with a unique public - * The Bluetooth device address stored in the CUSTOMER[0] and CUSTOMER[1] - * registers of the User Information Configuration Registers (UICR). - * The Bluetooth device address consists of the IEEE Organizationally Unique - * Identifier (OUI) combined with the hexadecimal digits that are printed on - * a 2D barcode and in human-readable text on the module label.The Bluetooth - * device address is stored in little endian format. The most significant - * bytes of the CUSTOMER[1] register are 0xFF to complete the 32-bit register. - */ - - /* Copy into device address. We can do this because we know platform */ - addr_low = NRF_UICR->CUSTOMER[0]; - addr_high = NRF_UICR->CUSTOMER[1]; -#else - /* Does FICR have a public address */ - if ((NRF_FICR->DEVICEADDRTYPE & 1) != 0) { - return -1; - } - - /* Copy into device address. We can do this because we know platform */ - addr_low = NRF_FICR->DEVICEADDR[0]; - addr_high = NRF_FICR->DEVICEADDR[1]; -#endif - - memcpy(addr->val, &addr_low, 4); - memcpy(&addr->val[4], &addr_high, 2); - addr->type = BLE_ADDR_PUBLIC; - - return 0; -} - -/* Returns random static address or -1 if not present */ -int -ble_hw_get_static_addr(ble_addr_t *addr) -{ - int rc; - - if ((NRF_FICR->DEVICEADDRTYPE & 1) == 1) { - memcpy(addr->val, (void *)&NRF_FICR->DEVICEADDR[0], 4); - memcpy(&addr->val[4], (void *)&NRF_FICR->DEVICEADDR[1], 2); - addr->val[5] |= 0xc0; - addr->type = BLE_ADDR_RANDOM; - rc = 0; - } else { - rc = -1; - } - - return rc; -} - -/** - * Clear the whitelist - * - * @return int - */ -void -ble_hw_whitelist_clear(void) -{ - NRF_RADIO->DACNF = 0; - g_ble_hw_whitelist_mask = 0; -} - -/** - * Add a device to the hw whitelist - * - * @param addr - * @param addr_type - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_whitelist_add(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint32_t mask; - - /* Find first ununsed device address match element */ - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if ((mask & g_ble_hw_whitelist_mask) == 0) { - NRF_RADIO->DAB[i] = get_le32(addr); - NRF_RADIO->DAP[i] = get_le16(addr + 4); - if (addr_type == BLE_ADDR_RANDOM) { - NRF_RADIO->DACNF |= (mask << 8); - } - g_ble_hw_whitelist_mask |= mask; - return BLE_ERR_SUCCESS; - } - mask <<= 1; - } - - return BLE_ERR_MEM_CAPACITY; -} - -/** - * Remove a device from the hw whitelist - * - * @param addr - * @param addr_type - * - */ -void -ble_hw_whitelist_rmv(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint8_t cfg_addr; - uint16_t dap; - uint16_t txadd; - uint32_t dab; - uint32_t mask; - - /* Find first ununsed device address match element */ - dab = get_le32(addr); - dap = get_le16(addr + 4); - txadd = NRF_RADIO->DACNF >> 8; - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if (mask & g_ble_hw_whitelist_mask) { - if ((dab == NRF_RADIO->DAB[i]) && (dap == NRF_RADIO->DAP[i])) { - cfg_addr = txadd & mask; - if (addr_type == BLE_ADDR_RANDOM) { - if (cfg_addr != 0) { - break; - } - } else { - if (cfg_addr == 0) { - break; - } - } - } - } - mask <<= 1; - } - - if (i < BLE_HW_WHITE_LIST_SIZE) { - g_ble_hw_whitelist_mask &= ~mask; - NRF_RADIO->DACNF &= ~mask; - } -} - -/** - * Returns the size of the whitelist in HW - * - * @return int Number of devices allowed in whitelist - */ -uint8_t -ble_hw_whitelist_size(void) -{ - return BLE_HW_WHITE_LIST_SIZE; -} - -/** - * Enable the whitelisted devices - */ -void -ble_hw_whitelist_enable(void) -{ - /* Enable the configured device addresses */ - NRF_RADIO->DACNF |= g_ble_hw_whitelist_mask; -} - -/** - * Disables the whitelisted devices - */ -void -ble_hw_whitelist_disable(void) -{ - /* Disable all whitelist devices */ - NRF_RADIO->DACNF &= 0x0000ff00; -} - -/** - * Boolean function which returns true ('1') if there is a match on the - * whitelist. - * - * @return int - */ -int -ble_hw_whitelist_match(void) -{ - return (int)NRF_RADIO->EVENTS_DEVMATCH; -} - -/* Encrypt data */ -int -ble_hw_encrypt_block(struct ble_encryption_block *ecb) -{ - int rc; - uint32_t end; - uint32_t err; - - /* Stop ECB */ - nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB); - /* XXX: does task stop clear these counters? Anyway to do this quicker? */ - NRF_ECB->EVENTS_ENDECB = 0; - NRF_ECB->EVENTS_ERRORECB = 0; - NRF_ECB->ECBDATAPTR = (uint32_t)ecb; - - /* Start ECB */ - nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB); - - /* Wait till error or done */ - rc = 0; - while (1) { - end = NRF_ECB->EVENTS_ENDECB; - err = NRF_ECB->EVENTS_ERRORECB; - if (end || err) { - if (err) { - rc = -1; - } - break; - } -#if BABBLESIM - tm_tick(); -#endif - } - - return rc; -} - -/** - * Random number generator ISR. - */ -static void -ble_rng_isr(void) -{ - uint8_t rnum; - - os_trace_isr_enter(); - - /* No callback? Clear and disable interrupts */ - if (g_ble_rng_isr_cb == NULL) { - nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); - NRF_RNG->EVENTS_VALRDY = 0; - (void)NRF_RNG->SHORTS; - os_trace_isr_exit(); - return; - } - - /* If there is a value ready grab it */ - if (NRF_RNG->EVENTS_VALRDY) { - NRF_RNG->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG->VALUE; - (*g_ble_rng_isr_cb)(rnum); - } - - os_trace_isr_exit(); -} - -/** - * Initialize the random number generator - * - * @param cb - * @param bias - * - * @return int - */ -int -ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias) -{ - /* Set bias */ - if (bias) { - NRF_RNG->CONFIG = 1; - } else { - NRF_RNG->CONFIG = 0; - } - - /* If we were passed a function pointer we need to enable the interrupt */ - if (cb != NULL) { -#ifndef RIOT_VERSION - NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1); -#endif -#if MYNEWT - NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr); -#else - ble_npl_hw_set_isr(RNG_IRQn, ble_rng_isr); -#endif - NVIC_EnableIRQ(RNG_IRQn); - g_ble_rng_isr_cb = cb; - } - - return 0; -} - -/** - * Start the random number generator - * - * @return int - */ -int -ble_hw_rng_start(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - NRF_RNG->EVENTS_VALRDY = 0; - - if (g_ble_rng_isr_cb) { - nrf_rng_int_enable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); - } - nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_START); - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Stop the random generator - * - * @return int - */ -int -ble_hw_rng_stop(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); - nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP); - NRF_RNG->EVENTS_VALRDY = 0; - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Read the random number generator. - * - * @return uint8_t - */ -uint8_t -ble_hw_rng_read(void) -{ - uint8_t rnum; - - /* Wait for a sample */ - while (NRF_RNG->EVENTS_VALRDY == 0) { - } - - NRF_RNG->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG->VALUE; - - return rnum; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -/** - * Clear the resolving list - * - * @return int - */ -void -ble_hw_resolv_list_clear(void) -{ - g_nrf_num_irks = 0; -} - -/** - * Add a device to the hw resolving list - * - * @param irk Pointer to IRK to add - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_resolv_list_add(uint8_t *irk) -{ - uint32_t *nrf_entry; - - /* Find first ununsed device address match element */ - if (g_nrf_num_irks == NRF_IRK_LIST_ENTRIES) { - return BLE_ERR_MEM_CAPACITY; - } - - /* Copy into irk list */ - nrf_entry = &g_nrf_irk_list[4 * g_nrf_num_irks]; - memcpy(nrf_entry, irk, 16); - - /* Add to total */ - ++g_nrf_num_irks; - return BLE_ERR_SUCCESS; -} - -/** - * Remove a device from the hw resolving list - * - * @param index Index of IRK to remove - */ -void -ble_hw_resolv_list_rmv(int index) -{ - uint32_t *irk_entry; - - if (index < g_nrf_num_irks) { - --g_nrf_num_irks; - irk_entry = &g_nrf_irk_list[index]; - if (g_nrf_num_irks > index) { - memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index)); - } - } -} - -/** - * Returns the size of the resolving list. NOTE: this returns the maximum - * allowable entries in the HW. Configuration options may limit this. - * - * @return int Number of devices allowed in resolving list - */ -uint8_t -ble_hw_resolv_list_size(void) -{ - return BLE_HW_RESOLV_LIST_SIZE; -} - -/** - * Called to determine if the address received was resolved. - * - * @return int Negative values indicate unresolved address; positive values - * indicate index in resolving list of resolved address. - */ -int -ble_hw_resolv_list_match(void) -{ - if (NRF_AAR->ENABLE && NRF_AAR->EVENTS_END && NRF_AAR->EVENTS_RESOLVED) { - return (int)NRF_AAR->STATUS; - } - - return -1; -} -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy.c b/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy.c deleted file mode 100644 index dc8ba4e7..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy.c +++ /dev/null @@ -1,2257 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "os/os.h" -/* Keep os_cputime explicitly to enable build on non-Mynewt platforms */ -#include "os/os_cputime.h" -#include "ble/xcvr.h" -#include "nimble/ble.h" -#include "nimble/nimble_opt.h" -#include "nimble/nimble_npl.h" -#include "controller/ble_phy.h" -#include "controller/ble_phy_trace.h" -#include "controller/ble_ll.h" -#include "controller/ble_ll_plna.h" -#include "nrfx.h" -#if MYNEWT -#include "mcu/nrf52_clock.h" -#include "mcu/cmsis_nvic.h" -#include "hal/hal_gpio.h" -#else -#include "core_cm4.h" -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) -#if !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) && !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52811) -#error LE Coded PHY can only be enabled on nRF52811 or nRF52840 -#endif -#endif - -#if BABBLESIM -extern void tm_tick(void); -#endif - -/* - * NOTE: This code uses a couple of PPI channels so care should be taken when - * using PPI somewhere else. - * - * Pre-programmed channels: CH20, CH21, CH23, CH25, CH31 - * Regular channels: CH4, CH5 and optionally CH6, CH7, CH17, CH18, CH19 - * - CH4 = cancel wfr timer on address match - * - CH5 = disable radio on wfr timer expiry - * - CH6 = PA/LNA control (enable) - * - CH7 = PA/LNA control (disable) - * - CH17 = (optional) gpio debug for radio ramp-up - * - CH18 = (optional) gpio debug for wfr timer RX enabled - * - CH19 = (optional) gpio debug for wfr timer radio disabled - * - */ - -/* XXX: 4) Make sure RF is higher priority interrupt than schedule */ - -/* - * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal - * and 16ms for a 30ppm crystal! We need to limit PDU size based on - * crystal accuracy. Look at this in the spec. - */ - -/* XXX: private header file? */ -extern uint8_t g_nrf_num_irks; -extern uint32_t g_nrf_irk_list[]; - -/* To disable all radio interrupts */ -#define NRF_RADIO_IRQ_MASK_ALL (0x34FF) - -/* - * We configure the nrf with a 1 byte S0 field, 8 bit length field, and - * zero bit S1 field. The preamble is 8 bits long. - */ -#define NRF_LFLEN_BITS (8) -#define NRF_S0LEN (1) -#define NRF_S1LEN_BITS (0) -#define NRF_CILEN_BITS (2) -#define NRF_TERMLEN_BITS (3) - -/* Maximum length of frames */ -#define NRF_MAXLEN (255) -#define NRF_BALEN (3) /* For base address of 3 bytes */ - -/* NRF_RADIO->PCNF0 configuration values */ -#define NRF_PCNF0 (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) | \ - (RADIO_PCNF0_S1INCL_Msk) | \ - (NRF_S0LEN << RADIO_PCNF0_S0LEN_Pos) | \ - (NRF_S1LEN_BITS << RADIO_PCNF0_S1LEN_Pos) -#define NRF_PCNF0_1M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_2M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_CODED (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | \ - (NRF_CILEN_BITS << RADIO_PCNF0_CILEN_Pos) | \ - (NRF_TERMLEN_BITS << RADIO_PCNF0_TERMLEN_Pos) - -/* BLE PHY data structure */ -struct ble_phy_obj -{ - uint8_t phy_stats_initialized; - int8_t phy_txpwr_dbm; - uint8_t phy_chan; - uint8_t phy_state; - uint8_t phy_transition; - uint8_t phy_transition_late; - uint8_t phy_rx_started; - uint8_t phy_encrypted; - uint8_t phy_privacy; - uint8_t phy_tx_pyld_len; - uint8_t phy_cur_phy_mode; - uint8_t phy_tx_phy_mode; - uint8_t phy_rx_phy_mode; - uint8_t phy_bcc_offset; - int8_t rx_pwr_compensation; - uint32_t phy_aar_scratch; - uint32_t phy_access_address; - struct ble_mbuf_hdr rxhdr; - void *txend_arg; - ble_phy_tx_end_func txend_cb; - uint32_t phy_start_cputime; -}; -struct ble_phy_obj g_ble_phy_data; - -/* XXX: if 27 byte packets desired we can make this smaller */ -/* Global transmit/receive buffer */ -static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/* Make sure word-aligned for faster copies */ -static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -#endif - -/* RF center frequency for each channel index (offset from 2400 MHz) */ -static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = { - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, /* 0-9 */ - 24, 28, 30, 32, 34, 36, 38, 40, 42, 44, /* 10-19 */ - 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, /* 20-29 */ - 66, 68, 70, 72, 74, 76, 78, 2, 26, 80, /* 30-39 */ -}; - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) -/* packet start offsets (in usecs) */ -static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 40, - [BLE_PHY_MODE_2M] = 24, - [BLE_PHY_MODE_CODED_125KBPS] = 376, - [BLE_PHY_MODE_CODED_500KBPS] = 376 -}; -#endif - -/* Various radio timings */ -/* Radio ramp-up times in usecs (fast mode) */ -#define BLE_PHY_T_TXENFAST (XCVR_TX_RADIO_RAMPUP_USECS) -#define BLE_PHY_T_RXENFAST (XCVR_RX_RADIO_RAMPUP_USECS) - -#if BABBLESIM -/* delay between EVENTS_READY and start of tx */ -static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 1, - [BLE_PHY_MODE_2M] = 1, -}; -/* delay between EVENTS_END and end of txd packet */ -static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 1, - [BLE_PHY_MODE_2M] = 1, -}; -/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ -static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 9, - [BLE_PHY_MODE_2M] = 5, -}; -/* delay between end of rxd packet and EVENTS_END */ -static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 9, - [BLE_PHY_MODE_2M] = 5, -}; -#else -/* delay between EVENTS_READY and start of tx */ -static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 5, - [BLE_PHY_MODE_CODED_500KBPS] = 5 -}; -/* delay between EVENTS_END and end of txd packet */ -static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 9, - [BLE_PHY_MODE_CODED_500KBPS] = 3 -}; -/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ -static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 17, - [BLE_PHY_MODE_CODED_500KBPS] = 17 -}; -/* delay between end of rxd packet and EVENTS_END */ -static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 27, - [BLE_PHY_MODE_CODED_500KBPS] = 22 -}; -#endif - -/* Statistics */ -STATS_SECT_START(ble_phy_stats) - STATS_SECT_ENTRY(phy_isrs) - STATS_SECT_ENTRY(tx_good) - STATS_SECT_ENTRY(tx_fail) - STATS_SECT_ENTRY(tx_late) - STATS_SECT_ENTRY(tx_bytes) - STATS_SECT_ENTRY(rx_starts) - STATS_SECT_ENTRY(rx_aborts) - STATS_SECT_ENTRY(rx_valid) - STATS_SECT_ENTRY(rx_crc_err) - STATS_SECT_ENTRY(rx_late) - STATS_SECT_ENTRY(radio_state_errs) - STATS_SECT_ENTRY(rx_hw_err) - STATS_SECT_ENTRY(tx_hw_err) -STATS_SECT_END -STATS_SECT_DECL(ble_phy_stats) ble_phy_stats; - -STATS_NAME_START(ble_phy_stats) - STATS_NAME(ble_phy_stats, phy_isrs) - STATS_NAME(ble_phy_stats, tx_good) - STATS_NAME(ble_phy_stats, tx_fail) - STATS_NAME(ble_phy_stats, tx_late) - STATS_NAME(ble_phy_stats, tx_bytes) - STATS_NAME(ble_phy_stats, rx_starts) - STATS_NAME(ble_phy_stats, rx_aborts) - STATS_NAME(ble_phy_stats, rx_valid) - STATS_NAME(ble_phy_stats, rx_crc_err) - STATS_NAME(ble_phy_stats, rx_late) - STATS_NAME(ble_phy_stats, radio_state_errs) - STATS_NAME(ble_phy_stats, rx_hw_err) - STATS_NAME(ble_phy_stats, tx_hw_err) -STATS_NAME_END(ble_phy_stats) - -/* - * NOTE: - * Tested the following to see what would happen: - * -> NVIC has radio irq enabled (interrupt # 1, mask 0x2). - * -> Set up nrf to receive. Clear ADDRESS event register. - * -> Enable ADDRESS interrupt on nrf5 by writing to INTENSET. - * -> Enable RX. - * -> Disable interrupts globally using OS_ENTER_CRITICAL(). - * -> Wait until a packet is received and the ADDRESS event occurs. - * -> Call ble_phy_disable(). - * - * At this point I wanted to see the state of the cortex NVIC. The IRQ - * pending bit was TRUE for the radio interrupt (as expected) as we never - * serviced the radio interrupt (interrupts were disabled). - * - * What was unexpected was this: without clearing the pending IRQ in the NVIC, - * when radio interrupts were re-enabled (address event bit in INTENSET set to - * 1) and the radio ADDRESS event register read 1 (it was never cleared after - * the first address event), the radio did not enter the ISR! I would have - * expected that if the following were true, an interrupt would occur: - * -> NVIC ISER bit set to TRUE - * -> NVIC ISPR bit reads TRUE, meaning interrupt is pending. - * -> Radio peripheral interrupts are enabled for some event (or events). - * -> Corresponding event register(s) in radio peripheral read 1. - * - * Not sure what the end result of all this is. We will clear the pending - * bit in the NVIC just to be sure when we disable the PHY. - */ - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - -/* - * Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE. - * However, when I used a smaller size it still overwrote the scratchpad. Until - * I figure this out I am just going to allocate 67 words so we have enough - * space for 267 bytes of scratch. I used 268 bytes since not sure if this - * needs to be aligned and burning a byte is no big deal. - */ -//#define NRF_ENC_SCRATCH_WORDS (((MYNEWT_VAL(BLE_LL_MAX_PKT_SIZE) + 16) + 3) / 4) -#define NRF_ENC_SCRATCH_WORDS (67) - -uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS]; - -struct nrf_ccm_data -{ - uint8_t key[16]; - uint64_t pkt_counter; - uint8_t dir_bit; - uint8_t iv[8]; -} __attribute__((packed)); - -struct nrf_ccm_data g_nrf_ccm_data; -#endif - -static int g_ble_phy_gpiote_idx; - -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) - -#define PLNA_SINGLE_GPIO \ - (!MYNEWT_VAL(BLE_LL_PA) || !MYNEWT_VAL(BLE_LL_LNA) || \ - (MYNEWT_VAL(BLE_LL_PA_GPIO) == MYNEWT_VAL(BLE_LL_LNA_GPIO))) - -#if PLNA_SINGLE_GPIO -static uint8_t plna_idx; -#else -#if MYNEWT_VAL(BLE_LL_PA) -static uint8_t plna_pa_idx; -#endif -#if MYNEWT_VAL(BLE_LL_LNA) -static uint8_t plna_lna_idx; -#endif -#endif - -#endif - -#ifndef BABBLESIM -static void -ble_phy_apply_errata_102_106_107(void) -{ - /* [102] RADIO: PAYLOAD/END events delayed or not triggered after ADDRESS - * [106] RADIO: Higher CRC error rates for some access addresses - * [107] RADIO: Immediate address match for access addresses containing MSBs 0x00 - */ - *(volatile uint32_t *)0x40001774 = ((*(volatile uint32_t *)0x40001774) & - 0xfffffffe) | 0x01000000; -} -#endif - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - -/* Packet start offset (in usecs). This is the preamble plus access address. - * For LE Coded PHY this also includes CI and TERM1. */ -uint32_t -ble_phy_mode_pdu_start_off(int phy_mode) -{ - return g_ble_phy_mode_pkt_start_off[phy_mode]; -} - -#if NRF52840_XXAA -static inline bool -ble_phy_mode_is_coded(uint8_t phy_mode) -{ - return (phy_mode == BLE_PHY_MODE_CODED_125KBPS) || - (phy_mode == BLE_PHY_MODE_CODED_500KBPS); -} - -static void -ble_phy_apply_nrf52840_errata(uint8_t new_phy_mode) -{ - bool new_coded = ble_phy_mode_is_coded(new_phy_mode); - bool cur_coded = ble_phy_mode_is_coded(g_ble_phy_data.phy_cur_phy_mode); - - /* - * Workarounds should be applied only when switching to/from LE Coded PHY - * so no need to apply them every time. - * - * nRF52840 Engineering A Errata v1.2 - * [164] RADIO: Low sensitivity in long range mode - * - * nRF52840 Rev 1 Errata - * [191] RADIO: High packet error rate in BLE Long Range mode - */ - if (new_coded == cur_coded) { - return; - } - - if (new_coded) { -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) - /* [164] */ - *(volatile uint32_t *)0x4000173C |= 0x80000000; - *(volatile uint32_t *)0x4000173C = - ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C); -#endif -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) - /* [191] */ - *(volatile uint32_t *) 0x40001740 = - ((*((volatile uint32_t *) 0x40001740)) & 0x7FFF00FF) | - 0x80000000 | (((uint32_t)(196)) << 8); -#endif - } else { -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) - /* [164] */ - *(volatile uint32_t *)0x4000173C &= ~0x80000000; -#endif -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) - /* [191] */ - *(volatile uint32_t *) 0x40001740 = - ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF); -#endif - } -} -#endif - -static void -ble_phy_mode_apply(uint8_t phy_mode) -{ - if (phy_mode == g_ble_phy_data.phy_cur_phy_mode) { - return; - } - -#if NRF52840_XXAA - ble_phy_apply_nrf52840_errata(phy_mode); -#endif - - switch (phy_mode) { - case BLE_PHY_MODE_1M: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_1M; - break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - case BLE_PHY_MODE_2M: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_2Mbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_2M; - break; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; - break; - case BLE_PHY_MODE_CODED_500KBPS: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; - break; -#endif - default: - assert(0); - } - - g_ble_phy_data.phy_cur_phy_mode = phy_mode; -} - -void -ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) -{ - g_ble_phy_data.phy_tx_phy_mode = tx_phy_mode; - g_ble_phy_data.phy_rx_phy_mode = rx_phy_mode; -} -#endif - -static void -ble_phy_plna_enable_pa(void) -{ -#if MYNEWT_VAL(BLE_LL_PA) - ble_ll_plna_pa_enable(); - -#if !PLNA_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_pa_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_pa_idx]); -#endif - - NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif -} - -static void -ble_phy_plna_enable_lna(void) -{ -#if MYNEWT_VAL(BLE_LL_LNA) - ble_ll_plna_lna_enable(); - -#if !PLNA_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_lna_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_lna_idx]); -#endif - - NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif -} - -int -ble_phy_get_cur_phy(void) -{ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return BLE_PHY_1M; - case BLE_PHY_MODE_2M: - return BLE_PHY_2M; - case BLE_PHY_MODE_CODED_125KBPS: - case BLE_PHY_MODE_CODED_500KBPS: - return BLE_PHY_CODED; - default: - assert(0); - return -1; - } -#else - return BLE_PHY_1M; -#endif -} - -/** - * Copies the data from the phy receive buffer into a mbuf chain. - * - * @param dptr Pointer to receive buffer - * @param rxpdu Pointer to already allocated mbuf chain - * - * NOTE: the packet header already has the total mbuf length in it. The - * lengths of the individual mbufs are not set prior to calling. - * - */ -void -ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) -{ - uint32_t rem_len; - uint32_t copy_len; - uint32_t block_len; - uint32_t block_rem_len; - void *dst; - void *src; - struct os_mbuf * om; - - /* Better be aligned */ - assert(((uint32_t)dptr & 3) == 0); - - block_len = rxpdu->om_omp->omp_databuf_len; - rem_len = OS_MBUF_PKTHDR(rxpdu)->omp_len; - src = dptr; - - /* - * Setup for copying from first mbuf which is shorter due to packet header - * and extra leading space - */ - copy_len = block_len - rxpdu->om_pkthdr_len - 4; - om = rxpdu; - dst = om->om_data; - - while (true) { - /* - * Always copy blocks of length aligned to word size, only last mbuf - * will have remaining non-word size bytes appended. - */ - block_rem_len = copy_len; - copy_len = min(copy_len, rem_len); - copy_len &= ~3; - - dst = om->om_data; - om->om_len = copy_len; - rem_len -= copy_len; - block_rem_len -= copy_len; - -#if BABBLESIM - memcpy(dst, src, copy_len); - dst += copy_len; - src += copy_len; -#else - __asm__ volatile (".syntax unified \n" - " mov r4, %[len] \n" - " b 2f \n" - "1: ldr r3, [%[src], %[len]] \n" - " str r3, [%[dst], %[len]] \n" - "2: subs %[len], #4 \n" - " bpl 1b \n" - " adds %[src], %[src], r4 \n" - " adds %[dst], %[dst], r4 \n" - : [dst] "+r" (dst), [src] "+r" (src), - [len] "+r" (copy_len) - : - : "r3", "r4", "memory" - ); -#endif - - if ((rem_len < 4) && (block_rem_len >= rem_len)) { - break; - } - - /* Move to next mbuf */ - om = SLIST_NEXT(om, om_next); - copy_len = block_len; - } - - /* Copy remaining bytes, if any, to last mbuf */ - om->om_len += rem_len; - -#if BABBLESIM - memcpy(dst, src, rem_len); -#else - __asm__ volatile (".syntax unified \n" - " b 2f \n" - "1: ldrb r3, [%[src], %[len]] \n" - " strb r3, [%[dst], %[len]] \n" - "2: subs %[len], #1 \n" - " bpl 1b \n" - : [len] "+r" (rem_len) - : [dst] "r" (dst), [src] "r" (src) - : "r3", "memory" - ); -#endif - - /* Copy header */ - memcpy(BLE_MBUF_HDR_PTR(rxpdu), &g_ble_phy_data.rxhdr, - sizeof(struct ble_mbuf_hdr)); -} - -/** - * Called when we want to wait if the radio is in either the rx or tx - * disable states. We want to wait until that state is over before doing - * anything to the radio - */ -static void -nrf_wait_disabled(void) -{ - uint32_t state; - - state = NRF_RADIO->STATE; - if (state != RADIO_STATE_STATE_Disabled) { - if ((state == RADIO_STATE_STATE_RxDisable) || - (state == RADIO_STATE_STATE_TxDisable)) { - /* This will end within a short time (6 usecs). Just poll */ - while (NRF_RADIO->STATE == state) { - /* If this fails, something is really wrong. Should last - * no more than 6 usecs */ -#if BABBLESIM - tm_tick(); -#endif - } - } - } -} - -/** - * - * - */ -static int -ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) -{ - uint32_t next_cc; - uint32_t cur_cc; - uint32_t cntr; - uint32_t delta; - - /* - * We need to adjust start time to include radio ramp-up and TX pipeline - * delay (the latter only if applicable, so only for TX). - * - * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on - * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate - * using TIMER0 with 1 usec precision. - */ - - cputime -= 2; - rem_usecs += 61; - if (tx) { - rem_usecs -= BLE_PHY_T_TXENFAST; - rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - } else { - rem_usecs -= BLE_PHY_T_RXENFAST; - } - - /* - * rem_usecs will be no more than 2 ticks, but if it is more than single - * tick then we should better count one more low-power tick rather than - * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the - * compare won't occur. - */ - - if (rem_usecs > 30) { - cputime++; - rem_usecs -= 30; - } - - /* - * Can we set the RTC compare to start TIMER0? We can do it if: - * a) Current compare value is not N+1 or N+2 ticks from current - * counter. - * b) The value we want to set is not at least N+2 from current - * counter. - * - * NOTE: since the counter can tick 1 while we do these calculations we - * need to account for it. - */ - next_cc = cputime & 0xffffff; - cur_cc = NRF_RTC0->CC[0]; - cntr = NRF_RTC0->COUNTER; - - delta = (cur_cc - cntr) & 0xffffff; - if ((delta <= 3) && (delta != 0)) { - return -1; - } - delta = (next_cc - cntr) & 0xffffff; - if ((delta & 0x800000) || (delta < 3)) { - return -1; - } - - /* Clear and set TIMER0 to fire off at proper time */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); - nrf_timer_cc_set(NRF_TIMER0, 0, rem_usecs); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - - /* Set RTC compare to start TIMER0 */ - NRF_RTC0->EVENTS_COMPARE[0] = 0; - nrf_rtc_cc_set(NRF_RTC0, 0, next_cc); - nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); - - /* Enable PPI */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); - - /* Store the cputime at which we set the RTC */ - g_ble_phy_data.phy_start_cputime = cputime; - - return 0; -} - -static int -ble_phy_set_start_now(void) -{ - os_sr_t sr; - uint32_t now; - - OS_ENTER_CRITICAL(sr); - - /* - * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not - * occur in such case. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); - nrf_timer_cc_set(NRF_TIMER0, 0, 1); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - - /* - * Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks - * from current value to guarantee triggering compare event, but let's set - * it to N+3 to account for possible extra tick on RTC0 during these - * operations. - */ - now = os_cputime_get32(); - NRF_RTC0->EVENTS_COMPARE[0] = 0; - nrf_rtc_cc_set(NRF_RTC0, 0, now + 3); - nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); - - /* Enable PPI */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); - /* - * Store the cputime at which we set the RTC - * - * XXX Compare event may be triggered on previous CC value (if it was set to - * less than N+2) so in rare cases actual start time may be 2 ticks earlier - * than what we expect. Since this is only used on RX, it may cause AUX scan - * to be scheduled 1 or 2 ticks too late so we'll miss it - it's acceptable - * for now. - */ - g_ble_phy_data.phy_start_cputime = now + 3; - - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Function is used to set PPI so that we can time out waiting for a reception - * to occur. This happens for two reasons: we have sent a packet and we are - * waiting for a response (txrx should be set to ENABLE_TXRX) or we are - * starting a connection event and we are a slave and we are waiting for the - * master to send us a packet (txrx should be set to ENABLE_RX). - * - * NOTE: when waiting for a txrx turn-around, wfr_usecs is not used as there - * is no additional time to wait; we know when we should receive the address of - * the received frame. - * - * @param txrx Flag denoting if this wfr is a txrx turn-around or not. - * @param tx_phy_mode phy mode for last TX (only valid for TX->RX) - * @param wfr_usecs Amount of usecs to wait. - */ -void -ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) -{ - uint32_t end_time; - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - - if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { - /* RX shall start exactly T_IFS after TX end captured in CC[2] */ - end_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; - /* Adjust for delay between EVENT_END and actual TX end time */ - end_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Wait a bit longer due to allowed active clock accuracy */ - end_time += 2; - /* - * It's possible that we'll capture PDU start time at the end of timer - * cycle and since wfr expires at the beginning of calculated timer - * cycle it can be almost 1 usec too early. Let's compensate for this - * by waiting 1 usec more. - */ - end_time += 1; - } else { - /* - * RX shall start no later than wfr_usecs after RX enabled. - * CC[0] is the time of RXEN so adjust for radio ram-up. - * Do not add jitter since this is already covered by LL. - */ - end_time = NRF_TIMER0->CC[0] + BLE_PHY_T_RXENFAST + wfr_usecs; - } - - /* - * Note: on LE Coded EVENT_ADDRESS is fired after TERM1 is received, so - * we are actually calculating relative to start of packet payload - * which is fine. - */ - - /* Adjust for receiving access address since this triggers EVENT_ADDRESS */ - end_time += ble_phy_mode_pdu_start_off(phy); - /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ - end_time += g_ble_phy_t_rxaddrdelay[phy]; - - /* wfr_secs is the time from rxen until timeout */ - nrf_timer_cc_set(NRF_TIMER0, 3, end_time); - NRF_TIMER0->EVENTS_COMPARE[3] = 0; - - /* Enable wait for response PPI */ - nrf_ppi_channels_enable(NRF_PPI, (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk)); - - /* - * It may happen that if CPU is halted for a brief moment (e.g. during flash - * erase or write), TIMER0 already counted past CC[3] and thus wfr will not - * fire as expected. In case this happened, let's just disable PPIs for wfr - * and trigger wfr manually (i.e. disable radio). - * - * Note that the same applies to RX start time set in CC[0] but since it - * should fire earlier than wfr, fixing wfr is enough. - * - * CC[1] is only used as a reference on RX start, we do not need it here so - * it can be used to read TIMER0 counter. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); - if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); - nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); - } -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -static uint32_t -ble_phy_get_ccm_datarate(void) -{ -#if BLE_LL_BT5_PHY_SUPPORTED - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_2M: - return CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - return CCM_MODE_DATARATE_125Kbps << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_CODED_500KBPS: - return CCM_MODE_DATARATE_500Kbps << CCM_MODE_DATARATE_Pos; -#endif - } - - assert(0); - return 0; -#else - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; -#endif -} -#endif - -/** - * Setup transceiver for receive. - */ -static void -ble_phy_rx_xcvr_setup(void) -{ - uint8_t *dptr; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM->OUTPTR = (uint32_t)dptr; - NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0]; - NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption | - ble_phy_get_ccm_datarate(); - NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data; - NRF_CCM->SHORTS = 0; - NRF_CCM->EVENTS_ERROR = 0; - NRF_CCM->EVENTS_ENDCRYPT = 0; - nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH25_Msk); - } else { - NRF_RADIO->PACKETPTR = (uint32_t)dptr; - } -#else - NRF_RADIO->PACKETPTR = (uint32_t)dptr; -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (g_ble_phy_data.phy_privacy) { - NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled; - NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - NRF_AAR->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch; - NRF_AAR->EVENTS_END = 0; - NRF_AAR->EVENTS_RESOLVED = 0; - NRF_AAR->EVENTS_NOTRESOLVED = 0; - } else { - if (g_ble_phy_data.phy_encrypted == 0) { - NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; - } - } -#endif - - /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk); - - /* Reset the rx started flag. Used for the wait for response */ - g_ble_phy_data.phy_rx_started = 0; - g_ble_phy_data.phy_state = BLE_PHY_STATE_RX; - -#if BLE_LL_BT5_PHY_SUPPORTED - /* - * On Coded PHY there are CI and TERM1 fields before PDU starts so we need - * to take this into account when setting up BCC. - */ - if (g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_125KBPS || - g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_500KBPS) { - g_ble_phy_data.phy_bcc_offset = 5; - } else { - g_ble_phy_data.phy_bcc_offset = 0; - } -#else - g_ble_phy_data.phy_bcc_offset = 0; -#endif - - /* I want to know when 1st byte received (after address) */ - nrf_radio_bcc_set(NRF_RADIO, 8 + g_ble_phy_data.phy_bcc_offset); /* in bits */ - NRF_RADIO->EVENTS_ADDRESS = 0; - NRF_RADIO->EVENTS_DEVMATCH = 0; - NRF_RADIO->EVENTS_BCMATCH = 0; - NRF_RADIO->EVENTS_RSSIEND = 0; - NRF_RADIO->EVENTS_CRCOK = 0; - NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | - RADIO_SHORTS_READY_START_Msk | - RADIO_SHORTS_ADDRESS_BCSTART_Msk | - RADIO_SHORTS_ADDRESS_RSSISTART_Msk | - RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - - nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_ADDRESS_Msk | - RADIO_INTENSET_DISABLED_Msk); -} - -/** - * Called from interrupt context when the transmit ends - * - */ -static void -ble_phy_tx_end_isr(void) -{ - uint8_t tx_phy_mode; - uint8_t was_encrypted; - uint8_t transition; - uint32_t rx_time; - - /* Store PHY on which we've just transmitted smth */ - tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; - - /* If this transmission was encrypted we need to remember it */ - was_encrypted = g_ble_phy_data.phy_encrypted; - (void)was_encrypted; - - /* Better be in TX state! */ - assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* - * XXX: not sure what to do. We had a HW error during transmission. - * For now I just count a stat but continue on like all is good. - */ - if (was_encrypted) { - if (NRF_CCM->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, tx_hw_err); - NRF_CCM->EVENTS_ERROR = 0; - } - } -#endif - - /* Call transmit end callback */ - if (g_ble_phy_data.txend_cb) { - g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); - } - - transition = g_ble_phy_data.phy_transition; - if (transition == BLE_PHY_TRANSITION_TX_RX) { - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* Packet pointer needs to be reset. */ - ble_phy_rx_xcvr_setup(); - - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); - - /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ - rx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; - /* Adjust for delay between EVENT_END and actual TX end time */ - rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Adjust for radio ramp-up */ - rx_time -= BLE_PHY_T_RXENFAST; - /* Start listening a bit earlier due to allowed active clock accuracy */ - rx_time -= 2; - - nrf_timer_cc_set(NRF_TIMER0, 0, rx_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - - ble_phy_plna_enable_lna(); - } else { - /* - * XXX: not sure we need to stop the timer here all the time. Or that - * it should be stopped here. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); - NRF_TIMER0->TASKS_SHUTDOWN = 1; - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk); - assert(transition == BLE_PHY_TRANSITION_NONE); - } -} - -static inline uint8_t -ble_phy_get_cur_rx_phy_mode(void) -{ - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - /* - * For Coded PHY mode can be set to either codings since actual coding is - * set in packet header. However, here we need actual coding of received - * packet as this determines pipeline delays so need to figure this out - * using CI field. - */ - if ((phy == BLE_PHY_MODE_CODED_125KBPS) || - (phy == BLE_PHY_MODE_CODED_500KBPS)) { - phy = NRF_RADIO->PDUSTAT & RADIO_PDUSTAT_CISTAT_Msk ? - BLE_PHY_MODE_CODED_500KBPS : - BLE_PHY_MODE_CODED_125KBPS; - } -#endif - - return phy; -} - -static void -ble_phy_rx_end_isr(void) -{ - int rc; - uint8_t *dptr; - uint8_t crcok; - uint32_t tx_time; - struct ble_mbuf_hdr *ble_hdr; - - /* Disable automatic RXEN */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); - - /* Set RSSI and CRC status flag in header */ - ble_hdr = &g_ble_phy_data.rxhdr; - assert(NRF_RADIO->EVENTS_RSSIEND != 0); - ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO->RSSISAMPLE) + - g_ble_phy_data.rx_pwr_compensation; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - - /* Count PHY crc errors and valid packets */ - crcok = NRF_RADIO->EVENTS_CRCOK; - if (!crcok) { - STATS_INC(ble_phy_stats, rx_crc_err); - } else { - STATS_INC(ble_phy_stats, rx_valid); - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - /* Only set MIC failure flag if frame is not zero length */ - if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) { - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE; - } - - /* - * XXX: not sure how to deal with this. This should not - * be a MIC failure but we should not hand it up. I guess - * this is just some form of rx error and that is how we - * handle it? For now, just set CRC error flags - */ - if (NRF_CCM->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } - - /* - * XXX: This is a total hack work-around for now but I dont - * know what else to do. If ENDCRYPT is not set and we are - * encrypted we need to not trust this frame and drop it. - */ - if (NRF_CCM->EVENTS_ENDCRYPT == 0) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } - } -#endif - } - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* - * Let's schedule TX now and we will just cancel it after processing RXed - * packet if we don't need TX. - * - * We need this to initiate connection in case AUX_CONNECT_REQ was sent on - * LE Coded S8. In this case the time we process RXed packet is roughly the - * same as the limit when we need to have TX scheduled (i.e. TIMER0 and PPI - * armed) so we may simply miss the slot and set the timer in the past. - * - * When TX is scheduled in advance, we may event process packet a bit longer - * during radio ramp-up - this gives us extra 40 usecs which is more than - * enough. - */ - - /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; - /* Adjust for delay between actual RX end time and EVENT_END */ - tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; - /* Adjust for radio ramp-up */ - tx_time -= BLE_PHY_T_TXENFAST; - /* Adjust for delay between EVENT_READY and actual TX start time */ - tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - - nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); - - ble_phy_plna_enable_pa(); - - /* - * XXX: Hack warning! - * - * It may happen (during flash erase) that CPU is stopped for a moment and - * TIMER0 already counted past CC[0]. In such case we will be stuck waiting - * for TX to start since EVENTS_COMPARE[0] will not happen any time soon. - * For now let's set a flag denoting that we are late in RX-TX transition so - * ble_phy_tx() will fail - this allows everything to cleanup nicely without - * the need for extra handling in many places. - * - * Note: CC[3] is used only for wfr which we do not need here. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); - g_ble_phy_data.phy_transition_late = 1; - } - - /* - * XXX: This is a horrible ugly hack to deal with the RAM S1 byte - * that is not sent over the air but is present here. Simply move the - * data pointer to deal with it. Fix this later. - */ - dptr[2] = dptr[1]; - dptr[1] = dptr[0]; - rc = ble_ll_rx_end(dptr + 1, ble_hdr); - if (rc < 0) { - ble_phy_disable(); - } -} - -static bool -ble_phy_rx_start_isr(void) -{ - int rc; - uint32_t state; - uint32_t usecs; - uint32_t pdu_usecs; - uint32_t ticks; - struct ble_mbuf_hdr *ble_hdr; - uint8_t *dptr; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int adva_offset; -#endif - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - - /* Clear events and clear interrupt */ - NRF_RADIO->EVENTS_ADDRESS = 0; - nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_ADDRESS_Msk); - - /* Clear wfr timer channels */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); - - /* Initialize the ble mbuf header */ - ble_hdr = &g_ble_phy_data.rxhdr; - ble_hdr->rxinfo.flags = ble_ll_state_get(); - ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan; - ble_hdr->rxinfo.handle = 0; - ble_hdr->rxinfo.phy = ble_phy_get_cur_phy(); - ble_hdr->rxinfo.phy_mode = ble_phy_get_cur_rx_phy_mode(); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_hdr->rxinfo.user_data = NULL; -#endif - - /* - * Calculate accurate packets start time (with remainder) - * - * We may start receiving packet somewhere during preamble in which case - * it is possible that actual transmission started before TIMER0 was - * running - need to take this into account. - */ - ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime; - - usecs = NRF_TIMER0->CC[1]; - pdu_usecs = ble_phy_mode_pdu_start_off(ble_hdr->rxinfo.phy_mode) + - g_ble_phy_t_rxaddrdelay[ble_hdr->rxinfo.phy_mode]; - if (usecs < pdu_usecs) { - g_ble_phy_data.phy_start_cputime--; - usecs += 30; - } - usecs -= pdu_usecs; - - ticks = os_cputime_usecs_to_ticks(usecs); - usecs -= os_cputime_ticks_to_usecs(ticks); - if (usecs == 31) { - usecs = 0; - ++ticks; - } - - ble_hdr->beg_cputime += ticks; - ble_hdr->rem_usecs = usecs; - - /* XXX: I wonder if we always have the 1st byte. If we need to wait for - * rx chain delay, it could be 18 usecs from address interrupt. The - nrf52 may be able to get here early. */ - /* Wait to get 1st byte of frame */ - while (1) { - state = NRF_RADIO->STATE; - if (NRF_RADIO->EVENTS_BCMATCH != 0) { - break; - } - - /* - * If state is disabled, we should have the BCMATCH. If not, - * something is wrong! - */ - if (state == RADIO_STATE_STATE_Disabled) { - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - NRF_RADIO->SHORTS = 0; - return false; - } - -#if BABBLESIM - tm_tick(); -#endif - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* - * If privacy is enabled and received PDU has TxAdd bit set (i.e. random - * address) we try to resolve address using AAR. - */ - if (g_ble_phy_data.phy_privacy && (dptr[3] & 0x40)) { - /* - * AdvA is located at 4th octet in RX buffer (after S0, length an S1 - * fields). In case of extended advertising PDU we need to add 2 more - * octets for extended header. - */ - adva_offset = (dptr[3] & 0x0f) == 0x07 ? 2 : 0; - NRF_AAR->ADDRPTR = (uint32_t)(dptr + 3 + adva_offset); - - /* Trigger AAR after last bit of AdvA is received */ - NRF_RADIO->EVENTS_BCMATCH = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH23_Msk); - nrf_radio_bcc_set(NRF_RADIO, (BLE_LL_PDU_HDR_LEN + adva_offset + - BLE_DEV_ADDR_LEN) * 8 + g_ble_phy_data.phy_bcc_offset); - } -#endif - - /* Call Link Layer receive start function */ - rc = ble_ll_rx_start(dptr + 3, - g_ble_phy_data.phy_chan, - &g_ble_phy_data.rxhdr); - if (rc >= 0) { - /* Set rx started flag and enable rx end ISR */ - g_ble_phy_data.phy_rx_started = 1; - } else { - /* Disable PHY */ - ble_phy_disable(); - STATS_INC(ble_phy_stats, rx_aborts); - } - - /* Count rx starts */ - STATS_INC(ble_phy_stats, rx_starts); - - return true; -} - -static void -ble_phy_isr(void) -{ - uint32_t irq_en; - - os_trace_isr_enter(); - - /* Read irq register to determine which interrupts are enabled */ - irq_en = NRF_RADIO->INTENSET; - - /* - * NOTE: order of checking is important! Possible, if things get delayed, - * we have both an ADDRESS and DISABLED interrupt in rx state. If we get - * an address, we disable the DISABLED interrupt. - */ - - /* We get this if we have started to receive a frame */ - if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) { - /* - * wfr timer is calculated to expire at the exact time we should start - * receiving a packet (with 1 usec precision) so it is possible it will - * fire at the same time as EVENT_ADDRESS. If this happens, radio will - * be disabled while we are waiting for EVENT_BCCMATCH after 1st byte - * of payload is received and ble_phy_rx_start_isr() will fail. In this - * case we should not clear DISABLED irq mask so it will be handled as - * regular radio disabled event below. In other case radio was disabled - * on purpose and there's nothing more to handle so we can clear mask. - */ - if (ble_phy_rx_start_isr()) { - irq_en &= ~RADIO_INTENCLR_DISABLED_Msk; - } - } - - /* Handle disabled event. This is enabled for both TX and RX. On RX, we - * need to check phy_rx_started flag to make sure we actually were receiving - * a PDU, otherwise this is due to wfr. - */ - if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) { - BLE_LL_ASSERT(NRF_RADIO->EVENTS_END || - ((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) && - !g_ble_phy_data.phy_rx_started)); - NRF_RADIO->EVENTS_END = 0; - NRF_RADIO->EVENTS_DISABLED = 0; - nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk); - - switch (g_ble_phy_data.phy_state) { - case BLE_PHY_STATE_RX: -#if MYNEWT_VAL(BLE_LL_LNA) - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; - ble_ll_plna_lna_disable(); -#endif - if (g_ble_phy_data.phy_rx_started) { - ble_phy_rx_end_isr(); - } else { - ble_ll_wfr_timer_exp(NULL); - } - break; - case BLE_PHY_STATE_TX: -#if MYNEWT_VAL(BLE_LL_PA) - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; - ble_ll_plna_pa_disable(); -#endif - ble_phy_tx_end_isr(); - break; - default: - BLE_LL_ASSERT(0); - } - } - - g_ble_phy_data.phy_transition_late = 0; - - /* Count # of interrupts */ - STATS_INC(ble_phy_stats, phy_isrs); - - os_trace_isr_exit(); -} - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ - MYNEWT_VAL(BLE_LL_PA) || \ - MYNEWT_VAL(BLE_LL_LNA) -static int -ble_phy_gpiote_configure(int pin) -{ - NRF_GPIO_Type *port; - - g_ble_phy_gpiote_idx--; - -#if NRF52840_XXAA - port = pin > 31 ? NRF_P1 : NRF_P0; - pin &= 0x1f; -#else - port = NRF_P0; -#endif - - /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */ - port->DIRSET = (1 << pin); - port->OUTCLR = (1 << pin); - - NRF_GPIOTE->CONFIG[g_ble_phy_gpiote_idx] = - (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | -#if NRF52840_XXAA - ((port == NRF_P1) << GPIOTE_CONFIG_PORT_Pos); -#else - 0; -#endif - - BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); - - return g_ble_phy_gpiote_idx; -} -#endif - -static void -ble_phy_dbg_time_setup(void) -{ - int idx __attribute__((unused)); - - /* - * We setup GPIOTE starting from last configuration index to minimize risk - * of conflict with GPIO setup via hal. It's not great solution, but since - * this is just debugging code we can live with this. - */ - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); - - nrf_ppi_channel_endpoint_setup(NRF_PPI, 17, (uint32_t)&(NRF_RADIO->EVENTS_READY), - (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH17_Msk); - - /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 20, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 21, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); - - /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 26, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 27, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); - -#if NRF52840_XXAA - nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_RXREADY), - (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#else - nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_READY), - (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#endif - nrf_ppi_channel_endpoint_setup(NRF_PPI, 19, (uint32_t)&(NRF_RADIO->EVENTS_DISABLED), - (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk); - - /* CH[4] and CH[5] are always on for wfr */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 4, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 5, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); -#endif -} - -/** - * ble phy init - * - * Initialize the PHY. - * - * @return int 0: success; PHY error code otherwise - */ -int -ble_phy_init(void) -{ - int rc; - - g_ble_phy_gpiote_idx = 8; - - /* Default phy to use is 1M */ - g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_rx_phy_mode = BLE_PHY_MODE_1M; - - g_ble_phy_data.rx_pwr_compensation = 0; - - /* Set phy channel to an invalid channel so first set channel works */ - g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; - - /* Toggle peripheral power to reset (just in case) */ - nrf_radio_power_set(NRF_RADIO, false); - nrf_radio_power_set(NRF_RADIO, true); - - /* Disable all interrupts */ - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - - /* Set configuration registers */ - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; - NRF_RADIO->PCNF0 = NRF_PCNF0; - - /* XXX: should maxlen be 251 for encryption? */ - NRF_RADIO->PCNF1 = NRF_MAXLEN | - (RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos) | - (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) | - RADIO_PCNF1_WHITEEN_Msk; - - /* Enable radio fast ramp-up */ - NRF_RADIO->MODECNF0 |= (RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos) & - RADIO_MODECNF0_RU_Msk; - - /* Set logical address 1 for TX and RX */ - NRF_RADIO->TXADDRESS = 0; - NRF_RADIO->RXADDRESSES = (1 << 0); - - /* Configure the CRC registers */ - NRF_RADIO->CRCCNF = (RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos) | RADIO_CRCCNF_LEN_Three; - - /* Configure BLE poly */ - NRF_RADIO->CRCPOLY = 0x0000065B; - - /* Configure IFS */ - NRF_RADIO->TIFS = BLE_LL_IFS; - - /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - nrf_ccm_int_disable(NRF_CCM, 0xffffffff); - NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM->EVENTS_ERROR = 0; - memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad)); -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - g_ble_phy_data.phy_aar_scratch = 0; - NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - nrf_aar_int_disable(NRF_AAR, 0xffffffff); - NRF_AAR->EVENTS_END = 0; - NRF_AAR->EVENTS_RESOLVED = 0; - NRF_AAR->EVENTS_NOTRESOLVED = 0; - NRF_AAR->NIRK = 0; -#endif - - /* TIMER0 setup for PHY when using RTC */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); - NRF_TIMER0->TASKS_SHUTDOWN = 1; - NRF_TIMER0->BITMODE = 3; /* 32-bit timer */ - NRF_TIMER0->MODE = 0; /* Timer mode */ - NRF_TIMER0->PRESCALER = 4; /* gives us 1 MHz */ - - /* - * PPI setup. - * Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used - * to cancel the wait for response timer. - * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait - * for response timer. - */ - nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL4, - (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS), - (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3])); - nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL5, - (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), - (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); - -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) -#if PLNA_SINGLE_GPIO - plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_idx]); -#else -#if MYNEWT_VAL(BLE_LL_PA) - plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE->TASKS_CLR[plna_pa_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_LL_LNA) - plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO)); - NRF_GPIOTE->TASKS_CLR[plna_lna_idx] = 1; -#endif -#endif - - NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); - NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif - - /* Set isr in vector table and enable interrupt */ -#ifndef RIOT_VERSION - NVIC_SetPriority(RADIO_IRQn, 0); -#endif -#if MYNEWT - NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr); -#else - ble_npl_hw_set_isr(RADIO_IRQn, ble_phy_isr); -#endif - NVIC_EnableIRQ(RADIO_IRQn); - - /* Register phy statistics */ - if (!g_ble_phy_data.phy_stats_initialized) { - rc = stats_init_and_reg(STATS_HDR(ble_phy_stats), - STATS_SIZE_INIT_PARMS(ble_phy_stats, - STATS_SIZE_32), - STATS_NAME_INIT_PARMS(ble_phy_stats), - "ble_phy"); - assert(rc == 0); - - g_ble_phy_data.phy_stats_initialized = 1; - } - - ble_phy_dbg_time_setup(); - - return 0; -} - -/** - * Puts the phy into receive mode. - * - * @return int 0: success; BLE Phy error code otherwise - */ -int -ble_phy_rx(void) -{ - /* - * Check radio state. - * - * In case radio is now disabling we'll wait for it to finish, but if for - * any reason it's just in idle state we proceed with RX as usual since - * nRF52 radio can ramp-up from idle state as well. - * - * Note that TX and RX states values are the same except for 3rd bit so we - * can make a shortcut here when checking for idle state. - */ - nrf_wait_disabled(); - if ((NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) && - ((NRF_RADIO->STATE & 0x07) != RADIO_STATE_STATE_RxIdle)) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, radio_state_errs); - return BLE_PHY_ERR_RADIO_STATE; - } - - /* Make sure all interrupts are disabled */ - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - - /* Clear events prior to enabling receive */ - NRF_RADIO->EVENTS_END = 0; - NRF_RADIO->EVENTS_DISABLED = 0; - - /* Setup for rx */ - ble_phy_rx_xcvr_setup(); - - /* PPI to start radio automatically shall be set here */ - assert(NRF_PPI->CHEN & PPI_CHEN_CH21_Msk); - - return 0; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/** - * Called to enable encryption at the PHY. Note that this state will persist - * in the PHY; in other words, if you call this function you have to call - * disable so that future PHY transmits/receives will not be encrypted. - * - * @param pkt_counter - * @param iv - * @param key - * @param is_master - */ -void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master) -{ - memcpy(g_nrf_ccm_data.key, key, 16); - g_nrf_ccm_data.pkt_counter = pkt_counter; - memcpy(g_nrf_ccm_data.iv, iv, 8); - g_nrf_ccm_data.dir_bit = is_master; - g_ble_phy_data.phy_encrypted = 1; - /* Enable the module (AAR cannot be on while CCM on) */ - NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; - NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; -} - -void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) -{ - g_nrf_ccm_data.pkt_counter = pkt_counter; - g_nrf_ccm_data.dir_bit = dir; -} - -void -ble_phy_encrypt_disable(void) -{ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH25_Msk); - nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_STOP); - NRF_CCM->EVENTS_ERROR = 0; - NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; - - g_ble_phy_data.phy_encrypted = 0; -} -#endif - -void -ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg) -{ - /* Set transmit end callback and arg */ - g_ble_phy_data.txend_cb = txend_cb; - g_ble_phy_data.txend_arg = arg; -} - -/** - * Called to set the start time of a transmission. - * - * This function is called to set the start time when we are not going from - * rx to tx automatically. - * - * NOTE: care must be taken when calling this function. The channel should - * already be set. - * - * @param cputime This is the tick at which the 1st bit of the preamble - * should be transmitted - * @param rem_usecs This is used only when the underlying timing uses a 32.768 - * kHz crystal. It is the # of usecs from the cputime tick - * at which the first bit of the preamble should be - * transmitted. - * @return int - */ -int -ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - int rc; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to RXEN since we are transmitting */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); - - if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { - STATS_INC(ble_phy_stats, tx_late); - ble_phy_disable(); - rc = BLE_PHY_ERR_TX_LATE; - } else { - /* Enable PPI to automatically start TXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); - rc = 0; - - ble_phy_plna_enable_pa(); - } - - return rc; -} - -/** - * Called to set the start time of a reception - * - * This function acts a bit differently than transmit. If we are late getting - * here we will still attempt to receive. - * - * NOTE: care must be taken when calling this function. The channel should - * already be set. - * - * @param cputime - * - * @return int - */ -int -ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - bool late = false; - int rc = 0; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to TXEN since we are transmitting */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); - - if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { - STATS_INC(ble_phy_stats, rx_late); - - /* We're late so let's just try to start RX as soon as possible */ - ble_phy_set_start_now(); - - late = true; - } - - /* Enable PPI to automatically start RXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - - ble_phy_plna_enable_lna(); - - /* Start rx */ - rc = ble_phy_rx(); - - /* - * If we enabled receiver but were late, let's return proper error code so - * caller can handle this. - */ - if (!rc && late) { - rc = BLE_PHY_ERR_RX_LATE; - } - - return rc; -} - -int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) -{ - int rc; - uint8_t *dptr; - uint8_t *pktptr; - uint8_t payload_len; - uint8_t hdr_byte; - uint32_t state; - uint32_t shortcuts; - - if (g_ble_phy_data.phy_transition_late) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - return BLE_PHY_ERR_TX_LATE; - } - - /* - * This check is to make sure that the radio is not in a state where - * it is moving to disabled state. If so, let it get there. - */ - nrf_wait_disabled(); - - /* - * XXX: Although we may not have to do this here, I clear all the PPI - * that should not be used when transmitting. Some of them are only enabled - * if encryption and/or privacy is on, but I dont care. Better to be - * paranoid, and if you are going to clear one, might as well clear them - * all. - */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - dptr = (uint8_t *)&g_ble_phy_enc_buf[0]; - pktptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM->INPTR = (uint32_t)dptr; - NRF_CCM->OUTPTR = (uint32_t)pktptr; - NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0]; - NRF_CCM->EVENTS_ERROR = 0; - NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | ble_phy_get_ccm_datarate(); - NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data; - } else { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; -#endif - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; - } -#else - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; -#endif - - /* Set PDU payload */ - payload_len = pducb(&dptr[3], pducb_arg, &hdr_byte); - - /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */ - dptr[0] = hdr_byte; - dptr[1] = payload_len; - dptr[2] = 0; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* Start key-stream generation and encryption (via short) */ - if (g_ble_phy_data.phy_encrypted) { - nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); - } -#endif - - NRF_RADIO->PACKETPTR = (uint32_t)pktptr; - - /* Clear the ready, end and disabled events */ - NRF_RADIO->EVENTS_READY = 0; - NRF_RADIO->EVENTS_END = 0; - NRF_RADIO->EVENTS_DISABLED = 0; - - /* Enable shortcuts for transmit start/end. */ - shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk; - NRF_RADIO->SHORTS = shortcuts; - nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_DISABLED_Msk); - - /* Set the PHY transition */ - g_ble_phy_data.phy_transition = end_trans; - - /* Set transmitted payload length */ - g_ble_phy_data.phy_tx_pyld_len = payload_len; - - /* If we already started transmitting, abort it! */ - state = NRF_RADIO->STATE; - if (state != RADIO_STATE_STATE_Tx) { - /* Set phy state to transmitting and count packet statistics */ - g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; - STATS_INC(ble_phy_stats, tx_good); - STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN); - rc = BLE_ERR_SUCCESS; - } else { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - rc = BLE_PHY_ERR_RADIO_STATE; - } - - return rc; -} - -/** - * ble phy txpwr set - * - * Set the transmit output power (in dBm). - * - * NOTE: If the output power specified is within the BLE limits but outside - * the chip limits, we "rail" the power level so we dont exceed the min/max - * chip values. - * - * @param dbm Power output in dBm. - * - * @return int 0: success; anything else is an error - */ -int -ble_phy_txpwr_set(int dbm) -{ - /* "Rail" power level if outside supported range */ - dbm = ble_phy_txpower_round(dbm); - - NRF_RADIO->TXPOWER = dbm; - g_ble_phy_data.phy_txpwr_dbm = dbm; - - return 0; -} - -/** - * ble phy txpwr round - * - * Get the rounded transmit output power (in dBm). - * - * @param dbm Power output in dBm. - * - * @return int Rounded power in dBm - */ -int ble_phy_txpower_round(int dbm) -{ - /* TODO this should be per nRF52XXX */ - - /* "Rail" power level if outside supported range */ - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; - } - - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; -} - -/** - * ble phy set access addr - * - * Set access address. - * - * @param access_addr Access address - * - * @return int 0: success; PHY error code otherwise - */ -static int -ble_phy_set_access_addr(uint32_t access_addr) -{ - NRF_RADIO->BASE0 = (access_addr << 8); - NRF_RADIO->PREFIX0 = (NRF_RADIO->PREFIX0 & 0xFFFFFF00) | (access_addr >> 24); - - g_ble_phy_data.phy_access_address = access_addr; - -#ifndef BABBLESIM - ble_phy_apply_errata_102_106_107(); -#endif - return 0; -} - -/** - * ble phy txpwr get - * - * Get the transmit power. - * - * @return int The current PHY transmit power, in dBm - */ -int -ble_phy_txpwr_get(void) -{ - return g_ble_phy_data.phy_txpwr_dbm; -} - -void -ble_phy_set_rx_pwr_compensation(int8_t compensation) -{ - g_ble_phy_data.rx_pwr_compensation = compensation; -} - -/** - * ble phy setchan - * - * Sets the logical frequency of the transceiver. The input parameter is the - * BLE channel index (0 to 39, inclusive). The NRF frequency register works like - * this: logical frequency = 2400 + FREQ (MHz). - * - * Thus, to get a logical frequency of 2402 MHz, you would program the - * FREQUENCY register to 2. - * - * @param chan This is the Data Channel Index or Advertising Channel index - * - * @return int 0: success; PHY error code otherwise - */ -int -ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) -{ - assert(chan < BLE_PHY_NUM_CHANS); - - /* Check for valid channel range */ - if (chan >= BLE_PHY_NUM_CHANS) { - return BLE_PHY_ERR_INV_PARAM; - } - - /* Set current access address */ - ble_phy_set_access_addr(access_addr); - - /* Configure crcinit */ - NRF_RADIO->CRCINIT = crcinit; - - /* Set the frequency and the data whitening initial value */ - g_ble_phy_data.phy_chan = chan; - NRF_RADIO->FREQUENCY = g_ble_phy_chan_freq[chan]; - NRF_RADIO->DATAWHITEIV = chan; - - return 0; -} - -/** - * Stop the timer used to count microseconds when using RTC for cputime - */ -static void -ble_phy_stop_usec_timer(void) -{ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); - NRF_TIMER0->TASKS_SHUTDOWN = 1; - nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); -} - -/** - * ble phy disable irq and ppi - * - * This routine is to be called when reception was stopped due to either a - * wait for response timeout or a packet being received and the phy is to be - * restarted in receive mode. Generally, the disable routine is called to stop - * the phy. - */ -static void -ble_phy_disable_irq_and_ppi(void) -{ - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - NRF_RADIO->SHORTS = 0; - nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | - PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk); - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); - NVIC_ClearPendingIRQ(RADIO_IRQn); - g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; -} - -void -ble_phy_restart_rx(void) -{ - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); - - ble_phy_set_start_now(); - /* Enable PPI to automatically start RXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - - ble_phy_rx(); -} - -/** - * ble phy disable - * - * Disables the PHY. This should be called when an event is over. It stops - * the usec timer (if used), disables interrupts, disables the RADIO, disables - * PPI and sets state to idle. - */ -void -ble_phy_disable(void) -{ - ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE); - - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); -} - -/* Gets the current access address */ -uint32_t ble_phy_access_addr_get(void) -{ - return g_ble_phy_data.phy_access_address; -} - -/** - * Return the phy state - * - * @return int The current PHY state. - */ -int -ble_phy_state_get(void) -{ - return g_ble_phy_data.phy_state; -} - -/** - * Called to see if a reception has started - * - * @return int - */ -int -ble_phy_rx_started(void) -{ - return g_ble_phy_data.phy_rx_started; -} - -/** - * Return the transceiver state - * - * @return int transceiver state. - */ -uint8_t -ble_phy_xcvr_state_get(void) -{ - uint32_t state; - state = NRF_RADIO->STATE; - return (uint8_t)state; -} - -/** - * Called to return the maximum data pdu payload length supported by the - * phy. For this chip, if encryption is enabled, the maximum payload is 27 - * bytes. - * - * @return uint8_t Maximum data channel PDU payload size supported - */ -uint8_t -ble_phy_max_data_pdu_pyld(void) -{ - return BLE_LL_DATA_PDU_MAX_PYLD; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -void -ble_phy_resolv_list_enable(void) -{ - NRF_AAR->NIRK = (uint32_t)g_nrf_num_irks; - g_ble_phy_data.phy_privacy = 1; -} - -void -ble_phy_resolv_list_disable(void) -{ - g_ble_phy_data.phy_privacy = 0; -} -#endif - -#if MYNEWT_VAL(BLE_LL_DTM) -void ble_phy_enable_dtm(void) -{ - /* When DTM is enabled we need to disable whitening as per - * Bluetooth v5.0 Vol 6. Part F. 4.1.1 - */ - NRF_RADIO->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk; -} - -void ble_phy_disable_dtm(void) -{ - /* Enable whitening */ - NRF_RADIO->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk; -} -#endif - -void -ble_phy_rfclk_enable(void) -{ -#if MYNEWT - nrf52_clock_hfxo_request(); -#else - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); -#endif -} - -void -ble_phy_rfclk_disable(void) -{ -#if MYNEWT - nrf52_clock_hfxo_release(); -#else - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); -#endif -} diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy_trace.c b/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy_trace.c deleted file mode 100644 index 93b2eb32..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/src/ble_phy_trace.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include "syscfg/syscfg.h" -#include "os/os_trace_api.h" - -#if MYNEWT_VAL(BLE_PHY_SYSVIEW) - -static os_trace_module_t g_ble_phy_trace_mod; -uint32_t ble_phy_trace_off; - -static void -ble_phy_trace_module_send_desc(void) -{ - os_trace_module_desc(&g_ble_phy_trace_mod, "0 phy_set_tx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "1 phy_set_rx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "2 phy_disable"); -} - -void -ble_phy_trace_init(void) -{ - ble_phy_trace_off = - os_trace_module_register(&g_ble_phy_trace_mod, "ble_phy", 3, - ble_phy_trace_module_send_desc); -} -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/syscfg.yml deleted file mode 100644 index 3bd49708..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf52/syscfg.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_PHY_SYSVIEW: - description: > - Enable SystemView tracing module for radio driver. - value: 0 - - BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state when radio is enabled using PPI channels - 20 or 21 and back to low state on radio EVENTS_READY. - This can be used to measure radio ram-up time. - value: -1 - - BLE_PHY_DBG_TIME_ADDRESS_END_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_ADDRESS and back to low state - on radio EVENTS_END. - This can be used to measure radio pipeline delays. - value: -1 - - BLE_PHY_DBG_TIME_WFR_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_RXREADY and back to low - state when wfr timer expires. - This can be used to check if wfr is calculated properly. - value: -1 - - BLE_PHY_NRF52840_ERRATA_164: - description: > - Enable workaround for anomaly 164 found in nRF52840. - "[164] RADIO: Low selectivity in long range mode" - This shall be only enabled for: - - nRF52840 Engineering A - value: 0 - - BLE_PHY_NRF52840_ERRATA_191: - description: > - Enable workaround for anomaly 191 found in nRF52840. - "[191] RADIO: High packet error rate in BLE Long Range mode" - This shall be only enabled for: - - nRF52840 Engineering B - - nRF52840 Engineering C - - nRF52840 Rev 1 (final silicon) - value: 1 - - BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: - description: > - Ublox BMD-345 modules come with public address preprogrammed - in UICR register. If enabled public address will be read from - custom UICR instead of FICR register. - value: 0 diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/include/ble/xcvr.h b/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/include/ble/xcvr.h deleted file mode 100644 index df6ef700..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/include/ble/xcvr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_BLE_XCVR_ -#define H_BLE_XCVR_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define XCVR_RX_RADIO_RAMPUP_USECS (40) -#define XCVR_TX_RADIO_RAMPUP_USECS (40) - -/* - * NOTE: we have to account for the RTC output compare issue. We want it to be - * 5 ticks. - */ -#define XCVR_PROC_DELAY_USECS (153) -#define XCVR_RX_START_DELAY_USECS (XCVR_RX_RADIO_RAMPUP_USECS) -#define XCVR_TX_START_DELAY_USECS (XCVR_TX_RADIO_RAMPUP_USECS) -#define XCVR_TX_SCHED_DELAY_USECS (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) -#define XCVR_RX_SCHED_DELAY_USECS (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) - -/* - * Define HW whitelist size. This is the total possible whitelist size; - * not necessarily the size that will be used (may be smaller) - */ -#define BLE_HW_WHITE_LIST_SIZE (8) - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_XCVR_ */ diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_hw.c b/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_hw.c deleted file mode 100644 index 92bf0249..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_hw.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Total number of resolving list elements */ -#define BLE_HW_RESOLV_LIST_SIZE (16) - -/* We use this to keep track of which entries are set to valid addresses */ -static uint8_t g_ble_hw_whitelist_mask; - -/* Random number generator isr callback */ -static ble_rng_isr_cb_t ble_rng_isr_cb; - -/* If LL privacy is enabled, allocate memory for AAR */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - -/* The NRF5340 supports up to 16 IRK entries */ -#if (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE) < 16) -#define NRF_IRK_LIST_ENTRIES (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)) -#else -#define NRF_IRK_LIST_ENTRIES (16) -#endif - -/* NOTE: each entry is 16 bytes long. */ -uint32_t g_nrf_irk_list[NRF_IRK_LIST_ENTRIES * 4]; - -/* Current number of IRK entries */ -uint8_t g_nrf_num_irks; - -#endif - -/* Returns public device address or -1 if not present */ -int -ble_hw_get_public_addr(ble_addr_t *addr) -{ - uint32_t addr_high; - uint32_t addr_low; - - /* Does FICR have a public address */ - if ((NRF_FICR_NS->DEVICEADDRTYPE & 1) != 0) { - return -1; - } - - /* Copy into device address. We can do this because we know platform */ - addr_low = NRF_FICR_NS->DEVICEADDR[0]; - addr_high = NRF_FICR_NS->DEVICEADDR[1]; - memcpy(addr->val, &addr_low, 4); - memcpy(&addr->val[4], &addr_high, 2); - addr->type = BLE_ADDR_PUBLIC; - - return 0; -} - -/* Returns random static address or -1 if not present */ -int -ble_hw_get_static_addr(ble_addr_t *addr) -{ - int rc; - - if ((NRF_FICR_NS->DEVICEADDRTYPE & 1) == 1) { - memcpy(addr->val, (void *)&NRF_FICR_NS->DEVICEADDR[0], 4); - memcpy(&addr->val[4], (void *)&NRF_FICR_NS->DEVICEADDR[1], 2); - addr->val[5] |= 0xc0; - addr->type = BLE_ADDR_RANDOM; - rc = 0; - } else { - rc = -1; - } - - return rc; -} - -/** - * Clear the whitelist - * - * @return int - */ -void -ble_hw_whitelist_clear(void) -{ - NRF_RADIO_NS->DACNF = 0; - g_ble_hw_whitelist_mask = 0; -} - -/** - * Add a device to the hw whitelist - * - * @param addr - * @param addr_type - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_whitelist_add(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint32_t mask; - - /* Find first ununsed device address match element */ - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if ((mask & g_ble_hw_whitelist_mask) == 0) { - NRF_RADIO_NS->DAB[i] = get_le32(addr); - NRF_RADIO_NS->DAP[i] = get_le16(addr + 4); - if (addr_type == BLE_ADDR_RANDOM) { - NRF_RADIO_NS->DACNF |= (mask << 8); - } - g_ble_hw_whitelist_mask |= mask; - return BLE_ERR_SUCCESS; - } - mask <<= 1; - } - - return BLE_ERR_MEM_CAPACITY; -} - -/** - * Remove a device from the hw whitelist - * - * @param addr - * @param addr_type - * - */ -void -ble_hw_whitelist_rmv(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint16_t dap; - uint16_t txadd; - uint32_t dab; - uint32_t mask; - - /* Find first ununsed device address match element */ - dab = get_le32(addr); - dap = get_le16(addr + 4); - txadd = NRF_RADIO_NS->DACNF >> 8; - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if (mask & g_ble_hw_whitelist_mask) { - if ((dab == NRF_RADIO_NS->DAB[i]) && (dap == NRF_RADIO_NS->DAP[i])) { - if (addr_type == !!(txadd & mask)) { - break; - } - } - } - mask <<= 1; - } - - if (i < BLE_HW_WHITE_LIST_SIZE) { - g_ble_hw_whitelist_mask &= ~mask; - NRF_RADIO_NS->DACNF &= ~mask; - } -} - -/** - * Returns the size of the whitelist in HW - * - * @return int Number of devices allowed in whitelist - */ -uint8_t -ble_hw_whitelist_size(void) -{ - return BLE_HW_WHITE_LIST_SIZE; -} - -/** - * Enable the whitelisted devices - */ -void -ble_hw_whitelist_enable(void) -{ - /* Enable the configured device addresses */ - NRF_RADIO_NS->DACNF |= g_ble_hw_whitelist_mask; -} - -/** - * Disables the whitelisted devices - */ -void -ble_hw_whitelist_disable(void) -{ - /* Disable all whitelist devices */ - NRF_RADIO_NS->DACNF &= 0x0000ff00; -} - -/** - * Boolean function which returns true ('1') if there is a match on the - * whitelist. - * - * @return int - */ -int -ble_hw_whitelist_match(void) -{ - return NRF_RADIO_NS->EVENTS_DEVMATCH; -} - -/* Encrypt data */ -int -ble_hw_encrypt_block(struct ble_encryption_block *ecb) -{ - int rc; - uint32_t end; - uint32_t err; - - /* Stop ECB */ - NRF_ECB_NS->TASKS_STOPECB = 1; - /* XXX: does task stop clear these counters? Anyway to do this quicker? */ - NRF_ECB_NS->EVENTS_ENDECB = 0; - NRF_ECB_NS->EVENTS_ERRORECB = 0; - NRF_ECB_NS->ECBDATAPTR = (uint32_t)ecb; - - /* Start ECB */ - NRF_ECB_NS->TASKS_STARTECB = 1; - - /* Wait till error or done */ - rc = 0; - while (1) { - end = NRF_ECB_NS->EVENTS_ENDECB; - err = NRF_ECB_NS->EVENTS_ERRORECB; - if (end || err) { - if (err) { - rc = -1; - } - break; - } - } - - return rc; -} - -/** - * Random number generator ISR. - */ -static void -ble_rng_isr(void) -{ - uint8_t rnum; - - os_trace_isr_enter(); - - /* No callback? Clear and disable interrupts */ - if (ble_rng_isr_cb == NULL) { - NRF_RNG_NS->INTENCLR = 1; - NRF_RNG_NS->EVENTS_VALRDY = 0; - (void)NRF_RNG_NS->SHORTS; - os_trace_isr_exit(); - return; - } - - /* If there is a value ready grab it */ - if (NRF_RNG_NS->EVENTS_VALRDY) { - NRF_RNG_NS->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG_NS->VALUE; - (*ble_rng_isr_cb)(rnum); - } - - os_trace_isr_exit(); -} - -/** - * Initialize the random number generator - * - * @param cb - * @param bias - * - * @return int - */ -int -ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias) -{ - /* Set bias */ - if (bias) { - NRF_RNG_NS->CONFIG = 1; - } else { - NRF_RNG_NS->CONFIG = 0; - } - - /* If we were passed a function pointer we need to enable the interrupt */ - if (cb != NULL) { -#ifndef RIOT_VERSION - NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1); -#endif -#if MYNEWT - NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr); -#else - ble_npl_hw_set_isr(RNG_IRQn, ble_rng_isr); -#endif - NVIC_EnableIRQ(RNG_IRQn); - ble_rng_isr_cb = cb; - } - - return 0; -} - -/** - * Start the random number generator - * - * @return int - */ -int -ble_hw_rng_start(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - NRF_RNG_NS->EVENTS_VALRDY = 0; - if (ble_rng_isr_cb) { - NRF_RNG_NS->INTENSET = 1; - } - NRF_RNG_NS->TASKS_START = 1; - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Stop the random generator - * - * @return int - */ -int -ble_hw_rng_stop(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - NRF_RNG_NS->INTENCLR = 1; - NRF_RNG_NS->TASKS_STOP = 1; - NRF_RNG_NS->EVENTS_VALRDY = 0; - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Read the random number generator. - * - * @return uint8_t - */ -uint8_t -ble_hw_rng_read(void) -{ - uint8_t rnum; - - /* Wait for a sample */ - while (NRF_RNG_NS->EVENTS_VALRDY == 0) { - } - - NRF_RNG_NS->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG_NS->VALUE; - - return rnum; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -/** - * Clear the resolving list - * - * @return int - */ -void -ble_hw_resolv_list_clear(void) -{ - g_nrf_num_irks = 0; -} - -/** - * Add a device to the hw resolving list - * - * @param irk Pointer to IRK to add - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_resolv_list_add(uint8_t *irk) -{ - uint32_t *nrf_entry; - - /* Find first ununsed device address match element */ - if (g_nrf_num_irks == NRF_IRK_LIST_ENTRIES) { - return BLE_ERR_MEM_CAPACITY; - } - - /* Copy into irk list */ - nrf_entry = &g_nrf_irk_list[4 * g_nrf_num_irks]; - memcpy(nrf_entry, irk, 16); - - /* Add to total */ - ++g_nrf_num_irks; - return BLE_ERR_SUCCESS; -} - -/** - * Remove a device from the hw resolving list - * - * @param index Index of IRK to remove - */ -void -ble_hw_resolv_list_rmv(int index) -{ - uint32_t *irk_entry; - - if (index < g_nrf_num_irks) { - --g_nrf_num_irks; - irk_entry = &g_nrf_irk_list[index]; - if (g_nrf_num_irks > index) { - memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index)); - } - } -} - -/** - * Returns the size of the resolving list. NOTE: this returns the maximum - * allowable entries in the HW. Configuration options may limit this. - * - * @return int Number of devices allowed in resolving list - */ -uint8_t -ble_hw_resolv_list_size(void) -{ - return BLE_HW_RESOLV_LIST_SIZE; -} - -/** - * Called to determine if the address received was resolved. - * - * @return int Negative values indicate unresolved address; positive values - * indicate index in resolving list of resolved address. - */ -int -ble_hw_resolv_list_match(void) -{ - if (NRF_AAR_NS->ENABLE && NRF_AAR_NS->EVENTS_END && - NRF_AAR_NS->EVENTS_RESOLVED) { - return (int)NRF_AAR_NS->STATUS; - } - - return -1; -} -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy.c b/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy.c deleted file mode 100644 index 9734e887..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy.c +++ /dev/null @@ -1,2038 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "controller/ble_ll_plna.h" - -#include -#include -#include -#include -#include - -#define DPPI_CH_PUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) -#define DPPI_CH_SUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) -#define DPPI_CH_UNSUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (0 << 31)) -#define DPPI_CH_MASK(_ch) (1 << (DPPI_CH_ ## _ch)) - -/* Channels 0..5 are always used. - * Channels 6 and 7 are used for PA/LNA (optionally). - * Channels 6..8 are used for GPIO debugging (optionally). - */ - -#define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0 -#define DPPI_CH_TIMER0_EVENTS_COMPARE_3 1 -#define DPPI_CH_RADIO_EVENTS_END 2 -#define DPPI_CH_RADIO_EVENTS_BCMATCH 3 -#define DPPI_CH_RADIO_EVENTS_ADDRESS 4 -#define DPPI_CH_RTC0_EVENTS_COMPARE_0 5 -#define DPPI_CH_RADIO_EVENTS_READY 6 -#define DPPI_CH_RADIO_EVENTS_DISABLED 7 -#define DPPI_CH_RADIO_EVENTS_RXREADY 8 - -#define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \ - DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) - -#define DPPI_CH_MASK_PLNA (DPPI_CH_MASK(RADIO_EVENTS_READY) | \ - DPPI_CH_MASK(RADIO_EVENTS_DISABLED)) - -extern uint8_t g_nrf_num_irks; -extern uint32_t g_nrf_irk_list[]; - -/* To disable all radio interrupts */ -#define NRF_RADIO_IRQ_MASK_ALL (0x34FF) - -/* - * We configure the nrf with a 1 byte S0 field, 8 bit length field, and - * zero bit S1 field. The preamble is 8 bits long. - */ -#define NRF_LFLEN_BITS (8) -#define NRF_S0LEN (1) -#define NRF_S1LEN_BITS (0) -#define NRF_CILEN_BITS (2) -#define NRF_TERMLEN_BITS (3) - -/* Maximum length of frames */ -#define NRF_MAXLEN (255) -#define NRF_BALEN (3) /* For base address of 3 bytes */ - -/* NRF_RADIO_NS->PCNF0 configuration values */ -#define NRF_PCNF0 (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) | \ - (RADIO_PCNF0_S1INCL_Msk) | \ - (NRF_S0LEN << RADIO_PCNF0_S0LEN_Pos) | \ - (NRF_S1LEN_BITS << RADIO_PCNF0_S1LEN_Pos) -#define NRF_PCNF0_1M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_2M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_CODED (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | \ - (NRF_CILEN_BITS << RADIO_PCNF0_CILEN_Pos) | \ - (NRF_TERMLEN_BITS << RADIO_PCNF0_TERMLEN_Pos) - -/* BLE PHY data structure */ -struct ble_phy_obj { - uint8_t phy_stats_initialized; - int8_t phy_txpwr_dbm; - uint8_t phy_chan; - uint8_t phy_state; - uint8_t phy_transition; - uint8_t phy_transition_late; - uint8_t phy_rx_started; - uint8_t phy_encrypted; - uint8_t phy_privacy; - uint8_t phy_tx_pyld_len; - uint8_t phy_cur_phy_mode; - uint8_t phy_tx_phy_mode; - uint8_t phy_rx_phy_mode; - uint8_t phy_bcc_offset; - int8_t rx_pwr_compensation; - uint32_t phy_aar_scratch; - uint32_t phy_access_address; - struct ble_mbuf_hdr rxhdr; - void *txend_arg; - ble_phy_tx_end_func txend_cb; - uint32_t phy_start_cputime; -}; -struct ble_phy_obj g_ble_phy_data; - -/* XXX: if 27 byte packets desired we can make this smaller */ -/* Global transmit/receive buffer */ -static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/* Make sure word-aligned for faster copies */ -static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -#endif - -/* RF center frequency for each channel index (offset from 2400 MHz) */ -static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = { - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, /* 0-9 */ - 24, 28, 30, 32, 34, 36, 38, 40, 42, 44, /* 10-19 */ - 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, /* 20-29 */ - 66, 68, 70, 72, 74, 76, 78, 2, 26, 80, /* 30-39 */ -}; - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) -/* packet start offsets (in usecs) */ -static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 40, - [BLE_PHY_MODE_2M] = 24, - [BLE_PHY_MODE_CODED_125KBPS] = 376, - [BLE_PHY_MODE_CODED_500KBPS] = 376 -}; -#endif - -/* Various radio timings */ -/* Radio ramp-up times in usecs (fast mode) */ -#define BLE_PHY_T_TXENFAST (XCVR_TX_RADIO_RAMPUP_USECS) -#define BLE_PHY_T_RXENFAST (XCVR_RX_RADIO_RAMPUP_USECS) - -/* delay between EVENTS_READY and start of tx */ -static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 5, - [BLE_PHY_MODE_CODED_500KBPS] = 5 -}; -/* delay between EVENTS_END and end of txd packet */ -static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 9, - [BLE_PHY_MODE_CODED_500KBPS] = 3 -}; -/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ -static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 17, - [BLE_PHY_MODE_CODED_500KBPS] = 17 -}; -/* delay between end of rxd packet and EVENTS_END */ -static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 27, - [BLE_PHY_MODE_CODED_500KBPS] = 22 -}; - -/* Statistics */ -STATS_SECT_START(ble_phy_stats) -STATS_SECT_ENTRY(phy_isrs) -STATS_SECT_ENTRY(tx_good) -STATS_SECT_ENTRY(tx_fail) -STATS_SECT_ENTRY(tx_late) -STATS_SECT_ENTRY(tx_bytes) -STATS_SECT_ENTRY(rx_starts) -STATS_SECT_ENTRY(rx_aborts) -STATS_SECT_ENTRY(rx_valid) -STATS_SECT_ENTRY(rx_crc_err) -STATS_SECT_ENTRY(rx_late) -STATS_SECT_ENTRY(radio_state_errs) -STATS_SECT_ENTRY(rx_hw_err) -STATS_SECT_ENTRY(tx_hw_err) -STATS_SECT_END -STATS_SECT_DECL(ble_phy_stats) ble_phy_stats; - -STATS_NAME_START(ble_phy_stats) -STATS_NAME(ble_phy_stats, phy_isrs) -STATS_NAME(ble_phy_stats, tx_good) -STATS_NAME(ble_phy_stats, tx_fail) -STATS_NAME(ble_phy_stats, tx_late) -STATS_NAME(ble_phy_stats, tx_bytes) -STATS_NAME(ble_phy_stats, rx_starts) -STATS_NAME(ble_phy_stats, rx_aborts) -STATS_NAME(ble_phy_stats, rx_valid) -STATS_NAME(ble_phy_stats, rx_crc_err) -STATS_NAME(ble_phy_stats, rx_late) -STATS_NAME(ble_phy_stats, radio_state_errs) -STATS_NAME(ble_phy_stats, rx_hw_err) -STATS_NAME(ble_phy_stats, tx_hw_err) -STATS_NAME_END(ble_phy_stats) - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/* - * Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE. - * However, when I used a smaller size it still overwrote the scratchpad. Until - * I figure this out I am just going to allocate 67 words so we have enough - * space for 267 bytes of scratch. I used 268 bytes since not sure if this - * needs to be aligned and burning a byte is no big deal. - * - *#define NRF_ENC_SCRATCH_WORDS (((MYNEWT_VAL(BLE_LL_MAX_PKT_SIZE) + 16) + 3) / 4) - */ -#define NRF_ENC_SCRATCH_WORDS (67) - -static uint32_t nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS]; - -struct nrf_ccm_data { - uint8_t key[16]; - uint64_t pkt_counter; - uint8_t dir_bit; - uint8_t iv[8]; -} __attribute__((packed)); - -static struct nrf_ccm_data nrf_ccm_data; -#endif - -static int g_ble_phy_gpiote_idx; - -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) - -#define PLNA_SINGLE_GPIO \ - (!MYNEWT_VAL(BLE_LL_PA) || !MYNEWT_VAL(BLE_LL_LNA) || \ - (MYNEWT_VAL(BLE_LL_PA_GPIO) == MYNEWT_VAL(BLE_LL_LNA_GPIO))) - -#if PLNA_SINGLE_GPIO -static uint8_t plna_idx; -#else -#if MYNEWT_VAL(BLE_LL_PA) -static uint8_t plna_pa_idx; -#endif -#if MYNEWT_VAL(BLE_LL_LNA) -static uint8_t plna_lna_idx; -#endif -#endif - -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 -static uint8_t phy_dbg_txrxen_ready_idx; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 -static uint8_t phy_dbg_address_end_idx; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 -static uint8_t phy_dbg_wfr_idx; -#endif - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - -uint32_t -ble_phy_mode_pdu_start_off(int phy_mode) -{ - return g_ble_phy_mode_pkt_start_off[phy_mode]; -} - -static void -ble_phy_mode_apply(uint8_t phy_mode) -{ - if (phy_mode == g_ble_phy_data.phy_cur_phy_mode) { - return; - } - - switch (phy_mode) { - case BLE_PHY_MODE_1M: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_1Mbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_1M; - break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - case BLE_PHY_MODE_2M: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_2Mbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0084); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_2M; - break; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_CODED; - break; - case BLE_PHY_MODE_CODED_500KBPS: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_CODED; - break; -#endif - default: - assert(0); - } - - g_ble_phy_data.phy_cur_phy_mode = phy_mode; -} -#endif - -void -ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) -{ - g_ble_phy_data.phy_tx_phy_mode = tx_phy_mode; - g_ble_phy_data.phy_rx_phy_mode = rx_phy_mode; -} - -static void -ble_phy_plna_enable_pa(void) -{ -#if MYNEWT_VAL(BLE_LL_PA) - ble_ll_plna_pa_enable(); - -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); -#endif -#endif -} - -static void -ble_phy_plna_disable_pa(void) -{ -#if MYNEWT_VAL(BLE_LL_PA) - ble_ll_plna_pa_disable(); - -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#endif -#endif -} - -static void -ble_phy_plna_enable_lna(void) -{ -#if MYNEWT_VAL(BLE_LL_LNA) - ble_ll_plna_lna_enable(); - -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); -#endif -#endif -} - -static void -ble_phy_plna_disable_lna(void) -{ -#if MYNEWT_VAL(BLE_LL_LNA) - ble_ll_plna_lna_disable(); - -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#endif -#endif -} - -int -ble_phy_get_cur_phy(void) -{ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return BLE_PHY_1M; - case BLE_PHY_MODE_2M: - return BLE_PHY_2M; - case BLE_PHY_MODE_CODED_125KBPS: - case BLE_PHY_MODE_CODED_500KBPS: - return BLE_PHY_CODED; - default: - assert(0); - return -1; - } -#else - return BLE_PHY_1M; -#endif -} - -void -ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) -{ - uint32_t rem_len; - uint32_t copy_len; - uint32_t block_len; - uint32_t block_rem_len; - void *dst; - void *src; - struct os_mbuf * om; - - /* Better be aligned */ - assert(((uint32_t)dptr & 3) == 0); - - block_len = rxpdu->om_omp->omp_databuf_len; - rem_len = OS_MBUF_PKTHDR(rxpdu)->omp_len; - src = dptr; - - /* - * Setup for copying from first mbuf which is shorter due to packet header - * and extra leading space - */ - copy_len = block_len - rxpdu->om_pkthdr_len - 4; - om = rxpdu; - dst = om->om_data; - - while (true) { - /* - * Always copy blocks of length aligned to word size, only last mbuf - * will have remaining non-word size bytes appended. - */ - block_rem_len = copy_len; - copy_len = min(copy_len, rem_len); - copy_len &= ~3; - - dst = om->om_data; - om->om_len = copy_len; - rem_len -= copy_len; - block_rem_len -= copy_len; - - __asm__ volatile (".syntax unified \n" - " mov r4, %[len] \n" - " b 2f \n" - "1: ldr r3, [%[src], %[len]] \n" - " str r3, [%[dst], %[len]] \n" - "2: subs %[len], #4 \n" - " bpl 1b \n" - " adds %[src], %[src], r4 \n" - " adds %[dst], %[dst], r4 \n" - : [dst] "+r" (dst), [src] "+r" (src), - [len] "+r" (copy_len) - : - : "r3", "r4", "memory" - ); - - if ((rem_len < 4) && (block_rem_len >= rem_len)) { - break; - } - - /* Move to next mbuf */ - om = SLIST_NEXT(om, om_next); - copy_len = block_len; - } - - /* Copy remaining bytes, if any, to last mbuf */ - om->om_len += rem_len; - __asm__ volatile (".syntax unified \n" - " b 2f \n" - "1: ldrb r3, [%[src], %[len]] \n" - " strb r3, [%[dst], %[len]] \n" - "2: subs %[len], #1 \n" - " bpl 1b \n" - : [len] "+r" (rem_len) - : [dst] "r" (dst), [src] "r" (src) - : "r3", "memory" - ); - - /* Copy header */ - memcpy(BLE_MBUF_HDR_PTR(rxpdu), &g_ble_phy_data.rxhdr, - sizeof(struct ble_mbuf_hdr)); -} - -/** - * Called when we want to wait if the radio is in either the rx or tx - * disable states. We want to wait until that state is over before doing - * anything to the radio - */ -static void -nrf_wait_disabled(void) -{ - uint32_t state; - - state = NRF_RADIO_NS->STATE; - if (state != RADIO_STATE_STATE_Disabled) { - if ((state == RADIO_STATE_STATE_RxDisable) || - (state == RADIO_STATE_STATE_TxDisable)) { - /* This will end within a short time (6 usecs). Just poll */ - while (NRF_RADIO_NS->STATE == state) { - /* If this fails, something is really wrong. Should last - * no more than 6 usecs - */ - } - } - } -} - -static int -ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) -{ - uint32_t next_cc; - uint32_t cur_cc; - uint32_t cntr; - uint32_t delta; - - /* - * We need to adjust start time to include radio ramp-up and TX pipeline - * delay (the latter only if applicable, so only for TX). - * - * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on - * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate - * using TIMER0 with 1 usec precision. - */ - - cputime -= 2; - rem_usecs += 61; - if (tx) { - rem_usecs -= BLE_PHY_T_TXENFAST; - rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - } else { - rem_usecs -= BLE_PHY_T_RXENFAST; - } - - /* - * rem_usecs will be no more than 2 ticks, but if it is more than single - * tick then we should better count one more low-power tick rather than - * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the - * compare won't occur. - */ - - if (rem_usecs > 30) { - cputime++; - rem_usecs -= 30; - } - - /* - * Can we set the RTC compare to start TIMER0? We can do it if: - * a) Current compare value is not N+1 or N+2 ticks from current - * counter. - * b) The value we want to set is not at least N+2 from current - * counter. - * - * NOTE: since the counter can tick 1 while we do these calculations we - * need to account for it. - */ - next_cc = cputime & 0xffffff; - cur_cc = NRF_RTC0_NS->CC[0]; - cntr = NRF_RTC0_NS->COUNTER; - - delta = (cur_cc - cntr) & 0xffffff; - if ((delta <= 3) && (delta != 0)) { - return -1; - } - delta = (next_cc - cntr) & 0xffffff; - if ((delta & 0x800000) || (delta < 3)) { - return -1; - } - - /* Clear and set TIMER0 to fire off at proper time */ - NRF_TIMER0_NS->TASKS_CLEAR = 1; - NRF_TIMER0_NS->CC[0] = rem_usecs; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* Set RTC compare to start TIMER0 */ - NRF_RTC0_NS->EVENTS_COMPARE[0] = 0; - NRF_RTC0_NS->CC[0] = next_cc; - NRF_RTC0_NS->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; - - /* Enable PPI */ - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_SUB(RTC0_EVENTS_COMPARE_0); - - /* Store the cputime at which we set the RTC */ - g_ble_phy_data.phy_start_cputime = cputime; - - return 0; -} - -static int -ble_phy_set_start_now(void) -{ - os_sr_t sr; - uint32_t now; - - OS_ENTER_CRITICAL(sr); - - /* - * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not - * occur in such case. - */ - NRF_TIMER0_NS->TASKS_CLEAR = 1; - NRF_TIMER0_NS->CC[0] = 1; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* - * Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks - * from current value to guarantee triggering compare event, but let's set - * it to N+3 to account for possible extra tick on RTC0 during these - * operations. - */ - now = os_cputime_get32(); - NRF_RTC0_NS->EVENTS_COMPARE[0] = 0; - NRF_RTC0_NS->CC[0] = now + 3; - NRF_RTC0_NS->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; - - /* Enable PPI */ - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_SUB(RTC0_EVENTS_COMPARE_0); - - /* - * Store the cputime at which we set the RTC - * - * XXX Compare event may be triggered on previous CC value (if it was set to - * less than N+2) so in rare cases actual start time may be 2 ticks earlier - * than what we expect. Since this is only used on RX, it may cause AUX scan - * to be scheduled 1 or 2 ticks too late so we'll miss it - it's acceptable - * for now. - */ - g_ble_phy_data.phy_start_cputime = now + 3; - - OS_EXIT_CRITICAL(sr); - - return 0; -} - -void -ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) -{ - uint32_t end_time; - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - - if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { - /* RX shall start exactly T_IFS after TX end captured in CC[2] */ - end_time = NRF_TIMER0_NS->CC[2] + BLE_LL_IFS; - /* Adjust for delay between EVENT_END and actual TX end time */ - end_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Wait a bit longer due to allowed active clock accuracy */ - end_time += 2; - /* - * It's possible that we'll capture PDU start time at the end of timer - * cycle and since wfr expires at the beginning of calculated timer - * cycle it can be almost 1 usec too early. Let's compensate for this - * by waiting 1 usec more. - */ - end_time += 1; - } else { - /* - * RX shall start no later than wfr_usecs after RX enabled. - * CC[0] is the time of RXEN so adjust for radio ram-up. - * Do not add jitter since this is already covered by LL. - */ - end_time = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST + wfr_usecs; - } - - /* - * Note: on LE Coded EVENT_ADDRESS is fired after TERM1 is received, so - * we are actually calculating relative to start of packet payload - * which is fine. - */ - - /* Adjust for receiving access address since this triggers EVENT_ADDRESS */ - end_time += ble_phy_mode_pdu_start_off(phy); - /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ - end_time += g_ble_phy_t_rxaddrdelay[phy]; - - /* wfr_secs is the time from rxen until timeout */ - NRF_TIMER0_NS->CC[3] = end_time; - NRF_TIMER0_NS->EVENTS_COMPARE[3] = 0; - - /* Subscribe for wait for response events */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); - - /* - * It may happen that if CPU is halted for a brief moment (e.g. during flash - * erase or write), TIMER0 already counted past CC[3] and thus wfr will not - * fire as expected. In case this happened, let's just disable PPIs for wfr - * and trigger wfr manually (i.e. disable radio). - * - * Note that the same applies to RX start time set in CC[0] but since it - * should fire earlier than wfr, fixing wfr is enough. - * - * CC[1] is only used as a reference on RX start, we do not need it here so - * it can be used to read TIMER0 counter. - */ - NRF_TIMER0_NS->TASKS_CAPTURE[1] = 1; - if (NRF_TIMER0_NS->CC[1] > NRF_TIMER0_NS->CC[3]) { - /* Unsubscribe from wfr events */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - - NRF_RADIO_NS->TASKS_DISABLE = 1; - } -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -static uint32_t -ble_phy_get_ccm_datarate(void) -{ -#if BLE_LL_BT5_PHY_SUPPORTED - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_2M: - return CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - return CCM_MODE_DATARATE_125Kbps << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_CODED_500KBPS: - return CCM_MODE_DATARATE_500Kbps << CCM_MODE_DATARATE_Pos; -#endif - } - - assert(0); - return 0; -#else - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; -#endif -} -#endif - -/** - * Setup transceiver for receive. - */ -static void -ble_phy_rx_xcvr_setup(void) -{ - uint8_t *dptr; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - NRF_RADIO_NS->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM_NS->INPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM_NS->OUTPTR = (uint32_t)dptr; - NRF_CCM_NS->SCRATCHPTR = (uint32_t)&nrf_encrypt_scratchpad[0]; - NRF_CCM_NS->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption | - ble_phy_get_ccm_datarate(); - NRF_CCM_NS->CNFPTR = (uint32_t)&nrf_ccm_data; - NRF_CCM_NS->SHORTS = 0; - NRF_CCM_NS->EVENTS_ERROR = 0; - NRF_CCM_NS->EVENTS_ENDCRYPT = 0; - NRF_CCM_NS->TASKS_KSGEN = 1; - - /* Subscribe to radio address event */ - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - } else { - NRF_RADIO_NS->PACKETPTR = (uint32_t)dptr; - } -#else - NRF_RADIO_NS->PACKETPTR = (uint32_t)dptr; -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (g_ble_phy_data.phy_privacy) { - NRF_AAR_NS->ENABLE = AAR_ENABLE_ENABLE_Enabled; - NRF_AAR_NS->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - NRF_AAR_NS->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch; - NRF_AAR_NS->EVENTS_END = 0; - NRF_AAR_NS->EVENTS_RESOLVED = 0; - NRF_AAR_NS->EVENTS_NOTRESOLVED = 0; - } else { - if (g_ble_phy_data.phy_encrypted == 0) { - NRF_AAR_NS->ENABLE = AAR_ENABLE_ENABLE_Disabled; - } - } -#endif - - /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); - - /* Reset the rx started flag. Used for the wait for response */ - g_ble_phy_data.phy_rx_started = 0; - g_ble_phy_data.phy_state = BLE_PHY_STATE_RX; - -#if BLE_LL_BT5_PHY_SUPPORTED - /* - * On Coded PHY there are CI and TERM1 fields before PDU starts so we need - * to take this into account when setting up BCC. - */ - if (g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_125KBPS || - g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_500KBPS) { - g_ble_phy_data.phy_bcc_offset = 5; - } else { - g_ble_phy_data.phy_bcc_offset = 0; - } -#else - g_ble_phy_data.phy_bcc_offset = 0; -#endif - - /* I want to know when 1st byte received (after address) */ - NRF_RADIO_NS->BCC = 8 + g_ble_phy_data.phy_bcc_offset; /* in bits */ - NRF_RADIO_NS->EVENTS_ADDRESS = 0; - NRF_RADIO_NS->EVENTS_DEVMATCH = 0; - NRF_RADIO_NS->EVENTS_BCMATCH = 0; - NRF_RADIO_NS->EVENTS_RSSIEND = 0; - NRF_RADIO_NS->EVENTS_CRCOK = 0; - NRF_RADIO_NS->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | - RADIO_SHORTS_READY_START_Msk | - RADIO_SHORTS_ADDRESS_BCSTART_Msk | - RADIO_SHORTS_ADDRESS_RSSISTART_Msk | - RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - - NRF_RADIO_NS->INTENSET = RADIO_INTENSET_ADDRESS_Msk | - RADIO_INTENSET_DISABLED_Msk; -} - -/** - * Called from interrupt context when the transmit ends - * - */ -static void -ble_phy_tx_end_isr(void) -{ - uint8_t tx_phy_mode; - uint8_t was_encrypted; - uint8_t transition; - uint32_t rx_time; - - /* Store PHY on which we've just transmitted smth */ - tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; - - /* If this transmission was encrypted we need to remember it */ - was_encrypted = g_ble_phy_data.phy_encrypted; - (void)was_encrypted; - - /* Better be in TX state! */ - assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* - * XXX: not sure what to do. We had a HW error during transmission. - * For now I just count a stat but continue on like all is good. - */ - if (was_encrypted) { - if (NRF_CCM_NS->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, tx_hw_err); - NRF_CCM_NS->EVENTS_ERROR = 0; - } - } -#endif - - /* Call transmit end callback */ - if (g_ble_phy_data.txend_cb) { - g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); - } - - transition = g_ble_phy_data.phy_transition; - if (transition == BLE_PHY_TRANSITION_TX_RX) { - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* Packet pointer needs to be reset. */ - ble_phy_rx_xcvr_setup(); - - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); - - /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ - rx_time = NRF_TIMER0_NS->CC[2] + BLE_LL_IFS; - /* Adjust for delay between EVENT_END and actual TX end time */ - rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Adjust for radio ramp-up */ - rx_time -= BLE_PHY_T_RXENFAST; - /* Start listening a bit earlier due to allowed active clock accuracy */ - rx_time -= 2; - - NRF_TIMER0_NS->CC[0] = rx_time; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* Start radio on timer */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_plna_enable_lna(); - } else { - NRF_TIMER0_NS->TASKS_STOP = 1; - NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; - - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); - - assert(transition == BLE_PHY_TRANSITION_NONE); - } -} - -static inline uint8_t -ble_phy_get_cur_rx_phy_mode(void) -{ - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - /* - * For Coded PHY mode can be set to either codings since actual coding is - * set in packet header. However, here we need actual coding of received - * packet as this determines pipeline delays so need to figure this out - * using CI field. - */ - if ((phy == BLE_PHY_MODE_CODED_125KBPS) || - (phy == BLE_PHY_MODE_CODED_500KBPS)) { - phy = NRF_RADIO_NS->PDUSTAT & RADIO_PDUSTAT_CISTAT_Msk ? - BLE_PHY_MODE_CODED_500KBPS : BLE_PHY_MODE_CODED_125KBPS; - } -#endif - - return phy; -} - -static void -ble_phy_rx_end_isr(void) -{ - int rc; - uint8_t *dptr; - uint8_t crcok; - uint32_t tx_time; - struct ble_mbuf_hdr *ble_hdr; - - /* Disable automatic RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - /* Set RSSI and CRC status flag in header */ - ble_hdr = &g_ble_phy_data.rxhdr; - assert(NRF_RADIO_NS->EVENTS_RSSIEND != 0); - ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO_NS->RSSISAMPLE) + - g_ble_phy_data.rx_pwr_compensation; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - - /* Count PHY crc errors and valid packets */ - crcok = NRF_RADIO_NS->EVENTS_CRCOK; - if (!crcok) { - STATS_INC(ble_phy_stats, rx_crc_err); - } else { - STATS_INC(ble_phy_stats, rx_valid); - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - /* Only set MIC failure flag if frame is not zero length */ - if ((dptr[1] != 0) && (NRF_CCM_NS->MICSTATUS == 0)) { - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE; - } - - /* - * XXX: not sure how to deal with this. This should not - * be a MIC failure but we should not hand it up. I guess - * this is just some form of rx error and that is how we - * handle it? For now, just set CRC error flags - */ - if (NRF_CCM_NS->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } - - /* - * XXX: This is a total hack work-around for now but I dont - * know what else to do. If ENDCRYPT is not set and we are - * encrypted we need to not trust this frame and drop it. - */ - if (NRF_CCM_NS->EVENTS_ENDCRYPT == 0) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } - } -#endif - } - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* - * Let's schedule TX now and we will just cancel it after processing RXed - * packet if we don't need TX. - * - * We need this to initiate connection in case AUX_CONNECT_REQ was sent on - * LE Coded S8. In this case the time we process RXed packet is roughly the - * same as the limit when we need to have TX scheduled (i.e. TIMER0 and PPI - * armed) so we may simply miss the slot and set the timer in the past. - * - * When TX is scheduled in advance, we may event process packet a bit longer - * during radio ramp-up - this gives us extra 40 usecs which is more than - * enough. - */ - - /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ - tx_time = NRF_TIMER0_NS->CC[2] + BLE_LL_IFS; - /* Adjust for delay between actual RX end time and EVENT_END */ - tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; - /* Adjust for radio ramp-up */ - tx_time -= BLE_PHY_T_TXENFAST; - /* Adjust for delay between EVENT_READY and actual TX start time */ - tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - - NRF_TIMER0_NS->CC[0] = tx_time; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* Enable automatic TX */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_plna_enable_pa(); - - /* - * XXX: Hack warning! - * - * It may happen (during flash erase) that CPU is stopped for a moment and - * TIMER0 already counted past CC[0]. In such case we will be stuck waiting - * for TX to start since EVENTS_COMPARE[0] will not happen any time soon. - * For now let's set a flag denoting that we are late in RX-TX transition so - * ble_phy_tx() will fail - this allows everything to cleanup nicely without - * the need for extra handling in many places. - * - * Note: CC[3] is used only for wfr which we do not need here. - */ - NRF_TIMER0_NS->TASKS_CAPTURE[3] = 1; - if (NRF_TIMER0_NS->CC[3] > NRF_TIMER0_NS->CC[0]) { - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - g_ble_phy_data.phy_transition_late = 1; - } - - /* - * XXX: This is a horrible ugly hack to deal with the RAM S1 byte - * that is not sent over the air but is present here. Simply move the - * data pointer to deal with it. Fix this later. - */ - dptr[2] = dptr[1]; - dptr[1] = dptr[0]; - rc = ble_ll_rx_end(dptr + 1, ble_hdr); - if (rc < 0) { - ble_phy_disable(); - } -} - -static bool -ble_phy_rx_start_isr(void) -{ - int rc; - uint32_t state; - uint32_t usecs; - uint32_t pdu_usecs; - uint32_t ticks; - struct ble_mbuf_hdr *ble_hdr; - uint8_t *dptr; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int adva_offset; -#endif - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - - /* Clear events and clear interrupt */ - NRF_RADIO_NS->EVENTS_ADDRESS = 0; - NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk; - - /* Clear wfr timer channels and DISABLED interrupt */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - - /* Initialize the ble mbuf header */ - ble_hdr = &g_ble_phy_data.rxhdr; - ble_hdr->rxinfo.flags = ble_ll_state_get(); - ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan; - ble_hdr->rxinfo.handle = 0; - ble_hdr->rxinfo.phy = ble_phy_get_cur_phy(); - ble_hdr->rxinfo.phy_mode = ble_phy_get_cur_rx_phy_mode(); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_hdr->rxinfo.user_data = NULL; -#endif - - /* - * Calculate accurate packets start time (with remainder) - * - * We may start receiving packet somewhere during preamble in which case - * it is possible that actual transmission started before TIMER0 was - * running - need to take this into account. - */ - ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime; - - usecs = NRF_TIMER0_NS->CC[1]; - pdu_usecs = ble_phy_mode_pdu_start_off(ble_hdr->rxinfo.phy_mode) + - g_ble_phy_t_rxaddrdelay[ble_hdr->rxinfo.phy_mode]; - if (usecs < pdu_usecs) { - g_ble_phy_data.phy_start_cputime--; - usecs += 30; - } - usecs -= pdu_usecs; - - ticks = os_cputime_usecs_to_ticks(usecs); - usecs -= os_cputime_ticks_to_usecs(ticks); - if (usecs == 31) { - usecs = 0; - ++ticks; - } - - ble_hdr->beg_cputime += ticks; - ble_hdr->rem_usecs = usecs; - - /* Wait to get 1st byte of frame */ - while (1) { - state = NRF_RADIO_NS->STATE; - if (NRF_RADIO_NS->EVENTS_BCMATCH != 0) { - break; - } - - /* - * If state is disabled, we should have the BCMATCH. If not, - * something is wrong! - */ - if (state == RADIO_STATE_STATE_Disabled) { - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - NRF_RADIO_NS->SHORTS = 0; - return false; - } - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* - * If privacy is enabled and received PDU has TxAdd bit set (i.e. random - * address) we try to resolve address using AAR. - */ - if (g_ble_phy_data.phy_privacy && (dptr[3] & 0x40)) { - /* - * AdvA is located at 4th octet in RX buffer (after S0, length an S1 - * fields). In case of extended advertising PDU we need to add 2 more - * octets for extended header. - */ - adva_offset = (dptr[3] & 0x0f) == 0x07 ? 2 : 0; - NRF_AAR_NS->ADDRPTR = (uint32_t)(dptr + 3 + adva_offset); - - /* Trigger AAR after last bit of AdvA is received */ - NRF_RADIO_NS->EVENTS_BCMATCH = 0; - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_SUB(RADIO_EVENTS_BCMATCH); - NRF_RADIO_NS->BCC = (BLE_LL_PDU_HDR_LEN + adva_offset + BLE_DEV_ADDR_LEN) * 8 + - g_ble_phy_data.phy_bcc_offset; - } -#endif - - /* Call Link Layer receive start function */ - rc = ble_ll_rx_start(dptr + 3, - g_ble_phy_data.phy_chan, - &g_ble_phy_data.rxhdr); - if (rc >= 0) { - /* Set rx started flag and enable rx end ISR */ - g_ble_phy_data.phy_rx_started = 1; - } else { - /* Disable PHY */ - ble_phy_disable(); - STATS_INC(ble_phy_stats, rx_aborts); - } - - /* Count rx starts */ - STATS_INC(ble_phy_stats, rx_starts); - - return true; -} - -static void -ble_phy_isr(void) -{ - uint32_t irq_en; - - os_trace_isr_enter(); - - /* Read irq register to determine which interrupts are enabled */ - irq_en = NRF_RADIO_NS->INTENCLR; - - /* - * NOTE: order of checking is important! Possible, if things get delayed, - * we have both an ADDRESS and DISABLED interrupt in rx state. If we get - * an address, we disable the DISABLED interrupt. - */ - - /* We get this if we have started to receive a frame */ - if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO_NS->EVENTS_ADDRESS) { - /* - * wfr timer is calculated to expire at the exact time we should start - * receiving a packet (with 1 usec precision) so it is possible it will - * fire at the same time as EVENT_ADDRESS. If this happens, radio will - * be disabled while we are waiting for EVENT_BCCMATCH after 1st byte - * of payload is received and ble_phy_rx_start_isr() will fail. In this - * case we should not clear DISABLED irq mask so it will be handled as - * regular radio disabled event below. In other case radio was disabled - * on purpose and there's nothing more to handle so we can clear mask. - */ - if (ble_phy_rx_start_isr()) { - irq_en &= ~RADIO_INTENCLR_DISABLED_Msk; - } - } - - /* Handle disabled event. This is enabled for both TX and RX. On RX, we - * need to check phy_rx_started flag to make sure we actually were receiving - * a PDU, otherwise this is due to wfr. - */ - if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && - NRF_RADIO_NS->EVENTS_DISABLED) { - BLE_LL_ASSERT(NRF_RADIO_NS->EVENTS_END || - ((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) && - !g_ble_phy_data.phy_rx_started)); - NRF_RADIO_NS->EVENTS_END = 0; - NRF_RADIO_NS->EVENTS_DISABLED = 0; - NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; - - switch (g_ble_phy_data.phy_state) { - case BLE_PHY_STATE_RX: - ble_phy_plna_disable_lna(); - if (g_ble_phy_data.phy_rx_started) { - ble_phy_rx_end_isr(); - } else { - ble_ll_wfr_timer_exp(NULL); - } - break; - case BLE_PHY_STATE_TX: - ble_phy_plna_disable_pa(); - ble_phy_tx_end_isr(); - break; - default: - BLE_LL_ASSERT(0); - } - } - - g_ble_phy_data.phy_transition_late = 0; - /* Count # of interrupts */ - STATS_INC(ble_phy_stats, phy_isrs); - - os_trace_isr_exit(); -} - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ - MYNEWT_VAL(BLE_LL_PA) || \ - MYNEWT_VAL(BLE_LL_LNA) -static int -ble_phy_gpiote_configure(int pin) -{ - NRF_GPIO_Type *port; - - g_ble_phy_gpiote_idx--; - - port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; - pin &= 0x1f; - - /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */ - port->DIRSET = (1 << pin); - port->OUTCLR = (1 << pin); - - NRF_GPIOTE_NS->CONFIG[g_ble_phy_gpiote_idx] = - (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | - ((port == NRF_P1_NS) << GPIOTE_CONFIG_PORT_Pos); - - BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); - - return g_ble_phy_gpiote_idx; -} -#endif - -static void -ble_phy_dbg_time_setup(void) -{ - int idx __attribute__((unused)) = 8; - - /* - * We setup GPIOTE starting from last configuration index to minimize risk - * of conflict with GPIO setup via hal. It's not great solution, but since - * this is just debugging code we can live with this. - */ - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); - phy_dbg_txrxen_ready_idx = idx; - - NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); - - /* Publish RADIO->EVENTS_READY */ - NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY); - -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); - phy_dbg_address_end_idx = idx; - - NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_END); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); - phy_dbg_wfr_idx = idx; - - NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(RADIO_EVENTS_RXREADY); - - /* TODO figure out how (if?) to subscribe task to multiple DPPI channels - * Currently only last one is working. Also using multiple GPIOTE for same - * PIN doesn't work... - */ - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); - - /* Publish RADIO->EVENTS_RXREADY */ - NRF_RADIO_NS->PUBLISH_RXREADY = DPPI_CH_PUB(RADIO_EVENTS_READY); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_RXREADY); - - /* Publish RADIO->EVENTS_DISABLED */ - NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED); -#endif -} - -int -ble_phy_init(void) -{ - int rc; - - g_ble_phy_gpiote_idx = 8; - - /* Default phy to use is 1M */ - g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_rx_phy_mode = BLE_PHY_MODE_1M; - - g_ble_phy_data.rx_pwr_compensation = 0; - - /* Set phy channel to an invalid channel so first set channel works */ - g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; - - /* Toggle peripheral power to reset (just in case) */ - NRF_RADIO_NS->POWER = 0; - NRF_RADIO_NS->POWER = 1; - - /* Errata 16 - RADIO: POWER register is not functional - * Workaround: Reset all RADIO registers in firmware. - */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = 0; - NRF_RADIO_NS->SUBSCRIBE_RXEN = 0; - NRF_RADIO_NS->SUBSCRIBE_DISABLE = 0; - - /* Disable all interrupts */ - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - - /* Set configuration registers */ - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_1Mbit; - NRF_RADIO_NS->PCNF0 = NRF_PCNF0; - - /* XXX: should maxlen be 251 for encryption? */ - NRF_RADIO_NS->PCNF1 = NRF_MAXLEN | - (RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos) | - (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) | - RADIO_PCNF1_WHITEEN_Msk; - - /* Enable radio fast ramp-up */ - NRF_RADIO_NS->MODECNF0 |= (RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos) & RADIO_MODECNF0_RU_Msk; - - /* Set logical address 1 for TX and RX */ - NRF_RADIO_NS->TXADDRESS = 0; - NRF_RADIO_NS->RXADDRESSES = (1 << 0); - - /* Configure the CRC registers */ - NRF_RADIO_NS->CRCCNF = (RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos) | RADIO_CRCCNF_LEN_Three; - - /* Configure BLE poly */ - NRF_RADIO_NS->CRCPOLY = 0x0000065B; - - /* Configure IFS */ - NRF_RADIO_NS->TIFS = BLE_LL_IFS; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - NRF_CCM_NS->INTENCLR = 0xffffffff; - NRF_CCM_NS->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM_NS->EVENTS_ERROR = 0; - memset(nrf_encrypt_scratchpad, 0, sizeof(nrf_encrypt_scratchpad)); -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - g_ble_phy_data.phy_aar_scratch = 0; - NRF_AAR_NS->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - NRF_AAR_NS->INTENCLR = 0xffffffff; - NRF_AAR_NS->EVENTS_END = 0; - NRF_AAR_NS->EVENTS_RESOLVED = 0; - NRF_AAR_NS->EVENTS_NOTRESOLVED = 0; - NRF_AAR_NS->NIRK = 0; -#endif - - /* TIMER0 setup for PHY when using RTC */ - NRF_TIMER0_NS->TASKS_STOP = 1; - NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; - NRF_TIMER0_NS->BITMODE = 3; /* 32-bit timer */ - NRF_TIMER0_NS->MODE = 0; /* Timer mode */ - NRF_TIMER0_NS->PRESCALER = 4; /* gives us 1 MHz */ - - /* Publish events */ - NRF_TIMER0_NS->PUBLISH_COMPARE[0] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_0); - NRF_TIMER0_NS->PUBLISH_COMPARE[3] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_3); - NRF_RADIO_NS->PUBLISH_END = DPPI_CH_PUB(RADIO_EVENTS_END); - NRF_RADIO_NS->PUBLISH_BCMATCH = DPPI_CH_PUB(RADIO_EVENTS_BCMATCH); - NRF_RADIO_NS->PUBLISH_ADDRESS = DPPI_CH_PUB(RADIO_EVENTS_ADDRESS); - NRF_RTC0_NS->PUBLISH_COMPARE[0] = DPPI_CH_PUB(RTC0_EVENTS_COMPARE_0); - - /* Enable channels we publish on */ - NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_ALL; - - /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[1] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[2] = DPPI_CH_SUB(RADIO_EVENTS_END); - -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) - /* We keep both channels enabled and CLR task subscribed all the time. It's - * enough to just (un)subscribe SET task when needed. - * TODO: figure out if this affects power consumption - */ - -#if PLNA_SINGLE_GPIO - plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[plna_idx] = 1; -#else -#if MYNEWT_VAL(BLE_LL_PA) - plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[plna_pa_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_LL_LNA) - plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[plna_lna_idx] = 1; -#endif -#endif - - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK_PLNA; -#endif - - /* Set isr in vector table and enable interrupt */ -#ifndef RIOT_VERSION - NVIC_SetPriority(RADIO_IRQn, 0); -#endif -#if MYNEWT - NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr); -#else - ble_npl_hw_set_isr(RADIO_IRQn, ble_phy_isr); -#endif - NVIC_EnableIRQ(RADIO_IRQn); - - /* Register phy statistics */ - if (!g_ble_phy_data.phy_stats_initialized) { - rc = stats_init_and_reg(STATS_HDR(ble_phy_stats), - STATS_SIZE_INIT_PARMS(ble_phy_stats, - STATS_SIZE_32), - STATS_NAME_INIT_PARMS(ble_phy_stats), - "ble_phy"); - assert(rc == 0); - - g_ble_phy_data.phy_stats_initialized = 1; - } - - ble_phy_dbg_time_setup(); - - return 0; -} - -int -ble_phy_rx(void) -{ - /* - * Check radio state. - * - * In case radio is now disabling we'll wait for it to finish, but if for - * any reason it's just in idle state we proceed with RX as usual since - * nRF52 radio can ramp-up from idle state as well. - * - * Note that TX and RX states values are the same except for 3rd bit so we - * can make a shortcut here when checking for idle state. - */ - nrf_wait_disabled(); - if ((NRF_RADIO_NS->STATE != RADIO_STATE_STATE_Disabled) && - ((NRF_RADIO_NS->STATE & 0x07) != RADIO_STATE_STATE_RxIdle)) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, radio_state_errs); - return BLE_PHY_ERR_RADIO_STATE; - } - - /* Make sure all interrupts are disabled */ - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - - /* Clear events prior to enabling receive */ - NRF_RADIO_NS->EVENTS_END = 0; - NRF_RADIO_NS->EVENTS_DISABLED = 0; - - /* Setup for rx */ - ble_phy_rx_xcvr_setup(); - - /* task to start RX should be subscribed here */ - assert(NRF_RADIO_NS->SUBSCRIBE_RXEN & DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0)); - - return 0; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_central) -{ - memcpy(nrf_ccm_data.key, key, 16); - nrf_ccm_data.pkt_counter = pkt_counter; - memcpy(nrf_ccm_data.iv, iv, 8); - nrf_ccm_data.dir_bit = is_central; - g_ble_phy_data.phy_encrypted = 1; - /* Enable the module (AAR cannot be on while CCM on) */ - NRF_AAR_NS->ENABLE = AAR_ENABLE_ENABLE_Disabled; - NRF_CCM_NS->ENABLE = CCM_ENABLE_ENABLE_Enabled; -} - -void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) -{ - nrf_ccm_data.pkt_counter = pkt_counter; - nrf_ccm_data.dir_bit = dir; -} - -void -ble_phy_encrypt_disable(void) -{ - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_CCM_NS->TASKS_STOP = 1; - NRF_CCM_NS->EVENTS_ERROR = 0; - NRF_CCM_NS->ENABLE = CCM_ENABLE_ENABLE_Disabled; - - g_ble_phy_data.phy_encrypted = 0; -} -#endif - -void -ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg) -{ - /* Set transmit end callback and arg */ - g_ble_phy_data.txend_cb = txend_cb; - g_ble_phy_data.txend_arg = arg; -} - -int -ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - int rc; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to RXEN since we are transmitting */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { - STATS_INC(ble_phy_stats, tx_late); - ble_phy_disable(); - rc = BLE_PHY_ERR_TX_LATE; - } else { - /* Enable PPI to automatically start TXEN */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - rc = 0; - - ble_phy_plna_enable_pa(); - } - return rc; -} - -int -ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - bool late = false; - int rc = 0; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to TXEN since we are transmitting */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { - STATS_INC(ble_phy_stats, rx_late); - - /* We're late so let's just try to start RX as soon as possible */ - ble_phy_set_start_now(); - - late = true; - } - - /* Enable PPI to automatically start RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_plna_enable_lna(); - - /* Start rx */ - rc = ble_phy_rx(); - - /* - * If we enabled receiver but were late, let's return proper error code so - * caller can handle this. - */ - if (!rc && late) { - rc = BLE_PHY_ERR_RX_LATE; - } - - return rc; -} - -int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) -{ - int rc; - uint8_t *dptr; - uint8_t *pktptr; - uint8_t payload_len; - uint8_t hdr_byte; - uint32_t state; - uint32_t shortcuts; - - if (g_ble_phy_data.phy_transition_late) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - return BLE_PHY_ERR_TX_LATE; - } - - /* - * This check is to make sure that the radio is not in a state where - * it is moving to disabled state. If so, let it get there. - */ - nrf_wait_disabled(); - - /* - * XXX: Although we may not have to do this here, I clear all the PPI - * that should not be used when transmitting. Some of them are only enabled - * if encryption and/or privacy is on, but I dont care. Better to be - * paranoid, and if you are going to clear one, might as well clear them - * all. - */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - dptr = (uint8_t *)&g_ble_phy_enc_buf[0]; - pktptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - NRF_CCM_NS->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM_NS->INPTR = (uint32_t)dptr; - NRF_CCM_NS->OUTPTR = (uint32_t)pktptr; - NRF_CCM_NS->SCRATCHPTR = (uint32_t)&nrf_encrypt_scratchpad[0]; - NRF_CCM_NS->EVENTS_ERROR = 0; - NRF_CCM_NS->MODE = CCM_MODE_LENGTH_Msk | ble_phy_get_ccm_datarate(); - NRF_CCM_NS->CNFPTR = (uint32_t)&nrf_ccm_data; - } else { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - NRF_AAR_NS->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; -#endif - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; - } -#else - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; -#endif - - /* Set PDU payload */ - payload_len = pducb(&dptr[3], pducb_arg, &hdr_byte); - - /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */ - dptr[0] = hdr_byte; - dptr[1] = payload_len; - dptr[2] = 0; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* Start key-stream generation and encryption (via short) */ - if (g_ble_phy_data.phy_encrypted) { - NRF_CCM_NS->TASKS_KSGEN = 1; - } -#endif - - NRF_RADIO_NS->PACKETPTR = (uint32_t)pktptr; - - /* Clear the ready, end and disabled events */ - NRF_RADIO_NS->EVENTS_READY = 0; - NRF_RADIO_NS->EVENTS_END = 0; - NRF_RADIO_NS->EVENTS_DISABLED = 0; - - /* Enable shortcuts for transmit start/end. */ - shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk; - NRF_RADIO_NS->SHORTS = shortcuts; - NRF_RADIO_NS->INTENSET = RADIO_INTENSET_DISABLED_Msk; - - /* Set the PHY transition */ - g_ble_phy_data.phy_transition = end_trans; - - /* Set transmitted payload length */ - g_ble_phy_data.phy_tx_pyld_len = payload_len; - - /* If we already started transmitting, abort it! */ - state = NRF_RADIO_NS->STATE; - if (state != RADIO_STATE_STATE_Tx) { - /* Set phy state to transmitting and count packet statistics */ - g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; - STATS_INC(ble_phy_stats, tx_good); - STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN); - rc = BLE_ERR_SUCCESS; - } else { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - rc = BLE_PHY_ERR_RADIO_STATE; - } - - return rc; -} - -int -ble_phy_txpwr_set(int dbm) -{ - /* "Rail" power level if outside supported range */ - dbm = ble_phy_txpower_round(dbm); - - NRF_RADIO_NS->TXPOWER = dbm; - g_ble_phy_data.phy_txpwr_dbm = dbm; - - return 0; -} - -int -ble_phy_txpower_round(int dbm) -{ - /* "Rail" power level if outside supported range */ - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; - } - - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; -} - -static int -ble_phy_set_access_addr(uint32_t access_addr) -{ - NRF_RADIO_NS->BASE0 = (access_addr << 8); - NRF_RADIO_NS->PREFIX0 = (NRF_RADIO_NS->PREFIX0 & 0xFFFFFF00) | (access_addr >> 24); - - g_ble_phy_data.phy_access_address = access_addr; - - return 0; -} - -int -ble_phy_txpwr_get(void) -{ - return g_ble_phy_data.phy_txpwr_dbm; -} - -void -ble_phy_set_rx_pwr_compensation(int8_t compensation) -{ - g_ble_phy_data.rx_pwr_compensation = compensation; -} - -int -ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) -{ - assert(chan < BLE_PHY_NUM_CHANS); - - /* Check for valid channel range */ - if (chan >= BLE_PHY_NUM_CHANS) { - return BLE_PHY_ERR_INV_PARAM; - } - - /* Set current access address */ - ble_phy_set_access_addr(access_addr); - - /* Configure crcinit */ - NRF_RADIO_NS->CRCINIT = crcinit; - - /* Set the frequency and the data whitening initial value */ - g_ble_phy_data.phy_chan = chan; - NRF_RADIO_NS->FREQUENCY = g_ble_phy_chan_freq[chan]; - NRF_RADIO_NS->DATAWHITEIV = chan; - - return 0; -} - -/** - * Stop the timer used to count microseconds when using RTC for cputime - */ -static void -ble_phy_stop_usec_timer(void) -{ - NRF_TIMER0_NS->TASKS_STOP = 1; - NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; - NRF_RTC0_NS->EVTENCLR = RTC_EVTENSET_COMPARE0_Msk; -} - -/** - * ble phy disable irq and ppi - * - * This routine is to be called when reception was stopped due to either a - * wait for response timeout or a packet being received and the phy is to be - * restarted in receive mode. Generally, the disable routine is called to stop - * the phy. - */ -static void -ble_phy_disable_irq_and_ppi(void) -{ - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - NRF_RADIO_NS->SHORTS = 0; - NRF_RADIO_NS->TASKS_DISABLE = 1; - - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#else -#if MYNEWT_VAL(BLE_LL_PA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#endif -#if MYNEWT_VAL(BLE_LL_LNA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#endif -#endif - - NVIC_ClearPendingIRQ(RADIO_IRQn); - g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; -} - -void -ble_phy_restart_rx(void) -{ - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); - - ble_phy_set_start_now(); - /* Enable PPI to automatically start RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_rx(); -} - -static void -ble_phy_dbg_clear_pins(void) -{ -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_txrxen_ready_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_address_end_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_wfr_idx] = 1; -#endif -} - -void -ble_phy_disable(void) -{ - ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE); - - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); - - ble_phy_dbg_clear_pins(); -} - -uint32_t -ble_phy_access_addr_get(void) -{ - return g_ble_phy_data.phy_access_address; -} - -int -ble_phy_state_get(void) -{ - return g_ble_phy_data.phy_state; -} - -int -ble_phy_rx_started(void) -{ - return g_ble_phy_data.phy_rx_started; -} - -uint8_t -ble_phy_xcvr_state_get(void) -{ - uint32_t state; - state = NRF_RADIO_NS->STATE; - return (uint8_t)state; -} - -uint8_t -ble_phy_max_data_pdu_pyld(void) -{ - return BLE_LL_DATA_PDU_MAX_PYLD; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -void -ble_phy_resolv_list_enable(void) -{ - NRF_AAR_NS->NIRK = (uint32_t)g_nrf_num_irks; - g_ble_phy_data.phy_privacy = 1; -} - -void -ble_phy_resolv_list_disable(void) -{ - g_ble_phy_data.phy_privacy = 0; -} -#endif - -#if MYNEWT_VAL(BLE_LL_DTM) -void -ble_phy_enable_dtm(void) -{ - /* When DTM is enabled we need to disable whitening as per - * Bluetooth v5.0 Vol 6. Part F. 4.1.1 - */ - NRF_RADIO_NS->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk; -} - -void -ble_phy_disable_dtm(void) -{ - /* Enable whitening */ - NRF_RADIO_NS->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk; -} -#endif - -void -ble_phy_rfclk_enable(void) -{ -#if MYNEWT - nrf5340_net_clock_hfxo_request(); -#else - NRF_CLOCK_NS->TASKS_HFCLKSTART = 1; -#endif -} - -void -ble_phy_rfclk_disable(void) -{ -#if MYNEWT - nrf5340_net_clock_hfxo_release(); -#else - NRF_CLOCK_NS->TASKS_HFCLKSTOP = 1; -#endif -} diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy_trace.c b/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy_trace.c deleted file mode 100644 index dad78679..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/src/ble_phy_trace.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include "controller/ble_phy_trace.h" - -#if MYNEWT_VAL(BLE_PHY_SYSVIEW) - -static os_trace_module_t g_ble_phy_trace_mod; -uint32_t ble_phy_trace_off; - -static void -ble_phy_trace_module_send_desc(void) -{ - os_trace_module_desc(&g_ble_phy_trace_mod, "0 phy_set_tx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "1 phy_set_rx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "2 phy_disable"); -} - -void -ble_phy_trace_init(void) -{ - ble_phy_trace_off = - os_trace_module_register(&g_ble_phy_trace_mod, "ble_phy", 3, - ble_phy_trace_module_send_desc); -} -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/syscfg.yml deleted file mode 100644 index ed82f6d6..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/nrf5340/syscfg.yml +++ /dev/null @@ -1,62 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_PHY_SYSVIEW: - description: > - Enable SystemView tracing module for radio driver. - value: 0 - - BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state when radio is enabled (TASKS_TXEN or TASKS_RXEN) - and back to low state on radio EVENTS_READY. - This can be used to measure radio ram-up time. - - Note: - GPIO control for selected pin needs to be assigned to Network - Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on - Application Core. - value: -1 - - BLE_PHY_DBG_TIME_ADDRESS_END_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_ADDRESS and back to low state - on radio EVENTS_END. - This can be used to measure radio pipeline delays. - - Note: - GPIO control for selected pin needs to be assigned to Network - Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on - Application Core. - value: -1 - - BLE_PHY_DBG_TIME_WFR_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_RXREADY and back to low - state when wfr timer expires. - This can be used to check if wfr is calculated properly. - - Note: - GPIO control for selected pin needs to be assigned to Network - Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on - Application Core. - value: -1 diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/pkg.yml b/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/pkg.yml deleted file mode 100644 index c3cb0fd3..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/pkg.yml +++ /dev/null @@ -1,31 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/drivers/plna/sky66112 -pkg.description: Driver for SKY66112 front-end module -pkg.author: "Apache Mynewt " -pkg.homepage: "https://mynewt.apache.org/" -pkg.apis: - - ble_ll_pa - - ble_ll_lna -pkg.deps: - - nimble/controller - -pkg.init: - sky66112_init: 999 diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/src/sky66112.c b/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/src/sky66112.c deleted file mode 100644 index 4a849fbb..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/src/sky66112.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include "syscfg/syscfg.h" -#include "hal/hal_gpio.h" -#include "controller/ble_ll_plna.h" - -#define NO_BYPASS \ - ((MYNEWT_VAL(SKY66112_TX_BYPASS) == 0) && \ - (MYNEWT_VAL(SKY66112_RX_BYPASS) == 0)) - -static void -sky66112_bypass(uint8_t enabled) -{ - if (NO_BYPASS) { - return; - } - - hal_gpio_write(MYNEWT_VAL(SKY66112_PIN_CPS), enabled); -} - -void -ble_ll_plna_pa_init(void) -{ - /* Nothing to do here */ -} - -void -ble_ll_plna_pa_enable(void) -{ - if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { - sky66112_bypass(0); - } -} - -void -ble_ll_plna_pa_disable(void) -{ - if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { - sky66112_bypass(1); - } -} - -void -ble_ll_plna_lna_init(void) -{ - /* Nothing to do here */ -} - -void -ble_ll_plna_lna_enable(void) -{ - if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { - sky66112_bypass(0); - } -} - -void -ble_ll_plna_lna_disable(void) -{ - if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { - sky66112_bypass(1); - } -} - -void -sky66112_init(void) -{ - int pin; - - /* Use CRX and CTX to enable sleep mode */ - pin = MYNEWT_VAL(SKY66112_PIN_CSD); - if (pin >= 0) { - hal_gpio_init_out(pin, 1); - } - - pin = MYNEWT_VAL(SKY66112_PIN_CPS); - if (NO_BYPASS) { - /* Disable bypass */ - if (pin >= 0) { - hal_gpio_init_out(pin, 0); - } - } else { - /* Enable bypass, we'll disable it when needed */ - assert(pin >= 0); - hal_gpio_init_out(pin, 1); - } - - pin = MYNEWT_VAL(SKY66112_PIN_CHL); - if (pin >= 0) { - hal_gpio_init_out(pin, MYNEWT_VAL(SKY66112_TX_HP_MODE)); - } - - /* Select ANT1 */ - pin = MYNEWT_VAL(SKY66112_PIN_SEL); - if (pin >= 0) { - hal_gpio_init_out(pin, 0); - } -} diff --git a/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/syscfg.yml deleted file mode 100644 index 50434553..00000000 --- a/lib/bt/host/nimble/nimble/nimble/drivers/plna/sky66112/syscfg.yml +++ /dev/null @@ -1,66 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - SKY66112_PIN_CSD: - description: > - GPIO pin number to control CSD signal. - When set to '-1', pin state will not be changed and it should be - driven externally. - value: -1 - SKY66112_PIN_CPS: - description: > - GPIO pin number to control CPS signal. - When set to '-1', pin state will not be changed and it should be - driven externally. - value: -1 - SKY66112_PIN_CHL: - description: > - GPIO pin number to control CHL signal. - When set to '-1', pin state will not be changed and it should be - driven externally. - value: -1 - SKY66112_PIN_SEL: - description: > - GPIO pin number to control SEL signal. - When set to '-1', pin state will not be changed and it should be - driven externally. - value: -1 - SKY66112_TX_HP_MODE: - description: > - Enables high-power mode for TX. - Only valid if CHL signal is controller by driver. - value: 0 - SKY66112_TX_BYPASS: - description: > - Enables bypass for TX which effectively disables operation as PA. - Only valid if CPS signal is controller by driver. - value: 0 - SKY66112_RX_BYPASS: - description: > - Enables bypass for RX which effectively disables operation as PA. - Only valid if CPS signal is controller by driver. - value: 0 - -syscfg.vals.!BLE_LL_PA: - # Enable TX bypass by default if PA is disabled - SKY66112_TX_BYPASS: 1 - -syscfg.vals.!BLE_LL_LNA: - # Enable RX bypass by default if LNA is disabled - SKY66112_RX_BYPASS: 1 diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_att.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_att.h index a4665aa3..29c21393 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_att.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_att.h @@ -189,7 +189,6 @@ struct os_mbuf; /** Execute Write Response. */ #define BLE_ATT_OP_EXEC_WRITE_RSP 0x19 - /** Read Multiple Variable Lenght Request */ #define BLE_ATT_OP_READ_MULT_VAR_REQ 0x20 @@ -205,8 +204,13 @@ struct os_mbuf; /** Indicate Response. */ #define BLE_ATT_OP_INDICATE_RSP 0x1e +/** Multiple Handle Value Length Notification Request */ +#define BLE_ATT_OP_NOTIFY_MULTI_REQ 0x23 + /** Write Command. */ #define BLE_ATT_OP_WRITE_CMD 0x52 + +/** Signed Write Command */ #define BLE_ATT_OP_SIGNED_WRITE_CMD 0xD2 /** @} */ @@ -343,6 +347,9 @@ uint16_t ble_att_preferred_mtu(void); */ int ble_att_set_preferred_mtu(uint16_t mtu); +int ble_att_set_default_bearer_using_cid(uint16_t conn_handle, uint16_t cid); +uint16_t ble_att_get_default_bearer_cid(uint16_t conn_handle); + #ifdef __cplusplus } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_ead.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_ead.h index 38cf1503..8d6b6082 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_ead.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_ead.h @@ -121,8 +121,6 @@ int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], const uint8_t iv[BLE_EAD_IV_SIZE], const uint8_t *encrypted_payload, size_t encrypted_payload_size, uint8_t *payload); -int ble_ead_serialize_data(const struct enc_adv_data *input, uint8_t *output); - #endif /* ENC_ADV_DATA */ #ifdef __cplusplus diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gap.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gap.h index 705f29a9..c94d81eb 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gap.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gap.h @@ -30,6 +30,21 @@ typedef enum gap_status gap_status_t; #define BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROV_SRV_ADV 3 #define BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SRV_ADV 4 +#define ESP_BLE_VENDOR_LEGACY_SCAN_REQ_EVT_MASK BIT(0) +#define ESP_BLE_VENDOR_CHAN_MAP_UPDATE_CMPL_EVT_MASK BIT(1) +#define ESP_BLE_VENDOR_TL_RUNNING_STATUS_EVT_MASK BIT(2) +#define ESP_BLE_VENDOR_SLEEP_WAKEUP_EVT_MASK BIT(3) +#define ESP_BLE_VENDOR_CONNECT_IND_REQ_EVT_MASK BIT(4) +#define ESP_BLE_VENDOR_AUX_CONNECT_RSP_EVT_MASK BIT(5) + +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#ifdef CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT +#define MAX_REATTEMPT_ALLOWED CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT +#else +#define MAX_REATTEMPT_ALLOWED 0 +#endif +#endif + /** * Configure LE Data Length in controller (OGF = 0x08, OCF = 0x0022). * @@ -88,6 +103,15 @@ int ble_hs_hci_util_write_sugg_def_data_len(uint16_t sugg_max_tx_octets, uint16_ */ int ble_gap_wl_tx_rmv(const ble_addr_t *addrs); +/** + * Adds the address in controller's white list. + * + * @param addrs The entry to be added in the white list. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_wl_tx_add(const ble_addr_t *addrs); + /** * Clears all addresses from controller's white list. * @@ -257,6 +281,20 @@ int ble_gap_set_chan_select(uint8_t select); int ble_gap_dev_authorization(uint16_t conn_handle, bool authorized); +/** + * Sets the vendor-specific event mask for BLE host. + * + * This function configures the vendor-specific event mask, enabling or disabling + * specific vendor-defined events from being reported by the controller. + * + * @param event_mask Bitmask representing the events to enable. + * + * @return 0 on success; + * A nonzero value indicating an error if the command fails. + */ +int +ble_hs_send_vs_event_mask(uint32_t event_mask); + void ble_gap_rx_test_evt(const void *buf, uint8_t len); void ble_gap_tx_test_evt(const void *buf, uint8_t len); void ble_gap_end_test_evt(const void *buf, uint8_t len); diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gattc_cache.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gattc_cache.h new file mode 100644 index 00000000..7ec9ff2e --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_esp_gattc_cache.h @@ -0,0 +1,255 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef H_BLE_ESP_GATTC_GET_CACHE_ +#define H_BLE_ESP_GATTC_GET_CACHE_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_GATT_CACHING) +#include "../src/ble_gattc_cache_priv.h" +/** Enumerates types of GATT database attributes */ + +typedef enum { + ESP_BLE_GATT_DB_PRIMARY_SERVICE, /*!< Primary services in the GATT database */ + ESP_BLE_GATT_DB_SECONDARY_SERVICE, /*!< Secondary services in the GATT database */ + ESP_BLE_GATT_DB_INCLUDED_SERVICE, /*!< Included services in the GATT database */ + ESP_BLE_GATT_DB_CHARACTERISTIC, /*!< Characteristics in the GATT database */ + ESP_BLE_GATT_DB_DESCRIPTOR, /*!< Descriptors in the GATT database */ + ESP_BLE_GATT_DB_ALL, /*!< All attributes in the GATT database */ +} esp_ble_gatt_db_attr_type_t; + +/** @brief Represents a GATT service element. */ +typedef struct { + bool is_primary; /*!< Indicates if the service is primary. */ + uint16_t start_handle; /*!< Service start handle. */ + uint16_t end_handle; /*!< Service end handle. */ + ble_uuid_any_t uuid; /*!< Service UUID. */ +} ble_gattc_service_elem_t; + +/** @brief Represents a GATT included service element. */ +typedef struct { + uint16_t handle; /*!< handle */ + uint16_t incl_svc_s_handle; /*!< Included service start handle. */ + uint16_t incl_svc_e_handle; /*!< Included service end handle. */ + ble_uuid_any_t uuid; /*!< Included service UUID. */ +} ble_gattc_included_svc_elem_t; + +/** @brief Represents a GATT characteristic element. */ +typedef struct { + uint16_t char_handle; /*!< Characteristic value handle. */ + uint8_t properties; /*!< Characteristic properties. */ + ble_uuid_any_t uuid; /*!< Characteristic UUID. */ +} ble_gattc_char_elem_t; + +/** @brief Represents a GATT descriptor element. */ +typedef struct { + uint16_t handle; /*!< Descriptor handle. */ + ble_uuid_any_t uuid; /*!< Descriptor UUID. */ +} ble_gattc_descr_elem_t; + +/** + * Retrieve service(s) from the cached GATT database for a given connection. + * + * This function searches the local GATT cache for a service matching the given UUID. + * If `svc_uuid` is not NULL, it returns the matching service(s). + * If `svc_uuid` is NULL, it returns all cached services. + * + * @param conn_handle Connection handle of the peer device. + * @param svc_uuid UUID of the service to search for (can be NULL to fetch all services). + * @param result Output buffer to store the retrieved service(s). + * @param count Number of entries in the cache + * @param offset Index offset for paginated access (used when more services exist). + * + * @return 0 on success, error code otherwise. + */ + + +int ble_gattc_get_service(uint16_t conn_handle, + ble_uuid_t *svc_uuid, + ble_gattc_service_elem_t *result, + uint16_t *count, uint16_t offset); +/** + * Retrieve all characteristics in a specified handle range from the cached GATT database. + * + * This function fetches all characteristics between the given start and end handles, + * typically the range of a service. Characteristics are returned from the local cache. + * + * @param conn_handle Connection handle of the peer device. + * @param start_handle Start handle of the attribute range (usually the service's start handle). + * @param end_handle End handle of the attribute range (usually the service's end handle). + * @param result Output buffer to store the retrieved characteristics. + * @param count The number of characteristics to retrieve. It will be updated with the actual number of characteristics found. + * @param offset The position offset to retrieve + * + * @return 0 on success, error code otherwise. + */ + + +int ble_gattc_get_all_char(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_gattc_char_elem_t *result, + uint16_t *count, uint16_t offset); +/** + * Retrieve all descriptors of a given characteristic from the cached GATT database. + * + * This function fetches all descriptors associated with the specified characteristic + * handle from the local GATT cache. + * + * @param conn_handle Connection handle of the peer device. + * @param char_handle Handle of the characteristic whose descriptors are to be fetched. + * @param result Output buffer to store the retrieved descriptors. + * @param count The number of descriptors to retrieve. It will be updated with the actual number of descriptors found. + * @param offset The position offset to retrieve + * + * @return 0 on success, error code otherwise. + */ + + + +int ble_gattc_get_all_descr(uint16_t conn_handle, + uint16_t char_handle, + ble_gattc_descr_elem_t *result, + uint16_t *count, uint16_t offset); + +/** + * Retrieve characteristics with a specific UUID from the cached GATT database. + * + * This function fetches all characteristics matching the given UUID within the specified + * handle range (typically a service's start and end handles) from the local GATT cache. + * + * @param conn_handle Connection handle of the peer device. + * @param start_handle Start handle of the attribute range. + * @param end_handle End handle of the attribute range. + * @param char_uuid UUID of the characteristic to search for. + * @param result Output buffer to store the retrieved characteristics. + * @param count The number of characteristics to retrieve. It will be updated with the actual number of characteristics found. + * + * @return 0 on success, error code otherwise. + */ + + +int ble_gattc_get_char_by_uuid(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_uuid_t *char_uuid, + ble_gattc_char_elem_t *result, uint16_t *count); + +/** + * Retrieve descriptors with a specific UUID from the cached GATT database. + * + * This function searches for all descriptors that match the given descriptor UUID + * within the specified handle range and associated with the given characteristic UUID. + * + * @param conn_handle Connection handle of the peer device. + * @param start_handle Start handle of the attribute range. + * @param end_handle End handle of the attribute range. + * @param char_uuid UUID of the characteristic to which the descriptor belongs. + * @param descr_uuid UUID of the descriptor to search for. + * @param result Output buffer to store the retrieved descriptors. + * @param count The number of descriptors to retrieve. It will be updated with the actual number of descriptors found. + * + * @return 0 on success, error code otherwise. + */ + +int ble_gattc_get_descr_by_uuid(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_uuid_t *char_uuid, + ble_uuid_t *descr_uuid, + ble_gattc_descr_elem_t *result, uint16_t *count); +/** + * Retrieve descriptors with a specific UUID for a given characteristic handle from the cached GATT database. + * + * This function searches the local GATT cache for descriptors matching the provided UUID + * that are associated with the specified characteristic handle. + * + * @param conn_handle Connection handle of the peer device. + * @param char_handle Handle of the characteristic whose descriptors are to be searched. + * @param descr_uuid UUID of the descriptor to search for. + * @param result Output buffer to store the retrieved descriptors. + * @param count The number of descriptors to retrieve. It will be updated with the actual number of descriptors found. + * + * @return 0 on success, error code otherwise. + */ + +int ble_gattc_get_descr_by_char_handle(uint16_t conn_handle, + uint16_t char_handle, + ble_uuid_t *descr_uuid, + ble_gattc_descr_elem_t *result, uint16_t *count); +/** + * Retrieve included services within a specified handle range from the cached GATT database. + * + * This function searches for included (referenced) services within the specified start and end handle range. + * If `incl_uuid` is not NULL, it returns only the included services that match the provided UUID. + * Otherwise, it returns all included services found in the range. + * + * @param conn_handle Connection handle of the peer device. + * @param start_handle Start handle of the attribute range. + * @param end_handle End handle of the attribute range. + * @param incl_uuid UUID of the included service to search for (can be NULL to fetch all). + * @param result Output buffer to store the retrieved included services. + * @param count The number of included services to retrieve. It will be updated with the actual number of included services found. + * + * @return 0 on success, error code otherwise. + */ +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +int ble_gattc_get_include_service(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_uuid_t *incl_uuid, + ble_gattc_included_svc_elem_t *result, uint16_t *count); +#endif + +/** + * Get the number of attributes of a given type from the cached GATT database. + * + * This function counts the number of attributes (services, characteristics, or descriptors) + * present in the local GATT cache within a specified handle range or under a specific + * characteristic, depending on the attribute type. + * + * @param conn_handle Connection handle of the peer device. + * @param type Type of attribute to count (e.g., service, characteristic, descriptor). + * @param start_handle Start handle of the range to search. + * @param end_handle End handle of the range to search. + * @param char_handle Characteristic handle (used only if type is `ESP_BLE_GATT_DB_DESCRIPTOR`). + * @param count Output pointer to store the number of attributes found. + * + * @return 0 on success, error code otherwise. + */ + +int ble_gattc_get_attr_count(uint16_t conn_handle, esp_ble_gatt_db_attr_type_t type, + uint16_t start_handle, uint16_t end_handle, + uint16_t char_handle, uint16_t *count); +/** + * Retrieve cached GATT attributes within a given handle range. + * + * This function fetches services, characteristics, and descriptors from the local + * GATT database cache between the specified start and end handles. + * + * @param conn_handle Connection handle of the peer device. + * @param start_handle Start handle of the GATT database range. + * @param end_handle End handle of the GATT database range. + * @param result Output buffer to store the retrieved GATT database elements. + * @param count The number of attribute to retrieve. It will be updated with the actual number of attributes found. + * + * @return 0 on success, error code otherwise. + */ + + +int ble_gattc_get_db(uint16_t conn_handle, + uint16_t start_handle, uint16_t end_handle, + ble_gattc_db_elem_t* result, uint16_t *count); + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gap.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gap.h index ebab72b8..d9c1bf34 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gap.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gap.h @@ -161,6 +161,16 @@ struct hci_conn_update; #define BLE_GAP_EVENT_AUTHORIZE 32 #define BLE_GAP_EVENT_TEST_UPDATE 33 #define BLE_GAP_EVENT_DATA_LEN_CHG 34 +#define BLE_GAP_EVENT_CONNLESS_IQ_REPORT 35 +#define BLE_GAP_EVENT_CONN_IQ_REPORT 36 +#define BLE_GAP_EVENT_CTE_REQ_FAILED 37 + +//TODO : Deprecate the EVENT_LINK_ESTAB going ahead +#define BLE_GAP_EVENT_LINK_ESTAB 38 +#define BLE_GAP_EVENT_EATT 39 +#define BLE_GAP_EVENT_PER_SUBEV_DATA_REQ 40 +#define BLE_GAP_EVENT_PER_SUBEV_RESP 41 +#define BLE_GAP_EVENT_PERIODIC_TRANSFER_V2 42 /* DTM events */ #define BLE_GAP_DTM_TX_START_EVT 0 @@ -218,6 +228,18 @@ struct ble_gap_sec_state { unsigned authorize:1; }; +/** Read Remote Version parameters **/ +struct ble_gap_read_rem_ver_params { + /** Version of the Current LMP **/ + uint8_t version; + + /** Company Identifier **/ + uint16_t manufacturer; + + /** Revision of the LMP **/ + uint16_t subversion; +}; + /** Advertising parameters */ struct ble_gap_adv_params { /** Advertising mode. Can be one of following constants: @@ -322,6 +344,9 @@ struct ble_gap_ext_disc_params { /** If passive scan should be used */ uint8_t passive:1; + + /** If observation procedure is to be disabled. By default all advertisement reports are accepted */ + uint8_t disable_observer_mode:1; }; /** @brief Discovery parameters */ @@ -343,6 +368,9 @@ struct ble_gap_disc_params { /** If enable duplicates filtering */ uint8_t filter_duplicates:1; + + /** If observation procedure is to be disabled. By default all advertisement reports are accepted */ + uint8_t disable_observer_mode:1; }; /** @brief Connection parameters update parameters */ @@ -504,6 +532,66 @@ struct ble_gap_repeat_pairing { uint8_t new_bonding:1; }; + +#define BLE_GAP_PER_ADV_DATA_STATUS_COMPLETE 0x00 +#define BLE_GAP_PER_ADV_DATA_STATUS_INCOMPLETE 0x01 +#define BLE_GAP_PER_ADV_DATA_STATUS_TRUNCATED 0x02 +#define BLE_GAP_PER_ADV_DATA_STATUS_RX_FAILED 0xFF + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +struct ble_gap_periodic_adv_response { + /** The subevent in which the response is received */ + uint8_t subevent; + + /** Status of the subevent indication. + * + * 0 if subevent indication was transmitted. + * 1 if subevent indication was not transmitted. + * All other values RFU. + */ + + /** The adv handle of the adv */ + uint8_t adv_handle; + + uint8_t tx_status; + + /** The TX power of the response in dBm */ + int8_t tx_power; + + /** The RSSI of the response in dBm */ + int8_t rssi; + + /** The Constant Tone Extension (CTE) of the advertisement */ + uint8_t cte_type; + + /** The response slot */ + uint8_t response_slot; + + /** Data status */ + uint8_t data_status; + + /** Data length */ + uint8_t data_length; + + /** response data */ + const uint8_t *data; +}; + +struct ble_gap_periodic_adv_response_params { + /** The periodic advertsing event for which response shall be sent in */ + uint16_t request_event; + + /** The request subevent for which response shall be sent in */ + uint8_t request_subevent; + + /** The subevent the response shall be sent in */ + uint8_t response_subevent; + + /** The response slot the response shall be sent in */ + uint8_t response_slot; +}; +#endif + /** * Represents a GAP-related event. When such an event occurs, the host * notifies the application by passing an instance of this structure to an @@ -537,8 +625,63 @@ struct ble_gap_event { /** The handle of the relevant connection. */ uint16_t conn_handle; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /* + * Adv_Handle is used to identify an advertising set. + * If the connection is established from periodic advertising with responses + * and Role is 0x00 then the Advertising_Handle parameter shall be set + * according to the periodic advertising train the connection was established from + */ + uint8_t adv_handle; + + /* + * Sync_Handle identifying the periodic advertising train + * If the connection is established from periodic advertising with responses + * and Role is 0x01, then the Sync_Handle parameter shall be set according + * to the periodic advertising train the connection was established from + */ + uint16_t sync_handle; +#endif } connect; + /** + * Represents a successful Link establishment attempt. Sometimes, in noisy environment, + * even if BLE_GAP_EVENT_CONNECT is posted, the link syncronization procedure may fail + * and link gets disconnected with reason 0x3E. Application can wait for below event to ensure + * the link syncronization is completed. Valid for the following event + * types: + * o BLE_GAP_EVENT_LINK_ESTAB + */ + + struct { + /** + * The final status of the link establishment; + * o 0: the connection was successfully established. + * o BLE host error code: the connection attempt failed for + * the specified reason. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /* + * Adv_Handle is used to identify an advertising set. + * If the connection is established from periodic advertising with responses + * and Role is 0x00 then the Advertising_Handle parameter shall be set + * according to the periodic advertising train the connection was established from + */ + uint8_t adv_handle; + /* + * Sync_Handle identifying the periodic advertising train + * If the connection is established from periodic advertising with responses + * and Role is 0x01, then the Sync_Handle parameter shall be set according + * to the periodic advertising train the connection was established from + */ + uint16_t sync_handle; +#endif + } link_estab; + /** * Represents a terminated connection. Valid for the following event * types: @@ -921,6 +1064,18 @@ struct ble_gap_event { /** Advertiser clock accuracy */ uint8_t adv_clk_accuracy; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /** Number of subevents. If zero, the periodic advertiser will be a broadcaster, + * without responses. + */ + uint8_t num_subevents; + /** Interval between subevents (N * 1.25 ms) */ + uint8_t subevent_interval; + /** Time between the advertising packet and the first response slot (N * 1.25 ms). */ + uint8_t response_slot_delay; + /** Time between response slots (N * 0.125 ms) */ + uint8_t response_slot_spacing; +#endif } periodic_sync; /** @@ -938,10 +1093,24 @@ struct ble_gap_event { /** Received signal strength indication in dBm (127 if unavailable) */ int8_t rssi; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /** + * It indicates the periodic advertising event counter (paEventCounter) of + * the event that the periodic advertising packet was received in. + */ + uint16_t event_counter; + /** + * It indicates Periodic Advertising with Responses subevent in which + * the periodic advertising packet was received in. + */ + uint8_t subevent; +#endif + /** Advertising data status, can be one of following constants: * - BLE_HCI_PERIODIC_DATA_STATUS_COMPLETE * - BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE * - BLE_HCI_PERIODIC_DATA_STATUS_TRUNCATED + * - BLE_HCI_PERIODIC_DATA_STATUS_RX_FAILED */ uint8_t data_status; @@ -1023,6 +1192,18 @@ struct ble_gap_event { /** Advertiser clock accuracy */ uint8_t adv_clk_accuracy; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /** Number of subevents. If zero, the periodic advertiser will be a broadcaster,- + * without responses. + */ + uint8_t num_subevents; + /** Interval between subevents (N * 1.25 ms) */ + uint8_t subevent_interval; + /** Time between the advertising packet and the first response slot (N * 1.25 ms). */ + uint8_t response_slot_delay; + /** Time between response slots (N * 0.125 ms) */ + uint8_t response_slot_spacing; +#endif } periodic_transfer; #endif @@ -1167,6 +1348,30 @@ struct ble_gap_event { uint16_t supervision_tmo; } subrate_change; #endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /** + * Represents a periodic advertising subevent data request + * with parameters valid for the following event types: + * o BLE_GAP_EVENT_PER_SUBEV_DATA_REQ + */ + struct { + /** Advertising handle */ + uint8_t adv_handle; + + /** Subevent start */ + uint8_t subevent_start; + + /** Number of subevents */ + uint8_t subevent_data_count; + } periodic_adv_subev_data_req; + + /** + * Represents a periodic advertising response + * with parameters valid for the following event types: + * o BLE_GAP_EVENT_PER_SUBEV_RESP + */ + struct ble_gap_periodic_adv_response periodic_adv_response; +#endif #if MYNEWT_VAL(BLE_HCI_VS) /** @@ -1206,6 +1411,31 @@ struct ble_gap_event { int out_response; } authorize; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + /** + * EATT Event + * + * Valid for the following event types: + * o BLE_GAP_EVENT_EATT + * + */ + struct { + /* Connection Handle */ + uint16_t conn_handle; + + /** Connected Status + * + * EATT Connected: 0 + * EATT Disconnected: 1 + */ + uint8_t status; + + /* CID of the bearer */ + uint16_t cid; + + } eatt; +#endif + #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) /** * Represents a event mentioning connection reattempt @@ -1246,7 +1476,6 @@ struct ble_gap_event { */ uint16_t num_pkt; } dtm_state; - /** * Represent an event for LE Data length change * @@ -1269,6 +1498,161 @@ struct ble_gap_event { /* Max Rx Time */ uint16_t max_rx_time; } data_len_chg; +#if MYNEWT_VAL(BLE_AOA_AOD) + /** + * Represents a AOA/AOD connectionless iq report event + * Valid for the following event types: + * o BLE_GAP_EVENT_CONNLESS_IQ_RPT + */ + struct { + /** Sync_Handle identifying the periodic advertising train. + * Range: 0x0000 to 0x0EFF + * 0x0FFF indicates Receiver Test mode. + */ + uint16_t sync_handle; + + /** The index of the channel on which the packet was received. + * Range: 0x00 to 0x27 + * Note: 0x25 to 0x27 can be used only for packets generated during test modes. + */ + uint8_t channel_index; + + /** RSSI of the packet. + * Range: -1270 to +200 (Units: 0.1 dBm). + */ + int16_t rssi; + + /** Antenna ID used for receiving the packet. */ + uint8_t rssi_antenna_id; + + /** Type of Constant Tone Extension (CTE). + * 0x00: AoA Constant Tone Extension + * 0x01: AoD Constant Tone Extension with 1 μs slots + * 0x02: AoD Constant Tone Extension with 2 μs slots + */ + uint8_t cte_type; + + /** Switching and sampling slot durations. + * 0x01: Switching and sampling slots are 1 μs each + * 0x02: Switching and sampling slots are 2 μs each + */ + uint8_t slot_durations; + + /** Status of the packet. + * 0x00: CRC was correct + * 0x01: CRC was incorrect, but Length and CTETime fields were used to determine sampling points + * 0x02: CRC was incorrect, but the Controller determined the position and length of the CTE in another way + * 0xFF: Insufficient resources to sample (Channel_Index, CTE_Type, and Slot_Durations invalid) + */ + uint8_t packet_status; + + /** Value of paEventCounter for the reported AUX_SYNC_IND PDU. */ + uint16_t periodic_event_counter; + + /** Total number of sample pairs (I and Q samples). + * 0x00: No samples provided (only permitted if Packet_Status is 0xFF) + * 0x09 to 0x52: Total number of sample pairs + */ + uint8_t sample_count; + + /** Array of I samples for the reported packet (signed integers). + * Each value represents an I sample at a specific sampling point. + * 0x80 indicates no valid sample available. + */ + int8_t *i_samples; + + /** Array of Q samples for the reported packet (signed integers). + * Each value represents a Q sample at a specific sampling point. + * 0x80 indicates no valid sample available. + */ + int8_t *q_samples; + } connless_iq_report; + + /** + * Represents a connection iq report. + * Valid for the following event types: + * o BLE_GAP_EVENT_CONN_IQ_RPT + */ + struct { + /** Connection handle identifying the connection. */ + uint16_t conn_handle; + + /** PHY used for receiving the packet. + * 0x01: LE 1M PHY + * 0x02: LE 2M PHY + */ + uint8_t rx_phy; + + /** The index of the data channel on which the packet was received. */ + uint8_t data_channel_index; + + /** RSSI of the packet. + * Range: -1270 to +200 (Units: 0.1 dBm). + */ + int16_t rssi; + + /** Antenna ID used for receiving the packet. */ + uint8_t rssi_antenna_id; + + /** Type of Constant Tone Extension (CTE). + * 0x00: AoA Constant Tone Extension + * 0x01: AoD Constant Tone Extension with 1 μs slots + * 0x02: AoD Constant Tone Extension with 2 μs slots + */ + uint8_t cte_type; + + /** Switching and sampling slot durations. + * 0x01: Switching and sampling slots are 1 μs each + * 0x02: Switching and sampling slots are 2 μs each + */ + uint8_t slot_durations; + + /** Status of the packet. + * 0x00: CRC was correct + * 0x01: CRC was incorrect, but Length and CTETime fields were used to determine sampling points + * 0x02: CRC was incorrect, but the Controller determined the position and length of the CTE in another way + * 0xFF: Insufficient resources to sample (Channel_Index, CTE_Type, and Slot_Durations invalid) + */ + uint8_t packet_status; + + /** Value of the connection event counter for the reported packet. */ + uint16_t conn_event_counter; + + /** Total number of sample pairs (I and Q samples). + * 0x00: No samples provided (only permitted if Packet_Status is 0xFF) + * 0x09 to 0x52: Total number of sample pairs + */ + uint8_t sample_count; + + /** Array of I samples for the reported packet (signed integers). + * Each value represents an I sample at a specific sampling point. + * 0x80 indicates no valid sample available. + */ + int8_t *i_samples; + + /** Array of Q samples for the reported packet (signed integers). + * Each value represents a Q sample at a specific sampling point. + * 0x80 indicates no valid sample available. + */ + int8_t *q_samples; + } conn_iq_report; + + /** + * Represents a cte req failed event + * Valid for the following event types: + * o BLE_GAP_EVENT_CTE_REQ_FAILED + */ + struct { + /** Status indicating the reason for failure. + * Refer to HCI error codes for detailed status values. + */ + uint8_t status; + + /** Connection handle identifying the connection. */ + uint16_t conn_handle; + } cte_req_fail; + +#endif }; }; @@ -1605,6 +1989,14 @@ struct ble_gap_ext_adv_params { /** Advertising Set ID */ uint8_t sid; + +#if MYNEWT_VAL(BLE_EXT_ADV_V2) + /** Primary PHY options */ + uint8_t primary_phy_opt; + + /** Secondary PHY options */ + uint8_t secondary_phy_opt; +#endif }; /** @@ -1738,6 +2130,34 @@ struct ble_gap_periodic_adv_params { * defaults */ uint16_t itvl_max; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + /** Number of subevents + * If zero, the periodic advertiser will be a broadcaster, without responses. + */ + uint8_t num_subevents; + + /** Interval between subevents (N * 1.25 ms) + * Shall be between 7.5ms and 318.75 ms. + */ + uint8_t subevent_interval; + + /** Time between the advertising packet in a subevent and the + * first response slot (N * 1.25 ms) + * + */ + uint8_t response_slot_delay; + + /** Time between response slots (N * 0.125 ms) + * Shall be between 0.25 and 31.875 ms. + */ + uint8_t response_slot_spacing; + + /** Number of subevent response slots + * If zero, response_slot_delay and response_slot_spacing are ignored. + */ + uint8_t num_response_slots; +#endif /* PERIODIC_ADV_WITH_RESPONSES */ }; #if MYNEWT_VAL(BLE_PERIODIC_ADV_ENH) @@ -1779,8 +2199,108 @@ struct ble_gap_periodic_sync_params { created */ unsigned int filter_duplicates:1; #endif +#if MYNEWT_VAL(BLE_AOA_AOD) + /** + * Specifies the type of Constant Tone Extension (CTE) to which the receiver should not synchronize. + * This parameter determines which types of packets with specific CTE configurations are ignored during synchronization. + * + * Possible values: + * 0: Do not sync to packets with an AoA Constant Tone Extension. + * 1: Do not sync to packets with an AoD Constant Tone Extension with 1 μs slots. + * 2: Do not sync to packets with an AoD Constant Tone Extension with 2 μs slots. + * 3: Do not sync to packets with a type 3 Constant Tone Extension (currently reserved for future use). + * 4: Do not sync to packets without a Constant Tone Extension. + */ + uint8_t sync_cte_type; +#endif }; + +#if MYNEWT_VAL(BLE_AOA_AOD) +#define BLE_GAP_CTE_TYPE_AOA 0x0 +#define BLE_GAP_CTE_TYPE_AOD_1US 0x1 +#define BLE_GAP_CTE_TYPE_AOD_2US 0x2 + +#define BLE_GAP_CTE_RSP_ALLOW_AOA_MASK BLE_HCI_CTE_RSP_ALLOW_AOA_MASK +#define BLE_GAP_CTE_RSP_ALLOW_AOD_1US_MASK BLE_HCI_CTE_RSP_ALLOW_AOD_1US_MASK +#define BLE_GAP_CTE_RSP_ALLOW_AOD_2US_MASK BLE_HCI_CTE_RSP_ALLOW_AOD_2US_MASK + + +/** @brief Periodic advertising parameters */ +struct ble_gap_periodic_adv_cte_params { + /** + * Constant Tone Extension length in 8 µs units (Range: 0x02 to 0x14) + */ + uint8_t cte_length; + + /** + * Constant Tone Extension type + * 0x00 : AoA Constant Tone Extension + * 0x01 : AoD Constant Tone Extension with 1 µs slots + * 0x02 : AoD Constant Tone Extension with 2 µs slots + */ + uint8_t cte_type; + + /** + * The number of Constant Tone Extensions to transmit in each periodic + * advertising interval (Range: 0x01 to 0x10) + */ + uint8_t cte_count; + + /** + * The number of Antenna IDs in the pattern + * (Range: 0x02 to 0x4B) + */ + uint8_t switching_pattern_length; + + /** + * Antenna ID in the pattern. + * there is a pattern pointer + */ + uint8_t* antenna_ids; + +}; + +struct ble_gap_cte_sampling_params { + /** + * The sampling rate used by the Controller + * 0x01 : Switching and sampling slots are 1 μs each + * 0x02 : Switching and sampling slots are 2 μs each + */ + uint8_t slot_durations; + + /** + * The number of Antenna IDs in the pattern + * (Range: 0x02 to 0x4B) + */ + uint8_t switching_pattern_length; + + /** + * Antenna ID in the pattern. + * there is a pattern pointer + */ + uint8_t* antenna_ids; + +}; + +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +struct ble_gap_set_periodic_adv_subev_data_params { + /** The subevent to set data for */ + uint8_t subevent; + + /** The first response slot to listen to */ + uint8_t response_slot_start; + + /** The number of response slots to listen to */ + uint8_t response_slot_count; + + /** The data to send */ + struct os_mbuf *data; +}; +#endif + /** * Configure periodic advertising for specified advertising instance * @@ -2023,6 +2543,122 @@ int ble_gap_clear_periodic_adv_list(void); * @return 0 on success; nonzero on failure. */ int ble_gap_read_periodic_adv_list_size(uint8_t *per_adv_list_size); + + + +#if MYNEWT_VAL(BLE_AOA_AOD) + +/** + * Set connectionless Constant Tone Extension (CTE) transmission parameters. + * + * @param instance Periodic advertising instance ID. + * @param params Pointer to the CTE transmission parameters. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_connless_cte_transmit_params(uint8_t instance, + const struct ble_gap_periodic_adv_cte_params *params); + +/** + * Enable or disable connectionless CTE transmission. + * + * @param instance Periodic advertising instance ID. + * @param cte_enable 0x00 to disable, 0x01 to enable CTE transmission. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_connless_cte_transmit_enable(uint8_t instance, uint8_t cte_enable); + +/** + * Enable or disable connectionless IQ sampling for periodic advertising. + * + * @param sync_handle Sync handle identifying the periodic advertiser. + * @param sampling_enable 0x00 to disable, 0x01 to enable IQ sampling. + * @param max_sampled_ctes Maximum number of sampled CTEs. + * @param cte_sampling_params Pointer to the CTE sampling parameters. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_connless_iq_sampling_enable(uint16_t sync_handle, uint8_t sampling_enable, + uint8_t max_sampled_ctes, + const struct ble_gap_cte_sampling_params *cte_sampling_params); + +/** + * Set connection CTE receive parameters. + * + * @param conn_handle Connection handle. + * @param sampling_enable 0x00 to disable, 0x01 to enable CTE sampling. + * @param cte_sampling_params Pointer to the CTE sampling parameters. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_conn_cte_recv_param(uint16_t conn_handle, uint8_t sampling_enable, + const struct ble_gap_cte_sampling_params *cte_sampling_params); + +/** + * Set connection CTE transmission parameters. + * + * @param conn_handle Connection handle. + * @param cte_types Bitfield specifying supported CTE types. + * @param switching_pattern_len Length of the antenna switching pattern. + * @param antenna_ids Pointer to the array of antenna IDs. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_conn_cte_transmit_param(uint16_t conn_handle, uint8_t cte_types, + uint8_t switching_pattern_len, const uint8_t *antenna_ids); + +/** + * Enable or disable connection CTE request. + * + * @param conn_handle Connection handle. + * @param enable 0x00 to disable, 0x01 to enable CTE request. + * @param cte_request_interval Interval between CTE requests in connection interval. + * @param requested_cte_length Requested CTE length in 8 µs units. + * @param requested_cte_type Requested CTE type. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_conn_cte_req_enable(uint16_t conn_handle, uint8_t enable, uint16_t cte_request_interval, + uint8_t requested_cte_length, uint8_t requested_cte_type); + +/** + * Enable or disable connection CTE response. + * + * @param conn_handle Connection handle. + * @param enable 0x00 to disable, 0x01 to enable CTE response. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_conn_cte_rsp_enable(uint16_t conn_handle, uint8_t enable); + +/** + * Read antenna information. + * + * @param switch_sampling_rates On success, stores the supported switching and sampling rates. + * @param num_antennae On success, stores the number of antennae. + * @param max_switch_pattern_len On success, stores the maximum switching pattern length. + * @param max_cte_len On success, stores the maximum CTE length. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_read_antenna_information(uint8_t *switch_sampling_rates, uint8_t *num_antennae, + uint8_t *max_switch_pattern_len, uint8_t *max_cte_len); + +#endif // MYNEWT_VAL(BLE_AOA_AOD) + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +int +ble_gap_set_periodic_adv_subev_data(uint8_t instance, uint8_t num_subevents, + const struct ble_gap_set_periodic_adv_subev_data_params *params); + +int ble_gap_periodic_adv_set_response_data(uint16_t sync_handle, + struct ble_gap_periodic_adv_response_params *param, + struct os_mbuf *data); + +int ble_gap_periodic_adv_sync_subev(uint16_t sync_handle, uint8_t include_tx_power, + uint8_t num_subevents, uint8_t *subevents); +#endif #endif @@ -2178,6 +2814,71 @@ int ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, const struct ble_gap_conn_params *params, ble_gap_event_fn *cb, void *cb_arg); +/** + * Initiates an Sync connect procedure for PAwR. + * + * @param own_addr_type The type of address the stack should use for + * itself during connection establishment. + * - BLE_OWN_ADDR_PUBLIC + * - BLE_OWN_ADDR_RANDOM + * - BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT + * - BLE_OWN_ADDR_RPA_RANDOM_DEFAULT + * @param advertising_handle The advertising_Handle identifying the periodic advertising train + * Range: 0x00 to 0xEF or 0xFF + * @param subevent The Subevent parameter is used to identify the subevent where a connection + request shall be initiated from a periodic advertising train. + The Advertising_Handle and Subevent parameters + shall be set to 0xFF if these + parameters are not used. + * @param peer_addr The address of the peer to connect to. + * If this parameter is NULL, the white list + * is used. + * @param duration_ms The duration of the discovery procedure. + * On expiration, the procedure ends and a + * BLE_GAP_EVENT_DISC_COMPLETE event is + * reported. Units are milliseconds. + * @param phy_mask Define on which PHYs connection attempt should + * be done + * @param phy_1m_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_1M_MASK is set in phy_mask + * this parameter can be specify to null for + * default values. + * @param phy_2m_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_2M_MASK is set in phy_mask + * this parameter can be specify to null for + * default values. + * @param phy_coded_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_CODED_MASK is set in + * phy_mask this parameter can be specify to + * null for default values. + * @param cb The callback to associate with this connect + * procedure. When the connect procedure + * completes, the result is reported through + * this callback. If the connect procedure + * succeeds, the connection inherits this + * callback as its event-reporting mechanism. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; + * BLE_HS_EALREADY if a connection attempt is + * already in progress; + * BLE_HS_EBUSY if initiating a connection is not + * possible because scanning is in progress; + * BLE_HS_EDONE if the specified peer is already + * connected; + * Other nonzero on error. + */ +int ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle, + uint8_t subevent, const ble_addr_t *peer_addr, + int32_t duration_ms, uint8_t phy_mask, + const struct ble_gap_conn_params *phy_1m_conn_params, + const struct ble_gap_conn_params *phy_2m_conn_params, + const struct ble_gap_conn_params *phy_coded_conn_params, + ble_gap_event_fn *cb, void *cb_arg); /** * Initiates an extended connect procedure. * @@ -2862,6 +3563,35 @@ int ble_gap_dtm_enh_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t pay */ int ble_gap_dtm_enh_rx_start(uint8_t rx_chan, uint8_t index, uint8_t phy); +/** + * Set Read Remote Version Information is used to retrieve the version, manufacturer, + * and subversion information of remote controller after connection established + * + * @param conn_handle Connection handle + * @param version Defines the specification version of the LE Controller + * @param manufacturer Indicates the manufacturer of the remote Controller + * @param subversion Manufacturer specific version + + * @return 0 on success; nonzero on failure +*/ + +int ble_gap_read_rem_ver_info(uint16_t conn_handle, uint8_t *version, uint16_t *manufacturer, uint16_t *subversion); + +/** + * Read local resolvable address command + * + * @param peer_addr_type Peer Identity Address type + * + * @param peer_addr Peer Identity Address + * + * @param out_addr Local Resolvable Address received from controller. + * + * @return 0 on success; nonzero on failure + */ + +int ble_gap_rd_local_resolv_addr(uint8_t peer_addr_type, const ble_addr_t *peer_addr, + uint8_t *out_addr); + #ifdef __cplusplus } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gatt.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gatt.h index c2facf29..8ad0cba5 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gatt.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_gatt.h @@ -28,6 +28,7 @@ */ #include +#include "nimble/ble.h" #include "host/ble_att.h" #include "host/ble_uuid.h" #include "host/ble_esp_gatt.h" @@ -188,7 +189,7 @@ struct ble_hs_cfg; #define BLE_GATT_SVC_TYPE_SECONDARY 2 /** @} */ -/** +/** * Client Presentation Format * GATT Format Types * Ref: Assigned Numbers Specification @@ -386,6 +387,16 @@ struct ble_hs_cfg; #define BLE_GATT_CHR_BT_SIG_DESC_INTERNAL 0x010F #define BLE_GATT_CHR_BT_SIG_DESC_EXTERNAL 0x0110 +/*** @server. */ +/** Represents one notification tuple in a multi notification PDU */ +struct ble_gatt_notif { + /** The attribute handle on which to notify. */ + uint16_t handle; + + /** The notification value. */ + struct os_mbuf * value; +}; + /*** @client. */ /** Represents a GATT error. */ struct ble_gatt_error { @@ -408,6 +419,22 @@ struct ble_gatt_svc { ble_uuid_any_t uuid; }; +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) +/** Represents a GATT Service. */ +struct ble_gatt_incl_svc { + /** The handle of the GATT include service. */ + uint16_t handle; + + /** The start handle of the GATT include service. */ + uint16_t start_handle; + + /** The end handle of the GATT include service. */ + uint16_t end_handle; + + /** The UUID of the GATT service. */ + ble_uuid_any_t uuid; +}; +#endif /** Represents a GATT attribute. */ struct ble_gatt_attr { @@ -458,6 +485,12 @@ typedef int ble_gatt_disc_svc_fn(uint16_t conn_handle, const struct ble_gatt_svc *service, void *arg); +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) +typedef int ble_gatt_disc_incl_svc_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_incl_svc *incl_svc, + void *arg); +#endif /** * The host will free the attribute mbuf automatically after the callback is * executed. The application can take ownership of the mbuf and prevent it @@ -561,10 +594,15 @@ int ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid, * * @return 0 on success; nonzero on failure. */ +#if MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +int ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, + ble_gatt_disc_incl_svc_fn *cb, void *cb_arg); +#else int ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, ble_gatt_disc_svc_fn *cb, void *cb_arg); - +#endif /** * Initiates GATT procedure: Discover All Characteristics of a Service. * @@ -851,6 +889,33 @@ int ble_gattc_write_reliable(uint16_t conn_handle, int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle, struct os_mbuf *om); +/** + * Sends a "free-form" multiple handle variable length characteristic + * notification. This function consumes supplied mbufs regardless of the + * outcome. Notifications are sent in order of supplied entries. + * Function tries to send minimum amount of PDUs. If PDU can't contain all + * of the characteristic values, multiple notifications are sent. If only one + * handle-value pair fits into PDU, or only one characteristic remains in the + * list, regular characteristic notification is sent. + * + * If GATT client doesn't support receiving multiple handle notifications, + * this will use GATT notification for each characteristic, separately. + * + * If value of characteristic is not specified it will be read from local + * GATT database. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_count Number of characteristics to notify about. + * @param tuples Handle-value pairs in form of `ble_gatt_notif` + * structures. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gatts_notify_multiple_custom(uint16_t conn_handle, + size_t chr_count, + struct ble_gatt_notif *tuples); + /** * Deprecated. Should not be used. Use ble_gatts_notify_custom instead. */ @@ -917,6 +982,8 @@ int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle); */ int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle); +void ble_gattc_cache_conn_undisc_all(ble_addr_t peer_addr); + /** Initialize the BLE GATT client. */ int ble_gattc_init(void); @@ -1102,6 +1169,12 @@ struct ble_gatt_access_ctxt { */ const struct ble_gatt_dsc_def *dsc; }; + + /** + * An offset in case of BLE_ATT_OP_READ_BLOB_REQ. + * If the value is greater than zero it's an indication of a long attribute read. + */ + uint16_t offset; }; /** @@ -1210,7 +1283,7 @@ STAILQ_HEAD(ble_gatts_clt_cfg_list, ble_gatts_clt_cfg); * BLE_HS_ENOMEM on heap exhaustion. */ int ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs); - +void ble_gatts_free_svcs(void); #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) /** * Adds a set of services for registration. All services added @@ -1339,6 +1412,14 @@ typedef void (*ble_gatt_svc_foreach_fn)(const struct ble_gatt_svc_def *svc, */ void ble_gatts_show_local(void); +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) +/** + * Calculates and returns the maximum + * Security Mode 1 Level requirement. + */ +uint8_t ble_gatts_security_mode_1_level(void); +#endif + /** * Resets the GATT server to its initial state. On success, this function * removes all supported services, characteristics, and descriptors. This diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs.h index 4eba4b44..79718b40 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs.h @@ -315,18 +315,49 @@ struct ble_hs_cfg { */ unsigned sm_sc:1; + /** @brief Security Manager - Enable/Disable Secure Connections Only flag + * + * If set, this will enforce P-256 elliptic curve encryption algorithm + * during pairing. + * It will force the max key size to be used during pairing. + */ + unsigned sm_sc_only:1; + + /** @brief Security Manager - Security Mode 1 Level for GATT related operations + * + * Possible values are: + * 0: Default value, ignored + * 1: No security + * 2: Unauthenticated pairing with encryption + * 3. Authenticated pairing with encryption + * 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key + */ + uint8_t sm_sec_lvl; + /** @brief Security Manager Key Press Notification flag * * Currently unsupported and should not be set. */ unsigned sm_keypress:1; + /** @brief Enable/Disable Enhanced ATT Support + * + * Primarily used to enable EATT behaviour; denotes the number of eatt + * channels. Set to 0 to disable eatt. + * + * Default value is CONFIG_BT_NIMBLE_EATT_CHAN_NUM. + */ + uint8_t eatt; + /** @brief Security Manager Local Key Distribution Mask */ uint8_t sm_our_key_dist; /** @brief Security Manager Remote Key Distribution Mask */ uint8_t sm_their_key_dist; + /** @brief Weather to use GATT caching or not for discovery operations */ + uint8_t gatt_use_cache; + /** @brief Stack reset callback * * This callback is executed when the host resets itself and the controller diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_adv.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_adv.h index 8d5e26a3..5d2ca2a6 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_adv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_adv.h @@ -22,6 +22,7 @@ #include #include "host/ble_uuid.h" +#include "syscfg/syscfg.h" #ifdef __cplusplus extern "C" { @@ -32,6 +33,8 @@ extern "C" { /** Max field payload size (account for 2-byte header). */ #define BLE_HS_ADV_MAX_FIELD_SZ (BLE_HS_ADV_MAX_SZ - 2) +#define BLE_HS_ADV_LE_SUPP_FEAT_LEN 6 + struct ble_hs_adv_field { uint8_t length; uint8_t type; @@ -113,7 +116,7 @@ struct ble_hs_adv_fields { unsigned device_addr_type; unsigned device_addr_is_present:1; - /*** 0xF1 - 32-bit service solicitation UUIDs */ + /*** 0x1f - 32-bit service solicitation UUIDs */ const ble_uuid32_t *sol_uuids32; uint8_t sol_num_uuids32; @@ -133,6 +136,21 @@ struct ble_hs_adv_fields { const uint8_t *uri; uint8_t uri_len; + /*** 0x27 - LE Supported Features. */ + /*** Core Spec v5.4 Vol. 6 Part B 4.6 */ + uint8_t le_supp_feat[BLE_HS_ADV_LE_SUPP_FEAT_LEN]; + unsigned le_supp_feat_is_present; + + /*** 0x2f - Advertising interval - long. */ + uint32_t adv_itvl_long; + unsigned adv_itvl_long_is_present:1; + +#if MYNEWT_VAL(ENC_ADV_DATA) + /*** 0x31 - Encrypted Advertising Data. */ + const uint8_t *enc_adv_data; + uint8_t enc_adv_data_len; +#endif + /*** 0xff - Manufacturer specific data. */ const uint8_t *mfg_data; uint8_t mfg_data_len; @@ -164,9 +182,12 @@ struct ble_hs_adv_fields { #define BLE_HS_ADV_TYPE_SVC_DATA_UUID32 0x20 #define BLE_HS_ADV_TYPE_SVC_DATA_UUID128 0x21 #define BLE_HS_ADV_TYPE_URI 0x24 +#define BLE_HS_ADV_TYPE_LE_SUPP_FEAT 0x27 #define BLE_HS_ADV_TYPE_MESH_PROV 0x29 #define BLE_HS_ADV_TYPE_MESH_MESSAGE 0x2a #define BLE_HS_ADV_TYPE_MESH_BEACON 0x2b +#define BLE_HS_ADV_TYPE_ADV_ITVL_LONG 0x2f +#define BLE_HS_ADV_TYPE_ENC_ADV_DATA 0x31 #define BLE_HS_ADV_TYPE_MFG_DATA 0xff #define BLE_HS_ADV_FLAGS_LEN 1 @@ -198,6 +219,8 @@ struct ble_hs_adv_fields { #define BLE_HS_ADV_ADDR_TYPE_LEN 1 +#define BLE_HS_ADV_ADV_ITVL_LONG_LEN 4 + int ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields, struct os_mbuf *om); @@ -210,6 +233,9 @@ int ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, int ble_hs_adv_parse(const uint8_t *data, uint8_t length, ble_hs_adv_parse_func_t func, void *user_data); +int ble_hs_adv_find_field(uint8_t type, const uint8_t *data, uint8_t length, + const struct ble_hs_adv_field **out); + #ifdef __cplusplus } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_pvcy.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_pvcy.h index 0e2fefca..1769b8f7 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_pvcy.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_pvcy.h @@ -69,7 +69,7 @@ void ble_hs_resolv_deinit(void); #endif int ble_hs_pvcy_set_resolve_enabled(int enable); -void ble_hs_set_rpa_timeout(uint16_t timeout); +int ble_hs_set_rpa_timeout(uint16_t timeout); #ifdef __cplusplus } diff --git a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_store.h b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_store.h index 732f4ff0..814bdcb8 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_store.h +++ b/lib/bt/host/nimble/nimble/nimble/host/include/host/ble_store.h @@ -38,6 +38,7 @@ extern "C" { #define BLE_STORE_OBJ_TYPE_PEER_ADDR 6 #define BLE_STORE_OBJ_TYPE_LOCAL_IRK 7 +#define BLE_STORE_OBJ_TYPE_CSFC 8 /** Failed to persist record; insufficient storage capacity. */ #define BLE_STORE_EVENT_OVERFLOW 1 @@ -121,6 +122,29 @@ struct ble_store_value_cccd { unsigned value_changed:1; }; +/** + * Used as a key for lookups of stored client supported features characteristic (CSFC). + * This struct corresponds to the BLE_STORE_OBJ_TYPE_CSFC store object type. + */ +struct ble_store_key_csfc { + /** + * Key by peer identity address; + */ + ble_addr_t peer_addr; + + /** Number of results to skip; 0 means retrieve the first match. */ + uint8_t idx; +}; + +/** + * Represents a stored client supported features characteristic (CSFC). + * This struct corresponds to the BLE_STORE_OBJ_TYPE_CSFC store object type. + */ +struct ble_store_value_csfc { + ble_addr_t peer_addr; + uint8_t csfc[MYNEWT_VAL(BLE_GATT_CSFC_SIZE)]; +}; + #if MYNEWT_VAL(ENC_ADV_DATA) /** * Used as a key for lookups of encrypted advertising data. This struct corresponds @@ -181,6 +205,7 @@ union ble_store_key { #endif struct ble_store_key_rpa_rec rpa_rec; struct ble_store_key_local_irk local_irk; + struct ble_store_key_csfc csfc; }; /** @@ -195,6 +220,7 @@ union ble_store_value { #endif struct ble_store_value_rpa_rec rpa_rec; struct ble_store_value_local_irk local_irk; + struct ble_store_value_csfc csfc; }; struct ble_store_status_event { @@ -361,10 +387,18 @@ int ble_store_read_cccd(const struct ble_store_key_cccd *key, int ble_store_write_cccd(const struct ble_store_value_cccd *value); int ble_store_delete_cccd(const struct ble_store_key_cccd *key); +int ble_store_read_csfc(const struct ble_store_key_csfc *key, + struct ble_store_value_csfc *out_value); +int ble_store_write_csfc(const struct ble_store_value_csfc *value); +int ble_store_delete_csfc(const struct ble_store_key_csfc *key); + void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, const struct ble_store_value_sec *value); void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, const struct ble_store_value_cccd *value); +void ble_store_key_from_value_csfc(struct ble_store_key_csfc *out_key, + const struct ble_store_value_csfc *value); + #if MYNEWT_VAL(ENC_ADV_DATA) int ble_store_read_ead(const struct ble_store_key_ead *key, struct ble_store_value_ead *out_value); diff --git a/lib/bt/host/nimble/nimble/nimble/host/mesh/src/adv.c b/lib/bt/host/nimble/nimble/nimble/host/mesh/src/adv.c index d6ed29f3..4b8d732e 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/mesh/src/adv.c +++ b/lib/bt/host/nimble/nimble/nimble/host/mesh/src/adv.c @@ -217,7 +217,7 @@ int bt_mesh_scan_enable(void) #if MYNEWT_VAL(BLE_EXT_ADV) struct ble_gap_ext_disc_params uncoded_params = { .itvl = MESH_SCAN_INTERVAL, .window = MESH_SCAN_WINDOW, - .passive = 1 }; + .passive = 1, .disable_observer_mode = 0}; BT_DBG(""); diff --git a/lib/bt/host/nimble/nimble/nimble/host/mesh/src/pb_adv.c b/lib/bt/host/nimble/nimble/nimble/host/mesh/src/pb_adv.c index 35a02b0d..8225c063 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/mesh/src/pb_adv.c +++ b/lib/bt/host/nimble/nimble/nimble/host/mesh/src/pb_adv.c @@ -30,6 +30,7 @@ #define START_PAYLOAD_MAX 20 #define CONT_PAYLOAD_MAX 23 +#define RX_BUFFER_MAX 65 #define START_LAST_SEG(gpc) (gpc >> 2) #define CONT_SEG_INDEX(gpc) (gpc >> 2) @@ -39,7 +40,8 @@ #define LINK_ACK 0x01 #define LINK_CLOSE 0x02 -#define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[20 + ((_seg - 1) * 23)]) +#define XACT_SEG_OFFSET(_seg) (20 + ((_seg - 1) * 23)) +#define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[XACT_SEG_OFFSET(_seg)]) #define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg))) #define XACT_ID_MAX 0x7f @@ -222,7 +224,7 @@ static void reset_adv_link(void) } link.tx.pending_ack = XACT_ID_NVAL; if (!rx_buf) { - rx_buf = NET_BUF_SIMPLE(65); + rx_buf = NET_BUF_SIMPLE(RX_BUFFER_MAX); } link.rx.buf = rx_buf; net_buf_simple_reset(link.rx.buf); @@ -386,6 +388,11 @@ static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf) return; } + if (XACT_SEG_OFFSET(seg) + buf->om_len > RX_BUFFER_MAX) { + BT_WARN("Rx buffer overflow. Malformed generic prov frame?"); + return; + } + memcpy(XACT_SEG_DATA(seg), buf->om_data, buf->om_len); XACT_SEG_RECV(seg); @@ -890,7 +897,7 @@ void pb_adv_init(void) k_work_init_delayable(&link.tx.retransmit, prov_retransmit); if (!rx_buf) { - rx_buf = NET_BUF_SIMPLE(65); + rx_buf = NET_BUF_SIMPLE(RX_BUFFER_MAX); } link.rx.buf = rx_buf; net_buf_simple_reset(link.rx.buf); diff --git a/lib/bt/host/nimble/nimble/nimble/host/mesh/src/prov_device.c b/lib/bt/host/nimble/nimble/nimble/host/mesh/src/prov_device.c index 01b1eac3..64b0bb30 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/mesh/src/prov_device.c +++ b/lib/bt/host/nimble/nimble/nimble/host/mesh/src/prov_device.c @@ -303,11 +303,11 @@ static void prov_dh_key_gen(void) #if !CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS if (MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { - if (uECC_valid_public_key(remote_pk, &curve_secp256r1)) { + if (uECC_valid_public_key(remote_pk, uECC_secp256r1())) { BT_ERR("Public key is not valid"); } else if (uECC_shared_secret(remote_pk, bt_mesh_prov->private_key_be, bt_mesh_prov_link.dhkey, - &curve_secp256r1) != TC_CRYPTO_SUCCESS) { + uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { BT_ERR("DHKey generation failed"); } else { dh_key_gen_complete(); diff --git a/lib/bt/host/nimble/nimble/nimble/host/pkg.yml b/lib/bt/host/nimble/nimble/nimble/host/pkg.yml index c069283c..cab496ca 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/pkg.yml +++ b/lib/bt/host/nimble/nimble/nimble/host/pkg.yml @@ -41,6 +41,9 @@ pkg.deps.BLE_SM_SC: pkg.deps.BLE_MESH: - nimble/host/mesh +pkg.deps.BLE_EATT_CHAN_NUM: + - nimble/host/services/gatt + pkg.req_apis: - ble_transport - console diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/ans/include/services/ans/ble_svc_ans.h b/lib/bt/host/nimble/nimble/nimble/host/services/ans/include/services/ans/ble_svc_ans.h index 435e9e11..1a5ce0a4 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/ans/include/services/ans/ble_svc_ans.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/ans/include/services/ans/ble_svc_ans.h @@ -20,6 +20,10 @@ #ifndef H_BLE_SVC_ANS_ #define H_BLE_SVC_ANS_ +#ifdef __cplusplus +extern "C" { +#endif + struct ble_hs_cfg; /* 16 Bit Alert Notification Service UUID */ @@ -81,5 +85,8 @@ int ble_svc_ans_unr_alert_add(uint8_t cat_id); void ble_svc_ans_init(void); +#ifdef __cplusplus +} #endif +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c b/lib/bt/host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c index edaf7f3c..0b02b9a9 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c @@ -26,6 +26,7 @@ #include "host/ble_gap.h" #include "services/ans/ble_svc_ans.h" +#if MYNEWT_VAL(BLE_GATTS) /* Max length of new alert info string */ #define BLE_SVC_ANS_INFO_STR_MAX_LEN 18 /* Max length of a new alert notification, max string length + 2 bytes @@ -390,8 +391,12 @@ ble_svc_ans_new_alert_notify(uint8_t cat_id, const char * info_str) memcpy(&ble_svc_ans_new_alert_val[2], info_str, info_str_len); } } +#if NIMBLE_BLE_CONNECT return ble_gatts_notify(ble_svc_ans_conn_handle, ble_svc_ans_new_alert_val_handle); +#else + return 0; +#endif } /** @@ -407,8 +412,12 @@ ble_svc_ans_unr_alert_notify(uint8_t cat_id) { ble_svc_ans_unr_alert_stat[0] = cat_id; ble_svc_ans_unr_alert_stat[1] = ble_svc_ans_unr_alert_cnt[cat_id]; +#if NIMBLE_BLE_CONNECT return ble_gatts_notify(ble_svc_ans_conn_handle, ble_svc_ans_unr_alert_val_handle); +#else + return 0; +#endif } /** @@ -462,3 +471,4 @@ ble_svc_ans_init(void) ble_svc_ans_new_alert_cat = MYNEWT_VAL(BLE_SVC_ANS_NEW_ALERT_CAT); ble_svc_ans_unr_alert_cat = MYNEWT_VAL(BLE_SVC_ANS_UNR_ALERT_CAT); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/bas/include/services/bas/ble_svc_bas.h b/lib/bt/host/nimble/nimble/nimble/host/services/bas/include/services/bas/ble_svc_bas.h index 24b9a26c..88675b40 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/bas/include/services/bas/ble_svc_bas.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/bas/include/services/bas/ble_svc_bas.h @@ -20,6 +20,10 @@ #ifndef H_BLE_SVC_BAS_ #define H_BLE_SVC_BAS_ +#ifdef __cplusplus +extern "C" { +#endif + /* 16 Bit Battery Service UUID */ #define BLE_SVC_BAS_UUID16 0x180F @@ -30,4 +34,8 @@ int ble_svc_bas_battery_level_set(uint8_t level); void ble_svc_bas_init(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c b/lib/bt/host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c index 631519cf..468e433b 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c @@ -26,6 +26,7 @@ #include "host/ble_gap.h" #include "services/bas/ble_svc_bas.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_BAS_SERVICE /* Characteristic value handles */ #if MYNEWT_VAL(BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE) > 0 static uint16_t ble_svc_bas_battery_handle; @@ -125,3 +126,4 @@ ble_svc_bas_init(void) rc = ble_gatts_add_svcs(ble_svc_bas_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/bleuart/src/bleuart.c b/lib/bt/host/nimble/nimble/nimble/host/services/bleuart/src/bleuart.c index 866595ed..0b4f107b 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/bleuart/src/bleuart.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/bleuart/src/bleuart.c @@ -30,6 +30,7 @@ #include "console/console.h" #include "esp_nimble_mem.h" +#if MYNEWT_VAL(BLE_GATTS) /* ble uart attr read handle */ uint16_t g_bleuart_attr_read_handle; @@ -202,3 +203,4 @@ bleuart_init(void) console_buf = nimble_platform_mem_malloc(MYNEWT_VAL(BLEUART_MAX_INPUT)); SYSINIT_PANIC_ASSERT(console_buf != NULL); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/cte/include/services/cte/ble_svc_cte.h b/lib/bt/host/nimble/nimble/nimble/host/services/cte/include/services/cte/ble_svc_cte.h new file mode 100644 index 00000000..b32e650e --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/host/services/cte/include/services/cte/ble_svc_cte.h @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_SVC_CTE_ +#define H_BLE_SVC_CTE_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; + +#define BLE_SVC_CTE_UUID16 0x184A +#define BLE_SVC_CTE_CHR_UUID16_ENABLE 0x2BAD +#define BLE_SVC_CTE_CHR_UUID16_MINIMUM_LENGTH 0x2BAE +#define BLE_SVC_CTE_CHR_UUID16_MINIMUM_TRANSMIT_COUNT 0x2BAF +#define BLE_SVC_CTE_CHR_UUID16_TRANSMIT_DURATION 0x2BB0 +#define BLE_SVC_CTE_CHR_UUID16_INTERVAL 0x2BB1 +#define BLE_SVC_CTE_CHR_UUID16_PHY 0x2BB2 + + +void ble_svc_cte_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/cte/pkg.yml b/lib/bt/host/nimble/nimble/nimble/host/services/cte/pkg.yml new file mode 100644 index 00000000..4e656d3d --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/host/services/cte/pkg.yml @@ -0,0 +1,34 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: nimble/host/services/cte +pkg.description: Constant Tone Extension Service +pkg.author: "GengYuchao " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - cte + - nimble + +pkg.deps: + - nimble/host + +pkg.init: + ble_svc_cte_init: 'MYNEWT_VAL(BLE_SVC_CTE_SYSINIT_STAGE)' diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/cte/src/ble_svc_cte.c b/lib/bt/host/nimble/nimble/nimble/host/services/cte/src/ble_svc_cte.c new file mode 100644 index 00000000..6446fdde --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/host/services/cte/src/ble_svc_cte.c @@ -0,0 +1,573 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include "sysinit/sysinit.h" +#include "syscfg/syscfg.h" +#include "host/ble_hs.h" +#include "host/ble_gap.h" +#include "services/cte/ble_svc_cte.h" + +/* XXX: We shouldn't be including the host's private header files. The host + * API needs to be updated with a function to query the advertising transmit + * power. + */ +#include "../src/ble_hs_hci_priv.h" + +#if MYNEWT_VAL(BLE_AOA_AOD) + +// Define the size of characteristic values +#define CTE_ENABLE_CHAR_SIZE 1 +#define CTE_MIN_LENGTH_CHAR_SIZE 1 +#define CTE_MIN_TRANSMIT_COUNT_SIZE 1 +#define CTE_TRANSMIT_DURATION_SIZE 1 +#define CTE_INTERVAL_CHAR_SIZE 2 +#define CTE_PHY_CHAR_SIZE 1 + +// Constant Tone Extension Enable characteristic value range +#define CTE_ENABLE_MIN_VALUE 0x00 +#define CTE_ENABLE_MAX_VALUE 0x03 +// Define the constant tone extension enable bit control macros +#define CTE_ENABLE_AOA_CONNECTION (1 << 0) // Bit 0: Enable AoA Constant Tone Extension on ACL connection with client +#define CTE_ENABLE_AOD_ADVERTISING (1 << 1) // Bit 1: Enable AoD Constant Tone Extension in advertising packets + +#define CTETYPE_ALLOW_AOA_CTE_RESPONSE (1 << 0) +#define CTETYPE_ALLOW_AOD_1US_CTE_RESPONSE (1 << 1) +#define CTETYPE_ALLOW_AOD_2US_CTE_RESPONSE (1 << 2) +#define CTETYPE_MASK_ALL (0x7) // mask for the first three bits + +// Advertising Constant Tone Extension Minimum Length characteristic value range +#define CTE_MIN_LEN_MIN_VALUE 2 +#define CTE_MIN_LEN_MAX_VALUE 20 + +// Advertising Constant Tone Extension Minimum Transmit Count characteristic value range +#define CTE_MIN_TX_COUNT_MIN_VALUE 1 +#define CTE_MIN_TX_COUNT_MAX_VALUE 15 + +// Advertising Constant Tone Extension Transmit Duration characteristic value range +#define CTE_TX_DURATION_MIN_VALUE 0 +#define CTE_TX_DURATION_MAX_VALUE 255 + +// Advertising Constant Tone Extension Interval characteristic value range +#define CTE_INTERVAL_MIN_VALUE 0x0006 +#define CTE_INTERVAL_MAX_VALUE 0xFFFF + +// Advertising Constant Tone Extension PHY characteristic value range +#define CTE_PHY_MIN_VALUE 0x00 +#define CTE_PHY_MAX_VALUE 0x01 + +// SERVICE Error Code +#define SERVICE_ERROR_WRITE_REQUEST_REJECTED 0xFC +#define SERVICE_ERROR_OUT_OF_RANGE 0xFF + +/* Structure to store CTE settings per connection */ +typedef struct { + uint16_t conn_handle; + uint8_t cte_enable; + uint8_t cte_min_length; + uint8_t cte_min_transmit_count; + uint8_t cte_transmit_duration; + uint16_t cte_interval; + uint8_t cte_phy; +}cte_instance_config_t; + +/* Structure to store CTE settings per client */ +static cte_instance_config_t cte_config[MYNEWT_VAL(BLE_MAX_CONNECTIONS)]; + + +/** + * @brief Constant Tone Extensio Service UUID + */ +static const ble_uuid128_t cte_svc_uuid = + BLE_UUID128_INIT(0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x10, 0x00, 0x00, 0x4A, 0x18, 0x00, 0x00); + +static int ble_svc_cte_enable_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static int ble_svc_cte_adv_cte_min_length_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static int ble_svc_cte_adv_cte_min_transmit_count_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static int ble_svc_cte_adv_cte_transmit_duration_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static int ble_svc_cte_adv_cte_interval_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static int ble_svc_cte_adv_cte_phy_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); +/** + * @brief Constant Tone Extensio Service definition + */ +static const struct ble_gatt_svc_def ble_svc_cte_defs[] = { + { + /*** Service: Asset Tracking Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_UUID16), + .characteristics = (struct ble_gatt_chr_def[]) { + { + /*** Characteristic: Constant Tone Extension Enable. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_ENABLE), + .access_cb = ble_svc_cte_enable_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Minimum Length. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_MINIMUM_LENGTH), + .access_cb = ble_svc_cte_adv_cte_min_length_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Minimum Transmit Count. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_MINIMUM_TRANSMIT_COUNT), + .access_cb = ble_svc_cte_adv_cte_min_transmit_count_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Transmit Duration. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_TRANSMIT_DURATION), + .access_cb = ble_svc_cte_adv_cte_transmit_duration_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Interval. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_INTERVAL), + .access_cb = ble_svc_cte_adv_cte_interval_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension PHY. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_PHY), + .access_cb = ble_svc_cte_adv_cte_phy_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + 0, /* No more characteristics in this service. */ + } + }, + }, + + { + 0, /* No more services. */ + }, +}; + +/** + * Find the CTE configuration instance for the given connection handle. + * + * @param conn_handle The connection handle to search for. + * @return A pointer to the matching CTE configuration instance, or NULL if not found. + */ +static cte_instance_config_t* cte_find_config_by_conn_handle(uint16_t conn_handle) { + for (int i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { + if (cte_config[i].conn_handle == conn_handle) { + return &cte_config[i]; + } + } + return NULL; +} + +/**@}*/ + +/** + * Handles writing a one-octet (1 byte) characteristic value in a BLE service. + * + * This function is used to validate and write a characteristic value that is + * exactly 1 byte long. It performs length checks, range validation, and then + * updates the destination buffer with the new value if all validations pass. + * + * @param om The mbuf containing the data to be written. + * @param min_value The minimum allowed value for the characteristic. + * @param max_value The maximum allowed value for the characteristic. + * @param dst A pointer to the destination buffer where the validated + * value will be stored. + * @param len A pointer to store the length of the written value (optional). + * If provided, it will be set to 1 on success. + * + * @return 0 on success; BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN if the + * length of data in the mbuf does not match the expected + * one-octet length; BLE_ATT_ERR_UNLIKELY if an unexpected + * error occurs while flattening the mbuf; SERVICE_ERROR_OUT_OF_RANGE + * if the value is outside the allowed range. + */ +static int +ble_svc_cte_one_octet_chr_write(struct os_mbuf *om, + uint32_t min_value, uint32_t max_value, + void *dst, uint16_t *len) +{ + uint16_t om_len; + uint8_t target_len = 1; + uint8_t value = 0; + int rc; + + // Get the length of the data in the mbuf + om_len = OS_MBUF_PKTLEN(om); + + // Ensure the data length matches the expected target length + if (om_len != target_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + // Flatten the mbuf data into the value buffer + rc = ble_hs_mbuf_to_flat(om, &value, target_len, NULL); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + // Check if the value is within the allowed range + if (value < min_value || value > max_value) { + return SERVICE_ERROR_OUT_OF_RANGE; + } + + // Update the destination with the validated value + memcpy(dst, &value, target_len); + if (len != NULL) { + *len = target_len; + } + + return 0; +} + +/** + * Handles writing a two-octet (2 bytes) characteristic value in a BLE service. + * + * This function is used to validate and write a characteristic value that is + * exactly 2 bytes long. It performs length checks, range validation, and then + * updates the destination buffer with the new value if all validations pass. + * + * @param om The mbuf containing the data to be written. + * @param min_value The minimum allowed value for the characteristic. + * @param max_value The maximum allowed value for the characteristic. + * @param dst A pointer to the destination buffer where the validated + * value will be stored. + * @param len A pointer to store the length of the written value (optional). + * If provided, it will be set to 2 on success. + * + * @return 0 on success; BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN if the + * length of data in the mbuf does not match the expected + * two-octet length; BLE_ATT_ERR_UNLIKELY if an unexpected + * error occurs while flattening the mbuf; SERVICE_ERROR_OUT_OF_RANGE + * if the value is outside the allowed range. + */ +static int +ble_svc_cte_two_octet_chr_write(struct os_mbuf *om, + uint32_t min_value, uint32_t max_value, + void *dst, uint16_t *len) +{ + uint16_t om_len; + uint8_t target_len = 2; + uint16_t value = 0; + int rc; + + // Get the length of the data in the mbuf + om_len = OS_MBUF_PKTLEN(om); + + // Ensure the data length matches the expected target length + if (om_len != target_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + // Flatten the mbuf data into the value buffer + rc = ble_hs_mbuf_to_flat(om, &value, target_len, NULL); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + // Check if the value is within the allowed range + if (value < min_value || value > max_value) { + return SERVICE_ERROR_OUT_OF_RANGE; + } + + // Update the destination with the validated value + memcpy(dst, &value, target_len); + if (len != NULL) { + *len = target_len; + } + + return 0; +} + + +/** + * @brief Access callback for Constant Tone Extensio Service cte enable + * + * This function is called when a read or write operation is performed on the Constant Tone Extensio + * characteristic. It handles the read and write requests. + * + * @param conn_handle The connection handle + * @param attr_handle The attribute handle + * @param ctxt The GATT access context + * @param arg Unused argument + * + * @return 0 on success; non-zero error code otherwise + */ +static int ble_svc_cte_enable_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + int rc = BLE_ATT_ERR_UNLIKELY; + + // Find the CTE configuration instance for the given connection handle + cte_instance_config_t *config = cte_find_config_by_conn_handle(conn_handle); + + // Return an error if no matching configuration instance is found + if (config == NULL) { + return BLE_ATT_ERR_UNLIKELY; + } + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + // Handle read characteristic request + rc = os_mbuf_append(ctxt->om, &config->cte_enable, sizeof(config->cte_enable)) == 0 ? + 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + break; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + // Handle write characteristic request + rc = ble_svc_cte_one_octet_chr_write(ctxt->om, + CTE_ENABLE_MIN_VALUE, + CTE_ENABLE_MAX_VALUE, + &config->cte_enable, NULL); + + if (rc == 0) { + if((config->cte_enable & CTE_ENABLE_AOA_CONNECTION) == CTE_ENABLE_AOA_CONNECTION) { + if(ble_gap_set_conn_cte_transmit_param(conn_handle, BLE_GAP_CTE_RSP_ALLOW_AOA_MASK, 0, NULL) != 0) + { + rc = 0xFC; + break; + } + if(ble_gap_conn_cte_rsp_enable(conn_handle, true) != 0) { + rc = 0xFC; + break; + } + } + if((config->cte_enable & CTE_ENABLE_AOD_ADVERTISING) == CTE_ENABLE_AOD_ADVERTISING) { + // TODO: Add Start advertising with CTE + } + } + break; + + default: + break; + } + + return rc; +} + +static int ble_svc_cte_adv_cte_min_length_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + int rc = BLE_ATT_ERR_UNLIKELY; + // Find the CTE configuration instance for the given connection handle + cte_instance_config_t *config = cte_find_config_by_conn_handle(conn_handle); + + // Return an error if no matching configuration instance is found + if (config == NULL) { + return BLE_ATT_ERR_UNLIKELY; + } + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + // Handle read characteristic request + rc = os_mbuf_append(ctxt->om, &config->cte_min_length, sizeof(config->cte_min_length)) == 0 ? + 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + break; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + // Handle write characteristic request + rc = ble_svc_cte_one_octet_chr_write(ctxt->om, + CTE_MIN_LEN_MIN_VALUE, + CTE_MIN_LEN_MAX_VALUE, + &config->cte_min_length, NULL); + + break; + + default: + break; + } + + return rc; +} + +static int ble_svc_cte_adv_cte_min_transmit_count_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + int rc = BLE_ATT_ERR_UNLIKELY; + // Find the CTE configuration instance for the given connection handle + cte_instance_config_t *config = cte_find_config_by_conn_handle(conn_handle); + + // Return an error if no matching configuration instance is found + if (config == NULL) { + return BLE_ATT_ERR_UNLIKELY; + } + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + // Handle read characteristic request + rc = os_mbuf_append(ctxt->om, &config->cte_min_transmit_count, sizeof(config->cte_min_transmit_count)) == 0 ? + 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + break; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + // Handle write characteristic request + rc = ble_svc_cte_one_octet_chr_write(ctxt->om, + CTE_MIN_TX_COUNT_MIN_VALUE, + CTE_MIN_TX_COUNT_MAX_VALUE, + &config->cte_min_transmit_count, NULL); + + break; + + default: + break; + } + + return rc; +} + +static int ble_svc_cte_adv_cte_transmit_duration_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + int rc = BLE_ATT_ERR_UNLIKELY; + // Find the CTE configuration instance for the given connection handle + cte_instance_config_t *config = cte_find_config_by_conn_handle(conn_handle); + + // Return an error if no matching configuration instance is found + if (config == NULL) { + return BLE_ATT_ERR_UNLIKELY; + } + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + // Handle read characteristic request + rc = os_mbuf_append(ctxt->om, &config->cte_transmit_duration, sizeof(config->cte_transmit_duration)) == 0 ? + 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + break; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + // Handle write characteristic request + rc = ble_svc_cte_one_octet_chr_write(ctxt->om, + CTE_TX_DURATION_MIN_VALUE, + CTE_TX_DURATION_MAX_VALUE, + &config->cte_transmit_duration, NULL); + + break; + + default: + break; + } + + return rc; +} + +static int ble_svc_cte_adv_cte_interval_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + int rc = BLE_ATT_ERR_UNLIKELY; + // Find the CTE configuration instance for the given connection handle + cte_instance_config_t *config = cte_find_config_by_conn_handle(conn_handle); + + // Return an error if no matching configuration instance is found + if (config == NULL) { + return BLE_ATT_ERR_UNLIKELY; + } + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + // Handle read characteristic request + rc = os_mbuf_append(ctxt->om, &config->cte_interval, sizeof(config->cte_interval)) == 0 ? + 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + break; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + // Handle write characteristic request + rc = ble_svc_cte_two_octet_chr_write(ctxt->om, + CTE_INTERVAL_MIN_VALUE, + CTE_INTERVAL_MAX_VALUE, + &config->cte_interval, NULL); + + break; + + default: + break; + } + + return rc; +} + +static int ble_svc_cte_adv_cte_phy_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + int rc = BLE_ATT_ERR_UNLIKELY; + // Find the CTE configuration instance for the given connection handle + cte_instance_config_t *config = cte_find_config_by_conn_handle(conn_handle); + + // Return an error if no matching configuration instance is found + if (config == NULL) { + return BLE_ATT_ERR_UNLIKELY; + } + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + // Handle read characteristic request + rc = os_mbuf_append(ctxt->om, &config->cte_phy, sizeof(config->cte_phy)) == 0 ? + 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + break; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + // Handle write characteristic request + rc = ble_svc_cte_one_octet_chr_write(ctxt->om, + CTE_PHY_MIN_VALUE, + CTE_PHY_MAX_VALUE, + &config->cte_phy, NULL); + break; + + default: + break; + } + + return rc; +} + +static void cte_init_config(void) { + for (int i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { + cte_config[i].conn_handle = i; + cte_config[i].cte_enable = 0; + cte_config[i].cte_min_length = CTE_MIN_LEN_MIN_VALUE; + cte_config[i].cte_min_transmit_count = CTE_MIN_TX_COUNT_MIN_VALUE; + cte_config[i].cte_transmit_duration = CTE_TX_DURATION_MIN_VALUE; + cte_config[i].cte_interval = CTE_INTERVAL_MIN_VALUE; + cte_config[i].cte_phy = CTE_PHY_MIN_VALUE; + } +} + +/** + * @brief Initialize the Constant Tone Extensio Service + */ +void +ble_svc_cte_init(void) +{ + int rc; + cte_init_config(); + + rc = ble_gatts_count_cfg(ble_svc_cte_defs); + assert(rc == 0); + + rc = ble_gatts_add_svcs(ble_svc_cte_defs); + assert(rc == 0); + +} + +#endif \ No newline at end of file diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/cte/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/host/services/cte/syscfg.yml new file mode 100644 index 00000000..24109fe1 --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/host/services/cte/syscfg.yml @@ -0,0 +1,23 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +syscfg.defs: + BLE_SVC_ATP_SYSINIT_STAGE: + description: > + Sysinit stage for the asset tag BLE service. + value: 303 + diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/cts/include/services/cts/ble_svc_cts.h b/lib/bt/host/nimble/nimble/nimble/host/services/cts/include/services/cts/ble_svc_cts.h index cf62f912..57df3ecc 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/cts/include/services/cts/ble_svc_cts.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/cts/include/services/cts/ble_svc_cts.h @@ -20,6 +20,10 @@ #ifndef H_BLE_SVC_CTS_ #define H_BLE_SVC_CTS_ +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_SVC_CTS_ERR_DATA_FIELD_IGNORED 0x80 /* 16 Bit Current Time Service UUID */ #define BLE_SVC_CTS_UUID16 0x1805 @@ -157,4 +161,8 @@ ble_svc_cts_init(struct ble_svc_cts_cfg cfg); void ble_svc_cts_time_updated(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c b/lib/bt/host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c index 1c9f8c88..29119c5f 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c @@ -28,7 +28,7 @@ #include "time.h" #include - +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_CTS_SERVICE struct ble_svc_cts_cfg cts_cfg = {0}; /* characteristic values */ @@ -277,3 +277,4 @@ ble_svc_cts_init(struct ble_svc_cts_cfg cfg) rc = ble_gatts_add_svcs(ble_svc_cts_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/dis/include/services/dis/ble_svc_dis.h b/lib/bt/host/nimble/nimble/nimble/host/services/dis/include/services/dis/ble_svc_dis.h index aa70d2e6..749c439f 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/dis/include/services/dis/ble_svc_dis.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/dis/include/services/dis/ble_svc_dis.h @@ -20,6 +20,10 @@ #ifndef H_BLE_SVC_DIS_ #define H_BLE_SVC_DIS_ +#ifdef __cplusplus +extern "C" { +#endif + /** * Example: * @@ -42,7 +46,16 @@ #define BLE_SVC_DIS_CHR_UUID16_HARDWARE_REVISION 0x2A27 #define BLE_SVC_DIS_CHR_UUID16_SOFTWARE_REVISION 0x2A28 #define BLE_SVC_DIS_CHR_UUID16_MANUFACTURER_NAME 0x2A29 +#define BLE_SVC_DIS_CHR_UUID16_IEEE_REG_CERT_LIST 0x2A2A #define BLE_SVC_DIS_CHR_UUID16_PNP_ID 0x2A50 +#define BLE_SVC_DIS_CHR_UUID16_UDI 0x2BFF + +/* One PTS Case requires DIS to be included. + * The UUID below is randomly chosen. + */ +static const ble_uuid128_t ble_svc_dis_include_uuid = + BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, + 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0xFF); /** * Structure holding data for the main characteristics @@ -81,14 +94,26 @@ struct ble_svc_dis_data { /** * System ID. * Represent the System Id of the device. + * Length: 8 Octets */ const char *system_id; /** * PNP ID. * Represent the PNP Id of the device. + * Length: 7 Octets */ const char *pnp_id; + + /** + * IEEE 11073-20601 Regulatory Certification Data List + */ + const char *ieee; + + /** + * UDI for Medical Devices + */ + const char *udi; }; /** @@ -102,6 +127,11 @@ extern struct ble_svc_dis_data ble_svc_dis_data; */ void ble_svc_dis_init(void); +/** + * Service initialisation as an included service. + */ +void ble_svc_dis_included_init(void); + const char *ble_svc_dis_model_number(void); int ble_svc_dis_model_number_set(const char *value); const char *ble_svc_dis_serial_number(void); @@ -119,4 +149,8 @@ int ble_svc_dis_system_id_set(const char *value); int ble_svc_dis_pnp_id_set(const char *value); const char *ble_svc_dis_pnp_id(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c b/lib/bt/host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c index 9066bc8e..2abf5bf2 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c @@ -23,6 +23,7 @@ #include "host/ble_hs.h" #include "services/dis/ble_svc_dis.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_DIS_SERVICE /* Device information */ struct ble_svc_dis_data ble_svc_dis_data = { .model_number = MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_DEFAULT), @@ -32,6 +33,9 @@ struct ble_svc_dis_data ble_svc_dis_data = { .software_revision = MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT), .manufacturer_name = MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT), .system_id = MYNEWT_VAL(BLE_SVC_DIS_SYSTEM_ID_DEFAULT), + .pnp_id = MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_DEFAULT), + .ieee = "dummy_data", + .udi = NULL, /** For now no UID fields are supported */ }; /* Access function */ @@ -109,6 +113,11 @@ static const struct ble_gatt_svc_def ble_svc_dis_defs[] = { MYNEWT_VAL(BLE_SVC_DIS_SYSTEM_ID_READ_PERM), }, { #endif + /*** Chatacteristic: IEEE 11073-20601 Regulatory Certification Data List */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_IEEE_REG_CERT_LIST), + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ, + }, { #if (MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_READ_PERM) >= 0) /*** Characteristic: PNP Id */ .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_PNP_ID), @@ -117,6 +126,11 @@ static const struct ble_gatt_svc_def ble_svc_dis_defs[] = { MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_READ_PERM), }, { #endif + /*** UDI for Medical Devices */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_UDI), + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ + }, { 0, /* No more characteristics in this service */ }, } @@ -127,6 +141,15 @@ static const struct ble_gatt_svc_def ble_svc_dis_defs[] = { }, }; +const struct ble_gatt_svc_def *included_services[] = {ble_svc_dis_defs, NULL}; +const struct ble_gatt_svc_def ble_svc_dis_include_def[] = { + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &ble_svc_dis_include_uuid.u, + .includes = included_services, + } +}; + /** * Simple read access callback for the device information service * characteristic. @@ -224,8 +247,22 @@ ble_svc_dis_access(uint16_t conn_handle, uint16_t attr_handle, info = MYNEWT_VAL(BLE_SVC_PNP_SYSTEM_ID_DEFAULT); } #endif + uint8_t flag = 0x01; + os_mbuf_append(ctxt->om, &flag, sizeof flag); break; #endif + case BLE_SVC_DIS_CHR_UUID16_IEEE_REG_CERT_LIST: + info = ble_svc_dis_data.ieee; + break; + + case BLE_SVC_DIS_CHR_UUID16_UDI: + info = ble_svc_dis_data.udi; + if (info == NULL) { + uint8_t flag = 0x00; + os_mbuf_append(ctxt->om, &flag, sizeof(flag)); + } + break; + default: assert(0); return BLE_ATT_ERR_UNLIKELY; @@ -344,6 +381,21 @@ ble_svc_dis_pnp_id_set(const char *value) return 0; } +void +ble_svc_dis_included_init(void) +{ + int rc; + + SYSINIT_ASSERT_ACTIVE(); + + rc = ble_gatts_count_cfg(ble_svc_dis_include_def); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gatts_add_svcs(ble_svc_dis_include_def); + SYSINIT_PANIC_ASSERT(rc == 0); +} + + /** * Initialize the DIS package. */ @@ -361,3 +413,4 @@ ble_svc_dis_init(void) rc = ble_gatts_add_svcs(ble_svc_dis_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h b/lib/bt/host/nimble/nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h index f748d649..92d305fb 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h @@ -34,6 +34,8 @@ extern "C" { #define BLE_SVC_GAP_CHR_UUID16_APPEARANCE 0x2a01 #define BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS 0x2a04 #define BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION 0x2aa6 +#define BLE_SVC_GAP_CHR_UUID16_RPA_ONLY 0x2AC9 +#define BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS 0x2BF5 #if MYNEWT_VAL(ENC_ADV_DATA) #define BLE_SVC_GAP_CHR_UUID16_KEY_MATERIAL 0x2B88 @@ -57,6 +59,7 @@ int ble_svc_gap_device_key_material_set(uint8_t *session_key, uint8_t *iv); #endif void ble_svc_gap_init(void); +void ble_svc_gap_deinit(void); #ifdef __cplusplus } diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c b/lib/bt/host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c index 2f783228..a04cf571 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c @@ -25,6 +25,8 @@ #include "services/gap/ble_svc_gap.h" #include "os/endian.h" +#if MYNEWT_VAL(BLE_GATTS) + #define PPCP_ENABLED \ MYNEWT_VAL(BLE_ROLE_PERIPHERAL) && \ (MYNEWT_VAL(BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL) || \ @@ -42,6 +44,7 @@ static char ble_svc_gap_name[BLE_SVC_GAP_NAME_MAX_LEN + 1] = static uint16_t ble_svc_gap_appearance = MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE); #if MYNEWT_VAL(ENC_ADV_DATA) +static uint16_t ble_svc_gap_enc_adv_data_handle; static struct key_material km = { .session_key = {0}, .iv = {0}, @@ -94,9 +97,24 @@ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = { .flags = BLE_GATT_CHR_F_READ, }, { #endif +#if MYNEWT_VAL(BLE_SVC_GAP_RPA_ONLY) + /*** Characteristic: Resolvable Private Address Only. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_RPA_ONLY), + .access_cb = ble_svc_gap_access, + .flags = BLE_GATT_CHR_F_READ, + }, { +#endif #if MYNEWT_VAL(ENC_ADV_DATA) .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_KEY_MATERIAL), .access_cb = ble_svc_gap_access, + .val_handle = &ble_svc_gap_enc_adv_data_handle, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_READ_AUTHOR | BLE_GATT_CHR_F_INDICATE, + }, { +#endif +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) + /*** Characteristic: LE GATT Security Levels. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS), + .access_cb = ble_svc_gap_access, .flags = BLE_GATT_CHR_F_READ, }, { #endif @@ -190,6 +208,26 @@ ble_svc_gap_appearance_write_access(struct ble_gatt_access_ctxt *ctxt) #endif } +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) +static int +ble_svc_gap_security_level_read_access(uint16_t conn_handle, struct os_mbuf * om) +{ + uint8_t security_level[2]; + int rc; + + /* Currently this characteristic is only supported for + * Security Mode 1 + */ + security_level[0] = 0x01; //Mode 1 + security_level[1] = ble_gatts_security_mode_1_level(); //Mode 1 Level + + rc = os_mbuf_append(om, security_level, sizeof(security_level)); + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +} +#endif + + static int ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) @@ -205,6 +243,15 @@ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_SLAVE_LATENCY)), htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_SUPERVISION_TMO)) }; +#endif +#if MYNEWT_VAL(BLE_SVC_GAP_RPA_ONLY) + /* As per Core Specification 6.0, Vol 3: Host, Part C: GAP, 12.5 + * The only allowed value for the characteristic is zero. + * All other values are RFU. + * As such, the presence of the characteristic itself indicates that + * the device is RPA only + */ + uint8_t rpa_only = 0; #endif int rc; @@ -248,6 +295,13 @@ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; #endif +#if MYNEWT_VAL(BLE_SVC_GAP_RPA_ONLY) + case BLE_SVC_GAP_CHR_UUID16_RPA_ONLY: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, &rpa_only, sizeof(rpa_only)); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +#endif + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_SVC_GAP_CHR_UUID16_KEY_MATERIAL: rc = os_mbuf_append(ctxt->om, &(km.session_key), sizeof(km.session_key)); @@ -256,6 +310,13 @@ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; #endif +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) + case BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = ble_svc_gap_security_level_read_access(conn_handle, ctxt->om); + return rc; +#endif + default: assert(0); return BLE_ATT_ERR_UNLIKELY; @@ -311,6 +372,7 @@ ble_svc_gap_device_key_material_set(uint8_t *session_key, uint8_t *iv) { memcpy(&km.session_key, session_key, BLE_EAD_KEY_SIZE); memcpy(&km.iv, iv, BLE_EAD_IV_SIZE); + ble_gatts_chr_updated(ble_svc_gap_enc_adv_data_handle); return 0; } #endif @@ -333,3 +395,10 @@ ble_svc_gap_init(void) SYSINIT_PANIC_ASSERT(rc == 0); #endif } + +void +ble_svc_gap_deinit(void) +{ + ble_gatts_free_svcs(); +} +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h b/lib/bt/host/nimble/nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h index a035f9a1..ea78fa61 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h @@ -29,10 +29,16 @@ extern "C" { struct ble_hs_cfg; -#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05 +#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05 #define BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16 0x2b3a #define BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16 0x2b29 +#define BLE_SVR_GATT_CHR_SVR_SUP_FEAT_EATT_FLAG 0x01 + +#define BLE_SVR_GATT_CHR_CLT_SUP_FEAT_ROBUST_CACHING_FLAG 0x01 +#define BLE_SVR_GATT_CHR_CLT_SUP_FEAT_EATT_FLAG 0x02 +#define BLE_SVR_GATT_CHR_CLT_SUP_FEAT_MULTI_NOTIF_FLAG 0x04 + #if MYNEWT_VAL(BLE_GATT_CACHING) #define BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16 0x2b2a @@ -45,7 +51,7 @@ uint8_t ble_svc_gatt_get_csfs(void); uint8_t ble_svc_gatt_get_local_cl_supported_feat(void); void ble_svc_gatt_changed(uint16_t start_handle, uint16_t end_handle); void ble_svc_gatt_init(void); - +void ble_svc_gatt_deinit(void); #ifdef __cplusplus } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c b/lib/bt/host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c index f32b7294..c76bc901 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -23,6 +23,7 @@ #include "host/ble_hs.h" #include "services/gatt/ble_svc_gatt.h" +#if MYNEWT_VAL(BLE_GATTS) #if MYNEWT_VAL(BLE_GATT_CACHING) static uint16_t ble_svc_gatt_db_hash_handle; static uint16_t ble_svc_gatt_client_supp_feature_handle; @@ -232,4 +233,27 @@ ble_svc_gatt_init(void) rc = ble_gatts_add_svcs(ble_svc_gatt_defs); SYSINIT_PANIC_ASSERT(rc == 0); + + if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 && ble_hs_cfg.eatt) { + ble_svc_gatt_local_srv_sup_feat |= (1 << BLE_SVC_GATT_SRV_SUP_FEAT_EATT_BIT); + } + + if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 && ble_hs_cfg.eatt) { + ble_svc_gatt_local_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT); + } + + if (MYNEWT_VAL(BLE_ATT_SVR_NOTIFY_MULTI) > 0) { + ble_svc_gatt_local_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_MULT_NTF_BIT); + } + + if (MYNEWT_VAL(BLE_GATT_CACHING) > 0) { + ble_svc_gatt_local_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_ROBUST_CATCHING_BIT); + } +} + +void +ble_svc_gatt_deinit(void) +{ + ble_gatts_free_svcs(); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/hid/include/services/hid/ble_svc_hid.h b/lib/bt/host/nimble/nimble/nimble/host/services/hid/include/services/hid/ble_svc_hid.h index dcdf129c..50c6e532 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/hid/include/services/hid/ble_svc_hid.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/hid/include/services/hid/ble_svc_hid.h @@ -21,6 +21,10 @@ #ifndef H_BLE_SVC_HID_ #define H_BLE_SVC_HID_ +#ifdef __cplusplus +extern "C" { +#endif + /* 16 Bit Battery Service UUID */ #define BLE_SVC_HID_UUID16 0x1812 @@ -65,6 +69,8 @@ struct ble_svc_hid_params{ unsigned int kbd_inp_present : 1; unsigned int kbd_out_present : 1; unsigned int mouse_inp_present : 1; + unsigned int kbd_inp_write_perm:1; + unsigned int mouse_inp_write_perm:1; /* protocol mode char */ uint8_t proto_mode; uint16_t proto_mode_handle; @@ -108,5 +114,9 @@ void ble_svc_hid_init(void); int ble_svc_hid_add(struct ble_svc_hid_params params); void ble_svc_hid_reset(void); +#ifdef __cplusplus +} +#endif + #endif #endif // CONFIG_BT_NIMBLE_HID_SERVICE diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c b/lib/bt/host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c index e091bb3d..bb5d11b6 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c @@ -23,7 +23,9 @@ #include "sysinit/sysinit.h" #include "syscfg/syscfg.h" + #if MYNEWT_VAL(BLE_SVC_HID_SERVICE) +#if MYNEWT_VAL(BLE_GATTS) #include "host/ble_hs.h" #include "host/ble_gap.h" #include "services/hid/ble_svc_hid.h" @@ -180,24 +182,34 @@ void fill_boot_kbd_inp(uint8_t instance) { struct ble_gatt_chr_def *chr, demo_chr; + uint16_t write_flags; if (!hid_instances[instance].kbd_inp_present) { return; } + + write_flags = BLE_GATT_CHR_F_WRITE | +#if MYNEWT_VAL(BLE_SM_LVL) == 2 + BLE_GATT_CHR_F_WRITE_ENC | +#elif MYNEWT_VAL(BLE_SM_LVL) == 3 + BLE_GATT_CHR_F_WRITE_ENC | BLE_GATT_CHR_F_WRITE_AUTHEN +#endif + 0; + write_flags = (hid_instances[instance].kbd_inp_write_perm ? write_flags : 0); + demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ .uuid = uuid_boot_kbd_inp, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].kbd_inp_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | - BLE_GATT_CHR_F_WRITE | #if MYNEWT_VAL(BLE_SM_LVL) == 2 - BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC | + BLE_GATT_CHR_F_READ_ENC | #elif MYNEWT_VAL(BLE_SM_LVL) == 3 - BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_WRITE_AUTHEN | - BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC | + BLE_GATT_CHR_F_READ_AUTHEN | + BLE_GATT_CHR_F_READ_ENC | #endif - 0, + write_flags, }; chr = ble_svc_hid_get_chr_block(); @@ -237,24 +249,34 @@ void fill_boot_mouse_inp(uint8_t instance) { struct ble_gatt_chr_def *chr, demo_chr; + uint16_t write_flags; if (!hid_instances[instance].mouse_inp_present) { return; } + + write_flags = BLE_GATT_CHR_F_WRITE | +#if MYNEWT_VAL(BLE_SM_LVL) == 2 + BLE_GATT_CHR_F_WRITE_ENC | +#elif MYNEWT_VAL(BLE_SM_LVL) == 3 + BLE_GATT_CHR_F_WRITE_ENC | BLE_GATT_CHR_F_WRITE_AUTHEN +#endif + 0; + write_flags = (hid_instances[instance].mouse_inp_write_perm ? write_flags : 0); + demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ .uuid = uuid_boot_mouse_inp, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].mouse_inp_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | - BLE_GATT_CHR_F_WRITE | #if MYNEWT_VAL(BLE_SM_LVL) == 2 - BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC | + BLE_GATT_CHR_F_READ_ENC | #elif MYNEWT_VAL(BLE_SM_LVL) == 3 - BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_WRITE_AUTHEN | - BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC | + BLE_GATT_CHR_F_READ_AUTHEN | + BLE_GATT_CHR_F_READ_ENC | #endif - 0, + write_flags, }; chr = ble_svc_hid_get_chr_block(); @@ -691,4 +713,5 @@ ble_svc_hid_init(void) rc = ble_gatts_add_svcs(ble_svc_hid_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif #endif // CONFIG_BT_NIMBLE_HID_SERVICE diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/hr/include/services/hr/ble_svc_hr.h b/lib/bt/host/nimble/nimble/nimble/host/services/hr/include/services/hr/ble_svc_hr.h index 9ed8b21f..2f8eaa50 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/hr/include/services/hr/ble_svc_hr.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/hr/include/services/hr/ble_svc_hr.h @@ -7,6 +7,10 @@ #ifndef H_BLE_SVC_HR_ #define H_BLE_SVC_HR_ +#ifdef __cplusplus +extern "C" { +#endif + struct ble_hs_cfg; /* 16 Bit Heart Rate Service UUID */ @@ -26,4 +30,8 @@ void ble_svc_hr_on_gap_disconnect(uint16_t conn_handle); void ble_svc_hr_init(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/hr/src/ble_svc_hr.c b/lib/bt/host/nimble/nimble/nimble/host/services/hr/src/ble_svc_hr.c index c471c9ff..6fa6c6b8 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/hr/src/ble_svc_hr.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/hr/src/ble_svc_hr.c @@ -13,6 +13,7 @@ #include "host/ble_gap.h" #include "services/hr/ble_svc_hr.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_HR_SERVICE /* Characteristic values */ static uint8_t ble_svc_hr_measurement; static uint16_t ble_svc_hr_body_sensor_loc; @@ -231,3 +232,4 @@ ble_svc_hr_init(void) ble_svc_hr_conn_handle[i] = -1; } } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/htp/include/services/htp/ble_svc_htp.h b/lib/bt/host/nimble/nimble/nimble/host/services/htp/include/services/htp/ble_svc_htp.h index 9b7fbac9..97c40451 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/htp/include/services/htp/ble_svc_htp.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/htp/include/services/htp/ble_svc_htp.h @@ -7,6 +7,10 @@ #ifndef H_BLE_SVC_HTP_ #define H_BLE_SVC_HTP_ +#ifdef __cplusplus +extern "C" { +#endif + struct ble_hs_cfg; /* 16 Bit Health Thermometer Service UUID */ @@ -47,4 +51,8 @@ int ble_svc_htp_notify(uint16_t conn_handle, float temp, bool temp_unit); void ble_svc_htp_init(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c b/lib/bt/host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c index 134e9803..7e1413ba 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c @@ -13,6 +13,7 @@ #include "host/ble_gap.h" #include "services/htp/ble_svc_htp.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_HTP_SERVICE /* Characteristic values */ static uint16_t ble_svc_htp_temp_type; static uint16_t ble_svc_htp_temp_msr_itvl; @@ -289,3 +290,4 @@ ble_svc_htp_init(void) memset(&conn_chr_subs, 0, sizeof(conn_chr_subs)); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/ias/include/services/ias/ble_svc_ias.h b/lib/bt/host/nimble/nimble/nimble/host/services/ias/include/services/ias/ble_svc_ias.h index 26c18d01..3bce343b 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/ias/include/services/ias/ble_svc_ias.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/ias/include/services/ias/ble_svc_ias.h @@ -20,6 +20,10 @@ #ifndef H_BLE_IAS_TPS_ #define H_BLE_IAS_TPS_ +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_SVC_IAS_UUID16 0x1802 #define BLE_SVC_IAS_CHR_UUID16_ALERT_LEVEL 0x2a06 @@ -33,6 +37,9 @@ typedef int ble_svc_ias_event_fn(uint8_t alert_level); void ble_svc_ias_set_cb(ble_svc_ias_event_fn *cb); void ble_svc_ias_init(void); +#ifdef __cplusplus +} #endif +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c b/lib/bt/host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c index 9f5da148..f9154976 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c @@ -23,6 +23,7 @@ #include "host/ble_hs.h" #include "services/ias/ble_svc_ias.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_IAS_SERVICE /* Callback function */ static ble_svc_ias_event_fn *ble_svc_ias_cb_fn; @@ -147,3 +148,4 @@ ble_svc_ias_init(void) rc = ble_gatts_add_svcs(ble_svc_ias_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c b/lib/bt/host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c index f42ca1e9..d883bf48 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c @@ -23,6 +23,7 @@ #include "host/ble_hs.h" #include "services/ipss/ble_svc_ipss.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_IPSS_SERVICE static const struct ble_gatt_svc_def ble_svc_ipss_defs[] = { { /*** Service: GATT */ @@ -49,3 +50,4 @@ ble_svc_ipss_init(void) rc = ble_gatts_add_svcs(ble_svc_ipss_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c b/lib/bt/host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c index b5f7f9bd..335a7927 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c @@ -23,6 +23,7 @@ #include "host/ble_hs.h" #include "services/lls/ble_svc_lls.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_LLS_SERVICE /* Callback function */ static ble_svc_lls_event_fn *ble_svc_lls_cb_fn; @@ -134,7 +135,9 @@ void ble_svc_lls_on_gap_disconnect(int reason) { if (reason == BLE_HS_HCI_ERR(BLE_ERR_CONN_SPVN_TMO)) { + if (ble_svc_lls_cb_fn != NULL) { ble_svc_lls_cb_fn(ble_svc_lls_alert_level); + } } } @@ -190,3 +193,4 @@ ble_svc_lls_init(void) rc = ble_gatts_add_svcs(ble_svc_lls_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/prox/include/services/prox/ble_svc_prox.h b/lib/bt/host/nimble/nimble/nimble/host/services/prox/include/services/prox/ble_svc_prox.h index b34fbb95..8b1e4c62 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/prox/include/services/prox/ble_svc_prox.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/prox/include/services/prox/ble_svc_prox.h @@ -7,6 +7,10 @@ #ifndef H_BLE_SVC_PROX_ #define H_BLE_SVC_PROX_ +#ifdef __cplusplus +extern "C" { +#endif + struct ble_hs_cfg; /* 16 Bit Proximity Sensor Service UUID */ @@ -29,4 +33,8 @@ struct ble_hs_cfg; */ void ble_svc_prox_init(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c b/lib/bt/host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c index c2c1df65..49c67dd5 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c @@ -13,6 +13,7 @@ #include "host/ble_gap.h" #include "services/prox/ble_svc_prox.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_PROX_SERVICE /* Characteristic values */ static uint8_t ble_svc_prox_link_loss_alert; static int8_t ble_svc_prox_alert; @@ -261,3 +262,4 @@ ble_svc_prox_init(void) ble_svc_prox_alert_conn[i] = false; } } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/sps/include/services/sps/ble_svc_sps.h b/lib/bt/host/nimble/nimble/nimble/host/services/sps/include/services/sps/ble_svc_sps.h index 72d4f4aa..5daa96ef 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/sps/include/services/sps/ble_svc_sps.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/sps/include/services/sps/ble_svc_sps.h @@ -22,11 +22,22 @@ #ifndef H_BLE_SVC_SPS_ #define H_BLE_SVC_SPS_ +#ifdef __cplusplus +extern "C" { +#endif #define BLE_SVC_SPS_UUID16 0x1813 -#define BLE_SVC_SPS_CHR_UUID16_SCAN_ITVL_WINDOW 0x2A23 +#define BLE_SVC_SPS_CHR_UUID16_SCAN_ITVL_WINDOW 0x2A4F #define BLE_SVC_SPS_CHR_UUID16_SCAN_REFRESH 0x2A31 +typedef int ble_svc_sps_event_fn(uint16_t scan_interval, uint16_t scan_window); + void ble_svc_sps_scan_refresh(void); void ble_svc_sps_init(uint16_t scan_itvl, uint16_t scan_window); +void ble_svc_sps_set_cb(ble_svc_sps_event_fn *cb); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c b/lib/bt/host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c index f7cbd197..c8ac0ad4 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c @@ -23,12 +23,14 @@ #include "host/ble_hs.h" #include "services/sps/ble_svc_sps.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_SPS_SERVICE static uint16_t ble_scan_itvl; static uint16_t ble_scan_window; static uint8_t ble_scan_refresh; static uint16_t ble_scan_itvl_handle; static uint16_t ble_scan_refresh_handle; +static ble_svc_sps_event_fn *ble_svc_sps_cb_fn; /* Access function */ static int @@ -100,9 +102,12 @@ ble_svc_sps_access(uint16_t conn_handle, uint16_t attr_handle, case BLE_SVC_SPS_CHR_UUID16_SCAN_ITVL_WINDOW: assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR); rc = ble_svc_sps_chr_write(ctxt->om, 0, sizeof(ble_scan_itvl) + sizeof(ble_scan_window), &write_val, NULL); - if(rc != 0) { + if(rc == 0) { ble_scan_itvl = (write_val & 0xffff0000) >> 16; - ble_scan_window = (write_val && 0x0000ffff); + ble_scan_window = (write_val & 0x0000ffff); + } + if (ble_svc_sps_cb_fn) { + ble_svc_sps_cb_fn(ble_scan_itvl, ble_scan_window); } return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; case BLE_SVC_SPS_CHR_UUID16_SCAN_REFRESH: @@ -118,6 +123,11 @@ ble_svc_sps_access(uint16_t conn_handle, uint16_t attr_handle, return 0; } +void +ble_svc_sps_set_cb(ble_svc_sps_event_fn *cb) +{ + ble_svc_sps_cb_fn = cb; +} /** * Initialize the SPS package. @@ -138,3 +148,4 @@ ble_svc_sps_init(uint16_t scan_itvl, uint16_t scan_window) rc = ble_gatts_add_svcs(ble_svc_sps_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/tps/include/services/tps/ble_svc_tps.h b/lib/bt/host/nimble/nimble/nimble/host/services/tps/include/services/tps/ble_svc_tps.h index ec4cd790..446cc37c 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/tps/include/services/tps/ble_svc_tps.h +++ b/lib/bt/host/nimble/nimble/nimble/host/services/tps/include/services/tps/ble_svc_tps.h @@ -20,6 +20,10 @@ #ifndef H_BLE_SVC_TPS_ #define H_BLE_SVC_TPS_ +#ifdef __cplusplus +extern "C" { +#endif + struct ble_hs_cfg; #define BLE_SVC_TPS_UUID16 0x1804 @@ -27,5 +31,8 @@ struct ble_hs_cfg; void ble_svc_tps_init(void); +#ifdef __cplusplus +} #endif +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c b/lib/bt/host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c index 9885a921..313eb7fb 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c +++ b/lib/bt/host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c @@ -30,6 +30,7 @@ */ #include "../src/ble_hs_hci_priv.h" +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_TPS_SERVICE int8_t ble_svc_tps_tx_power_level; /* Access function */ @@ -105,3 +106,4 @@ ble_svc_tps_init(void) rc = ble_gatts_add_svcs(ble_svc_tps_defs); SYSINIT_PANIC_ASSERT(rc == 0); } +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_aes_ccm.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_aes_ccm.c index 285db47e..7af09830 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_aes_ccm.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_aes_ccm.c @@ -265,14 +265,20 @@ int ble_aes_ccm_decrypt(const uint8_t key[16], uint8_t nonce[13], const uint8_t uint8_t *out_msg, size_t mic_size) { uint8_t mic[16]; + uint8_t key_reversed[16]; if (aad_len >= 0xff00 || mic_size > sizeof(mic)) { return BLE_HS_EINVAL; } - ble_aes_ccm_crypt(key, nonce, enc_msg, out_msg, msg_len); + /** Setting the correct endian-ness of the key */ + for (int i = 0; i < 16; i++) { + key_reversed[i] = key[15 - i]; + } + + ble_aes_ccm_crypt(key_reversed, nonce, enc_msg, out_msg, msg_len); - ble_aes_ccm_auth(key, nonce, out_msg, msg_len, aad, aad_len, mic, mic_size); + ble_aes_ccm_auth(key_reversed, nonce, out_msg, msg_len, aad, aad_len, mic, mic_size); /*if (memcmp(mic, enc_msg + msg_len, mic_size)) { printf("\n%s return here", __func__); @@ -286,16 +292,25 @@ int ble_aes_ccm_encrypt(const uint8_t key[16], uint8_t nonce[13], const uint8_t size_t msg_len, const uint8_t *aad, size_t aad_len, uint8_t *out_msg, size_t mic_size) { + /** MIC starts after encrypted message and is part of encrypted advertisement data */ uint8_t *mic = out_msg + msg_len; + uint8_t key_reversed[16]; /* Unsupported AAD size */ if (aad_len >= 0xff00 || mic_size > 16) { return BLE_HS_EINVAL; } - ble_aes_ccm_auth(key, nonce, out_msg, msg_len, aad, aad_len, mic, mic_size); + /* Correcting the endian-ness of the key */ + for (int i = 0; i < 16; i++) { + key_reversed[i] = key[15 - i]; + } + + /** Calculating MIC */ + ble_aes_ccm_auth(key_reversed, nonce, msg, msg_len, aad, aad_len, mic, mic_size); - ble_aes_ccm_crypt(key, nonce, msg, out_msg, msg_len); + /** Encrypting advertisment */ + ble_aes_ccm_crypt(key_reversed, nonce, msg, out_msg, msg_len); return 0; } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att.c index 91e77080..ea008e43 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att.c @@ -35,7 +35,7 @@ static uint16_t ble_att_preferred_mtu_val; /** Dispatch table for incoming ATT requests. Sorted by op code. */ -typedef int ble_att_rx_fn(uint16_t conn_handle, struct os_mbuf **om); +typedef int ble_att_rx_fn(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om); struct ble_att_rx_dispatch_entry { uint8_t bde_op; ble_att_rx_fn *bde_fn; @@ -43,36 +43,41 @@ struct ble_att_rx_dispatch_entry { /** Dispatch table for incoming ATT commands. Must be ordered by op code. */ static const struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = { +#if MYNEWT_VAL(BLE_GATTC) { BLE_ATT_OP_ERROR_RSP, ble_att_clt_rx_error }, - { BLE_ATT_OP_MTU_REQ, ble_att_svr_rx_mtu }, { BLE_ATT_OP_MTU_RSP, ble_att_clt_rx_mtu }, - { BLE_ATT_OP_FIND_INFO_REQ, ble_att_svr_rx_find_info }, { BLE_ATT_OP_FIND_INFO_RSP, ble_att_clt_rx_find_info }, - { BLE_ATT_OP_FIND_TYPE_VALUE_REQ, ble_att_svr_rx_find_type_value }, { BLE_ATT_OP_FIND_TYPE_VALUE_RSP, ble_att_clt_rx_find_type_value }, - { BLE_ATT_OP_READ_TYPE_REQ, ble_att_svr_rx_read_type }, { BLE_ATT_OP_READ_TYPE_RSP, ble_att_clt_rx_read_type }, - { BLE_ATT_OP_READ_REQ, ble_att_svr_rx_read }, { BLE_ATT_OP_READ_RSP, ble_att_clt_rx_read }, - { BLE_ATT_OP_READ_BLOB_REQ, ble_att_svr_rx_read_blob }, { BLE_ATT_OP_READ_BLOB_RSP, ble_att_clt_rx_read_blob }, - { BLE_ATT_OP_READ_MULT_REQ, ble_att_svr_rx_read_mult }, { BLE_ATT_OP_READ_MULT_RSP, ble_att_clt_rx_read_mult }, - { BLE_ATT_OP_READ_GROUP_TYPE_REQ, ble_att_svr_rx_read_group_type }, { BLE_ATT_OP_READ_GROUP_TYPE_RSP, ble_att_clt_rx_read_group_type }, - { BLE_ATT_OP_WRITE_REQ, ble_att_svr_rx_write }, { BLE_ATT_OP_WRITE_RSP, ble_att_clt_rx_write }, - { BLE_ATT_OP_PREP_WRITE_REQ, ble_att_svr_rx_prep_write }, { BLE_ATT_OP_PREP_WRITE_RSP, ble_att_clt_rx_prep_write }, - { BLE_ATT_OP_EXEC_WRITE_REQ, ble_att_svr_rx_exec_write }, { BLE_ATT_OP_EXEC_WRITE_RSP, ble_att_clt_rx_exec_write }, + { BLE_ATT_OP_INDICATE_RSP, ble_att_clt_rx_indicate }, + { BLE_ATT_OP_READ_MULT_VAR_RSP, ble_att_clt_rx_read_mult_var }, +#endif +#if MYNEWT_VAL(BLE_GATTS) + { BLE_ATT_OP_MTU_REQ, ble_att_svr_rx_mtu }, + { BLE_ATT_OP_FIND_INFO_REQ, ble_att_svr_rx_find_info }, + { BLE_ATT_OP_FIND_TYPE_VALUE_REQ, ble_att_svr_rx_find_type_value }, + { BLE_ATT_OP_READ_TYPE_REQ, ble_att_svr_rx_read_type }, + { BLE_ATT_OP_READ_REQ, ble_att_svr_rx_read }, + { BLE_ATT_OP_READ_BLOB_REQ, ble_att_svr_rx_read_blob }, + { BLE_ATT_OP_READ_MULT_REQ, ble_att_svr_rx_read_mult }, + { BLE_ATT_OP_READ_GROUP_TYPE_REQ, ble_att_svr_rx_read_group_type }, + { BLE_ATT_OP_WRITE_REQ, ble_att_svr_rx_write }, + { BLE_ATT_OP_PREP_WRITE_REQ, ble_att_svr_rx_prep_write }, + { BLE_ATT_OP_EXEC_WRITE_REQ, ble_att_svr_rx_exec_write }, { BLE_ATT_OP_NOTIFY_REQ, ble_att_svr_rx_notify }, { BLE_ATT_OP_INDICATE_REQ, ble_att_svr_rx_indicate }, - { BLE_ATT_OP_INDICATE_RSP, ble_att_clt_rx_indicate }, { BLE_ATT_OP_READ_MULT_VAR_REQ, ble_att_svr_rx_read_mult_var }, - { BLE_ATT_OP_READ_MULT_VAR_RSP, ble_att_clt_rx_read_mult_var }, + { BLE_ATT_OP_NOTIFY_MULTI_REQ, ble_att_svr_rx_notify_multi }, { BLE_ATT_OP_WRITE_CMD, ble_att_svr_rx_write_no_rsp }, { BLE_ATT_OP_SIGNED_WRITE_CMD, ble_att_svr_rx_signed_write }, +#endif }; #define BLE_ATT_RX_DISPATCH_SZ \ @@ -132,6 +137,8 @@ STATS_NAME_START(ble_att_stats) STATS_NAME(ble_att_stats, indicate_req_tx) STATS_NAME(ble_att_stats, indicate_rsp_rx) STATS_NAME(ble_att_stats, indicate_rsp_tx) + STATS_NAME(ble_att_stats, multi_notify_req_rx) + STATS_NAME(ble_att_stats, multi_notify_req_tx) STATS_NAME(ble_att_stats, write_cmd_rx) STATS_NAME(ble_att_stats, write_cmd_tx) STATS_NAME_END(ble_att_stats) @@ -147,23 +154,27 @@ ble_att_rx_dispatch_entry_find(uint8_t op) if (entry->bde_op == op) { return entry; } - - if (entry->bde_op > op) { - break; - } } return NULL; } int -ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn, +ble_att_conn_chan_find(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan) { - return ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, + return ble_hs_misc_conn_chan_find(conn_handle, cid, out_conn, out_chan); } +int +ble_att_conn_chan_find_by_psm(uint16_t conn_handle, uint16_t psm, + struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan) +{ + return ble_hs_misc_conn_chan_find(conn_handle, psm, out_conn, out_chan); +} + void ble_att_inc_tx_stat(uint8_t att_op) { @@ -272,6 +283,10 @@ ble_att_inc_tx_stat(uint8_t att_op) STATS_INC(ble_att_stats, indicate_rsp_tx); break; + case BLE_ATT_OP_NOTIFY_MULTI_REQ: + STATS_INC(ble_att_stats, multi_notify_req_tx); + break; + case BLE_ATT_OP_WRITE_CMD: STATS_INC(ble_att_stats, write_cmd_tx); break; @@ -389,6 +404,10 @@ ble_att_inc_rx_stat(uint8_t att_op) STATS_INC(ble_att_stats, indicate_rsp_rx); break; + case BLE_ATT_OP_NOTIFY_MULTI_REQ: + STATS_INC(ble_att_stats, multi_notify_req_rx); + break; + case BLE_ATT_OP_WRITE_CMD: STATS_INC(ble_att_stats, write_cmd_rx); break; @@ -413,7 +432,7 @@ ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan, } uint16_t -ble_att_mtu(uint16_t conn_handle) +ble_att_mtu_by_cid(uint16_t conn_handle, uint16_t cid) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; @@ -422,7 +441,7 @@ ble_att_mtu(uint16_t conn_handle) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, cid, &conn, &chan); if (rc == 0) { mtu = ble_att_chan_mtu(chan); } else { @@ -434,6 +453,12 @@ ble_att_mtu(uint16_t conn_handle) return mtu; } +uint16_t +ble_att_mtu(uint16_t conn_handle) +{ + return ble_att_mtu_by_cid(conn_handle, BLE_L2CAP_CID_ATT); +} + void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu) { @@ -449,6 +474,16 @@ ble_att_chan_mtu(const struct ble_l2cap_chan *chan) { uint16_t mtu; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (ble_hs_cfg.eatt && chan->psm == BLE_EATT_PSM) { + /* The ATT_MTU for the Enhanced ATT bearer shall be set to the minimum of the + * MTU field values of the two devices. Reference: + * Core v5.4 Vol 3 Part G 5.3.1 ATT_MTU + */ + return min(chan->coc_tx.mtu, chan->coc_rx.mtu); + } +#endif + /* If either side has not exchanged MTU size, use the default. Otherwise, * use the lesser of the two exchanged values. */ @@ -467,35 +502,46 @@ ble_att_chan_mtu(const struct ble_l2cap_chan *chan) static void ble_att_rx_handle_unknown_request(uint8_t op, uint16_t conn_handle, - struct os_mbuf **om) + uint16_t cid, struct os_mbuf **om) { /* If this is command (bit6 is set to 1), do nothing */ if (op & 0x40) { return; } - +#if MYNEWT_VAL(BLE_GATTS) os_mbuf_adj(*om, OS_MBUF_PKTLEN(*om)); - ble_att_svr_tx_error_rsp(conn_handle, *om, op, 0, + ble_att_svr_tx_error_rsp(conn_handle, cid, *om, op, 0, BLE_ATT_ERR_REQ_NOT_SUPPORTED); +#endif *om = NULL; } +static void +ble_att_send_outstanding_after_response(uint16_t conn_handle) +{ + struct ble_hs_conn *conn; + struct ble_l2cap_chan *chan; + int rc; + + ble_hs_lock(); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, + &chan); + if (rc) { + return; + } + conn->client_att_busy = false; + ble_att_tx_with_conn(conn, chan, NULL); + ble_hs_unlock(); +} + static int -ble_att_rx(struct ble_l2cap_chan *chan) +ble_att_rx_extended(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om) { const struct ble_att_rx_dispatch_entry *entry; uint8_t op; - uint16_t conn_handle; - struct os_mbuf **om; int rc; - conn_handle = ble_l2cap_get_conn_handle(chan); - if (conn_handle == BLE_HS_CONN_HANDLE_NONE) { - return BLE_HS_ENOTCONN; - } - - om = &chan->rx_buf; BLE_HS_DBG_ASSERT(*om != NULL); rc = os_mbuf_copydata(*om, 0, 1, &op); @@ -503,9 +549,13 @@ ble_att_rx(struct ble_l2cap_chan *chan) return BLE_HS_EMSGSIZE; } + if (cid == BLE_L2CAP_CID_ATT && ble_att_is_response_op(op)) { + ble_att_send_outstanding_after_response(conn_handle); + } + entry = ble_att_rx_dispatch_entry_find(op); if (entry == NULL) { - ble_att_rx_handle_unknown_request(op, conn_handle, om); + ble_att_rx_handle_unknown_request(op, conn_handle, cid, om); return BLE_HS_ENOTSUP; } @@ -514,10 +564,10 @@ ble_att_rx(struct ble_l2cap_chan *chan) /* Strip L2CAP ATT header from the front of the mbuf. */ os_mbuf_adj(*om, 1); - rc = entry->bde_fn(conn_handle, om); + rc = entry->bde_fn(conn_handle, cid, om); if (rc != 0) { if (rc == BLE_HS_ENOTSUP) { - ble_att_rx_handle_unknown_request(op, conn_handle, om); + ble_att_rx_handle_unknown_request(op, conn_handle, cid, om); } return rc; } @@ -525,6 +575,19 @@ ble_att_rx(struct ble_l2cap_chan *chan) return 0; } +static int +ble_att_rx(struct ble_l2cap_chan *chan) +{ + uint16_t conn_handle; + + conn_handle = ble_l2cap_get_conn_handle(chan); + if (conn_handle == BLE_HS_CONN_HANDLE_NONE) { + return BLE_HS_ENOTCONN; + } + + return ble_att_rx_extended(conn_handle, chan->scid, &chan->rx_buf); +} + uint16_t ble_att_preferred_mtu(void) { @@ -585,6 +648,105 @@ ble_att_create_chan(uint16_t conn_handle) return chan; } +bool +ble_att_is_request_op(uint8_t opcode) +{ + switch (opcode) { + case BLE_ATT_OP_MTU_REQ: + case BLE_ATT_OP_FIND_INFO_REQ: + case BLE_ATT_OP_FIND_TYPE_VALUE_REQ: + case BLE_ATT_OP_READ_TYPE_REQ: + case BLE_ATT_OP_READ_REQ: + case BLE_ATT_OP_READ_BLOB_REQ: + case BLE_ATT_OP_READ_MULT_REQ: + case BLE_ATT_OP_READ_GROUP_TYPE_REQ: + case BLE_ATT_OP_WRITE_REQ: + case BLE_ATT_OP_PREP_WRITE_REQ: + case BLE_ATT_OP_EXEC_WRITE_REQ: + case BLE_ATT_OP_INDICATE_REQ: + case BLE_ATT_OP_READ_MULT_VAR_REQ: + return true; + } + return false; +} + +bool +ble_att_is_response_op(uint8_t opcode) +{ + switch (opcode) { + case BLE_ATT_OP_MTU_RSP: + case BLE_ATT_OP_ERROR_RSP: + case BLE_ATT_OP_FIND_INFO_RSP: + case BLE_ATT_OP_FIND_TYPE_VALUE_RSP: + case BLE_ATT_OP_READ_TYPE_RSP: + case BLE_ATT_OP_INDICATE_RSP: + case BLE_ATT_OP_READ_RSP: + case BLE_ATT_OP_READ_BLOB_RSP: + case BLE_ATT_OP_READ_MULT_RSP: + case BLE_ATT_OP_READ_GROUP_TYPE_RSP: + case BLE_ATT_OP_WRITE_RSP: + case BLE_ATT_OP_PREP_WRITE_RSP: + case BLE_ATT_OP_EXEC_WRITE_RSP: + case BLE_ATT_OP_READ_MULT_VAR_RSP: + return true; + } + + return false; +} + +bool +ble_att_is_att_pdu_op(uint8_t opcode) +{ + if (ble_att_is_request_op(opcode)) { + return true; + } + + if (ble_att_is_response_op(opcode)) { + return true; + } + + switch (opcode) { + case BLE_ATT_OP_NOTIFY_MULTI_REQ: + case BLE_ATT_OP_WRITE_CMD: + case BLE_ATT_OP_SIGNED_WRITE_CMD: + case BLE_ATT_OP_NOTIFY_REQ: + return true; + } + return false; +} + +int +ble_att_set_default_bearer_using_cid(uint16_t conn_handle, uint16_t cid) { +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + struct ble_hs_conn * conn; + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); + + if (conn == NULL) { + return BLE_HS_ENOTCONN; + } + conn->default_cid = cid; + return 0; +#endif + return BLE_HS_ENOTSUP; +} + +uint16_t +ble_att_get_default_bearer_cid(uint16_t conn_handle) { +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + struct ble_hs_conn * conn; + + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + return 0; + } + return conn->default_cid; +#endif + return 0; +} + int ble_att_init(void) { @@ -599,6 +761,8 @@ ble_att_init(void) return BLE_HS_EOS; } + ble_eatt_init(ble_att_rx_extended); + return 0; } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_clt.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_clt.c index 2b62e27b..acdf8e8d 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_clt.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_clt.c @@ -32,12 +32,13 @@ #endif #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTC) /***************************************************************************** * $error response * *****************************************************************************/ int -ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_error(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { struct ble_att_error_rsp *rsp; int rc; @@ -49,7 +50,7 @@ ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom) rsp = (struct ble_att_error_rsp *)(*rxom)->om_data; - ble_gattc_rx_err(conn_handle, le16toh(rsp->baep_handle), + ble_gattc_rx_err(conn_handle, cid, le16toh(rsp->baep_handle), le16toh(rsp->baep_error_code)); return 0; @@ -74,7 +75,7 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc != 0) { rc = BLE_HS_ENOTCONN; } else if (chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU) { @@ -95,14 +96,14 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu) req->bamc_mtu = htole16(mtu); - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, BLE_L2CAP_CID_ATT, txom); if (rc != 0) { return rc; } ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc == 0) { chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU; } @@ -113,7 +114,7 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu) } int -ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { struct ble_att_mtu_cmd *cmd; struct ble_l2cap_chan *chan; @@ -122,13 +123,19 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) mtu = 0; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (ble_hs_cfg.eatt && cid != BLE_L2CAP_CID_ATT) { + return BLE_HS_ENOTSUP; + } +#endif + rc = ble_hs_mbuf_pullup_base(rxom, sizeof(*cmd)); if (rc == 0) { cmd = (struct ble_att_mtu_cmd *)(*rxom)->om_data; ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, NULL, &chan); + rc = ble_att_conn_chan_find(conn_handle, cid, NULL, &chan); if (rc == 0) { ble_att_set_peer_mtu(chan, le16toh(cmd->bamc_mtu)); mtu = ble_att_chan_mtu(chan); @@ -141,7 +148,7 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) } } - ble_gattc_rx_mtu(conn_handle, rc, mtu); + ble_gattc_rx_mtu(conn_handle, BLE_L2CAP_CID_ATT, rc, mtu); return rc; } @@ -150,7 +157,7 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, +ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO @@ -172,7 +179,7 @@ ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, req->bafq_start_handle = htole16(start_handle); req->bafq_end_handle = htole16(end_handle); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } static int @@ -227,7 +234,7 @@ ble_att_clt_parse_find_info_entry(struct os_mbuf **rxom, uint8_t rsp_format, } int -ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om) +ble_att_clt_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO return BLE_HS_ENOTSUP; @@ -254,14 +261,14 @@ ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om) } /* Hand find-info entry to GATT. */ - ble_gattc_rx_find_info_idata(conn_handle, &idata); + ble_gattc_rx_find_info_idata(conn_handle, cid, &idata); } rc = 0; done: /* Notify GATT that response processing is done. */ - ble_gattc_rx_find_info_complete(conn_handle, rc); + ble_gattc_rx_find_info_complete(conn_handle, cid, rc); return rc; } @@ -274,8 +281,9 @@ done: * anyway */ int -ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle, uint16_t attribute_type, +ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t cid, + uint16_t start_handle, uint16_t end_handle, + uint16_t attribute_type, const void *attribute_value, int value_len) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE @@ -300,7 +308,7 @@ ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, req->bavq_attr_type = htole16(attribute_type); memcpy(req->bavq_value, attribute_value, value_len); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } static int @@ -326,7 +334,7 @@ ble_att_clt_parse_find_type_value_hinfo( } int -ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE return BLE_HS_ENOTSUP; @@ -343,11 +351,11 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) break; } - ble_gattc_rx_find_type_value_hinfo(conn_handle, &hinfo); + ble_gattc_rx_find_type_value_hinfo(conn_handle, cid, &hinfo); } /* Notify GATT client that the full response has been parsed. */ - ble_gattc_rx_find_type_value_complete(conn_handle, rc); + ble_gattc_rx_find_type_value_complete(conn_handle, cid, rc); return 0; } @@ -357,7 +365,7 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, +ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE @@ -382,11 +390,11 @@ ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, ble_uuid_flat(uuid, req->uuid); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } int -ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE return BLE_HS_ENOTSUP; @@ -428,13 +436,13 @@ ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) adata.value_len = data_len - sizeof(*data); adata.value = data->value; - ble_gattc_rx_read_type_adata(conn_handle, &adata); + ble_gattc_rx_read_type_adata(conn_handle, cid, &adata); os_mbuf_adj(*rxom, data_len); } done: /* Notify GATT that the response is done being parsed. */ - ble_gattc_rx_read_type_complete(conn_handle, rc); + ble_gattc_rx_read_type_complete(conn_handle, cid, rc); return rc; } @@ -444,7 +452,7 @@ done: *****************************************************************************/ int -ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle) +ble_att_clt_tx_read(uint16_t conn_handle, uint16_t cid, uint16_t handle) { #if !NIMBLE_BLE_ATT_CLT_READ return BLE_HS_ENOTSUP; @@ -465,7 +473,7 @@ ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle) req->barq_handle = htole16(handle); - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, cid, txom); if (rc != 0) { return rc; } @@ -474,14 +482,14 @@ ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle) } int -ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ return BLE_HS_ENOTSUP; #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_rsp(conn_handle, 0, rxom); + ble_gattc_rx_read_rsp(conn_handle, cid, 0, rxom); return 0; } @@ -490,7 +498,7 @@ ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset) +ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t offset) { #if !NIMBLE_BLE_ATT_CLT_READ_BLOB return BLE_HS_ENOTSUP; @@ -512,7 +520,7 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset) req->babq_handle = htole16(handle); req->babq_offset = htole16(offset); - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, cid, txom); if (rc != 0) { return rc; } @@ -521,14 +529,14 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset) } int -ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_BLOB return BLE_HS_ENOTSUP; #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_blob_rsp(conn_handle, 0, rxom); + ble_gattc_rx_read_blob_rsp(conn_handle, cid, 0, rxom); return 0; } @@ -536,8 +544,8 @@ ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) * $read multiple * *****************************************************************************/ int -ble_att_clt_tx_read_mult(uint16_t conn_handle, const uint16_t *handles, - int num_handles, bool variable) +ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t cid, + const uint16_t *handles, int num_handles, bool variable) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT return BLE_HS_ENOTSUP; @@ -565,30 +573,30 @@ ble_att_clt_tx_read_mult(uint16_t conn_handle, const uint16_t *handles, req->handles[i] = htole16(handles[i]); } - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } int -ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT return BLE_HS_ENOTSUP; #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_mult_rsp(conn_handle, 0, rxom, false); + ble_gattc_rx_read_mult_rsp(conn_handle, cid, 0, rxom, false); return 0; } int -ble_att_clt_rx_read_mult_var(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT_VAR return BLE_HS_ENOTSUP; #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_mult_rsp(conn_handle, 0, rxom, true); + ble_gattc_rx_read_mult_rsp(conn_handle, cid, 0, rxom, true); return 0; } @@ -597,7 +605,7 @@ ble_att_clt_rx_read_mult_var(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_read_group_type(uint16_t conn_handle, +ble_att_clt_tx_read_group_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid) { @@ -622,7 +630,7 @@ ble_att_clt_tx_read_group_type(uint16_t conn_handle, req->bagq_end_handle = htole16(end_handle); ble_uuid_flat(uuid, req->uuid); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } static int @@ -650,7 +658,7 @@ ble_att_clt_parse_read_group_type_adata( } int -ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE return BLE_HS_ENOTSUP; @@ -680,13 +688,13 @@ ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - ble_gattc_rx_read_group_type_adata(conn_handle, &adata); + ble_gattc_rx_read_group_type_adata(conn_handle, cid, &adata); os_mbuf_adj(*rxom, len); } done: /* Notify GATT that the response is done being parsed. */ - ble_gattc_rx_read_group_type_complete(conn_handle, rc); + ble_gattc_rx_read_group_type_complete(conn_handle, cid, rc); return rc; } @@ -695,7 +703,7 @@ done: *****************************************************************************/ int -ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, +ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t cid, uint16_t handle, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_WRITE @@ -714,12 +722,12 @@ ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, req->bawq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); } int -ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom) +ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_WRITE_NO_RSP return BLE_HS_ENOTSUP; @@ -753,24 +761,24 @@ ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, cmd->handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); } int -ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_WRITE return BLE_HS_ENOTSUP; #endif /* No payload. */ - ble_gattc_rx_write_rsp(conn_handle); + ble_gattc_rx_write_rsp(conn_handle, cid); return 0; } int -ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t handle, uint8_t *csrk, - uint32_t counter, struct os_mbuf *txom) +ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t cid, uint16_t handle, + uint8_t *csrk, uint32_t counter, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_SIGNED_WRITE return BLE_HS_ENOTSUP; @@ -856,7 +864,7 @@ ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t handle, uint8_t * if(message != NULL) nimble_platform_mem_free(message); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); err: if(message != NULL) nimble_platform_mem_free(message); os_mbuf_free_chain(txom2); @@ -868,7 +876,7 @@ err: *****************************************************************************/ int -ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, +ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t offset, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_PREP_WRITE @@ -897,7 +905,7 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, #endif if (OS_MBUF_PKTLEN(txom) > - ble_att_mtu(conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) { + ble_att_mtu_by_cid(conn_handle, cid) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) { rc = BLE_HS_EINVAL; goto err; } @@ -912,7 +920,7 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, req->bapc_offset = htole16(offset); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); err: os_mbuf_free_chain(txom); @@ -920,7 +928,7 @@ err: } int -ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_prep_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_PREP_WRITE return BLE_HS_ENOTSUP; @@ -949,7 +957,7 @@ ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) done: /* Notify GATT client that the full response has been parsed. */ - ble_gattc_rx_prep_write_rsp(conn_handle, rc, handle, offset, rxom); + ble_gattc_rx_prep_write_rsp(conn_handle, cid, rc, handle, offset, rxom); return rc; } @@ -958,7 +966,7 @@ done: *****************************************************************************/ int -ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags) +ble_att_clt_tx_exec_write(uint16_t conn_handle, uint16_t cid, uint8_t flags) { #if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE return BLE_HS_ENOTSUP; @@ -975,7 +983,7 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags) req->baeq_flags = flags; - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, cid, txom); if (rc != 0) { return rc; } @@ -984,16 +992,18 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags) } int -ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE return BLE_HS_ENOTSUP; #endif - ble_gattc_rx_exec_write_rsp(conn_handle, 0); + ble_gattc_rx_exec_write_rsp(conn_handle, cid, 0); return 0; } +#endif + /***************************************************************************** * $handle value notification * *****************************************************************************/ @@ -1008,6 +1018,7 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, struct ble_att_notify_req *req; struct os_mbuf *txom2; + uint16_t cid; int rc; if (handle == 0) { @@ -1024,7 +1035,10 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, req->banq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY); + rc = ble_att_tx(conn_handle, cid, txom2); + ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY); + return rc; err: os_mbuf_free_chain(txom); @@ -1036,8 +1050,8 @@ err: *****************************************************************************/ int -ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom) +ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_INDICATE return BLE_HS_ENOTSUP; @@ -1061,23 +1075,55 @@ ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, req->baiq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); err: os_mbuf_free_chain(txom); return rc; } +#if MYNEWT_VAL(BLE_GATTC) int -ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_INDICATE return BLE_HS_ENOTSUP; #endif /* No payload. */ - ble_gatts_rx_indicate_rsp(conn_handle); + ble_gatts_rx_indicate_rsp(conn_handle, cid); return 0; } +/***************************************************************************** +* $multiple handle value notification * +*****************************************************************************/ + +int +ble_att_clt_tx_notify_mult(uint16_t conn_handle, struct os_mbuf *txom) +{ +#if !NIMBLE_BLE_ATT_CLT_NOTIFY_MULT + return BLE_HS_ENOTSUP; +#endif + + struct os_mbuf *txom2; + uint16_t cid; + int rc; + + if (ble_att_cmd_get(BLE_ATT_OP_NOTIFY_MULTI_REQ, 0, &txom2) == NULL) { + return BLE_HS_ENOMEM; + } + + os_mbuf_concat(txom2, txom); + + cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY); + rc = ble_att_tx(conn_handle, cid, txom2); + if (cid != BLE_L2CAP_CID_ATT) { + ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY); + } + + return rc; +} + +#endif #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd.c index 6669392f..36f7c9aa 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd.c @@ -55,28 +55,67 @@ ble_att_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom) } int -ble_att_tx(uint16_t conn_handle, struct os_mbuf *txom) +ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, struct os_mbuf *txom) { - struct ble_l2cap_chan *chan; - struct ble_hs_conn *conn; int rc; + struct os_mbuf_pkthdr *omp; + + if (!txom) { + if (conn->client_att_busy) { + return 0; + } + omp = STAILQ_FIRST(&conn->att_tx_q); + if (omp == NULL) { + return 0; + } + STAILQ_REMOVE_HEAD(&conn->att_tx_q, omp_next); + txom = OS_MBUF_PKTHDR_TO_MBUF(omp); + BLE_EATT_LOG_DEBUG("%s: wakeup will send %p\n", __func__, txom); + } BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1); + + if (ble_att_is_request_op(txom->om_data[0])) { + if (conn->client_att_busy) { + BLE_EATT_LOG_DEBUG("ATT Queue %p, client busy %d\n", txom, conn->client_att_busy); + STAILQ_INSERT_TAIL(&conn->att_tx_q, OS_MBUF_PKTHDR(txom), omp_next); + return 0; + } + conn->client_att_busy = true; + } + ble_att_inc_tx_stat(txom->om_data[0]); - ble_hs_lock(); + ble_att_truncate_to_mtu(chan, txom); + rc = ble_l2cap_tx(conn, chan, txom); + assert(rc == 0); + return rc; +} + +int +ble_att_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) +{ + struct ble_l2cap_chan *chan; + struct ble_hs_conn *conn; + int rc; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (ble_hs_cfg.eatt && cid != BLE_L2CAP_CID_ATT) { + return ble_eatt_tx(conn_handle, cid, txom); + } +#endif + + ble_hs_lock(); rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc != 0) { + ble_hs_unlock(); os_mbuf_free_chain(txom); - } else { - ble_att_truncate_to_mtu(chan, txom); - rc = ble_l2cap_tx(conn, chan, txom); + return rc; } + rc = ble_att_tx_with_conn(conn, chan, txom); ble_hs_unlock(); - return rc; } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd_priv.h index 54052a98..f3090d11 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_cmd_priv.h @@ -309,6 +309,20 @@ struct ble_att_exec_write_req { */ #define BLE_ATT_EXEC_WRITE_RSP_SZ 1 +/** + * | Parameter | Size (octets) | + * +-----------------------------------------------+-------------------+ + * | Attribute Opcode | 1 | + * | Attribute Handle Length Value Tuple List | 8 to (ATT_MTU-1) | + */ +#define BLE_ATT_NOTIFY_MULTI_REQ_BASE_SZ 9 + +struct ble_att_tuple_list { + uint16_t handle; + uint16_t value_len; + uint8_t data[0]; +} __attribute__((packed)); + /** * | Parameter | Size (octets) | * +------------------------------------+-------------------+ @@ -454,8 +468,15 @@ void ble_att_indicate_rsp_write(void *payload, int len); void *ble_att_cmd_prepare(uint8_t opcode, size_t len, struct os_mbuf *txom); void *ble_att_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom); -int ble_att_tx(uint16_t conn_handle, struct os_mbuf *txom); - +int ble_att_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom); + +struct ble_l2cap_chan; +struct ble_hs_conn; +int ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, + struct os_mbuf *txom); +bool ble_att_is_response_op(uint8_t opcode); +bool ble_att_is_request_op(uint8_t opcode); +bool ble_att_is_att_pdu_op(uint8_t opcode); #ifdef __cplusplus } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_priv.h index 0e723de9..7494cb6e 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_priv.h @@ -102,6 +102,8 @@ STATS_SECT_START(ble_att_stats) STATS_SECT_ENTRY(indicate_req_tx) STATS_SECT_ENTRY(indicate_rsp_rx) STATS_SECT_ENTRY(indicate_rsp_tx) + STATS_SECT_ENTRY(multi_notify_req_rx) + STATS_SECT_ENTRY(multi_notify_req_tx) STATS_SECT_ENTRY(write_cmd_rx) STATS_SECT_ENTRY(write_cmd_tx) STATS_SECT_END @@ -171,13 +173,15 @@ SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry); /*** @gen */ struct ble_l2cap_chan *ble_att_create_chan(uint16_t conn_handle); -int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn, +int ble_att_conn_chan_find(uint16_t conn_handle, uint16_t cid, + struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan); void ble_att_inc_tx_stat(uint8_t att_op); void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan, struct os_mbuf *txom); void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan); +uint16_t ble_att_mtu_by_cid(uint16_t conn_handle, uint16_t cid); int ble_att_init(void); /*** @svr */ @@ -190,36 +194,38 @@ ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at, const ble_uuid_t *uuid, uint16_t end_handle); uint16_t ble_att_svr_prev_handle(void); -int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_svr_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id); int32_t ble_att_svr_ticks_until_tmo(const struct ble_att_svr_conn *svr, ble_npl_time_t now); -int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_svr_rx_find_type_value(uint16_t conn_handle, +int ble_att_svr_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_svr_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_type(uint16_t conn_handle, +int ble_att_svr_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_group_type(uint16_t conn_handle, +int ble_att_svr_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read(uint16_t conn_handle, +int ble_att_svr_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_blob(uint16_t conn_handle, +int ble_att_svr_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_mult_var(uint16_t conn_handle, +int ble_att_svr_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_mult(uint16_t conn_handle, +int ble_att_svr_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_write(uint16_t conn_handle, +int ble_att_svr_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_svr_rx_prep_write(uint16_t conn_handle, +int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_svr_rx_signed_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_svr_rx_prep_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_exec_write(uint16_t conn_handle, +int ble_att_svr_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_notify(uint16_t conn_handle, +int ble_att_svr_rx_notify(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_indicate(uint16_t conn_handle, +int ble_att_svr_rx_notify_multi(uint16_t conn_handle, uint16_t cid, + struct os_mbuf **rxom); +int ble_att_svr_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list); int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle, @@ -231,9 +237,12 @@ int ble_att_svr_init(void); void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle); void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle); -int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, +int ble_att_svr_tx_error_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom, uint8_t req_op, uint16_t handle, uint8_t error_code); +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) +uint8_t ble_att_svr_security_mode_1_level(void); +#endif /*** $clt */ /** An information-data entry in a find information response. */ @@ -264,52 +273,56 @@ struct ble_att_read_group_type_adata { uint8_t *value; }; -int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_rx_error(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu); -int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle); -int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, +int ble_att_clt_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t cid, uint16_t handle); +int ble_att_clt_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t offset); -int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_mult(uint16_t conn_handle, +int ble_att_clt_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t cid, const uint16_t *handles, int num_handles, bool variable); -int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_rx_read_mult_var(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, +int ble_att_clt_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid); -int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_group_type(uint16_t conn_handle, +int ble_att_clt_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_group_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid128); -int ble_att_clt_rx_read_group_type(uint16_t conn_handle, +int ble_att_clt_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, +int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle); -int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, +int ble_att_clt_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, uint16_t attribute_type, const void *attribute_value, int value_len); -int ble_att_clt_rx_find_type_value(uint16_t conn_handle, +int ble_att_clt_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom); -int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom); -int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, - uint16_t offset, struct os_mbuf *txom); -int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags); -int ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t handle, - uint8_t * csrk, uint32_t counter, - struct os_mbuf * txom); -int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom); +int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom); +int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t cid, + uint16_t handle, uint16_t offset, + struct os_mbuf *txom); +int ble_att_clt_rx_prep_write(uint16_t conn_handle, uint16_t cid, + struct os_mbuf **rxom); +int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint16_t cid, + uint8_t flags); +int ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t cid, + uint16_t handle, uint8_t * csrk, + uint32_t counter, struct os_mbuf * txom); +int ble_att_clt_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, struct os_mbuf *txom); -int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom); -int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom); +int ble_att_clt_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_notify_mult(uint16_t conn_handle, struct os_mbuf *txom); #ifdef __cplusplus } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_svr.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_svr.c index f15b4b0b..517b1e2d 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_svr.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_att_svr.c @@ -28,6 +28,8 @@ #include "esp_nimble_mem.h" #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTS) + /** * ATT server - Attribute Protocol * @@ -325,7 +327,7 @@ ble_att_svr_check_perms(uint16_t conn_handle, int is_read, /* In SC Only mode all characteristics requiring security * require it on level 4 */ - if (MYNEWT_VAL(BLE_SM_SC_ONLY)) { + if (ble_hs_cfg.sm_sc_only) { if (!sec_state.authenticated || !sec_state.encrypted) { *out_att_err = BLE_ATT_ERR_INSUFFICIENT_AUTHEN; @@ -371,7 +373,9 @@ ble_att_svr_check_perms(uint16_t conn_handle, int is_read, if (author) { /* XXX: Prompt user for authorization. */ + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); if(!conn->bhc_sec_state.authorize){ rc = ble_gap_authorize_event(conn_handle, entry->ha_handle_id, is_read); if (rc == BLE_GAP_AUTHORIZE_REJECT) { @@ -623,7 +627,7 @@ ble_att_svr_write_handle(uint16_t conn_handle, uint16_t attr_handle, } int -ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, +ble_att_svr_tx_error_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom, uint8_t req_op, uint16_t handle, uint8_t error_code) { struct ble_att_error_rsp *rsp; @@ -640,7 +644,7 @@ ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, rsp->baep_handle = htole16(handle); rsp->baep_error_code = error_code; - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } /** @@ -667,13 +671,10 @@ ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, * field. */ static int -ble_att_svr_tx_rsp(uint16_t conn_handle, int hs_status, struct os_mbuf *om, +ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_mbuf *om, uint8_t att_op, uint8_t err_status, uint16_t err_handle) { - struct ble_l2cap_chan *chan; - struct ble_hs_conn *conn; int do_tx; - int rc; if (hs_status != 0 && err_status == 0) { /* Processing failed, but err_status of 0 means don't send error. */ @@ -683,28 +684,14 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int hs_status, struct os_mbuf *om, } if (do_tx) { - ble_hs_lock(); - - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); - if (rc != 0) { - /* No longer connected. */ - hs_status = rc; - } else { - if (hs_status == 0) { - BLE_HS_DBG_ASSERT(om != NULL); - - ble_att_inc_tx_stat(om->om_data[0]); - ble_att_truncate_to_mtu(chan, om); - hs_status = ble_l2cap_tx(conn, chan, om); - om = NULL; - if (hs_status != 0) { - err_status = BLE_ATT_ERR_UNLIKELY; - } - } + if (hs_status == 0) { + hs_status = ble_att_tx(conn_handle, cid, om); + om = NULL; + if (hs_status) { + err_status = BLE_ATT_ERR_UNLIKELY; + } } - ble_hs_unlock(); - if (hs_status != 0) { STATS_INC(ble_att_stats, error_rsp_tx); @@ -715,7 +702,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int hs_status, struct os_mbuf *om, os_mbuf_adj(om, OS_MBUF_PKTLEN(om)); } if (om != NULL) { - ble_att_svr_tx_error_rsp(conn_handle, om, att_op, + ble_att_svr_tx_error_rsp(conn_handle, cid, om, att_op, err_handle, err_status); om = NULL; } @@ -742,7 +729,7 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **rxom, txom = NULL; ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, NULL, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, NULL, &chan); if (rc == 0) { mtu = chan->my_mtu; } @@ -774,7 +761,7 @@ done: } int -ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { struct ble_att_mtu_cmd *cmd; struct ble_l2cap_chan *chan; @@ -787,6 +774,10 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) txom = NULL; mtu = 0; + if (cid != BLE_L2CAP_CID_ATT) { + return BLE_HS_ENOTSUP; + } + rc = ble_att_svr_pullup_req_base(rxom, sizeof(*cmd), &att_err); if (rc != 0) { goto done; @@ -804,12 +795,12 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_MTU_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, BLE_L2CAP_CID_ATT, rc, txom, BLE_ATT_OP_MTU_REQ, att_err, 0); if (rc == 0) { ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc == 0) { ble_att_set_peer_mtu(chan, mtu); chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU; @@ -908,7 +899,7 @@ done: } static int -ble_att_svr_build_find_info_rsp(uint16_t conn_handle, +ble_att_svr_build_find_info_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, struct os_mbuf **rxom, struct os_mbuf **out_txom, @@ -937,7 +928,7 @@ ble_att_svr_build_find_info_rsp(uint16_t conn_handle, /* Write the variable length Information Data field, populating the format * field as appropriate. */ - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); rc = ble_att_svr_fill_info(start_handle, end_handle, txom, mtu, &rsp->bafp_format); if (rc != 0) { @@ -954,7 +945,7 @@ done: } int -ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_FIND_INFO) return BLE_HS_ENOTSUP; @@ -991,7 +982,7 @@ ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - rc = ble_att_svr_build_find_info_rsp(conn_handle, + rc = ble_att_svr_build_find_info_rsp(conn_handle, cid, start_handle, end_handle, rxom, &txom, &att_err); if (rc != 0) { @@ -1002,7 +993,7 @@ ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_FIND_INFO_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_FIND_INFO_REQ, att_err, err_handle); return rc; } @@ -1217,7 +1208,7 @@ done: } static int -ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, +ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, ble_uuid16_t attr_type, @@ -1244,7 +1235,7 @@ ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, } /* Write the variable length Information Data field. */ - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); rc = ble_att_svr_fill_type_value(conn_handle, start_handle, end_handle, attr_type, *rxom, txom, mtu, @@ -1261,7 +1252,7 @@ done: } int -ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_FIND_TYPE) return BLE_HS_ENOTSUP; @@ -1299,7 +1290,7 @@ ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) rc = BLE_HS_EBADDATA; goto done; } - rc = ble_att_svr_build_find_type_value_rsp(conn_handle, start_handle, + rc = ble_att_svr_build_find_type_value_rsp(conn_handle, cid, start_handle, end_handle, attr_type, rxom, &txom, &att_err); if (rc != 0) { @@ -1310,7 +1301,7 @@ ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, att_err, err_handle); return rc; @@ -1323,20 +1314,38 @@ static void ble_att_svr_make_conn_aware(uint16_t conn_handle) { int i = 0; conn = ble_hs_conn_find_assert(conn_handle); - conn->bhc_gatt_svr.aware_state = true; + conn->bhc_gatt_svr.aware_state = false; + conn->bhc_gatt_svr.half_aware = 1; ble_hs_conn_addrs(conn, &addrs); for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { - ble_gatts_conn_aware_states[i].aware = true; + ble_gatts_conn_aware_states[i].aware = false; + ble_gatts_conn_aware_states[i].half_aware = 1; } } } static bool ble_att_svr_check_conn_aware(uint16_t conn_handle) { struct ble_hs_conn *conn; + struct ble_hs_conn_addrs addrs; + conn = ble_hs_conn_find_assert(conn_handle); + + if (conn->bhc_gatt_svr.half_aware == 1) { + conn->bhc_gatt_svr.half_aware = 0; + conn->bhc_gatt_svr.aware_state = true; + + ble_hs_conn_addrs(conn, &addrs); + for(int i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { + if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, + addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { + ble_gatts_conn_aware_states[i].half_aware = 0; + ble_gatts_conn_aware_states[i].aware = true; + } + } + } return conn->bhc_gatt_svr.aware_state; } @@ -1348,7 +1357,7 @@ static uint8_t * ble_att_svr_get_csfs(uint16_t conn_handle) { #endif static int -ble_att_svr_build_read_type_rsp(uint16_t conn_handle, +ble_att_svr_build_read_type_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid, struct os_mbuf **rxom, @@ -1391,7 +1400,7 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, goto done; } - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); /* Find all matching attributes, writing a record for each. */ entry = NULL; @@ -1463,7 +1472,7 @@ done: } int -ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_TYPE) return BLE_HS_ENOTSUP; @@ -1471,6 +1480,10 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) struct ble_att_read_type_req *req; uint16_t start_handle, end_handle; +#if MYNEWT_VAL(BLE_GATT_CACHING) + struct ble_hs_conn *conn; + struct ble_hs_conn_addrs addrs; +#endif struct os_mbuf *txom; uint16_t err_handle; uint16_t pktlen; @@ -1517,14 +1530,39 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) #if MYNEWT_VAL(BLE_GATT_CACHING) ble_hs_lock(); - ble_att_svr_make_conn_aware(conn_handle); - ble_hs_unlock(); + if (uuid.u.type == BLE_UUID_TYPE_16 && ( + uuid.u16.value == BLE_ATT_UUID_INCLUDE || + uuid.u16.value == BLE_ATT_UUID_CHARACTERISTIC || + uuid.u16.value == BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16)) { + int i = 0; - if(rc != 0) { - goto done; + conn = ble_hs_conn_find_assert(conn_handle); + conn->bhc_gatt_svr.aware_state = true; + conn->bhc_gatt_svr.half_aware = 0; + + ble_hs_conn_addrs(conn, &addrs); + for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { + if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, + addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { + ble_gatts_conn_aware_states[i].aware = true; + ble_gatts_conn_aware_states[i].half_aware = 0; + } + } + } else { + if((ble_att_svr_get_csfs(conn_handle)[0] & 1) + && ble_svc_gatt_csf_handle() != err_handle ) { + if (!ble_att_svr_check_conn_aware(conn_handle)) { + att_err = BLE_ATT_ERR_DB_OUT_OF_SYNC; + rc = BLE_HS_EREJECT; + ble_att_svr_make_conn_aware(conn_handle); + ble_hs_unlock(); + goto done; + } + } } + ble_hs_unlock(); #endif - rc = ble_att_svr_build_read_type_rsp(conn_handle, start_handle, end_handle, + rc = ble_att_svr_build_read_type_rsp(conn_handle, cid, start_handle, end_handle, &uuid.u, rxom, &txom, &att_err, &err_handle); if (rc != 0) { @@ -1534,13 +1572,13 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_TYPE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_TYPE_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ) return BLE_HS_ENOTSUP; @@ -1597,13 +1635,13 @@ ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) } done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_BLOB) return BLE_HS_ENOTSUP; @@ -1665,13 +1703,13 @@ ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_BLOB_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_BLOB_REQ, att_err, err_handle); return rc; } static int -ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, +ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom, struct os_mbuf **out_txom, uint8_t *att_err, @@ -1682,7 +1720,7 @@ ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, uint16_t mtu; int rc; - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); rc = ble_att_svr_pkt(rxom, &txom, att_err); if (rc != 0) { @@ -1732,7 +1770,7 @@ done: } int -ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_MULT) return BLE_HS_ENOTSUP; @@ -1763,18 +1801,18 @@ ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) ble_hs_unlock(); #endif - rc = ble_att_svr_build_read_mult_rsp(conn_handle, rxom, &txom, &att_err, + rc = ble_att_svr_build_read_mult_rsp(conn_handle, cid, rxom, &txom, &att_err, &err_handle); #if MYNEWT_VAL(BLE_GATT_CACHING) done : #endif - return ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_MULT_REQ, + return ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_MULT_REQ, att_err, err_handle); } static int -ble_att_svr_build_read_mult_rsp_var(uint16_t conn_handle, +ble_att_svr_build_read_mult_rsp_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom, struct os_mbuf **out_txom, uint8_t *att_err, @@ -1787,7 +1825,7 @@ ble_att_svr_build_read_mult_rsp_var(uint16_t conn_handle, struct os_mbuf *tmp = NULL; int rc; - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); rc = ble_att_svr_pkt(rxom, &txom, att_err); if (rc != 0) { @@ -1856,7 +1894,7 @@ done: } int -ble_att_svr_rx_read_mult_var(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_MULT) return BLE_HS_ENOTSUP; @@ -1887,13 +1925,13 @@ ble_att_svr_rx_read_mult_var(uint16_t conn_handle, struct os_mbuf **rxom) ble_hs_unlock(); #endif - rc = ble_att_svr_build_read_mult_rsp_var(conn_handle, rxom, &txom, &att_err, + rc = ble_att_svr_build_read_mult_rsp_var(conn_handle, cid, rxom, &txom, &att_err, &err_handle); #if MYNEWT_VAL(BLE_GATT_CACHING) done: #endif - return ble_att_svr_tx_rsp(conn_handle, rc, txom, + return ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_MULT_VAR_REQ, att_err, err_handle); } @@ -1923,7 +1961,20 @@ ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, return rc; } - rc = ble_uuid_init_from_buf(uuid, val, attr_len); + /** + * - For Primary/Secondary Services: attr_len is typically 2 (16-bit), 4 (32-bit), or 16 (128-bit) + * - For Included Services: + * - When UUID is 16-bit, value length = 2 (start) + 2 (end) + 2 (uuid) = 6 + * - So, attr_len == 6 implies 16-bit UUID, and the UUID is at offset 4 + */ + if (attr_len == 6) { + // Adjust attr_len to pass only UUID (last 2 bytes) to uuid init + attr_len = 2; + rc = ble_uuid_init_from_buf(uuid, val + 4, attr_len); + } else { + // For normal services (not included), UUID starts at offset 0 + rc = ble_uuid_init_from_buf(uuid, val, attr_len); + } return rc; } @@ -1962,7 +2013,7 @@ ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu, * @return 0 on success; BLE_HS error code on failure. */ static int -ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, +ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *group_uuid, @@ -1992,7 +2043,7 @@ ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, entry = NULL; - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); /* Just reuse the request buffer for the response. */ txom = *rxom; @@ -2134,7 +2185,7 @@ done: } int -ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_GROUP_TYPE) return BLE_HS_ENOTSUP; @@ -2203,9 +2254,10 @@ ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - rc = ble_att_svr_build_read_group_type_rsp(conn_handle, start_handle, - end_handle, &uuid.u, - rxom, &txom, &att_err, + rc = ble_att_svr_build_read_group_type_rsp(conn_handle, cid, + start_handle, end_handle, + &uuid.u, rxom, + &txom, &att_err, &err_handle); if (rc != 0) { goto done; @@ -2214,7 +2266,7 @@ ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_GROUP_TYPE_REQ, att_err, err_handle); return rc; @@ -2249,7 +2301,7 @@ done: } int -ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_WRITE) return BLE_HS_ENOTSUP; @@ -2309,13 +2361,13 @@ ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_WRITE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_WRITE_REQ, att_err, handle); return rc; } int -ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_WRITE_NO_RSP) return BLE_HS_ENOTSUP; @@ -2352,12 +2404,16 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom) } int -ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_signed_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_SIGNED_WRITE) return BLE_HS_ENOTSUP; #endif + if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 && ble_hs_cfg.eatt) { + return BLE_HS_ENOTSUP; + } + struct ble_att_signed_write_cmd *req; struct ble_store_value_sec value_sec; struct ble_store_key_sec key_sec; @@ -2456,10 +2512,10 @@ ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom) goto err; } - if(message != NULL) nimble_platform_mem_free(message); + nimble_platform_mem_free(message); return 0; err: - if(message != NULL) nimble_platform_mem_free(message); + nimble_platform_mem_free(message); return rc; } @@ -2727,7 +2783,7 @@ ble_att_svr_insert_prep_entry(uint16_t conn_handle, } int -ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_prep_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_QUEUED_WRITE) return BLE_HS_ENOTSUP; @@ -2817,13 +2873,13 @@ ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_PREP_WRITE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_PREP_WRITE_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_QUEUED_WRITE) return BLE_HS_ENOTSUP; @@ -2907,13 +2963,13 @@ done: ble_att_svr_prep_clear(&prep_list); } - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_EXEC_WRITE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_EXEC_WRITE_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_notify(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_NOTIFY) return BLE_HS_ENOTSUP; @@ -2942,7 +2998,7 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) /* All indications shall be confirmed, but only these with required * security established shall be pass to application */ - if (MYNEWT_VAL(BLE_SM_LVL) >= 2 && !sec_state.encrypted) { + if (ble_hs_cfg.sm_sec_lvl >= 2 && !sec_state.encrypted) { return 0; } @@ -2955,6 +3011,67 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) return 0; } +int +ble_att_svr_rx_notify_multi(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) +{ +#if !MYNEWT_VAL(BLE_ATT_SVR_NOTIFY_MULTI) + return BLE_HS_ENOTSUP; +#endif + + struct ble_att_tuple_list *req; + uint16_t handle; + int rc = 0; + uint16_t pkt_len; + struct os_mbuf *tmp; + uint16_t attr_len; + + pkt_len = OS_MBUF_PKTLEN(*rxom); + while (pkt_len > 0) { + rc = ble_att_svr_pullup_req_base(rxom, sizeof(struct ble_att_tuple_list), NULL); + if (rc != 0) { + return BLE_HS_ENOMEM; + } + + req = (struct ble_att_tuple_list *)(*rxom)->om_data; + + handle = le16toh(req->handle); + attr_len = le16toh(req->value_len); + + os_mbuf_adj(*rxom, 4); + + if (attr_len > BLE_ATT_ATTR_MAX_LEN) { + BLE_HS_LOG_ERROR("attr length (%d) > max (%d)", + attr_len, BLE_ATT_ATTR_MAX_LEN); + rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + goto done; + } + + tmp = os_msys_get_pkthdr(attr_len, 0); + if (!tmp) { + BLE_HS_LOG_ERROR("not enough resources, aborting"); + rc = BLE_ATT_ERR_INSUFFICIENT_RES; + goto done; + } + + rc = os_mbuf_appendfrom(tmp, *rxom, 0, attr_len); + if (rc) { + BLE_HS_LOG_ERROR("not enough resources, aborting"); + rc = BLE_ATT_ERR_INSUFFICIENT_RES; + goto done; + } + + ble_gap_notify_rx_event(conn_handle, handle, tmp, 0); + + os_mbuf_adj(*rxom, attr_len); + pkt_len = OS_MBUF_PKTLEN(*rxom); + } +done: + os_mbuf_free_chain(*rxom); + *rxom = NULL; + + return rc; +} + /** * @return 0 on success; nonzero on failure. */ @@ -2988,7 +3105,7 @@ done: } int -ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_INDICATE) return BLE_HS_ENOTSUP; @@ -3033,7 +3150,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) /* All indications shall be confirmed, but only these with required * security established shall be pass to application */ - if (MYNEWT_VAL(BLE_SM_LVL) >= 2 && !sec_state.encrypted) { + if (ble_hs_cfg.sm_sec_lvl >= 2 && !sec_state.encrypted) { goto done; } @@ -3046,7 +3163,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_INDICATE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_INDICATE_REQ, att_err, handle); return rc; } @@ -3366,4 +3483,46 @@ int ble_att_fill_database_info(uint8_t *out_data) return 0; } #endif + +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) +/** + * Return the highest Security Mode 1 Level requirement. + * + * @return Maximum level requirement + */ +uint8_t +ble_att_svr_security_mode_1_level() +{ + struct ble_att_svr_entry *entry; + uint8_t highest_security_level = 0x01; //No Security + uint8_t sec_level; + uint8_t flags; + + for (entry = STAILQ_FIRST(&ble_att_svr_list); + entry != NULL; + entry = STAILQ_NEXT(entry, ha_next)) { + + flags = entry->ha_flags; + if ((flags & BLE_ATT_F_READ_AUTHEN) || (flags & BLE_ATT_F_WRITE_AUTHEN)) { + sec_level = 0x03; //Authenticated pairing with encryption + /* This is the highest currently supported value. + * Break here. + */ + highest_security_level = 0x03; + break; + } else if ((flags & BLE_ATT_F_READ_ENC) || (flags & BLE_ATT_F_WRITE_ENC)) { + sec_level = 0x02; //Unauthenticated pairing with encryption + } else { + sec_level = 0x01; //No security (No authentication and no encryption) + } + + if (sec_level > highest_security_level) { + highest_security_level = sec_level; + } + } + + return highest_security_level; +} +#endif +#endif #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_ead.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_ead.c index 8f437fa8..be497b52 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_ead.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_ead.c @@ -68,15 +68,18 @@ static int ead_encrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], const uint8_ int err; uint8_t nonce[BLE_EAD_NONCE_SIZE]; + /** Nonce is concatenation of Randomizer and IV */ err = ble_ead_generate_nonce(iv, randomizer, nonce); if (err != 0) { return -1; } + /** Copying Randomizer to the start of encrypted advertisment data */ memcpy(encrypted_payload, nonce, BLE_EAD_RANDOMIZER_SIZE); err = ble_aes_ccm_encrypt(session_key, nonce, payload, payload_size, ble_ead_aad, BLE_EAD_AAD_SIZE, &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE], BLE_EAD_MIC_SIZE); + if (err != 0) { BLE_HS_LOG(DEBUG, "Failed to encrypt the payload (ble_ccm_encrypt err %d)", err); return -1; @@ -178,30 +181,6 @@ int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], const uint8_t i return ead_decrypt(session_key, iv, encrypted_payload, encrypted_payload_size, payload); } -int ble_ead_serialize_data(const struct enc_adv_data *input, uint8_t *output) -{ - if ( input == NULL) { - BLE_HS_LOG(DEBUG, "input is NULL"); - return 0; - } - - if ( output == NULL) { - BLE_HS_LOG(DEBUG, "output is NULL"); - return 0; - } - - uint8_t adv_data_len = input->len; - uint8_t data_len = adv_data_len + 1; - - output[0] = data_len; - output[1] = input->type; - - memcpy(&output[2], input->data, adv_data_len); - - return data_len + 1; - -} - #endif /* ENC_ADV_DATA */ #ifdef __cplusplus diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt.c new file mode 100644 index 00000000..1bbf02ac --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt.c @@ -0,0 +1,605 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + +#include +#include +#include "host/ble_hs_log.h" +#include "ble_att_cmd_priv.h" +#include "ble_hs_priv.h" +#include "ble_l2cap_priv.h" +#include "ble_eatt_priv.h" +#include "services/gatt/ble_svc_gatt.h" + +struct ble_eatt { + SLIST_ENTRY(ble_eatt) next; + uint16_t conn_handle; + struct ble_l2cap_chan *chan; + uint8_t client_op; + + /* Packet transmit queue */ + STAILQ_HEAD(, os_mbuf_pkthdr) eatt_tx_q; + + struct ble_npl_event setup_ev; + struct ble_npl_event wakeup_ev; +}; + +SLIST_HEAD(ble_eatt_list, ble_eatt); + +static struct ble_eatt_list g_ble_eatt_list; +static ble_eatt_att_rx_fn ble_eatt_att_rx_cb; + +#define BLE_EATT_DATABUF_SIZE ( \ + MYNEWT_VAL(BLE_EATT_MTU) + \ + 2 + \ + sizeof (struct os_mbuf_pkthdr) + \ + sizeof (struct os_mbuf)) + +#define BLE_EATT_MEMBLOCK_SIZE \ + (OS_ALIGN(BLE_EATT_DATABUF_SIZE, 4)) + +#define BLE_EATT_MEMPOOL_SIZE \ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, BLE_EATT_MEMBLOCK_SIZE) +static os_membuf_t ble_eatt_conn_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM), + sizeof(struct ble_eatt)) +]; +static struct os_mempool ble_eatt_conn_pool; +static os_membuf_t ble_eatt_sdu_coc_mem[BLE_EATT_MEMPOOL_SIZE]; +struct os_mbuf_pool ble_eatt_sdu_os_mbuf_pool; +static struct os_mempool ble_eatt_sdu_mbuf_mempool; + +static struct ble_gap_event_listener ble_eatt_listener; + +static struct ble_npl_event g_read_sup_cl_feat_ev; +static struct ble_npl_event g_read_sup_srv_feat_ev; + +static void ble_eatt_setup_cb(struct ble_npl_event *ev); +static void ble_eatt_start(uint16_t conn_handle); + +static struct ble_eatt * +ble_eatt_find_not_busy(uint16_t conn_handle) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if ((eatt->conn_handle == conn_handle) && !eatt->client_op && eatt->chan) { + return eatt; + } + } + return NULL; +} + +static struct ble_eatt * +ble_eatt_find_by_conn_handle(uint16_t conn_handle) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if (eatt->conn_handle == conn_handle) { + return eatt; + } + } + return NULL; + +} + +static struct ble_eatt * +ble_eatt_find_by_conn_handle_and_busy_op(uint16_t conn_handle, uint8_t op) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if (eatt->conn_handle == conn_handle && eatt->client_op == op) { + return eatt; + } + } + return NULL; + +} + +static struct ble_eatt * +ble_eatt_find(uint16_t conn_handle, uint16_t cid) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if ((eatt->conn_handle == conn_handle) && + (eatt->chan) && + (eatt->chan->scid == cid)) { + return eatt; + } + } + return NULL; + +} + +static int +ble_eatt_prepare_rx_sdu(struct ble_l2cap_chan *chan) +{ + int rc; + struct os_mbuf *om; + + om = os_mbuf_get_pkthdr(&ble_eatt_sdu_os_mbuf_pool, 0); + if (!om) { + BLE_EATT_LOG_ERROR("eatt: no memory for sdu\n"); + return BLE_HS_ENOMEM; + } + + rc = ble_l2cap_recv_ready(chan, om); + if (rc) { + BLE_EATT_LOG_ERROR("eatt: Failed to supply RX SDU conn_handle 0x%04x (status=%d)\n", + chan->conn_handle, rc); + os_mbuf_free_chain(om); + } + return rc; +} + +static void +ble_eatt_wakeup_cb(struct ble_npl_event *ev) +{ + struct ble_eatt *eatt; + struct os_mbuf *txom; + struct os_mbuf_pkthdr *omp; + struct ble_l2cap_chan_info info; + + eatt = ble_npl_event_get_arg(ev); + assert(eatt); + + omp = STAILQ_FIRST(&eatt->eatt_tx_q); + if (omp != NULL) { + STAILQ_REMOVE_HEAD(&eatt->eatt_tx_q, omp_next); + + txom = OS_MBUF_PKTHDR_TO_MBUF(omp); + ble_l2cap_get_chan_info(eatt->chan, &info); + ble_eatt_tx(eatt->conn_handle, info.dcid, txom); + } +} + +static struct ble_eatt * +ble_eatt_alloc(void) +{ + struct ble_eatt *eatt; + + eatt = os_memblock_get(&ble_eatt_conn_pool); + if (eatt) { + SLIST_INSERT_HEAD(&g_ble_eatt_list, eatt, next); + } else { + BLE_EATT_LOG_DEBUG("eatt: Failed to allocate new eatt context\n"); + return NULL; + } + + eatt->conn_handle = BLE_HS_CONN_HANDLE_NONE; + eatt->chan = NULL; + eatt->client_op = 0; + + STAILQ_INIT(&eatt->eatt_tx_q); + ble_npl_event_init(&eatt->setup_ev, ble_eatt_setup_cb, eatt); + ble_npl_event_init(&eatt->wakeup_ev, ble_eatt_wakeup_cb, eatt); + return eatt; +} + +static void +ble_eatt_free(struct ble_eatt *eatt) +{ + struct os_mbuf_pkthdr *omp; + + while ((omp = STAILQ_FIRST(&eatt->eatt_tx_q)) != NULL) { + STAILQ_REMOVE_HEAD(&eatt->eatt_tx_q, omp_next); + os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(omp)); + } + + SLIST_REMOVE(&g_ble_eatt_list, eatt, ble_eatt, next); + os_memblock_put(&ble_eatt_conn_pool, eatt); +} + +static int +ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) +{ + struct ble_eatt *eatt = arg; + struct ble_gap_conn_desc desc; + uint8_t opcode; + int rc; + + switch (event->type) { + case BLE_L2CAP_EVENT_COC_CONNECTED: + BLE_EATT_LOG_DEBUG("eatt: Connected \n"); + if (event->connect.status) { + ble_eatt_free(eatt); + return 0; + } + eatt->chan = event->connect.chan; + ble_gap_eatt_event(event->connect.conn_handle, 0, event->connect.chan->scid); + break; + case BLE_L2CAP_EVENT_COC_DISCONNECTED: + BLE_EATT_LOG_DEBUG("eatt: Disconnected \n"); + ble_eatt_free(eatt); + ble_gap_eatt_event(event->disconnect.conn_handle, 1, event->disconnect.chan->scid); + break; + case BLE_L2CAP_EVENT_COC_ACCEPT: + BLE_EATT_LOG_DEBUG("eatt: Accept request\n"); + + eatt = ble_eatt_alloc(); + if (!eatt) { + return BLE_HS_ENOMEM; + } + eatt->conn_handle = event->accept.conn_handle; + event->accept.chan->cb_arg = eatt; + + rc = ble_eatt_prepare_rx_sdu(event->accept.chan); + if (rc) { + ble_eatt_free(eatt); + return rc; + } + break; + case BLE_L2CAP_EVENT_COC_TX_UNSTALLED: + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); + break; + case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: + assert(eatt->chan == event->receive.chan); + opcode = event->receive.sdu_rx->om_data[0]; + if (ble_att_is_response_op(opcode)) { + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); + } else if (!ble_att_is_att_pdu_op(opcode)) { + /* As per BLE 5.4 Standard, Vol. 3, Part G, section 5.3.2 + * (ENHANCED ATT BEARER L2CAP INTEROPERABILITY REQUIREMENTS: + * Channel Requirements): + * All packets sent on this L2CAP channel shall be Attribute PDUs. + * + * Disconnect peer with invalid behavior. + */ + ble_l2cap_disconnect(eatt->chan); + return BLE_HS_EREJECT; + } + + assert (!ble_gap_conn_find(event->receive.conn_handle, &desc)); + /* As per BLE 5.4 Standard, Vol. 3, Part G, section 5.3.2 + * (ENHANCED ATT BEARER L2CAP INTEROPERABILITY REQUIREMENTS: + * Channel Requirements): + * The channel shall be encrypted. + * + * Disconnect peer with invalid behavior - ATT PDU received before + * encryption. + */ + if (!desc.sec_state.encrypted) { + ble_l2cap_disconnect(eatt->chan); + return BLE_HS_EREJECT; + } + + ble_eatt_att_rx_cb(event->receive.conn_handle, eatt->chan->scid, &event->receive.sdu_rx); + if (event->receive.sdu_rx) { + os_mbuf_free_chain(event->receive.sdu_rx); + event->receive.sdu_rx = NULL; + } + rc = ble_eatt_prepare_rx_sdu(event->receive.chan); + if (rc) { + /* Receiving L2CAP data is no longer possible, terminate connection */ + ble_l2cap_disconnect(eatt->chan); + return BLE_HS_ENOMEM; + } + break; + default: + break; + } + + return 0; +} + +static void +ble_eatt_setup_cb(struct ble_npl_event *ev) +{ + struct ble_eatt *eatt; + struct os_mbuf *om; + int rc; + + eatt = ble_npl_event_get_arg(ev); + assert(eatt); + + om = os_mbuf_get_pkthdr(&ble_eatt_sdu_os_mbuf_pool, 0); + if (!om) { + ble_eatt_free(eatt); + BLE_EATT_LOG_ERROR("eatt: no memory for sdu\n"); + return; + } + + BLE_EATT_LOG_DEBUG("eatt: connecting eatt on conn_handle 0x%04x\n", eatt->conn_handle); + rc = ble_l2cap_enhanced_connect(eatt->conn_handle, BLE_EATT_PSM, + MYNEWT_VAL(BLE_EATT_MTU), 1, &om, ble_eatt_l2cap_event_fn, eatt); + if (rc) { + BLE_EATT_LOG_ERROR("eatt: Failed to connect EATT on conn_handle 0x%04x (status=%d)\n", + eatt->conn_handle, rc); + os_mbuf_free_chain(om); + ble_eatt_free(eatt); + } +} + +static int +ble_gatt_eatt_write_cl_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) { + BLE_EATT_LOG_DEBUG("eatt: Cannot write to Client Supported features on peer device\n"); + return 0; + } + + ble_eatt_start(conn_handle); + return 0; +} + +static int +ble_gatt_eatt_read_cl_uuid_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + uint8_t client_supported_feat; + int rc; + + if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) { + BLE_EATT_LOG_DEBUG("eatt: Cannot find Client Supported features on peer device\n"); + return BLE_HS_EDONE; + } + + if (attr == NULL) { + BLE_EATT_LOG_ERROR("eatt: Invalid attribute \n"); + return BLE_HS_EDONE; + } + + if (error->status == 0) { + client_supported_feat = MYNEWT_VAL(BLE_CLIENT_SUPPORTED_FEATURES); + rc = ble_gattc_write_flat(conn_handle, attr->handle, &client_supported_feat, 1, + ble_gatt_eatt_write_cl_cb, NULL); + BLE_EATT_LOG_DEBUG("eatt: %s , write rc = %d \n", __func__, rc); + assert(rc == 0); + return 0; + } + + return BLE_HS_EDONE; +} + +static int +ble_gatt_eatt_read_uuid_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + uint8_t supported_features; + int rc; + + if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) { + BLE_EATT_LOG_DEBUG("eatt: Cannot find Server Supported features on peer device\n"); + return BLE_HS_EDONE; + } + + if (attr == NULL) { + BLE_EATT_LOG_ERROR("eatt: Invalid attribute \n"); + return BLE_HS_EDONE; + } + + rc = os_mbuf_copydata(attr->om, 0, 1, &supported_features); + if (rc) { + BLE_EATT_LOG_ERROR("eatt: Cannot read srv supported features \n"); + return BLE_HS_EDONE; + } + + if (supported_features & 0x01) { + ble_npl_event_set_arg(&g_read_sup_cl_feat_ev, (void *)((uintptr_t) conn_handle)); + ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_cl_feat_ev); + } + return BLE_HS_EDONE; +} + +static void +ble_gatt_eatt_read_svr_uuid(struct ble_npl_event *ev) +{ + uint16_t conn_handle; + + conn_handle = (uint16_t)((uintptr_t)(ble_npl_event_get_arg(ev))); + + ble_gattc_read_by_uuid(conn_handle, 1, 0xffff, + BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16), + ble_gatt_eatt_read_uuid_cb, NULL); +} + +static void +ble_gatt_eatt_read_cl_uuid(struct ble_npl_event *ev) +{ + uint16_t conn_handle; + + conn_handle = (uint16_t)((uintptr_t)(ble_npl_event_get_arg(ev))); + + ble_gattc_read_by_uuid(conn_handle, 1, 0xffff, + BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16), + ble_gatt_eatt_read_cl_uuid_cb, NULL); +} + +static int +ble_eatt_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_eatt *eatt; + + switch (event->type) { + case BLE_GAP_EVENT_ENC_CHANGE: + if (event->enc_change.status != 0) { + return 0; + } + + if (ble_hs_cfg.eatt == 0) { + return 0; + } + + /* Don't try to connect if already connected */ + if (ble_eatt_find_by_conn_handle(event->enc_change.conn_handle)) { + return 0; + } + + BLE_EATT_LOG_DEBUG("eatt: Encryption enabled, connecting EATT (conn_handle=0x%04x)\n", + event->enc_change.conn_handle); + + ble_npl_event_set_arg(&g_read_sup_srv_feat_ev, (void *)((uintptr_t)(event->enc_change.conn_handle))); + ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_srv_feat_ev); + + break; + case BLE_GAP_EVENT_DISCONNECT: + eatt = ble_eatt_find_by_conn_handle(event->disconnect.conn.conn_handle); + assert(eatt == NULL); + break; + default: + break; + } + return 0; +} + +uint16_t +ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) +{ + uint16_t default_cid; + struct ble_eatt * eatt; + + default_cid = ble_att_get_default_bearer_cid(conn_handle); + if (default_cid) { + eatt = ble_eatt_find(conn_handle, default_cid); + } else { + eatt = ble_eatt_find_not_busy(conn_handle); + } + if (!eatt) { + return BLE_L2CAP_CID_ATT; + } + + eatt->client_op = op; + return eatt->chan->scid; +} + + +void +ble_eatt_release_chan(uint16_t conn_handle, uint8_t op) +{ + struct ble_eatt * eatt; + + eatt = ble_eatt_find_by_conn_handle_and_busy_op(conn_handle, op); + if (!eatt) { + BLE_EATT_LOG_DEBUG("ble_eatt_release_chan:" + "EATT not found for conn_handle 0x%04x, operation 0x%02\n", conn_handle, op); + return; + } + + eatt->client_op = 0; +} + +int +ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) +{ + struct ble_eatt *eatt; + int rc; + + BLE_EATT_LOG_DEBUG("eatt: %s, size %d ", __func__, OS_MBUF_PKTLEN(txom)); + eatt = ble_eatt_find(conn_handle, cid); + if (!eatt || !eatt->chan) { + BLE_EATT_LOG_ERROR("Eatt not available"); + rc = BLE_HS_ENOENT; + goto error; + } + + ble_att_truncate_to_mtu(eatt->chan, txom); + rc = ble_l2cap_send(eatt->chan, txom); + if (rc == 0) { + goto done; + } + + if (rc == BLE_HS_ESTALLED) { + BLE_EATT_LOG_DEBUG("ble_eatt_tx: Eatt stalled"); + } else if (rc == BLE_HS_EBUSY) { + BLE_EATT_LOG_DEBUG("ble_eatt_tx: Message queued"); + STAILQ_INSERT_HEAD(&eatt->eatt_tx_q, OS_MBUF_PKTHDR(txom), omp_next); + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); + } else { + BLE_EATT_LOG_ERROR("eatt: %s, ERROR %d ", __func__, rc); + assert(0); + } +done: + return 0; + +error: + os_mbuf_free_chain(txom); + return rc; +} + +static void +ble_eatt_start(uint16_t conn_handle) +{ + struct ble_gap_conn_desc desc; + struct ble_eatt *eatt; + int rc; + + rc = ble_gap_conn_find(conn_handle, &desc); + assert(rc == 0); + if (desc.role != BLE_GAP_ROLE_MASTER) { + /* Let master to create ecoc. + */ + return; + } + + for (int i = 0; i < ble_hs_cfg.eatt; i++) { + eatt = ble_eatt_alloc(); + if (!eatt) { + return; + } + + eatt->conn_handle = conn_handle; + + /* Setup EATT */ + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->setup_ev); + eatt = NULL; + } +} + +void +ble_eatt_init(ble_eatt_att_rx_fn att_rx_cb) +{ + int rc; + + rc = os_mempool_init(&ble_eatt_sdu_mbuf_mempool, + MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, + BLE_EATT_MEMBLOCK_SIZE, + ble_eatt_sdu_coc_mem, + "ble_eatt_sdu"); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); + + rc = os_mbuf_pool_init(&ble_eatt_sdu_os_mbuf_pool, + &ble_eatt_sdu_mbuf_mempool, + BLE_EATT_MEMBLOCK_SIZE, + MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); + + rc = os_mempool_init(&ble_eatt_conn_pool, MYNEWT_VAL(BLE_EATT_CHAN_NUM), + sizeof (struct ble_eatt), + ble_eatt_conn_mem, "ble_eatt_conn_pool"); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); + + rc = ble_gap_event_listener_register(&ble_eatt_listener, ble_eatt_gap_event, NULL); + ble_l2cap_create_server(BLE_EATT_PSM, MYNEWT_VAL(BLE_EATT_MTU), ble_eatt_l2cap_event_fn, NULL); + + ble_npl_event_init(&g_read_sup_srv_feat_ev, ble_gatt_eatt_read_svr_uuid, NULL); + ble_npl_event_init(&g_read_sup_cl_feat_ev, ble_gatt_eatt_read_cl_uuid, NULL); + + ble_eatt_att_rx_cb = att_rx_cb; +} +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt_priv.h new file mode 100644 index 00000000..1797ce67 --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_eatt_priv.h @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "syscfg/syscfg.h" +#include "os/os_mbuf.h" +#include "host/ble_l2cap.h" + +#ifndef BLE_EATT_H_ +#define BLE_EATT_H_ + +typedef int (* ble_eatt_att_rx_fn)(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx_buf); + +#define BLE_EATT_PSM (0x0027) + +#define BLE_GATT_OP_SERVER 0xF1 +#define BLE_GATT_OP_DUMMY 0xF2 + +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 +void ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn); +uint16_t ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op); +void ble_eatt_release_chan(uint16_t conn_handle, uint8_t op); +int ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom); +#else +static inline void +ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn) +{ +} + +static inline void +ble_eatt_release_chan(uint16_t conn_handle, uint8_t op) +{ + +} + +static inline uint16_t +ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) +{ + return BLE_L2CAP_CID_ATT; +} + +#endif +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap.c index d896565e..072b415b 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap.c @@ -108,7 +108,7 @@ #define BLE_GAP_UPDATE_TIMEOUT_MS 40000 /* ms */ -#if MYNEWT_VAL(BLE_ROLE_CENTRAL) +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) static const struct ble_gap_conn_params ble_gap_conn_params_dflt = { .scan_itvl = 0x0010, .scan_window = 0x0010, @@ -127,9 +127,21 @@ struct ble_gap_connect_reattempt_ctxt { ble_addr_t peer_addr; uint8_t peer_addr_present:1; int32_t duration_ms; - struct ble_gap_conn_params conn_params; + struct ble_gap_conn_params conn_params_1m; ble_gap_event_fn *cb; void *cb_arg; +#if MYNEWT_VAL(BLE_EXT_ADV) + uint8_t phy_mask; + struct ble_gap_conn_params conn_params_2m; + struct ble_gap_conn_params conn_params_coded; +#endif // MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + ble_addr_t periodic_addr; + uint8_t adv_sid; + int sync_reattempt; + int count; + struct ble_gap_periodic_sync_params periodic_params; +#endif // MYNEWT_VAL(BLE_PERIODIC_ADV) }ble_conn_reattempt; struct ble_gap_adv_reattempt_ctxt { @@ -159,7 +171,6 @@ struct ble_gap_adv_reattempt_ctxt { }ble_adv_reattempt; #endif - /** * The state of the in-progress master connection. If no master connection is * currently in progress, then the op field is set to BLE_GAP_OP_NULL. @@ -188,6 +199,7 @@ struct ble_gap_master_state { struct { uint8_t limited:1; + uint8_t observer:1; } disc; }; }; @@ -276,6 +288,12 @@ struct ble_gap_multi_conn_state static struct ble_gap_multi_conn_state ble_gap_multi_conn; #endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +static uint8_t pawr_adv_handle; +static uint16_t pawr_sync_handle; +#endif + +int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry); #if NIMBLE_BLE_CONNECT @@ -302,6 +320,11 @@ static int ble_gap_conn_cancel_tx(void); static int ble_gap_disc_enable_tx(int enable, int filter_duplicates); #endif +uint16_t g_max_tx_time[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; +uint16_t g_max_rx_time[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1 ]; +uint16_t g_max_tx_octets[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; +uint16_t g_max_rx_octets[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; + STATS_SECT_DECL(ble_gap_stats) ble_gap_stats; STATS_NAME_START(ble_gap_stats) STATS_NAME(ble_gap_stats, wl_set) @@ -559,6 +582,29 @@ ble_gap_conn_find(uint16_t handle, struct ble_gap_conn_desc *out_desc) #endif } +int +ble_gap_read_rem_ver_info(uint16_t conn_handle, uint8_t *version, uint16_t *manufacturer, uint16_t *subversion) +{ +#if NIMBLE_BLE_CONNECT + struct ble_hs_conn *conn; + + ble_hs_lock(); + + conn = ble_hs_conn_find(conn_handle); + + ble_hs_unlock(); + + if (conn == NULL ) { + return BLE_HS_ENOTCONN; + } + + *version = conn->bhc_rd_rem_ver_params.version; + *manufacturer = conn->bhc_rd_rem_ver_params.manufacturer; + *subversion = conn->bhc_rd_rem_ver_params.subversion; +#endif + return 0; +} + int ble_gap_conn_find_by_addr(const ble_addr_t *addr, struct ble_gap_conn_desc *out_desc) @@ -998,7 +1044,7 @@ ble_gap_master_extract_state(struct ble_gap_master_state *out_state, } #endif -#if NIMBLE_BLE_ADVERTISE || NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) || NIMBLE_BLE_ADVERTISE static void ble_gap_slave_extract_cb(uint8_t instance, ble_gap_event_fn **out_cb, void **out_cb_arg) @@ -1011,7 +1057,9 @@ ble_gap_slave_extract_cb(uint8_t instance, ble_hs_unlock(); } +#endif +#if NIMBLE_BLE_ADVERTISE static void ble_gap_adv_finished(uint8_t instance, int reason, uint16_t conn_handle, uint8_t num_events) @@ -1052,7 +1100,22 @@ ble_gap_master_connect_failure(int status) event.type = BLE_GAP_EVENT_CONNECT; event.connect.status = status; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.connect.sync_handle = pawr_sync_handle; + event.connect.adv_handle = pawr_adv_handle; +#endif + rc = state.cb(&event, state.cb_arg); + +//TODO Remove duplication of event fields + event.type = BLE_GAP_EVENT_LINK_ESTAB; + event.link_estab.status = status; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.link_estab.sync_handle = pawr_sync_handle; + event.link_estab.adv_handle = pawr_adv_handle; +#endif rc = state.cb(&event, state.cb_arg); + } else { rc = 0; } @@ -1078,11 +1141,33 @@ ble_gap_master_connect_cancelled(void) /* Connect procedure timed out. */ event.connect.status = BLE_HS_ETIMEOUT; } + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.connect.sync_handle = pawr_sync_handle; + event.connect.adv_handle = pawr_adv_handle; +#endif + state.cb(&event, state.cb_arg); + +//TODO Remove duplication of event fields + event.type = BLE_GAP_EVENT_LINK_ESTAB; + event.link_estab.conn_handle = BLE_HS_CONN_HANDLE_NONE; + if (state.conn.cancel) { + /* Connect procedure successfully cancelled. */ + event.link_estab.status = BLE_HS_EAPP; + } else { + /* Connect procedure timed out. */ + event.link_estab.status = BLE_HS_ETIMEOUT; + } + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.link_estab.sync_handle = pawr_sync_handle; + event.link_estab.adv_handle = pawr_adv_handle; +#endif state.cb(&event, state.cb_arg); } } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT static void ble_gap_update_notify(uint16_t conn_handle, int status); @@ -1115,8 +1200,12 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle) ble_l2cap_sig_conn_broken(conn_handle, BLE_ERR_CONN_ESTABLISHMENT); ble_sm_connection_broken(conn_handle); - ble_gatts_connection_broken(conn_handle); - ble_gattc_connection_broken(conn_handle); +#if MYNEWT_VAL(BLE_GATTS) + ble_gatts_connection_broken(conn_handle); +#endif +#if MYNEWT_VAL(BLE_GATTC) + ble_gattc_connection_broken(conn_handle); +#endif ble_hs_flow_connection_broken(conn_handle);; rc = ble_hs_atomic_conn_delete(conn_handle); @@ -1124,12 +1213,33 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle) return rc; } +#if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + /* This reattempt will be done automatically. The `scheduling_len` maybe set in the ble_gap_multi_connect(). */ + ble_gap_multi_conn.scheduling_len_set = true; +#endif // MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + +#if MYNEWT_VAL(BLE_EXT_ADV) + rc = ble_gap_ext_connect(ble_conn_reattempt.own_addr_type, + (ble_conn_reattempt.peer_addr_present == 1 ? &ble_conn_reattempt.peer_addr : NULL), + ble_conn_reattempt.duration_ms, ble_conn_reattempt.phy_mask, + ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_1M_MASK ? &ble_conn_reattempt.conn_params_1m : NULL, + ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_2M_MASK ? &ble_conn_reattempt.conn_params_2m : NULL, + ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_CODED_MASK ? &ble_conn_reattempt.conn_params_coded : NULL, + ble_conn_reattempt.cb, + ble_conn_reattempt.cb_arg); +#else rc = ble_gap_connect(ble_conn_reattempt.own_addr_type, (ble_conn_reattempt.peer_addr_present == 1 ? &ble_conn_reattempt.peer_addr : NULL), ble_conn_reattempt.duration_ms, - &ble_conn_reattempt.conn_params, + &ble_conn_reattempt.conn_params_1m, ble_conn_reattempt.cb, - &conn); + ble_conn_reattempt.cb_arg); +#endif // #if MYNEWT_VAL(BLE_EXT_ADV) + +#if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + ble_gap_multi_conn.scheduling_len_set = false; +#endif // MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + if (rc != 0) { return rc; } @@ -1366,7 +1476,10 @@ ble_gap_update_next_exp(int32_t *out_ticks_from_now) } -#if NIMBLE_BLE_SCAN + +#if (MYNEWT_VAL(BLE_ROLE_CENTRAL) || \ + (MYNEWT_VAL(BLE_ROLE_CENTRAL) && !MYNEWT_VAL(BLE_EXT_ADV)) || \ + (NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV))) static void ble_gap_master_set_timer(uint32_t ticks_from_now) { @@ -1444,6 +1557,8 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) struct ble_gap_update_entry *entry; struct ble_gap_snapshot snap; struct ble_gap_event event; + struct ble_hs_conn *conn; + bool send = 1; int rc; memset(&event, 0, sizeof event); @@ -1473,20 +1588,46 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) */ ble_l2cap_sig_conn_broken(conn_handle, reason); ble_sm_connection_broken(conn_handle); +#if MYNEWT_VAL(BLE_GATTS) ble_gatts_connection_broken(conn_handle); +#endif + +#if MYNEWT_VAL(BLE_GATTC) ble_gattc_connection_broken(conn_handle); +#endif + #if MYNEWT_VAL(BLE_GATT_CACHING) ble_gattc_cache_conn_broken(conn_handle); #endif ble_hs_flow_connection_broken(conn_handle);; + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); + + // Send disconnect event in slave role if connect was sent + if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { + if (slave_conn[conn_handle]) { + slave_conn[conn_handle] = 0; + } else { + send = 0; + } + } + ble_hs_atomic_conn_delete(conn_handle); + g_max_tx_time[conn_handle] = 0; + g_max_rx_time[conn_handle] = 0; + g_max_tx_octets[conn_handle] = 0; + g_max_rx_octets[conn_handle] = 0; + event.type = BLE_GAP_EVENT_DISCONNECT; event.disconnect.reason = reason; - ble_gap_event_listener_call(&event); - ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg); + if (send) { + ble_gap_event_listener_call(&event); + ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg); + } STATS_INC(ble_gap_stats, disconnect); #endif @@ -1634,7 +1775,11 @@ int ble_gap_ext_adv_active(uint8_t instance) if (instance >= BLE_ADV_INSTANCES) { return 0; } +#if NIMBLE_BLE_ADVERTISE || NIMBLE_BLE_CONNECT return ble_gap_adv_active_instance(instance); +#else + return 0; +#endif } #endif @@ -1710,11 +1855,16 @@ ble_gap_accept_master_conn(void) static int ble_gap_accept_slave_conn(uint8_t instance) { - int rc; - + int rc = 0; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + if (instance >= BLE_ADV_INSTANCES) { + rc = BLE_HS_ENOENT; +} +#else if (instance >= BLE_ADV_INSTANCES) { - rc = BLE_HS_ENOENT; + rc = BLE_HS_ENOENT; } else if (!ble_gap_adv_active_instance(instance)) { + rc = BLE_HS_ENOENT; } else { if (ble_gap_slave[instance].connectable) { @@ -1728,6 +1878,7 @@ ble_gap_accept_slave_conn(uint8_t instance) STATS_INC(ble_gap_stats, connect_slv); } +#endif return rc; } #endif @@ -1741,11 +1892,16 @@ ble_gap_rx_adv_report_sanity_check(const uint8_t *adv_data, uint8_t adv_data_len STATS_INC(ble_gap_stats, rx_adv_report); +#if MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN) + /* In case to allow scan with connect, return directly */ + return 0; +#endif + if (ble_gap_master.op != BLE_GAP_OP_M_DISC) { return -1; } - if (MYNEWT_VAL(BLE_ROLE_OBSERVER)) { + if (ble_gap_master.disc.observer) { /* Observer role is enabled; All adv reports regardless of * Flags AD Type need to be discovered. */ @@ -1812,6 +1968,7 @@ ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc) void ble_gap_rx_adv_set_terminated(const struct ble_hci_ev_le_subev_adv_set_terminated *ev) { +#if NIMBLE_BLE_ADVERTISE uint16_t conn_handle; int reason; @@ -1826,6 +1983,7 @@ ble_gap_rx_adv_set_terminated(const struct ble_hci_ev_le_subev_adv_set_terminate } ble_gap_adv_finished(ev->adv_handle, reason, conn_handle, ev->num_events); +#endif } static void @@ -1861,7 +2019,6 @@ ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev) /* Periodic adv events */ #if MYNEWT_VAL(BLE_PERIODIC_ADV) - void ble_gap_rx_peroidic_adv_sync_estab(const struct ble_hci_ev_le_subev_periodic_adv_sync_estab *ev) { @@ -1869,7 +2026,9 @@ ble_gap_rx_peroidic_adv_sync_estab(const struct ble_hci_ev_le_subev_periodic_adv struct ble_gap_event event; ble_gap_event_fn *cb; void *cb_arg; - +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + int rc; +#endif memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_PERIODIC_SYNC; @@ -1882,6 +2041,11 @@ ble_gap_rx_peroidic_adv_sync_estab(const struct ble_hci_ev_le_subev_periodic_adv if (!ev->status) { sync_handle = le16toh(ev->sync_handle); +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + if (ble_conn_reattempt.sync_reattempt) { + ble_conn_reattempt.sync_reattempt = 0; + } +#endif ble_gap_sync.psync->sync_handle = sync_handle; ble_gap_sync.psync->adv_sid = ev->sid; memcpy(ble_gap_sync.psync->advertiser_addr.val, ev->peer_addr, 6); @@ -1896,26 +2060,62 @@ ble_gap_rx_peroidic_adv_sync_estab(const struct ble_hci_ev_le_subev_periodic_adv event.periodic_sync.adv_phy = ev->phy; event.periodic_sync.per_adv_ival = ev->interval; event.periodic_sync.adv_clk_accuracy = ev->aca; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.periodic_sync.num_subevents = ev->num_subevents; + event.periodic_sync.subevent_interval = ev->subevent_interval; + event.periodic_sync.response_slot_delay = ev->response_slot_delay; + event.periodic_sync.response_slot_spacing = ev->response_slot_spacing; +#endif ble_hs_periodic_sync_insert(ble_gap_sync.psync); } else { ble_hs_periodic_sync_free(ble_gap_sync.psync); - } +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + if (ev->status == BLE_ERR_CONN_ESTABLISHMENT) { + if (ble_conn_reattempt.count < MAX_REATTEMPT_ALLOWED) { + if (ble_gap_sync.op == BLE_GAP_OP_SYNC) { + memset(&ble_gap_sync, 0, sizeof(ble_gap_sync)); + } + ble_conn_reattempt.count += 1; + ble_conn_reattempt.sync_reattempt = 1; - cb = ble_gap_sync.cb; - cb_arg = ble_gap_sync.cb_arg; + ble_hs_unlock(); - ble_gap_sync.op = BLE_GAP_OP_NULL; - ble_gap_sync.cb_arg = NULL; - ble_gap_sync.cb_arg = NULL; - ble_gap_sync.psync = NULL; + rc = ble_gap_periodic_adv_sync_create(&ble_conn_reattempt.periodic_addr, ble_conn_reattempt.adv_sid, + &ble_conn_reattempt.periodic_params, + ble_conn_reattempt.cb, ble_conn_reattempt.cb_arg); + if (rc != 0) { + return; + } - ble_hs_unlock(); + ble_hs_lock(); + } + } +#endif + } +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + if (!ble_conn_reattempt.sync_reattempt || ble_conn_reattempt.count >= MAX_REATTEMPT_ALLOWED) { + memset(&ble_conn_reattempt.periodic_addr, 0, sizeof(ble_addr_t)); + ble_conn_reattempt.adv_sid = 0; + ble_conn_reattempt.count = 0; + memset(&ble_conn_reattempt.periodic_params, 0x0, sizeof(struct ble_gap_periodic_sync_params)); +#endif + cb = ble_gap_sync.cb; + cb_arg = ble_gap_sync.cb_arg; - ble_gap_event_listener_call(&event); - if (cb) { - cb(&event, cb_arg); + ble_gap_sync.op = BLE_GAP_OP_NULL; + ble_gap_sync.cb_arg = NULL; + ble_gap_sync.cb_arg = NULL; + ble_gap_sync.psync = NULL; + + ble_gap_event_listener_call(&event); + if (cb) { + cb(&event, cb_arg); + } +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT } +#endif + ble_hs_unlock(); } void @@ -1947,6 +2147,10 @@ ble_gap_rx_periodic_adv_rpt(const struct ble_hci_ev_le_subev_periodic_adv_rpt *e event.periodic_report.data_status = ev->data_status; event.periodic_report.data_length = ev->data_len; event.periodic_report.data = ev->data; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.periodic_report.event_counter = ev->event_counter; + event.periodic_report.subevent = ev->subevent; +#endif /* TODO should we allow for listener too? this can be spammy and is more * like ACL data, not general event @@ -2033,6 +2237,92 @@ ble_gap_rx_transmit_power_report(const struct ble_hci_ev_le_subev_transmit_power } #endif + +#if MYNEWT_VAL(BLE_AOA_AOD) + +void +ble_gap_rx_connless_iq_report(const struct ble_hci_ev_le_subev_connless_iq_rpt *ev) +{ + struct ble_hs_periodic_sync *psync; + struct ble_gap_event event; + ble_gap_event_fn *cb = NULL; + void *cb_arg = NULL; + uint16_t sync_handle = le16toh(ev->sync_handle); + + /* The handle must be in the list */ + ble_hs_lock(); + psync = ble_hs_periodic_sync_find_by_handle(sync_handle); + cb = psync->cb; + cb_arg = psync->cb_arg; + ble_hs_unlock(); + + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_CONNLESS_IQ_REPORT; + event.connless_iq_report.sync_handle = sync_handle; + event.connless_iq_report.channel_index = ev->channel_index; + event.connless_iq_report.rssi = le16toh(ev->rssi); + event.connless_iq_report.rssi_antenna_id = ev->rssi_antenna_id; + event.connless_iq_report.cte_type = ev->cte_type; + event.connless_iq_report.slot_durations = ev->slot_durations; + event.connless_iq_report.packet_status = ev->packet_status; + event.connless_iq_report.periodic_event_counter = le16toh(ev->periodic_event_counter); + event.connless_iq_report.sample_count = ev->sample_count; + event.connless_iq_report.i_samples = (int8_t *)(ev->iq_samples); + event.connless_iq_report.q_samples = (int8_t *)(ev->iq_samples + ev->sample_count); + + ble_gap_event_listener_call(&event); + + if (cb) { + cb(&event, cb_arg); + } +} + + +void +ble_gap_rx_conn_iq_report(const struct ble_hci_ev_le_subev_conn_iq_rpt *ev) +{ + struct ble_gap_event event; + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_CONN_IQ_REPORT; + event.conn_iq_report.conn_handle = le16toh(ev->conn_handle); + event.conn_iq_report.data_channel_index = ev->data_channel_index; + event.conn_iq_report.rx_phy = ev->rx_phy; + event.conn_iq_report.rssi = le16toh(ev->rssi); + event.conn_iq_report.rssi_antenna_id = ev->rssi_antenna_id; + event.conn_iq_report.cte_type = ev->cte_type; + event.conn_iq_report.slot_durations = ev->slot_durations; + event.conn_iq_report.packet_status = ev->packet_status; + event.conn_iq_report.conn_event_counter = le16toh(ev->conn_event_counter); + event.conn_iq_report.sample_count = ev->sample_count; + event.conn_iq_report.i_samples = (int8_t *)(ev->iq_samples); + event.conn_iq_report.q_samples = (int8_t *)(ev->iq_samples + ev->sample_count); + + ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, event.conn_iq_report.conn_handle); + +} + +void +ble_gap_rx_cte_req_failed(const struct ble_hci_ev_le_subev_cte_req_failed *ev) +{ + struct ble_gap_event event; + uint16_t conn_handle; + conn_handle = le16toh(ev->conn_handle); + + memset(&event, 0x0, sizeof event); + + event.type = BLE_GAP_EVENT_CTE_REQ_FAILED; + event.cte_req_fail.status = ev->status; + event.cte_req_fail.conn_handle = conn_handle; + + ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, conn_handle); +} + +#endif + #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) static int periodic_adv_transfer_disable(uint16_t conn_handle) @@ -2098,7 +2388,11 @@ ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_ memset(&event, 0, sizeof event); +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.type = BLE_GAP_EVENT_PERIODIC_TRANSFER_V2; +#else event.type = BLE_GAP_EVENT_PERIODIC_TRANSFER; +#endif // MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) event.periodic_transfer.status = ev->status; /* only sync handle is not valid on error */ @@ -2127,7 +2421,12 @@ ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_ event.periodic_transfer.adv_phy = ev->phy; event.periodic_transfer.per_adv_itvl = le16toh(ev->interval); event.periodic_transfer.adv_clk_accuracy = ev->aca; - +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.periodic_transfer.num_subevents = ev->num_subevents; + event.periodic_transfer.subevent_interval = ev->subevent_interval; + event.periodic_transfer.response_slot_delay = ev->response_slot_delay; + event.periodic_transfer.response_slot_spacing = ev->response_slot_spacing; +#endif ble_hs_unlock(); cb(&event, cb_arg); @@ -2183,6 +2482,9 @@ void ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change *ev) { struct ble_gap_event event; + uint16_t conn_handle; + + conn_handle = le16toh(ev->conn_handle); memset(&event, 0x0, sizeof event); @@ -2195,6 +2497,88 @@ ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change *ev) event.subrate_change.supervision_tmo = le16toh(ev->supervision_tmo); ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, conn_handle); +} +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +void +ble_gap_rx_periodic_adv_subev_data_req(const struct ble_hci_ev_le_subev_periodic_adv_subev_data_req *ev) +{ + struct ble_gap_event event; + ble_gap_event_fn *cb; + void *cb_arg; + + memset(&event, 0x0, sizeof event); + + event.type = BLE_GAP_EVENT_PER_SUBEV_DATA_REQ; + event.periodic_adv_subev_data_req.adv_handle = ev->adv_handle; + event.periodic_adv_subev_data_req.subevent_start = ev->subevent_start; + event.periodic_adv_subev_data_req.subevent_data_count = ev->subevent_data_count; + + ble_gap_slave_extract_cb(ev->adv_handle, &cb, &cb_arg); + if (cb != NULL) { + cb(&event, cb_arg); + } + + ble_gap_event_listener_call(&event); +} + +void +ble_gap_rx_periodic_adv_response(const struct ble_gap_periodic_adv_response resp) +{ + struct ble_gap_event event; + ble_gap_event_fn *cb; + void *cb_arg; + + memset(&event, 0x0, sizeof event); + + event.type = BLE_GAP_EVENT_PER_SUBEV_RESP; + memcpy(&event.periodic_adv_response, &resp, + sizeof(struct ble_gap_periodic_adv_response)); + + ble_gap_slave_extract_cb(resp.adv_handle, &cb, &cb_arg); + if (cb != NULL) { + cb(&event, cb_arg); + } + + ble_gap_event_listener_call(&event); +} + +void +ble_gap_rx_conn_comp_failed(const struct ble_gap_conn_complete *evt) +{ + struct ble_gap_event event, event_link_estab; + ble_gap_event_fn *cb; + void *cb_arg; + + memset(&event, 0x0, sizeof event); + memset(&event_link_estab, 0x0, sizeof event); + + event.type = BLE_GAP_EVENT_CONNECT; + event.connect.conn_handle = evt->connection_handle; + event.connect.status = BLE_ERR_CONN_ESTABLISHMENT; + + event.connect.sync_handle = evt->sync_handle; + event.connect.adv_handle = evt->adv_handle; + +//TODO Remove duplication of event fields + event_link_estab.type = BLE_GAP_EVENT_LINK_ESTAB; + event_link_estab.link_estab.conn_handle = evt->connection_handle; + event_link_estab.link_estab.status = BLE_ERR_CONN_ESTABLISHMENT; + + event_link_estab.link_estab.sync_handle = evt->sync_handle; + event_link_estab.link_estab.adv_handle = evt->adv_handle; + + ble_gap_master_reset_state(); + ble_gap_slave_extract_cb(evt->adv_handle, &cb, &cb_arg); + if (cb != NULL) { + cb(&event, cb_arg); + cb(&event_link_estab, cb_arg); + } + + ble_gap_event_listener_call(&event); + ble_gap_event_listener_call(&event_link_estab); } #endif @@ -2210,6 +2594,18 @@ ble_gap_rd_rem_sup_feat_tx(uint16_t handle) BLE_HCI_OCF_LE_RD_REM_FEAT), &cmd, sizeof(cmd), NULL, 0); } + +static int +ble_gap_rd_rem_ver_tx(uint16_t handle) +{ + struct ble_hci_rd_rem_ver_info_cp cmd; + + cmd.conn_handle = htole16(handle); + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, + BLE_HCI_OCF_RD_REM_VER_INFO), + &cmd, sizeof(cmd), NULL, 0); +} #endif /** @@ -2220,14 +2616,19 @@ int ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) { #if NIMBLE_BLE_CONNECT - struct ble_gap_event event; struct ble_hs_conn *conn; int rc; #if MYNEWT_VAL(BLE_GATT_CACHING) - struct ble_hs_conn_addrs addrs + struct ble_hs_conn_addrs addrs; #endif STATS_INC(ble_gap_stats, rx_conn_complete); +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint8_t v1_evt = 0; + if (evt->adv_handle == 0xFF && evt->sync_handle == 0xFFFF) { + v1_evt = 1; + } +#endif // MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) /* in that case *only* status field is valid so we determine role * based on error code @@ -2240,9 +2641,11 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) * with ext advertising this is send from set terminated event */ #if !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE if (ble_gap_adv_active()) { ble_gap_adv_finished(0, 0, 0, 0); } +#endif #endif break; case BLE_ERR_UNK_CONN_ID: @@ -2256,6 +2659,13 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) } } break; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + case BLE_ERR_CONN_ESTABLISHMENT: + if (!v1_evt) { + ble_gap_rx_conn_comp_failed(evt); + } + break; +#endif // MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) default: /* this should never happen, unless controller is broken */ BLE_HS_LOG(INFO, "controller reported invalid error code in conn" @@ -2309,6 +2719,17 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) conn->bhc_our_addr_type = ble_gap_master.conn.our_addr_type; ble_gap_master_reset_state(); } else { +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + if (!v1_evt) { + conn->bhc_cb = ble_gap_master.cb; + conn->bhc_cb_arg = ble_gap_master.cb_arg; + conn->bhc_our_addr_type = ble_gap_master.conn.our_addr_type; + } else { + conn->bhc_cb = ble_gap_slave[instance].cb; + conn->bhc_cb_arg = ble_gap_slave[instance].cb_arg; + conn->bhc_our_addr_type = ble_gap_slave[instance].our_addr_type; + } +#else conn->bhc_cb = ble_gap_slave[instance].cb; conn->bhc_cb_arg = ble_gap_slave[instance].cb_arg; conn->bhc_our_addr_type = ble_gap_slave[instance].our_addr_type; @@ -2316,7 +2737,8 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) memcpy(conn->bhc_our_rnd_addr, ble_gap_slave[instance].rnd_addr, 6); #endif ble_gap_slave_reset_state(instance); - } +#endif +} conn->bhc_peer_addr.type = evt->peer_addr_type; memcpy(conn->bhc_peer_addr.val, evt->peer_addr, 6); @@ -2339,26 +2761,39 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) ble_hs_lock(); - memset(&event, 0, sizeof event); ble_hs_conn_insert(conn); ble_hs_unlock(); - event.type = BLE_GAP_EVENT_CONNECT; - event.connect.conn_handle = evt->connection_handle; - event.connect.status = 0; - /* add gatt connection */ #if MYNEWT_VAL(BLE_GATT_CACHING) if (evt->role == BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER) { ble_hs_conn_addrs(conn, &addrs); rc = ble_gattc_cache_conn_create(conn->bhc_handle, addrs.peer_id_addr); + } else { + conn->bhc_gatt_svr.aware_state = true; + conn->bhc_gatt_svr.half_aware = 0; + /* This is also done when bonding is restored, so `conn` and `ble_gatts_conn_aware_states` need to be kept in sync */ + ble_hs_conn_addrs(conn, &addrs); + for (int i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { + if (memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, + addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { + conn->bhc_gatt_svr.half_aware = ble_gatts_conn_aware_states[i].half_aware; + conn->bhc_gatt_svr.aware_state = ble_gatts_conn_aware_states[i].aware; + } + } } #endif - ble_gap_event_listener_call(&event); - ble_gap_call_conn_event_cb(&event, evt->connection_handle); +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + pawr_sync_handle = evt->sync_handle; + pawr_adv_handle = evt->adv_handle; +#endif - ble_gap_rd_rem_sup_feat_tx(evt->connection_handle); + if (evt->role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) { + ble_gap_rd_rem_ver_tx(evt->connection_handle); + } else { + ble_gap_rd_rem_sup_feat_tx(evt->connection_handle); + } return 0; #else @@ -2366,6 +2801,46 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) #endif } +void +ble_gap_event_connect_call(uint16_t conn_handle, int status) +{ + struct ble_gap_event event; + uint16_t handle = le16toh(conn_handle); + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_CONNECT; + event.connect.status = status; + event.connect.conn_handle = handle; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.connect.sync_handle = pawr_sync_handle; + event.connect.adv_handle = pawr_adv_handle; +#endif + + ble_gap_event_listener_call(&event); +#if NIMBLE_BLE_CONNECT + ble_gap_call_conn_event_cb(&event, handle); +#endif + +//TODO : Remove duplication of event + event.type = BLE_GAP_EVENT_LINK_ESTAB; + event.link_estab.status = status; + event.link_estab.conn_handle = handle; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + event.link_estab.sync_handle = pawr_sync_handle; + event.link_estab.adv_handle = pawr_adv_handle; +#endif + + ble_gap_event_listener_call(&event); +#if NIMBLE_BLE_CONNECT + ble_gap_call_conn_event_cb(&event, handle); +#endif + + ble_hs_hci_util_set_data_len(le16toh(conn_handle), BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX, + BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX); +} + void ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev) { @@ -2375,11 +2850,48 @@ ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used ble_hs_lock(); conn = ble_hs_conn_find(le16toh(ev->conn_handle)); - if ((conn != NULL) && (ev->status == 0)) { + + ble_hs_unlock(); + + if ((conn != NULL) && (conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { conn->supported_feat = get_le32(ev->features); + ble_gap_rd_rem_ver_tx(ev->conn_handle); + } else { + if ((conn != NULL) && (ev->status == 0)) { + conn->supported_feat = get_le32(ev->features); + } + + if (conn != NULL) { + ble_gap_event_connect_call(ev->conn_handle, ev->status); + slave_conn[ev->conn_handle] = 1; + } } +#endif +} + +void +ble_gap_rx_rd_rem_ver_info_complete(const struct ble_hci_ev_rd_rem_ver_info_cmp *ev) +{ +#if NIMBLE_BLE_CONNECT + struct ble_hs_conn *conn; + + ble_hs_lock(); + + conn = ble_hs_conn_find(le16toh(ev->conn_handle)); ble_hs_unlock(); + + conn->bhc_rd_rem_ver_params.version = ev->version; + conn->bhc_rd_rem_ver_params.manufacturer = ev->manufacturer; + conn->bhc_rd_rem_ver_params.subversion = ev->subversion; + + if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { + ble_gap_rd_rem_sup_feat_tx(ev->conn_handle); + } else { + if ((conn != NULL) && (ev->status == 0)) { + ble_gap_event_connect_call(ev->conn_handle, ev->status); + } + } #endif } @@ -2436,6 +2948,11 @@ ble_gap_rx_data_len_change(const struct ble_hci_ev_le_subev_data_len_chg *ev) event.data_len_chg.max_tx_time = le16toh(ev->max_tx_time); event.data_len_chg.max_rx_time = le16toh(ev->max_rx_time); + g_max_tx_octets[conn_handle] = event.data_len_chg.max_tx_octets; + g_max_rx_octets[conn_handle] = event.data_len_chg.max_rx_octets; + g_max_tx_time[conn_handle] = event.data_len_chg.max_tx_time; + g_max_rx_time[conn_handle] = event.data_len_chg.max_rx_time; + ble_gap_event_listener_call(&event); ble_gap_call_conn_event_cb(&event, conn_handle); #endif @@ -2445,7 +2962,7 @@ static int32_t ble_gap_master_timer(void) { uint32_t ticks_until_exp; -#if NIMBLE_BLE_SCAN || NIMBLE_BLE_CONNECT +#if NIMBLE_BLE_CONNECT || (NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV)) int rc; #endif @@ -2632,12 +3149,13 @@ ble_gap_wl_busy(void) ble_gap_master.conn.using_wl; } -static int +int ble_gap_wl_tx_add(const ble_addr_t *addr) { struct ble_hci_le_add_whte_list_cp cmd; - if (addr->type > BLE_ADDR_RANDOM) { + if (addr->type > BLE_ADDR_RANDOM && + addr->type != BLE_ADDR_ANONYMOUS) { return BLE_HS_EINVAL; } @@ -2717,7 +3235,8 @@ ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count) for (i = 0; i < white_list_count; i++) { if (addrs[i].type != BLE_ADDR_PUBLIC && - addrs[i].type != BLE_ADDR_RANDOM) { + addrs[i].type != BLE_ADDR_RANDOM && + addrs[i].type != BLE_ADDR_ANONYMOUS) { rc = BLE_HS_EINVAL; goto done; @@ -2983,12 +3502,14 @@ ble_gap_adv_validate(uint8_t own_addr_type, const ble_addr_t *peer_addr, return BLE_HS_EINVAL; } +#if NIMBLE_BLE_CONNECT /* Don't allow connectable advertising if we won't be able to allocate * a new connection. */ if (!ble_hs_conn_can_alloc()) { return BLE_HS_ENOMEM; } +#endif break; case BLE_GAP_CONN_MODE_DIR: @@ -3043,7 +3564,7 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, goto done; } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_adv_reattempt.type = 0; ble_adv_reattempt.own_addr_type = own_addr_type; @@ -3193,7 +3714,7 @@ ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields) if (!ble_hs_is_enabled()) { return BLE_HS_EDISABLED; } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT memcpy(&ble_adv_reattempt.fields, adv_fields, sizeof( struct ble_hs_adv_fields)); #endif @@ -3249,45 +3770,38 @@ ble_gap_adv_active(void) #if MYNEWT_VAL(BLE_EXT_ADV) static int -ble_gap_ext_adv_params_tx(uint8_t instance, - const struct ble_gap_ext_adv_params *params, - int8_t *selected_tx_power) - +ble_gap_set_ext_adv_params(struct ble_hci_le_set_ext_adv_params_cp *cmd, + uint8_t instance, const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) { - struct ble_hci_le_set_ext_adv_params_cp cmd; - struct ble_hci_le_set_ext_adv_params_rp rsp; - int rc; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.adv_handle = instance; + cmd->adv_handle = instance; if (params->connectable) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE; } if (params->scannable) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE; } if (params->directed) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED; - cmd.peer_addr_type = params->peer.type; - memcpy(cmd.peer_addr, params->peer.val, BLE_DEV_ADDR_LEN); + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED; + cmd->peer_addr_type = params->peer.type; + memcpy(cmd->peer_addr, params->peer.val, BLE_DEV_ADDR_LEN); } if (params->high_duty_directed) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED; } if (params->anonymous) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV; } if (params->include_tx_power) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR; } if (params->legacy_pdu) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; /* check right away if the applied configuration is valid before handing * the command to the controller to improve error reporting */ - switch (cmd.props) { + switch (cmd->props) { case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND: case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR: case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR: @@ -3302,38 +3816,96 @@ ble_gap_ext_adv_params_tx(uint8_t instance, /* Fill optional fields if application did not specify them. */ if (params->itvl_min == 0 && params->itvl_max == 0) { /* TODO for now limited to legacy values*/ - put_le24(cmd.pri_itvl_min, BLE_GAP_ADV_FAST_INTERVAL1_MIN); - put_le24(cmd.pri_itvl_max, BLE_GAP_ADV_FAST_INTERVAL2_MAX); + put_le24(cmd->pri_itvl_min, BLE_GAP_ADV_FAST_INTERVAL1_MIN); + put_le24(cmd->pri_itvl_max, BLE_GAP_ADV_FAST_INTERVAL2_MAX); } else { - put_le24(cmd.pri_itvl_min, params->itvl_min); - put_le24(cmd.pri_itvl_max, params->itvl_max); + put_le24(cmd->pri_itvl_min, params->itvl_min); + put_le24(cmd->pri_itvl_max, params->itvl_max); } if (params->channel_map == 0) { - cmd.pri_chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; + cmd->pri_chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; } else { - cmd.pri_chan_map = params->channel_map; + cmd->pri_chan_map = params->channel_map; } /* Zero is the default value for filter policy and high duty cycle */ - cmd.filter_policy = params->filter_policy; - cmd.tx_power = params->tx_power; + cmd->filter_policy = params->filter_policy; + cmd->tx_power = params->tx_power; if (params->legacy_pdu) { - cmd.pri_phy = BLE_HCI_LE_PHY_1M; - cmd.sec_phy = BLE_HCI_LE_PHY_1M; + cmd->pri_phy = BLE_HCI_LE_PHY_1M; + cmd->sec_phy = BLE_HCI_LE_PHY_1M; } else { - cmd.pri_phy = params->primary_phy; - cmd.sec_phy = params->secondary_phy; + cmd->pri_phy = params->primary_phy; + cmd->sec_phy = params->secondary_phy; + } + + cmd->own_addr_type = params->own_addr_type; + cmd->sec_max_skip = 0; + cmd->sid = params->sid; + cmd->scan_req_notif = params->scan_req_notif; + + return 0; +} + +static int +ble_gap_ext_adv_params_tx_v1(uint8_t instance, + const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) +{ + struct ble_hci_le_set_ext_adv_params_cp cmd; + struct ble_hci_le_set_ext_adv_params_rp rsp; + int rc; + + memset(&cmd, 0, sizeof(cmd)); + + rc = ble_gap_set_ext_adv_params(&cmd, instance, params, selected_tx_power); + + if (rc != 0) { + return rc; + } + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM), + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + + if (rc != 0) { + return rc; + } + + if (selected_tx_power) { + *selected_tx_power = rsp.tx_power; + } + + return 0; + +} + +#if MYNEWT_VAL(BLE_EXT_ADV_V2) +static int +ble_gap_ext_adv_params_tx_v2(uint8_t instance, + const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) +{ + + struct ble_hci_le_set_ext_adv_params_v2_cp cmd; + struct ble_hci_le_set_ext_adv_params_rp rsp; + int rc; + + memset(&cmd, 0, sizeof(cmd)); + + rc = ble_gap_set_ext_adv_params(&(cmd.cmd), instance, params, selected_tx_power); + + if (rc != 0) { + return rc; } - cmd.own_addr_type = params->own_addr_type; - cmd.sec_max_skip = 0; - cmd.sid = params->sid; - cmd.scan_req_notif = params->scan_req_notif; + cmd.pri_phy_opt = params->primary_phy_opt; + cmd.sec_phy_opt = params->secondary_phy_opt; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM), + BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2), &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { @@ -3346,6 +3918,35 @@ ble_gap_ext_adv_params_tx(uint8_t instance, return 0; } +#endif + +static int +ble_gap_ext_adv_params_tx(uint8_t instance, + const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) +{ + int rc = 0; + +#if MYNEWT_VAL(BLE_EXT_ADV_V2) + struct ble_hs_hci_sup_cmd sup_cmd; + sup_cmd = ble_hs_hci_get_hci_supported_cmd(); + + /* Return Error if phy is non-zero and controller doesn't support V2 */ + if (!((sup_cmd.commands[46] & 0x04) != 0) && + (params->primary_phy_opt || params->secondary_phy_opt)) { + return BLE_HS_EINVAL; + } + + if ((sup_cmd.commands[46] & 0x04) != 0) { + rc = ble_gap_ext_adv_params_tx_v2(instance, params, selected_tx_power); + return rc; + } +#endif + + rc = ble_gap_ext_adv_params_tx_v1(instance, params, selected_tx_power); + + return rc; +} static int ble_gap_ext_adv_params_validate(const struct ble_gap_ext_adv_params *params) @@ -3428,7 +4029,7 @@ ble_gap_ext_adv_configure(uint8_t instance, return rc; } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_adv_reattempt.instance = instance; memcpy(&ble_adv_reattempt.params, params, sizeof(struct ble_gap_ext_adv_params)); @@ -3447,10 +4048,12 @@ ble_gap_ext_adv_configure(uint8_t instance, ble_hs_lock(); +#if NIMBLE_BLE_ADVERTISE || NIMBLE_BLE_CONNECT if (ble_gap_adv_active_instance(instance)) { ble_hs_unlock(); return BLE_HS_EBUSY; } +#endif rc = ble_gap_ext_adv_params_tx(instance, params, selected_tx_power); if (rc) { @@ -3562,7 +4165,7 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events) return BLE_HS_EDISABLED; } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_adv_reattempt.type = 1; ble_adv_reattempt.instance = instance; ble_adv_reattempt.duration = duration; @@ -3663,14 +4266,18 @@ ble_gap_ext_adv_stop_no_lock(uint8_t instance) struct ble_hci_le_set_ext_adv_enable_cp *cmd; uint8_t buf[sizeof(*cmd) + sizeof(cmd->sets[0])]; uint16_t opcode; +#if NIMBLE_BLE_ADVERTISE || NIMBLE_BLE_CONNECT bool active; +#endif int rc; if (!ble_gap_slave[instance].configured) { return BLE_HS_EINVAL; } +#if NIMBLE_BLE_ADVERTISE || NIMBLE_BLE_CONNECT active = ble_gap_adv_active_instance(instance); +#endif BLE_HS_LOG(INFO, "GAP procedure initiated: stop extended advertising.\n"); @@ -3691,11 +4298,15 @@ ble_gap_ext_adv_stop_no_lock(uint8_t instance) ble_gap_slave[instance].op = BLE_GAP_OP_NULL; +#if NIMBLE_BLE_ADVERTISE || NIMBLE_BLE_CONNECT if (!active) { return BLE_HS_EALREADY; } else { return 0; } +#endif + + return 0; } int @@ -3855,7 +4466,7 @@ ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data) goto done; } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT uint16_t len = OS_MBUF_PKTLEN(data); ble_adv_reattempt.type = 1; @@ -4051,7 +4662,11 @@ ble_gap_periodic_adv_params_tx(uint8_t instance, const struct ble_gap_periodic_adv_params *params) { +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + struct ble_hci_le_set_periodic_adv_params_v2 cmd; +#else struct ble_hci_le_set_periodic_adv_params_cp cmd; +#endif uint16_t opcode; cmd.adv_handle = instance; @@ -4072,8 +4687,19 @@ ble_gap_periodic_adv_params_tx(uint8_t instance, cmd.props = 0; } - opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS); +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + cmd.num_subevents = params->num_subevents; + cmd.subevent_interval = params->subevent_interval; + cmd.response_slot_delay = params->response_slot_delay; + cmd.response_slot_spacing = params->response_slot_spacing; + cmd.num_response_slots = params->num_response_slots; +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS_V2); +#else + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS); +#endif return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } @@ -4110,7 +4736,7 @@ ble_gap_periodic_adv_configure(uint8_t instance, rc = ble_gap_periodic_adv_params_validate(params); if (rc) { - return rc; + return rc; } ble_hs_lock(); @@ -4509,6 +5135,18 @@ ble_gap_periodic_adv_sync_create(const ble_addr_t *addr, uint8_t adv_sid, return BLE_HS_ENOMEM; } +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + ble_conn_reattempt.adv_sid = adv_sid; + + if (addr != NULL ) { + memcpy(&ble_conn_reattempt.periodic_addr, addr, sizeof(ble_addr_t)); + } + if (params != NULL ) { + memcpy(&ble_conn_reattempt.periodic_params, params, sizeof(struct ble_gap_periodic_sync_params)); + } + ble_conn_reattempt.cb = cb; + ble_conn_reattempt.cb_arg = cb_arg; +#endif ble_npl_event_init(&psync->lost_ev, ble_gap_npl_sync_lost, psync); if (addr) { @@ -4533,7 +5171,11 @@ ble_gap_periodic_adv_sync_create(const ble_addr_t *addr, uint8_t adv_sid, cmd.sid = adv_sid; cmd.skip = params->skip; cmd.sync_timeout = htole16(params->sync_timeout); +#if MYNEWT_VAL(BLE_AOA_AOD) + cmd.sync_cte_type = params->sync_cte_type; +#else cmd.sync_cte_type = 0x00; +#endif opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC); rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); @@ -4781,17 +5423,26 @@ periodic_adv_transfer_enable(uint16_t conn_handle, opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER_PARAMS); + memset(&cmd, 0, sizeof(cmd)); cmd.conn_handle = htole16(conn_handle); - cmd.sync_cte_type = 0x00; - cmd.mode = params->reports_disabled ? 0x01 : 0x02; + + if (params != NULL) { +#if MYNEWT_VAL(BLE_AOA_AOD) + cmd.sync_cte_type = params->sync_cte_type; +#else + cmd.sync_cte_type = 0x00; +#endif + cmd.mode = params->reports_disabled ? 0x01 : 0x02; #if MYNEWT_VAL(BLE_PERIODIC_ADV_ENH) - if (params->filter_duplicates) - cmd.mode = 0x03; + if (!params->reports_disabled && params->filter_duplicates) { + cmd.mode = 0x03; + } #endif - cmd.skip = htole16(params->skip); - cmd.sync_timeout = htole16(params->sync_timeout); + cmd.skip = htole16(params->skip); + cmd.sync_timeout = htole16(params->sync_timeout); + } rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (!rc) { @@ -4816,7 +5467,11 @@ periodic_adv_set_default_sync_params(const struct ble_gap_periodic_sync_params * memset(&cmd, 0, sizeof(cmd)); if (params != NULL) { +#if MYNEWT_VAL(BLE_AOA_AOD) + cmd.sync_cte_type = params->sync_cte_type; +#else cmd.sync_cte_type = 0x00; +#endif cmd.mode = params->reports_disabled ? 0x01 : 0x02; #if MYNEWT_VAL(BLE_PERIODIC_ADV_ENH) @@ -4973,6 +5628,157 @@ ble_gap_read_periodic_adv_list_size(uint8_t *per_adv_list_size) return 0; } +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +static int +ble_gap_calc_periodic_adv_data_size(uint8_t num_subevents, + const struct ble_gap_set_periodic_adv_subev_data_params *params) { + int len = 0; + const struct ble_gap_set_periodic_adv_subev_data_params *param; + int raw_subev_size = sizeof(*param) - sizeof(struct os_mbuf*); + + for(int i = 0; i < num_subevents; i++) { + param = params + i; + len += raw_subev_size; + len += OS_MBUF_PKTLEN(param->data); + } + return len; +} +int +ble_gap_set_periodic_adv_subev_data(uint8_t instance, uint8_t num_subevents, + const struct ble_gap_set_periodic_adv_subev_data_params *params) +{ + struct ble_hci_le_set_periodic_adv_subev_data_cp *cmd; + struct periodic_adv_subevents *subevents; + uint8_t len = ble_gap_calc_periodic_adv_data_size(num_subevents, params); + uint8_t buf[len + 2]; + uint16_t opcode; + uint16_t subev_data_len; + int rc; + + if (instance >= BLE_ADV_INSTANCES) { + rc = BLE_HS_EINVAL; + goto done; + } + + if (!ble_hs_is_enabled()) { + rc = BLE_HS_EDISABLED; + goto done; + } + + /* Check if we can set all of data in one hci command. */ + if ((len + 2) >= 0xff) { + rc = BLE_HS_EINVAL; + goto done; + } + + ble_hs_lock(); + + /* Periodic advertising cannot start unless it is configured before */ + if (!ble_gap_slave[instance].periodic_configured) { + ble_hs_unlock(); + rc = BLE_HS_EINVAL; + goto done; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_SUBEV_DATA); + + cmd = (void *) buf; + subevents = cmd->subevents; + + cmd->adv_handle = instance; + cmd->num_subevents = num_subevents; + + for (int i = 0; i < num_subevents; i++) { + subevents->subevent = params[i].subevent; + subevents->response_slot_start = params[i].response_slot_start; + subevents->response_slot_count = params[i].response_slot_count; + ble_hs_mbuf_to_flat(params[i].data, subevents->subevent_data, OS_MBUF_PKTLEN(params[i].data), + (void*)&subev_data_len); + subevents->subevent_data_length = OS_MBUF_PKTLEN(params[i].data); + subevents = (struct periodic_adv_subevents *)( + (uint32_t)subevents + sizeof(struct periodic_adv_subevents) + subev_data_len); + } + + rc = ble_hs_hci_cmd_tx(opcode, cmd, len + 2, NULL, 0); + if (rc != 0) { + ble_hs_unlock(); + goto done; + } + + ble_gap_slave[instance].periodic_op = BLE_GAP_OP_S_PERIODIC_ADV; + + ble_hs_unlock(); + +done: + for (int i = 0; i < num_subevents; i++) { + os_mbuf_free_chain(params[i].data); + } + return rc; +} + +int ble_gap_periodic_adv_set_response_data(uint16_t sync_handle, + struct ble_gap_periodic_adv_response_params *param, + struct os_mbuf *data) +{ + struct ble_hci_le_set_periodic_adv_response_data *cmd; + uint16_t opcode; + int len = sizeof(*cmd); + int data_len = 0; + if (data) { + data_len = OS_MBUF_PKTLEN(data); + } + uint8_t buf[len + data_len]; + + //!TODO: Check if we can set all of data in one hci command. + + cmd = (void *) buf; + + (void)memset(cmd, 0, sizeof(*cmd)); + put_le16(&cmd->sync_handle, sync_handle); + put_le16(&cmd->request_event, param->request_event); + cmd->request_subevent = param->request_subevent; + cmd->response_subevent = param->response_subevent; + cmd->response_slot = param->response_slot; + cmd->response_data_length = data_len; + if (data_len) { + ble_hs_mbuf_to_flat(data, cmd->response_data, data_len, NULL); + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_RESPONSE_DATA); + + return ble_hs_hci_cmd_tx(opcode, cmd, len + data_len, NULL, 0); +} + +int ble_gap_periodic_adv_sync_subev(uint16_t sync_handle, uint8_t include_tx_power, + uint8_t num_subevents, uint8_t *subevents) +{ + struct ble_hci_le_set_periodic_adv_sync_subevent *cmd; + struct ble_hci_le_set_periodic_adv_sync_subevent_rp rsp; + struct ble_hs_periodic_sync *psync; + uint8_t cmd_buf[sizeof(*cmd) + num_subevents]; + uint16_t opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_SYNC_SUBEVENT); + int rc; + + psync = ble_hs_periodic_sync_find_by_handle(sync_handle); + if (!psync) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + cmd = (void *)cmd_buf; + + put_le16(&cmd->sync_handle, sync_handle); + put_le16(&cmd->periodic_adv_properties, (uint16_t)(include_tx_power << 6)); + cmd->num_subevents = num_subevents; + memcpy(cmd->subevents, subevents, num_subevents); + + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + num_subevents, &rsp, sizeof(rsp)); + if (!rc) { + BLE_HS_DBG_ASSERT(le16toh(rsp.sync_handle) == sync_handle); + } + return rc; +} +#endif #endif /***************************************************************************** @@ -5054,7 +5860,201 @@ ble_gap_ext_disc_enable_tx(uint8_t enable, uint8_t filter_duplicates, &cmd, sizeof(cmd), NULL, 0); } #endif + +#if MYNEWT_VAL(BLE_AOA_AOD) +int +ble_gap_set_connless_cte_transmit_params(uint8_t instance, const struct ble_gap_periodic_adv_cte_params *params) +{ + uint8_t buf[sizeof(struct ble_hci_le_set_connless_cte_tx_params_cp) + + params->switching_pattern_length]; + struct ble_hci_le_set_connless_cte_tx_params_cp *cmd = (void *)buf; + uint8_t len = sizeof(buf); + uint16_t opcode; + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_PARAMS); + + cmd->adv_handle = instance; + cmd->cte_length = params->cte_length; + cmd->cte_type = params->cte_type; + cmd->cte_count = params->cte_count; + cmd->switching_pattern_len = params->switching_pattern_length; + memcpy(cmd->switching_pattern, params->antenna_ids, params->switching_pattern_length); + + return ble_hs_hci_cmd_tx(opcode, cmd, len, NULL, 0); +} + +int +ble_gap_set_connless_cte_transmit_enable(uint8_t instance, uint8_t cte_enable) +{ + struct ble_hci_le_set_connless_cte_tx_enable_cp cmd; + uint16_t opcode; + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_ENABLE); + + cmd.adv_handle = instance; + cmd.cte_enable = cte_enable; + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +} + +int +ble_gap_set_connless_iq_sampling_enable(uint16_t sync_handle, uint8_t sampling_enable, uint8_t max_sampled_ctes, + const struct ble_gap_cte_sampling_params *cte_sampling_params) +{ + uint8_t buf[sizeof(struct ble_hci_le_set_connless_iq_sampling_enable_cp) + + cte_sampling_params->switching_pattern_length]; + struct ble_hci_le_set_connless_iq_sampling_enable_cp *cmd = (struct ble_hci_le_set_connless_iq_sampling_enable_cp*)buf; + struct ble_hci_le_set_connless_iq_sampling_enable_rp rsp; + uint8_t len = sizeof(buf); + uint16_t opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_CONNLESS_IQ_SAMPLING_ENABLE); + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + cmd->sync_handle = htole16(sync_handle); + cmd->sampling_enable = sampling_enable; + cmd->max_sampled_ctes = max_sampled_ctes; + cmd->slot_durations = cte_sampling_params->slot_durations; + cmd->switching_pattern_len = cte_sampling_params->switching_pattern_length; + memcpy(cmd->antenna_ids, cte_sampling_params->antenna_ids, cte_sampling_params->switching_pattern_length); + + return ble_hs_hci_cmd_tx(opcode, cmd, len, &rsp, sizeof(rsp)); +} + +int +ble_gap_set_conn_cte_recv_param(uint16_t conn_handle, uint8_t sampling_enable, const struct ble_gap_cte_sampling_params *cte_sampling_params) +{ + uint8_t buf[sizeof(struct ble_hci_le_set_conn_cte_rx_params_cp) + cte_sampling_params->switching_pattern_length]; + struct ble_hci_le_set_conn_cte_rx_params_cp *cmd = (void *)buf; + struct ble_hci_le_set_conn_cte_rx_params_rp rsp; + uint8_t len = sizeof(buf); + uint16_t opcode; + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_CONN_CTE_RX_PARAMS); + + cmd->conn_handle = conn_handle; + cmd->sampling_enable = sampling_enable; + cmd->slot_durations = cte_sampling_params->slot_durations; + cmd->switching_pattern_len = cte_sampling_params->switching_pattern_length; + memcpy(cmd->antenna_ids, cte_sampling_params->antenna_ids, cte_sampling_params->switching_pattern_length); + + return ble_hs_hci_cmd_tx(opcode, cmd, len, &rsp, sizeof(rsp)); +} + +int +ble_gap_set_conn_cte_transmit_param(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, const uint8_t *antenna_ids) +{ + uint8_t buf[sizeof(struct ble_hci_le_set_conn_cte_tx_params_cp) + switching_pattern_len]; + struct ble_hci_le_set_conn_cte_tx_params_cp *cmd = (void *)buf; + struct ble_hci_le_set_conn_cte_tx_params_rp rsp; + uint8_t len = sizeof(buf); + uint16_t opcode; + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_CONN_CTE_TX_PARAMS); + + cmd->conn_handle = htole16(conn_handle); + cmd->cte_types = cte_types; + if (cmd->cte_types != BIT(0) && (switching_pattern_len == 0 || antenna_ids == NULL)) { + BLE_HS_LOG(ERROR, "Invalid antenna_ids!\n"); + return BLE_HS_EINVAL; + } + cmd->switching_pattern_len = switching_pattern_len; + memcpy(cmd->antenna_ids, antenna_ids, switching_pattern_len); + + + return ble_hs_hci_cmd_tx(opcode, cmd, len, &rsp, sizeof(rsp)); +} + +int +ble_gap_conn_cte_req_enable(uint16_t conn_handle, uint8_t enable, uint16_t cte_request_interval, + uint8_t requested_cte_length, uint8_t requested_cte_type) +{ + uint8_t buf[sizeof(struct ble_gap_conn_cte_req_enable_cp)]; + struct ble_gap_conn_cte_req_enable_cp *cmd = (void *)buf; + struct ble_gap_conn_cte_req_enable_rp rsp; + uint8_t len = sizeof(buf); + uint16_t opcode; + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_CONN_CTE_REQ_ENABLE); + + cmd->conn_handle = htole16(conn_handle); + cmd->enable = enable; + cmd->cte_request_interval = htole16(cte_request_interval); + cmd->requested_cte_length = requested_cte_length; + cmd->requested_cte_type = requested_cte_type; + + return ble_hs_hci_cmd_tx(opcode, cmd, len, &rsp, sizeof(rsp)); +} + +int +ble_gap_conn_cte_rsp_enable(uint16_t conn_handle, uint8_t enable) +{ + struct ble_hci_le_set_conn_cte_rsp_enable_cp cmd; + struct ble_hci_le_set_conn_cte_rsp_enable_rp rsp; + uint16_t opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_CONN_CTE_RESP_ENABLE); + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + cmd.conn_handle = htole16(conn_handle); + cmd.enable = enable; + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); +} + +int +ble_gap_read_antenna_information(uint8_t *switch_sampling_rates, uint8_t *num_antennae, uint8_t *max_switch_pattern_len, uint8_t *max_cte_len) +{ + struct ble_hci_le_rd_antenna_info_rp rsp; + uint16_t opcode; + int rc = 0; + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_ANTENNA_INFO); + + rc = ble_hs_hci_cmd_tx(opcode, NULL, 0, &rsp, sizeof(rsp)); + + if (rc != 0) { + return rc; + } + + *switch_sampling_rates = rsp.switch_sampling_rates; + *num_antennae = rsp.num_antennae; + *max_switch_pattern_len = rsp.max_switch_pattern_len; + *max_cte_len = rsp.max_cte_len; + + return 0; +} + +#endif // MYNEWT_VAL(BLE_AOA_AOD) + #endif + #if NIMBLE_BLE_SCAN #if !MYNEWT_VAL(BLE_EXT_ADV) static int @@ -5112,10 +6112,12 @@ ble_gap_disc_cancel_no_lock(void) STATS_INC(ble_gap_stats, discover_cancel); +#if !MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN) if (!ble_gap_disc_active()) { rc = BLE_HS_EALREADY; goto done; } +#endif rc = ble_gap_disc_disable_tx(); if (rc != 0) { @@ -5258,6 +6260,7 @@ ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, if (uncoded_params) { ble_gap_ext_scan_params_to_hci(uncoded_params, &ucp); ble_gap_ext_disc_fill_dflts(limited, &ucp); + ble_gap_master.disc.observer = !uncoded_params->disable_observer_mode; /* XXX: We should do it only once */ if (!uncoded_params->passive) { @@ -5271,6 +6274,7 @@ ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, if (coded_params) { ble_gap_ext_scan_params_to_hci(coded_params, &cp); ble_gap_ext_disc_fill_dflts(limited, &cp); + ble_gap_master.disc.observer = !coded_params->disable_observer_mode; /* XXX: We should do it only once */ if (!coded_params->passive) { @@ -5384,6 +6388,7 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, p.itvl = disc_params->itvl; p.passive = disc_params->passive; p.window = disc_params->window; + p.disable_observer_mode = disc_params->disable_observer_mode; if (duration_ms == BLE_HS_FOREVER) { duration_ms = 0; @@ -5440,6 +6445,7 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, } ble_gap_master.disc.limited = params.limited; + ble_gap_master.disc.observer = !params.disable_observer_mode; ble_gap_master.cb = cb; ble_gap_master.cb_arg = cb_arg; @@ -5559,64 +6565,300 @@ ble_gap_subrate_req(uint16_t conn_handle, uint16_t subrate_min, uint16_t subrate struct ble_hci_le_subrate_req_cp cmd; uint16_t opcode; - cmd.conn_handle = htole16(conn_handle); - cmd.subrate_min = htole16(subrate_min); - cmd.subrate_max = htole16(subrate_max); - cmd.max_latency = htole16(max_latency); - cmd.cont_num = htole16(cont_num); - cmd.supervision_tmo = htole16(supervision_tmo); + cmd.conn_handle = htole16(conn_handle); + cmd.subrate_min = htole16(subrate_min); + cmd.subrate_max = htole16(subrate_max); + cmd.max_latency = htole16(max_latency); + cmd.cont_num = htole16(cont_num); + cmd.supervision_tmo = htole16(supervision_tmo); + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SUBRATE_REQ); + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +} +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) || (MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_ROLE_CENTRAL)) +static int +ble_gap_check_conn_params(uint8_t phy, const struct ble_gap_conn_params *params) +{ + if (phy != BLE_HCI_LE_PHY_2M) { + /* Check scan interval and window */ + if ((params->scan_itvl < BLE_HCI_SCAN_ITVL_MIN) || + (params->scan_itvl > BLE_HCI_SCAN_ITVL_MAX) || + (params->scan_window < BLE_HCI_SCAN_WINDOW_MIN) || + (params->scan_window > BLE_HCI_SCAN_WINDOW_MAX) || + (params->scan_itvl < params->scan_window)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + } + /* Check connection interval min */ + if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_min > BLE_HCI_CONN_ITVL_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + /* Check connection interval max */ + if ((params->itvl_max < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_max > BLE_HCI_CONN_ITVL_MAX) || + (params->itvl_max < params->itvl_min)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection latency */ + if (params->latency > BLE_HCI_CONN_LATENCY_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check supervision timeout */ + if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || + (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection event length */ + if (params->min_ce_len > params->max_ce_len) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + return 0; +} +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +static int +ble_gap_ext_conn_create_conn_synced_tx(uint8_t own_addr_type, + uint8_t advertising_handle, uint8_t subevent, + const ble_addr_t *peer_addr, uint8_t phy_mask, + const struct ble_gap_conn_params *phy_1m_conn_params, + const struct ble_gap_conn_params *phy_2m_conn_params, + const struct ble_gap_conn_params *phy_coded_conn_params) +{ + struct ble_hci_le_ext_create_conn_v2_cp *cmd; + struct conn_params *params; + uint8_t buf[sizeof(*cmd) + 3 * sizeof(*params)]; + uint8_t len = sizeof(*cmd); + int rc; + + /* Check own addr type */ + if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (phy_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK | + BLE_HCI_LE_PHY_2M_PREF_MASK | + BLE_HCI_LE_PHY_CODED_PREF_MASK)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cmd = (void *) buf; + params = cmd->conn_params; + if (peer_addr == NULL) { + /* Application wants to connect to any device in the white list. The + * peer address type and peer address fields are ignored by the + * controller; fill them with dummy values. + */ + cmd->filter_policy = BLE_HCI_CONN_FILT_USE_WL; + cmd->peer_addr_type = 0; + memset(cmd->peer_addr, 0, sizeof(cmd->peer_addr)); + } else { + /* Check peer addr type */ + if (peer_addr->type > BLE_HCI_CONN_PEER_ADDR_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cmd->filter_policy = BLE_HCI_CONN_FILT_NO_WL; + cmd->peer_addr_type = peer_addr->type; + memcpy(cmd->peer_addr, peer_addr->val, sizeof(cmd->peer_addr)); + } + + cmd->own_addr_type = own_addr_type; + cmd->init_phy_mask = phy_mask; + + cmd->adv_handle = advertising_handle; + cmd->subevent = subevent; + + if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) { + rc = ble_gap_check_conn_params(BLE_HCI_LE_PHY_1M, phy_1m_conn_params); + if (rc) { + return rc; + } + + params->scan_itvl = htole16(phy_1m_conn_params->scan_itvl); + params->scan_window = htole16(phy_1m_conn_params->scan_window); + params->conn_min_itvl = htole16(phy_1m_conn_params->itvl_min); + params->conn_max_itvl = htole16(phy_1m_conn_params->itvl_max); + params->conn_latency = htole16(phy_1m_conn_params->latency); + params->supervision_timeout = htole16(phy_1m_conn_params->supervision_timeout); + params->min_ce = htole16(phy_1m_conn_params->min_ce_len); + params->max_ce = htole16(phy_1m_conn_params->max_ce_len); + + params++; + len += sizeof(*params); + } + + if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) { + rc = ble_gap_check_conn_params(BLE_HCI_LE_PHY_2M, phy_2m_conn_params); + if (rc) { + return rc; + } + + params->scan_itvl = htole16(phy_2m_conn_params->scan_itvl); + params->scan_window = htole16(phy_2m_conn_params->scan_window); + params->conn_min_itvl = htole16(phy_2m_conn_params->itvl_min); + params->conn_max_itvl = htole16(phy_2m_conn_params->itvl_max); + params->conn_latency = htole16(phy_2m_conn_params->latency); + params->supervision_timeout = htole16(phy_2m_conn_params->supervision_timeout); + params->min_ce = htole16(phy_2m_conn_params->min_ce_len); + params->max_ce = htole16(phy_2m_conn_params->max_ce_len); + + params++; + len += sizeof(*params); + } + + if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) { + rc = ble_gap_check_conn_params(BLE_HCI_LE_PHY_CODED, phy_coded_conn_params); + if (rc) { + return rc; + } + + params->scan_itvl = htole16(phy_coded_conn_params->scan_itvl); + params->scan_window = htole16(phy_coded_conn_params->scan_window); + params->conn_min_itvl = htole16(phy_coded_conn_params->itvl_min); + params->conn_max_itvl = htole16(phy_coded_conn_params->itvl_max); + params->conn_latency = htole16(phy_coded_conn_params->latency); + params->supervision_timeout = htole16(phy_coded_conn_params->supervision_timeout); + params->min_ce = htole16(phy_coded_conn_params->min_ce_len); + params->max_ce = htole16(phy_coded_conn_params->max_ce_len); + + params++; + len += sizeof(*params); + } + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_LE_EXT_CREATE_CONN_V2), + cmd, len, NULL, 0); +} + + +int +ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handle, + uint8_t subevent, const ble_addr_t *peer_addr, + int32_t duration_ms, uint8_t phy_mask, + const struct ble_gap_conn_params *phy_1m_conn_params, + const struct ble_gap_conn_params *phy_2m_conn_params, + const struct ble_gap_conn_params *phy_coded_conn_params, + ble_gap_event_fn *cb, void *cb_arg) +{ + int rc; + + STATS_INC(ble_gap_stats, initiate); + + ble_hs_lock(); + + if (ble_gap_conn_active()) { + rc = BLE_HS_EALREADY; + goto done; + } + + if (ble_gap_disc_active()) { + rc = BLE_HS_EBUSY; + goto done; + } + + if (!ble_hs_is_enabled()) { + rc = BLE_HS_EDISABLED; + goto done; + } + + if (ble_gap_is_preempted()) { + rc = BLE_HS_EPREEMPTED; + goto done; + } + + if (!ble_hs_conn_can_alloc()) { + rc = BLE_HS_ENOMEM; + goto done; + } + + if (peer_addr && + peer_addr->type != BLE_ADDR_PUBLIC && + peer_addr->type != BLE_ADDR_RANDOM && + peer_addr->type != BLE_ADDR_PUBLIC_ID && + peer_addr->type != BLE_ADDR_RANDOM_ID) { + + rc = BLE_HS_EINVAL; + goto done; + } + + if ((phy_mask & BLE_GAP_LE_PHY_1M_MASK) && phy_1m_conn_params == NULL) { + phy_1m_conn_params = &ble_gap_conn_params_dflt; + } - opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SUBRATE_REQ); + if ((phy_mask & BLE_GAP_LE_PHY_2M_MASK) && phy_2m_conn_params == NULL) { + phy_2m_conn_params = &ble_gap_conn_params_dflt; + } - return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); -} -#endif + if ((phy_mask & BLE_GAP_LE_PHY_CODED_MASK) && + phy_coded_conn_params == NULL) { -#if MYNEWT_VAL(BLE_EXT_ADV) -#if MYNEWT_VAL(BLE_ROLE_CENTRAL) -static int -ble_gap_check_conn_params(uint8_t phy, const struct ble_gap_conn_params *params) -{ - if (phy != BLE_HCI_LE_PHY_2M) { - /* Check scan interval and window */ - if ((params->scan_itvl < BLE_HCI_SCAN_ITVL_MIN) || - (params->scan_itvl > BLE_HCI_SCAN_ITVL_MAX) || - (params->scan_window < BLE_HCI_SCAN_WINDOW_MIN) || - (params->scan_window > BLE_HCI_SCAN_WINDOW_MAX) || - (params->scan_itvl < params->scan_window)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } + phy_coded_conn_params = &ble_gap_conn_params_dflt; } - /* Check connection interval min */ - if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) || - (params->itvl_min > BLE_HCI_CONN_ITVL_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; + + if (duration_ms == 0) { + duration_ms = BLE_GAP_CONN_DUR_DFLT; } - /* Check connection interval max */ - if ((params->itvl_max < BLE_HCI_CONN_ITVL_MIN) || - (params->itvl_max > BLE_HCI_CONN_ITVL_MAX) || - (params->itvl_max < params->itvl_min)) { - return BLE_ERR_INV_HCI_CMD_PARMS; + + /* The connection creation timeout is not really useful for PAwR. + * The controller will give a result for the connection attempt + * within a periodic interval. We do not know the periodic interval + * used, so disable the timeout. + */ + + /* Verify peer not already connected. */ + if (ble_hs_conn_find_by_addr(peer_addr) != NULL) { + rc = BLE_HS_EDONE; + goto done; } - /* Check connection latency */ - if (params->latency > BLE_HCI_CONN_LATENCY_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; + /* XXX: Verify conn_params. */ + + rc = ble_hs_id_use_addr(own_addr_type); + if (rc != 0) { + goto done; } - /* Check supervision timeout */ - if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || - (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; + BLE_HS_LOG(INFO, "GAP procedure initiated: extended connect; \n"); + + ble_gap_master.cb = cb; + ble_gap_master.cb_arg = cb_arg; + ble_gap_master.conn.using_wl = peer_addr == NULL; + ble_gap_master.conn.our_addr_type = own_addr_type; + + ble_gap_master.op = BLE_GAP_OP_M_CONN; + + rc = ble_gap_ext_conn_create_conn_synced_tx(own_addr_type,advertising_handle,subevent, peer_addr, phy_mask, + phy_1m_conn_params, phy_2m_conn_params, + phy_coded_conn_params); + if (rc != 0) { + ble_gap_master_reset_state(); + goto done; } - /* Check connection event length */ - if (params->min_ce_len > params->max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; + rc = 0; + +done: + ble_hs_unlock(); + + if (rc != 0) { + STATS_INC(ble_gap_stats, initiate_fail); } + return rc; - return 0; } +#endif + +#if MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) static int ble_gap_ext_conn_create_tx( @@ -5728,7 +6970,60 @@ ble_gap_ext_conn_create_tx( BLE_HCI_OCF_LE_EXT_CREATE_CONN), cmd, len, NULL, 0); } -#endif + +/** + * Initiates a connect procedure. + * + * @param own_addr_type The type of address the stack should use for + * itself during connection establishment. + * o BLE_OWN_ADDR_PUBLIC + * o BLE_OWN_ADDR_RANDOM + * o BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT + * o BLE_OWN_ADDR_RPA_RANDOM_DEFAULT + * @param peer_addr The address of the peer to connect to. + * If this parameter is NULL, the white list + * is used. + * @param duration_ms The duration of the discovery procedure. + * On expiration, the procedure ends and a + * BLE_GAP_EVENT_DISC_COMPLETE event is + * reported. Units are milliseconds. + * @param phy_mask Define on which PHYs connection attempt should + * be done + * @param phy_1m_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_1M_MASK is set in phy_mask + * this parameter can be specify to null for + * default values. + * @param phy_2m_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_2M_MASK is set in phy_mask + * this parameter can be specify to null for + * default values. + * @param phy_coded_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_CODED_MASK is set in + * phy_mask this parameter can be specify to + * null for default values. + * @param cb The callback to associate with this connect + * procedure. When the connect procedure + * completes, the result is reported through + * this callback. If the connect procedure + * succeeds, the connection inherits this + * callback as its event-reporting mechanism. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; + * BLE_HS_EALREADY if a connection attempt is + * already in progress; + * BLE_HS_EBUSY if initiating a connection is not + * possible because scanning is in progress; + * BLE_HS_EDONE if the specified peer is already + * connected; + * Other nonzero on error. + */ + +#endif // MYNEWT_VAL(BLE_ROLE_CENTRAL) /** * Initiates a connect procedure. @@ -5811,10 +7106,12 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, goto done; } +#if !MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN) if (ble_gap_disc_active()) { rc = BLE_HS_EBUSY; goto done; } +#endif if (!ble_hs_is_enabled()) { rc = BLE_HS_EDISABLED; @@ -5890,7 +7187,7 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, ble_gap_master.op = BLE_GAP_OP_M_CONN; -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_conn_reattempt.own_addr_type = own_addr_type; if (peer_addr != NULL) { @@ -5902,21 +7199,22 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, } ble_conn_reattempt.duration_ms = duration_ms; + ble_conn_reattempt.phy_mask = phy_mask; if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) { - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_1m, phy_1m_conn_params, sizeof(struct ble_gap_conn_params)); } if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) { - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_2m, phy_2m_conn_params, sizeof(struct ble_gap_conn_params)); } if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) { - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_coded, phy_coded_conn_params, sizeof(struct ble_gap_conn_params)); } @@ -5988,10 +7286,12 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, goto done; } +#if !MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN) if (ble_gap_disc_active()) { rc = BLE_HS_EBUSY; goto done; } +#endif if (!ble_hs_is_enabled()) { rc = BLE_HS_EDISABLED; @@ -6079,7 +7379,7 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, memset(&bhc_peer_addr, 0, sizeof bhc_peer_addr); } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_conn_reattempt.own_addr_type = own_addr_type; if (peer_addr != NULL) { ble_conn_reattempt.peer_addr_present = 1; @@ -6092,7 +7392,7 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, } ble_conn_reattempt.duration_ms = duration_ms; - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_1m, conn_params, sizeof(struct ble_gap_conn_params)); ble_conn_reattempt.cb = cb; @@ -6208,6 +7508,7 @@ ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, #endif // MYNEWT_VAL(BLE_EXT_ADV) scheduling_len_us = multi_conn_params->scheduling_len_us; + /* `scheduling_len_us == 0` is allowed. It indicates that the optimization for this connection * is disabled. The connection interval must be an integer multiple of `common factor`. Note * that the unit of the connection interval is 1.25ms, while the common factor's unit is 0.625ms. @@ -6266,7 +7567,7 @@ ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, multi_conn_params->phy_2m_conn_params, multi_conn_params->phy_coded_conn_params, cb, cb_arg); #else - rc = ble_gap_ext_connect(multi_conn_params->own_addr_type, multi_conn_params->peer_addr, + rc = ble_gap_connect(multi_conn_params->own_addr_type, multi_conn_params->peer_addr, multi_conn_params->duration_ms, multi_conn_params->phy_1m_conn_params, cb, cb_arg); #endif // MYNEWT_VAL(BLE_EXT_ADV) @@ -6764,6 +8065,30 @@ int ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time) { + /* Check if host has triggered Set data len for same parameters + * which are currently set in controller. + * If yes, then just return event to host indicating success + * since controller will not send any event in this scenario + */ + if (g_max_tx_time[conn_handle] == tx_time && g_max_tx_octets[conn_handle] == tx_octets) { + + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_DATA_LEN_CHG; + event.data_len_chg.max_tx_octets = g_max_tx_octets[conn_handle]; + event.data_len_chg.max_rx_octets = g_max_rx_octets[conn_handle]; + event.data_len_chg.max_tx_time = g_max_tx_time[conn_handle]; + event.data_len_chg.max_rx_time = g_max_rx_time[conn_handle]; + event.data_len_chg.conn_handle = conn_handle; + + ble_gap_event_listener_call(&event); +#if NIMBLE_BLE_CONNECT + ble_gap_call_conn_event_cb(&event, conn_handle); +#endif + return 0; + } + return ble_hs_hci_util_set_data_len(conn_handle, tx_octets, tx_time); } @@ -6863,7 +8188,9 @@ done: int ble_gap_dev_authorization(uint16_t conn_handle, bool authorized) { + ble_hs_lock(); struct ble_hs_conn *conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); if (conn != NULL) { if (!(conn->bhc_sec_state.authenticated)) { @@ -6935,14 +8262,59 @@ ble_gap_encryption_initiate(uint16_t conn_handle, #endif } +#if NIMBLE_BLE_SM && MYNEWT_VAL(BLE_SMP_ID_RESET) +static void +ble_gap_reset_irk(void) +{ + ble_addr_t oldest_peer_id_addr[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + struct ble_store_value_local_irk value_local_irk; + struct ble_store_key_local_irk key_local_irk; + uint8_t *local_id = NULL; + int rc, num_peers; + uint8_t tmp_addr[6]; + + ble_store_util_bonded_peers(&oldest_peer_id_addr[0], &num_peers, + MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + + if (num_peers != 0) { + return ; + } + + memset(&key_local_irk, 0, sizeof key_local_irk); + memset(&value_local_irk, 0x0, sizeof value_local_irk); + + ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL); + + if (local_id) { + memcpy (key_local_irk.addr.val , local_id, BLE_DEV_ADDR_LEN); + } + + key_local_irk.addr.type = BLE_ADDR_PUBLIC; + + ble_store_delete_local_irk(&key_local_irk); + + ble_hs_pvcy_set_default_irk(); + + //Remove the previous entry pertaining to 00:00:00:00:00:00 address + memset(tmp_addr, 0, 6); + rc = ble_hs_pvcy_remove_entry(0, tmp_addr); + if (rc != 0) { + BLE_HS_LOG(INFO, "Failed to remove old all zero IRK"); + return; + } + + ble_hs_pvcy_set_our_irk(NULL); + + BLE_HS_LOG(INFO,"Local IRK Reset"); +} +#endif + int ble_gap_unpair(const ble_addr_t *peer_addr) { #if NIMBLE_BLE_SM - int rc; - int ltk_rc = 0; - int irk_rc = 0; + int rc, err = 0; struct ble_hs_conn *conn; union ble_store_value value; union ble_store_key key; @@ -6985,32 +8357,46 @@ ble_gap_unpair(const ble_addr_t *peer_addr) // Checking if the device is in ble_store if (!rc) { if (value.sec.irk_present) { + /* We cannot delete entry from resolving list if there is ongoing + * discovery or advertising in progress */ + + if (ble_gap_adv_active() || + ble_gap_disc_active()) { + return BLE_HS_EBUSY; + } + // Delete the IRK as it is Distributed - irk_rc = ble_hs_pvcy_remove_entry(key.sec.peer_addr.type, - key.sec.peer_addr.val); - if (irk_rc != 0) { - BLE_HS_LOG(ERROR, "Error while removing IRK , rc = %x\n",irk_rc); + rc = ble_hs_pvcy_remove_entry(key.sec.peer_addr.type,key.sec.peer_addr.val); + if (rc != 0) { + BLE_HS_LOG(ERROR, "Error while removing IRK , rc = %x\n",rc); } } - if (value.sec.ltk_present || value.sec.irk_present || value.sec.csrk_present) { - // Delete the Peer record from store as LTK is present - ltk_rc = ble_store_util_delete_peer(&key.sec.peer_addr); - if (ltk_rc != 0) { - BLE_HS_LOG(ERROR, "Error while removing LTK , rc = %x\n",ltk_rc); - } + // Delete the Peer record from store as LTK is present + rc = ble_store_util_delete_peer(&key.sec.peer_addr); + if (rc != 0) { + BLE_HS_LOG(ERROR, "Error while removing LTK , rc = %x\n",rc); } - } - else { - rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, &key, &value); - if(!rc) { + } else { + rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, &key, &value); + if (!rc) { ble_store_util_delete_peer(&key.sec.peer_addr); - } - else { - BLE_HS_LOG(ERROR,"No record found for the given address in ble store , rc = %x\n",rc); - return rc; - } + } else { + BLE_HS_LOG(ERROR,"No record found for the given address in ble store , rc = %x\n",rc); + err = rc ; + } + } +#if MYNEWT_VAL(BLE_SMP_ID_RESET) + /* There are tracking risks associated with using a fixed or static IRK. + * A best-practices approach, when all pairing and bonding records are deleted, + * assign a new randomly-generated IRK. + */ + ble_gap_reset_irk(); +#endif + + if (err) { + return err; } return 0; @@ -7022,7 +8408,7 @@ ble_gap_unpair(const ble_addr_t *peer_addr) int ble_gap_unpair_oldest_peer(void) { -#if NIMBLE_BLE_SM +#if NIMBLE_BLE_SM && MYNEWT_VAL(BLE_STORE_MAX_BONDS) ble_addr_t oldest_peer_id_addr[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int num_peers; int rc; @@ -7134,6 +8520,7 @@ ble_gap_enc_event(uint16_t conn_handle, int status, /* If encryption succeeded and encryption has been restored for bonded device, * notify gatt server so it has chance to send notification/indication if needed. */ +#if MYNEWT_VAL(BLE_GATTS) if (security_restored) { ble_gatts_bonding_restored(conn_handle); #if MYNEWT_VAL(BLE_GATT_CACHING) @@ -7141,17 +8528,22 @@ ble_gap_enc_event(uint16_t conn_handle, int status, #endif return; } +#endif /* If this is fresh pairing and bonding has been established, * notify gatt server about that so previous subscriptions (before bonding) * can be stored. */ +#if MYNEWT_VAL(BLE_GATTS) if (bonded) { ble_gatts_bonding_established(conn_handle); #if MYNEWT_VAL(BLE_GATT_CACHING) ble_gattc_cache_conn_bonding_established(conn_handle); #endif } + +#endif + #endif } @@ -7175,14 +8567,23 @@ int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp) { #if NIMBLE_BLE_SM && NIMBLE_BLE_CONNECT + int rc; + +#if MYNEWT_VAL(BLE_HANDLE_REPEAT_PAIRING_DELETION) + /* Delete pairing internally instead of expecting host to do so */ + struct ble_gap_conn_desc desc; + rc = ble_gap_conn_find(rp->conn_handle, &desc); + assert(rc == 0); + ble_store_util_delete_peer(&desc.peer_id_addr); + return BLE_GAP_REPEAT_PAIRING_RETRY; +#else struct ble_gap_event event; - int rc; - memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_REPEAT_PAIRING; event.repeat_pairing = *rp; rc = ble_gap_call_conn_event_cb(&event, rp->conn_handle); return rc; +#endif #else return 0; #endif @@ -7339,6 +8740,19 @@ ble_gap_vs_hci_event(const void *buf, uint8_t len) ble_gap_event_listener_call(&event); } + +int +ble_hs_send_vs_event_mask(uint32_t event_mask) +{ + struct ble_hci_vs_set_event_mask_cp cmd; + + /* Populate command */ + cmd.event_mask = htole32(event_mask); + + /* Send command via HCI */ + return ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_EVT_MASK, + &cmd, sizeof(cmd), NULL, 0); +} #endif int @@ -7426,6 +8840,27 @@ ble_gap_end_test_evt(const void *buf, uint8_t len) ble_gap_event_listener_call(&event); } +/***************************************************************************** + * EATT * + *****************************************************************************/ +void +ble_gap_eatt_event(uint16_t conn_handle, uint8_t status, uint16_t cid) +{ +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_EATT; + + event.eatt.conn_handle = conn_handle; + event.eatt.status = status; + event.eatt.cid = cid; + + ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, conn_handle); +#endif +} + /***************************************************************************** * $preempt * *****************************************************************************/ @@ -7811,6 +9246,30 @@ ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, return BLE_HS_ENOTSUP; #endif } +int +ble_gap_rd_local_resolv_addr(uint8_t peer_addr_type, const ble_addr_t *peer_addr, + uint8_t *out_addr) +{ + struct ble_hci_le_rd_local_resolv_addr_cp cmd; + struct ble_hci_le_rd_local_resolv_addr_rp rsp; + uint16_t opcode; + int rc; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_LOCAL_RESOLV_ADDR); + + cmd.peer_addr_type = peer_addr_type; + memcpy(&cmd.peer_id_addr, peer_addr->val, sizeof(cmd.peer_id_addr)); + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + + if (rc!=0) { + return rc; + } + + memcpy(out_addr, &rsp.rpa, sizeof(rsp.rpa)); + + return 0; +} #if MYNEWT_VAL(BLE_HCI_VS) #if MYNEWT_VAL(BLE_POWER_CONTROL) @@ -7985,8 +9444,10 @@ ble_gap_host_check_status(void) uint16_t sync_handle = 0; #endif struct ble_hs_conn *conn; +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) ble_addr_t oldest_peer_id_addr[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; - int num_peers; + int num_peers = 0; +#endif /* Stop Advertising */ #if MYNEWT_VAL(BLE_EXT_ADV) @@ -8001,10 +9462,12 @@ ble_gap_host_check_status(void) } #else +#if NIMBLE_BLE_ADVERTISE || NIMBLE_BLE_CONNECT if (ble_gap_adv_active_instance(0)) { BLE_HS_LOG(ERROR, "Gap Advertising is active \n"); status |= BIT(BLE_GAP_STATUS_ADV); } +#endif #endif /* Stop scanning */ @@ -8027,6 +9490,7 @@ ble_gap_host_check_status(void) } } +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) /* Check for paired devices*/ ble_store_util_bonded_peers(&oldest_peer_id_addr[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); @@ -8035,6 +9499,7 @@ ble_gap_host_check_status(void) BLE_HS_LOG(ERROR, "Unpaired device exists\n"); status |= BIT(BLE_GAP_STATUS_PAIRED); } +#endif /* gatts reset */ if (ble_gatts_get_cfgable_chrs()) { diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap_priv.h index 5e05b8c6..a9f029f9 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gap_priv.h @@ -95,6 +95,8 @@ void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev #endif void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); void ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev); +void ble_gap_rx_rd_rem_ver_info_complete(const struct ble_hci_ev_rd_rem_ver_info_cmp *ev); +void ble_gap_event_connect_call(uint16_t conn_handle, int status); #if MYNEWT_VAL(BLE_CONN_SUBRATING) void ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change *ev); #endif @@ -102,6 +104,11 @@ void ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change * void ble_gap_rx_transmit_power_report(const struct ble_hci_ev_le_subev_transmit_power_report *ev); void ble_gap_rx_le_pathloss_threshold(const struct ble_hci_ev_le_subev_path_loss_threshold *ev); #endif +#if MYNEWT_VAL(BLE_AOA_AOD) +void ble_gap_rx_connless_iq_report(const struct ble_hci_ev_le_subev_connless_iq_rpt *ev); +void ble_gap_rx_conn_iq_report(const struct ble_hci_ev_le_subev_conn_iq_rpt *ev); +void ble_gap_rx_cte_req_failed(const struct ble_hci_ev_le_subev_cte_req_failed *ev); +#endif struct ble_gap_conn_complete { @@ -116,8 +123,17 @@ struct ble_gap_conn_complete uint8_t master_clk_acc; uint8_t local_rpa[BLE_DEV_ADDR_LEN]; uint8_t peer_rpa[BLE_DEV_ADDR_LEN]; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint8_t adv_handle; + uint16_t sync_handle; +#endif }; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +void ble_gap_rx_periodic_adv_subev_data_req(const struct ble_hci_ev_le_subev_periodic_adv_subev_data_req *ev); +void ble_gap_rx_periodic_adv_response(const struct ble_gap_periodic_adv_response resp); +void ble_gap_rx_conn_comp_failed(const struct ble_gap_conn_complete *evt); +#endif int ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance); void ble_gap_rx_disconn_complete(const struct ble_hci_ev_disconn_cmp *ev); void ble_gap_rx_update_complete(const struct ble_hci_ev_le_subev_conn_upd_complete *ev); @@ -143,6 +159,7 @@ int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp); void ble_gap_pairing_complete_event(uint16_t conn_handle, int status); void ble_gap_vs_hci_event(const void *buf, uint8_t len); int ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, int is_read); +void ble_gap_eatt_event(uint16_t conn_handle, uint8_t status, uint16_t cid); int ble_gap_master_in_progress(void); void ble_gap_preempt(void); diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatt_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatt_priv.h index 34c10ed1..eda5b85e 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatt_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatt_priv.h @@ -68,6 +68,8 @@ STATS_SECT_START(ble_gattc_stats) STATS_SECT_ENTRY(write_reliable_fail) STATS_SECT_ENTRY(notify) STATS_SECT_ENTRY(notify_fail) + STATS_SECT_ENTRY(multi_notify) + STATS_SECT_ENTRY(multi_notify_fail) STATS_SECT_ENTRY(indicate) STATS_SECT_ENTRY(indicate_fail) STATS_SECT_ENTRY(proc_timeout) @@ -90,7 +92,6 @@ extern STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats; #define BLE_GATT_CHR_DECL_SZ_16 5 #define BLE_GATT_CHR_DECL_SZ_128 19 -#define BLE_GATT_CHR_CLI_SUP_FEAT_SZ 1 /** * For now only 3 bits in first octet are defined * @@ -108,6 +109,7 @@ struct ble_gatts_conn { int num_clt_cfgs; #if MYNEWT_VAL(BLE_GATT_CACHING) bool aware_state; + uint8_t half_aware:1; bool sent_err; #endif @@ -119,7 +121,7 @@ struct ble_gatts_conn { * future proof if more octets might be used. * (Vol. 3, Part G, 7.2) */ - uint8_t peer_cl_sup_feat[BLE_GATT_CHR_CLI_SUP_FEAT_SZ]; + uint8_t peer_cl_sup_feat[MYNEWT_VAL(BLE_GATT_CSFC_SIZE)]; }; /*** @client. */ @@ -127,32 +129,32 @@ struct ble_gatts_conn { int ble_gattc_locked_by_cur_task(void); void ble_gatts_indicate_fail_notconn(uint16_t conn_handle); -void ble_gattc_rx_err(uint16_t conn_handle, uint16_t handle, uint16_t status); -void ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu); -void ble_gattc_rx_read_type_adata(uint16_t conn_handle, +void ble_gattc_rx_err(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t status); +void ble_gattc_rx_mtu(uint16_t conn_handle, uint16_t cid, int status, uint16_t chan_mtu); +void ble_gattc_rx_read_type_adata(uint16_t conn_handle, uint16_t cid, struct ble_att_read_type_adata *adata); -void ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status); -void ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_type_complete(uint16_t conn_handle, uint16_t cid, int status); +void ble_gattc_rx_read_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **rxom); -void ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **rxom); -void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **rxom, bool variable); -void ble_gattc_rx_read_group_type_adata( - uint16_t conn_handle, struct ble_att_read_group_type_adata *adata); -void ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int rc); -void ble_gattc_rx_find_type_value_hinfo( - uint16_t conn_handle, struct ble_att_find_type_value_hinfo *hinfo); -void ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status); -void ble_gattc_rx_write_rsp(uint16_t conn_handle); -void ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, uint16_t cid, + struct ble_att_read_group_type_adata *adata); +void ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, uint16_t cid, int rc); +void ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, uint16_t cid, + struct ble_att_find_type_value_hinfo *hinfo); +void ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, uint16_t cid, int status); +void ble_gattc_rx_write_rsp(uint16_t conn_handle, uint16_t cid); +void ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, uint16_t cid, int status, uint16_t handle, uint16_t offset, struct os_mbuf **rxom); -void ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status); -void ble_gatts_rx_indicate_rsp(uint16_t conn_handle); -void ble_gattc_rx_find_info_idata(uint16_t conn_handle, +void ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, uint16_t cid, int status); +void ble_gatts_rx_indicate_rsp(uint16_t conn_handle, uint16_t cid); +void ble_gattc_rx_find_info_idata(uint16_t conn_handle, uint16_t cid, struct ble_att_find_info_idata *idata); -void ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status); +void ble_gattc_rx_find_info_complete(uint16_t conn_handle, uint16_t cid, int status); void ble_gattc_connection_txable(uint16_t conn_handle); void ble_gattc_connection_broken(uint16_t conn_handle); int32_t ble_gattc_timer(void); @@ -222,11 +224,13 @@ int ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs, int ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle, uint8_t op, uint16_t offset, struct os_mbuf **om, void *arg); +void ble_gatts_set_clt_cfg_perm_flags(uint8_t flags); #if MYNEWT_VAL(BLE_GATT_CACHING) struct ble_gatts_aware_state { uint8_t peer_id_addr[6]; bool aware; + uint8_t half_aware:1; }; extern struct ble_gatts_aware_state ble_gatts_conn_aware_states[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc.c index 0669b6c2..037b5f46 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc.c @@ -61,9 +61,12 @@ #include "host/ble_gap.h" #include "ble_hs_priv.h" #include "ble_gattc_cache_priv.h" - +#if MYNEWT_VAL(BLE_GATT_CACHING) +#include "host/ble_esp_gattc_cache.h" +#endif #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTC) #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif @@ -72,6 +75,7 @@ #define max(a, b) ((a) > (b) ? (a) : (b)) #endif +#endif /***************************************************************************** * $definitions / declarations * *****************************************************************************/ @@ -83,6 +87,7 @@ #define BLE_GATTC_UNRESPONSIVE_TIMEOUT_MS 30000 /* ms */ #define BLE_GATT_OP_NONE UINT8_MAX + #define BLE_GATT_OP_MTU 0 #define BLE_GATT_OP_DISC_ALL_SVCS 1 #define BLE_GATT_OP_DISC_SVC_UUID 2 @@ -110,6 +115,7 @@ struct ble_gattc_proc { uint32_t exp_os_ticks; uint16_t conn_handle; + uint16_t cid; uint8_t op; uint8_t flags; @@ -139,7 +145,11 @@ struct ble_gattc_proc { uint16_t cur_start; uint16_t cur_end; +#if MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + ble_gatt_disc_incl_svc_fn *cb; +#else ble_gatt_disc_svc_fn *cb; +#endif void *cb_arg; } find_inc_svcs; @@ -224,6 +234,10 @@ struct ble_gattc_proc { }; }; + +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) +static struct ble_gattc_proc_list temp_proc_list; +#endif STAILQ_HEAD(ble_gattc_proc_list, ble_gattc_proc); /** @@ -232,6 +246,8 @@ STAILQ_HEAD(ble_gattc_proc_list, ble_gattc_proc); */ typedef void ble_gattc_err_fn(struct ble_gattc_proc *proc, int status, uint16_t att_handle); + +#if MYNEWT_VAL(BLE_GATTC) static ble_gattc_err_fn ble_gattc_mtu_err; static ble_gattc_err_fn ble_gattc_disc_all_svcs_err; static ble_gattc_err_fn ble_gattc_disc_svc_uuid_err; @@ -243,12 +259,18 @@ static ble_gattc_err_fn ble_gattc_read_err; static ble_gattc_err_fn ble_gattc_read_uuid_err; static ble_gattc_err_fn ble_gattc_read_long_err; static ble_gattc_err_fn ble_gattc_read_mult_err; +static ble_gattc_err_fn ble_gattc_read_mult_var_err; static ble_gattc_err_fn ble_gattc_write_err; static ble_gattc_err_fn ble_gattc_write_long_err; static ble_gattc_err_fn ble_gattc_write_reliable_err; +#endif + +#if MYNEWT_VAL(BLE_GATTS) static ble_gattc_err_fn ble_gatts_indicate_err; +#endif static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_CNT] = { +#if MYNEWT_VAL(BLE_GATTC) [BLE_GATT_OP_MTU] = ble_gattc_mtu_err, [BLE_GATT_OP_DISC_ALL_SVCS] = ble_gattc_disc_all_svcs_err, [BLE_GATT_OP_DISC_SVC_UUID] = ble_gattc_disc_svc_uuid_err, @@ -260,12 +282,17 @@ static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_READ_UUID] = ble_gattc_read_uuid_err, [BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_err, [BLE_GATT_OP_READ_MULT] = ble_gattc_read_mult_err, + [BLE_GATT_OP_READ_MULT_VAR] = ble_gattc_read_mult_var_err, [BLE_GATT_OP_WRITE] = ble_gattc_write_err, [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_err, [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_err, +#endif +#if MYNEWT_VAL(BLE_GATTS) [BLE_GATT_OP_INDICATE] = ble_gatts_indicate_err, +#endif }; +#if MYNEWT_VAL(BLE_GATTC) /** * Resume functions - these handle periodic retries of procedures that have * stalled due to memory exhaustion. @@ -295,6 +322,7 @@ ble_gattc_resume_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_READ_UUID] = NULL, [BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_resume, [BLE_GATT_OP_READ_MULT] = NULL, + [BLE_GATT_OP_READ_MULT_VAR] = NULL, [BLE_GATT_OP_WRITE] = NULL, [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_resume, [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_resume, @@ -318,6 +346,7 @@ static ble_gattc_tmo_fn ble_gattc_read_tmo; static ble_gattc_tmo_fn ble_gattc_read_uuid_tmo; static ble_gattc_tmo_fn ble_gattc_read_long_tmo; static ble_gattc_tmo_fn ble_gattc_read_mult_tmo; +static ble_gattc_tmo_fn ble_gattc_read_mult_var_tmo; static ble_gattc_tmo_fn ble_gattc_write_tmo; static ble_gattc_tmo_fn ble_gattc_write_long_tmo; static ble_gattc_tmo_fn ble_gattc_write_reliable_tmo; @@ -336,6 +365,7 @@ ble_gattc_tmo_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_READ_UUID] = ble_gattc_read_uuid_tmo, [BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_tmo, [BLE_GATT_OP_READ_MULT] = ble_gattc_read_mult_tmo, + [BLE_GATT_OP_READ_MULT_VAR] = ble_gattc_read_mult_var_tmo, [BLE_GATT_OP_WRITE] = ble_gattc_write_tmo, [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_tmo, [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_tmo, @@ -420,6 +450,7 @@ static const struct ble_gattc_rx_exec_entry { { BLE_GATT_OP_WRITE_RELIABLE, ble_gattc_write_reliable_rx_exec }, }; +#endif static os_membuf_t ble_gattc_proc_mem[ OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GATT_MAX_PROCS), sizeof (struct ble_gattc_proc)) @@ -430,6 +461,7 @@ static struct os_mempool ble_gattc_proc_pool; /* The list of active GATT client procedures. */ static struct ble_gattc_proc_list ble_gattc_procs; +#if MYNEWT_VAL(BLE_GATTC) /* The time when we should attempt to resume stalled procedures, in OS ticks. * A value of 0 indicates no stalled procedures. */ @@ -472,6 +504,8 @@ STATS_NAME_START(ble_gattc_stats) STATS_NAME(ble_gattc_stats, write_reliable_fail) STATS_NAME(ble_gattc_stats, notify) STATS_NAME(ble_gattc_stats, notify_fail) + STATS_NAME(ble_gattc_stats, multi_notify) + STATS_NAME(ble_gattc_stats, multi_notify_fail) STATS_NAME(ble_gattc_stats, indicate) STATS_NAME(ble_gattc_stats, indicate_fail) STATS_NAME(ble_gattc_stats, proc_timeout) @@ -480,6 +514,7 @@ STATS_NAME_END(ble_gattc_stats) /***************************************************************************** * $debug * *****************************************************************************/ +#endif static void ble_gattc_dbg_assert_proc_not_inserted(struct ble_gattc_proc *proc) @@ -497,6 +532,7 @@ ble_gattc_dbg_assert_proc_not_inserted(struct ble_gattc_proc *proc) #endif } + /***************************************************************************** * $log * *****************************************************************************/ @@ -507,6 +543,7 @@ ble_gattc_log_proc_init(const char *name) BLE_HS_LOG(INFO, "GATT procedure initiated: %s", name); } +#if MYNEWT_VAL(BLE_GATTC) static void ble_gattc_log_uuid(const ble_uuid_t *uuid) { @@ -645,6 +682,7 @@ ble_gattc_log_write_reliable(struct ble_gattc_proc *proc) } BLE_HS_LOG(INFO, "\n"); } +#endif static void ble_gattc_log_notify(uint16_t att_handle) @@ -653,6 +691,18 @@ ble_gattc_log_notify(uint16_t att_handle) BLE_HS_LOG(INFO, "att_handle=%d\n", att_handle); } + +#if MYNEWT_VAL(BLE_GATTC) +static void +ble_gattc_log_multi_notify(struct ble_gatt_notif * tuples, uint16_t num) +{ + ble_gattc_log_proc_init("multi handle notify; "); + for (int i = 0; i < num; i++) { + BLE_HS_LOG(INFO, "att_handle=%d", tuples[i].handle); + } +} + +#endif static void ble_gattc_log_indicate(uint16_t att_handle) { @@ -660,6 +710,7 @@ ble_gattc_log_indicate(uint16_t att_handle) BLE_HS_LOG(INFO, "att_handle=%d\n", att_handle); } +#if MYNEWT_VAL(BLE_GATTC) /***************************************************************************** * $rx entry * *****************************************************************************/ @@ -688,7 +739,7 @@ ble_gattc_rx_entry_find(uint8_t op, const void *rx_entries, int num_entries) /***************************************************************************** * $proc * *****************************************************************************/ - +#endif /** * Allocates a proc entry. * @@ -707,6 +758,15 @@ ble_gattc_proc_alloc(void) return proc; } + +static void +ble_gattc_proc_prepare(struct ble_gattc_proc *proc, uint16_t conn_handle, uint8_t op) +{ + proc->conn_handle = conn_handle; + proc->op = op; + proc->cid = ble_eatt_get_available_chan_cid(conn_handle, op); +} + /** * Frees the specified proc entry. No-op if passed a null pointer. */ @@ -738,6 +798,12 @@ ble_gattc_proc_free(struct ble_gattc_proc *proc) break; } +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (ble_hs_cfg.eatt && proc->cid != BLE_L2CAP_CID_ATT) { + ble_eatt_release_chan(proc->conn_handle, proc->op); + } +#endif + #if MYNEWT_VAL(BLE_HS_DEBUG) memset(proc, 0xff, sizeof *proc); #endif @@ -763,6 +829,7 @@ ble_gattc_proc_set_exp_timer(struct ble_gattc_proc *proc) ble_npl_time_ms_to_ticks32(BLE_GATTC_UNRESPONSIVE_TIMEOUT_MS); } +#if MYNEWT_VAL(BLE_GATTC) static void ble_gattc_proc_set_resume_timer(struct ble_gattc_proc *proc) { @@ -782,6 +849,8 @@ ble_gattc_proc_set_resume_timer(struct ble_gattc_proc *proc) } } +#endif + static void ble_gattc_process_status(struct ble_gattc_proc *proc, int status) { @@ -801,6 +870,7 @@ ble_gattc_process_status(struct ble_gattc_proc *proc, int status) } } +#if MYNEWT_VAL(BLE_GATTC) /** * Processes the return code that results from an attempt to resume a * procedure. If the resume attempt failed due to memory exhaustion at a lower @@ -826,6 +896,7 @@ ble_gattc_process_resume_status(struct ble_gattc_proc *proc, int status) /***************************************************************************** * $util * *****************************************************************************/ +#endif /** * Retrieves the error dispatch entry with the specified op code. @@ -837,6 +908,7 @@ ble_gattc_err_dispatch_get(uint8_t op) return ble_gattc_err_dispatch[op]; } +#if MYNEWT_VAL(BLE_GATTC) /** * Retrieves the error dispatch entry with the specified op code. */ @@ -854,10 +926,12 @@ ble_gattc_tmo_dispatch_get(uint8_t op) return ble_gattc_tmo_dispatch[op]; } +#endif typedef int ble_gattc_match_fn(struct ble_gattc_proc *proc, void *arg); struct ble_gattc_criteria_conn_op { uint16_t conn_handle; + uint16_t psm; uint8_t op; }; @@ -889,6 +963,29 @@ ble_gattc_proc_matches_conn_op(struct ble_gattc_proc *proc, void *arg) return 1; } +#if MYNEWT_VAL(BLE_GATTC) +static int +ble_gattc_proc_matches_conn_cid_op(struct ble_gattc_proc *proc, void *arg) +{ + const struct ble_gattc_criteria_conn_op *criteria; + + criteria = arg; + + if (criteria->conn_handle != proc->conn_handle) { + return 0; + } + + if (criteria->psm != proc->cid) { + return 0; + } + + if (criteria->op != proc->op && criteria->op != BLE_GATT_OP_NONE) { + return 0; + } + + return 1; +} + struct ble_gattc_criteria_exp { ble_npl_time_t now; int32_t next_exp_in; @@ -918,6 +1015,7 @@ ble_gattc_proc_matches_expired(struct ble_gattc_proc *proc, void *arg) struct ble_gattc_criteria_conn_rx_entry { uint16_t conn_handle; + uint16_t cid; const void *rx_entries; int num_rx_entries; const void *matching_rx_entry; @@ -931,7 +1029,8 @@ ble_gattc_proc_matches_conn_rx_entry(struct ble_gattc_proc *proc, void *arg) criteria = arg; if (criteria->conn_handle != BLE_HS_CONN_HANDLE_NONE && - criteria->conn_handle != proc->conn_handle) { + (criteria->conn_handle != proc->conn_handle || + criteria->cid != proc->cid)) { return 0; } @@ -943,6 +1042,8 @@ ble_gattc_proc_matches_conn_rx_entry(struct ble_gattc_proc *proc, void *arg) return (criteria->matching_rx_entry != NULL); } +#endif + static void ble_gattc_extract(ble_gattc_match_fn *cb, void *arg, int max_procs, struct ble_gattc_proc_list *dst_list) @@ -950,6 +1051,10 @@ ble_gattc_extract(ble_gattc_match_fn *cb, void *arg, int max_procs, struct ble_gattc_proc *proc; struct ble_gattc_proc *prev; struct ble_gattc_proc *next; +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + struct ble_gattc_proc *cur; + uint8_t flag = 0; +#endif int num_extracted; /* Only the parent task is allowed to remove entries from the list. */ @@ -961,6 +1066,28 @@ ble_gattc_extract(ble_gattc_match_fn *cb, void *arg, int max_procs, ble_hs_lock(); prev = NULL; + +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + proc = STAILQ_FIRST(&temp_proc_list); + while (proc != NULL) { + next = STAILQ_NEXT(proc, next); + STAILQ_FOREACH(cur, &ble_gattc_procs, next) { + if (proc == cur) { + flag = 1; + break; + } + } + if (!flag) { + /* Detected a preemption case */ + STAILQ_INSERT_TAIL(&ble_gattc_procs, proc, next); + } + flag = 0; + proc = next; + } + /* Clear the temp proc list */ + STAILQ_INIT(&temp_proc_list); +#endif + proc = STAILQ_FIRST(&ble_gattc_procs); while (proc != NULL) { next = STAILQ_NEXT(proc, next); @@ -989,6 +1116,7 @@ ble_gattc_extract(ble_gattc_match_fn *cb, void *arg, int max_procs, ble_hs_unlock(); } +#if MYNEWT_VAL(BLE_GATTC) static struct ble_gattc_proc * ble_gattc_extract_one(ble_gattc_match_fn *cb, void *arg) { @@ -998,6 +1126,8 @@ ble_gattc_extract_one(ble_gattc_match_fn *cb, void *arg) return STAILQ_FIRST(&dst_list); } +#endif + static void ble_gattc_extract_by_conn_op(uint16_t conn_handle, uint8_t op, int max_procs, struct ble_gattc_proc_list *dst_list) @@ -1010,12 +1140,28 @@ ble_gattc_extract_by_conn_op(uint16_t conn_handle, uint8_t op, int max_procs, ble_gattc_extract(ble_gattc_proc_matches_conn_op, &criteria, max_procs, dst_list); } + +#if MYNEWT_VAL(BLE_GATTC) +static void +ble_gattc_extract_by_conn_cid_op(uint16_t conn_handle, uint16_t psm, uint8_t op, + int max_procs, + struct ble_gattc_proc_list *dst_list) +{ + struct ble_gattc_criteria_conn_op criteria; + + criteria.conn_handle = conn_handle; + criteria.op = op; + criteria.psm = psm; + + ble_gattc_extract(ble_gattc_proc_matches_conn_cid_op, &criteria, max_procs, dst_list); +} + static struct ble_gattc_proc * -ble_gattc_extract_first_by_conn_op(uint16_t conn_handle, uint8_t op) +ble_gattc_extract_first_by_conn_cid_op(uint16_t conn_handle, uint16_t cid, uint8_t op) { struct ble_gattc_proc_list dst_list; - ble_gattc_extract_by_conn_op(conn_handle, op, 1, &dst_list); + ble_gattc_extract_by_conn_cid_op(conn_handle, cid, op, 1, &dst_list); return STAILQ_FIRST(&dst_list); } @@ -1050,7 +1196,7 @@ ble_gattc_extract_expired(struct ble_gattc_proc_list *dst_list) } static struct ble_gattc_proc * -ble_gattc_extract_with_rx_entry(uint16_t conn_handle, +ble_gattc_extract_with_rx_entry(uint16_t conn_handle, uint16_t cid, const void *rx_entries, int num_rx_entries, const void **out_rx_entry) { @@ -1058,6 +1204,7 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle, struct ble_gattc_proc *proc; criteria.conn_handle = conn_handle; + criteria.cid = cid; criteria.rx_entries = rx_entries; criteria.num_rx_entries = num_rx_entries; criteria.matching_rx_entry = NULL; @@ -1075,6 +1222,7 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle, * list and returned. * * @param conn_handle The connection handle to match against. + * @param cid Source CID of L2CAP channel used * @param rx_entries The array of rx entries corresponding to the * op code of the incoming response. * @param out_rx_entry On success, the address of the matching rx @@ -1083,12 +1231,12 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle, * @return The matching proc entry on success; * null on failure. */ -#define BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, rx_entries, out_rx_entry) \ +#define BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, rx_entries, out_rx_entry) \ ble_gattc_extract_with_rx_entry( \ - (conn_handle), (rx_entries), \ + (conn_handle), (cid), (rx_entries), \ sizeof (rx_entries) / sizeof (rx_entries)[0], \ (const void **)(out_rx_entry)) - +#endif /** * Causes all GATT procedures matching the specified criteria to fail with the @@ -1118,6 +1266,7 @@ ble_gattc_fail_procs(uint16_t conn_handle, uint8_t op, int status) } } +#if MYNEWT_VAL(BLE_GATTC) static void ble_gattc_resume_procs(void) { @@ -1303,7 +1452,7 @@ ble_gattc_mtu_tx(struct ble_gattc_proc *proc) int rc; ble_hs_lock(); - rc = ble_att_conn_chan_find(proc->conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(proc->conn_handle, proc->cid, &conn, &chan); if (rc == 0) { mtu = chan->my_mtu; } @@ -1332,6 +1481,7 @@ ble_gattc_exchange_mtu(uint16_t conn_handle, ble_gatt_mtu_fn *cb, void *cb_arg) proc->op = BLE_GATT_OP_MTU; proc->conn_handle = conn_handle; + proc->cid = BLE_L2CAP_CID_ATT; proc->mtu.cb = cb; proc->mtu.cb_arg = cb_arg; @@ -1408,7 +1558,7 @@ ble_gattc_disc_all_svcs_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_read_group_type(proc->conn_handle, + rc = ble_att_clt_tx_read_group_type(proc->conn_handle, proc->cid, proc->disc_all_svcs.prev_handle + 1, 0xffff, &uuid.u); if (rc != 0) { @@ -1561,12 +1711,17 @@ ble_gattc_disc_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb, goto done; } - proc->op = BLE_GATT_OP_DISC_ALL_SVCS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_ALL_SVCS); + proc->disc_all_svcs.prev_handle = 0x0000; proc->disc_all_svcs.cb = cb; proc->disc_all_svcs.cb_arg = cb_arg; +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + ble_hs_lock(); + STAILQ_INSERT_TAIL(&temp_proc_list, proc, next); + ble_hs_unlock(); +#endif ble_gattc_log_proc_init("discover all services\n"); rc = ble_gattc_disc_all_svcs_tx(proc); @@ -1577,6 +1732,11 @@ ble_gattc_disc_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb, done: if (rc != 0) { STATS_INC(ble_gattc_stats, disc_all_svcs_fail); +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + ble_hs_lock(); + STAILQ_REMOVE(&temp_proc_list,proc,ble_gattc_proc, next); + ble_hs_unlock(); +#endif } ble_gattc_process_status(proc, rc); @@ -1641,7 +1801,7 @@ ble_gattc_disc_svc_uuid_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); ble_uuid_flat(&proc->disc_svc_uuid.service_uuid.u, val); - rc = ble_att_clt_tx_find_type_value(proc->conn_handle, + rc = ble_att_clt_tx_find_type_value(proc->conn_handle, proc->cid, proc->disc_svc_uuid.prev_handle + 1, 0xffff, BLE_ATT_UUID_PRIMARY_SERVICE, val, @@ -1780,8 +1940,8 @@ ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid, goto done; } - proc->op = BLE_GATT_OP_DISC_SVC_UUID; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_SVC_UUID); + ble_uuid_to_any(uuid, &proc->disc_svc_uuid.service_uuid); proc->disc_svc_uuid.prev_handle = 0x0000; proc->disc_svc_uuid.cb = cb; @@ -1814,15 +1974,22 @@ done: * @return The return code of the callback (or 0 if there * is no callback). */ +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) static int ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle, - struct ble_gatt_svc *service) + struct ble_gatt_incl_svc *incl_svc) +#else +static int +ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status, + uint16_t att_handle, + struct ble_gatt_svc *incl_svc) +#endif { int rc; BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task()); - BLE_HS_DBG_ASSERT(service != NULL || status != 0); + BLE_HS_DBG_ASSERT(incl_svc != NULL || status != 0); ble_gattc_dbg_assert_proc_not_inserted(proc); if (status != 0 && status != BLE_HS_EDONE) { @@ -1834,7 +2001,7 @@ ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status, } else { rc = proc->find_inc_svcs.cb(proc->conn_handle, ble_gattc_error(status, att_handle), - service, proc->find_inc_svcs.cb_arg); + incl_svc, proc->find_inc_svcs.cb_arg); } return rc; @@ -1862,7 +2029,7 @@ ble_gattc_find_inc_svcs_tx(struct ble_gattc_proc *proc) if (proc->find_inc_svcs.cur_start == 0) { /* Find the next included service. */ - rc = ble_att_clt_tx_read_type(proc->conn_handle, + rc = ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->find_inc_svcs.prev_handle + 1, proc->find_inc_svcs.end_handle, &uuid.u); if (rc != 0) { @@ -1870,7 +2037,7 @@ ble_gattc_find_inc_svcs_tx(struct ble_gattc_proc *proc) } } else { /* Read the UUID of the previously found service. */ - rc = ble_att_clt_tx_read(proc->conn_handle, + rc = ble_att_clt_tx_read(proc->conn_handle, proc->cid, proc->find_inc_svcs.cur_start); if (rc != 0) { return rc; @@ -1924,7 +2091,11 @@ static int ble_gattc_find_inc_svcs_rx_read_rsp(struct ble_gattc_proc *proc, int status, struct os_mbuf **om) { +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) + struct ble_gatt_incl_svc service; +#else struct ble_gatt_svc service; +#endif int rc; ble_gattc_dbg_assert_proc_not_inserted(proc); @@ -1953,6 +2124,7 @@ ble_gattc_find_inc_svcs_rx_read_rsp(struct ble_gattc_proc *proc, int status, /* Report discovered service to application. */ service.start_handle = proc->find_inc_svcs.cur_start; service.end_handle = proc->find_inc_svcs.cur_end; + rc = ble_gattc_find_inc_svcs_cb(proc, 0, 0, &service); if (rc != 0) { /* Application has indicated that the procedure should be aborted. */ @@ -1982,7 +2154,11 @@ static int ble_gattc_find_inc_svcs_rx_adata(struct ble_gattc_proc *proc, struct ble_att_read_type_adata *adata) { +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) + struct ble_gatt_incl_svc service = {0}; +#else struct ble_gatt_svc service = {0}; +#endif int call_cb; int cbrc; int rc; @@ -2016,6 +2192,9 @@ ble_gattc_find_inc_svcs_rx_adata(struct ble_gattc_proc *proc, break; case BLE_GATTS_INC_SVC_LEN_UUID: +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) + service.handle = adata->att_handle; +#endif service.start_handle = get_le16(adata->value + 0); service.end_handle = get_le16(adata->value + 2); rc = ble_uuid_init_from_att_buf(&service.uuid, adata->value + 4, 2); @@ -2076,10 +2255,17 @@ ble_gattc_find_inc_svcs_rx_complete(struct ble_gattc_proc *proc, int status) return 0; } +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) +int +ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, + ble_gatt_disc_incl_svc_fn *cb, void *cb_arg) +#else int ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, ble_gatt_disc_svc_fn *cb, void *cb_arg) +#endif { #if !MYNEWT_VAL(BLE_GATT_FIND_INC_SVCS) return BLE_HS_ENOTSUP; @@ -2088,6 +2274,12 @@ ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, struct ble_gattc_proc *proc; int rc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + rc = ble_gattc_cache_conn_search_inc_svcs(conn_handle, start_handle, end_handle, cb, cb_arg); + if (rc == 0) { + return rc; + } +#endif STATS_INC(ble_gattc_stats, find_inc_svcs); proc = ble_gattc_proc_alloc(); @@ -2096,8 +2288,8 @@ ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_FIND_INC_SVCS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_FIND_INC_SVCS); + proc->find_inc_svcs.prev_handle = start_handle - 1; proc->find_inc_svcs.end_handle = end_handle; proc->find_inc_svcs.cb = cb; @@ -2176,7 +2368,7 @@ ble_gattc_disc_all_chrs_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_read_type(proc->conn_handle, + rc = ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->disc_all_chrs.prev_handle + 1, proc->disc_all_chrs.end_handle, &uuid.u); if (rc != 0) { @@ -2330,13 +2522,18 @@ ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_DISC_ALL_CHRS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_ALL_CHRS); + proc->disc_all_chrs.prev_handle = start_handle - 1; proc->disc_all_chrs.end_handle = end_handle; proc->disc_all_chrs.cb = cb; proc->disc_all_chrs.cb_arg = cb_arg; +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + ble_hs_lock(); + STAILQ_INSERT_TAIL(&temp_proc_list, proc, next); + ble_hs_unlock(); +#endif ble_gattc_log_disc_all_chrs(proc); rc = ble_gattc_disc_all_chrs_tx(proc); @@ -2347,6 +2544,11 @@ ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle, done: if (rc != 0) { STATS_INC(ble_gattc_stats, disc_all_chrs_fail); +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + ble_hs_lock(); + STAILQ_REMOVE(&temp_proc_list,proc,ble_gattc_proc, next); + ble_hs_unlock(); +#endif } ble_gattc_process_status(proc, rc); @@ -2410,7 +2612,7 @@ ble_gattc_disc_chr_uuid_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_read_type(proc->conn_handle, + rc = ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->disc_chr_uuid.prev_handle + 1, proc->disc_chr_uuid.end_handle, &uuid.u); if (rc != 0) { @@ -2575,8 +2777,8 @@ ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_DISC_CHR_UUID; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_CHR_UUID); + ble_uuid_to_any(uuid, &proc->disc_chr_uuid.chr_uuid); proc->disc_chr_uuid.prev_handle = start_handle - 1; proc->disc_chr_uuid.end_handle = end_handle; @@ -2655,7 +2857,7 @@ ble_gattc_disc_all_dscs_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_find_info(proc->conn_handle, + rc = ble_att_clt_tx_find_info(proc->conn_handle, proc->cid, proc->disc_all_dscs.prev_handle + 1, proc->disc_all_dscs.end_handle); if (rc != 0) { @@ -2791,14 +2993,19 @@ ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_DISC_ALL_DSCS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_ALL_DSCS); + proc->disc_all_dscs.chr_val_handle = start_handle; proc->disc_all_dscs.prev_handle = start_handle; proc->disc_all_dscs.end_handle = end_handle; proc->disc_all_dscs.cb = cb; proc->disc_all_dscs.cb_arg = cb_arg; +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + ble_hs_lock(); + STAILQ_INSERT_TAIL(&temp_proc_list, proc, next); + ble_hs_unlock(); +#endif ble_gattc_log_disc_all_dscs(proc); rc = ble_gattc_disc_all_dscs_tx(proc); @@ -2809,12 +3016,421 @@ ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle, done: if (rc != 0) { STATS_INC(ble_gattc_stats, disc_all_dscs_fail); +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + ble_hs_lock(); + STAILQ_REMOVE(&temp_proc_list,proc,ble_gattc_proc, next); + ble_hs_unlock(); +#endif } ble_gattc_process_status(proc, rc); return rc; } +#if MYNEWT_VAL(BLE_GATT_CACHING) +int ble_gattc_check_valid_param(uint16_t num, uint16_t offset) +{ + if (num == 0) { + return BLE_ATT_ERR_ATTR_NOT_FOUND; + } else if (offset >= num) { + return BLE_ATT_ERR_INVALID_OFFSET; + } + + return 0; // Success +} + +static void ble_gattc_fill_gatt_db_conversion(uint16_t *count, uint16_t num, esp_ble_gatt_db_attr_type_t type, + uint16_t offset, void *result, ble_gattc_db_elem_t *db) +{ + uint16_t db_size = ((*count + offset) > num) ? (num - offset) : *count; + switch (type) { + case ESP_BLE_GATT_DB_PRIMARY_SERVICE: + case ESP_BLE_GATT_DB_SECONDARY_SERVICE: { + ble_gattc_service_elem_t *svc_result = (ble_gattc_service_elem_t *)result; + for (int i = 0; i < db_size; i++) { + svc_result->is_primary = (db[offset + i].type == (int)BLE_GATT_DB_PRIMARY_SERVICE); + svc_result->start_handle = db[offset + i].start_handle; + svc_result->end_handle = db[offset + i].end_handle; + svc_result->uuid = db[offset + i].uuid; + svc_result++; + } + break; + } + case ESP_BLE_GATT_DB_CHARACTERISTIC: { + ble_gattc_char_elem_t *char_result = (ble_gattc_char_elem_t *)result; + for (int i = 0; i < db_size; i++) { + char_result->char_handle = db[offset + i].handle; + char_result->properties = db[offset + i].properties; + char_result->uuid = db[offset + i].uuid; + char_result++; + } + break; + } + case ESP_BLE_GATT_DB_DESCRIPTOR: { + ble_gattc_descr_elem_t *descr_result = (ble_gattc_descr_elem_t *)result; + for (int i = 0; i < db_size; i++) { + descr_result->handle = db[offset + i].handle; + descr_result->uuid = db[offset + i].uuid; + descr_result++; + } + break; + } + case BLE_GATT_DB_INCLUDED_SERVICE: { + ble_gattc_included_svc_elem_t *incl_result = (ble_gattc_included_svc_elem_t *)result; + for (int i = 0; i < db_size; i++) { + incl_result->handle = db[offset + i].handle; + incl_result->incl_svc_s_handle = db[offset + i].start_handle; + incl_result->incl_svc_e_handle = db[offset + i].end_handle; + incl_result->uuid = db[offset + i].uuid; + incl_result++; + } + break; + } + default: + BLE_HS_LOG(DEBUG,"%s(), Not support type(%d)", __func__, type); + break; + } +} + +void ble_gattc_get_cached_service_by_uuid_db(uint16_t conn_id, + ble_uuid_t *svc_uuid, + ble_gattc_db_elem_t **db, + uint16_t *count) +{ + ble_gattc_get_service_with_uuid(conn_id, svc_uuid, db, count); +} + +void ble_gattc_get_cached_all_char_db(uint16_t conn_id, uint16_t start_handle, + uint16_t end_handle, ble_gattc_db_elem_t **db, + uint16_t *count) +{ + ble_gattc_get_db_with_operation(conn_id, BLE_GATT_OP_GET_ALL_CHAR, + 0, NULL, NULL, NULL, + start_handle, end_handle, db, count); + +} + +void ble_gattc_get_cached_all_descriptor_db(uint16_t conn_id, uint16_t char_handle, + ble_gattc_db_elem_t **db, uint16_t *count) +{ + ble_gattc_get_db_with_operation(conn_id, BLE_GATT_OP_GET_ALL_DESC, + char_handle, NULL, NULL, NULL, + 0, 0xFFFF, db, count); + +} + +void ble_gattc_get_cached_char_by_uuid_db(uint16_t conn_id, uint16_t start_handle, + uint16_t end_handle, ble_uuid_t *char_uuid, + ble_gattc_db_elem_t **db, uint16_t *count) +{ + ble_gattc_get_db_with_operation(conn_id, BLE_GATT_OP_GET_CHAR_BY_UUID, + 0, char_uuid, NULL, NULL, + start_handle, end_handle, db, count); + +} + +void ble_gatt_get_cached_descr_by_uuid_db(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, + ble_uuid_t *char_uuid, ble_uuid_t *descr_uuid, + ble_gattc_db_elem_t **db, uint16_t *count) +{ + ble_gattc_get_db_with_operation(conn_id, BLE_GATT_OP_GET_DESC_BY_UUID, + 0, char_uuid, descr_uuid, NULL, + start_handle, end_handle, db, count); +} + +void ble_gattc_get_cached_descr_by_char_handle_db(uint16_t conn_id, uint16_t char_handle, + ble_uuid_t *descr_uuid, + ble_gattc_db_elem_t **db, uint16_t *count) +{ + ble_gattc_get_db_with_operation(conn_id, BLE_GATT_OP_GET_DESC_BY_HANDLE, + char_handle, NULL, descr_uuid, NULL, + 0, 0xFFFF, db, count); +} + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +void ble_gattc_get_cached_include_service_db(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, + ble_uuid_t *incl_uuid, + ble_gattc_db_elem_t **db, uint16_t *count) +{ + ble_gattc_get_db_with_operation(conn_id, BLE_GATT_OP_GET_INCLUDE_SVC, + 0, NULL, NULL, incl_uuid, + start_handle, end_handle, db, count); +} +#endif + +void ble_gattc_get_db_size(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint16_t *count) +{ + ble_gattc_get_db_size_handle(conn_handle, start_handle, end_handle, count); +} + +void ble_gattc_get_db_size_by_type(uint16_t conn_handle, ble_gattc_db_attr_type type, + uint16_t start_handle, uint16_t end_handle, + uint16_t char_handle, uint16_t *count) +{ + ble_gattc_get_db_size_with_type_handle(conn_handle, type, start_handle, end_handle, char_handle, count); +} + +void ble_gattc_get_cached_gatt_db(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_gattc_db_elem_t **db, + uint16_t *count, uint16_t *db_num) +{ + ble_gattc_get_gatt_db(conn_handle, start_handle, end_handle, db,count, db_num); +} + +int ble_gattc_get_service(uint16_t conn_handle, + ble_uuid_t *svc_uuid, + ble_gattc_service_elem_t *result, + uint16_t *count, uint16_t offset) +{ + int rc; + ble_gattc_db_elem_t *db = NULL; + uint16_t svc_num = 0; + + ble_gattc_get_cached_service_by_uuid_db(conn_handle, svc_uuid, &db, &svc_num); + rc = ble_gattc_check_valid_param(svc_num, offset); + if (rc != 0) { + if (db) { + free(db); + } + *count = 0; + return rc; + } else { + ble_gattc_fill_gatt_db_conversion(count, svc_num, ESP_BLE_GATT_DB_PRIMARY_SERVICE, offset, (void *)result, db); + } + + *count = svc_num; + //free the db buffer after used. + if (db) { + free(db); + } + return 0; +} + +int ble_gattc_get_all_char(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_gattc_char_elem_t *result, + uint16_t *count, uint16_t offset) +{ + int rc; + ble_gattc_db_elem_t *db = NULL; + uint16_t char_num = 0; + + ble_gattc_get_cached_all_char_db(conn_handle, start_handle, end_handle, &db, &char_num); + rc = ble_gattc_check_valid_param(char_num, offset); + if (rc != 0) { + if (db) { + free(db); + } + *count = 0; + return rc; + } else { + ble_gattc_fill_gatt_db_conversion(count, char_num, ESP_BLE_GATT_DB_CHARACTERISTIC, offset, (void *)result, db); + } + + *count = char_num; + //free the db buffer after used. + if (db) { + free(db); + } + return 0; +} + +int ble_gattc_get_all_descr(uint16_t conn_handle, + uint16_t char_handle, + ble_gattc_descr_elem_t *result, + uint16_t *count, uint16_t offset) +{ + int rc; + ble_gattc_db_elem_t *db = NULL; + uint16_t descr_num = 0; + + ble_gattc_get_cached_all_descriptor_db(conn_handle, char_handle, &db, &descr_num); + rc = ble_gattc_check_valid_param(descr_num, offset); + if (rc != 0) { + if (db) { + free(db); + } + *count = 0; + return rc; + } else { + ble_gattc_fill_gatt_db_conversion(count, descr_num, ESP_BLE_GATT_DB_DESCRIPTOR, offset, (void *)result, db); + } + + *count = descr_num; + // free the db buffer after used. + if (db) { + free(db); + } + return 0; +} + +int ble_gattc_get_char_by_uuid(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_uuid_t *char_uuid, + ble_gattc_char_elem_t *result, uint16_t *count) +{ + int rc; + ble_gattc_db_elem_t *db = NULL; + uint16_t char_num = 0; + + ble_gattc_get_cached_char_by_uuid_db(conn_handle, start_handle, end_handle, char_uuid, &db, &char_num); + + rc = ble_gattc_check_valid_param(char_num, 0); + if (rc != 0) { + if (db) { + free(db); + } + *count = 0; + return rc; + } else { + ble_gattc_fill_gatt_db_conversion(count, char_num, ESP_BLE_GATT_DB_CHARACTERISTIC, 0, (void *)result, db); + } + + *count = char_num; + // free the db buffer after used. + if (db) { + free(db); + } + return 0; + +} + +int ble_gattc_get_descr_by_uuid(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_uuid_t *char_uuid, + ble_uuid_t *descr_uuid, + ble_gattc_descr_elem_t *result, uint16_t *count) +{ + int rc; + ble_gattc_db_elem_t *db = NULL; + uint16_t descr_num = 0; + + ble_gatt_get_cached_descr_by_uuid_db(conn_handle, start_handle, end_handle, char_uuid, descr_uuid, &db, &descr_num); + + rc = ble_gattc_check_valid_param(descr_num, 0); + if (rc != 0) { + if (db) { + free(db); + } + *count = 0; + return rc; + } else { + ble_gattc_fill_gatt_db_conversion(count, descr_num, ESP_BLE_GATT_DB_DESCRIPTOR, 0, (void *)result, db); + } + + *count = descr_num; + // free the db buffer after used. + if (db) { + free(db); + } + return 0; +} + +int ble_gattc_get_descr_by_char_handle(uint16_t conn_handle, + uint16_t char_handle, + ble_uuid_t *descr_uuid, + ble_gattc_descr_elem_t *result, uint16_t *count) +{ + int rc; + ble_gattc_db_elem_t *db = NULL; + uint16_t descr_num = 0; + + ble_gattc_get_cached_descr_by_char_handle_db(conn_handle, char_handle, descr_uuid, &db, &descr_num); + + rc = ble_gattc_check_valid_param(descr_num, 0); + if (rc != 0) { + if (db) { + free(db); + } + *count = 0; + return rc; + } else { + ble_gattc_fill_gatt_db_conversion(count, descr_num, ESP_BLE_GATT_DB_DESCRIPTOR, 0, (void *)result, db); + } + + *count = descr_num; + // free the db buffer after used. + if (db) { + free(db); + } + return 0; + +} + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +int ble_gattc_get_include_service(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_uuid_t *incl_uuid, + ble_gattc_included_svc_elem_t *result, uint16_t *count) +{ + int rc; + ble_gattc_db_elem_t *db = NULL; + uint16_t incl_num = 0; + + ble_gattc_get_cached_include_service_db(conn_handle, start_handle, end_handle, incl_uuid, &db, &incl_num); + + rc = ble_gattc_check_valid_param(incl_num,0); + if (rc != 0) { + if (db) { + free(db); + } + *count = 0; + return rc; + } else { + ble_gattc_fill_gatt_db_conversion(count, incl_num, ESP_BLE_GATT_DB_INCLUDED_SERVICE, 0, (void *)result, db); + } + + *count = incl_num; + //free the db buffer after used. + if (db) { + free(db); + } + return 0; + +} +#endif + +int ble_gattc_get_attr_count(uint16_t conn_handle, esp_ble_gatt_db_attr_type_t type, + uint16_t start_handle, uint16_t end_handle, + uint16_t char_handle, uint16_t *count) +{ + if (type == ESP_BLE_GATT_DB_ALL) { + ble_gattc_get_db_size(conn_handle, start_handle, end_handle, count); + } else { + ble_gattc_get_db_size_by_type(conn_handle, type, start_handle, end_handle, char_handle, count); + } + return 0; +} + +int ble_gattc_get_db(uint16_t conn_handle, + uint16_t start_handle, uint16_t end_handle, + ble_gattc_db_elem_t *result, uint16_t *count) +{ + uint16_t num = 0; + ble_gattc_db_elem_t *db = NULL; + + ble_gattc_get_cached_gatt_db(conn_handle, start_handle, end_handle, &db, &num, count); + + if (num == 0) { + return BLE_ATT_ERR_ATTR_NOT_FOUND; + } + if (db) { + memcpy(result, db, num * sizeof(ble_gattc_db_elem_t)); // Copy data + free(db); // Free allocated memory + } + + return 0; +} + +#endif + /***************************************************************************** * $read * *****************************************************************************/ @@ -2907,7 +3523,7 @@ ble_gattc_read_tx(struct ble_gattc_proc *proc) { int rc; - rc = ble_att_clt_tx_read(proc->conn_handle, proc->read.handle); + rc = ble_att_clt_tx_read(proc->conn_handle, proc->cid, proc->read.handle); if (rc != 0) { return rc; } @@ -2934,8 +3550,8 @@ ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle, goto done; } - proc->op = BLE_GATT_OP_READ; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ); + proc->read.handle = attr_handle; proc->read.cb = cb; proc->read.cb_arg = cb_arg; @@ -3070,7 +3686,7 @@ ble_gattc_read_uuid_rx_complete(struct ble_gattc_proc *proc, int status) static int ble_gattc_read_uuid_tx(struct ble_gattc_proc *proc) { - return ble_att_clt_tx_read_type(proc->conn_handle, + return ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->read_uuid.start_handle, proc->read_uuid.end_handle, &proc->read_uuid.chr_uuid.u); @@ -3096,8 +3712,8 @@ ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_READ_UUID; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_UUID); + ble_uuid_to_any(uuid, &proc->read_uuid.chr_uuid); proc->read_uuid.start_handle = start_handle; proc->read_uuid.end_handle = end_handle; @@ -3180,12 +3796,12 @@ ble_gattc_read_long_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); if (proc->read_long.offset == 0) { - rc = ble_att_clt_tx_read(proc->conn_handle, proc->read_long.handle); + rc = ble_att_clt_tx_read(proc->conn_handle, proc->cid, proc->read_long.handle); if (rc != 0) { return rc; } } else { - rc = ble_att_clt_tx_read_blob(proc->conn_handle, + rc = ble_att_clt_tx_read_blob(proc->conn_handle, proc->cid, proc->read_long.handle, proc->read_long.offset); if (rc != 0) { @@ -3256,7 +3872,7 @@ ble_gattc_read_long_rx_read_rsp(struct ble_gattc_proc *proc, int status, } /* Determine if this is the end of the attribute value. */ - mtu = ble_att_mtu(proc->conn_handle); + mtu = ble_att_mtu_by_cid(proc->conn_handle, proc->cid); if (mtu == 0) { /* No longer connected. */ return BLE_HS_EDONE; @@ -3297,8 +3913,8 @@ ble_gattc_read_long(uint16_t conn_handle, uint16_t handle, uint16_t offset, goto done; } - proc->op = BLE_GATT_OP_READ_LONG; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_LONG); + proc->read_long.handle = handle; proc->read_long.offset = offset; proc->read_long.cb = cb; @@ -3337,7 +3953,7 @@ ble_gattc_read_mult_cb_var(struct ble_gattc_proc *proc, int status, return 0; } - memset(attr, 0, sizeof(*attr)); + memset(attr, 0, sizeof(attr)); for (i = 0; i < proc->read_mult.num_handles; i++) { attr[i].handle = proc->read_mult.handles[i]; @@ -3455,6 +4071,15 @@ ble_gattc_read_mult_tmo(struct ble_gattc_proc *proc) ble_gattc_read_mult_cb(proc, BLE_HS_ETIMEOUT, 0, 0); } +static void +ble_gattc_read_mult_var_tmo(struct ble_gattc_proc *proc) +{ + BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task()); + ble_gattc_dbg_assert_proc_not_inserted(proc); + + ble_gattc_read_mult_cb_var(proc, BLE_HS_ETIMEOUT, 0, 0); +} + /** * Handles an incoming ATT error response for the specified * read-multiple-characteristics proc. @@ -3467,12 +4092,24 @@ ble_gattc_read_mult_err(struct ble_gattc_proc *proc, int status, ble_gattc_read_mult_cb(proc, status, att_handle, NULL); } +/** + * Handles an incoming ATT error response for the specified + * read-multiple-variable-lengthcharacteristics proc. + */ +static void +ble_gattc_read_mult_var_err(struct ble_gattc_proc *proc, int status, + uint16_t att_handle) +{ + ble_gattc_dbg_assert_proc_not_inserted(proc); + ble_gattc_read_mult_cb_var(proc, status, att_handle, NULL); +} + static int ble_gattc_read_mult_tx(struct ble_gattc_proc *proc) { int rc; - rc = ble_att_clt_tx_read_mult(proc->conn_handle, proc->read_mult.handles, + rc = ble_att_clt_tx_read_mult(proc->conn_handle, proc->cid, proc->read_mult.handles, proc->read_mult.num_handles, proc->read_mult.variable); if (rc != 0) { return rc; @@ -3510,12 +4147,9 @@ ble_gattc_read_mult_internal(uint16_t conn_handle, const uint16_t *handles, goto done; } - if (variable) { - proc->op = BLE_GATT_OP_READ_MULT_VAR; - } else { - proc->op = BLE_GATT_OP_READ_MULT; - } - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, + variable ? BLE_GATT_OP_READ_MULT_VAR : BLE_GATT_OP_READ_MULT); + memcpy(proc->read_mult.handles, handles, num_handles * sizeof *handles); proc->read_mult.num_handles = num_handles; proc->read_mult.variable = variable; @@ -3573,15 +4207,18 @@ ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, #endif int rc; + uint16_t cid; STATS_INC(ble_gattc_stats, write_no_rsp); ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 0); - rc = ble_att_clt_tx_write_cmd(conn_handle, attr_handle, txom); + cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY); + rc = ble_att_clt_tx_write_cmd(conn_handle, cid, attr_handle, txom); if (rc != 0) { STATS_INC(ble_gattc_stats, write); } + ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY); return rc; } @@ -3653,7 +4290,7 @@ ble_gattc_signed_write(uint16_t conn_handle, uint16_t attr_handle, /* Converting the csrk to little endian */ swap_buf(csrk, value_sec.csrk, 16); - rc = ble_att_clt_tx_signed_write_cmd(conn_handle, attr_handle, + rc = ble_att_clt_tx_signed_write_cmd(conn_handle, BLE_L2CAP_CID_ATT, attr_handle, csrk, value_sec.sign_counter, txom); if (rc != 0) { goto err; @@ -3749,15 +4386,15 @@ ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, goto done; } - proc->op = BLE_GATT_OP_WRITE; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_WRITE); + proc->write.att_handle = attr_handle; proc->write.cb = cb; proc->write.cb_arg = cb_arg; ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 1); - rc = ble_att_clt_tx_write_req(conn_handle, attr_handle, txom); + rc = ble_att_clt_tx_write_req(conn_handle, proc->cid, attr_handle, txom); txom = NULL; if (rc != 0) { goto done; @@ -3862,7 +4499,7 @@ ble_gattc_write_long_tx(struct ble_gattc_proc *proc) om = NULL; - max_sz = ble_att_mtu(proc->conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + max_sz = ble_att_mtu_by_cid(proc->conn_handle, proc->cid) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; if (max_sz <= 0) { /* Not connected. */ rc = BLE_HS_ENOTCONN; @@ -3874,7 +4511,7 @@ ble_gattc_write_long_tx(struct ble_gattc_proc *proc) proc->write_long.attr.offset); if (write_len <= 0) { - rc = ble_att_clt_tx_exec_write(proc->conn_handle, + rc = ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_EXECUTE); goto done; } @@ -3894,7 +4531,7 @@ ble_gattc_write_long_tx(struct ble_gattc_proc *proc) goto done; } - rc = ble_att_clt_tx_prep_write(proc->conn_handle, + rc = ble_att_clt_tx_prep_write(proc->conn_handle, proc->cid, proc->write_long.attr.handle, proc->write_long.attr.offset, om); om = NULL; @@ -3938,9 +4575,9 @@ ble_gattc_write_long_err(struct ble_gattc_proc *proc, int status, */ if (proc->write_long.attr.offset > 0 && proc->write_long.attr.offset < - OS_MBUF_PKTLEN(proc->write_long.attr.om)) { + OS_MBUF_PKTLEN(proc->write_long.attr.om)) { - ble_att_clt_tx_exec_write(proc->conn_handle, + ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_CANCEL); } @@ -4006,7 +4643,8 @@ ble_gattc_write_long_rx_prep(struct ble_gattc_proc *proc, rc = BLE_HS_EBADDATA; /* if data doesn't match up send cancel write */ - ble_att_clt_tx_exec_write(proc->conn_handle, BLE_ATT_EXEC_WRITE_F_CANCEL); + ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, + BLE_ATT_EXEC_WRITE_F_CANCEL); goto err; } else { /* Send follow-up request. */ @@ -4067,8 +4705,8 @@ ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle, goto done; } - proc->op = BLE_GATT_OP_WRITE_LONG; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_WRITE_LONG); + proc->write_long.attr.handle = attr_handle; proc->write_long.attr.offset = offset; proc->write_long.attr.om = txom; @@ -4078,6 +4716,11 @@ ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle, /* The mbuf is consumed by the procedure. */ txom = NULL; + if (proc->write_long.attr.offset > OS_MBUF_PKTLEN(proc->write_long.attr.om)) { + rc = BLE_ATT_ERR_INVALID_OFFSET; + goto done; + } + ble_gattc_log_write_long(proc); rc = ble_gattc_write_long_tx(proc); @@ -4168,14 +4811,14 @@ ble_gattc_write_reliable_tx(struct ble_gattc_proc *proc) attr_idx = proc->write_reliable.cur_attr; if (attr_idx >= proc->write_reliable.num_attrs) { - rc = ble_att_clt_tx_exec_write(proc->conn_handle, + rc = ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_EXECUTE); goto done; } attr = proc->write_reliable.attrs + attr_idx; - max_sz = ble_att_mtu(proc->conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + max_sz = ble_att_mtu_by_cid(proc->conn_handle, proc->cid) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; if (max_sz <= 0) { /* Not connected. */ rc = BLE_HS_ENOTCONN; @@ -4198,8 +4841,8 @@ ble_gattc_write_reliable_tx(struct ble_gattc_proc *proc) goto done; } - rc = ble_att_clt_tx_prep_write(proc->conn_handle, attr->handle, - attr->offset, om); + rc = ble_att_clt_tx_prep_write(proc->conn_handle, proc->cid, + attr->handle, attr->offset, om); om = NULL; if (rc != 0) { goto done; @@ -4242,7 +4885,7 @@ ble_gattc_write_reliable_err(struct ble_gattc_proc *proc, int status, */ if (proc->write_reliable.cur_attr < proc->write_reliable.num_attrs) { - ble_att_clt_tx_exec_write(proc->conn_handle, + ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_CANCEL); } } @@ -4355,8 +4998,8 @@ ble_gattc_write_reliable(uint16_t conn_handle, goto done; } - proc->op = BLE_GATT_OP_WRITE_RELIABLE; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_WRITE_RELIABLE); + proc->write_reliable.num_attrs = num_attrs; proc->write_reliable.cur_attr = 0; proc->write_reliable.cb = cb; @@ -4407,6 +5050,8 @@ static int ble_gatts_check_conn_aware(uint16_t conn_handle, bool *aware) { } #endif +#endif + int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom) @@ -4473,6 +5118,119 @@ done: return rc; } +#if MYNEWT_VAL(BLE_GATTC) +int +ble_gatts_notify_multiple_custom(uint16_t conn_handle, + size_t chr_count, + struct ble_gatt_notif *tuples) +{ +#if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + return BLE_HS_ENOTSUP; +#endif + + int rc = 0; + int i = 0; + uint16_t cur_chr_cnt = 0; + /* mtu = MTU - 1 octet (OP code) */ + uint16_t mtu = ble_att_mtu(conn_handle) - 1; + struct os_mbuf *txom; + struct ble_hs_conn *conn; + + txom = ble_hs_mbuf_att_pkt(); + if (txom == NULL) { + return BLE_HS_ENOMEM; + } + + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + return ENOTCONN; + } + + STATS_INC(ble_gattc_stats, multi_notify); + ble_gattc_log_multi_notify(tuples, chr_count); + + /* Read missing values */ + for (i = 0; i < chr_count; i++) { + if (tuples->handle == 0) { + rc = BLE_HS_EINVAL; + goto done; + } + if (tuples[i].value == NULL) { + /* No custom attribute data; read the value from the specified + * attribute + */ + rc = ble_att_svr_read_local(tuples[i].handle, &tuples[i].value); + if (rc != 0) { + BLE_HS_LOG(ERROR, "Attribute read failed (err=0x%02x)", rc); + goto done; + } + } + } + + /* If peer does not support fall back to multiple single value + * Notifications */ + if ((conn->bhc_gatt_svr.peer_cl_sup_feat[0] & 0x04) == 0) { + for (i = 0; i < chr_count; i++) { + rc = ble_att_clt_tx_notify(conn_handle, tuples[i].handle, tuples[i].value); + if (rc != 0) { + goto done; + } + } + goto done; + } + + for (i = 0; i < chr_count; i++) { + if (OS_MBUF_PKTLEN(txom) + OS_MBUF_PKTLEN(tuples[i].value) > mtu && cur_chr_cnt < 2) { + rc = ble_att_clt_tx_notify(conn_handle, tuples[i].handle, + tuples[i].value); + if (rc != 0) { + goto done; + } + continue; + } else if (OS_MBUF_PKTLEN(txom) + OS_MBUF_PKTLEN(tuples[i].value) > mtu) { + rc = ble_att_clt_tx_notify_mult(conn_handle, txom); + if (rc != 0) { + goto done; + } + cur_chr_cnt = 0; + /* buffer was consumed, allocate new one */ + txom = ble_hs_mbuf_att_pkt(); + if (txom == NULL) { + return BLE_HS_ENOMEM; + } + } + + /* Handle */ + os_mbuf_append(txom, &tuples[i].handle, sizeof(uint16_t)); + + /* Length */ + os_mbuf_append(txom, &OS_MBUF_PKTLEN(tuples[i].value), + sizeof(uint16_t)); + + /* Value */ + os_mbuf_concat(txom, tuples[i].value); + cur_chr_cnt++; + } + + if (cur_chr_cnt == 1) { + rc = ble_att_clt_tx_notify(conn_handle, tuples[chr_count].handle, + tuples[chr_count].value); + } else { + rc = ble_att_clt_tx_notify_mult(conn_handle, txom); + } + +done: + if (rc != 0) { + STATS_INC(ble_gattc_stats, multi_notify_fail); + } + + /* Tell the application that multiple notification transmissions were attempted. */ + for (i = 0; i < chr_count; i++) { + ble_gap_notify_tx_event(rc, conn_handle, tuples[i].handle, 0); + } + return rc; +} + /** * Deprecated. Should not be used. Use ble_gatts_notify_custom instead. */ @@ -4482,6 +5240,7 @@ ble_gattc_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, { return ble_gatts_notify_custom(conn_handle, chr_val_handle, txom); } +#endif int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) @@ -4497,6 +5256,7 @@ ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) return rc; } +#if MYNEWT_VAL(BLE_GATTC) /** * Deprecated. Should not be used. Use ble_gatts_notify instead. */ @@ -4506,10 +5266,12 @@ ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle) return ble_gatts_notify(conn_handle, chr_val_handle); } +#endif + /***************************************************************************** * $indicate * *****************************************************************************/ - +#if MYNEWT_VAL(BLE_GATTS) /** * Handles an incoming ATT error response for the specified indication proc. * A device should never send an error in response to an indication. If this @@ -4539,7 +5301,9 @@ ble_gatts_indicate_err(struct ble_gattc_proc *proc, int status, /* Send the next indication if one is pending. */ ble_gatts_send_next_indicate(proc->conn_handle); } +#endif +#if MYNEWT_VAL(BLE_GATTC) static void ble_gatts_indicate_tmo(struct ble_gattc_proc *proc) { @@ -4557,24 +5321,28 @@ ble_gatts_indicate_tmo(struct ble_gattc_proc *proc) static void ble_gatts_indicate_rx_rsp(struct ble_gattc_proc *proc) { - int rc; - ble_gattc_dbg_assert_proc_not_inserted(proc); +#if MYNEWT_VAL(BLE_GATTS) + int rc; rc = ble_gatts_rx_indicate_ack(proc->conn_handle, proc->indicate.chr_val_handle); if (rc != 0) { return; } +#endif /* Tell the application about the received acknowledgment. */ ble_gap_notify_tx_event(BLE_HS_EDONE, proc->conn_handle, proc->indicate.chr_val_handle, 1); - +#if MYNEWT_VAL(BLE_GATTS) /* Send the next indication if one is pending. */ ble_gatts_send_next_indicate(proc->conn_handle); +#endif } +#endif + /** * Causes the indication in progress for the specified connection (if any) to * fail with a status code of BLE_HS_ENOTCONN; @@ -4608,8 +5376,8 @@ ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, goto done; } - proc->op = BLE_GATT_OP_INDICATE; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_INDICATE); + proc->indicate.chr_val_handle = chr_val_handle; ble_gattc_log_indicate(chr_val_handle); @@ -4648,7 +5416,7 @@ ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, } } - rc = ble_att_clt_tx_indicate(conn_handle, chr_val_handle, txom); + rc = ble_att_clt_tx_indicate(conn_handle, proc->cid, chr_val_handle, txom); txom = NULL; if (rc != 0) { goto done; @@ -4675,6 +5443,7 @@ done: return rc; } +#if MYNEWT_VAL(BLE_GATTC) /** * Deprecated. Should not be used. Use ble_gatts_indicate_custom instead. */ @@ -4684,6 +5453,8 @@ ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, { return ble_gatts_indicate_custom(conn_handle, chr_val_handle, txom); } +#endif + int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle) @@ -4691,6 +5462,8 @@ ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle) return ble_gatts_indicate_custom(conn_handle, chr_val_handle, NULL); } + +#if MYNEWT_VAL(BLE_GATTC) /** * Deprecated. Should not be used. Use ble_gatts_indicate instead. */ @@ -4709,12 +5482,12 @@ ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle) * procedure. */ void -ble_gattc_rx_err(uint16_t conn_handle, uint16_t handle, uint16_t status) +ble_gattc_rx_err(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t status) { struct ble_gattc_proc *proc; ble_gattc_err_fn *err_cb; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, BLE_GATT_OP_NONE); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_NONE); if (proc != NULL) { err_cb = ble_gattc_err_dispatch_get(proc->op); if (err_cb != NULL) { @@ -4729,11 +5502,13 @@ ble_gattc_rx_err(uint16_t conn_handle, uint16_t handle, uint16_t status) * GATT procedure. */ void -ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu) +ble_gattc_rx_mtu(uint16_t conn_handle, uint16_t cid, int status, uint16_t chan_mtu) { struct ble_gattc_proc *proc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, BLE_GATT_OP_MTU); + assert(cid == BLE_L2CAP_CID_ATT); + + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, BLE_L2CAP_CID_ATT, BLE_GATT_OP_MTU); if (proc != NULL) { ble_gattc_mtu_cb(proc, status, 0, chan_mtu); ble_gattc_process_status(proc, BLE_HS_EDONE); @@ -4745,7 +5520,7 @@ ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu) * find-information-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_info_idata(uint16_t conn_handle, +ble_gattc_rx_find_info_idata(uint16_t conn_handle, uint16_t cid, struct ble_att_find_info_idata *idata) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO @@ -4755,7 +5530,7 @@ ble_gattc_rx_find_info_idata(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_DISC_ALL_DSCS); if (proc != NULL) { rc = ble_gattc_disc_all_dscs_rx_idata(proc, idata); @@ -4768,7 +5543,7 @@ ble_gattc_rx_find_info_idata(uint16_t conn_handle, * find-information-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status) +ble_gattc_rx_find_info_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO return; @@ -4777,8 +5552,8 @@ ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, - BLE_GATT_OP_DISC_ALL_DSCS); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, + BLE_GATT_OP_DISC_ALL_DSCS); if (proc != NULL) { rc = ble_gattc_disc_all_dscs_rx_complete(proc, status); ble_gattc_process_status(proc, rc); @@ -4790,7 +5565,7 @@ ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status) * find-by-type-value-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, +ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, uint16_t cid, struct ble_att_find_type_value_hinfo *hinfo) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE @@ -4800,7 +5575,7 @@ ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_DISC_SVC_UUID); if (proc != NULL) { rc = ble_gattc_disc_svc_uuid_rx_hinfo(proc, hinfo); @@ -4813,7 +5588,7 @@ ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, * find-by-type-value-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status) +ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE return; @@ -4822,8 +5597,8 @@ ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, - BLE_GATT_OP_DISC_SVC_UUID); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, + BLE_GATT_OP_DISC_SVC_UUID); if (proc != NULL) { rc = ble_gattc_disc_svc_uuid_rx_complete(proc, status); ble_gattc_process_status(proc, rc); @@ -4835,7 +5610,7 @@ ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status) * to the appropriate active GATT procedure. */ void -ble_gattc_rx_read_type_adata(uint16_t conn_handle, +ble_gattc_rx_read_type_adata(uint16_t conn_handle, uint16_t cid, struct ble_att_read_type_adata *adata) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE @@ -4846,7 +5621,7 @@ ble_gattc_rx_read_type_adata(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_read_type_elem_entries, &rx_entry); if (proc != NULL) { @@ -4860,7 +5635,7 @@ ble_gattc_rx_read_type_adata(uint16_t conn_handle, * the appropriate active GATT procedure. */ void -ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status) +ble_gattc_rx_read_type_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE return; @@ -4871,7 +5646,7 @@ ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status) int rc; proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY( - conn_handle, ble_gattc_rx_read_type_complete_entries, + conn_handle, cid, ble_gattc_rx_read_type_complete_entries, &rx_entry); if (proc != NULL) { rc = rx_entry->cb(proc, status); @@ -4884,7 +5659,7 @@ ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status) * read-by-group-type-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, +ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, uint16_t cid, struct ble_att_read_group_type_adata *adata) { #if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE @@ -4894,7 +5669,7 @@ ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_DISC_ALL_SVCS); if (proc != NULL) { rc = ble_gattc_disc_all_svcs_rx_adata(proc, adata); @@ -4907,7 +5682,7 @@ ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, * read-by-group-type-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int status) +ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE return; @@ -4916,8 +5691,8 @@ ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, - BLE_GATT_OP_DISC_ALL_SVCS); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, + BLE_GATT_OP_DISC_ALL_SVCS); if (proc != NULL) { rc = ble_gattc_disc_all_svcs_rx_complete(proc, status); ble_gattc_process_status(proc, rc); @@ -4929,7 +5704,7 @@ ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int status) * procedure. */ void -ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, struct os_mbuf **om) +ble_gattc_rx_read_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **om) { #if !NIMBLE_BLE_ATT_CLT_READ return; @@ -4939,7 +5714,7 @@ ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, struct os_mbuf **om) struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_read_rsp_entries, &rx_entry); if (proc != NULL) { @@ -4953,7 +5728,7 @@ ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, struct os_mbuf **om) * procedure. */ void -ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, +ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **om) { #if !NIMBLE_BLE_ATT_CLT_READ_BLOB @@ -4963,7 +5738,7 @@ ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_READ_LONG); if (proc != NULL) { rc = ble_gattc_read_long_rx_read_rsp(proc, status, om); @@ -4976,7 +5751,7 @@ ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, * GATT procedure. */ void -ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, +ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **om, bool variable) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT @@ -4988,7 +5763,7 @@ ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, op = variable ? BLE_GATT_OP_READ_MULT_VAR : BLE_GATT_OP_READ_MULT; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, op); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, op); if (proc != NULL) { ble_gattc_read_mult_cb(proc, status, 0, om); ble_gattc_process_status(proc, BLE_HS_EDONE); @@ -5000,7 +5775,7 @@ ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, * procedure. */ void -ble_gattc_rx_write_rsp(uint16_t conn_handle) +ble_gattc_rx_write_rsp(uint16_t conn_handle, uint16_t cid) { #if !NIMBLE_BLE_ATT_CLT_WRITE return; @@ -5008,7 +5783,7 @@ ble_gattc_rx_write_rsp(uint16_t conn_handle) struct ble_gattc_proc *proc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_WRITE); if (proc != NULL) { ble_gattc_write_cb(proc, 0, 0); @@ -5021,7 +5796,7 @@ ble_gattc_rx_write_rsp(uint16_t conn_handle) * GATT procedure. */ void -ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, +ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, uint16_t cid, int status, uint16_t handle, uint16_t offset, struct os_mbuf **om) { @@ -5033,7 +5808,7 @@ ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_prep_entries, &rx_entry); if (proc != NULL) { @@ -5047,7 +5822,7 @@ ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, * GATT procedure. */ void -ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status) +ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE return; @@ -5057,7 +5832,7 @@ ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_exec_entries, &rx_entry); if (proc != NULL) { rc = rx_entry->cb(proc, status); @@ -5065,12 +5840,13 @@ ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status) } } +#if MYNEWT_VAL(BLE_GATTC) /** * Dispatches an incoming ATT handle-value-confirmation to the appropriate * active GATT procedure. */ void -ble_gatts_rx_indicate_rsp(uint16_t conn_handle) +ble_gatts_rx_indicate_rsp(uint16_t conn_handle, uint16_t cid) { #if !NIMBLE_BLE_ATT_CLT_INDICATE return; @@ -5078,13 +5854,14 @@ ble_gatts_rx_indicate_rsp(uint16_t conn_handle) struct ble_gattc_proc *proc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_INDICATE); if (proc != NULL) { ble_gatts_indicate_rx_rsp(proc); ble_gattc_process_status(proc, BLE_HS_EDONE); } } +#endif /***************************************************************************** * $misc * @@ -5101,7 +5878,19 @@ ble_gatts_rx_indicate_rsp(uint16_t conn_handle) void ble_gattc_connection_broken(uint16_t conn_handle) { + struct ble_hs_conn *conn; + struct os_mbuf_pkthdr *omp; + ble_gattc_fail_procs(conn_handle, BLE_GATT_OP_NONE, BLE_HS_ENOTCONN); + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); + + while ((omp = STAILQ_FIRST(&conn->att_tx_q)) != NULL) { + STAILQ_REMOVE_HEAD(&conn->att_tx_q, omp_next); + os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(omp)); + } } /** @@ -5113,11 +5902,16 @@ ble_gattc_any_jobs(void) return !STAILQ_EMPTY(&ble_gattc_procs); } +#endif + int ble_gattc_init(void) { int rc; +#if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) + STAILQ_INIT(&temp_proc_list); +#endif STAILQ_INIT(&ble_gattc_procs); if (MYNEWT_VAL(BLE_GATT_MAX_PROCS) > 0) { diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache.c index 7f0bf310..497393c3 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache.c @@ -31,7 +31,7 @@ #define GATT_CACHE_PREFIX "gatt_" #define INVALID_ADDR_NUM 0xff #define MAX_DEVICE_IN_CACHE 50 -#define MAX_ADDR_LIST_CACHE_BUF 2048 +#define MAX_ADDR_LIST_CACHE_BUF 4096 #if MYNEWT_VAL(BLE_GATT_CACHING) static const char *cache_key = "gattc_cache_key"; @@ -305,7 +305,8 @@ static void check_uuid(ble_uuid_any_t *uuid) static void ble_gattc_fill_nv_attr_entry(ble_uuid_any_t uuid, uint16_t s_handle, uint16_t e_handle, ble_gatt_attr_type attr_type, bool is_primary, - struct ble_gatt_nv_attr *nv_attr, int index, uint8_t properties) + struct ble_gatt_nv_attr *nv_attr, int index, uint8_t properties, + uint16_t incl_svc_s_handle, uint16_t incl_svc_e_handle) { ble_uuid_copy(&nv_attr[index].uuid, &uuid.u); check_uuid(&nv_attr[index].uuid); @@ -314,6 +315,8 @@ ble_gattc_fill_nv_attr_entry(ble_uuid_any_t uuid, uint16_t s_handle, uint16_t e_ nv_attr[index].is_primary = is_primary; nv_attr[index].attr_type = attr_type; nv_attr[index].properties = properties; + nv_attr[index].incl_svc_s_handle = incl_svc_s_handle; + nv_attr[index].incl_svc_e_handle = incl_svc_e_handle; if (s_handle >= svc_end_handle) { svc_end_handle = s_handle; @@ -327,6 +330,9 @@ static void ble_gattc_fill_nv_attr(struct ble_gattc_cache_conn *peer, size_t num_attr, struct ble_gatt_nv_attr *nv_attr) { struct ble_gattc_cache_conn_svc *svc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *included_svc; +#endif struct ble_gattc_cache_conn_chr *chr; struct ble_gattc_cache_conn_dsc *dsc; @@ -336,18 +342,29 @@ ble_gattc_fill_nv_attr(struct ble_gattc_cache_conn *peer, size_t num_attr, struc SLIST_FOREACH(svc, &peer->svcs, next) { ble_gattc_fill_nv_attr_entry(svc->svc.uuid, svc->svc.start_handle, svc->svc.end_handle, BLE_GATT_ATTR_TYPE_SRVC, svc->type == BLE_GATT_SVC_TYPE_PRIMARY, - nv_attr, index, 0); + nv_attr, index, 0, 0, 0); svc_index = index; index++; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + if (!SLIST_EMPTY(&svc->incl_svc)) { + SLIST_FOREACH(included_svc, &svc->incl_svc, next) { + ble_gattc_fill_nv_attr_entry(included_svc->svc.uuid, included_svc->svc.handle, + 0, BLE_GATT_ATTR_TYPE_INCL_SRVC, false, + nv_attr, index, 0, included_svc->svc.start_handle, included_svc->svc.end_handle); + index++; + } + + } +#endif SLIST_FOREACH(chr, &svc->chrs, next) { ble_gattc_fill_nv_attr_entry(chr->chr.uuid, chr->chr.val_handle, chr->chr.def_handle, BLE_GATT_ATTR_TYPE_CHAR, false, - nv_attr, index, chr->chr.properties); + nv_attr, index, chr->chr.properties, 0, 0); index++; SLIST_FOREACH(dsc, &chr->dscs, next) { ble_gattc_fill_nv_attr_entry(dsc->dsc.uuid, dsc->dsc.handle, 0, BLE_GATT_ATTR_TYPE_CHAR_DESCR, false, nv_attr, index, - 0); + 0, 0, 0); index++; } } @@ -388,6 +405,7 @@ ble_gattc_cache_addr_save(uint8_t *out_index, ble_addr_t addr, uint8_t * hash_ke address list. */ if(num > MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) { + nimble_platform_mem_free(p_buf); return BLE_HS_ENOMEM; } BLE_HS_LOG(DEBUG, "BD addr not present"); @@ -396,6 +414,7 @@ ble_gattc_cache_addr_save(uint8_t *out_index, ble_addr_t addr, uint8_t * hash_ke } else { BLE_HS_LOG(DEBUG, "Hash key not present, saving new data"); if(num > MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) { + nimble_platform_mem_free(p_buf); return BLE_HS_ENOMEM; } insert_ind = num - 1; @@ -485,6 +504,7 @@ ble_gattc_cache_save(struct ble_gattc_cache_conn *peer, size_t num_attr) if(rc != 0) { /* cannot save address, return */ BLE_HS_LOG(ERROR, "Failed to save cache %d", rc); + nimble_platform_mem_free(nv_attr); return; } @@ -530,6 +550,7 @@ static int ble_gattc_add_svc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_attr) { struct ble_gatt_svc *gatt_svc; + int rc; gatt_svc = (struct ble_gatt_svc *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_svc)); if (gatt_svc == NULL) { @@ -540,29 +561,39 @@ ble_gattc_add_svc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_at gatt_svc->end_handle = nv_attr.e_handle; ble_uuid_copy(&gatt_svc->uuid, &nv_attr.uuid.u); - return ble_gattc_cache_conn_svc_add(peer_addr, gatt_svc); + rc = ble_gattc_cache_conn_svc_add(peer_addr, gatt_svc, nv_attr.is_primary); + nimble_platform_mem_free(gatt_svc); + return rc; } +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) static int ble_gattc_add_inc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_attr) { - struct ble_gatt_svc *gatt_svc; + int rc; + struct ble_gatt_incl_svc *gatt_incl_svc; - gatt_svc = (struct ble_gatt_svc *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_svc)); - if (gatt_svc == NULL) { + gatt_incl_svc = (struct ble_gatt_incl_svc *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_incl_svc)); + if (gatt_incl_svc == NULL) { return BLE_HS_ENOMEM; } - gatt_svc->start_handle = nv_attr.s_handle; - gatt_svc->end_handle = nv_attr.e_handle; - ble_uuid_copy(&gatt_svc->uuid, &nv_attr.uuid.u); - return ble_gattc_cache_conn_inc_add(peer_addr, gatt_svc); + gatt_incl_svc->handle = nv_attr.s_handle; + gatt_incl_svc->start_handle = nv_attr.incl_svc_s_handle; + gatt_incl_svc->end_handle = nv_attr.incl_svc_e_handle; + ble_uuid_copy(&gatt_incl_svc->uuid, &nv_attr.uuid.u); + + rc = ble_gattc_cache_conn_inc_add(peer_addr, gatt_incl_svc); + nimble_platform_mem_free(gatt_incl_svc); + return rc; } +#endif static int ble_gattc_add_chr_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_attr) { struct ble_gatt_chr *gatt_chr; + int rc; gatt_chr = (struct ble_gatt_chr *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_chr)); if (gatt_chr == NULL) { return BLE_HS_ENOMEM; @@ -573,13 +604,16 @@ ble_gattc_add_chr_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_at ble_uuid_copy(&gatt_chr->uuid, &nv_attr.uuid.u); gatt_chr->properties = nv_attr.properties; - return ble_gattc_cache_conn_chr_add(peer_addr, 0, gatt_chr); + rc = ble_gattc_cache_conn_chr_add(peer_addr, 0, gatt_chr); + nimble_platform_mem_free(gatt_chr); + return rc; } static int ble_gattc_add_dsc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_attr) { struct ble_gatt_dsc *gatt_dsc; + int rc; gatt_dsc = (struct ble_gatt_dsc *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_dsc)); if (gatt_dsc == NULL) { return BLE_HS_ENOMEM; @@ -588,7 +622,9 @@ ble_gattc_add_dsc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_at gatt_dsc->handle = nv_attr.s_handle; ble_uuid_copy(&gatt_dsc->uuid, &nv_attr.uuid.u); - return ble_gattc_cache_conn_dsc_add(peer_addr, 0, gatt_dsc); + rc = ble_gattc_cache_conn_dsc_add(peer_addr, 0, gatt_dsc); + nimble_platform_mem_free(gatt_dsc); + return rc; } int @@ -613,11 +649,7 @@ ble_gattc_cache_load(ble_addr_t peer_addr) for (int i = 0; i < num_attr; i++) { switch (nv_attr[i].attr_type) { case BLE_GATT_ATTR_TYPE_SRVC: - if (nv_attr[i].is_primary) { - rc = ble_gattc_add_svc_from_cache(peer_addr, nv_attr[i]); - } else { - rc = ble_gattc_add_inc_from_cache(peer_addr, nv_attr[i]); - } + rc = ble_gattc_add_svc_from_cache(peer_addr, nv_attr[i]); break; case BLE_GATT_ATTR_TYPE_CHAR: @@ -628,6 +660,11 @@ ble_gattc_cache_load(ble_addr_t peer_addr) rc = ble_gattc_add_dsc_from_cache(peer_addr, nv_attr[i]); break; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + case BLE_GATT_ATTR_TYPE_INCL_SRVC: + rc = ble_gattc_add_inc_from_cache(peer_addr, nv_attr[i]); + break; +#endif default: break; } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c index 8ec8fdaa..d46ab111 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c @@ -35,6 +35,9 @@ #define CHECK_CACHE_CONN_STATE(cache_state, cb, cb_arg, opcode, \ s_handle, e_handle, p_uuid) \ + if (ble_hs_cfg.gatt_use_cache == 0) { \ + return BLE_HS_ENOTSUP; \ + } \ op = &conn->pending_op; \ switch(cache_state) { \ case SVC_DISC_IN_PROGRESS: \ @@ -86,6 +89,11 @@ static void *ble_gattc_cache_conn_svc_mem; static struct os_mempool ble_gattc_cache_conn_svc_pool; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +static void *ble_gattc_cache_conn_incl_svc_mem; +static struct os_mempool ble_gattc_cache_conn_incl_svc_pool; +#endif + static void *ble_gattc_cache_conn_chr_mem; static struct os_mempool ble_gattc_cache_conn_chr_pool; @@ -337,6 +345,13 @@ ble_gattc_cache_conn_chr_find(const struct ble_gattc_cache_conn_svc *svc, uint16 return chr; } +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +static void +ble_gattc_cache_conn_incl_svc_delete(struct ble_gattc_cache_conn_incl_svc *incl_svc) +{ + os_memblock_put(&ble_gattc_cache_conn_incl_svc_pool, incl_svc); +} +#endif static void ble_gattc_cache_conn_chr_delete(struct ble_gattc_cache_conn_chr *chr) { @@ -546,13 +561,68 @@ ble_gattc_cache_conn_dsc_find_uuid(const struct ble_gattc_cache_conn *ble_gattc_ return NULL; } +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +static struct ble_gattc_cache_conn_incl_svc * +ble_gattc_cache_conn_incl_svc_find_prev(const struct ble_gattc_cache_conn_svc *svc, uint16_t incl_svc_handle) +{ + struct ble_gattc_cache_conn_incl_svc *prev; + struct ble_gattc_cache_conn_incl_svc *incl_svc; + + prev = NULL; + SLIST_FOREACH(incl_svc, &svc->incl_svc, next) { + if (incl_svc->svc.handle >= incl_svc_handle) { + break; + } + + prev = incl_svc; + } + + return prev; +} + +static struct ble_gattc_cache_conn_incl_svc * +ble_gattc_cache_conn_incl_svc_find(const struct ble_gattc_cache_conn_svc *svc, uint16_t incl_svc_handle, + struct ble_gattc_cache_conn_incl_svc **out_prev) +{ + struct ble_gattc_cache_conn_incl_svc *prev; + struct ble_gattc_cache_conn_incl_svc *incl_svc; + + prev = ble_gattc_cache_conn_incl_svc_find_prev(svc, incl_svc_handle); + if (prev == NULL) { + incl_svc = SLIST_FIRST(&svc->incl_svc); + } else { + incl_svc = SLIST_NEXT(prev, next); + } + + if (incl_svc != NULL && incl_svc->svc.handle != incl_svc_handle) { + incl_svc = NULL; + } + + if (out_prev != NULL) { + *out_prev = prev; + } + return incl_svc; +} +#endif + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +int +ble_gattc_cache_conn_inc_add(ble_addr_t peer_addr, const struct ble_gatt_incl_svc *gatt_svc) +#else int ble_gattc_cache_conn_inc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *gatt_svc) +#endif { - struct ble_gattc_cache_conn_svc *prev; struct ble_gattc_cache_conn_svc *svc; + struct ble_gattc_cache_conn_svc *prev; struct ble_gattc_cache_conn *peer; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *incl_svc; + struct ble_gattc_cache_conn_incl_svc *incl_svc_prev; + struct ble_gattc_cache_conn_svc *cur_svc; +#endif + peer = ble_gattc_cache_conn_find_by_addr(peer_addr); if (peer == NULL) { BLE_HS_LOG(ERROR, "Peer not found"); @@ -560,36 +630,79 @@ ble_gattc_cache_conn_inc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *ga } svc = ble_gattc_cache_conn_svc_find(peer, gatt_svc->start_handle, &prev); - if (svc != NULL) { - /* Inc already discovered. */ + + if (!svc) { + /* Secondary Service */ + svc = os_memblock_get(&ble_gattc_cache_conn_svc_pool); + if (svc == NULL) { + /* Out of memory. */ + return BLE_HS_ENOMEM; + } + + memset(svc, 0, sizeof * svc); + + svc->type = BLE_GATT_SVC_TYPE_SECONDARY; + svc->svc.start_handle = gatt_svc->start_handle; + svc->svc.end_handle = gatt_svc->end_handle; + memcpy(&svc->svc.uuid, &gatt_svc->uuid, sizeof(ble_uuid_any_t)); + + SLIST_INIT(&svc->chrs); +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + SLIST_INIT(&svc->incl_svc); +#endif + if (prev == NULL) { + SLIST_INSERT_HEAD(&peer->svcs, svc, next); + } else { + SLIST_INSERT_AFTER(prev, svc, next); + } + + BLE_HS_LOG(DEBUG, "Secondary Svc added with start_handle = %d , end_handle = %d", + gatt_svc->start_handle, gatt_svc->end_handle); + } + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + /* Including the services into including list of current service*/ + cur_svc = ble_gattc_cache_conn_svc_find_range(peer, gatt_svc->handle); + + if (cur_svc == NULL) { + /* Can't find service for discovered included service; this shouldn't + * happen. + */ + BLE_HS_LOG(WARN, "Current Service is NULL.\n"); + assert(0); + return BLE_HS_EUNKNOWN; + } + + incl_svc = ble_gattc_cache_conn_incl_svc_find(cur_svc, gatt_svc->handle, &incl_svc_prev); + if (incl_svc != NULL) { + /* Already discovered */ return 0; } - svc = os_memblock_get(&ble_gattc_cache_conn_svc_pool); - if (svc == NULL) { - /* Out of memory. */ + incl_svc = os_memblock_get(&ble_gattc_cache_conn_incl_svc_pool); + if (incl_svc == NULL) { return BLE_HS_ENOMEM; } - memset(svc, 0, sizeof * svc); - svc->type = BLE_GATT_SVC_TYPE_SECONDARY; - svc->svc = *gatt_svc; - SLIST_INIT(&svc->chrs); + incl_svc->svc.handle = gatt_svc->handle; + incl_svc->svc.start_handle = gatt_svc->start_handle; + incl_svc->svc.end_handle = gatt_svc->end_handle; + memcpy(&incl_svc->svc.uuid, &gatt_svc->uuid, sizeof(ble_uuid_any_t)); - if (prev == NULL) { - SLIST_INSERT_HEAD(&peer->svcs, svc, next); + if (incl_svc_prev == NULL) { + SLIST_INSERT_HEAD(&cur_svc->incl_svc, incl_svc, next); } else { - SLIST_INSERT_AFTER(prev, svc, next); + SLIST_INSERT_AFTER(incl_svc_prev, incl_svc, next); } - BLE_HS_LOG(DEBUG, "Inc added with start_handle = %d and end_handle = %d", - gatt_svc->start_handle, gatt_svc->end_handle); - + BLE_HS_LOG(DEBUG, "Inc added with handle = %d", + gatt_svc->handle); +#endif return 0; } int -ble_gattc_cache_conn_svc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *gatt_svc) +ble_gattc_cache_conn_svc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *gatt_svc, bool is_primary) { struct ble_gattc_cache_conn_svc *prev; struct ble_gattc_cache_conn_svc *svc; @@ -614,8 +727,16 @@ ble_gattc_cache_conn_svc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *ga } memset(svc, 0, sizeof * svc); - svc->type = BLE_GATT_SVC_TYPE_PRIMARY; + if (is_primary) { + svc->type = BLE_GATT_SVC_TYPE_PRIMARY; + } else { + svc->type = BLE_GATT_SVC_TYPE_SECONDARY; + } + svc->svc = *gatt_svc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + SLIST_INIT(&svc->incl_svc); +#endif SLIST_INIT(&svc->chrs); if (prev == NULL) { @@ -635,6 +756,14 @@ ble_gattc_cache_conn_svc_delete(struct ble_gattc_cache_conn_svc *svc) { struct ble_gattc_cache_conn_chr *chr; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *incl_svc; + // Free included services + while ((incl_svc = SLIST_FIRST(&svc->incl_svc)) != NULL) { + SLIST_REMOVE_HEAD(&svc->incl_svc, next); + ble_gattc_cache_conn_incl_svc_delete(incl_svc); + } +#endif while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) { SLIST_REMOVE_HEAD(&svc->chrs, next); ble_gattc_cache_conn_chr_delete(chr); @@ -652,14 +781,83 @@ ble_gattc_cache_conn_get_db_size(struct ble_gattc_cache_conn *peer) size_t db_size = 0; struct ble_gattc_cache_conn_svc *svc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *included_svc; +#endif + struct ble_gattc_cache_conn_chr *chr; + struct ble_gattc_cache_conn_dsc *dsc; + + SLIST_FOREACH(svc, &peer->svcs, next) { + db_size++; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + SLIST_FOREACH(included_svc, &svc->incl_svc, next) { + db_size++; + } +#endif + SLIST_FOREACH(chr, &svc->chrs, next) { + db_size++; + SLIST_FOREACH(dsc, &chr->dscs, next) { + db_size++; + } + } + } + + return db_size; +} + +size_t +ble_gattc_get_db_size_with_handle(struct ble_gattc_cache_conn *peer, uint16_t start_handle, uint16_t end_handle) +{ + if (peer == NULL || SLIST_EMPTY(&peer->svcs)) { + return 0; + } + + struct ble_gattc_cache_conn_svc *svc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *included_svc; +#endif struct ble_gattc_cache_conn_chr *chr; struct ble_gattc_cache_conn_dsc *dsc; + size_t db_size = 0; SLIST_FOREACH(svc, &peer->svcs, next) { + if (svc->svc.end_handle < start_handle) { + continue; + } + if (svc->svc.start_handle > end_handle) { + break; + } + db_size++; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + SLIST_FOREACH(included_svc, &svc->incl_svc, next) { + if (included_svc->svc.handle < start_handle) { + continue; + } + if (included_svc->svc.handle > end_handle) { + return db_size; + } + + db_size++; + } +#endif SLIST_FOREACH(chr, &svc->chrs, next) { + if (chr->chr.val_handle < start_handle) { + continue; + } + if (chr->chr.val_handle > end_handle) { + return db_size; + } db_size++; + SLIST_FOREACH(dsc, &chr->dscs, next) { + if (dsc->dsc.handle < start_handle) { + continue; + } + + if (dsc->dsc.handle > end_handle) { + return db_size; + } db_size++; } } @@ -668,6 +866,492 @@ ble_gattc_cache_conn_get_db_size(struct ble_gattc_cache_conn *peer) return db_size; } +size_t +ble_gattc_get_db_size_with_type(struct ble_gattc_cache_conn *peer, uint8_t type, + uint16_t start_handle, uint16_t end_handle, uint16_t char_handle) +{ + if (peer == NULL || SLIST_EMPTY(&peer->svcs)) { + return 0; + } + struct ble_gattc_cache_conn_svc *svc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *included_svc; +#endif + struct ble_gattc_cache_conn_chr *chr; + struct ble_gattc_cache_conn_dsc *dsc; + size_t db_size = 0; + // Iterate through the services in the cache connection. + SLIST_FOREACH(svc, &peer->svcs, next) { + // Skip services that are out of the requested handle range. + if (svc->svc.end_handle < start_handle || svc->svc.start_handle > end_handle) { + continue; + } + + // Handle the different types of GATT database entries. + switch (type) { + case BLE_GATT_DB_PRIMARY_SERVICE: + if (svc->type == BLE_GATT_SVC_TYPE_PRIMARY && + svc->svc.start_handle >= start_handle && + svc->svc.end_handle <= end_handle) { + db_size++; + } + break; + + case BLE_GATT_DB_SECONDARY_SERVICE: + if (svc->type == BLE_GATT_SVC_TYPE_SECONDARY && + svc->svc.start_handle >= start_handle && + svc->svc.end_handle <= end_handle) { + db_size++; + } + break; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + case BLE_GATT_DB_INCLUDED_SERVICE: + // Iterate through included service. + SLIST_FOREACH(included_svc, &svc->incl_svc, next) { + if (included_svc->svc.handle >= start_handle && included_svc->svc.handle <= end_handle) { + db_size++; + } + } + break; +#endif + case BLE_GATT_DB_CHARACTERISTIC: + // Iterate through characteristics. + SLIST_FOREACH(chr, &svc->chrs, next) { + if (chr->chr.val_handle >= start_handle && chr->chr.val_handle <= end_handle) { + db_size++; + } + } + break; + + case BLE_GATT_DB_DESCRIPTOR: + // Iterate through characteristics and their descriptors. + SLIST_FOREACH(chr, &svc->chrs, next) { + if (chr->chr.val_handle >= start_handle && chr->chr.val_handle <= end_handle) { + if (chr->chr.val_handle == char_handle) { + SLIST_FOREACH(dsc, &chr->dscs, next) { + if (dsc->dsc.handle >= start_handle && + dsc->dsc.handle <= end_handle && + chr->chr.val_handle == char_handle) { + db_size++; + } + } + } + } + } + break; + } + } + + return db_size; +} + +// fill a element into database +void ble_gattc_fill_gatt_db_el(ble_gattc_db_elem_t *attr, + ble_gattc_db_attr_type type, + uint16_t handle, + uint16_t s_handle, + uint16_t e_handle, + uint8_t prop, + ble_uuid_any_t uuid) +{ + attr->type = type; + attr->handle = handle; + attr->start_handle = s_handle; + attr->end_handle = e_handle; + attr->properties = prop; + attr->uuid = uuid; +} + +void ble_gattc_get_service_with_uuid(uint16_t conn_handle, + ble_uuid_t *svc_uuid, + ble_gattc_db_elem_t **svc_db, + uint16_t *count) +{ + + struct ble_gattc_cache_conn *cache_conn; + struct ble_gattc_cache_conn_svc *svc; + + // Find the connection in the cache + cache_conn = ble_gattc_cache_conn_find(conn_handle); + if (cache_conn == NULL || SLIST_EMPTY(&cache_conn->svcs)) { + BLE_HS_LOG(WARN, "%s(), no service.", __func__); + *count = 0; + *svc_db = NULL; + return; + } + + size_t db_size = 0; + SLIST_FOREACH(svc, &cache_conn->svcs, next) { + if (svc_uuid == NULL || ble_uuid_cmp(&svc->svc.uuid.u, svc_uuid) == 0) { + db_size++; + } + } + + if (!db_size) { + BLE_HS_LOG(DEBUG, "the db size is 0."); + *count = 0; + *svc_db = NULL; + return; + } + + // Allocate memory for the GATT database + void *buffer = malloc(db_size * sizeof(ble_gattc_db_elem_t)); + if (!buffer) { + BLE_HS_LOG(WARN, "%s(), no resource.", __func__); + *count = 0; + *svc_db = NULL; + return; + } + ble_gattc_db_elem_t *curr_db_attr = buffer; + db_size = 0; + + // Iterate through services in the cache + SLIST_FOREACH(svc, &cache_conn->svcs, next) { + if (svc_uuid == NULL || ble_uuid_cmp(&svc->svc.uuid.u, svc_uuid) == 0) { + ble_gattc_fill_gatt_db_el(curr_db_attr, + svc->type == BLE_GATT_SVC_TYPE_PRIMARY ? /* attr type */ + BLE_GATT_DB_PRIMARY_SERVICE:BLE_GATT_DB_SECONDARY_SERVICE, + 0, /* handle */ + svc->svc.start_handle, /* s_handle */ + svc->svc.end_handle, /* e_handle */ + 0, /* property */ + svc->svc.uuid); /* uuid */ + curr_db_attr++; + db_size++; + } + } + + *svc_db = buffer; + *count = db_size; +} + +void ble_gattc_get_db_with_operation(uint16_t conn_handle, + ble_gatt_get_db_op_t op, + uint16_t char_handle, + ble_uuid_t *char_uuid, + ble_uuid_t *descr_uuid, + ble_uuid_t *incl_uuid, + uint16_t start_handle, uint16_t end_handle, + ble_gattc_db_elem_t **char_db, + uint16_t *count) +{ + + struct ble_gattc_cache_conn *cache_conn; + struct ble_gattc_cache_conn_svc *svc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *included_svc; +#endif + struct ble_gattc_cache_conn_chr *chr; + struct ble_gattc_cache_conn_dsc *dsc; + + // Find the connection in the cache + cache_conn = ble_gattc_cache_conn_find(conn_handle); + if (cache_conn == NULL || SLIST_EMPTY(&cache_conn->svcs)) { + BLE_HS_LOG(WARN, "the service cache is empty."); + *count = 0; + *char_db = NULL; + return; + } + size_t db_size = ble_gattc_get_db_size_with_handle(cache_conn, start_handle, end_handle); + + if (!db_size) { + BLE_HS_LOG(DEBUG, "the db size is 0."); + *count = 0; + *char_db = NULL; + return; + } + + // Allocate memory for the GATT database + void *buffer = malloc(db_size * sizeof(ble_gattc_db_elem_t)); + if (!buffer) { + BLE_HS_LOG(WARN, "%s(), no resource.", __func__); + *count = 0; + *char_db = NULL; + return; + } + ble_gattc_db_elem_t *curr_db_attr = buffer; + db_size = 0; + + // Iterate through services in the cache + SLIST_FOREACH(svc, &cache_conn->svcs, next) { + if (svc->svc.end_handle < start_handle || svc->svc.start_handle > end_handle) { + continue; + } + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + // Check for included services + if (op == BLE_GATT_OP_GET_INCLUDE_SVC) { + if (SLIST_EMPTY(&svc->incl_svc)) { + continue; + } + SLIST_FOREACH(included_svc, &svc->incl_svc, next) { + if (included_svc->svc.handle < start_handle || included_svc->svc.handle > end_handle) { + continue; + } + + if (incl_uuid == NULL || ble_uuid_cmp(&included_svc->svc.uuid.u, incl_uuid) == 0) { + ble_gattc_fill_gatt_db_el(curr_db_attr, + BLE_GATT_DB_INCLUDED_SERVICE, /* attr type*/ + included_svc->svc.handle, /* handle */ + included_svc->svc.start_handle, /* s_handle */ + included_svc->svc.end_handle, /* e_handle */ + 0, /* property */ + included_svc->svc.uuid); /* uuid */ + curr_db_attr++; + db_size++; + } + } + continue; + } +#endif + // Check for characteristics + SLIST_FOREACH(chr, &svc->chrs, next) { + if (chr->chr.val_handle < start_handle || chr->chr.val_handle > end_handle) { + continue; + } + if ((op == BLE_GATT_OP_GET_ALL_CHAR || op == BLE_GATT_OP_GET_CHAR_BY_UUID) && + (char_uuid == NULL || ble_uuid_cmp(&chr->chr.uuid.u, char_uuid) == 0)) { + ble_gattc_fill_gatt_db_el(curr_db_attr, + BLE_GATT_DB_CHARACTERISTIC, /* attr type*/ + chr->chr.val_handle, /* handle */ + 0, /* s_handle */ + 0, /* e_handle */ + chr->chr.properties, /* property */ + chr->chr.uuid); /* uuid */ + curr_db_attr++; + db_size++; + continue; + } + + if ((op == BLE_GATT_OP_GET_DESC_BY_HANDLE || op == BLE_GATT_OP_GET_ALL_DESC) && + (chr->chr.val_handle != char_handle)) { + continue; + } + + if ((op == BLE_GATT_OP_GET_DESC_BY_UUID && ble_uuid_cmp(&chr->chr.uuid.u, char_uuid) != 0)) { + continue; + } + + // Check for descriptors + if (!SLIST_EMPTY(&chr->dscs)) { + SLIST_FOREACH(dsc, &chr->dscs, next) { + if (dsc->dsc.handle < start_handle || dsc->dsc.handle > end_handle) { + continue; + } + if (((op == BLE_GATT_OP_GET_ALL_DESC || op == BLE_GATT_OP_GET_DESC_BY_UUID) && + (descr_uuid == NULL || ble_uuid_cmp(&dsc->dsc.uuid.u, descr_uuid) == 0)) || + (op == BLE_GATT_OP_GET_DESC_BY_HANDLE && ble_uuid_cmp(&dsc->dsc.uuid.u, descr_uuid) == 0)) { + ble_gattc_fill_gatt_db_el(curr_db_attr, + BLE_GATT_DB_DESCRIPTOR, /* attr type*/ + dsc->dsc.handle, /* handle */ + 0, /* s_handle */ + 0, /* e_handle */ + 0, /* property */ + dsc->dsc.uuid); /* uuid */ + curr_db_attr++; + db_size++; + } + } + } + + } + } + + *char_db = buffer; + *count = db_size; + return; +} + +void ble_gattc_get_db_size_with_type_handle(uint16_t conn_handle, + ble_gattc_db_attr_type type, + uint16_t start_handle, + uint16_t end_handle, + uint16_t char_handle, uint16_t *count) +{ + struct ble_gattc_cache_conn *cache_conn; + + cache_conn = ble_gattc_cache_conn_find(conn_handle); + if (cache_conn == NULL) { + *count = 0; + return ; + } + + *count = ble_gattc_get_db_size_with_type(cache_conn, type, start_handle, end_handle, char_handle); +} + +void ble_gattc_get_db_size_handle(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + uint16_t *count) +{ + struct ble_gattc_cache_conn *cache_conn; + + cache_conn = ble_gattc_cache_conn_find(conn_handle); + if (cache_conn == NULL) { + *count = 0; + return; + } + *count = ble_gattc_get_db_size_with_handle(cache_conn, start_handle, end_handle); +} + +// Copy the server GATT database into db parameter. + +static void ble_gattc_get_gatt_db_impl(struct ble_gattc_cache_conn *peer, + uint16_t start_handle, + uint16_t end_handle, + ble_gattc_db_elem_t **db, + uint16_t *count, uint16_t *db_num) +{ + if (!peer || SLIST_EMPTY(&peer->svcs)) { + *count = 0; + *db = NULL; + return; + } + + size_t db_size = ble_gattc_get_db_size_with_handle(peer, start_handle, end_handle); + if (!db_size) { + BLE_HS_LOG(DEBUG, "the db size is 0."); + *count = 0; + *db = NULL; + return; + } + db_size = (*db_num > db_size) ? db_size : (*db_num); + // Allocate memory for the GATT database + void *buffer = malloc(db_size * sizeof(ble_gattc_db_elem_t)); + if (!buffer) { + BLE_HS_LOG(WARN, "%s(), no resource.", __func__); + *count = 0; + *db = NULL; + return; + } + + ble_gattc_db_elem_t *curr_db_attr = buffer; + struct ble_gattc_cache_conn_svc *svc; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *included_svc; +#endif + struct ble_gattc_cache_conn_chr *chr; + struct ble_gattc_cache_conn_dsc *dsc; + + + SLIST_FOREACH(svc, &peer->svcs, next) { + if (svc->svc.end_handle < start_handle) { + continue; + } + + if (svc->svc.start_handle > end_handle) { + break; + } + ble_gattc_fill_gatt_db_el(curr_db_attr, + svc->type == BLE_GATT_SVC_TYPE_PRIMARY ? /* attr type */ + BLE_GATT_DB_PRIMARY_SERVICE: + BLE_GATT_DB_SECONDARY_SERVICE, + 0, /* attr handle */ + svc->svc.start_handle, /* start handle*/ + svc->svc.end_handle, /* end handle */ + 0, /* property */ + svc->svc.uuid); /* uuid */ + curr_db_attr++; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + // Iterate over included services + SLIST_FOREACH(included_svc, &svc->incl_svc, next) { + if (included_svc->svc.handle < start_handle) { + continue; + } + + if (included_svc->svc.handle > end_handle) { + *db = buffer; + *count = db_size; + return; + } + + ble_gattc_fill_gatt_db_el(curr_db_attr, + BLE_GATT_DB_INCLUDED_SERVICE, /* attr type */ + included_svc->svc.handle, /* attr handle */ + included_svc->svc.start_handle, /* s_handle */ + included_svc->svc.end_handle, /* e_handle */ + 0, /* property */ + included_svc->svc.uuid); /* uuid */ + curr_db_attr++; + } +#endif + // Iterate over characterstic + SLIST_FOREACH(chr, &svc->chrs, next) { + if (chr->chr.val_handle < start_handle) { + continue; + } + + if (chr->chr.val_handle > end_handle) { + *db = buffer; + *count = db_size; + return; + } + ble_gattc_fill_gatt_db_el(curr_db_attr, + BLE_GATT_DB_CHARACTERISTIC, /* attr type */ + chr->chr.val_handle, /* attr handle */ + 0, /* s_handle */ + 0, /* e_handle */ + chr->chr.properties, /* property */ + chr->chr.uuid); /* uuid */ + curr_db_attr++; + // Iterate over descriptors + SLIST_FOREACH(dsc, &chr->dscs, next) { + if (dsc->dsc.handle < start_handle) { + continue; + } + + if (dsc->dsc.handle > end_handle) { + *db = buffer; + *count = db_size; + return; + } + ble_gattc_fill_gatt_db_el(curr_db_attr, + BLE_GATT_DB_DESCRIPTOR, /* attr type */ + dsc->dsc.handle, /* attr handle */ + 0, /* s_handle */ + 0, /* e_handle */ + 0, /* property */ + dsc->dsc.uuid); /* uuid */ + curr_db_attr++; + } + } + } + + *db = buffer; + *count = db_size; + + return; +} + +// Copy the server GATT database into db parameter +void ble_gattc_get_gatt_db(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_gattc_db_elem_t **db, + uint16_t *count, uint16_t *db_num) +{ + struct ble_gattc_cache_conn *cache_conn; + + cache_conn = ble_gattc_cache_conn_find(conn_handle); + + if (cache_conn == NULL) { + BLE_HS_LOG(ERROR, "Unknown conn ID: %d", conn_handle); + return; + } + + if (cache_conn->cache_state != CACHE_VERIFIED){ + BLE_HS_LOG(ERROR, "server cache not available, server state = %d",cache_conn->cache_state); + return; + } + + if (SLIST_EMPTY(&cache_conn->svcs)) { + BLE_HS_LOG(ERROR, "the service cache is empty."); + return; + } + ble_gattc_get_gatt_db_impl(cache_conn, start_handle, end_handle, db, count, db_num); + +} + static void ble_gattc_cache_conn_cache_peer(struct ble_gattc_cache_conn *peer) { @@ -718,6 +1402,7 @@ ble_gattc_cache_conn_bonding_established(uint16_t conn_handle) BLE_HS_DBG_ASSERT(conn != NULL); ble_hs_conn_addrs(conn, &addrs); peer->ble_gattc_cache_conn_addr = conn->bhc_peer_addr; + peer->ble_gattc_cache_conn_addr.type = ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); @@ -811,6 +1496,7 @@ ble_gattc_cache_conn_disc_complete(struct ble_gattc_cache_conn *peer, int rc) BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16)); if (bonded || chr != NULL) { /* persist the cache */ + ble_gattc_cacheReset(&hs_conn->bhc_peer_addr); ble_gattc_cache_conn_cache_peer(peer); /* TODO */ } } else { @@ -827,7 +1513,7 @@ ble_gattc_cache_conn_disc_complete(struct ble_gattc_cache_conn *peer, int rc) } break; case BLE_GATT_OP_DISC_SVC_UUID : - rc = ble_gattc_cache_conn_search_svc_by_uuid(peer->conn_handle, &op->uuid, op->cb, op->cb_arg); + rc = ble_gattc_cache_conn_search_svc_by_uuid(peer->conn_handle, op->uuid, op->cb, op->cb_arg); if (rc != 0) { BLE_HS_LOG(ERROR, "search service by uuid failed"); } @@ -845,7 +1531,7 @@ ble_gattc_cache_conn_disc_complete(struct ble_gattc_cache_conn *peer, int rc) } break; case BLE_GATT_OP_DISC_CHR_UUID : - rc = ble_gattc_cache_conn_search_chrs_by_uuid(peer->conn_handle, op->start_handle, op->end_handle, &op->uuid, op->cb, op->cb_arg); + rc = ble_gattc_cache_conn_search_chrs_by_uuid(peer->conn_handle, op->start_handle, op->end_handle, op->uuid, op->cb, op->cb_arg); if (rc != 0) { BLE_HS_LOG(ERROR, "search chars by uuid failed"); } @@ -860,9 +1546,15 @@ ble_gattc_cache_conn_disc_complete(struct ble_gattc_cache_conn *peer, int rc) } } -static void -ble_gattc_cache_conn_undisc_all(struct ble_gattc_cache_conn *peer) +void +ble_gattc_cache_conn_undisc_all(ble_addr_t peer_addr) { + struct ble_gattc_cache_conn * peer = NULL; + + peer = ble_gattc_cache_conn_find_by_addr(peer_addr); + if (peer == NULL) { + return; + } ble_gattc_cacheReset(&peer->ble_gattc_cache_conn_addr); struct ble_gattc_cache_conn_svc *svc; @@ -873,9 +1565,15 @@ ble_gattc_cache_conn_undisc_all(struct ble_gattc_cache_conn *peer) } } +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +static int +ble_gattc_cache_conn_inc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, + const struct ble_gatt_incl_svc *service, void *arg) +#else static int ble_gattc_cache_conn_inc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service, void *arg) +#endif { struct ble_gattc_cache_conn *peer; int rc; @@ -890,7 +1588,7 @@ ble_gattc_cache_conn_inc_disced(uint16_t conn_handle, const struct ble_gatt_erro case BLE_HS_EDONE: /* All services discovered; start discovering incs. */ - ble_gattc_cache_conn_disc_chrs(peer); + ble_gattc_cache_conn_disc_incs(peer); rc = 0; break; @@ -918,7 +1616,7 @@ ble_gattc_cache_conn_svc_disced(uint16_t conn_handle, const struct ble_gatt_erro switch (error->status) { case 0: - rc = ble_gattc_cache_conn_svc_add(peer->ble_gattc_cache_conn_addr, service); + rc = ble_gattc_cache_conn_svc_add(peer->ble_gattc_cache_conn_addr, service, true); break; case BLE_HS_EDONE: @@ -946,7 +1644,7 @@ ble_gattc_cache_conn_disc(struct ble_gattc_cache_conn *peer) { int rc; - ble_gattc_cache_conn_undisc_all(peer); + ble_gattc_cache_conn_undisc_all(peer->ble_gattc_cache_conn_addr); peer->disc_prev_chr_val = 1; @@ -964,6 +1662,11 @@ ble_gattc_cache_conn_on_read(uint16_t conn_handle, { uint16_t res; + if (error->status == BLE_HS_EDONE) { + /* Ignore Read by UUID follow-up callback */ + return 0; + } + if (error->status != 0) { res = error->status; ble_gattc_cache_conn_disc_complete((struct ble_gattc_cache_conn *)arg, res); @@ -975,9 +1678,10 @@ ble_gattc_cache_conn_on_read(uint16_t conn_handle, BLE_HS_LOG(INFO, "Hash value up to date, skipping Discovery"); ble_gattc_cache_conn_disc_complete((struct ble_gattc_cache_conn *)arg, res); return 0; + } else { + res = ble_gattc_cache_conn_disc((struct ble_gattc_cache_conn *)arg); + return res; } - return 0; - } int @@ -1194,6 +1898,7 @@ ble_gattc_cache_conn_disc_incs(struct ble_gattc_cache_conn *peer) if (peer->cur_svc == NULL) { if (peer->disc_prev_chr_val > 0) { ble_gattc_cache_conn_disc_chrs(peer); + return; } } } @@ -1204,7 +1909,7 @@ ble_gattc_cache_conn_disc_incs(struct ble_gattc_cache_conn *peer) svc->svc.end_handle, ble_gattc_cache_conn_inc_disced, peer); if (rc != 0) { - ble_gattc_cache_conn_disc_complete(peer, rc); + ble_gattc_cache_conn_disc_chrs(peer); } return; } @@ -1226,6 +1931,10 @@ ble_gattc_cache_conn_update(uint16_t conn_handle, uint16_t start_handle, uint16_ } peer->cache_state = CACHE_INVALID; + if (MYNEWT_VAL(BLE_GATT_CACHING_DISABLE_AUTO)) { + /* Do not automatically re-discover and correct cache */ + return; + } rc = ble_gattc_cache_conn_disc(peer); if (rc != 0) { peer->cache_state = CACHE_INVALID; @@ -1249,7 +1958,7 @@ ble_gattc_cache_conn_get_svc_changed_handle(uint16_t conn_handle) BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16)); if (chr == NULL) { - BLE_HS_LOG(ERROR, "Cannot find service change characteristic"); + BLE_HS_LOG(DEBUG, "Cannot find service change characteristic"); return -1; } return chr->chr.val_handle; @@ -1264,6 +1973,10 @@ ble_gattc_cache_conn_free_mem(void) free(ble_gattc_cache_conn_svc_mem); ble_gattc_cache_conn_svc_mem = NULL; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + free(ble_gattc_cache_conn_incl_svc_mem); + ble_gattc_cache_conn_incl_svc_mem = NULL; +#endif free(ble_gattc_cache_conn_chr_mem); ble_gattc_cache_conn_chr_mem = NULL; @@ -1277,16 +1990,23 @@ ble_gattc_cache_conn_init() int rc; int max_ble_gattc_cache_conns; int max_svcs; +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + int max_incl_svcs; +#endif int max_chrs; int max_dscs; void *storage_cb; - max_ble_gattc_cache_conns = MYNEWT_VAL(BLE_MAX_CONNECTIONS); - max_svcs = (MYNEWT_VAL(BLE_MAX_CONNECTIONS)) * + max_ble_gattc_cache_conns = MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS); + max_svcs = (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) * (MYNEWT_VAL(BLE_GATT_CACHING_MAX_SVCS)); - max_chrs = (MYNEWT_VAL(BLE_MAX_CONNECTIONS)) * +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + max_incl_svcs = (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) * + (MYNEWT_VAL(BLE_GATT_CACHING_MAX_INCL_SVCS)); +#endif + max_chrs = (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) * (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CHRS)); - max_dscs = (MYNEWT_VAL(BLE_MAX_CONNECTIONS)) * + max_dscs = (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) * (MYNEWT_VAL(BLE_GATT_CACHING_MAX_DSCS)); /* Free memory first in case this function gets called more than once. */ ble_gattc_cache_conn_free_mem(); @@ -1321,6 +2041,22 @@ ble_gattc_cache_conn_init() goto err; } +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + ble_gattc_cache_conn_incl_svc_mem = malloc( + OS_MEMPOOL_BYTES(max_incl_svcs, sizeof(struct ble_gattc_cache_conn_incl_svc))); + if (ble_gattc_cache_conn_incl_svc_mem == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + rc = os_mempool_init(&ble_gattc_cache_conn_incl_svc_pool, max_incl_svcs, + sizeof(struct ble_gattc_cache_conn_incl_svc), ble_gattc_cache_conn_incl_svc_mem, + "ble_gattc_cache_conn_incl_svc_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto err; + } +#endif ble_gattc_cache_conn_chr_mem = malloc( OS_MEMPOOL_BYTES(max_chrs, sizeof(struct ble_gattc_cache_conn_chr))); if (ble_gattc_cache_conn_chr_mem == NULL) { @@ -1385,7 +2121,6 @@ ble_gattc_cache_error(int status, uint16_t att_handle) static int ble_gattc_cache_conn_verify(struct ble_gattc_cache_conn *conn) { struct ble_hs_conn *gap_conn; - const struct ble_gattc_cache_conn_chr *chr; int rc; if (conn->cache_state == CACHE_VERIFIED) { @@ -1404,16 +2139,10 @@ static int ble_gattc_cache_conn_verify(struct ble_gattc_cache_conn *conn) conn->cache_state = CACHE_VERIFIED; return 0; } - chr = ble_gattc_cache_conn_chr_find_uuid(conn, - BLE_UUID16_DECLARE(BLE_GATT_SVC_UUID16), - BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16)); - if (chr == NULL) { - /* no way to verify */ - conn->cache_state = CACHE_INVALID; - return 0; - } - rc = ble_gattc_read(conn->conn_handle, chr->chr.val_handle, - ble_gattc_cache_conn_on_read, conn); + + rc = ble_gattc_read_by_uuid(conn->conn_handle, 0x0001, 0xFFFF, + BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16), + ble_gattc_cache_conn_on_read, conn); if (rc != 0) { /* no way to verify */ conn->cache_state = CACHE_INVALID; @@ -1440,6 +2169,9 @@ static void ble_gattc_cache_search_all_svcs_cb(struct ble_npl_event *ev) if (conn == NULL) { return; } + + ble_npl_event_deinit(&conn->disc_ev); + op = &conn->pending_op; dcb = op->cb; SLIST_FOREACH(svc, &conn->svcs, next) { @@ -1449,13 +2181,14 @@ static void ble_gattc_cache_search_all_svcs_cb(struct ble_npl_event *ev) } status = BLE_HS_EDONE; dcb(conn->conn_handle, ble_gattc_cache_error(status, 0), &svc->svc, op->cb_arg); + return; } static void ble_gattc_cache_conn_fill_op(struct ble_gattc_cache_conn_op *op, uint16_t start_handle, uint16_t end_handle, - ble_uuid_t uuid, + const ble_uuid_t *uuid, void *cb, void *cb_arg, uint8_t cb_type) @@ -1490,7 +2223,7 @@ ble_gattc_cache_conn_search_all_svcs(uint16_t conn_handle, } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_SVCS, - 0, 0, uuid); + 0, 0, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_search_all_svcs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1513,15 +2246,19 @@ ble_gattc_cache_conn_search_svc_by_uuid_cb(struct ble_npl_event *ev) if (conn == NULL) { return; } + + ble_npl_event_deinit(&conn->disc_ev); + op = &conn->pending_op; dcb = op->cb; SLIST_FOREACH(svc, &conn->svcs, next) { - if (svc->type == BLE_GATT_SVC_TYPE_PRIMARY && ble_uuid_cmp(&svc->svc.uuid.u, &op->uuid) == 0) { + if (svc->type == BLE_GATT_SVC_TYPE_PRIMARY && ble_uuid_cmp(&svc->svc.uuid.u, op->uuid) == 0) { dcb(conn_handle, ble_gattc_cache_error(status, 0), &svc->svc, op->cb_arg); } } status = BLE_HS_EDONE; dcb(conn_handle, ble_gattc_cache_error(status, 0), &svc->svc, op->cb_arg); + return; } @@ -1547,7 +2284,7 @@ ble_gattc_cache_conn_search_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t * } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_SVC_UUID, - 0, 0, *uuid); + 0, 0, uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_svc_by_uuid_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1563,15 +2300,35 @@ ble_gattc_cache_conn_search_inc_svcs_cb(struct ble_npl_event *ev) struct ble_gattc_cache_conn_op *op; int status = 0; uint16_t conn_handle; + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_svc *incl_svc; + ble_gatt_disc_incl_svc_fn *dcb; +#else ble_gatt_disc_svc_fn *dcb; +#endif conn_handle = *(uint16_t*)ble_npl_event_get_arg(ev); conn = ble_gattc_cache_conn_find(conn_handle); if (conn == NULL) { return; } + + ble_npl_event_deinit(&conn->disc_ev); + op = &conn->pending_op; dcb = op->cb; + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + svc = ble_gattc_cache_conn_svc_find_range(conn, op->start_handle); + + SLIST_FOREACH(incl_svc, &svc->incl_svc, next) { + dcb(conn->conn_handle, ble_gattc_cache_error(status, 0), &incl_svc->svc, op->cb_arg); + + } + status = BLE_HS_EDONE; + dcb(conn->conn_handle, ble_gattc_cache_error(status, 0), &incl_svc->svc, op->cb_arg); +#else SLIST_FOREACH(svc, &conn->svcs, next) { if (svc->type == BLE_GATT_SVC_TYPE_SECONDARY && (svc->svc.start_handle >= op->start_handle && svc->svc.end_handle <= op->end_handle)) { @@ -1580,12 +2337,21 @@ ble_gattc_cache_conn_search_inc_svcs_cb(struct ble_npl_event *ev) } status = BLE_HS_EDONE; dcb(conn->conn_handle, ble_gattc_cache_error(status, 0), &svc->svc, op->cb_arg); +#endif return; } + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +int +ble_gattc_cache_conn_search_inc_svcs(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, + ble_gatt_disc_incl_svc_fn *cb, void *cb_arg) +#else int ble_gattc_cache_conn_search_inc_svcs(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, ble_gatt_disc_svc_fn *cb, void *cb_arg) +#endif { struct ble_gattc_cache_conn *conn; struct ble_gattc_cache_conn_op *op; @@ -1605,8 +2371,8 @@ ble_gattc_cache_conn_search_inc_svcs(uint16_t conn_handle, uint16_t start_handle return rc; } - CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_CHRS, - start_handle, end_handle, uuid); + CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_FIND_INC_SVCS, + start_handle, end_handle, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_inc_svcs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1629,6 +2395,9 @@ ble_gattc_cache_conn_search_all_chrs_cb(struct ble_npl_event *ev) if (conn == NULL) { return; } + + ble_npl_event_deinit(&conn->disc_ev); + op = &conn->pending_op; dcb = op->cb; svc = ble_gattc_cache_conn_svc_find_range(conn, op->start_handle); @@ -1638,6 +2407,7 @@ ble_gattc_cache_conn_search_all_chrs_cb(struct ble_npl_event *ev) } status = BLE_HS_EDONE; dcb(conn_handle, ble_gattc_cache_error(status, 0), &chr->chr, op->cb_arg); + return; } @@ -1665,7 +2435,7 @@ ble_gattc_cache_conn_search_all_chrs(uint16_t conn_handle, uint16_t start_handle } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_CHRS, - start_handle, end_handle, uuid); + start_handle, end_handle, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_all_chrs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1688,17 +2458,21 @@ ble_gattc_cache_conn_search_chrs_by_uuid_cb(struct ble_npl_event *ev) if (conn == NULL) { return; } + + ble_npl_event_deinit(&conn->disc_ev); + op = &conn->pending_op; dcb = op->cb; svc = ble_gattc_cache_conn_svc_find_range(conn, op->start_handle); /* return all chrs */ SLIST_FOREACH(chr, &svc->chrs, next) { - if (ble_uuid_cmp(&chr->chr.uuid.u, &op->uuid) == 0) { + if (ble_uuid_cmp(&chr->chr.uuid.u, op->uuid) == 0) { dcb(conn_handle, ble_gattc_cache_error(status, 0), &chr->chr, op->cb_arg); } } status = BLE_HS_EDONE; dcb(conn_handle, ble_gattc_cache_error(status, 0), &chr->chr, op->cb_arg); + return; } @@ -1725,7 +2499,7 @@ ble_gattc_cache_conn_search_chrs_by_uuid(uint16_t conn_handle, uint16_t start_ha } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_CHR_UUID, - start_handle, end_handle, *uuid); + start_handle, end_handle, uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_chrs_by_uuid_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1749,6 +2523,9 @@ ble_gattc_cache_conn_search_all_dscs_cb(struct ble_npl_event *ev) if (conn == NULL) { return; } + + ble_npl_event_deinit(&conn->disc_ev); + op = &conn->pending_op; dcb = op->cb; svc = ble_gattc_cache_conn_svc_find_range(conn, op->start_handle); @@ -1758,6 +2535,7 @@ ble_gattc_cache_conn_search_all_dscs_cb(struct ble_npl_event *ev) } status = BLE_HS_EDONE; dcb(conn_handle, ble_gattc_cache_error(status, 0), chr->chr.val_handle, &dsc->dsc, op->cb_arg); + return; } @@ -1785,7 +2563,7 @@ ble_gattc_cache_conn_search_all_dscs(uint16_t conn_handle, uint16_t start_handle } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_DSCS, - start_handle, end_handle, uuid); + start_handle, end_handle, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_all_dscs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_priv.h index 85b9c8fb..a9d3ef14 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gattc_cache_priv.h @@ -47,6 +47,8 @@ typedef struct ble_gatt_nv_attr { ble_uuid_any_t uuid; uint8_t properties; /* used for characteristic only */ unsigned int is_primary : 1; /* used for service only */ + uint16_t incl_svc_s_handle; + uint16_t incl_svc_e_handle; } ble_gatt_nv_attr; /* cache conn */ @@ -65,6 +67,15 @@ struct ble_gattc_cache_conn_chr { }; SLIST_HEAD(ble_gattc_cache_conn_chr_list, ble_gattc_cache_conn_chr); +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +struct ble_gattc_cache_conn_incl_svc { + SLIST_ENTRY(ble_gattc_cache_conn_incl_svc) next; + struct ble_gatt_incl_svc svc; +}; + +SLIST_HEAD(ble_gattc_cache_conn_incl_list, ble_gattc_cache_conn_incl_svc); +#endif + struct ble_gattc_cache_conn_svc { SLIST_ENTRY(ble_gattc_cache_conn_svc) next; /** @@ -74,7 +85,9 @@ struct ble_gattc_cache_conn_svc { */ uint8_t type; struct ble_gatt_svc svc; - +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + struct ble_gattc_cache_conn_incl_list incl_svc; +#endif struct ble_gattc_cache_conn_chr_list chrs; }; SLIST_HEAD(ble_gattc_cache_conn_svc_list, ble_gattc_cache_conn_svc); @@ -96,7 +109,7 @@ struct ble_gattc_cache_conn_op { request comes while the cache is building */ uint16_t start_handle; uint16_t end_handle; - ble_uuid_t uuid; + const ble_uuid_t *uuid; void *cb; void *cb_arg; uint8_t cb_type; @@ -122,6 +135,35 @@ struct ble_gattc_cache_conn { the application about the discovery results */ struct ble_npl_event disc_ev; }; + +/** Enumerates types of GATT database attributes */ +typedef enum { + BLE_GATT_DB_PRIMARY_SERVICE, /*!< Primary service attribute. */ + BLE_GATT_DB_SECONDARY_SERVICE, /*!< Secondary service attribute. */ + BLE_GATT_DB_INCLUDED_SERVICE, /*!< Included service attribute. */ + BLE_GATT_DB_CHARACTERISTIC, /*!< Characteristic attribute. */ + BLE_GATT_DB_DESCRIPTOR, /*!< Descriptor attribute. */ +} ble_gattc_db_attr_type; + +typedef enum { + BLE_GATT_OP_GET_SVC_BY_UUID, /*!< Get primary service from cache using service UUID. */ + BLE_GATT_OP_GET_ALL_CHAR, /*!< Get all characteristics for a given service from cache. */ + BLE_GATT_OP_GET_ALL_DESC, /*!< Get all descriptors for a given characteristic from cache. */ + BLE_GATT_OP_GET_CHAR_BY_UUID, /*!< Get characteristic from a service using characteristic UUID. */ + BLE_GATT_OP_GET_DESC_BY_UUID, /*!< Get descriptor from a characteristic using descriptor UUID. */ + BLE_GATT_OP_GET_DESC_BY_HANDLE, /*!< Get descriptor from cache using descriptor handle. */ + BLE_GATT_OP_GET_INCLUDE_SVC, /*!< Get included services from a given service in cache. */ +} ble_gatt_get_db_op_t; + +typedef struct { + ble_gatt_get_db_op_t type; /*!< Attribute type (e.g., characteristic, descriptor) */ + uint16_t handle; /*!< Attribute handle (unique identifier) */ + uint16_t start_handle; /*!< Service start handle */ + uint16_t end_handle; /*!< Service end handle */ + uint8_t properties; /*!< Characteristic properties (read, write, notify, etc.) */ + ble_uuid_any_t uuid; /*!< Attribute UUID */ +} ble_gattc_db_elem_t; + /* apis from gatt service */ uint16_t ble_svc_gatt_changed_handle(); uint16_t ble_svc_gatt_hash_handle(); @@ -132,12 +174,100 @@ uint8_t ble_svc_gatt_get_csfs(); void ble_svc_gatt_changed(uint16_t start_handle, uint16_t end_handle); #endif int ble_gattc_cache_conn_add(uint16_t conn_handle, ble_addr_t ble_gattc_cache_conn_addr); -int ble_gattc_cache_conn_svc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *gatt_svc); -int ble_gattc_cache_conn_inc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *gatt_svc); +int ble_gattc_cache_conn_svc_add(ble_addr_t peer_addr, const struct ble_gatt_svc *gatt_svc, bool is_primary); +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) +int ble_gattc_cache_conn_inc_add(ble_addr_t peer_addr, const struct ble_gatt_incl_svc *gatt_svc); +#else +int ble_gattc_cache_conn_inc_add(ble_addr_t peer_addr,const struct ble_gatt_svc *gatt_svc); +#endif int ble_gattc_cache_conn_chr_add(ble_addr_t peer_addr, uint16_t svc_start_handle, const struct ble_gatt_chr *gatt_chr); int ble_gattc_cache_conn_dsc_add(ble_addr_t peer_addr, uint16_t chr_val_handle, const struct ble_gatt_dsc *gatt_dsc); + + +/** + * These APIs fetch previously discovered GATT information (like services, + * characteristics, or descriptors) from the local cache without triggering + * a new discovery procedure. + */ + +void ble_gattc_get_cached_service_by_uuid_db(uint16_t conn_handle, + ble_uuid_t *svc_uuid, + ble_gattc_db_elem_t **db, + uint16_t *count); + +void ble_gattc_get_cached_all_char_db(uint16_t conn_id, uint16_t start_handle, + uint16_t end_handle, ble_gattc_db_elem_t **db, + uint16_t *count); + +void ble_gattc_get_cached_all_descriptor_db(uint16_t conn_id, uint16_t char_handle, + ble_gattc_db_elem_t **db, uint16_t *count); + +void ble_gattc_get_cached_char_by_uuid_db(uint16_t conn_id, uint16_t start_handle, + uint16_t end_handle, ble_uuid_t *char_uuid, + ble_gattc_db_elem_t **db, uint16_t *count); + +void ble_gatt_get_cached_descr_by_uuid_db(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, + ble_uuid_t *char_uuid, ble_uuid_t *descr_uuid, + ble_gattc_db_elem_t **db, uint16_t *count); + +void ble_gattc_get_cached_descr_by_char_handle_db(uint16_t conn_id, uint16_t char_handle, + ble_uuid_t *descr_uuid, + ble_gattc_db_elem_t **db, uint16_t *count); + +void ble_gattc_get_cached_gatt_db(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + ble_gattc_db_elem_t **db, + uint16_t *count, uint16_t *db_num); +void ble_gattc_get_db_size(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint16_t *count); + +void ble_gattc_get_db_size_by_type(uint16_t conn_handle, ble_gattc_db_attr_type type, + uint16_t start_handle, uint16_t end_handle, + uint16_t char_handle, uint16_t *count); + +void ble_gattc_fill_gatt_db_el(ble_gattc_db_elem_t *attr, + ble_gattc_db_attr_type type, + uint16_t handle, + uint16_t s_handle, + uint16_t e_handle, + uint8_t prop, + ble_uuid_any_t uuid); + +void ble_gattc_get_service_with_uuid(uint16_t conn_handle, + ble_uuid_t *svc_uuid, + ble_gattc_db_elem_t **svc_db, + uint16_t *count); + +void ble_gattc_get_db_with_operation(uint16_t conn_handle, + ble_gatt_get_db_op_t op, + uint16_t char_handle, + ble_uuid_t *char_uuid, + ble_uuid_t *descr_uuid, + ble_uuid_t *incl_uuid, + uint16_t start_handle, uint16_t end_handle, + ble_gattc_db_elem_t **char_db, + uint16_t *count); + +void ble_gattc_get_db_size_with_type_handle(uint16_t conn_handle, + ble_gattc_db_attr_type type, + uint16_t start_handle, + uint16_t end_handle, + uint16_t char_handle, + uint16_t *count); + +void ble_gattc_get_db_size_handle(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + uint16_t *count); + +void ble_gattc_get_gatt_db(uint16_t conn_id, + uint16_t start_handle, + uint16_t end_handle, + ble_gattc_db_elem_t **db, + uint16_t *count, uint16_t *db_num); /** * Loads the cache for the connection given by conn_handle */ @@ -162,9 +292,15 @@ int ble_gattc_cache_conn_search_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb, void *cb_arg); int ble_gattc_cache_conn_search_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid, ble_gatt_disc_svc_fn *cb, void *cb_arg); +#if (MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)) +int ble_gattc_cache_conn_search_inc_svcs(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, + ble_gatt_disc_incl_svc_fn *cb, void *cb_arg); +#else int ble_gattc_cache_conn_search_inc_svcs(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, ble_gatt_disc_svc_fn *cb, void *cb_arg); +#endif int ble_gattc_cache_conn_search_all_chrs(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, ble_gatt_chr_fn *cb, void *cb_arg); @@ -176,6 +312,8 @@ ble_gattc_cache_conn_search_all_dscs(uint16_t conn_handle, uint16_t start_handle uint16_t end_handle, ble_gatt_dsc_fn *cb, void *cb_arg); +struct ble_gattc_cache_conn * +ble_gattc_cache_conn_find(uint16_t conn_handle); #ifdef __cplusplus } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatts.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatts.c index bec30c4e..8c7efa39 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatts.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_gatts.c @@ -26,6 +26,10 @@ #include "host/ble_store.h" #include "ble_hs_priv.h" #include "esp_nimble_mem.h" + +#if MYNEWT_VAL(BLE_GATTS) +static uint8_t perm_flags = BLE_ATT_F_READ | BLE_ATT_F_WRITE ; + #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) #include "services/gatt/ble_svc_gatt.h" #endif @@ -175,6 +179,11 @@ ble_gatts_clt_cfg_free(struct ble_gatts_clt_cfg *cfg) } #endif +void ble_gatts_set_clt_cfg_perm_flags(uint8_t flags) +{ + perm_flags = flags ; +} + static int ble_gatts_svc_access(uint16_t conn_handle, uint16_t attr_handle, uint8_t op, uint16_t offset, struct os_mbuf **om, @@ -512,6 +521,7 @@ ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle, gatt_ctxt.op = ble_gatts_chr_op(att_op); gatt_ctxt.chr = chr_def; + gatt_ctxt.offset = offset; ble_gatts_chr_inc_val_stat(gatt_ctxt.op); rc = ble_gatts_val_access(conn_handle, attr_handle, offset, &gatt_ctxt, om, @@ -605,16 +615,20 @@ ble_gatts_calculate_hash(uint8_t *out_hash_key) rc = ble_att_fill_database_info(buf); if(rc != 0) { - return rc; + goto done; } rc = ble_sm_alg_aes_cmac(key, buf, size, out_hash_key); if(rc != 0) { - return rc; + goto done; } swap_in_place(out_hash_key, 16); - return 0; + + rc = 0; +done: + nimble_platform_mem_free(buf); + return rc; } #endif @@ -1000,8 +1014,7 @@ static int ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle) { int rc; - - rc = ble_att_svr_register(uuid_ccc, BLE_ATT_F_READ | BLE_ATT_F_WRITE, 0, + rc = ble_att_svr_register(uuid_ccc, perm_flags, 0, att_handle, ble_gatts_clt_cfg_access, NULL); if (rc != 0) { return rc; @@ -1508,7 +1521,13 @@ ble_gatts_connection_broken(uint16_t conn_handle) for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { - ble_gatts_conn_aware_states[i].aware = conn->bhc_gatt_svr.aware_state; + if(conn->bhc_gatt_svr.half_aware) { + ble_gatts_conn_aware_states[i].aware = false; + ble_gatts_conn_aware_states[i].half_aware = 0; + } else { + ble_gatts_conn_aware_states[i].aware = conn->bhc_gatt_svr.aware_state; + ble_gatts_conn_aware_states[i].half_aware = conn->bhc_gatt_svr.half_aware; + } } } } @@ -2173,8 +2192,8 @@ ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat goto done; } - if (BLE_GATT_CHR_CLI_SUP_FEAT_SZ < len) { - len = BLE_GATT_CHR_CLI_SUP_FEAT_SZ; + if (MYNEWT_VAL(BLE_GATT_CSFC_SIZE) < len) { + len = MYNEWT_VAL(BLE_GATT_CSFC_SIZE); } memcpy(out_supported_feat, conn->bhc_gatt_svr.peer_cl_sup_feat, @@ -2189,7 +2208,9 @@ int ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) { struct ble_hs_conn *conn; - uint8_t feat[BLE_GATT_CHR_CLI_SUP_FEAT_SZ] = {}; + struct ble_store_value_csfc value_csfc; + struct ble_store_key_csfc key_csfc; + uint8_t feat[MYNEWT_VAL(BLE_GATT_CSFC_SIZE)] = {}; uint16_t len; int rc = 0; int i; @@ -2202,8 +2223,8 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) /* RFU bits are ignored so we can skip any bytes larger than supported */ len = os_mbuf_len(om); - if (len > BLE_GATT_CHR_CLI_SUP_FEAT_SZ) { - len = BLE_GATT_CHR_CLI_SUP_FEAT_SZ; + if (len > MYNEWT_VAL(BLE_GATT_CSFC_SIZE)) { + len = MYNEWT_VAL(BLE_GATT_CSFC_SIZE); } if (os_mbuf_copydata(om, 0, len, feat) < 0) { @@ -2211,7 +2232,7 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) } /* clear RFU bits */ - for (i = 0; i < BLE_GATT_CHR_CLI_SUP_FEAT_SZ; i++) { + for (i = 0; i < MYNEWT_VAL(BLE_GATT_CSFC_SIZE); i++) { feat[i] &= (BLE_GATT_CHR_CLI_SUP_FEAT_MASK >> (8 * i)); } @@ -2226,7 +2247,7 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) * Disabling already enabled features is not permitted * (Vol. 3, Part F, 3.3.3) */ - for (i = 0; i < BLE_GATT_CHR_CLI_SUP_FEAT_SZ; i++) { + for (i = 0; i < MYNEWT_VAL(BLE_GATT_CSFC_SIZE); i++) { if ((conn->bhc_gatt_svr.peer_cl_sup_feat[i] & feat[i]) != conn->bhc_gatt_svr.peer_cl_sup_feat[i]) { rc = BLE_ATT_ERR_VALUE_NOT_ALLOWED; @@ -2234,7 +2255,26 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) } } - memcpy(conn->bhc_gatt_svr.peer_cl_sup_feat, feat, BLE_GATT_CHR_CLI_SUP_FEAT_SZ); + memcpy(conn->bhc_gatt_svr.peer_cl_sup_feat, feat, MYNEWT_VAL(BLE_GATT_CSFC_SIZE)); + + if (conn->bhc_sec_state.bonded) { + memset(&key_csfc, 0, sizeof key_csfc); + key_csfc.peer_addr = conn->bhc_peer_addr; + + rc = ble_store_delete_csfc(&key_csfc); + if (rc != 0) { + goto done; + } + + memset(&value_csfc, 0, sizeof value_csfc); + value_csfc.peer_addr = conn->bhc_peer_addr; + memcpy(value_csfc.csfc, feat, MYNEWT_VAL(BLE_GATT_CSFC_SIZE)); + + rc = ble_store_write_csfc(&value_csfc); + if (rc != 0) { + goto done; + } + } done: ble_hs_unlock(); @@ -2350,6 +2390,7 @@ void ble_gatts_bonding_established(uint16_t conn_handle) { struct ble_store_value_cccd cccd_value; + struct ble_store_value_csfc csfc; struct ble_gatts_clt_cfg *clt_cfg; struct ble_gatts_conn *gatt_srv; struct ble_hs_conn *conn; @@ -2394,6 +2435,19 @@ ble_gatts_bonding_established(uint16_t conn_handle) } } + csfc.peer_addr = conn->bhc_peer_addr; + csfc.peer_addr.type = + ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); + + memcpy(csfc.csfc, conn->bhc_gatt_svr.peer_cl_sup_feat, MYNEWT_VAL(BLE_GATT_CSFC_SIZE)); + + ble_hs_unlock(); + ble_store_write_csfc(&csfc); + ble_hs_lock(); + + conn = ble_hs_conn_find(conn_handle); + BLE_HS_DBG_ASSERT(conn != NULL); + #if MYNEWT_VAL(BLE_GATT_CACHING) /* store the bonded peer aware_state if space not available delete the @@ -2405,6 +2459,8 @@ ble_gatts_bonding_established(uint16_t conn_handle) sizeof(struct ble_gatts_aware_state)); memcpy(ble_gatts_conn_aware_states[new_idx].peer_id_addr, addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val); + ble_gatts_conn_aware_states[new_idx].aware = conn->bhc_gatt_svr.aware_state; + ble_gatts_conn_aware_states[new_idx].half_aware = conn->bhc_gatt_svr.half_aware; last_conn_aware_state_index = new_idx; #endif ble_hs_unlock(); @@ -2423,6 +2479,8 @@ ble_gatts_bonding_restored(uint16_t conn_handle) { struct ble_store_value_cccd cccd_value; struct ble_store_key_cccd cccd_key; + struct ble_store_value_csfc csfc_value; + struct ble_store_key_csfc csfc_key; struct ble_gatts_clt_cfg *clt_cfg; struct ble_hs_conn *conn; uint8_t att_op; @@ -2450,6 +2508,7 @@ ble_gatts_bonding_restored(uint16_t conn_handle) for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { + conn->bhc_gatt_svr.half_aware = ble_gatts_conn_aware_states[i].half_aware; conn->bhc_gatt_svr.aware_state = ble_gatts_conn_aware_states[i].aware; } } @@ -2522,6 +2581,14 @@ ble_gatts_bonding_restored(uint16_t conn_handle) cccd_key.idx++; } + + memset(&csfc_key, 0, sizeof csfc_key); + csfc_key.peer_addr = conn->bhc_peer_addr; + rc = ble_store_read_csfc(&csfc_key, &csfc_value); + if (rc != 0) { + return; + } + memcpy(conn->bhc_gatt_svr.peer_cl_sup_feat, csfc_value.csfc, MYNEWT_VAL(BLE_GATT_CSFC_SIZE)); } #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) @@ -2726,6 +2793,7 @@ static void ble_gatts_remove_clt_cfg(struct ble_gatts_clt_cfg_list *clt_cfgs, ui static int ble_gatts_conn_unaware(struct ble_hs_conn *conn, void *arg) { conn->bhc_gatt_svr.aware_state = false; + conn->bhc_gatt_svr.half_aware = 0; return 0; } #endif @@ -2825,6 +2893,7 @@ int ble_gatts_add_dynamic_svcs(const struct ble_gatt_svc_def *svcs) { #if MYNEWT_VAL(BLE_GATT_CACHING) /* make all bonded connections unaware */ for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { + ble_gatts_conn_aware_states[i].half_aware = 0; ble_gatts_conn_aware_states[i].aware = false; } ble_hs_conn_foreach(ble_gatts_conn_unaware, NULL); @@ -2926,6 +2995,7 @@ done: /* make all bonded connections them unaware */ for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { ble_gatts_conn_aware_states[i].aware = false; + ble_gatts_conn_aware_states[i].half_aware = 0; } ble_hs_conn_foreach(ble_gatts_conn_unaware, NULL); #endif @@ -2968,6 +3038,19 @@ done: return rc; } +void ble_gatts_free_svcs(void) +{ + /* Ensure the memory is freed only if it was previously allocated */ + if (ble_gatts_svc_defs != NULL) { + /* Free the memory for the service definitions */ + free(ble_gatts_svc_defs); + /* Set the pointer to NULL to avoid dangling pointer */ + ble_gatts_svc_defs = NULL; + /* Reset the number of service definitions to 0 */ + ble_gatts_num_svc_defs = 0; + } +} + int ble_gatts_svc_set_visibility(uint16_t handle, int visible) { @@ -3178,6 +3261,17 @@ ble_gatts_lcl_svc_foreach(ble_gatt_svc_foreach_fn cb, void *arg) #endif } +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) +uint8_t +ble_gatts_security_mode_1_level() { + uint8_t security_level; + + security_level = ble_att_svr_security_mode_1_level(); + + return security_level; +} +#endif + int ble_gatts_reset(void) { @@ -3244,3 +3338,5 @@ ble_gatts_init(void) return 0; } + +#endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs.c index 1ed13f82..7036fecc 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs.c @@ -40,7 +40,7 @@ MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)) static void ble_hs_event_rx_hci_ev(struct ble_npl_event *ev); -#if NIMBLE_BLE_CONNECT +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_GATTS) static void ble_hs_event_tx_notify(struct ble_npl_event *ev); #endif static void ble_hs_event_reset(struct ble_npl_event *ev); @@ -100,7 +100,11 @@ uint16_t ble_hs_max_services; uint16_t ble_hs_max_client_configs; #if MYNEWT_VAL(BLE_HS_DEBUG) +#define MAX_NESTED_LOCKS 5 +static TaskHandle_t ble_hs_task_handles[MAX_NESTED_LOCKS]; +static int ble_hs_task_handle_index = 0; static uint8_t ble_hs_mutex_locked; +static uint8_t counter_lock = 0; static TaskHandle_t ble_hs_task_handle; static uint8_t ble_hs_dbg_mutex_locked; #endif @@ -179,8 +183,11 @@ ble_hs_lock_nested(void) rc = ble_npl_mutex_pend(&ble_hs_mutex, 0xffffffff); #if MYNEWT_VAL(BLE_HS_DEBUG) + counter_lock++; ble_hs_mutex_locked = 1; ble_hs_task_handle = xTaskGetCurrentTaskHandle(); + ble_hs_task_handles[ble_hs_task_handle_index] = xTaskGetCurrentTaskHandle(); + ble_hs_task_handle_index++; #endif BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED); } @@ -198,14 +205,22 @@ ble_hs_unlock_nested(void) ble_hs_dbg_mutex_locked = 0; return; } - if(ble_hs_task_handle == xTaskGetCurrentTaskHandle()) { - ble_hs_task_handle = NULL; - ble_hs_mutex_locked = 0; + if (counter_lock > 0) { + counter_lock--; + if (counter_lock == 0) { + ble_hs_mutex_locked = 0; + } + if (ble_hs_task_handles[ble_hs_task_handle_index - 1] == xTaskGetCurrentTaskHandle()) { + ble_hs_task_handle_index--; + ble_hs_task_handles[ble_hs_task_handle_index] = NULL; + ble_hs_task_handle = ble_hs_task_handles[ble_hs_task_handle_index -1]; + } } #endif rc = ble_npl_mutex_release(&ble_hs_mutex); BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED); + } /** @@ -417,9 +432,10 @@ ble_hs_timer_exp(struct ble_npl_event *ev) switch (ble_hs_sync_state) { case BLE_HS_SYNC_STATE_GOOD: #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTC) ticks_until_next = ble_gattc_timer(); ble_hs_timer_sched(ticks_until_next); - +#endif ticks_until_next = ble_l2cap_sig_timer(); ble_hs_timer_sched(ticks_until_next); @@ -532,12 +548,14 @@ ble_hs_event_rx_hci_ev(struct ble_npl_event *ev) } #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTS) static void ble_hs_event_tx_notify(struct ble_npl_event *ev) { ble_gatts_tx_notifications(); } #endif +#endif static void ble_hs_event_rx_data(struct ble_npl_event *ev) @@ -673,10 +691,12 @@ ble_hs_start(void) ble_npl_callout_init(&ble_hs_timer, ble_hs_evq, ble_hs_timer_exp, NULL); #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTS) rc = ble_gatts_start(); if (rc != 0) { return rc; } +#endif #endif ble_hs_sync(); @@ -697,7 +717,7 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg) { int rc; -#if (BT_HCI_LOG_INCLUDED == TRUE) +#if ((BT_HCI_LOG_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED) uint16_t len = OS_MBUF_PKTHDR(om)->omp_len + 1; uint8_t *data = (uint8_t *)malloc(len); assert(data != NULL); @@ -733,7 +753,7 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg) int ble_hs_tx_data(struct os_mbuf *om) { -#if (BT_HCI_LOG_INCLUDED == TRUE) +#if ((BT_HCI_LOG_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED) uint16_t len = 0; uint8_t data[MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) + 1]; data[0] = 0x02; @@ -768,8 +788,10 @@ ble_hs_init(void) ble_hs_enabled_state = BLE_HS_ENABLED_STATE_OFF; #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTS) ble_npl_event_init(&ble_hs_ev_tx_notifications, ble_hs_event_tx_notify, NULL); +#endif #endif ble_npl_event_init(&ble_hs_ev_reset, ble_hs_event_reset, NULL); ble_npl_event_init(&ble_hs_ev_start_stage1, ble_hs_event_start_stage1, @@ -787,15 +809,23 @@ ble_hs_init(void) SYSINIT_PANIC_ASSERT(rc == 0); #endif + #if NIMBLE_BLE_CONNECT rc = ble_l2cap_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#endif + rc = ble_gap_init(); + SYSINIT_PANIC_ASSERT(rc == 0); + +#if NIMBLE_BLE_CONNECT rc = ble_att_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#if MYNEWT_VAL(BLE_GATTS) rc = ble_att_svr_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#endif rc = ble_gattc_init(); SYSINIT_PANIC_ASSERT(rc == 0); @@ -805,11 +835,11 @@ ble_hs_init(void) SYSINIT_PANIC_ASSERT(rc == 0); #endif +#if MYNEWT_VAL(BLE_GATTS) rc = ble_gatts_init(); SYSINIT_PANIC_ASSERT(rc == 0); #endif - rc = ble_gap_init(); - SYSINIT_PANIC_ASSERT(rc == 0); +#endif ble_hs_stop_init(); @@ -833,11 +863,6 @@ ble_hs_init(void) ble_hs_evq_set(nimble_port_get_dflt_eventq()); #endif -#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED - /* Configure the HCI transport to communicate with a host. */ - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); -#endif - /* Enqueue the start event to the default event queue. Using the default * queue ensures the event won't run until the end of main(). This allows * the application to configure this package in the meantime. @@ -891,10 +916,6 @@ ble_hs_deinit(void) ble_monitor_deinit(); #endif -#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED - ble_hci_trans_cfg_hs(NULL, NULL, NULL, NULL); -#endif - ble_npl_mutex_deinit(&ble_hs_mutex); ble_mqueue_deinit(&ble_hs_rx_q); diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv.c index aef917f7..0403c479 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv.c @@ -22,6 +22,9 @@ #include "nimble/ble.h" #include "host/ble_hs_adv.h" #include "ble_hs_priv.h" +#if MYNEWT_VAL(ENC_ADV_DATA) +#include "host/ble_ead.h" +#endif struct find_field_data { uint8_t type; @@ -526,6 +529,33 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } + /*** 0x27 - LE Supported Features. */ + if (adv_fields->le_supp_feat_is_present) { + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_LE_SUPP_FEAT, + BLE_HS_ADV_LE_SUPP_FEAT_LEN, + adv_fields->le_supp_feat, dst, &dst_len_local, + max_len, om); + } + + /*** 0x2f - Advertising interval - long. */ + if (adv_fields->adv_itvl_long_is_present && adv_fields->adv_itvl_long > 0xFFFF) { + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_ADV_ITVL_LONG, + BLE_HS_ADV_ADV_ITVL_LONG_LEN, + &adv_fields->adv_itvl_long, dst, &dst_len_local, + max_len, om); + } + +#if MYNEWT_VAL(ENC_ADV_DATA) + /*** 0x31 - Encrypted Advertising Data. */ + if ((adv_fields->enc_adv_data != NULL) && + (adv_fields->enc_adv_data_len > BLE_EAD_RANDOMIZER_SIZE + BLE_EAD_MIC_SIZE)) { + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_ENC_ADV_DATA, + adv_fields->enc_adv_data_len, + adv_fields->enc_adv_data, dst, &dst_len_local, + max_len, om); + } +#endif + /*** 0xff - Manufacturer specific data. */ if ((adv_fields->mfg_data != NULL) && (adv_fields->mfg_data_len >= 2)) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_MFG_DATA, @@ -862,6 +892,13 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, } break; +#if MYNEWT_VAL(ENC_ADV_DATA) + case BLE_HS_ADV_TYPE_ENC_ADV_DATA: + adv_fields->enc_adv_data = data; + adv_fields->enc_adv_data_len = data_len; + break; +#endif + case BLE_HS_ADV_TYPE_MFG_DATA: adv_fields->mfg_data = data; adv_fields->mfg_data_len = data_len; diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv_priv.h index 5c8a6ecc..669850fc 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_adv_priv.h @@ -26,8 +26,6 @@ extern "C" { int ble_hs_adv_set_flat(uint8_t type, int data_len, const void *data, uint8_t *dst, uint8_t *dst_len, uint8_t max_len); -int ble_hs_adv_find_field(uint8_t type, const uint8_t *data, uint8_t length, - const struct ble_hs_adv_field **out); #ifdef __cplusplus } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_cfg.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_cfg.c index a46a604a..d750fa04 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_cfg.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_cfg.c @@ -27,7 +27,11 @@ struct ble_hs_cfg ble_hs_cfg = { .sm_bonding = MYNEWT_VAL(BLE_SM_BONDING), .sm_mitm = MYNEWT_VAL(BLE_SM_MITM), .sm_sc = MYNEWT_VAL(BLE_SM_SC), + .sm_sc_only = MYNEWT_VAL(BLE_SM_SC_ONLY), + .sm_sec_lvl = MYNEWT_VAL(BLE_SM_LVL), .sm_keypress = MYNEWT_VAL(BLE_SM_KEYPRESS), .sm_our_key_dist = MYNEWT_VAL(BLE_SM_OUR_KEY_DIST), .sm_their_key_dist = MYNEWT_VAL(BLE_SM_THEIR_KEY_DIST), + .eatt = MYNEWT_VAL(BLE_EATT_CHAN_NUM), + .gatt_use_cache = MYNEWT_VAL(BLE_GATT_CACHING), }; diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn.c index 0af96f28..5b8aca22 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn.c @@ -45,9 +45,15 @@ ble_hs_conn_can_alloc(void) return 0; #endif - return ble_hs_conn_pool.mp_num_free >= 1 && - ble_l2cap_chan_pool.mp_num_free >= BLE_HS_CONN_MIN_CHANS && - ble_gatts_conn_can_alloc(); +#if MYNEWT_VAL(BLE_GATTS) + return ble_hs_conn_pool.mp_num_free >= 1 && + ble_l2cap_chan_pool.mp_num_free >= BLE_HS_CONN_MIN_CHANS && + ble_gatts_conn_can_alloc(); +#else + return ble_hs_conn_pool.mp_num_free >= 1 && + ble_l2cap_chan_pool.mp_num_free >= BLE_HS_CONN_MIN_CHANS; +#endif + } struct ble_l2cap_chan * @@ -187,13 +193,15 @@ ble_hs_conn_alloc(uint16_t conn_handle) if (rc != 0) { goto err; } - +#if MYNEWT_VAL(BLE_GATTS) rc = ble_gatts_conn_init(&conn->bhc_gatt_svr); if (rc != 0) { goto err; } +#endif STAILQ_INIT(&conn->bhc_tx_q); + STAILQ_INIT(&conn->att_tx_q); STATS_INC(ble_hs_stats, conn_create); @@ -244,7 +252,9 @@ ble_hs_conn_free(struct ble_hs_conn *conn) return; } +#if MYNEWT_VAL(BLE_GATTS) ble_att_svr_prep_clear(&conn->bhc_att_svr.basc_prep_list); +#endif while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) { ble_hs_conn_delete_chan(conn, chan); @@ -542,7 +552,7 @@ ble_hs_conn_timer(void) } #endif -#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO +#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO && MYNEWT_VAL(BLE_GATTS) /* Check each connection's rx queued write timer. If too much * time passes after a prep write is received, the queue is * cleared. diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn_priv.h index 0e451194..c994ed22 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_conn_priv.h @@ -95,6 +95,7 @@ struct ble_hs_conn { struct ble_gatts_conn bhc_gatt_svr; struct ble_gap_sec_state bhc_sec_state; + struct ble_gap_read_rem_ver_params bhc_rd_rem_ver_params; ble_gap_event_fn *bhc_cb; void *bhc_cb_arg; @@ -102,6 +103,12 @@ struct ble_hs_conn { #if MYNEWT_VAL(BLE_PERIODIC_ADV) struct ble_hs_periodic_sync *psync; #endif + + STAILQ_HEAD(, os_mbuf_pkthdr) att_tx_q; + bool client_att_busy; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + uint16_t default_cid; +#endif }; struct ble_hs_conn_addrs { diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci.c index b1ac4bdb..606f8848 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci.c @@ -28,10 +28,236 @@ #include "bt_common.h" #if (BT_HCI_LOG_INCLUDED == TRUE) #include "hci_log/bt_hci_log.h" +#include "host/ble_hs.h" #endif // (BT_HCI_LOG_INCLUDED == TRUE) #define BLE_HCI_CMD_TIMEOUT_MS 2000 +#if MYNEWT_VAL(BLE_ERR_CHECK) +/* HCI ERROR */ +#define BLE_ERR_UNKNOWN_HCI_CMD 0x01 +#define BLE_ERR_UNK_CONN_ID 0x02 +#define BLE_ERR_HW_FAIL 0x03 +#define BLE_ERR_PAGE_TMO 0x04 +#define BLE_ERR_AUTH_FAIL 0x05 +#define BLE_ERR_PINKEY_MISSING 0x06 +#define BLE_ERR_MEM_CAPACITY 0x07 +#define BLE_ERR_CONN_SPVN_TMO 0x08 +#define BLE_ERR_CONN_LIMIT 0x09 +#define BLE_ERR_SYNCH_CONN_LIMIT 0x0a +#define BLE_ERR_ACL_CONN_EXISTS 0x0b +#define BLE_ERR_CMD_DISALLOWED 0x0c +#define BLE_ERR_CONN_REJ_RESOURCES 0x0d +#define BLE_ERR_CONN_REJ_SECURITY 0x0e +#define BLE_ERR_CONN_REJ_BD_ADDR 0x0f +#define BLE_ERR_CONN_ACCEPT_TMO 0x10 +#define BLE_ERR_UNSUPPORTED 0x11 +#define BLE_ERR_INV_HCI_CMD_PARMS 0x12 +#define BLE_ERR_REM_USER_CONN_TERM 0x13 +#define BLE_ERR_RD_CONN_TERM_RESRCS 0x14 +#define BLE_ERR_RD_CONN_TERM_PWROFF 0x15 +#define BLE_ERR_CONN_TERM_LOCAL 0x16 +#define BLE_ERR_REPEATED_ATTEMPTS 0x17 +#define BLE_ERR_NO_PAIRING 0x18 +#define BLE_ERR_UNK_LMP 0x19 +#define BLE_ERR_UNSUPP_REM_FEATURE 0x1a +#define BLE_ERR_SCO_OFFSET 0x1b +#define BLE_ERR_SCO_ITVL 0x1c +#define BLE_ERR_SCO_AIR_MODE 0x1d +#define BLE_ERR_INV_LMP_LL_PARM 0x1e +#define BLE_ERR_UNSPECIFIED 0x1f +#define BLE_ERR_UNSUPP_LMP_LL_PARM 0x20 +#define BLE_ERR_NO_ROLE_CHANGE 0x21 +#define BLE_ERR_LMP_LL_RSP_TMO 0x22 +#define BLE_ERR_LMP_COLLISION 0x23 +#define BLE_ERR_LMP_PDU 0x24 +#define BLE_ERR_ENCRYPTION_MODE 0x25 +#define BLE_ERR_LINK_KEY_CHANGE 0x26 +#define BLE_ERR_UNSUPP_QOS 0x27 +#define BLE_ERR_INSTANT_PASSED 0x28 +#define BLE_ERR_UNIT_KEY_PAIRING 0x29 +#define BLE_ERR_DIFF_TRANS_COLL 0x2a +/*#define BLE_ERR_RESERVED 0x2b*/ +#define BLE_ERR_QOS_PARM 0x2c +#define BLE_ERR_QOS_REJECTED 0x2d +#define BLE_ERR_CHAN_CLASS 0x2e +#define BLE_ERR_INSUFFICIENT_SEC 0x2f +#define BLE_ERR_PARM_OUT_OF_RANGE 0x30 +/*#define BLE_ERR_RESERVED 0x31*/ +#define BLE_ERR_PENDING_ROLE_SW 0x32 +/*#define BLE_ERR_RESERVED 0x33*/ +#define BLE_ERR_RESERVED_SLOT 0x34 +#define BLE_ERR_ROLE_SW_FAIL 0x35 +#define BLE_ERR_INQ_RSP_TOO_BIG 0x36 +#define BLE_ERR_SEC_SIMPLE_PAIR 0x37 +#define BLE_ERR_HOST_BUSY_PAIR 0x38 +#define BLE_ERR_CONN_REJ_CHANNEL 0x39 +#define BLE_ERR_CTLR_BUSY 0x3a +#define BLE_ERR_CONN_PARMS 0x3b +#define BLE_ERR_DIR_ADV_TMO 0x3c +#define BLE_ERR_CONN_TERM_MIC 0x3d +#define BLE_ERR_CONN_ESTABLISHMENT 0x3e +#define BLE_ERR_MAC_CONN_FAIL 0x3f +#define BLE_ERR_COARSE_CLK_ADJ 0x40 +#define BLE_ERR_TYPE0_SUBMAP_NDEF 0x41 +#define BLE_ERR_UNK_ADV_INDENT 0x42 +#define BLE_ERR_LIMIT_REACHED 0x43 +#define BLE_ERR_OPERATION_CANCELLED 0x44 +#define BLE_ERR_PACKET_TOO_LONG 0x45 +#define BLE_ERR_MAX 0xff + +struct err_code { + int error_code; + const char *msg; +}; + +static struct err_code core_err_code_list[] = { + { BLE_HS_EAGAIN, ": BLE_HS_EAGAIN (Temporary failure; try again)" }, + { BLE_HS_EALREADY, ": BLE_HS_EALREADY (Operation already in progress or completed)" }, + { BLE_HS_EINVAL, ": BLE_HS_EINVAL (One or more arguments are invalid)" }, + { BLE_HS_EMSGSIZE, ": BLE_HS_EMSGSIZE (The provided buffer is too small)" }, + { BLE_HS_ENOENT, ": BLE_HS_ENOENT (No entry matching the specified criteria)" }, + { BLE_HS_ENOMEM, ": BLE_HS_ENOMEM (Operation failed due to resource exhaustion)" }, + { BLE_HS_ENOTCONN, ": BLE_HS_ENOTCONN (No open connection with the specified handle)" }, + { BLE_HS_ENOTSUP, ": BLE_HS_ENOTSUP (Operation disabled at compile time)" }, + { BLE_HS_EAPP, ": BLE_HS_EAPP (Application callback behaved unexpectedly)" }, + { BLE_HS_EBADDATA, ": BLE_HS_EBADDATA (Command from peer is invalid)" }, + { BLE_HS_EOS, ": BLE_HS_EOS (Mynewt OS error)" }, + { BLE_HS_ECONTROLLER, ": BLE_HS_ECONTROLLER (Event from controller is invalid)" }, + { BLE_HS_ETIMEOUT, ": BLE_HS_ETIMEOUT (Operation timed out)" }, + { BLE_HS_EDONE, ": BLE_HS_EDONE (Operation completed successfully)" }, + { BLE_HS_EBUSY, ": BLE_HS_EBUSY (Operation cannot be performed until procedure completes)" }, + { BLE_HS_EREJECT, ": BLE_HS_EREJECT (Peer rejected a connection parameter update request)" }, + { BLE_HS_EUNKNOWN, ": BLE_HS_EUNKNOWN (Unexpected failure; catch all)" }, + { BLE_HS_EROLE, ": BLE_HS_EROLE (Operation requires different role (e.g., central vs. peripheral))" }, + { BLE_HS_ETIMEOUT_HCI, ": BLE_HS_ETIMEOUT_HCI (HCI request timed out; controller unresponsive)" }, + { BLE_HS_ENOMEM_EVT, ": BLE_HS_ENOMEM_EVT (Controller failed to send event due to memory exhaustion)" }, + { BLE_HS_ENOADDR, ": BLE_HS_ENOADDR (Operation requires an identity address but none configured)" }, + { BLE_HS_ENOTSYNCED, ": BLE_HS_ENOTSYNCED (Attempt to use the host before it is synced with controller)" }, + { BLE_HS_EAUTHEN, ": BLE_HS_EAUTHEN (Insufficient authentication)" }, + { BLE_HS_EAUTHOR, ": BLE_HS_EAUTHOR (Insufficient authorization)" }, + { BLE_HS_EENCRYPT, ": BLE_HS_EENCRYPT (Insufficient encryption level)" }, + { BLE_HS_EENCRYPT_KEY_SZ, ": BLE_HS_EENCRYPT_KEY_SZ (Insufficient key size" }, + { BLE_HS_ESTORE_CAP, ": BLE_HS_ESTORE_CAP (BLE_HS_ESTORE_FAIL,)" }, + { BLE_HS_ESTORE_FAIL, ": BLE_HS_ESTORE_FAIL (Storage IO error)" }, + { BLE_HS_EPREEMPTED, ": BLE_HS_EPREEMPTED (ation was preempted)" }, + { BLE_HS_EDISABLED, ": BLE_HS_EDISABLED (Operation disabled)" }, + { BLE_HS_ESTALLED, ": BLE_HS_ESTALLED (Operation stalled)" } +}; + +static struct err_code err_code_list[] = { + { BLE_HS_HCI_ERR(BLE_ERR_UNKNOWN_HCI_CMD), ": BLE_ERR_UNKNOWN_HCI_CMD (Unknown HCI Command)" }, + { BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID), ": BLE_ERR_UNK_CONN_ID (Unknown Connection Identifier)" }, + { BLE_HS_HCI_ERR(BLE_ERR_HW_FAIL), ": BLE_ERR_HW_FAIL (Hardware Failure)" }, + { BLE_HS_HCI_ERR(BLE_ERR_PAGE_TMO), ": BLE_ERR_PAGE_TMO (Page Timeout)" }, + { BLE_HS_HCI_ERR(BLE_ERR_AUTH_FAIL), ": BLE_ERR_AUTH_FAIL (Authentication Failure)" }, + { BLE_HS_HCI_ERR(BLE_ERR_PINKEY_MISSING), ": BLE_ERR_PINKEY_MISSING (PIN or Key Missing)" }, + { BLE_HS_HCI_ERR(BLE_ERR_MEM_CAPACITY), ": BLE_ERR_MEM_CAPACITY (Memory Capacity Exceeded)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_SPVN_TMO), ": BLE_ERR_CONN_SPVN_TMO (Connection Timeout)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_LIMIT), ": BLE_ERR_CONN_LIMIT (Connection Limit Exceeded)" }, + { BLE_HS_HCI_ERR(BLE_ERR_SYNCH_CONN_LIMIT), ": BLE_ERR_SYNCH_CONN_LIMIT (Synchronous Connection Limit To A Device Exceeded)" }, + { BLE_HS_HCI_ERR(BLE_ERR_ACL_CONN_EXISTS), ": BLE_ERR_ACL_CONN_EXISTS (ACL Connection Already Exists)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CMD_DISALLOWED), ": BLE_ERR_CMD_DISALLOWED (Command Disallowed)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_REJ_RESOURCES), ": BLE_ERR_CONN_REJ_RESOURCES (Connection Rejected due to Limited Resources)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_REJ_SECURITY), ": BLE_ERR_CONN_REJ_SECURITY (Connection Rejected Due To Security Reasons)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_REJ_BD_ADDR), ": BLE_ERR_CONN_REJ_BD_ADDR (Connection Rejected due to Unacceptable BD_ADDR)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_ACCEPT_TMO), ": BLE_ERR_CONN_ACCEPT_TMO (Connection Accept Timeout Exceeded)" }, + { BLE_HS_HCI_ERR(BLE_ERR_UNSUPPORTED), ": BLE_ERR_UNSUPPORTED (Unsupported Feature or Parameter Value)" }, + { BLE_HS_HCI_ERR(BLE_ERR_INV_HCI_CMD_PARMS), ": BLE_ERR_INV_HCI_CMD_PARMS (Invalid HCI Command Parameters)" }, + { BLE_HS_HCI_ERR(BLE_ERR_REM_USER_CONN_TERM), ": BLE_ERR_REM_USER_CONN_TERM (Remote User Terminated Connection)" }, + { BLE_HS_HCI_ERR(BLE_ERR_RD_CONN_TERM_RESRCS), ": BLE_ERR_RD_CONN_TERM_RESRCS (Remote Device Terminated Connection due to Low Resources)" }, + { BLE_HS_HCI_ERR(BLE_ERR_RD_CONN_TERM_PWROFF), ": BLE_ERR_RD_CONN_TERM_PWROFF (Remote Device Terminated Connection due to Power Off)" }, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_TERM_LOCAL), ": BLE_ERR_CONN_TERM_LOCAL (Connection Terminated By Local Host)" }, + { BLE_HS_HCI_ERR(BLE_ERR_REPEATED_ATTEMPTS), ": BLE_ERR_REPEATED_ATTEMPTS (Repeated Attempts)" }, + { BLE_HS_HCI_ERR(BLE_ERR_NO_PAIRING), ": BLE_ERR_NO_PAIRING (Pairing Not Allowed)" }, + { BLE_HS_HCI_ERR(BLE_ERR_UNK_LMP), ": BLE_ERR_UNK_LMP (Unknown LMP PDU)" }, + { BLE_HS_HCI_ERR(BLE_ERR_UNSUPP_REM_FEATURE), ": BLE_ERR_UNSUPP_REM_FEATURE (Unsupported Remote Feature / Unsupported LMP Feature)" }, + { BLE_HS_HCI_ERR(BLE_ERR_SCO_OFFSET), ": BLE_ERR_SCO_OFFSET (SCO Offset Rejected)" }, + { BLE_HS_HCI_ERR(BLE_ERR_SCO_ITVL), ": BLE_ERR_SCO_ITVL (SCO Interval Rejected)" }, + { BLE_HS_HCI_ERR(BLE_ERR_SCO_AIR_MODE), ": BLE_ERR_SCO_AIR_MODE (SCO Air Mode Rejected)" }, + { BLE_HS_HCI_ERR(BLE_ERR_INV_LMP_LL_PARM), ": BLE_ERR_INV_LMP_LL_PARM (Invalid LMP Parameters / Invalid LL Parameters)" }, + { BLE_HS_HCI_ERR(BLE_ERR_UNSPECIFIED), ": BLE_ERR_UNSPECIFIED (Unspecified Error)" }, + { BLE_HS_HCI_ERR(BLE_ERR_UNSUPP_LMP_LL_PARM), ": BLE_ERR_UNSUPP_LMP_LL_PARM (Unsupported LMP Parameter Value / Unsupported LL Parameter Value)" }, + { BLE_HS_HCI_ERR(BLE_ERR_NO_ROLE_CHANGE), ": BLE_ERR_NO_ROLE_CHANGE (Role Change Not Allowed)" }, + { BLE_HS_HCI_ERR(BLE_ERR_LMP_LL_RSP_TMO), ": BLE_ERR_LMP_LL_RSP_TMO (LMP Response Timeout / LL Response Timeout)" }, + { BLE_HS_HCI_ERR(BLE_ERR_LMP_COLLISION), ": BLE_ERR_LMP_COLLISION (LMP Error Transaction Collision)" }, + { BLE_HS_HCI_ERR(BLE_ERR_LMP_PDU), ": BLE_ERR_LMP_PDU (LMP PDU Not Allowed)" }, + { BLE_HS_HCI_ERR(BLE_ERR_ENCRYPTION_MODE), ": BLE_ERR_ENCRYPTION_MODE (Encryption Mode Not Acceptable)"}, + { BLE_HS_HCI_ERR(BLE_ERR_LINK_KEY_CHANGE), ": BLE_ERR_LINK_KEY_CHANGE (Link Key cannot be Changed)"}, + { BLE_HS_HCI_ERR(BLE_ERR_UNSUPP_QOS), ": BLE_ERR_UNSUPP_QOS (Requested QoS Not Supported)"}, + { BLE_HS_HCI_ERR(BLE_ERR_INSTANT_PASSED), ": BLE_ERR_INSTANT_PASSED (Instant Passed)"}, + { BLE_HS_HCI_ERR(BLE_ERR_UNIT_KEY_PAIRING), ": BLE_ERR_UNIT_KEY_PAIRING (Pairing With Unit Key Not Supported)"}, + { BLE_HS_HCI_ERR(BLE_ERR_DIFF_TRANS_COLL), ": BLE_ERR_DIFF_TRANS_COLL (Different Transaction Collision)"}, + { BLE_HS_HCI_ERR(BLE_ERR_QOS_PARM), ": BLE_ERR_QOS_PARM (QoS Unacceptable Parameter)"}, + { BLE_HS_HCI_ERR(BLE_ERR_QOS_REJECTED), ": BLE_ERR_QOS_REJECTED (QoS Rejected)"}, + { BLE_HS_HCI_ERR(BLE_ERR_CHAN_CLASS), ": BLE_ERR_CHAN_CLASS (Channel Classification Not Supported)"}, + { BLE_HS_HCI_ERR(BLE_ERR_INSUFFICIENT_SEC), ": BLE_ERR_INSUFFICIENT_SEC (Insufficient Security)"}, + { BLE_HS_HCI_ERR(BLE_ERR_PARM_OUT_OF_RANGE), ": BLE_ERR_PARM_OUT_OF_RANGE (Parameter Out Of Mandatory Range)"}, + { BLE_HS_HCI_ERR(BLE_ERR_PENDING_ROLE_SW), ": BLE_ERR_PENDING_ROLE_SW (Role Switch Pending)"}, + { BLE_HS_HCI_ERR(BLE_ERR_RESERVED_SLOT), ": BLE_ERR_RESERVED_SLOT (Reserved Slot Violation)"}, + { BLE_HS_HCI_ERR(BLE_ERR_ROLE_SW_FAIL), ": BLE_ERR_ROLE_SW_FAIL (Role Switch Failed)"}, + { BLE_HS_HCI_ERR(BLE_ERR_INQ_RSP_TOO_BIG), ": BLE_ERR_INQ_RSP_TOO_BIG (Extended Inquiry Response Too Large)"}, + { BLE_HS_HCI_ERR(BLE_ERR_SEC_SIMPLE_PAIR), ": BLE_ERR_SEC_SIMPLE_PAIR (Secure Simple Pairing Not Supported By Host)"}, + { BLE_HS_HCI_ERR(BLE_ERR_HOST_BUSY_PAIR), ": BLE_ERR_HOST_BUSY_PAIR (Host Busy - Pairing)"}, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_REJ_CHANNEL), ": BLE_ERR_CONN_REJ_CHANNEL (Connection Rejected due to No Suitable Channel Found)"}, + { BLE_HS_HCI_ERR(BLE_ERR_CTLR_BUSY), ": BLE_ERR_CTLR_BUSY (Controller Busy)"}, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_PARMS), ": BLE_ERR_CONN_PARMS (Unacceptable Connection Parameters)"}, + { BLE_HS_HCI_ERR(BLE_ERR_DIR_ADV_TMO), ": BLE_ERR_DIR_ADV_TMO (Directed Advertising Timeout)"}, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_TERM_MIC), ": BLE_ERR_CONN_TERM_MIC (Connection Terminated due to MIC Failure)"}, + { BLE_HS_HCI_ERR(BLE_ERR_CONN_ESTABLISHMENT), ": BLE_ERR_CONN_ESTABLISHMENT (Connection Failed to be Established)"}, + { BLE_HS_HCI_ERR(BLE_ERR_MAC_CONN_FAIL), ": BLE_ERR_MAC_CONN_FAIL (MAC Connection Failed)"}, + { BLE_HS_HCI_ERR(BLE_ERR_COARSE_CLK_ADJ), ": BLE_ERR_COARSE_CLK_ADJ (Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging)"}, + { BLE_HS_HCI_ERR(BLE_ERR_TYPE0_SUBMAP_NDEF), ": BLE_ERR_TYPE0_SUBMAP_NDEF (Type0 Submap Not Defined)"}, + { BLE_HS_HCI_ERR(BLE_ERR_UNK_ADV_INDENT), ": BLE_ERR_UNK_ADV_INDENT (Unknown Advertising Identifier)"}, + { BLE_HS_HCI_ERR(BLE_ERR_LIMIT_REACHED), ": BLE_ERR_LIMIT_REACHED (Limit Reached)"}, + { BLE_HS_HCI_ERR(BLE_ERR_OPERATION_CANCELLED), ": BLE_ERR_OPERATION_CANCELLED (Operation Cancelled by Host)"}, + { BLE_HS_HCI_ERR(BLE_ERR_PACKET_TOO_LONG), ": BLE_ERR_PACKET_TOO_LONG (Packet Too Long)"}, + { BLE_HS_HCI_ERR(BLE_ERR_MAX), ": BLE_ERR_MAX"} +}; + +static void esp_core_err_to_name(int error_code, uint16_t *opcode) +{ + for (int i = 0; ibhc_outstanding_pkts++; + ble_hs_hci_avail_pkts--; + rc = ble_hs_tx_data(frag); if (rc != 0) { + conn->bhc_outstanding_pkts--; + ble_hs_hci_avail_pkts++; goto err; } @@ -615,10 +850,6 @@ ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om) */ conn->bhc_flags |= BLE_HS_CONN_F_TX_FRAG; pb = BLE_HCI_PB_MIDDLE; - - /* Account for the controller buf that will hold the txed fragment. */ - conn->bhc_outstanding_pkts++; - ble_hs_hci_avail_pkts--; } if (txom != NULL) { @@ -690,6 +921,18 @@ ble_hs_hci_get_hci_version(void) return ble_hs_hci_version; } +void +ble_hs_hci_set_hci_supported_cmd(struct ble_hs_hci_sup_cmd sup_cmd) +{ + ble_hs_hci_sup_cmd = sup_cmd; +} + +struct ble_hs_hci_sup_cmd +ble_hs_hci_get_hci_supported_cmd(void) +{ + return ble_hs_hci_sup_cmd; +} + void ble_hs_hci_init(void) { diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c index 76ec034d..a9487eaa 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c @@ -91,7 +91,7 @@ ble_hs_hci_cmd_send(uint16_t opcode, uint8_t len, const void *cmddata) buf--; #endif -#if (BT_HCI_LOG_INCLUDED == TRUE) +#if ((BT_HCI_LOG_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED) uint8_t *data; #if !(SOC_ESP_NIMBLE_CONTROLLER) && CONFIG_BT_CONTROLLER_ENABLED data = (uint8_t *)buf + 1; diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c index 64b37f01..7b410d35 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c @@ -35,12 +35,7 @@ struct ble_gap_reattempt_ctxt { extern int ble_gap_master_connect_reattempt(uint16_t conn_handle); extern int ble_gap_slave_adv_reattempt(void); - -#ifdef CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT -#define MAX_REATTEMPT_ALLOWED CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT -#else -#define MAX_REATTEMPT_ALLOWED 0 -#endif +extern int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; #endif #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) @@ -57,6 +52,7 @@ typedef int ble_hs_hci_evt_fn(uint8_t event_code, const void *data, unsigned int len); static ble_hs_hci_evt_fn ble_hs_hci_evt_hw_error; static ble_hs_hci_evt_fn ble_hs_hci_evt_num_completed_pkts; +static ble_hs_hci_evt_fn ble_hs_hci_evt_rd_rem_ver_complete; #if NIMBLE_BLE_CONNECT static ble_hs_hci_evt_fn ble_hs_hci_evt_disconn_complete; static ble_hs_hci_evt_fn ble_hs_hci_evt_encrypt_change; @@ -103,6 +99,15 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_transmit_power_report; #if MYNEWT_VAL(BLE_CONN_SUBRATING) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_subrate_change; #endif +#if MYNEWT_VAL(BLE_AOA_AOD) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_connless_iq_report; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_iq_report; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_cte_req_failed; +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_subev_data_req; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_subev_resp_rep; +#endif /* Statistics */ struct host_hci_stats { @@ -122,6 +127,7 @@ struct ble_hs_hci_evt_dispatch_entry { static const struct ble_hs_hci_evt_dispatch_entry ble_hs_hci_evt_dispatch[] = { { BLE_HCI_EVCODE_LE_META, ble_hs_hci_evt_le_meta }, + { BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP, ble_hs_hci_evt_rd_rem_ver_complete }, { BLE_HCI_EVCODE_NUM_COMP_PKTS, ble_hs_hci_evt_num_completed_pkts }, #if NIMBLE_BLE_CONNECT { BLE_HCI_EVCODE_DISCONN_CMP, ble_hs_hci_evt_disconn_complete }, @@ -177,6 +183,19 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { #if MYNEWT_VAL(BLE_CONN_SUBRATING) [BLE_HCI_LE_SUBEV_SUBRATE_CHANGE] = ble_hs_hci_evt_le_subrate_change, #endif +#if MYNEWT_VAL(BLE_AOA_AOD) + [BLE_HCI_LE_SUBEV_CONNLESS_IQ_RPT] = ble_hs_hci_evt_le_connless_iq_report, + [BLE_HCI_LE_SUBEV_CONN_IQ_RPT] = ble_hs_hci_evt_le_conn_iq_report, + [BLE_HCI_LE_SUBEV_CTE_REQ_FAILED] = ble_hs_hci_evt_le_cte_req_failed, +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB_V2] = ble_hs_hci_evt_le_periodic_adv_sync_estab, + [BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT_V2] = ble_hs_hci_evt_le_periodic_adv_rpt, + [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER_V2] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, + [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SUBEV_DATA_REQ] = ble_hs_hci_evt_le_periodic_adv_subev_data_req, + [BLE_HCI_LE_SUBEV_PERIODIC_ADV_RESP_REPORT] = ble_hs_hci_evt_le_periodic_adv_subev_resp_rep, + [BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE_V2] = ble_hs_hci_evt_le_enh_conn_complete, +#endif }; #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \ @@ -206,7 +225,6 @@ ble_hs_hci_evt_le_dispatch_find(uint8_t event_code) if (event_code >= BLE_HS_HCI_EVT_LE_DISPATCH_SZ) { return NULL; } - return ble_hs_hci_evt_le_dispatch[event_code]; } @@ -230,18 +248,53 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, ble_hs_unlock(); #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) - if (conn && ev->reason == BLE_ERR_CONN_ESTABLISHMENT) { + if (conn) { uint16_t handle; int rc; - if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { //slave - BLE_HS_LOG(INFO, "Reattempt advertising; reason: 0x%x, status = %x", - ev->reason, ev->status); + /* For master role, check if failure reason is 0x3E, to restart connect attempt + * For slave role, check whether + * a. Failure reason is 0x3E + * b. Connect event was not posted and 0x8 was received + * Restart advertising in above reasons for slave. + */ + + if ((conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \ + (ev->reason == BLE_ERR_CONN_ESTABLISHMENT)) { // master + if (reattempt_conn.count < MAX_REATTEMPT_ALLOWED) { + /* Go for connection */ + BLE_HS_LOG(INFO, "Reattempt connection; reason = 0x%x, status = %d," + "reattempt count = %d ", ev->reason, ev->status, + reattempt_conn.count); + reattempt_conn.count += 1; + + handle = le16toh(ev->conn_handle); + /* Post event to interested application */ + ble_gap_reattempt_count(handle, reattempt_conn.count); + rc = ble_gap_master_connect_reattempt(ev->conn_handle); + if (rc != 0) { + BLE_HS_LOG(INFO, "Master reconnect attempt failed; rc = %d", rc); + } + } else { + /* Exhausted attempts */ + memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); + } + } + else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \ + ((ev->reason == BLE_ERR_CONN_ESTABLISHMENT) || \ + (!slave_conn[ev->conn_handle] && ev->reason == BLE_ERR_CONN_SPVN_TMO))) { //slave + + BLE_HS_LOG(INFO, "Reattempt advertising; reason: 0x%x, status = %x", + ev->reason, ev->status); ble_l2cap_sig_conn_broken(ev->conn_handle, BLE_ERR_CONN_ESTABLISHMENT); ble_sm_connection_broken(ev->conn_handle); - ble_gatts_connection_broken(ev->conn_handle); - ble_gattc_connection_broken(ev->conn_handle); +#if MYNEWT_VAL(BLE_GATTS) + ble_gatts_connection_broken(ev->conn_handle); +#endif +#if MYNEWT_VAL(BLE_GATTC) + ble_gattc_connection_broken(ev->conn_handle); +#endif ble_hs_flow_connection_broken(ev->conn_handle);; #if MYNEWT_VAL(BLE_GATT_CACHING) ble_gattc_cache_conn_broken(ev->conn_handle); @@ -253,36 +306,14 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, rc = ble_gap_slave_adv_reattempt(); if (rc != 0) { - BLE_HS_LOG(INFO, "Adv reattempt failed; rc= %d ", rc); + BLE_HS_LOG(INFO, "Adv reattempt failed; rc= %d ", rc); } return 0; // Restart advertising, so don't post disconnect event - - } else { // master - if (reattempt_conn.count < MAX_REATTEMPT_ALLOWED ) { - /* Got for connection */ - BLE_HS_LOG(INFO, "Reattempt connection; reason = 0x%x, status = %d," - "reattempt count = %d ", ev->reason, ev->status, - reattempt_conn.count); - reattempt_conn.count += 1; - - handle = le16toh(ev->conn_handle); - /* Post event to interested application */ - ble_gap_reattempt_count(handle, reattempt_conn.count); - - rc = ble_gap_master_connect_reattempt(ev->conn_handle); - if (rc != 0) { - BLE_HS_LOG(INFO, "Master reconnect attempt failed; rc = %d", rc); - } - } else { - /* Exhausted attempts */ - memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); - } - } - } - else { + } else { /* Normal disconnect. Reset the structure */ memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); + } } #endif @@ -352,6 +383,10 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, const void *data, uint16_t num_pkts; int i; + if (len < sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + if (len != sizeof(*ev) + (ev->count * sizeof(ev->completed[0]))) { return BLE_HS_ECONTROLLER; } @@ -470,7 +505,7 @@ ble_hs_hci_evt_le_enh_conn_complete(uint8_t subevent, const void *data, #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) /* RPA needs to be resolved here, as controller is not aware of the * address is RPA in Host based RPA */ - if (ble_host_rpa_enabled() && !memcmp(evt.local_rpa, ble_hs_conn_null_addr, 6) == 0) { + if (ble_host_rpa_enabled() && ((!memcmp(evt.local_rpa, ble_hs_conn_null_addr, 6)) == 0)) { uint8_t *local_id_rpa = ble_hs_get_rpa_local(); memcpy(evt.local_rpa, local_id_rpa, BLE_DEV_ADDR_LEN); } @@ -488,7 +523,7 @@ ble_hs_hci_evt_le_enh_conn_complete(uint8_t subevent, const void *data, evt.connection_handle = BLE_HS_CONN_HANDLE_NONE; #endif } -#if MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_EXT_ADV) && !MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) if (evt.status == BLE_ERR_DIR_ADV_TMO || evt.role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) { /* store this until we get set terminated event with adv handle */ @@ -496,6 +531,16 @@ ble_hs_hci_evt_le_enh_conn_complete(uint8_t subevent, const void *data, return 0; } #endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + if (subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) { + evt.adv_handle = 0xFF; + evt.sync_handle = 0xFFFF; + } else { + evt.adv_handle = ev->adv_handle; + evt.sync_handle = ev->sync_handle; + } +#endif return ble_gap_rx_conn_complete(&evt, 0); } @@ -582,15 +627,13 @@ ble_hs_hci_evt_le_adv_rpt_first_pass(const void *data, unsigned int len) rpt = data; - len -= sizeof(*rpt) + 1; - data += sizeof(rpt) + 1; - if (rpt->data_len > len) { return BLE_HS_ECONTROLLER; } - len -= rpt->data_len; - data += rpt->data_len; + /* extra byte for RSSI after adv data */ + len -= sizeof(*rpt) + 1 + rpt->data_len; + data += sizeof(*rpt) + 1 + rpt->data_len; } /* Make sure length was correct */ @@ -711,6 +754,22 @@ ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent, const void *data, return 0; } +static int +ble_hs_hci_evt_rd_rem_ver_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_rd_rem_ver_info_cmp *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + ble_gap_rx_rd_rem_ver_info_complete(ev); + + return 0; +} + + #if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN static int ble_hs_hci_decode_legacy_type(uint16_t evt_type) @@ -731,29 +790,66 @@ ble_hs_hci_decode_legacy_type(uint16_t evt_type) return -1; } } -#endif static int -ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, - unsigned int len) +ble_hs_hci_evt_le_ext_adv_rpt_first_pass(const void *data, unsigned int len) { -#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN const struct ble_hci_ev_le_subev_ext_adv_rpt *ev = data; const struct ext_adv_report *report; - struct ble_gap_ext_disc_desc desc; int i; - int legacy_event_type; if (len < sizeof(*ev)) { - return BLE_HS_EBADDATA; + return BLE_HS_ECONTROLLER; } + len -= sizeof(*ev); + data += sizeof(*ev); + if (ev->num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN || ev->num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) { return BLE_HS_EBADDATA; } - /* TODO properly validate len of the event */ + for (i = 0; i < ev->num_reports; i++) { + if (len < sizeof(*report)) { + return BLE_HS_ECONTROLLER; + } + + report = data; + + if (report->data_len > len) { + return BLE_HS_ECONTROLLER; + } + + len -= sizeof(*report) + report->data_len; + data += sizeof(*report) + report->data_len; + } + + /* Make sure length was correct */ + if (len) { + return BLE_HS_ECONTROLLER; + } + + return 0; +} +#endif + +static int +ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, + unsigned int len) +{ +#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN + const struct ble_hci_ev_le_subev_ext_adv_rpt *ev = data; + const struct ext_adv_report *report; + struct ble_gap_ext_disc_desc desc; + int legacy_event_type; + int rc; + int i; + + rc = ble_hs_hci_evt_le_ext_adv_rpt_first_pass(data, len); + if (rc != 0) { + return rc; + } report = &ev->reports[0]; for (i = 0; i < ev->num_reports; i++) { @@ -946,6 +1042,13 @@ ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, const void *data, return BLE_HS_ECONTROLLER; } + /* this indicates bug in controller as host uses instances from + * 0-BLE_ADV_INSTANCES range only + */ + if (ev->adv_handle >= BLE_ADV_INSTANCES) { + return BLE_HS_ECONTROLLER; + } + if (ev->status == 0) { /* ignore return code as we need to terminate advertising set anyway */ ble_gap_rx_conn_complete(&pend_conn_complete, ev->adv_handle); @@ -967,6 +1070,13 @@ ble_hs_hci_evt_le_scan_req_rcvd(uint8_t subevent, const void *data, return BLE_HS_ECONTROLLER; } + /* this indicates bug in controller as host uses instances from + * 0-BLE_ADV_INSTANCES range only + */ + if (ev->adv_handle >= BLE_ADV_INSTANCES) { + return BLE_HS_ECONTROLLER; + } + ble_gap_rx_scan_req_rcvd(ev); #endif @@ -990,6 +1100,116 @@ ble_hs_hci_evt_le_subrate_change(uint8_t subevent, const void *data, } #endif +#if MYNEWT_VAL(BLE_AOA_AOD) +static int +ble_hs_hci_evt_le_connless_iq_report(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_connless_iq_rpt *ev = data; + + if (len < sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + ble_gap_rx_connless_iq_report(ev); + + return 0; +} + +static int +ble_hs_hci_evt_le_conn_iq_report(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_conn_iq_rpt *ev = data; + if (len < sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + ble_gap_rx_conn_iq_report(ev); + + return 0; +} + +static int +ble_hs_hci_evt_le_cte_req_failed(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_cte_req_failed *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + ble_gap_rx_cte_req_failed(ev); + + return 0; +} +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +static int +ble_hs_hci_evt_le_periodic_adv_subev_data_req(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_periodic_adv_subev_data_req *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + ble_gap_rx_periodic_adv_subev_data_req(ev); + + return 0; +} + +static int +ble_hs_hci_evt_le_periodic_adv_subev_resp_rep(uint8_t subevent, const void *data, unsigned int len) +{ + const struct ble_hci_ev_le_subev_periodic_adv_resp_rep *ev = data; + const struct periodic_adv_response *response; + struct ble_gap_periodic_adv_response resp; + uint32_t size; + + /* TODO: compare with the total length including the response data. */ + size = sizeof(*ev); + for (uint8_t i = 0; i < ev->num_responses; i ++) { + size += sizeof(struct periodic_adv_response) + ev->responses[i].data_length; + } + if (len < size) { + return BLE_HS_ECONTROLLER; + } + + len -= sizeof(*ev); + data += sizeof(*ev); + + resp.adv_handle = ev->adv_handle; + resp.subevent = ev->subevent; + resp.tx_status = ev->tx_status; + + for (uint8_t i = 0; i < ev->num_responses; i++) { + response = data; + if (len < sizeof(*response) + response->data_length) { + return BLE_HS_ECONTROLLER; + } + + len -= sizeof(*response) + response->data_length; + data += sizeof(*response) + response->data_length; + + resp.tx_power = response->tx_power; + resp.rssi = response->rssi; + resp.cte_type = response->cte_type; + resp.response_slot = response->response_slot; + resp.data_length = response->data_length; + resp.data = response->data; + resp.data_status = response->data_status; + + ble_gap_rx_periodic_adv_response(resp); + } + + return 0; +} +#endif + #if NIMBLE_BLE_CONNECT static int ble_hs_hci_evt_le_conn_upd_complete(uint8_t subevent, const void *data, @@ -1098,8 +1318,8 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev) if(ev->opcode == BLE_HCI_EVCODE_COMMAND_COMPLETE) { /* Check if this Command complete has a parsable opcode */ - struct ble_hci_ev_command_complete *cmd_complete = (void *) ev->data; - entry = ble_hs_hci_evt_dispatch_find(cmd_complete->opcode); + struct ble_hci_ev_command_complete *cmd_complete = (void *) ev->data; + entry = ble_hs_hci_evt_dispatch_find(cmd_complete->opcode); } else { entry = ble_hs_hci_evt_dispatch_find(ev->opcode); @@ -1115,8 +1335,9 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev) BLE_HS_LOG(DEBUG, "ble_hs_event_rx_hci_ev; opcode=0x%x ", ev->opcode); /* For LE Meta, print subevent code */ - if(ev->opcode == 0x3e) + if(ev->opcode == 0x3e) { BLE_HS_LOG(DEBUG, "subevent: 0x%x", ev->data[0]); + } BLE_HS_LOG(DEBUG, "\n"); } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_priv.h index ab862dc5..db66c354 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_priv.h @@ -79,6 +79,10 @@ struct hci_periodic_adv_params #endif #endif +struct ble_hs_hci_sup_cmd { + uint8_t commands[64]; +}; + extern uint16_t ble_hs_hci_avail_pkts; /* This function is not waiting for command status/complete HCI events */ @@ -92,6 +96,8 @@ void ble_hs_hci_set_le_supported_feat(uint32_t feat); uint32_t ble_hs_hci_get_le_supported_feat(void); void ble_hs_hci_set_hci_version(uint8_t hci_version); uint8_t ble_hs_hci_get_hci_version(void); +void ble_hs_hci_set_hci_supported_cmd(struct ble_hs_hci_sup_cmd sup_cmd); +struct ble_hs_hci_sup_cmd ble_hs_hci_get_hci_supported_cmd(void); #if MYNEWT_VAL(BLE_HS_PHONY_HCI_ACKS) typedef int ble_hs_hci_phony_ack_fn(uint8_t *ack, int ack_buf_len); diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_id.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_id.c index 3fa07187..ae423934 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_id.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_id.c @@ -224,11 +224,13 @@ ble_hs_id_addr(uint8_t id_addr_type, const uint8_t **out_id_addr, switch (id_addr_type) { case BLE_ADDR_PUBLIC: + case BLE_ADDR_PUBLIC_ID: id_addr = ble_hs_id_pub; nrpa = 0; break; case BLE_ADDR_RANDOM: + case BLE_ADDR_RANDOM_ID: id_addr = ble_hs_id_rnd; nrpa = (ble_hs_id_rnd[5] & 0xc0) == 0; break; diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_priv.h index c5781ccc..cb97e537 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_priv.h @@ -24,6 +24,7 @@ #include #include "ble_att_cmd_priv.h" #include "ble_att_priv.h" +#include "ble_eatt_priv.h" #include "ble_gap_priv.h" #include "ble_gatt_priv.h" #include "ble_hs_hci_priv.h" diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_pvcy.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_pvcy.c index 403fd4ec..a0cb261a 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_pvcy.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_pvcy.c @@ -51,11 +51,11 @@ ble_hs_pvcy_set_addr_timeout(uint16_t timeout) &cmd, sizeof(cmd), NULL, 0); } -void ble_hs_set_rpa_timeout (uint16_t timeout) +int ble_hs_set_rpa_timeout (uint16_t timeout) { rpa_timeout = timeout; - ble_hs_pvcy_set_addr_timeout(rpa_timeout); + return ble_hs_pvcy_set_addr_timeout(rpa_timeout); } uint16_t ble_hs_get_rpa_timeout(void) diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_resolv.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_resolv.c index 6fcbc051..217cef19 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_resolv.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_resolv.c @@ -36,13 +36,6 @@ #define BLE_RESOLV_LIST_SIZE (MYNEWT_VAL(BLE_STORE_MAX_BONDS) + 1) #define BLE_MAX_RPA_TIMEOUT_VAL 0xA1B8 -static struct ble_hs_resolv_data g_ble_hs_resolv_data; -static struct ble_hs_resolv_entry g_ble_hs_resolv_list[BLE_RESOLV_LIST_SIZE]; -/* Allocate one extra space for peer_records than no. of Bonds, it will take - * care of storage overflow */ -static struct ble_hs_dev_records peer_dev_rec[BLE_RESOLV_LIST_SIZE]; -static int ble_store_num_peer_dev_rec; - struct ble_hs_resolv_data { uint8_t addr_res_enabled; uint8_t rl_cnt; @@ -50,6 +43,13 @@ struct ble_hs_resolv_data { struct ble_npl_callout rpa_timer; }; +static struct ble_hs_resolv_data g_ble_hs_resolv_data; +static struct ble_hs_resolv_entry g_ble_hs_resolv_list[BLE_RESOLV_LIST_SIZE]; +/* Allocate one extra space for peer_records than no. of Bonds, it will take + * care of storage overflow */ +static struct ble_hs_dev_records peer_dev_rec[BLE_RESOLV_LIST_SIZE]; +static int ble_store_num_peer_dev_rec; + /* NRPA bit: Enables NRPA as private address. */ static bool nrpa_pvcy; diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_startup.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_startup.c index a9c9fe79..ff3ad055 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_startup.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_hs_startup.c @@ -68,6 +68,26 @@ ble_hs_startup_read_local_ver_tx(void) return 0; } +static int +ble_hs_startup_read_sup_cmd_tx(void) +{ + struct ble_hci_ip_rd_loc_supp_cmd_rp rsp; + struct ble_hs_hci_sup_cmd sup_cmd; + int rc; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, + BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD), + NULL, 0, &rsp, sizeof(rsp)); + if (rc != 0) { + return rc; + } + + memcpy(&sup_cmd.commands, &rsp.commands, sizeof(sup_cmd)); + ble_hs_hci_set_hci_supported_cmd(sup_cmd); + + return 0; +} + static int ble_hs_startup_le_read_sup_f_tx(void) { @@ -247,6 +267,7 @@ ble_hs_startup_le_set_evmask_tx(void) * 0x0000000400000000 LE Subrate change event */ mask |= 0x0000000400000000; + } #endif #if MYNEWT_VAL(BLE_POWER_CONTROL) @@ -281,6 +302,42 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_AOA_AOD) + if (version >= BLE_HCI_VER_BCS_5_1) { + /** + * Enable the following LE events: + * 0x0000000000100000 LE Connectionless IQ Report event + * 0x0000000000200000 LE Connection IQ Report event + * 0x0000000000400000 LE CTE Request Failed event + */ + mask |= 0x0000000000700000; + } +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + if (version >= BLE_HCI_VER_BCS_5_4) { + /** + * Enable the following LE events: + * 0x0000000800000000 LE Periodic Advertising Sync Established event V2 + * 0x0000001000000000 LE Periodic Advertising Report Event V2 + * 0x0000004000000000 LE Periodic Advertising Subevent Data Request event + * 0x0000008000000000 LE Periodic Advertising Response Report event + * 0x0000010000000000 LE Enhanced Connection Complete event V2 + */ + mask |= 0x000001d800000000; + } +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + if (version >= BLE_HCI_VER_BCS_5_4) { + /** + * Enable the following LE events: + * 0x0000002000000000 LE Periodic Advertising Sync Transfer Received event V2 + */ + mask |= 0x0000002000000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, @@ -299,20 +356,23 @@ ble_hs_startup_set_evmask_tx(void) struct ble_hci_cb_set_event_mask_cp cmd; struct ble_hci_cb_set_event_mask2_cp cmd2; uint8_t version; + struct ble_hs_hci_sup_cmd sup_cmd; int rc; version = ble_hs_hci_get_hci_version(); + sup_cmd = ble_hs_hci_get_hci_supported_cmd(); /** * Enable the following events: * 0x0000000000000010 Disconnection Complete Event * 0x0000000000000080 Encryption Change Event + * 0x0000000000000800 Read Remote Version Information Complete event * 0x0000000000008000 Hardware Error Event * 0x0000000002000000 Data Buffer Overflow Event * 0x0000800000000000 Encryption Key Refresh Complete Event * 0x2000000000000000 LE Meta-Event */ - cmd.event_mask = htole64(0x2000800002008090); + cmd.event_mask = htole64(0x2000800002008890); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_SET_EVENT_MASK), @@ -321,7 +381,7 @@ ble_hs_startup_set_evmask_tx(void) return rc; } - if (version >= BLE_HCI_VER_BCS_4_1) { + if ((version >= BLE_HCI_VER_BCS_4_1) && ((sup_cmd.commands[22] & 0x04) != 0)) { /** * Enable the following events: * 0x0000000000800000 Authenticated Payload Timeout Event @@ -349,7 +409,7 @@ ble_hs_startup_reset_tx(void) int ble_hs_startup_go(void) { - //struct ble_store_gen_key gen_key; + struct ble_store_gen_key gen_key; int rc; rc = ble_hs_startup_reset_tx(); @@ -362,7 +422,11 @@ ble_hs_startup_go(void) return rc; } - /* XXX: Read local supported commands. */ + /* Read local supported commands. */ + rc = ble_hs_startup_read_sup_cmd_tx(); + if (rc != 0) { + return rc; + } /* we need to check this only if using external controller */ #if !MYNEWT_VAL(BLE_CONTROLLER) @@ -403,7 +467,7 @@ ble_hs_startup_go(void) if (rc != 0) { return rc; } -#if 0 + if (ble_hs_cfg.store_gen_key_cb) { memset(&gen_key, 0, sizeof(gen_key)); rc = ble_hs_cfg.store_gen_key_cb(BLE_STORE_GEN_KEY_IRK, &gen_key, @@ -416,12 +480,10 @@ ble_hs_startup_go(void) } if (rc != 0) { + ble_hs_pvcy_set_default_irk(); + ble_hs_pvcy_set_our_irk(NULL); } -#endif - ble_hs_pvcy_set_default_irk(); - - ble_hs_pvcy_set_our_irk(NULL); /* If flow control is enabled, configure the controller to use it. */ ble_hs_flow_startup(); diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap.c index 50fe18c6..8bcd1fb6 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap.c @@ -208,7 +208,29 @@ ble_l2cap_reconfig(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu } } - return ble_l2cap_sig_coc_reconfig(conn_handle, chans, num, new_mtu); + return ble_l2cap_sig_coc_reconfig(conn_handle, chans, num, new_mtu, MYNEWT_VAL(BLE_L2CAP_COC_MPS)); +} + +int +ble_l2cap_reconfig_mtu_mps(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu, uint16_t new_mps) +{ + int i; + uint16_t conn_handle; + + if (num == 0 || !chans) { + return BLE_HS_EINVAL; + } + + conn_handle = chans[0]->conn_handle; + + for (i = 1; i < num; i++) { + if (conn_handle != chans[i]->conn_handle) { + BLE_HS_LOG(ERROR, "All channels should have same conn handle\n"); + return BLE_HS_EINVAL; + } + } + + return ble_l2cap_sig_coc_reconfig(conn_handle, chans, num, new_mtu, new_mps); } int @@ -385,7 +407,7 @@ ble_l2cap_rx(struct ble_hs_conn *conn, } /* For CIDs from dynamic range we check if SDU size isn't larger than MPS */ - if (chan->dcid >= 0x0040 && chan->dcid <= 0x007F && l2cap_hdr.len > chan->my_coc_mps) { + if (chan->dcid >= 0x0040 && chan->dcid <= 0x007F && l2cap_hdr.len > (chan->my_coc_mps + BLE_L2CAP_SDU_SZ)) { /* Data exceeds MPS */ BLE_HS_LOG(ERROR, "error: sdu_len > chan->my_coc_mps (%d>%d)\n", l2cap_hdr.len, chan->my_coc_mps); @@ -399,7 +421,7 @@ ble_l2cap_rx(struct ble_hs_conn *conn, ble_l2cap_remove_rx(conn, chan); } - if (l2cap_hdr.len > ble_l2cap_get_mtu(chan)) { + if (l2cap_hdr.len - BLE_L2CAP_SDU_SZ > ble_l2cap_get_mtu(chan)) { /* More data than we expected on the channel. * Disconnect peer with invalid behaviour */ diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c index 90d2a057..21c91ef0 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c @@ -211,7 +211,7 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) sdu_len = get_le16((*om)->om_data); - BLE_HS_LOG(INFO, "First LE frame received %d, SDU len: %d\n", + BLE_HS_LOG(DEBUG, "First LE frame received %d, SDU len: %d\n", om_total, sdu_len + 2); /* We should receive payload of size sdu_len + 2 bytes of sdu_len field */ @@ -298,7 +298,7 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) * However, we still have buffer to for next LE Frame so lets give one more * credit to peer so it can send us full SDU */ - if (rx->credits == 0) { + if (chan->disable_auto_credit_update == false && rx->credits == 0) { /* Remote did not send full SDU. Lets give him one more credits to do * so since we have still buffer to handle it */ @@ -637,7 +637,7 @@ ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx) /* We want to back only that much credits which remote side is missing * to be able to send complete SDU. */ - if (chan->coc_rx.credits < c->initial_credits) { + if (chan->disable_auto_credit_update == false && chan->coc_rx.credits < c->initial_credits) { ble_hs_unlock(); ble_l2cap_sig_le_credits(chan->conn_handle, chan->scid, c->initial_credits - chan->coc_rx.credits); diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_priv.h index 21e6a8bf..08ad3b3e 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_priv.h @@ -55,6 +55,7 @@ extern struct os_mempool ble_l2cap_chan_pool; #define BLE_L2CAP_CID_BLACK_HOLE 0xffff #define BLE_L2CAP_HDR_SZ 4 +#define BLE_L2CAP_SDU_SZ 2 typedef uint8_t ble_l2cap_chan_flags; @@ -91,6 +92,19 @@ struct ble_l2cap_chan { struct ble_l2cap_coc_endpoint coc_rx; struct ble_l2cap_coc_endpoint coc_tx; uint16_t initial_credits; +/** + * Disable automatically sending credits to a remote + * + * This field disables automatically sending extra credit to a + * remote that has exhausted all of its available credits. + * Setting this field to "true" will enable behaviour to + * "not automatically send credits to a peer whose credits are exhausted" + * Setting this field to "false" will enable behaviour to + * "automatically send credits to a peer whose credits are exhausted" + * this behaviour. + * + */ + bool disable_auto_credit_update; ble_l2cap_event_fn *cb; void *cb_arg; #endif @@ -137,6 +151,7 @@ int ble_l2cap_enhanced_connect(uint16_t conn_handle, uint8_t num, struct os_mbuf *sdu_rx[], ble_l2cap_event_fn *cb, void *cb_arg); int ble_l2cap_reconfig(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu); +int ble_l2cap_reconfig_mtu_mps(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu, uint16_t new_mps); #ifdef __cplusplus } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig.c index 42459179..aca61cd0 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig.c @@ -428,6 +428,10 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle, return rc; } + if (OS_MBUF_PKTLEN(*om) != BLE_L2CAP_SIG_UPDATE_REQ_SZ) { + return BLE_HS_EBADDATA; + } + rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags); if (rc != 0) { return rc; @@ -506,6 +510,10 @@ ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle, goto done; } + if (OS_MBUF_PKTLEN(*om) != BLE_L2CAP_SIG_UPDATE_RSP_SZ) { + return BLE_HS_EBADDATA; + } + rsp = (struct ble_l2cap_sig_update_rsp *)(*om)->om_data; switch (le16toh(rsp->result)) { @@ -904,6 +912,10 @@ ble_l2cap_sig_credit_base_reconfig_rsp_rx(uint16_t conn_handle, return rc; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*rsp)) { + return BLE_HS_EBADDATA; + } + rsp = (struct ble_l2cap_sig_credit_base_reconfig_rsp *)(*om)->om_data; ble_l2cap_sig_coc_reconfig_cb(proc, (rsp->result > 0) ? BLE_HS_EREJECT : 0); ble_l2cap_sig_proc_free(proc); @@ -1181,11 +1193,15 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct ble_hs_conn *conn; uint16_t scid; - rc = ble_hs_mbuf_pullup_base(om, sizeof(req)); + rc = ble_hs_mbuf_pullup_base(om, sizeof(*req)); if (rc != 0) { return rc; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*req)) { + return BLE_HS_EBADDATA; + } + rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_RSP, hdr->identifier, sizeof(*rsp), &txom); if (!rsp) { @@ -1300,6 +1316,10 @@ ble_l2cap_sig_coc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, goto done; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*rsp)) { + return BLE_HS_EBADDATA; + } + rsp = (struct ble_l2cap_sig_le_con_rsp *)(*om)->om_data; chan = proc->connect.chan[0]; @@ -1493,7 +1513,7 @@ done: int ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], - uint8_t num, uint16_t new_mtu) + uint8_t num, uint16_t new_mtu, uint16_t new_mps) { struct ble_hs_conn *conn; struct ble_l2cap_sig_proc *proc; @@ -1529,7 +1549,7 @@ ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], proc->op = BLE_L2CAP_SIG_PROC_OP_RECONFIG; proc->reconfig.cid_cnt = num; proc->reconfig.new_mtu = new_mtu; - proc->reconfig.new_mps = MYNEWT_VAL(BLE_L2CAP_COC_MPS); + proc->reconfig.new_mps = new_mps; proc->id = ble_l2cap_sig_next_id(); proc->conn_handle = conn_handle; @@ -1592,6 +1612,10 @@ ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, ble_hs_lock(); conn = ble_hs_conn_find_assert(conn_handle); + if (OS_MBUF_PKTLEN(*om) != sizeof(*req)) { + return BLE_HS_EBADDATA; + } + req = (struct ble_l2cap_sig_disc_req *) (*om)->om_data; /* Let's find matching channel. Note that destination CID in the request @@ -1677,6 +1701,10 @@ ble_l2cap_sig_disc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, goto done; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*rsp)) { + return BLE_HS_EBADDATA; + } + chan = proc->disconnect.chan; if (!chan) { goto done; @@ -1752,6 +1780,10 @@ ble_l2cap_sig_le_credits_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, return 0; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*req)) { + return BLE_HS_EBADDATA; + } + req = (struct ble_l2cap_sig_le_credits *) (*om)->om_data; /* Ignore when peer sends zero credits */ diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig_priv.h b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig_priv.h index a698cd0d..b997ce35 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_sig_priv.h @@ -154,7 +154,7 @@ int ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, uint8_t num, struct os_mbuf *sdu_rx[], ble_l2cap_event_fn *cb, void *cb_arg); int ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], - uint8_t num, uint16_t new_mtu); + uint8_t num, uint16_t new_mtu, uint16_t new_mps); #else static inline int ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, @@ -166,7 +166,7 @@ ble_l2cap_sig_ecoc_connect(uint16_t conn_handle, } static inline int ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], - uint8_t num, uint16_t new_mtu) + uint8_t num, uint16_t new_mtu, uint16_t new_mps) { return BLE_HS_ENOTSUP; } diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm.c index 527cd96d..1ce9be90 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm.c @@ -557,11 +557,12 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) switch (peer_addr.type) { case BLE_ADDR_PUBLIC: case BLE_ADDR_PUBLIC_ID: - conn->bhc_peer_addr.type = BLE_ADDR_PUBLIC_ID; #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) /* In case of Host based privacy, we should not be changing * peer address type to BLE_ADDR_PUBLIC_ID */ conn->bhc_peer_addr.type = BLE_ADDR_PUBLIC; +#else + conn->bhc_peer_addr.type = BLE_ADDR_PUBLIC_ID; #endif break; @@ -974,7 +975,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, &prev); if (proc != NULL) { - if (res->execute) { + if (res && res->execute) { ble_sm_exec(proc, res, res->state_arg); } @@ -993,36 +994,42 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, } } - if (res->sm_err != 0 && tx_fail) { + if (res && (res->sm_err != 0) && tx_fail) { ble_sm_pair_fail_tx(conn_handle, res->sm_err); } ble_hs_unlock(); - if (res->enc_cb && - res->app_status != BLE_HS_ENOTCONN) { - /* Do not send this event on broken connection */ - ble_gap_pairing_complete_event(conn_handle, res->sm_err); - } - if (proc == NULL) { break; } - if (res->app_status == 518 ) { - conn = ble_hs_conn_find(conn_handle); + if (res->app_status == 518 ) { + conn = ble_hs_conn_find(conn_handle); conn_flags = conn->bhc_flags; ble_sm_proc_free(proc); - if (conn_flags & BLE_HS_CONN_F_MASTER) { - ble_sm_pair_initiate(conn_handle); - } - else { - ble_sm_slave_initiate(conn_handle); + if (conn_flags & BLE_HS_CONN_F_MASTER) { + ble_sm_pair_initiate(conn_handle); + } else { + ble_sm_slave_initiate(conn_handle); } - break; + break; + } + + if (res->enc_cb && + res->app_status != BLE_HS_ENOTCONN) { + /* Do not send this event on broken connection */ + ble_gap_pairing_complete_event(conn_handle, res->sm_err); + } + /* Persist keys if bonding has successfully completed. */ + if (res->app_status == 0 && + rm && + proc->flags & BLE_SM_PROC_F_BONDING) { + + ble_sm_persist_keys(proc); } if (res->enc_cb) { @@ -1036,13 +1043,6 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, ble_gap_passkey_event(conn_handle, &res->passkey_params); } - /* Persist keys if bonding has successfully completed. */ - if (res->app_status == 0 && - rm && - proc->flags & BLE_SM_PROC_F_BONDING) { - - ble_sm_persist_keys(proc); - } if (rm) { ble_sm_proc_free(proc); @@ -1838,7 +1838,7 @@ ble_sm_verify_auth_requirements(uint8_t cmd) /* Fail if security level forces MITM protection and remote does not * support it */ - if (MYNEWT_VAL(BLE_SM_LVL) >= 3 && !(cmd & BLE_SM_PAIR_AUTHREQ_MITM)) { + if (ble_hs_cfg.sm_sec_lvl >= 3 && !(cmd & BLE_SM_PAIR_AUTHREQ_MITM)) { return false; } return true; @@ -1922,7 +1922,7 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); - } else if (MYNEWT_VAL(BLE_SM_LVL) == 1) { + } else if (ble_hs_cfg.sm_sec_lvl == 1) { res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); } else if (req->max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN) { @@ -1931,18 +1931,18 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, } else if (req->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); - } else if (MYNEWT_VAL(BLE_SM_SC_ONLY)) { - /* Fail if Secure Connections Only mode is on and remote does not - * meet key size requirements - MITM was checked in last step. - * Fail if SC is not supported by peer or key size is too small + } else if (ble_hs_cfg.sm_sc_only && !(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) { + /* Fail if Secure Connections Only mode is on and SC is not supported by peer */ - if (!(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) { - res->sm_err = BLE_SM_ERR_AUTHREQ; - res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); - } else if (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) { - res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; - res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); - } + res->sm_err = BLE_SM_ERR_AUTHREQ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); + res->enc_cb = 1; + } else if (ble_hs_cfg.sm_sc_only && (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) { + /* Fail if Secure Connections Only mode is on and key size is too small + */ + res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); + res->enc_cb = 1; } else if (!ble_sm_verify_auth_requirements(req->authreq)) { res->sm_err = BLE_SM_ERR_AUTHREQ; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); @@ -2006,7 +2006,7 @@ ble_sm_pair_rsp_rx(uint16_t conn_handle, struct os_mbuf **om, } else if (rsp->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); - } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && (rsp->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) { + } else if (ble_hs_cfg.sm_sc_only && (rsp->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) { /* Fail if Secure Connections Only mode is on and remote does not meet * key size requirements - MITM was checked in last step */ @@ -2651,42 +2651,42 @@ ble_sm_fail_rx(uint16_t conn_handle, struct os_mbuf **om, int ble_sm_incr_our_sign_counter(uint16_t conn_handle) { - struct ble_store_key_sec key_sec; - struct ble_store_value_sec value_sec; - struct ble_gap_conn_desc desc; - int rc; + struct ble_store_key_sec key_sec; + struct ble_store_value_sec value_sec; + struct ble_gap_conn_desc desc; + int rc; - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc != 0) { - return rc; - } + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc != 0) { + return rc; + } - memset(&key_sec, 0, sizeof key_sec); - key_sec.peer_addr = desc.peer_id_addr; + memset(&key_sec, 0, sizeof key_sec); + key_sec.peer_addr = desc.peer_id_addr; - rc = ble_store_read_our_sec(&key_sec, &value_sec); - if (rc != 0) { - return rc; - } - if (value_sec.csrk_present != 1) { - return BLE_HS_ENOENT; - } - if (value_sec.sign_counter == (uint32_t)0xffffffff) { - return BLE_HS_ENOMEM; - } + rc = ble_store_read_our_sec(&key_sec, &value_sec); + if (rc != 0) { + return rc; + } + if (value_sec.csrk_present != 1) { + return BLE_HS_ENOENT; + } + if (value_sec.sign_counter == (uint32_t)0xffffffff) { + return BLE_HS_ENOMEM; + } - rc = ble_store_delete_our_sec(&key_sec); - if (rc != 0) { - return rc; - } + rc = ble_store_delete_our_sec(&key_sec); + if (rc != 0) { + return rc; + } - value_sec.sign_counter += 1; - rc = ble_store_write_our_sec(&value_sec); - if (rc != 0) { - return rc; - } + value_sec.sign_counter += 1; + rc = ble_store_write_our_sec(&value_sec); + if (rc != 0) { + return rc; + } - return 0; + return 0; } /** @@ -2701,42 +2701,48 @@ ble_sm_incr_our_sign_counter(uint16_t conn_handle) int ble_sm_incr_peer_sign_counter(uint16_t conn_handle) { - struct ble_store_key_sec key_sec; - struct ble_store_value_sec value_sec; - struct ble_gap_conn_desc desc; - int rc; - - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc != 0) { - return rc; - } - - memset(&key_sec, 0, sizeof key_sec); - key_sec.peer_addr = desc.peer_id_addr; - - rc = ble_store_read_peer_sec(&key_sec, &value_sec); - if (rc != 0) { - return rc; - } - if (value_sec.csrk_present != 1) { - return BLE_HS_ENOENT; - } - if (value_sec.sign_counter == (uint32_t)0xffffffff) { - return BLE_HS_ENOMEM; - } - - rc = ble_store_delete_peer_sec(&key_sec); - if (rc != 0) { - return rc; - } - - value_sec.sign_counter += 1; - rc = ble_store_write_peer_sec(&value_sec); - if (rc != 0) { - return rc; - } - - return 0; + struct ble_store_key_sec key_sec; + struct ble_store_value_sec value_sec; + struct ble_gap_conn_desc desc; + int rc; + + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc != 0) { + return rc; + } + + memset(&key_sec, 0, sizeof key_sec); + key_sec.peer_addr = desc.peer_id_addr; + + rc = ble_store_read_peer_sec(&key_sec, &value_sec); + if (rc != 0) { + return rc; + } + if (value_sec.csrk_present != 1) { + return BLE_HS_ENOENT; + } + if (value_sec.sign_counter == (uint32_t)0xffffffff) { + return BLE_HS_ENOMEM; + } + + rc = ble_store_delete_peer_sec(&key_sec); + if (rc != 0) { + return rc; + } + + if (value_sec.irk_present == 1) { + ble_hs_pvcy_remove_entry(value_sec.peer_addr.type, value_sec.peer_addr.val); + // No need to check if the above command fails or passes + // Proceed with trying to write the new sign counter + } + + value_sec.sign_counter += 1; + rc = ble_store_write_peer_sec(&value_sec); + if (rc != 0) { + return rc; + } + + return 0; } /** diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_alg.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_alg.c index e0dc71c5..6e1533a5 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_alg.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_alg.c @@ -32,14 +32,12 @@ #if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) #include "mbedtls/aes.h" -#if MYNEWT_VAL(BLE_SM_SC) #include "mbedtls/cipher.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/cmac.h" #include "mbedtls/ecdh.h" #include "mbedtls/ecp.h" -#endif #else #include "tinycrypt/aes.h" @@ -240,16 +238,6 @@ done: return rc; } -#if MYNEWT_VAL(BLE_SM_SC) - -static void -ble_sm_alg_log_buf(const char *name, const uint8_t *buf, int len) -{ - BLE_HS_LOG(DEBUG, " %s=", name); - ble_hs_log_flat_buf(buf, len); - BLE_HS_LOG(DEBUG, "\n"); -} - /** * Cypher based Message Authentication Code (CMAC) with AES 128 bit * @@ -321,6 +309,16 @@ ble_sm_alg_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, } #endif +#if MYNEWT_VAL(BLE_SM_SC) + +static void +ble_sm_alg_log_buf(const char *name, const uint8_t *buf, int len) +{ + BLE_HS_LOG(DEBUG, " %s=", name); + ble_hs_log_flat_buf(buf, len); + BLE_HS_LOG(DEBUG, "\n"); +} + int ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, uint8_t z, uint8_t *out_enc_data) @@ -598,11 +596,11 @@ exit: } #else - if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { + if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { return BLE_HS_EUNKNOWN; } - rc = uECC_shared_secret(pk, priv, dh, &curve_secp256r1); + rc = uECC_shared_secret(pk, priv, dh, uECC_secp256r1()); if (rc == TC_CRYPTO_FAIL) { return BLE_HS_EUNKNOWN; } @@ -711,7 +709,7 @@ ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) return BLE_HS_EUNKNOWN; } #else - if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { + if (uECC_make_key(pk, priv, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { return BLE_HS_EUNKNOWN; } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_cmd.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_cmd.c index b84df1ec..a740dc3a 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_cmd.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_sm_cmd.c @@ -29,18 +29,20 @@ void * ble_sm_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom) { struct ble_sm_hdr *hdr; + void *data; *txom = ble_hs_mbuf_l2cap_pkt(); if (*txom == NULL) { return NULL; } - if (os_mbuf_extend(*txom, sizeof(*hdr) + len) == NULL) { + data = os_mbuf_extend(*txom, sizeof(*hdr) + len); + if (data == NULL) { os_mbuf_free_chain(*txom); return NULL; } - hdr = (struct ble_sm_hdr *)(*txom)->om_data; + hdr = (struct ble_sm_hdr *)data; hdr->opcode = opcode; diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_store.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_store.c index d1cabfac..a407cd8f 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_store.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_store.c @@ -285,6 +285,42 @@ ble_store_delete_cccd(const struct ble_store_key_cccd *key) return rc; } +int +ble_store_read_csfc(const struct ble_store_key_csfc *key, + struct ble_store_value_csfc *out_value) +{ + union ble_store_value *store_value; + union ble_store_key *store_key; + int rc; + + store_key = (void *)key; + store_value = (void *)out_value; + rc = ble_store_read(BLE_STORE_OBJ_TYPE_CSFC, store_key, store_value); + return rc; +} + +int +ble_store_write_csfc(const struct ble_store_value_csfc *value) +{ + union ble_store_value *store_value; + int rc; + + store_value = (void *)value; + rc = ble_store_write(BLE_STORE_OBJ_TYPE_CSFC, store_value); + return rc; +} + +int +ble_store_delete_csfc(const struct ble_store_key_csfc *key) +{ + union ble_store_key *store_key; + int rc; + + store_key = (void *)key; + rc = ble_store_delete(BLE_STORE_OBJ_TYPE_CSFC, store_key); + return rc; +} + void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, const struct ble_store_value_cccd *value) @@ -436,6 +472,14 @@ ble_store_key_from_value_rpa_rec(struct ble_store_key_rpa_rec *out_key, out_key->idx = 0; } +void +ble_store_key_from_value_csfc(struct ble_store_key_csfc *out_key, + const struct ble_store_value_csfc *value) +{ + out_key->peer_addr = value->peer_addr; + out_key->idx = 0; +} + void ble_store_key_from_value(int obj_type, union ble_store_key *out_key, @@ -456,12 +500,17 @@ ble_store_key_from_value(int obj_type, break; #endif case BLE_STORE_OBJ_TYPE_PEER_ADDR: - ble_store_key_from_value_rpa_rec(&out_key->rpa_rec, &value->rpa_rec); - break; + ble_store_key_from_value_rpa_rec(&out_key->rpa_rec, &value->rpa_rec); + break; - case BLE_STORE_OBJ_TYPE_LOCAL_IRK: + case BLE_STORE_OBJ_TYPE_LOCAL_IRK: ble_store_key_from_value_local_irk(&out_key->local_irk, &value->local_irk); - break; + break; + + case BLE_STORE_OBJ_TYPE_CSFC: + ble_store_key_from_value_csfc(&out_key->csfc, &value->csfc); + break; + default: BLE_HS_DBG_ASSERT(0); @@ -506,6 +555,10 @@ ble_store_iterate(int obj_type, key.local_irk.addr = *BLE_ADDR_ANY; pidx = &key.local_irk.idx; break; + case BLE_STORE_OBJ_TYPE_CSFC: + key.csfc.peer_addr = *BLE_ADDR_ANY; + pidx = &key.csfc.idx; + break; default: BLE_HS_DBG_ASSERT(0); return BLE_HS_EINVAL; @@ -550,6 +603,7 @@ ble_store_clear(void) BLE_STORE_OBJ_TYPE_OUR_SEC, BLE_STORE_OBJ_TYPE_PEER_SEC, BLE_STORE_OBJ_TYPE_CCCD, + BLE_STORE_OBJ_TYPE_CSFC, BLE_STORE_OBJ_TYPE_PEER_ADDR, BLE_STORE_OBJ_TYPE_LOCAL_IRK, #if MYNEWT_VAL(ENC_ADV_DATA) diff --git a/lib/bt/host/nimble/nimble/nimble/host/src/ble_store_util.c b/lib/bt/host/nimble/nimble/nimble/host/src/ble_store_util.c index b1227755..837b8c8c 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/src/ble_store_util.c +++ b/lib/bt/host/nimble/nimble/nimble/host/src/ble_store_util.c @@ -154,6 +154,14 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) return rc; } + memset(&key, 0, sizeof key); + key.csfc.peer_addr = *peer_id_addr; + + rc = ble_store_util_delete_all(BLE_STORE_OBJ_TYPE_CSFC, &key); + if (rc != 0) { + return rc; + } + #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) struct ble_hs_dev_records *peer_rec = ble_rpa_find_peer_dev_rec(key.sec.peer_addr.val); @@ -346,6 +354,7 @@ ble_store_util_status_rr(struct ble_store_status_event *event, void *arg) case BLE_STORE_OBJ_TYPE_PEER_ADDR: return ble_gap_unpair_oldest_peer(); case BLE_STORE_OBJ_TYPE_CCCD: + case BLE_STORE_OBJ_TYPE_CSFC: /* Try unpairing oldest peer except current peer */ return ble_gap_unpair_oldest_except(&event->overflow.value->cccd.peer_addr); #if MYNEWT_VAL(ENC_ADV_DATA) diff --git a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c index 770edfb0..cab63634 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c +++ b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c @@ -49,6 +49,12 @@ struct ble_store_value_cccd int ble_store_config_num_cccds; +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) +struct ble_store_value_csfc + ble_store_config_csfcs[MYNEWT_VAL(BLE_STORE_MAX_CSFCS)]; +#endif +int ble_store_config_num_csfcs; + #if MYNEWT_VAL(ENC_ADV_DATA) struct ble_store_value_ead ble_store_config_eads[MYNEWT_VAL(BLE_STORE_MAX_EADS)]; @@ -302,7 +308,6 @@ ble_store_config_write_our_sec(const struct ble_store_value_sec *value_sec) } -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_config_delete_obj(void *values, int value_size, int idx, int *num_values) @@ -324,6 +329,7 @@ ble_store_config_delete_obj(void *values, int value_size, int idx, return 0; } +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_config_delete_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_secs, @@ -693,6 +699,7 @@ ble_store_config_write_ead(const struct ble_store_value_ead *value_ead) static int ble_store_config_find_local_irk(const struct ble_store_key_local_irk *key) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_value_local_irk *local_irk; int skipped; int i; @@ -714,7 +721,7 @@ ble_store_config_find_local_irk(const struct ble_store_key_local_irk *key) return i; } - +#endif return -1; } @@ -763,6 +770,7 @@ ble_store_config_read_local_irk(const struct ble_store_key_local_irk *key_irk, static int ble_store_config_write_local_irk(const struct ble_store_value_local_irk *value_irk) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_key_local_irk key_irk; int idx; int rc; @@ -789,6 +797,9 @@ ble_store_config_write_local_irk(const struct ble_store_value_local_irk *value_i } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } @@ -872,6 +883,7 @@ ble_store_config_write_rpa_rec(const struct ble_store_value_rpa_rec *value_rpa_r static int ble_store_config_delete_rpa_rec(const struct ble_store_key_rpa_rec *key_rpa_rec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int idx; int rc; @@ -894,6 +906,127 @@ ble_store_config_delete_rpa_rec(const struct ble_store_key_rpa_rec *key_rpa_rec) } return 0; +#else + return BLE_HS_ENOENT; +#endif +} + +/***************************************************************************** + * $csfc * + *****************************************************************************/ + +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) +static int +ble_store_config_find_csfc(const struct ble_store_key_csfc *key, + const struct ble_store_value_csfc *value_csfc, + int num_value_csfc) +{ + const struct ble_store_value_csfc *cur; + int i; + + if (!ble_addr_cmp(&key->peer_addr, BLE_ADDR_ANY)) { + if (key->idx < num_value_csfc) { + return key->idx; + } + } else if (key->idx == 0) { + for (i = 0; i < num_value_csfc; i++) { + cur = &value_csfc[i]; + + if (!ble_addr_cmp(&cur->peer_addr, &key->peer_addr)) { + return i; + } + } + } + + return -1; +} +#endif + +static int +ble_store_config_delete_csfc(const struct ble_store_key_csfc *key_csfc) +{ +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + int idx; + int rc; + + idx = ble_store_config_find_csfc(key_csfc, ble_store_config_csfcs, + ble_store_config_num_csfcs); + if (idx == -1) { + return BLE_HS_ENOENT; + } + + rc = ble_store_config_delete_obj(ble_store_config_csfcs, + sizeof *ble_store_config_csfcs, + idx, &ble_store_config_num_csfcs); + + if (rc != 0) { + return rc; + } + + rc = ble_store_config_persist_csfcs(); + if (rc != 0) { + return rc; + } + + return 0; +#else + return BLE_HS_ENOENT; +#endif +} + +static int +ble_store_config_read_csfc(const struct ble_store_key_csfc *key_csfc, + struct ble_store_value_csfc *value_csfc) +{ +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + int idx; + + idx = ble_store_config_find_csfc(key_csfc, ble_store_config_csfcs, + ble_store_config_num_csfcs); + if (idx == -1) { + return BLE_HS_ENOENT; + } + + *value_csfc = ble_store_config_csfcs[idx]; + return 0; +#else + return BLE_HS_ENOENT; +#endif +} + +static int +ble_store_config_write_csfc(const struct ble_store_value_csfc *value_csfc) +{ +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + struct ble_store_key_csfc key_csfc; + int idx; + int rc; + + ble_store_key_from_value_csfc(&key_csfc, value_csfc); + idx = ble_store_config_find_csfc(&key_csfc, ble_store_config_csfcs, + ble_store_config_num_csfcs); + if (idx == -1) { + if (ble_store_config_num_csfcs >= MYNEWT_VAL(BLE_STORE_MAX_CSFCS)) { + BLE_HS_LOG(DEBUG, "error persisting csfc; too many entries (%d)\n", + ble_store_config_num_csfcs); + return BLE_HS_ESTORE_CAP; + } + + idx = ble_store_config_num_csfcs; + ble_store_config_num_csfcs++; + } + + ble_store_config_csfcs[idx] = *value_csfc; + + rc = ble_store_config_persist_csfcs(); + if (rc != 0) { + return rc; + } + + return 0; +#else + return BLE_HS_ENOENT; +#endif } /***************************************************************************** @@ -938,6 +1071,10 @@ ble_store_config_read(int obj_type, const union ble_store_key *key, rc = ble_store_config_read_cccd(&key->cccd, &value->cccd); return rc; + case BLE_STORE_OBJ_TYPE_CSFC: + rc = ble_store_config_read_csfc(&key->csfc, &value->csfc); + return rc; + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_STORE_OBJ_TYPE_ENC_ADV_DATA: rc = ble_store_config_read_ead(&key->ead, &value->ead); @@ -979,6 +1116,10 @@ ble_store_config_write(int obj_type, const union ble_store_value *val) rc = ble_store_config_write_cccd(&val->cccd); return rc; + case BLE_STORE_OBJ_TYPE_CSFC: + rc = ble_store_config_write_csfc(&val->csfc); + return rc; + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_STORE_OBJ_TYPE_ENC_ADV_DATA: rc = ble_store_config_write_ead(&val->ead); @@ -1015,6 +1156,10 @@ ble_store_config_delete(int obj_type, const union ble_store_key *key) rc = ble_store_config_delete_cccd(&key->cccd); return rc; + case BLE_STORE_OBJ_TYPE_CSFC: + rc = ble_store_config_delete_csfc(&key->csfc); + return rc; + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_STORE_OBJ_TYPE_ENC_ADV_DATA: rc = ble_store_config_delete_ead(&key->ead); @@ -1047,6 +1192,7 @@ ble_store_config_init(void) ble_store_config_num_our_secs = 0; ble_store_config_num_peer_secs = 0; ble_store_config_num_cccds = 0; + ble_store_config_num_csfcs = 0; #if MYNEWT_VAL(ENC_ADV_DATA) ble_store_config_num_eads = 0; #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_conf.c b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_conf.c index 1300bc16..8d2d9051 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_conf.c +++ b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_conf.c @@ -57,6 +57,12 @@ static struct conf_handler ble_store_config_conf_handler = { #define BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ \ (MYNEWT_VAL(BLE_STORE_MAX_CCCDS) * BLE_STORE_CONFIG_CCCD_ENCODE_SZ + 1) +#define BLE_STORE_CONFIG_CSFC_ENCODE_SZ \ + BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_csfc)) + +#define BLE_STORE_CONFIG_CSFC_SET_ENCODE_SZ \ + (MYNEWT_VAL(BLE_STORE_MAX_CSFCS) * BLE_STORE_CONFIG_CSFC_ENCODE_SZ + 1) + #if MYNEWT_VAL(ENC_ADV_DATA) #define BLE_STORE_CONFIG_EAD_ENCODE_SZ \ BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_ead)) @@ -127,6 +133,13 @@ ble_store_config_conf_set(int argc, char **argv, char *val) sizeof *ble_store_config_cccds, &ble_store_config_num_cccds); return rc; + } else if (strcmp(argv[0], "csfc") == 0) { + rc = ble_store_config_deserialize_arr( + val, + ble_store_config_csfcs, + sizeof *ble_store_config_csfcs, + &&ble_store_config_num_csfcs); + return rc; } #if MYNEWT_VAL(ENC_ADV_DATA) else if (strcmp(argv[0], "ead") == 0) { @@ -181,6 +194,13 @@ ble_store_config_conf_export(void (*func)(char *name, char *val), sizeof buf.cccd); func("ble_hs/cccd", buf.cccd); + ble_store_config_serialize_arr(ble_store_config_csfcs, + sizeof *ble_store_config_csfcs, + ble_store_config_num_csfcs, + buf.csfc, + sizeof buf.csfc); + func("ble_hs/csfc", buf.csfc); + #if MYNEWT_VAL(ENC_ADV_DATA) ble_store_config_serialize_arr(ble_store_config_eads, sizeof *ble_store_config_eads, @@ -264,6 +284,25 @@ ble_store_config_persist_cccds(void) return 0; } +int +ble_store_config_persist_csfcs(void) +{ + char buf[BLE_STORE_CONFIG_CSFC_SET_ENCODE_SZ]; + int rc; + + ble_store_config_serialize_arr(ble_store_config_csfcs, + sizeof *ble_store_config_csfcs, + ble_store_config_num_csfcs, + buf, + sizeof buf); + rc = conf_save_one("ble_hs/csfc", buf); + if (rc != 0) { + return BLE_HS_ESTORE_FAIL; + } + + return 0; +} + #if MYNEWT_VAL(ENC_ADV_DATA) int ble_store_config_persist_eads(void) diff --git a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_priv.h b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_priv.h index 581cefdc..a3dcc6aa 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_priv.h +++ b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_config_priv.h @@ -36,6 +36,10 @@ extern struct ble_store_value_cccd ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; extern int ble_store_config_num_cccds; +extern struct ble_store_value_csfc + ble_store_config_csfcs[MYNEWT_VAL(BLE_STORE_MAX_CSFCS)]; +extern int ble_store_config_num_csfcs; + #if MYNEWT_VAL(ENC_ADV_DATA) extern struct ble_store_value_ead ble_store_config_eads[MYNEWT_VAL(BLE_STORE_MAX_EADS)]; @@ -56,6 +60,7 @@ extern int ble_store_config_num_local_irks; int ble_store_config_persist_our_secs(void); int ble_store_config_persist_peer_secs(void); int ble_store_config_persist_cccds(void); +int ble_store_config_persist_csfcs(void); #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int ble_restore_our_sec_nvs(void); int ble_restore_peer_sec_nvs(void); @@ -72,6 +77,7 @@ void ble_store_config_conf_init(void); static inline int ble_store_config_persist_our_secs(void) { return 0; } static inline int ble_store_config_persist_peer_secs(void) { return 0; } static inline int ble_store_config_persist_cccds(void) { return 0; } +static inline int ble_store_config_persist_csfcs(void) { return 0; } #if MYNEWT_VAL(ENC_ADV_DATA) static inline int ble_store_config_persist_eads(void) { return 0; } #endif diff --git a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c index 8ae391e4..4b0ade85 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c +++ b/lib/bt/host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c @@ -39,6 +39,7 @@ #define NIMBLE_NVS_PEER_SEC_KEY "peer_sec" #define NIMBLE_NVS_OUR_SEC_KEY "our_sec" #define NIMBLE_NVS_CCCD_SEC_KEY "cccd_sec" +#define NIMBLE_NVS_CSFC_SEC_KEY "csfc_sec" #define NIMBLE_NVS_PEER_RECORDS_KEY "p_dev_rec" #define NIMBLE_NVS_NAMESPACE "nimble_bond" @@ -66,7 +67,7 @@ get_nvs_key_string(int obj_type, int index, char *key_string) } else if (obj_type == BLE_STORE_OBJ_TYPE_OUR_SEC) { sprintf(key_string, "%s_%d", NIMBLE_NVS_OUR_SEC_KEY, index); #if MYNEWT_VAL(ENC_ADV_DATA) - } else if (obj_type == NIMBLE_NVS_EAD_SEC_KEY) { + } else if (obj_type == BLE_STORE_OBJ_TYPE_ENC_ADV_DATA) { sprintf(key_string, "%s_%d", NIMBLE_NVS_EAD_SEC_KEY, index); #endif } else if (obj_type == BLE_STORE_OBJ_TYPE_LOCAL_IRK) { @@ -74,8 +75,10 @@ get_nvs_key_string(int obj_type, int index, char *key_string) } else if (obj_type == BLE_STORE_OBJ_TYPE_PEER_ADDR){ sprintf(key_string, "%s_%d", NIMBLE_NVS_RPA_RECORDS_KEY, index); - }else { + } else if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { sprintf(key_string, "%s_%d", NIMBLE_NVS_CCCD_SEC_KEY, index); + } else { + sprintf(key_string, "%s_%d", NIMBLE_NVS_CSFC_SEC_KEY, index); } } } @@ -110,8 +113,10 @@ get_nvs_max_obj_value(int obj_type) } else { if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { return MYNEWT_VAL(BLE_STORE_MAX_CCCDS); + } else if (obj_type == BLE_STORE_OBJ_TYPE_CSFC) { + return MYNEWT_VAL(BLE_STORE_MAX_CSFCS); #if MYNEWT_VAL(ENC_ADV_DATA) - } else if (obj_type == BLE_STORE_OBJ_TYPE_EAD) { + } else if (obj_type == BLE_STORE_OBJ_TYPE_ENC_ADV_DATA) { return MYNEWT_VAL(BLE_STORE_MAX_EADS); #endif } else { @@ -176,8 +181,11 @@ get_nvs_db_value(int obj_type, char *key_string, union ble_store_value *val) if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { err = nvs_get_blob(nimble_handle, key_string, &val->cccd, &required_size); + } else if (obj_type == BLE_STORE_OBJ_TYPE_CSFC) { + err = nvs_get_blob(nimble_handle, key_string, &val->csfc, + &required_size); #if MYNEWT_VAL(ENC_ADV_DATA) - } else if (obj_type == BLE_STORE_OBJ_TYPE_EAD) { + } else if (obj_type == BLE_STORE_OBJ_TYPE_ENC_ADV_DATA) { err = nvs_get_blob(nimble_handle, key_string, &val->ead, &required_size); #endif @@ -255,8 +263,11 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value) if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { err = get_nvs_matching_index(&cur.sec, value, num_value, sizeof(struct ble_store_value_cccd)); + } else if (obj_type == BLE_STORE_OBJ_TYPE_CSFC) { + err = get_nvs_matching_index(&cur.csfc, value, num_value, + sizeof(struct ble_store_value_csfc)); #if MYNEWT_VAL(ENC_ADV_DATA) - } else if (obj_type == BLE_STORE_OBJ_TYPE_EAD) { + } else if (obj_type == BLE_STORE_OBJ_TYPE_ENC_ADV_DATA) { err = get_nvs_matching_index(&cur.sec, value, num_value, sizeof(struct ble_store_value_ead)); #endif @@ -392,8 +403,11 @@ ble_store_nvs_write(int obj_type, const union ble_store_value *val) if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { return ble_nvs_write_key_value(key_string, &val->cccd, sizeof(struct ble_store_value_cccd)); + } else if (obj_type == BLE_STORE_OBJ_TYPE_CSFC) { + return ble_nvs_write_key_value(key_string, &val->csfc, sizeof(struct + ble_store_value_csfc)); #if MYNEWT_VAL(ENC_ADV_DATA) - } else if (obj_type == BLE_STORE_OBJ_TYPE_EAD) { + } else if (obj_type == BLE_STORE_OBJ_TYPE_ENC_ADV_DATA) { return ble_nvs_write_key_value(key_string, &val->ead, sizeof(struct ble_store_value_ead)); #endif @@ -489,8 +503,13 @@ populate_db_from_nvs(int obj_type, void *dst, int *db_num) memcpy(db_item, &cur.cccd, sizeof(struct ble_store_value_cccd)); db_item += sizeof(struct ble_store_value_cccd); (*db_num)++; + } else if (obj_type == BLE_STORE_OBJ_TYPE_CSFC) { + ESP_LOGD(TAG, "CSFC in RAM is filled up from NVS index = %d", i); + memcpy(db_item, &cur.csfc, sizeof(struct ble_store_value_csfc)); + db_item += sizeof(struct ble_store_value_csfc); + (*db_num)++; #if MYNEWT_VAL(ENC_ADV_DATA) - } if (obj_type == BLE_STORE_OBJ_TYPE_EAD) { + } else if (obj_type == BLE_STORE_OBJ_TYPE_ENC_ADV_DATA) { ESP_LOGD(TAG, "EAD in RAM is filled up from NVS index = %d", i); memcpy(db_item, &cur.ead, sizeof(struct ble_store_value_ead)); db_item += sizeof(struct ble_store_value_ead); @@ -581,8 +600,19 @@ ble_nvs_restore_sec_keys(void) ble_store_config_num_cccds); #endif +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_CSFC, ble_store_config_csfcs, + &ble_store_config_num_csfcs); + if (err != ESP_OK) { + ESP_LOGE(TAG, "NVS operation failed for 'CSFC'"); + return err; + } + ESP_LOGD(TAG, "ble_store_config_csfcs restored %d bonds", + ble_store_config_num_csfcs); +#endif + #if MYNEWT_VAL(ENC_ADV_DATA) - err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_EAD, ble_store_config_eads, + err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, ble_store_config_eads, &ble_store_config_num_eads); if (err != ESP_OK) { ESP_LOGE(TAG, "NVS operation failed for 'EAD'"); @@ -667,6 +697,38 @@ int ble_store_config_persist_cccds(void) } #endif +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) +int ble_store_config_persist_csfcs(void) +{ + int nvs_count, nvs_idx; + union ble_store_value val; + + nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_CSFC, 0, NULL, 0); + if (nvs_count == -1) { + ESP_LOGE(TAG, "NVS operation failed while persisting CSFC"); + return BLE_HS_ESTORE_FAIL; + } + + if (nvs_count < ble_store_config_num_csfcs) { + /* NVS db count less than RAM count, write operation */ + ESP_LOGD(TAG, "Persisting CSFC value in NVS..."); + val.csfc = ble_store_config_csfcs[ble_store_config_num_csfcs - 1]; + return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_CSFC, &val); + } else if (nvs_count > ble_store_config_num_csfcs) { + /* NVS db count more than RAM count, delete operation */ + nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_CSFC, 0, + ble_store_config_csfcs, ble_store_config_num_csfcs); + if (nvs_idx == -1) { + ESP_LOGE(TAG, "NVS delete operation failed for CSFC"); + return BLE_HS_ESTORE_FAIL; + } + ESP_LOGD(TAG, "Deleting CSFC, nvs idx = %d", nvs_idx); + return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_CSFC, nvs_idx); + } + return 0; +} +#endif + #if MYNEWT_VAL(ENC_ADV_DATA) int ble_store_config_persist_eads(void) { @@ -693,7 +755,7 @@ int ble_store_config_persist_eads(void) return BLE_HS_ESTORE_FAIL; } ESP_LOGD(TAG, "Deleting EAD, nvs idx = %d", nvs_idx); - return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_EAD, nvs_idx); + return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, nvs_idx); } return 0; } diff --git a/lib/bt/host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c b/lib/bt/host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c index d587b8ac..2d7c3af1 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c +++ b/lib/bt/host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c @@ -27,7 +27,6 @@ * use the store/config package. For a RAM-only BLE store, * use store/config and set BLE_STORE_CONFIG_PERSIST to 0. */ - #include #include @@ -36,6 +35,7 @@ #include "host/ble_hs.h" #include "store/ram/ble_store_ram.h" +#if !MYNEWT_VAL(BLE_USED_IN_IDF) #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static struct ble_store_value_sec ble_store_ram_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; @@ -57,6 +57,13 @@ static struct ble_store_value_cccd static int ble_store_ram_num_cccds; +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) +static struct ble_store_value_csfc + ble_store_ram_csfcs[MYNEWT_VAL(BLE_STORE_MAX_CSFCS)]; +#endif + +static int ble_store_ram_num_csfcs; + #if MYNEWT_VAL(ENC_ADV_DATA) static struct ble_store_value_ead ble_store_ram_eads[MYNEWT_VAL(BLE_STORE_MAX_EADS)]; @@ -184,7 +191,7 @@ ble_store_ram_write_our_sec(const struct ble_store_value_sec *value_sec) } -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) || MYNEWT_VAL(BLE_STORE_MAX_CCCDS) static int ble_store_ram_delete_obj(void *values, int value_size, int idx, int *num_values) @@ -205,7 +212,9 @@ ble_store_ram_delete_obj(void *values, int value_size, int idx, return 0; } +#endif +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_ram_delete_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_secs, @@ -432,6 +441,111 @@ ble_store_ram_write_cccd(const struct ble_store_value_cccd *value_cccd) } +/***************************************************************************** + * $csfc * + *****************************************************************************/ + +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) +static int +ble_store_ram_find_csfc(const struct ble_store_key_csfc *key) +{ + struct ble_store_value_csfc *csfc; + int skipped; + int i; + + skipped = 0; + for (i = 0; i < ble_store_ram_num_csfcs; i++) { + csfc = ble_store_ram_csfcs + i; + + if (ble_addr_cmp(&key->peer_addr, BLE_ADDR_ANY)) { + if (ble_addr_cmp(&csfc->peer_addr, &key->peer_addr)) { + continue; + } + } + + if (key->idx > skipped) { + skipped++; + continue; + } + + return i; + } + + return -1; +} +#endif + +static int +ble_store_ram_delete_csfc(const struct ble_store_key_csfc *key_csfc) +{ +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + int idx; + int rc; + + idx = ble_store_ram_find_csfc(key_csfc); + if (idx == -1) { + return BLE_HS_ENOENT; + } + + rc = ble_store_ram_delete_obj(ble_store_ram_csfcs, + sizeof *ble_store_ram_csfcs, + idx, + &ble_store_ram_num_csfcs); + if (rc != 0) { + return rc; + } + return 0; +#else + return BLE_HS_ENOENT; +#endif +} + +static int +ble_store_ram_read_csfc(const struct ble_store_key_csfc *key_csfc, + struct ble_store_value_csfc *value_csfc) +{ +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + int idx; + + idx = ble_store_ram_find_csfc(key_csfc); + if (idx == -1) { + return BLE_HS_ENOENT; + } + + *value_csfc = ble_store_ram_csfcs[idx]; + + return 0; +#else + return BLE_HS_ENOENT; +#endif +} + +static int +ble_store_ram_write_csfc(const struct ble_store_value_csfc *value_csfc) +{ +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + struct ble_store_key_csfc key_csfc; + int idx; + + ble_store_key_from_value_csfc(&key_csfc, value_csfc); + idx = ble_store_ram_find_csfc(&key_csfc); + if (idx == -1) { + if (ble_store_ram_num_csfcs >= MYNEWT_VAL(BLE_STORE_MAX_CSFCS)) { + BLE_HS_LOG(DEBUG, "error persisting csfc; too many entries (%d)\n", + ble_store_ram_num_csfcs); + return BLE_HS_ESTORE_CAP; + } + + idx = ble_store_ram_num_csfcs; + ble_store_ram_num_csfcs++; + } + + ble_store_ram_csfcs[idx] = *value_csfc; + return 0; +#else + return BLE_HS_ENOENT; +#endif +} /***************************************************************************** * $ead * @@ -567,6 +681,10 @@ ble_store_ram_read(int obj_type, const union ble_store_key *key, rc = ble_store_ram_read_cccd(&key->cccd, &value->cccd); return rc; + case BLE_STORE_OBJ_TYPE_CSFC: + rc = ble_store_ram_read_csfc(&key->csfc, &value->csfc); + return rc; + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_STORE_OBJ_TYPE_ENC_ADV_DATA: rc = ble_store_ram_read_ead(&key->ead, &value->ead); @@ -602,6 +720,10 @@ ble_store_ram_write(int obj_type, const union ble_store_value *val) rc = ble_store_ram_write_cccd(&val->cccd); return rc; + case BLE_STORE_OBJ_TYPE_CSFC: + rc = ble_store_ram_write_csfc(&val->csfc); + return rc; + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_STORE_OBJ_TYPE_ENC_ADV_DATA: rc = ble_store_ram_write_ead(&val->ead); @@ -631,6 +753,10 @@ ble_store_ram_delete(int obj_type, const union ble_store_key *key) rc = ble_store_ram_delete_cccd(&key->cccd); return rc; + case BLE_STORE_OBJ_TYPE_CSFC: + rc = ble_store_ram_delete_csfc(&key->csfc); + return rc; + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_STORE_OBJ_TYPE_ENC_ADV_DATA: rc = ble_store_ram_delete_ead(&key->ead); @@ -656,7 +782,9 @@ ble_store_ram_init(void) ble_store_ram_num_our_secs = 0; ble_store_ram_num_peer_secs = 0; ble_store_ram_num_cccds = 0; + ble_store_ram_num_csfcs = 0; #if MYNEWT_VAL(ENC_ADV_DATA) ble_store_ram_num_eads = 0; #endif } +#endif //Not used in IDF diff --git a/lib/bt/host/nimble/nimble/nimble/host/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/host/syscfg.yml index eb1abdf4..6694ee4c 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/syscfg.yml +++ b/lib/bt/host/nimble/nimble/nimble/host/syscfg.yml @@ -277,6 +277,10 @@ syscfg.defs: description: > Enables sending and receiving of GATT indications. (0/1) value: 1 + BLE_GATT_NOTIFY_MULTIPLE: + description: > + Enables sending and receiving of GATT multi handle notifications. + value: 1 # GATT options. BLE_GATT_READ_MAX_ATTRS: @@ -299,6 +303,22 @@ syscfg.defs: due to memory exhaustion. (0/1) Units are milliseconds. (0/1) value: 1000 + # Enhanced ATT bearer options + BLE_EATT_CHAN_NUM: + description: > + Maximum number of supported EATT channels (in total). If set to 0 + EATT support it disabled. + value: 0 + restrictions: + - BLE_GATT_NOTIFY_MULTIPLE + - BLE_L2CAP_ENHANCED_COC + - 'BLE_L2CAP_COC_MAX_NUM >= BLE_EATT_CHAN_NUM' + + BLE_EATT_MTU: + description: > + MTU used for EATT channels. + value: 128 + # Supported server ATT commands. (0/1) BLE_ATT_SVR_FIND_INFO: description: > @@ -357,6 +377,12 @@ syscfg.defs: Enables processing of incoming Handle Value Notification ATT commands. (0/1) value: 1 + BLE_ATT_SVR_NOTIFY_MULTI: + description: > + Enables processing of incoming Multi Handle Value Notification ATT + commands. (0/1) + value: MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52) + BLE_ATT_SVR_INDICATE: description: > Enables processing of incoming Handle Value Indication ATT @@ -467,11 +493,22 @@ syscfg.defs: description: 'Minimum level for the BLE host log.' value: 1 + BLE_EATT_LOG_MOD: + description: 'Numeric module ID to use for BLE EATT log messages.' + value: 27 + BLE_EATT_LOG_LVL: + description: 'Minimum level for the BLE EATT log.' + value: 1 + syscfg.logs: BLE_HS_LOG: module: MYNEWT_VAL(BLE_HS_LOG_MOD) level: MYNEWT_VAL(BLE_HS_LOG_LVL) + BLE_EATT_LOG: + module: MYNEWT_VAL(BLE_EATT_LOG_MOD) + level: MYNEWT_VAL(BLE_EATT_LOG_LVL) + syscfg.vals.BLE_MESH: BLE_SM_SC: 1 diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_clt_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_clt_test.c index 0b6d55d3..35d2e235 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_clt_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_clt_test.c @@ -67,9 +67,9 @@ ble_att_clt_test_tx_write_req_or_cmd(uint16_t conn_handle, uint16_t handle, om = ble_hs_test_util_om_from_flat(value, value_len); if (is_req) { - rc = ble_att_clt_tx_write_req(conn_handle, handle, om); + rc = ble_att_clt_tx_write_req(conn_handle, BLE_L2CAP_CID_ATT, handle, om); } else { - rc = ble_att_clt_tx_write_cmd(conn_handle, handle, om); + rc = ble_att_clt_tx_write_cmd(conn_handle, BLE_L2CAP_CID_ATT, handle, om); } TEST_ASSERT(rc == 0); } @@ -78,25 +78,35 @@ TEST_CASE_SELF(ble_att_clt_test_tx_find_info) { uint16_t conn_handle; int rc; + struct ble_hs_conn *conn; ble_hs_test_util_assert_mbufs_freed(NULL); conn_handle = ble_att_clt_test_misc_init(); + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); /*** Success. */ - rc = ble_att_clt_tx_find_info(conn_handle, 1, 0xffff); + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 1, 0xffff); TEST_ASSERT(rc == 0); /*** Error: start handle of 0. */ - rc = ble_att_clt_tx_find_info(conn_handle, 0, 0xffff); + /** In unit tests we don't are not receiving response - procedure will + * not complete. Reset `client_att_busy` flag so new request can be sent + */ + conn->client_att_busy = false; + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 0, 0xffff); TEST_ASSERT(rc == BLE_HS_EINVAL); /*** Error: start handle greater than end handle. */ - rc = ble_att_clt_tx_find_info(conn_handle, 500, 499); + conn->client_att_busy = false; + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 500, 499); TEST_ASSERT(rc == BLE_HS_EINVAL); /*** Success; start and end handles equal. */ - rc = ble_att_clt_tx_find_info(conn_handle, 500, 500); + conn->client_att_busy = false; + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 500, 500); TEST_ASSERT(rc == 0); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -175,9 +185,14 @@ ble_att_clt_test_case_tx_write_req_or_cmd(int is_req) uint16_t conn_handle; uint8_t value300[500] = { 0 }; uint8_t value5[5] = { 6, 7, 54, 34, 8 }; + struct ble_hs_conn *conn; conn_handle = ble_att_clt_test_misc_init(); + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); + /*** 5-byte write. */ ble_att_clt_test_tx_write_req_or_cmd(conn_handle, 0x1234, value5, sizeof value5, is_req); @@ -185,6 +200,10 @@ ble_att_clt_test_case_tx_write_req_or_cmd(int is_req) is_req); /*** Overlong write; verify command truncated to ATT MTU. */ + /** In unit tests we are not receiving response - procedure will + * not complete. Reset `client_att_busy` flag so new request can be sent + */ + conn->client_att_busy = false; ble_att_clt_test_tx_write_req_or_cmd(conn_handle, 0xab83, value300, sizeof value300, is_req); ble_att_clt_test_misc_verify_tx_write(0xab83, value300, @@ -206,7 +225,7 @@ ble_att_clt_test_misc_prep_good(uint16_t handle, uint16_t offset, conn_handle = ble_att_clt_test_misc_init(); om = ble_hs_test_util_om_from_flat(attr_data, attr_data_len); - rc = ble_att_clt_tx_prep_write(conn_handle, handle, offset, om); + rc = ble_att_clt_tx_prep_write(conn_handle, BLE_L2CAP_CID_ATT, handle, offset, om); TEST_ASSERT(rc == 0); om = ble_hs_test_util_prev_tx_dequeue_pullup(); @@ -232,7 +251,7 @@ ble_att_clt_test_misc_exec_good(uint8_t flags) conn_handle = ble_att_clt_test_misc_init(); - rc = ble_att_clt_tx_exec_write(conn_handle, flags); + rc = ble_att_clt_tx_exec_write(conn_handle, BLE_L2CAP_CID_ATT, flags); TEST_ASSERT(rc == 0); om = ble_hs_test_util_prev_tx_dequeue_pullup(); @@ -256,7 +275,7 @@ ble_att_clt_test_misc_prep_bad(uint16_t handle, uint16_t offset, om = ble_hs_test_util_om_from_flat(attr_data, attr_data_len); - rc = ble_att_clt_tx_prep_write(conn_handle, handle, offset, om); + rc = ble_att_clt_tx_prep_write(conn_handle, BLE_L2CAP_CID_ATT, handle, offset, om); TEST_ASSERT(rc == status); } @@ -287,11 +306,11 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_read(conn_handle, 1); + rc = ble_att_clt_tx_read(conn_handle, BLE_L2CAP_CID_ATT, 1); TEST_ASSERT(rc == 0); /*** Error: handle of 0. */ - rc = ble_att_clt_tx_read(conn_handle, 0); + rc = ble_att_clt_tx_read(conn_handle, BLE_L2CAP_CID_ATT, 0); TEST_ASSERT(rc == BLE_HS_EINVAL); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -333,11 +352,11 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_blob) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_read_blob(conn_handle, 1, 0); + rc = ble_att_clt_tx_read_blob(conn_handle, BLE_L2CAP_CID_ATT, 1, 0); TEST_ASSERT(rc == 0); /*** Error: handle of 0. */ - rc = ble_att_clt_tx_read_blob(conn_handle, 0, 0); + rc = ble_att_clt_tx_read_blob(conn_handle, BLE_L2CAP_CID_ATT, 0, 0); TEST_ASSERT(rc == BLE_HS_EINVAL); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -380,7 +399,7 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_mult) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_read_mult(conn_handle, ((uint16_t[]){ 1, 2 }), 2, false); + rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, ((uint16_t[]){ 1, 2 }), 2, false); TEST_ASSERT(rc == 0); om = ble_hs_test_util_prev_tx_dequeue_pullup(); @@ -392,7 +411,7 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_mult) TEST_ASSERT(get_le16(om->om_data + BLE_ATT_READ_MULT_REQ_BASE_SZ + 2) == 2); /*** Error: no handles. */ - rc = ble_att_clt_tx_read_mult(conn_handle, NULL, 0, false); + rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, NULL, 0, false); TEST_ASSERT(rc == BLE_HS_EINVAL); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -501,14 +520,14 @@ TEST_CASE_SELF(ble_att_clt_test_tx_exec_write) uint16_t conn_handle; int rc; - conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ ble_att_clt_test_misc_exec_good(BLE_ATT_EXEC_WRITE_F_CANCEL); ble_att_clt_test_misc_exec_good(BLE_ATT_EXEC_WRITE_F_EXECUTE); /*** Success: nonzero == execute. */ - rc = ble_att_clt_tx_exec_write(conn_handle, 0x02); + conn_handle = ble_att_clt_test_misc_init(); + rc = ble_att_clt_tx_exec_write(conn_handle, BLE_L2CAP_CID_ATT, 0x02); TEST_ASSERT(rc == 0); ble_hs_test_util_assert_mbufs_freed(NULL); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_svr_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_svr_test.c index 60ab14b4..84394d6a 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_svr_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_att_svr_test.c @@ -24,6 +24,7 @@ #include "nimble/hci_common.h" #include "ble_hs_test.h" #include "host/ble_uuid.h" +#include "host/ble_l2cap.h" #include "ble_hs_test_util.h" static uint8_t *ble_att_svr_test_attr_r_1; @@ -478,7 +479,7 @@ ble_att_svr_test_misc_verify_all_read_mult( } static void -ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle) +ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle, uint16_t cid) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; @@ -487,7 +488,7 @@ ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, cid, &conn, &chan); assert(rc == 0); my_mtu = chan->my_mtu; @@ -644,7 +645,7 @@ ble_att_svr_test_misc_mtu_exchange(uint16_t my_mtu, uint16_t peer_sent, buf, sizeof buf); TEST_ASSERT(rc == 0); - ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle); + ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle, BLE_L2CAP_CID_ATT); ble_hs_lock(); rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, @@ -1138,19 +1139,19 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) conn_handle = ble_att_svr_test_misc_init(128); /*** Start handle of 0. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 0, 0); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 0, 0); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE); /*** Start handle > end handle. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 101, 100); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 101, 100); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 101, BLE_ATT_ERR_INVALID_HANDLE); /*** No attributes. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 200, 300); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 200, 300); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND); @@ -1160,13 +1161,13 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) ble_att_svr_test_misc_attr_fn_r_1, NULL); TEST_ASSERT(rc == 0); - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 200, 300); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 200, 300); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND); /*** One 128-bit entry. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle1); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle1, handle1); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1181,7 +1182,7 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) ble_att_svr_test_misc_attr_fn_r_1, NULL); TEST_ASSERT(rc == 0); - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle2); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle1, handle2); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1199,7 +1200,7 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) ble_att_svr_test_misc_attr_fn_r_1, NULL); TEST_ASSERT(rc == 0); - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle3); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle1, handle3); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1213,7 +1214,7 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) } })); /*** Remaining 16-bit entry requested. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle3, handle3); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle3, handle3); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1936,13 +1937,13 @@ TEST_CASE_SELF(ble_att_svr_test_oom) TEST_ASSERT_FATAL(rc == 0); /* Ensure we were able to send a real response. */ - ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle); + ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle, BLE_L2CAP_CID_ATT); /*** Find information; always respond affirmatively, even when no mbufs. */ ble_hs_test_util_prev_tx_dequeue(); /* Receive a request. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 1, 100); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 1, 100); TEST_ASSERT_FATAL(rc == 0); /* Ensure we were able to send a real response. */ diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_conn_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_conn_test.c index 5cb94ce8..d74dd6fc 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_conn_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_conn_test.c @@ -385,6 +385,7 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) uint16_t attr_handle; uint16_t offset = 0; int rc; + struct ble_hs_conn *conn; ble_gatt_conn_test_util_init(); @@ -405,65 +406,92 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) /*** Schedule some GATT procedures. */ /* Connection 1. */ mtu_arg.exp_conn_handle = 1; + ble_hs_lock(); + conn = ble_hs_conn_find(1); + ble_hs_unlock(); + + /** In unit tests we are not receiving response - procedure will + * not complete. Reset `client_att_busy` flag so new request can be sent + */ + conn->client_att_busy = false; ble_gattc_exchange_mtu(1, ble_gatt_conn_test_mtu_cb, &mtu_arg); disc_all_svcs_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_disc_all_svcs(1, ble_gatt_conn_test_disc_all_svcs_cb, &disc_all_svcs_arg); TEST_ASSERT_FATAL(rc == 0); disc_svc_uuid_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_disc_svc_by_uuid(1, BLE_UUID16_DECLARE(0x1111), ble_gatt_conn_test_disc_svc_uuid_cb, &disc_svc_uuid_arg); TEST_ASSERT_FATAL(rc == 0); find_inc_svcs_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_find_inc_svcs(1, 1, 0xffff, ble_gatt_conn_test_find_inc_svcs_cb, &find_inc_svcs_arg); TEST_ASSERT_FATAL(rc == 0); disc_all_chrs_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_disc_all_chrs(1, 1, 0xffff, ble_gatt_conn_test_disc_all_chrs_cb, &disc_all_chrs_arg); TEST_ASSERT_FATAL(rc == 0); /* Connection 2. */ + ble_hs_lock(); + conn = ble_hs_conn_find(2); + ble_hs_unlock(); + disc_all_dscs_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_disc_all_dscs(2, 3, 0xffff, ble_gatt_conn_test_disc_all_dscs_cb, &disc_all_dscs_arg); disc_chr_uuid_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_disc_chrs_by_uuid(2, 2, 0xffff, BLE_UUID16_DECLARE(0x2222), ble_gatt_conn_test_disc_chr_uuid_cb, &disc_chr_uuid_arg); read_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_read(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE, ble_gatt_conn_test_read_cb, &read_arg); TEST_ASSERT_FATAL(rc == 0); read_uuid_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_read_by_uuid(2, 1, 0xffff, BLE_UUID16_DECLARE(0x3333), ble_gatt_conn_test_read_uuid_cb, &read_uuid_arg); TEST_ASSERT_FATAL(rc == 0); read_long_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_read_long(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE, offset, ble_gatt_conn_test_read_long_cb, &read_long_arg); TEST_ASSERT_FATAL(rc == 0); /* Connection 3. */ + ble_hs_lock(); + conn = ble_hs_conn_find(3); + ble_hs_unlock(); + read_mult_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_gattc_read_mult(3, ((uint16_t[3]){5,6,7}), 3, ble_gatt_conn_test_read_mult_cb, &read_mult_arg); TEST_ASSERT_FATAL(rc == 0); write_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_hs_test_util_gatt_write_flat( 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE, ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value, @@ -471,6 +499,7 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) TEST_ASSERT_FATAL(rc == 0); write_long_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_hs_test_util_gatt_write_long_flat( 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE, ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value, @@ -481,10 +510,12 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) attr.offset = 0; attr.om = os_msys_get_pkthdr(0, 0); write_rel_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_gattc_write_reliable( 3, &attr, 1, ble_gatt_conn_test_write_rel_cb, &write_rel_arg); TEST_ASSERT_FATAL(rc == 0); + conn->client_att_busy = false; rc = ble_gatts_indicate(3, attr_handle); TEST_ASSERT_FATAL(rc == 0); @@ -528,6 +559,11 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) TEST_ASSERT(ble_gatt_conn_test_gap_event.type == 255); /* Connection 3. */ + /** This is required because of call ble_att_clt_tx_exec_write + * from ble_att_clt_tx_exec_write after broken connection - + * ble_gattc_fail_procs is called + */ + conn->client_att_busy = false; ble_gattc_connection_broken(3); TEST_ASSERT(mtu_arg.called == 1); TEST_ASSERT(disc_all_svcs_arg.called == 1); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_c_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_c_test.c index e19db341..d0034889 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_c_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_c_test.c @@ -25,6 +25,7 @@ #include "ble_hs_test.h" #include "host/ble_gatt.h" #include "host/ble_uuid.h" +#include "host/ble_l2cap.h" #include "ble_hs_test_util.h" struct ble_gatt_disc_c_test_char { @@ -50,8 +51,8 @@ ble_gatt_disc_c_test_init(void) } static int -ble_gatt_disc_c_test_misc_rx_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_c_test_char *chars) +ble_gatt_disc_c_test_misc_rx_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_c_test_char *chars) { struct ble_att_read_type_rsp rsp; uint8_t buf[1024]; @@ -86,14 +87,14 @@ ble_gatt_disc_c_test_misc_rx_rsp_once( if (chars[i].uuid->type == BLE_UUID_TYPE_16) { if (off + BLE_ATT_READ_TYPE_ADATA_SZ_16 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; } } else { if (off + BLE_ATT_READ_TYPE_ADATA_SZ_128 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; @@ -121,7 +122,7 @@ ble_gatt_disc_c_test_misc_rx_rsp_once( } static void -ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, +ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, uint16_t cid, uint16_t end_handle, struct ble_gatt_disc_c_test_char *chars) { @@ -130,7 +131,7 @@ ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, idx = 0; while (chars[idx].def_handle != 0) { - count = ble_gatt_disc_c_test_misc_rx_rsp_once(conn_handle, + count = ble_gatt_disc_c_test_misc_rx_rsp_once(conn_handle, cid, chars + idx); if (count == 0) { break; @@ -140,7 +141,8 @@ ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, if (chars[idx - 1].def_handle != end_handle) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, + BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, chars[idx - 1].def_handle); } @@ -229,7 +231,7 @@ ble_gatt_disc_c_test_misc_all(uint16_t start_handle, uint16_t end_handle, ble_gatt_disc_c_test_misc_cb, &num_left); TEST_ASSERT(rc == 0); - ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, chars); + ble_gatt_disc_c_test_misc_rx_rsp(2, BLE_L2CAP_CID_ATT, end_handle, chars); ble_gatt_disc_c_test_misc_verify_chars(chars, stop_after); } @@ -252,7 +254,7 @@ ble_gatt_disc_c_test_misc_uuid(uint16_t start_handle, uint16_t end_handle, &stop_after); TEST_ASSERT(rc == 0); - ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, rsp_chars); + ble_gatt_disc_c_test_misc_rx_rsp(2, BLE_L2CAP_CID_ATT, end_handle, rsp_chars); ble_gatt_disc_c_test_misc_verify_chars(ret_chars, 0); } @@ -574,7 +576,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs); + num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs); /* Make sure there are still undiscovered characteristics. */ TEST_ASSERT_FATAL(num_chrs < sizeof chrs / sizeof chrs[0] - 1); @@ -598,7 +600,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs + num_chrs); + ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs + num_chrs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -617,7 +619,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_all) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); @@ -663,7 +665,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs); + num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs); /* Make sure there are still undiscovered characteristics. */ TEST_ASSERT_FATAL(num_chrs < sizeof chrs / sizeof chrs[0] - 1); @@ -686,7 +688,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs + num_chrs); + ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs + num_chrs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -704,7 +706,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_uuid) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_d_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_d_test.c index e405c86f..acee2ef8 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_d_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_d_test.c @@ -49,8 +49,8 @@ ble_gatt_disc_d_test_init(void) } static int -ble_gatt_disc_d_test_misc_rx_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_d_test_dsc *dscs) +ble_gatt_disc_d_test_misc_rx_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_d_test_dsc *dscs) { struct ble_att_find_info_rsp rsp; uint8_t buf[1024]; @@ -77,14 +77,14 @@ ble_gatt_disc_d_test_misc_rx_rsp_once( if (dscs[i].dsc_uuid.u.type == BLE_UUID_TYPE_16) { if (off + BLE_ATT_FIND_INFO_IDATA_16_SZ > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; } } else { if (off + BLE_ATT_FIND_INFO_IDATA_128_SZ > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; @@ -104,7 +104,7 @@ ble_gatt_disc_d_test_misc_rx_rsp_once( off += ble_uuid_length(&dscs[i].dsc_uuid.u); } - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -113,6 +113,7 @@ ble_gatt_disc_d_test_misc_rx_rsp_once( static void ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle, + uint16_t cid, uint16_t end_handle, struct ble_gatt_disc_d_test_dsc *dscs) { @@ -121,7 +122,7 @@ ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle, idx = 0; while (dscs[idx].chr_val_handle != 0) { - count = ble_gatt_disc_d_test_misc_rx_rsp_once(conn_handle, dscs + idx); + count = ble_gatt_disc_d_test_misc_rx_rsp_once(conn_handle, cid, dscs + idx); if (count == 0) { break; } @@ -130,7 +131,8 @@ ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle, if (dscs[idx - 1].dsc_handle != end_handle) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_FIND_INFO_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, + BLE_ATT_OP_FIND_INFO_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, end_handle); } @@ -223,7 +225,7 @@ ble_gatt_disc_d_test_misc_all(uint16_t chr_val_handle, uint16_t end_handle, ble_gatt_disc_d_test_misc_cb, &num_left); TEST_ASSERT(rc == 0); - ble_gatt_disc_d_test_misc_rx_rsp(2, end_handle, dscs); + ble_gatt_disc_d_test_misc_rx_rsp(2, BLE_L2CAP_CID_ATT, end_handle, dscs); ble_gatt_disc_d_test_misc_verify_dscs(dscs, stop_after); } @@ -389,7 +391,7 @@ TEST_CASE_SELF(ble_gatt_disc_d_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_dscs = ble_gatt_disc_d_test_misc_rx_rsp_once(1, dscs); + num_dscs = ble_gatt_disc_d_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, dscs); /* Make sure there are still undiscovered services. */ TEST_ASSERT_FATAL(num_dscs < sizeof dscs / sizeof dscs[0] - 1); @@ -412,7 +414,7 @@ TEST_CASE_SELF(ble_gatt_disc_d_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_d_test_misc_rx_rsp_once(1, dscs + num_dscs); + ble_gatt_disc_d_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, dscs + num_dscs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -430,7 +432,7 @@ TEST_CASE_SELF(ble_gatt_disc_d_test_oom_all) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_s_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_s_test.c index 3e7a3026..87735f7d 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_s_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_disc_s_test.c @@ -56,8 +56,8 @@ ble_gatt_disc_s_test_misc_svc_length(struct ble_gatt_disc_s_test_svc *service) } static int -ble_gatt_disc_s_test_misc_rx_all_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_all_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { struct ble_att_read_group_type_rsp rsp; uint8_t buf[1024]; @@ -86,14 +86,14 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once( if (services[i].uuid->type == BLE_UUID_TYPE_16) { if (off + BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; } } else { if (off + BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle,cid)) { /* Can't fit any more entries. */ break; @@ -110,7 +110,7 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once( off += ble_uuid_length(services[i].uuid); } - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -118,22 +118,22 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once( } static void -ble_gatt_disc_s_test_misc_rx_all_rsp( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_all_rsp(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { int count; int idx; idx = 0; while (services[idx].start_handle != 0) { - count = ble_gatt_disc_s_test_misc_rx_all_rsp_once(conn_handle, + count = ble_gatt_disc_s_test_misc_rx_all_rsp_once(conn_handle, cid, services + idx); idx += count; } if (services[idx - 1].end_handle != 0xffff) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, BLE_ATT_OP_READ_GROUP_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, services[idx - 1].start_handle); @@ -141,8 +141,8 @@ ble_gatt_disc_s_test_misc_rx_all_rsp( } static int -ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { uint8_t buf[1024]; int off; @@ -160,7 +160,7 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( } if (off + BLE_ATT_FIND_TYPE_VALUE_HINFO_BASE_SZ > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; @@ -173,7 +173,7 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( off += 2; } - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -181,22 +181,22 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( } static void -ble_gatt_disc_s_test_misc_rx_uuid_rsp( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_uuid_rsp(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { int count; int idx; idx = 0; while (services[idx].start_handle != 0) { - count = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(conn_handle, + count = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(conn_handle, cid, services + idx); idx += count; } if (services[idx - 1].end_handle != 0xffff) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, services[idx - 1].start_handle); @@ -269,7 +269,7 @@ ble_gatt_disc_s_test_misc_good_all(struct ble_gatt_disc_s_test_svc *services) rc = ble_gattc_disc_all_svcs(2, ble_gatt_disc_s_test_misc_disc_cb, NULL); TEST_ASSERT(rc == 0); - ble_gatt_disc_s_test_misc_rx_all_rsp(2, services); + ble_gatt_disc_s_test_misc_rx_all_rsp(2, BLE_L2CAP_CID_ATT, services); ble_gatt_disc_s_test_misc_verify_services(services); } @@ -290,7 +290,7 @@ ble_gatt_disc_s_test_misc_good_uuid( ble_hs_test_util_verify_tx_disc_svc_uuid(services[0].uuid); - ble_gatt_disc_s_test_misc_rx_uuid_rsp(2, services); + ble_gatt_disc_s_test_misc_rx_uuid_rsp(2, BLE_L2CAP_CID_ATT, services); ble_gatt_disc_s_test_misc_verify_services(services); } @@ -425,7 +425,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_svcs = ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, svcs); + num_svcs = ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, BLE_L2CAP_CID_ATT, svcs); /* Make sure there are still undiscovered services. */ TEST_ASSERT_FATAL(num_svcs < sizeof svcs / sizeof svcs[0] - 1); @@ -448,7 +448,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, svcs + num_svcs); + ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, BLE_L2CAP_CID_ATT, svcs + num_svcs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -465,7 +465,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_all) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_GROUP_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); @@ -504,7 +504,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_svcs = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, svcs); + num_svcs = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, BLE_L2CAP_CID_ATT, svcs); /* Make sure there are still undiscovered services. */ TEST_ASSERT_FATAL(num_svcs < sizeof svcs / sizeof svcs[0] - 1); @@ -527,7 +527,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, svcs + num_svcs); + ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, BLE_L2CAP_CID_ATT, svcs + num_svcs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -545,7 +545,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_uuid) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_GROUP_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); @@ -579,7 +579,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_timeout) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, svcs); + ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, BLE_L2CAP_CID_ATT, svcs); /* Keep trying to resume for 30 seconds, but never free any mbufs. Verify * procedure eventually times out. diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_find_s_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_find_s_test.c index 172bdd33..5f8075c9 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_find_s_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_find_s_test.c @@ -90,8 +90,8 @@ ble_gatt_find_s_test_misc_verify_incs( } static int -ble_gatt_find_s_test_misc_rx_read_type( - uint16_t conn_handle, struct ble_gatt_find_s_test_entry *entries) +ble_gatt_find_s_test_misc_rx_read_type(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_find_s_test_entry *entries) { struct ble_att_read_type_rsp rsp; uint8_t buf[1024]; @@ -134,14 +134,15 @@ ble_gatt_find_s_test_misc_rx_read_type( } if (i == 0) { - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, + BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 0); return 0; } ble_att_read_type_rsp_write(buf + 0, BLE_ATT_READ_TYPE_RSP_BASE_SZ, &rsp); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -149,7 +150,7 @@ ble_gatt_find_s_test_misc_rx_read_type( } static void -ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, const ble_uuid_t *uuid) +ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, uint16_t cid, const ble_uuid_t *uuid) { uint8_t buf[17]; int rc; @@ -159,7 +160,7 @@ ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, const ble_uuid_t *uuid) buf[0] = BLE_ATT_OP_READ_RSP; ble_uuid_flat(uuid, buf + 1); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, 17); TEST_ASSERT(rc == 0); } @@ -200,7 +201,7 @@ ble_gatt_find_s_test_misc_verify_tx_read(uint16_t handle) } static void -ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, +ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, struct ble_gatt_find_s_test_entry *entries) { @@ -219,7 +220,7 @@ ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, idx = 0; while (1) { ble_gatt_find_s_test_misc_verify_tx_read_type(cur_start, end_handle); - num_found = ble_gatt_find_s_test_misc_rx_read_type(conn_handle, + num_found = ble_gatt_find_s_test_misc_rx_read_type(conn_handle, cid, entries + idx); if (num_found == 0) { break; @@ -229,7 +230,7 @@ ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, TEST_ASSERT(num_found == 1); ble_gatt_find_s_test_misc_verify_tx_read( entries[idx].start_handle); - ble_gatt_find_s_test_misc_rx_read(conn_handle, + ble_gatt_find_s_test_misc_rx_read(conn_handle, cid, entries[idx].uuid); } @@ -255,7 +256,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 5, 10, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 5, 10, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 6, .start_handle = 35, @@ -275,7 +276,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 34, 100, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 34, 100, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 36, .start_handle = 403, @@ -290,7 +291,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 34, 100, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 34, 100, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 36, .start_handle = 403, @@ -310,7 +311,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 1, 100, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 1, 100, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 36, .start_handle = 403, @@ -379,7 +380,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_find_s_test_misc_rx_read_type(1, incs); + ble_gatt_find_s_test_misc_rx_read_type(1, BLE_L2CAP_CID_ATT, incs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -402,11 +403,11 @@ TEST_CASE_SELF(ble_gatt_find_s_test_oom) * follow-up request, so there is always an mbuf available. */ /* XXX: Find a way to test this. */ - ble_gatt_find_s_test_misc_rx_read(1, incs[0].uuid); + ble_gatt_find_s_test_misc_rx_read(1, BLE_L2CAP_CID_ATT, incs[0].uuid); /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_find_s_test_misc_rx_read_type(1, incs + 1); + ble_gatt_find_s_test_misc_rx_read_type(1, BLE_L2CAP_CID_ATT, incs + 1); /* Verify the procedure succeeds after mbufs become available. */ rc = os_mbuf_free_chain(oms); @@ -414,9 +415,9 @@ TEST_CASE_SELF(ble_gatt_find_s_test_oom) os_time_advance(ticks_until); ble_gattc_timer(); - ble_gatt_find_s_test_misc_rx_read(1, incs[1].uuid); + ble_gatt_find_s_test_misc_rx_read(1, BLE_L2CAP_CID_ATT, incs[1].uuid); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_read_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_read_test.c index 572b0bf1..a22e5a55 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_read_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_read_test.c @@ -160,7 +160,7 @@ ble_gatt_read_test_long_cb(uint16_t conn_handle, } static void -ble_gatt_read_test_misc_rx_rsp_good_raw(uint16_t conn_handle, +ble_gatt_read_test_misc_rx_rsp_good_raw(uint16_t conn_handle, uint16_t cid, uint8_t att_op, const void *data, int data_len) { @@ -174,27 +174,28 @@ ble_gatt_read_test_misc_rx_rsp_good_raw(uint16_t conn_handle, buf[0] = att_op; memcpy(buf + 1, data, data_len); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, 1 + data_len); TEST_ASSERT(rc == 0); } static void -ble_gatt_read_test_misc_rx_rsp_good(uint16_t conn_handle, +ble_gatt_read_test_misc_rx_rsp_good(uint16_t conn_handle, uint16_t cid, struct ble_hs_test_util_flat_attr *attr) { - ble_gatt_read_test_misc_rx_rsp_good_raw(conn_handle, BLE_ATT_OP_READ_RSP, + ble_gatt_read_test_misc_rx_rsp_good_raw(conn_handle, cid, + BLE_ATT_OP_READ_RSP, attr->value, attr->value_len); } static void -ble_gatt_read_test_misc_rx_rsp_bad(uint16_t conn_handle, +ble_gatt_read_test_misc_rx_rsp_bad(uint16_t conn_handle, uint16_t cid, uint8_t att_error, uint16_t err_handle) { /* Send the pending ATT Read Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, BLE_ATT_OP_READ_REQ, att_error, err_handle); } @@ -255,7 +256,7 @@ ble_gatt_read_test_misc_verify_good(struct ble_hs_test_util_flat_attr *attr) rc = ble_gattc_read(2, attr->handle, ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_good(2, attr); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attr); TEST_ASSERT(ble_gatt_read_test_num_attrs == 1); TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == 2); @@ -278,7 +279,7 @@ ble_gatt_read_test_misc_verify_bad(uint8_t att_status, rc = ble_gattc_read(2, attr->handle, ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, attr->handle); + ble_gatt_read_test_misc_rx_rsp_bad(2, BLE_L2CAP_CID_ATT, att_status, attr->handle); TEST_ASSERT(ble_gatt_read_test_num_attrs == 0); TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2); @@ -309,7 +310,8 @@ ble_gatt_read_test_misc_uuid_verify_good( while (1) { num_read = ble_gatt_read_test_misc_uuid_rx_rsp_good(2, attrs + idx); if (num_read == 0) { - ble_hs_test_util_rx_att_err_rsp(2, BLE_ATT_OP_READ_TYPE_REQ, + ble_hs_test_util_rx_att_err_rsp(2, BLE_L2CAP_CID_ATT, + BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, start_handle); break; @@ -369,7 +371,7 @@ ble_gatt_read_test_misc_long_verify_good( } else { att_op = BLE_ATT_OP_READ_BLOB_RSP; } - ble_gatt_read_test_misc_rx_rsp_good_raw(2, att_op, + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, att_op, attr->value + off, chunk_sz); rem_len -= chunk_sz; off += chunk_sz; @@ -401,7 +403,7 @@ ble_gatt_read_test_misc_long_verify_bad( ble_gatt_read_test_long_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, attr->handle); + ble_gatt_read_test_misc_rx_rsp_bad(2, BLE_L2CAP_CID_ATT, att_status, attr->handle); TEST_ASSERT(ble_gatt_read_test_num_attrs == 0); TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2); @@ -458,7 +460,7 @@ ble_gatt_read_test_misc_mult_verify_good( ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_MULT_RSP, + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_MULT_RSP, expected_value, off); TEST_ASSERT(ble_gatt_read_test_complete); @@ -488,7 +490,7 @@ ble_gatt_read_test_misc_mult_verify_bad( ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, err_handle); + ble_gatt_read_test_misc_rx_rsp_bad(2, BLE_L2CAP_CID_ATT, att_status, err_handle); TEST_ASSERT(ble_gatt_read_test_num_attrs == 0); TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2); @@ -801,9 +803,9 @@ TEST_CASE_SELF(ble_gatt_read_test_concurrent) rc = ble_gattc_read(2, attrs[2].handle, ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 0); - ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 1); - ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 2); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attrs + 0); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attrs + 1); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attrs + 2); TEST_ASSERT(ble_gatt_read_test_num_attrs == 3); @@ -852,8 +854,8 @@ TEST_CASE_SELF(ble_gatt_read_test_long_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - chunk_sz = ble_att_mtu(2) - BLE_ATT_READ_RSP_BASE_SZ; - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_RSP, + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_READ_RSP_BASE_SZ; + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_RSP, attr.value + off, chunk_sz); off += chunk_sz; @@ -875,8 +877,8 @@ TEST_CASE_SELF(ble_gatt_read_test_long_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - chunk_sz = ble_att_mtu(2) - BLE_ATT_READ_RSP_BASE_SZ; - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_RSP, + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_READ_RSP_BASE_SZ; + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_RSP, attr.value + off, chunk_sz); off += chunk_sz; @@ -897,7 +899,7 @@ TEST_CASE_SELF(ble_gatt_read_test_long_oom) ble_gattc_timer(); chunk_sz = attr.value_len - off; - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_RSP, + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_RSP, attr.value + off, chunk_sz); off += chunk_sz; diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_write_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_write_test.c index caa8e565..ea815c0d 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_write_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_gatt_write_test.c @@ -87,8 +87,8 @@ ble_gatt_write_test_rx_rsp(uint16_t conn_handle) } static void -ble_gatt_write_test_rx_prep_rsp(uint16_t conn_handle, uint16_t attr_handle, - uint16_t offset, +ble_gatt_write_test_rx_prep_rsp(uint16_t conn_handle, uint16_t cid, + uint16_t attr_handle, uint16_t offset, const void *attr_data, uint16_t attr_data_len) { struct ble_att_prep_write_cmd rsp; @@ -102,19 +102,19 @@ ble_gatt_write_test_rx_prep_rsp(uint16_t conn_handle, uint16_t attr_handle, memcpy(buf + BLE_ATT_PREP_WRITE_CMD_BASE_SZ, attr_data, attr_data_len); rc = ble_hs_test_util_l2cap_rx_payload_flat( - conn_handle, BLE_L2CAP_CID_ATT, buf, + conn_handle, cid, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ + attr_data_len); TEST_ASSERT(rc == 0); } static void -ble_gatt_write_test_rx_exec_rsp(uint16_t conn_handle) +ble_gatt_write_test_rx_exec_rsp(uint16_t conn_handle, uint16_t cid) { uint8_t op; int rc; op = BLE_ATT_OP_EXEC_WRITE_RSP; - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, &op, 1); TEST_ASSERT(rc == 0); } @@ -129,10 +129,10 @@ ble_gatt_write_test_misc_long_good(int attr_len) ble_gatt_write_test_init(); - ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), + ble_hs_test_util_create_conn(2, ((uint8_t[]) {2,3,4,5,6,7,8,9}), NULL, NULL); - mtu = ble_att_mtu(2); + mtu = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT); rc = ble_hs_test_util_gatt_write_long_flat( 2, 100, ble_gatt_write_test_attr_value, attr_len, @@ -152,7 +152,7 @@ ble_gatt_write_test_misc_long_good(int attr_len) /* Receive Prep Write response. */ ble_gatt_write_test_rx_prep_rsp( - 2, 100, off, ble_gatt_write_test_attr_value + off, len); + 2, BLE_L2CAP_CID_ATT, 100, off, ble_gatt_write_test_attr_value + off, len); /* Verify callback hasn't gotten called. */ TEST_ASSERT(!ble_gatt_write_test_cb_called); @@ -164,13 +164,13 @@ ble_gatt_write_test_misc_long_good(int attr_len) ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); } -typedef void ble_gatt_write_test_long_fail_fn(uint16_t conn_handle, +typedef void ble_gatt_write_test_long_fail_fn(uint16_t conn_handle, uint16_t cid, int off, int len); static void @@ -185,9 +185,9 @@ ble_gatt_write_test_misc_long_bad(int attr_len, ble_gatt_write_test_init(); - ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), + ble_hs_test_util_create_conn(2, ((uint8_t[]) {2,3,4,5,6,7,8,9}), NULL, NULL); - mtu = ble_att_mtu(2); + mtu = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT); rc = ble_hs_test_util_gatt_write_long_flat( 2, 100, ble_gatt_write_test_attr_value, attr_len, @@ -214,9 +214,9 @@ ble_gatt_write_test_misc_long_bad(int attr_len, } if (!fail_now) { ble_gatt_write_test_rx_prep_rsp( - 2, 100, off, ble_gatt_write_test_attr_value + off, len); + 2, BLE_L2CAP_CID_ATT, 100, off, ble_gatt_write_test_attr_value + off, len); } else { - cb(2, off, len); + cb(2, BLE_L2CAP_CID_ATT, off, len); break; } @@ -233,38 +233,38 @@ ble_gatt_write_test_misc_long_bad(int attr_len, } static void -ble_gatt_write_test_misc_long_fail_handle(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_handle(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 99, off, ble_gatt_write_test_attr_value + off, + conn_handle, cid, 99, off, ble_gatt_write_test_attr_value + off, len); } static void -ble_gatt_write_test_misc_long_fail_offset(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_offset(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 100, off + 1, ble_gatt_write_test_attr_value + off, + conn_handle, cid, 100, off + 1, ble_gatt_write_test_attr_value + off, len); } static void -ble_gatt_write_test_misc_long_fail_value(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_value(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 100, off, ble_gatt_write_test_attr_value + off + 1, + conn_handle, cid, 100, off, ble_gatt_write_test_attr_value + off + 1, len); } static void -ble_gatt_write_test_misc_long_fail_length(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_length(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 100, off, ble_gatt_write_test_attr_value + off, + conn_handle, cid, 100, off, ble_gatt_write_test_attr_value + off, len - 1); } @@ -313,9 +313,9 @@ ble_gatt_write_test_misc_reliable_good( flat_attrs + num_attrs); } - ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), + ble_hs_test_util_create_conn(2, ((uint8_t[]) {2,3,4,5,6,7,8,9}), NULL, NULL); - mtu = ble_att_mtu(2); + mtu = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT); rc = ble_gattc_write_reliable(2, attrs, num_attrs, ble_gatt_write_test_reliable_cb_good, NULL); @@ -336,7 +336,7 @@ ble_gatt_write_test_misc_reliable_good( attr->value + off, len); /* Receive Prep Write response. */ - ble_gatt_write_test_rx_prep_rsp(2, attr->handle, off, + ble_gatt_write_test_rx_prep_rsp(2, BLE_L2CAP_CID_ATT, attr->handle, off, attr->value + off, len); /* Verify callback hasn't gotten called. */ @@ -353,7 +353,7 @@ ble_gatt_write_test_misc_reliable_good( ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); @@ -599,7 +599,7 @@ TEST_CASE_SELF(ble_gatt_write_test_long_queue_full) /* Receive Prep Write response. */ len = BLE_ATT_MTU_DFLT - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; ble_gatt_write_test_rx_prep_rsp( - 2, 100, off, ble_gatt_write_test_attr_value + off, len); + 2, BLE_L2CAP_CID_ATT, 100, off, ble_gatt_write_test_attr_value + off, len); /* Verify callback hasn't gotten called. */ TEST_ASSERT(!ble_gatt_write_test_cb_called); @@ -611,7 +611,8 @@ TEST_CASE_SELF(ble_gatt_write_test_long_queue_full) TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() != NULL); /* Receive queue full error. */ - ble_hs_test_util_rx_att_err_rsp(2, BLE_ATT_OP_PREP_WRITE_REQ, + ble_hs_test_util_rx_att_err_rsp(2, BLE_L2CAP_CID_ATT, + BLE_ATT_OP_PREP_WRITE_REQ, BLE_ATT_ERR_PREPARE_QUEUE_FULL, 100); /* Verify callback was called. */ @@ -654,14 +655,14 @@ TEST_CASE_SELF(ble_gatt_write_test_long_oom) ble_gatt_write_test_cb_good, NULL); TEST_ASSERT_FATAL(rc == 0); - chunk_sz = ble_att_mtu(2) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; ble_hs_test_util_verify_tx_prep_write(attr.handle, off, attr.value + off, chunk_sz); /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_write_test_rx_prep_rsp(2, attr.handle, off, attr.value + off, + ble_gatt_write_test_rx_prep_rsp(2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; @@ -688,7 +689,7 @@ TEST_CASE_SELF(ble_gatt_write_test_long_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); ble_gatt_write_test_rx_prep_rsp( - 2, attr.handle, off, attr.value + off, chunk_sz); + 2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; /* Ensure no follow-up request got sent. It should not have gotten sent @@ -711,7 +712,7 @@ TEST_CASE_SELF(ble_gatt_write_test_long_oom) ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); @@ -750,14 +751,14 @@ TEST_CASE_SELF(ble_gatt_write_test_reliable_oom) ble_gatt_write_test_reliable_cb_good, NULL); TEST_ASSERT_FATAL(rc == 0); - chunk_sz = ble_att_mtu(2) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; ble_hs_test_util_verify_tx_prep_write(attr.handle, off, attr.value + off, chunk_sz); /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_write_test_rx_prep_rsp(2, attr.handle, off, attr.value + off, + ble_gatt_write_test_rx_prep_rsp(2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; @@ -784,7 +785,7 @@ TEST_CASE_SELF(ble_gatt_write_test_reliable_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); ble_gatt_write_test_rx_prep_rsp( - 2, attr.handle, off, attr.value + off, chunk_sz); + 2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; /* Ensure no follow-up request got sent. It should not have gotten sent @@ -807,7 +808,7 @@ TEST_CASE_SELF(ble_gatt_write_test_reliable_oom) ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_pvcy_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_pvcy_test.c index 79b93b83..7fd357d0 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_pvcy_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_pvcy_test.c @@ -51,7 +51,7 @@ ble_hs_pvcy_test_util_all_gap_procs(int adv_status, int conn_status, int disc_status) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; ble_addr_t peer_addr; int rc; @@ -338,7 +338,7 @@ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_adv) /*** Discovery active. */ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_disc) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int rc; ble_hs_pvcy_test_util_init(); @@ -407,7 +407,7 @@ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_conn) /*** Advertising and discovery active. */ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_adv_disc) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int rc; ble_hs_pvcy_test_util_init(); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.c index c336ddf9..f5463b3e 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.c @@ -741,7 +741,7 @@ ble_hs_test_util_set_att_mtu(uint16_t conn_handle, uint16_t mtu) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); assert(rc == 0); chan->my_mtu = mtu; chan->peer_mtu = mtu; @@ -772,6 +772,7 @@ ble_hs_test_util_rx_att_mtu_cmd(uint16_t conn_handle, int is_req, uint16_t mtu) int ble_hs_test_util_rx_att_find_info_req(uint16_t conn_handle, + uint16_t cid, uint16_t start_handle, uint16_t end_handle) { @@ -784,7 +785,7 @@ ble_hs_test_util_rx_att_find_info_req(uint16_t conn_handle, ble_att_find_info_req_write(buf, sizeof buf, &req); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, sizeof buf); return rc; @@ -1070,7 +1071,7 @@ ble_hs_test_util_rx_att_indicate_req(uint16_t conn_handle, } void -ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op, +ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint16_t cid, uint8_t req_op, uint8_t error_code, uint16_t err_handle) { struct ble_att_error_rsp rsp; @@ -1083,7 +1084,7 @@ ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op, ble_att_error_rsp_write(buf, sizeof buf, &rsp); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, sizeof buf); TEST_ASSERT(rc == 0); } diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.h b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.h index 7a0aa3eb..6d5d04c0 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.h +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util.h @@ -173,6 +173,7 @@ void ble_hs_test_util_set_att_mtu(uint16_t conn_handle, uint16_t mtu); int ble_hs_test_util_rx_att_mtu_cmd(uint16_t conn_handle, int is_req, uint16_t mtu); int ble_hs_test_util_rx_att_find_info_req(uint16_t conn_handle, + uint16_t cid, uint16_t start_handle, uint16_t end_handle); int ble_hs_test_util_rx_att_find_type_value_req(uint16_t conn_handle, @@ -228,8 +229,9 @@ int ble_hs_test_util_rx_att_indicate_req(uint16_t conn_handle, uint16_t attr_handle, void *attr_val, uint16_t attr_len); -void ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op, - uint8_t error_code, uint16_t err_handle); +void ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint16_t cid, + uint8_t req_op, uint8_t error_code, + uint16_t err_handle); void ble_hs_test_util_verify_tx_prep_write(uint16_t attr_handle, uint16_t offset, const void *data, int data_len); diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util_hci.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util_hci.c index e8054c2f..c27af143 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util_hci.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_hs_test_util_hci.c @@ -250,6 +250,19 @@ static const struct ble_hs_test_util_hci_ack hci_startup_seq[] = { .evt_params = { 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, .evt_params_len = 8, }, + { + .opcode = ble_hs_hci_util_opcode_join( + BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD), + .evt_params = { 0x20, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x28, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0xf7, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xe0, 0x63, 0xe0, 0x04, 0x02, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .evt_params_len = 64 + }, { .opcode = ble_hs_hci_util_opcode_join( BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT), diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_os_test.c b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_os_test.c index 6588c679..1703a0cf 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_os_test.c +++ b/lib/bt/host/nimble/nimble/nimble/host/test/src/ble_os_test.c @@ -193,7 +193,7 @@ ble_os_disc_test_cb(struct ble_gap_event *event, void *arg) static void ble_os_disc_test_task_handler(void *arg) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int cb_called; int rc; diff --git a/lib/bt/host/nimble/nimble/nimble/host/test/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/host/test/syscfg.yml index 031b6c8b..cfb3a817 100644 --- a/lib/bt/host/nimble/nimble/nimble/host/test/syscfg.yml +++ b/lib/bt/host/nimble/nimble/nimble/host/test/syscfg.yml @@ -30,3 +30,4 @@ syscfg.vals: BLE_VERSION: 52 BLE_L2CAP_ENHANCED_COC: 1 BLE_TRANSPORT_LL: custom + BLE_EATT_CHAN_NUM: 0 diff --git a/lib/bt/host/nimble/nimble/nimble/include/nimble/ble.h b/lib/bt/host/nimble/nimble/nimble/include/nimble/ble.h index 6979e945..e9a498d2 100644 --- a/lib/bt/host/nimble/nimble/nimble/include/nimble/ble.h +++ b/lib/bt/host/nimble/nimble/nimble/include/nimble/ble.h @@ -282,6 +282,7 @@ enum ble_error_codes #define BLE_ADDR_RANDOM (0x01) #define BLE_ADDR_PUBLIC_ID (0x02) #define BLE_ADDR_RANDOM_ID (0x03) +#define BLE_ADDR_ANONYMOUS (0xFF) #define BLE_ADDR_ANY (&(ble_addr_t) { 0, {0, 0, 0, 0, 0, 0} }) diff --git a/lib/bt/host/nimble/nimble/nimble/include/nimble/hci_common.h b/lib/bt/host/nimble/nimble/nimble/include/nimble/hci_common.h index 76a8b871..62ac9e8e 100644 --- a/lib/bt/host/nimble/nimble/nimble/include/nimble/hci_common.h +++ b/lib/bt/host/nimble/nimble/nimble/include/nimble/hci_common.h @@ -600,6 +600,7 @@ struct ble_hci_le_set_ext_adv_params_cp { uint8_t sid; uint8_t scan_req_notif; } __attribute__((packed)); + struct ble_hci_le_set_ext_adv_params_rp { int8_t tx_power; } __attribute__((packed)); @@ -714,6 +715,18 @@ struct ble_hci_le_ext_create_conn_cp { struct conn_params conn_params[0]; } __attribute__((packed)); +#define BLE_HCI_LE_EXT_CREATE_CONN_V2 (0x0085) +struct ble_hci_le_ext_create_conn_v2_cp { + uint8_t adv_handle; + uint8_t subevent; + uint8_t filter_policy; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t init_phy_mask; + struct conn_params conn_params[0]; +} __attribute__((packed)); + #define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_FILTER 0x01 #define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DISABLED 0x02 #define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DUPLICATES 0x04 @@ -784,14 +797,88 @@ struct ble_hci_le_set_privacy_mode_cp { #define BLE_HCI_OCF_LE_RX_TEST_V3 (0x004F) #define BLE_HCI_OCF_LE_TX_TEST_V3 (0x0050) + #define BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_PARAMS (0x0051) +struct ble_hci_le_set_connless_cte_tx_params_cp { + uint8_t adv_handle; + uint8_t cte_length; + uint8_t cte_type; + uint8_t cte_count; + uint8_t switching_pattern_len; + uint8_t switching_pattern[0]; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_ENABLE (0x0052) +struct ble_hci_le_set_connless_cte_tx_enable_cp { + uint8_t adv_handle; + uint8_t cte_enable; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_CONNLESS_IQ_SAMPLING_ENABLE (0x0053) +struct ble_hci_le_set_connless_iq_sampling_enable_cp { + uint16_t sync_handle; + uint8_t sampling_enable; + uint8_t slot_durations; + uint8_t max_sampled_ctes; + uint8_t switching_pattern_len; + uint8_t antenna_ids[0]; +} __attribute__((packed)); + +struct ble_hci_le_set_connless_iq_sampling_enable_rp { + uint16_t sync_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_CONN_CTE_RX_PARAMS (0x0054) +struct ble_hci_le_set_conn_cte_rx_params_cp { + uint16_t conn_handle; + uint8_t sampling_enable; + uint8_t slot_durations; + uint8_t switching_pattern_len; + uint8_t antenna_ids[0]; +} __attribute__((packed)); +struct ble_hci_le_set_conn_cte_rx_params_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_CONN_CTE_TX_PARAMS (0x0055) +struct ble_hci_le_set_conn_cte_tx_params_cp { + uint16_t conn_handle; + uint8_t cte_types; + uint8_t switching_pattern_len; + uint8_t antenna_ids[0]; +} __attribute__((packed)); +struct ble_hci_le_set_conn_cte_tx_params_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_CONN_CTE_REQ_ENABLE (0x0056) +struct ble_gap_conn_cte_req_enable_cp { + uint16_t conn_handle; + uint8_t enable; + uint16_t cte_request_interval; + uint8_t requested_cte_length; + uint8_t requested_cte_type; +} __attribute__((packed)); +struct ble_gap_conn_cte_req_enable_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_CONN_CTE_RESP_ENABLE (0x0057) +struct ble_hci_le_set_conn_cte_rsp_enable_cp { + uint16_t conn_handle; + uint8_t enable; +} __attribute__((packed)); +struct ble_hci_le_set_conn_cte_rsp_enable_rp { + uint16_t conn_handle; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_ANTENNA_INFO (0x0058) +struct ble_hci_le_rd_antenna_info_rp { + uint8_t switch_sampling_rates; + uint8_t num_antennae; + uint8_t max_switch_pattern_len; + uint8_t max_cte_len; +} __attribute__((packed)); #define BLE_HCI_OCF_LE_PERIODIC_ADV_RECEIVE_ENABLE (0x0059) struct ble_hci_le_periodic_adv_receive_enable_cp { @@ -1137,7 +1224,7 @@ struct ble_hci_le_set_transmit_power_report_enable_cp { uint8_t remote_enable; } __attribute__((packed)); -#define BLE_HCI_OCF_LE_SET_DATA_ADDR_CHANGE (0x007C) +#define BLE_HCI_OCF_LE_SET_DATA_ADDR_CHANGE (0x007C) struct ble_hci_le_set_data_addr_change_cp { uint8_t adv_handle; uint8_t change_reason; @@ -1157,10 +1244,68 @@ struct ble_hci_le_subrate_req_cp { uint16_t conn_handle; uint16_t subrate_min; uint16_t subrate_max; + uint16_t max_latency; uint16_t cont_num; uint16_t supervision_tmo; } __attribute__((packed)); +#define BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2 (0x007F) +struct ble_hci_le_set_ext_adv_params_v2_cp { + struct ble_hci_le_set_ext_adv_params_cp cmd; + uint8_t pri_phy_opt; + uint8_t sec_phy_opt; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_SUBEV_DATA (0x0082) +struct periodic_adv_subevents { + uint8_t subevent; + uint8_t response_slot_start; + uint8_t response_slot_count; + uint8_t subevent_data_length; + uint8_t subevent_data[0]; +} __attribute__((packed)); + +struct ble_hci_le_set_periodic_adv_subev_data_cp { + uint8_t adv_handle; + uint8_t num_subevents; + struct periodic_adv_subevents subevents[0]; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_RESPONSE_DATA (0x0083) +struct ble_hci_le_set_periodic_adv_response_data { + uint16_t sync_handle; + uint16_t request_event; + uint8_t request_subevent; + uint8_t response_subevent; + uint8_t response_slot; + uint8_t response_data_length; + uint8_t response_data[0]; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_SYNC_SUBEVENT (0x0084) +struct ble_hci_le_set_periodic_adv_sync_subevent { + uint16_t sync_handle; + uint16_t periodic_adv_properties; + uint8_t num_subevents; + uint8_t subevents[0]; +} __attribute__((packed)); +struct ble_hci_le_set_periodic_adv_sync_subevent_rp { + uint16_t sync_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS_V2 (0x0086) +struct ble_hci_le_set_periodic_adv_params_v2 { + uint8_t adv_handle; + uint16_t min_itvl; + uint16_t max_itvl; + uint16_t props; + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; + uint8_t num_response_slots; +} __attribute__((packed)); + /* --- Vendor specific commands (OGF 0x003F) */ /* Read Random Static Address */ #define BLE_HCI_OCF_VS_RD_STATIC_ADDR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001)) @@ -1238,6 +1383,11 @@ struct ble_hci_vs_duplicate_exception_list_cp { #define BLE_HCI_OCF_VS_SET_CHAN_SELECT (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0112)) +#define BLE_HCI_OCF_VS_SET_EVT_MASK (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0116)) +struct ble_hci_vs_set_event_mask_cp { + uint32_t event_mask; +} __attribute__((packed)); + /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) @@ -1278,8 +1428,17 @@ struct ble_hci_vs_duplicate_exception_list_cp { #define BLE_HCI_ADV_PEER_ADDR_MAX (1) /* --- LE advertising channel tx power (OCF 0x0007) */ -#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) -#define BLE_HCI_ADV_CHAN_TXPWR_MAX (10) +#if MYNEWT_VAL(BLE_VERSION) == 50 +#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) +#define BLE_HCI_ADV_CHAN_TXPWR_MAX (10) +#elif MYNEWT_VAL(BLE_VERSION) == 51 +#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) +#define BLE_HCI_ADV_CHAN_TXPWR_MAX (20) +#elif MYNEWT_VAL(BLE_VERSION) >= 52 +#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-127) +#define BLE_HCI_ADV_CHAN_TXPWR_MAX (20) +#endif + /* --- LE set scan enable (OCF 0x000c) */ @@ -1392,7 +1551,11 @@ struct ble_hci_vs_duplicate_exception_list_cp { #define BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MIN (0x001b) #define BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX (0x00fb) #define BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MIN (0x0148) +#if BLE_50_FEATURE_SUPPORT #define BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX (0x4290) +#else +#define BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX (0x0848) +#endif /* --- LE read maximum default PHY (OCF 0x0030) */ #define BLE_HCI_LE_PHY_1M (1) @@ -1463,11 +1626,22 @@ struct ble_hci_vs_duplicate_exception_list_cp { #define BLE_HCI_PERIODIC_DATA_STATUS_COMPLETE 0x00 #define BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE 0x01 #define BLE_HCI_PERIODIC_DATA_STATUS_TRUNCATED 0x02 +#define BLE_HCI_PERIODIC_DATA_STATUS_RX_FAILED 0xFF /* --- LE set privacy mode (OCF 0x004E) */ #define BLE_HCI_PRIVACY_NETWORK (0) #define BLE_HCI_PRIVACY_DEVICE (1) +/* --- LE set cte type (OCF 0x0051) */ +#define BLE_HCI_CTE_TYPE_AOA (0) +#define BLE_HCI_CTE_TYPE_AOD_1US (1) +#define BLE_HCI_CTE_TYPE_AOD_2US (2) + +/* --- LE set allow cte rsp types (OCF 0x0055) */ +#define BLE_HCI_CTE_RSP_ALLOW_AOA_MASK (0x01) +#define BLE_HCI_CTE_RSP_ALLOW_AOD_1US_MASK (0x02) +#define BLE_HCI_CTE_RSP_ALLOW_AOD_2US_MASK (0x04) + /* Event Codes */ #define BLE_HCI_EVCODE_INQUIRY_CMP (0x01) #define BLE_HCI_EVCODE_INQUIRY_RESULT (0x02) @@ -1638,6 +1812,8 @@ struct ble_hci_ev_vs_css_slot_changed { #define BLE_HCI_VS_SUBEV_ID_LLCP_TRACE (0x17) +#define BLE_HCI_VS_SUBEV_LE_SLEEP_WAKE_UP (0xC3) + /* LE sub-event codes */ #define BLE_HCI_LE_SUBEV_CONN_COMPLETE (0x01) struct ble_hci_ev_le_subev_conn_complete { @@ -1728,6 +1904,7 @@ struct ble_hci_ev_le_subev_gen_dhkey_complete { } __attribute__((packed)); #define BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE (0x0A) +#define BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE_V2 (0x29) struct ble_hci_ev_le_subev_enh_conn_complete { uint8_t subev_code; uint8_t status; @@ -1741,6 +1918,10 @@ struct ble_hci_ev_le_subev_enh_conn_complete { uint16_t conn_latency; uint16_t supervision_timeout; uint8_t mca; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint8_t adv_handle; + uint16_t sync_handle; +#endif } __attribute__((packed)); #define BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT (0x0B) @@ -1789,7 +1970,8 @@ struct ble_hci_ev_le_subev_ext_adv_rpt { struct ext_adv_report reports[0]; } __attribute__((packed)); -#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB (0x0E) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB (0x0E) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB_V2 (0x24) struct ble_hci_ev_le_subev_periodic_adv_sync_estab { uint8_t subev_code; uint8_t status; @@ -1800,15 +1982,41 @@ struct ble_hci_ev_le_subev_periodic_adv_sync_estab { uint8_t phy; uint16_t interval; uint8_t aca; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; +#endif } __attribute__((packed)); #define BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT (0x0F) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT_V2 (0x25) struct ble_hci_ev_le_subev_periodic_adv_rpt { uint8_t subev_code; uint16_t sync_handle; int8_t tx_power; int8_t rssi; uint8_t cte_type; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint16_t event_counter; + uint8_t subevent; +#endif + uint8_t data_status; + uint8_t data_len; + uint8_t data[0]; +} __attribute__((packed)); + +struct ble_hci_ev_le_subev_periodic_adv_rpt_v2 { + uint8_t subev_code; + uint16_t sync_handle; + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint16_t event_counter; + uint8_t subevent; +#endif // MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) uint8_t data_status; uint8_t data_len; uint8_t data[0]; @@ -1849,11 +2057,47 @@ struct ble_hci_ev_le_subev_chan_sel_alg { uint8_t csa; } __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_CONNLESS_IQ_RPT (0x15) +struct ble_hci_ev_le_subev_connless_iq_rpt { + uint8_t subev_code; + uint16_t sync_handle; + uint8_t channel_index; + int16_t rssi; + uint8_t rssi_antenna_id; + uint8_t cte_type; + uint8_t slot_durations; + uint8_t packet_status; + uint16_t periodic_event_counter; + uint8_t sample_count; + int8_t iq_samples[0]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_CONN_IQ_RPT (0x16) +struct ble_hci_ev_le_subev_conn_iq_rpt { + uint8_t subev_code; + uint16_t conn_handle; + uint8_t rx_phy; + uint8_t data_channel_index; + int16_t rssi; + uint8_t rssi_antenna_id; + uint8_t cte_type; + uint8_t slot_durations; + uint8_t packet_status; + uint16_t conn_event_counter; + uint8_t sample_count; + int8_t iq_samples[0]; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_CTE_REQ_FAILED (0x17) +struct ble_hci_ev_le_subev_cte_req_failed { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; +} __attribute__((packed)); -#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER (0x18) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER (0x18) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER_V2 (0x26) struct ble_hci_ev_le_subev_periodic_adv_sync_transfer { uint8_t subev_code; uint8_t status; @@ -1866,6 +2110,12 @@ struct ble_hci_ev_le_subev_periodic_adv_sync_transfer { uint8_t phy; uint16_t interval; uint8_t aca; +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; +#endif } __attribute__((packed)); #define BLE_HCI_LE_SUBEV_CIS_ESTABLISHED (0x19) @@ -2003,6 +2253,34 @@ struct ble_hci_ev_le_subev_subrate_change { uint16_t supervision_tmo; } __attribute__((packed)); +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SUBEV_DATA_REQ (0x27) +struct ble_hci_ev_le_subev_periodic_adv_subev_data_req { + uint8_t subev_code; + uint8_t adv_handle; + uint8_t subevent_start; + uint8_t subevent_data_count; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_RESP_REPORT (0x28) +struct periodic_adv_response { + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; + uint8_t response_slot; + uint8_t data_status; + uint8_t data_length; + uint8_t data[0]; +} __attribute__((packed)); + +struct ble_hci_ev_le_subev_periodic_adv_resp_rep { + uint8_t subev_code; + uint8_t adv_handle; + uint8_t subevent; + uint8_t tx_status; + uint8_t num_responses; + struct periodic_adv_response responses[0]; +} __attribute__((packed)); + #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) // LE vendor hci event #define BLE_HCI_LE_SUBEV_DISCARD_REPORT_EVT 0XF0 diff --git a/lib/bt/host/nimble/nimble/nimble/include/nimble/nimble_opt_auto.h b/lib/bt/host/nimble/nimble/nimble/include/nimble/nimble_opt_auto.h index 6326abf5..8b3fde02 100644 --- a/lib/bt/host/nimble/nimble/nimble/include/nimble/nimble_opt_auto.h +++ b/lib/bt/host/nimble/nimble/nimble/include/nimble/nimble_opt_auto.h @@ -113,6 +113,10 @@ extern "C" { #define NIMBLE_BLE_ATT_CLT_INDICATE \ (MYNEWT_VAL(BLE_GATT_INDICATE)) +#undef NIMBLE_BLE_ATT_CLT_NOTIFY_MULT +#define NIMBLE_BLE_ATT_CLT_NOTIFY_MULT \ + (MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE)) + /** Security manager settings. */ #undef NIMBLE_BLE_SM diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml deleted file mode 100644 index 9b9ee83e..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml +++ /dev/null @@ -1,28 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/transport/dialog_cmac/cmac_driver/diag -pkg.description: Default diag configuration for CMAC -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - dialog - - da1469x - - cmac -pkg.apis: dialog_cmac_diag diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c deleted file mode 100644 index 83299038..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include "syscfg/syscfg.h" -#include "mcu/mcu.h" - -#if MYNEWT_VAL(BLE_CONTROLLER) -void -cmac_diag_setup_cmac(void) -{ - MCU_DIAG_MAP( 0, 4, DSER); - MCU_DIAG_MAP( 1, 6, CMAC_ON_ERROR); - MCU_DIAG_MAP( 2, 2, PHY_TX_EN); - MCU_DIAG_MAP( 3, 2, PHY_RX_EN); - MCU_DIAG_MAP( 4, 2, PHY_TXRX_DATA_COMB); - MCU_DIAG_MAP( 5, 2, PHY_TXRX_DATA_EN_COMB); - MCU_DIAG_MAP( 6, 5, EV1US_FRAME_START); - MCU_DIAG_MAP( 7, 5, EV_BS_START); - MCU_DIAG_MAP( 8, 5, EV1C_BS_STOP); - MCU_DIAG_MAP( 9, 5, EV1US_PHY_TO_IDLE); - MCU_DIAG_MAP(10, 9, CALLBACK_IRQ); - MCU_DIAG_MAP(11, 9, FIELD_IRQ); - MCU_DIAG_MAP(12, 9, FRAME_IRQ); - MCU_DIAG_MAP(13, 3, SLP_TIMER_ACTIVE); - MCU_DIAG_MAP(14, 4, SLEEPING); - MCU_DIAG_MAP(15, 8, LL_TIMER1_00); -} -#else -void -cmac_diag_setup_host(void) -{ - /* Setup pins for diagnostic signals */ - mcu_gpio_set_pin_function(42, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG0); /* DIAG_0 @ P1.10 */ - mcu_gpio_set_pin_function(43, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG1); /* DIAG_1 @ P1.11 */ - mcu_gpio_set_pin_function(44, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG2); /* DIAG_2 @ P1.12 */ - mcu_gpio_set_pin_function(24, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_3 @ P0.24 */ - mcu_gpio_set_pin_function(21, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_4 @ P0.21 */ - mcu_gpio_set_pin_function(20, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_5 @ P0.20 */ - mcu_gpio_set_pin_function(19, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_6 @ P0.19 */ - mcu_gpio_set_pin_function(18, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_7 @ P0.18 */ - mcu_gpio_set_pin_function(31, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_8 @ P0.31 */ - mcu_gpio_set_pin_function(30, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_9 @ P0.30 */ - mcu_gpio_set_pin_function(29, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_10 @ P0.29 */ - mcu_gpio_set_pin_function(28, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_11 @ P0.28 */ - mcu_gpio_set_pin_function(27, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_12 @ P0.27 */ - mcu_gpio_set_pin_function(26, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_13 @ P0.26 */ - mcu_gpio_set_pin_function(38, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_14 @ P1.06 */ - mcu_gpio_set_pin_function(41, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_15 @ P1.09 */ -} -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h deleted file mode 100644 index dc6ee903..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef __MCU_CMAC_DIAG_H_ -#define __MCU_CMAC_DIAG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void cmac_diag_setup_host(void); -void cmac_diag_setup_cmac(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __MCU_CMAC_DIAG_H_ */ diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h deleted file mode 100644 index 50d86755..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef __DA1469X_CMAC_V2_H_ -#define __DA1469X_CMAC_V2_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void cmac_host_init(void); -void cmac_host_signal2cmac(void); -void cmac_host_rf_calibrate(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __DA1469X_CMAC_V2_H_ */ diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h deleted file mode 100644 index 887af258..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef __MCU_CMAC_SHARED_H_ -#define __MCU_CMAC_SHARED_H_ - -#include -#include "syscfg/syscfg.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define CMAC_SHARED_MAGIC_CMAC (0x4C6C) /* "lL" */ -#define CMAC_SHARED_MAGIC_SYS (0x5368) /* "hS" */ - -#define CMAC_SHARED_F_SYS_LPCLK_AVAILABLE (0x0001) - -/* - * Simple circular buffer for storing random numbers generated by M33 - * Empty: cmr_in = cmr_out = 0; - * Full: cmr_in + 1 = cmr_out - * - * cmr_in: used by the M33 to add random numbers to the circular buffer. - * cmr_out: used by CMAC to retrieve random numbers - * - * NOTE: cmr_in and cmr_out are indices. - */ -#define CMAC_RAND_BUF_ELEMS (16) - -struct cmac_rand { - int cmr_active; - int cmr_in; - int cmr_out; - uint32_t cmr_buf[CMAC_RAND_BUF_ELEMS]; -}; - -struct cmac_mbox { - uint16_t rd_off; - uint16_t wr_off; -}; - -struct cmac_dcdc { - uint8_t enabled; - uint32_t v18; - uint32_t v18p; - uint32_t vdd; - uint32_t v14; - uint32_t ctrl1; -}; - -struct cmac_trim { - uint8_t rfcu_len; - uint8_t rfcu_mode1_len; - uint8_t rfcu_mode2_len; - uint8_t synth_len; - uint32_t rfcu[ MYNEWT_VAL(CMAC_TRIM_SIZE_RFCU) ]; - uint32_t rfcu_mode1[2]; - uint32_t rfcu_mode2[2]; - uint32_t synth[ MYNEWT_VAL(CMAC_TRIM_SIZE_SYNTH) ]; -}; - -#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) -struct cmac_debug { - int8_t last_rx_rssi; - int8_t tx_power_override; - - uint32_t cal_res_1; - uint32_t cal_res_2; - uint32_t trim_val1_tx_1; - uint32_t trim_val1_tx_2; - uint32_t trim_val2_tx; - uint32_t trim_val2_rx; -}; -#endif - -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) -struct cmac_coredump { - uint32_t lr; - uint32_t pc; - uint32_t assert; - const char *assert_file; - uint32_t assert_line; - - uint32_t CM_STAT_REG; - uint32_t CM_LL_TIMER1_36_10_REG; - uint32_t CM_LL_TIMER1_9_0_REG; - uint32_t CM_ERROR_REG; - uint32_t CM_EXC_STAT_REG; -}; -#endif - -#define CMAC_PENDING_OP_LP_CLK 0x0001 -#define CMAC_PENDING_OP_RF_CAL 0x0002 - -struct cmac_shared_data { - uint16_t magic_cmac; - uint16_t magic_sys; - uint16_t pending_ops; - uint16_t lp_clock_freq; /* LP clock frequency */ - uint32_t xtal32m_settle_us;/* XTAL32M settling time */ - struct cmac_mbox mbox_s2c; /* SYS2CMAC mailbox */ - struct cmac_mbox mbox_c2s; /* CMAC2SYS mailbox */ - struct cmac_dcdc dcdc; /* DCDC settings */ - struct cmac_trim trim; /* Trim data */ - struct cmac_rand rand; /* Random numbers */ -#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - struct cmac_debug debug; /* Extra debug data */ -#endif -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) - struct cmac_coredump coredump; -#endif - - uint8_t mbox_s2c_buf[ MYNEWT_VAL(CMAC_MBOX_SIZE_S2C) ]; - uint8_t mbox_c2s_buf[ MYNEWT_VAL(CMAC_MBOX_SIZE_C2S) ]; -}; - -#if MYNEWT_VAL(BLE_CONTROLLER) -extern volatile struct cmac_shared_data g_cmac_shared_data; -#else -extern volatile struct cmac_shared_data *g_cmac_shared_data; -#endif - -/* cmac_mbox */ -typedef int (cmac_mbox_read_cb)(const void *data, uint16_t len); -typedef void (cmac_mbox_write_notif_cb)(void); -void cmac_mbox_set_read_cb(cmac_mbox_read_cb *cb); -void cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb); -int cmac_mbox_has_data(void); -int cmac_mbox_read(void); -int cmac_mbox_write(const void *data, uint16_t len); - -/* cmac_rand */ -typedef void (*cmac_rand_isr_cb_t)(uint8_t rnum); -void cmac_rand_start(void); -void cmac_rand_stop(void); -void cmac_rand_read(void); -void cmac_rand_write(void); -void cmac_rand_chk_fill(void); -int cmac_rand_get_next(void); -int cmac_rand_is_active(void); -int cmac_rand_is_full(void); -void cmac_rand_fill(uint32_t *buf, int num_words); -void cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb); - -void cmac_shared_init(void); -void cmac_shared_sync(void); - -#if MYNEWT_VAL(BLE_CONTROLLER) -#define CMAC_SHARED_LOCK_VAL 0xc0000000 -#else -#define CMAC_SHARED_LOCK_VAL 0x40000000 -#endif - -static inline void -cmac_shared_lock(void) -{ - volatile uint32_t *bsr_set = (void *)0x50050074; - volatile uint32_t *bsr_stat = (void *)0x5005007c; - - while ((*bsr_stat & 0xc0000000) != CMAC_SHARED_LOCK_VAL) { - *bsr_set = CMAC_SHARED_LOCK_VAL; - } -} - -static inline void -cmac_shared_unlock(void) -{ - volatile uint32_t *bsr_reset = (void *)0x50050078; - - *bsr_reset = CMAC_SHARED_LOCK_VAL; -} - -#ifdef __cplusplus -} -#endif - -#endif /* __MCU_CMAC_SHARED_H_ */ diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/pkg.yml b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/pkg.yml deleted file mode 100644 index 1fa003ab..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/pkg.yml +++ /dev/null @@ -1,39 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/transport/dialog_cmac/cmac_driver -pkg.description: Driver for Dialog CMAC IPC -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - dialog - - da1469x - - cmac - -pkg.req_apis.CMAC_DEBUG_DIAG_ENABLE: - - dialog_cmac_diag - -pkg.ign_files.BLE_CONTROLLER: - - cmac_host.c - -pkg.post_link_cmds.BLE_CONTROLLER: - scripts/create_cmac_bin.sh: 100 - -pkg.pre_link_cmds.!BLE_CONTROLLER: - scripts/build_libcmac.sh: 100 diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh deleted file mode 100755 index bbc822aa..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -NEWT=${MYNEWT_NEWT_PATH} -OBJCOPY=${MYNEWT_OBJCOPY_PATH} -AR=${MYNEWT_AR_PATH} -LIBCMAC_A=${MYNEWT_USER_SRC_DIR}/libcmac.a - -export WORK_DIR=${MYNEWT_USER_WORK_DIR} -export BASENAME_ROM=cmac.rom -export BASENAME_RAM=cmac.ram - -if [ ${MYNEWT_VAL_CMAC_IMAGE_SINGLE} -eq 0 ]; then - # Create empty binary for ROM image (1 byte required for objcopy) - truncate -s 1 ${WORK_DIR}/${BASENAME_ROM}.bin - # Create fixed size RAM image - truncate -s ${MYNEWT_VAL_CMAC_IMAGE_RAM_SIZE} ${WORK_DIR}/${BASENAME_RAM}.bin -else - ${NEWT} build ${MYNEWT_VAL_CMAC_IMAGE_TARGET_NAME} -fi - -cd ${WORK_DIR} - -# Convert both binaries to objects and create archive to link -${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \ - --rename-section .data=.libcmac.rom ${BASENAME_ROM}.bin ${BASENAME_ROM}.o -${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \ - --rename-section .data=.libcmac.ram ${BASENAME_RAM}.bin ${BASENAME_RAM}.o -${AR} -rcs ${LIBCMAC_A} ${BASENAME_ROM}.o ${BASENAME_RAM}.o diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh deleted file mode 100755 index 954d0860..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -OBJCOPY=${MYNEWT_OBJCOPY_PATH} -ELF=${MYNEWT_APP_BIN_DIR}/blehci.elf - -cd ${WORK_DIR} - -# Strip .ram section from ROM image -${OBJCOPY} -R .ram -O binary ${ELF} ${BASENAME_ROM}.bin -# RAM image is the same as binary created by newt -cp ${ELF}.bin ${BASENAME_RAM}.bin - -# Create a copy of ROM image to flash to partition, if required -cp ${BASENAME_ROM}.bin ${ELF}.rom.bin diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c deleted file mode 100644 index cdb00060..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "sysflash/sysflash.h" -#include "os/os.h" -#include "mcu/mcu.h" -#include "mcu/cmsis_nvic.h" -#include "mcu/da1469x_hal.h" -#include "mcu/da1469x_lpclk.h" -#include "mcu/da1469x_clock.h" -#include "mcu/da1469x_trimv.h" -#include "mcu/da1469x_pdc.h" -#include "cmac_driver/cmac_host.h" -#include "cmac_driver/cmac_shared.h" -#include "cmac_driver/cmac_diag.h" -#include "trng/trng.h" -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) -#include "console/console.h" -#endif - -/* CMAC data */ -extern char _binary_cmac_rom_bin_start[]; -extern char _binary_cmac_rom_bin_end; -extern char _binary_cmac_ram_bin_start[]; -extern char _binary_cmac_ram_bin_end; - -struct cmac_image_info { - uint32_t magic; - uint32_t size_rom; - uint32_t size_ram; - uint32_t offset_data; - uint32_t offset_shared; -}; - -/* PDC entry for waking up CMAC */ -static int8_t g_cmac_host_pdc_sys2cmac; -/* PDC entry for waking up M33 */ -static int8_t g_cmac_host_pdc_cmac2sys; - -static void cmac_host_rand_fill(struct os_event *ev); -static struct os_event g_cmac_host_rand_ev = { - .ev_cb = cmac_host_rand_fill -}; - -static void cmac_host_rand_chk_fill(void); - -#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) -static void cmac_host_error_w4flush(struct os_event *ev); -static struct os_event g_cmac_host_error_ev = { - .ev_cb = cmac_host_error_w4flush -}; -#endif - -static void -cmac2sys_isr(void) -{ -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) - volatile struct cmac_coredump *cd = &g_cmac_shared_data->coredump; - const char *assert_file; -#endif - - os_trace_isr_enter(); - - /* Clear CMAC2SYS interrupt */ - *(volatile uint32_t *)0x40002000 = 2; - - cmac_mbox_read(); - - if (*(volatile uint32_t *)0x40002000 & 0x1c00) { -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) - console_blocking_mode(); - console_printf("CMAC error (0x%08lx)\n", *(volatile uint32_t *)0x40002000); - console_printf(" lr:0x%08lx pc:0x%08lx\n", cd->lr, cd->pc); - if (cd->assert) { - console_printf(" assert:0x%08lx\n", cd->assert); - if (cd->assert_file) { - /* Need to translate pointer from M0 code segment to M33 data */ - assert_file = cd->assert_file + MCU_MEM_SYSRAM_START_ADDRESS + - MEMCTRL->CMI_CODE_BASE_REG; - console_printf(" %s:%d\n", - assert_file, (unsigned)cd->assert_line); - } - } - console_printf(" 0x%08lx CM_ERROR_REG\n", cd->CM_ERROR_REG); - console_printf(" 0x%08lx CM_EXC_STAT_REG\n", cd->CM_EXC_STAT_REG); - console_printf(" 0x%08lx CM_LL_TIMER1_36_10_REG\n", cd->CM_LL_TIMER1_36_10_REG); - console_printf(" 0x%08lx CM_LL_TIMER1_9_0_REG\n", cd->CM_LL_TIMER1_9_0_REG); - - /* Spin if debugger is connected to CMAC to avoid resetting it */ - if (cd->CM_STAT_REG & 0x20) { - for (;;); - } -#endif - -#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) - NVIC_DisableIRQ(CMAC2SYS_IRQn); - /* Wait until UART is flushed and then assert */ - cmac_host_error_w4flush(NULL); - return; -#endif - - /* XXX CMAC is in error state, need to recover */ - assert(0); - return; - } - - cmac_host_rand_chk_fill(); - - os_trace_isr_exit(); -} - -static void -cmac_host_rand_fill(struct os_event *ev) -{ - size_t num_bytes; - struct trng_dev *trng; - uint32_t *rnum; - uint32_t rnums[CMAC_RAND_BUF_ELEMS]; - - /* Check if full */ - if (!cmac_rand_is_active() || cmac_rand_is_full()) { - return; - } - - assert(ev->ev_arg != NULL); - - /* Fill buffer with random numbers even though we may not use all of them */ - trng = ev->ev_arg; - rnum = &rnums[0]; - num_bytes = trng_read(trng, rnum, CMAC_RAND_BUF_ELEMS * sizeof(uint32_t)); - - cmac_rand_fill(rnum, num_bytes / 4); - cmac_host_signal2cmac(); -} - -static void -cmac_host_rand_chk_fill(void) -{ - if (cmac_rand_is_active() && !cmac_rand_is_full()) { - os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_rand_ev); - } -} - -#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) -#if MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) < 0 || MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) > 2 -#error Invalid BLE_HCI_UART_PORT -#endif -static void -cmac_host_error_w4flush(struct os_event *ev) -{ - static UART_Type * const regs[] = { - (void *)UART, - (void *)UART2, - (void *)UART3 - }; - - if (!ev) { - /* Move to task context, we do not want to spin in interrupt */ - os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_error_ev); - return; - } - - do { - cmac_mbox_read(); - while ((regs[MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)]->UART_LSR_REG & - UART_UART_LSR_REG_UART_TEMT_Msk) == 0) { - /* Wait until both FIFO and shift registers are empty */ - } - } while (cmac_mbox_has_data()); - - /* Reset CMAC */ - CRG_TOP->CLK_RADIO_REG |= CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk; - - assert(0); -} -#endif - -void -cmac_host_signal2cmac(void) -{ - da1469x_pdc_set(g_cmac_host_pdc_sys2cmac); -} - -static void -cmac_host_lpclk_cb(uint32_t freq) -{ - /* No need to wakeup CMAC if LP clock frequency did not change */ - if (g_cmac_shared_data->lp_clock_freq == freq) { - return; - } - - cmac_shared_lock(); - g_cmac_shared_data->lp_clock_freq = freq; - g_cmac_shared_data->pending_ops |= CMAC_PENDING_OP_LP_CLK; - cmac_shared_unlock(); - - cmac_host_signal2cmac(); -} - -#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) -static void -cmac_host_print_trim(const char *name, const uint32_t *tv, unsigned len) -{ - console_printf("[CMAC] Trim values for '%s'\n", name); - - while (len) { - console_printf(" 0x%08x = 0x%08x\n", (unsigned)tv[0], (unsigned)tv[1]); - len -= 2; - tv += 2; - } -} -#endif - -void -cmac_host_rf_calibrate(void) -{ - cmac_shared_lock(); - g_cmac_shared_data->pending_ops |= CMAC_PENDING_OP_RF_CAL; - cmac_shared_unlock(); - - cmac_host_signal2cmac(); -} - -void -cmac_host_init(void) -{ - struct trng_dev *trng; - struct cmac_image_info ii; - uint32_t cmac_rom_size; - uint32_t cmac_ram_size; -#if !MYNEWT_VAL(CMAC_IMAGE_SINGLE) - const struct flash_area *fa; - int rc; -#endif - struct cmac_trim *trim; - - /* Get trng os device */ - trng = (struct trng_dev *) os_dev_open("trng", OS_TIMEOUT_NEVER, NULL); - assert(trng); - g_cmac_host_rand_ev.ev_arg = trng; - -#if MYNEWT_VAL(CMAC_DEBUG_DIAG_ENABLE) - cmac_diag_setup_host(); -#endif - -#if MYNEWT_VAL(CMAC_DEBUG_SWD_ENABLE) - /* Enable CMAC debugger */ - CRG_TOP->SYS_CTRL_REG |= 0x40; /* CRG_TOP_SYS_CTRL_REG_CMAC_DEBUGGER_ENABLE_Msk */ -#endif - - /* - * Add PDC entry to wake up CMAC from M33 - * - * XXX if MCU_DEBUG_GPIO_DEEP_SLEEP is enabled on CMAC, this should also - * enable PD_COM so CMAC can access GPIOs after wake up - */ - g_cmac_host_pdc_sys2cmac = da1469x_pdc_add(MCU_PDC_TRIGGER_MAC_TIMER, - MCU_PDC_MASTER_CMAC, - MCU_PDC_EN_XTAL); - da1469x_pdc_set(g_cmac_host_pdc_sys2cmac); - da1469x_pdc_ack(g_cmac_host_pdc_sys2cmac); - - /* Add PDC entry to wake up M33 from CMAC, if does not exist yet */ - g_cmac_host_pdc_cmac2sys = da1469x_pdc_find(MCU_PDC_TRIGGER_COMBO, - MCU_PDC_MASTER_M33, 0); - if (g_cmac_host_pdc_cmac2sys < 0) { - g_cmac_host_pdc_cmac2sys = da1469x_pdc_add(MCU_PDC_TRIGGER_COMBO, - MCU_PDC_MASTER_M33, - MCU_PDC_EN_XTAL); - da1469x_pdc_set(g_cmac_host_pdc_cmac2sys); - da1469x_pdc_ack(g_cmac_host_pdc_cmac2sys); - } - - /* Setup CMAC2SYS interrupt */ - NVIC_SetVector(CMAC2SYS_IRQn, (uint32_t)cmac2sys_isr); - NVIC_SetPriority(CMAC2SYS_IRQn, MYNEWT_VAL(CMAC_CMAC2SYS_IRQ_PRIORITY)); - NVIC_DisableIRQ(CMAC2SYS_IRQn); - - /* Enable Radio LDO */ - CRG_TOP->POWER_CTRL_REG |= CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Msk; - - /* Enable CMAC, but keep it in reset */ - CRG_TOP->CLK_RADIO_REG = (1 << CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Pos) | - (1 << CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Pos) | - (0 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Pos) | - (1 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Pos) | - (0 << CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Pos); - - /* Calculate size of ROM and RAM area */ - cmac_rom_size = &_binary_cmac_rom_bin_end - &_binary_cmac_rom_bin_start[0]; - cmac_ram_size = &_binary_cmac_ram_bin_end - &_binary_cmac_ram_bin_start[0]; - - /* Load image header and check if image can be loaded */ -#if MYNEWT_VAL(CMAC_IMAGE_SINGLE) - memcpy(&ii, &_binary_cmac_rom_bin_start[128], sizeof(ii)); -#else - rc = flash_area_open(FLASH_AREA_IMAGE_1, &fa); - assert(rc == 0); - rc = flash_area_read(fa, 128, &ii, sizeof(ii)); - assert(rc == 0); -#endif - - assert(ii.magic == 0xC3ACC3AC); - assert(ii.size_rom == cmac_rom_size); - assert(ii.size_ram <= cmac_ram_size); - - /* Copy CMAC image to RAM */ -#if MYNEWT_VAL(CMAC_IMAGE_SINGLE) - memset(&_binary_cmac_ram_bin_start, 0xaa, cmac_ram_size); - memcpy(&_binary_cmac_ram_bin_start, &_binary_cmac_rom_bin_start, ii.size_rom); -#else - memset(&_binary_cmac_ram_bin_start, 0xaa, cmac_ram_size); - rc = flash_area_read(fa, 0, &_binary_cmac_ram_bin_start, ii.size_rom); - assert(rc == 0); -#endif - - /* Setup CMAC memory addresses */ - MEMCTRL->CMI_CODE_BASE_REG = (uint32_t)&_binary_cmac_ram_bin_start; - MEMCTRL->CMI_DATA_BASE_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.offset_data; - MEMCTRL->CMI_SHARED_BASE_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.offset_shared; - MEMCTRL->CMI_END_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.size_ram - 1; - - /* Initialize shared memory */ - cmac_shared_init(); - - trim = (struct cmac_trim *)&g_cmac_shared_data->trim; - trim->rfcu_len = da1469x_trimv_group_read(6, trim->rfcu, ARRAY_SIZE(trim->rfcu)); - trim->rfcu_mode1_len = da1469x_trimv_group_read(8, trim->rfcu_mode1, ARRAY_SIZE(trim->rfcu_mode1)); - trim->rfcu_mode2_len = da1469x_trimv_group_read(10, trim->rfcu_mode2, ARRAY_SIZE(trim->rfcu_mode2)); - trim->synth_len = da1469x_trimv_group_read(7, trim->synth, ARRAY_SIZE(trim->synth)); - -#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) - cmac_host_print_trim("rfcu", trim->rfcu, trim->rfcu_len); - cmac_host_print_trim("rfcu_mode1", trim->rfcu_mode1, trim->rfcu_mode1_len); - cmac_host_print_trim("rfcu_mode2", trim->rfcu_mode2, trim->rfcu_mode2_len); - cmac_host_print_trim("synth", trim->synth, trim->synth_len); -#endif - - /* Release CMAC from reset and sync */ - CRG_TOP->CLK_RADIO_REG &= ~CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk; - cmac_shared_sync(); - - da1469x_lpclk_register_cmac_cb(cmac_host_lpclk_cb); - -#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) && MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - /* Trim values are calculated on RF init, so are valid after synced with CMAC */ - console_printf("[CMAC] Calculated trim_val1: 1=0x%08x 2=0x%08x\n", - (unsigned)g_cmac_shared_data->debug.trim_val1_tx_1, - (unsigned)g_cmac_shared_data->debug.trim_val1_tx_2); - console_printf("[CMAC] Calculated trim_val2: tx=0x%08x rx=0x%08x\n", - (unsigned)g_cmac_shared_data->debug.trim_val2_tx, - (unsigned)g_cmac_shared_data->debug.trim_val2_rx); -#endif -} diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c deleted file mode 100644 index d2ee9ac9..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "mcu/mcu.h" -#include "os/os_arch.h" -#include "os/os.h" - -#ifndef min -#define min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#endif - -static cmac_mbox_read_cb *g_cmac_mbox_read_cb; -static cmac_mbox_write_notif_cb *g_cmac_mbox_write_notif_cb; - -void -cmac_mbox_set_read_cb(cmac_mbox_read_cb *cb) -{ - g_cmac_mbox_read_cb = cb; -} - -void -cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb) -{ - g_cmac_mbox_write_notif_cb = cb; -} - -int -cmac_mbox_has_data(void) -{ -#if MYNEWT_VAL(BLE_CONTROLLER) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c; -#else - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; -#endif - - return mbox->rd_off != mbox->wr_off; -} - -int -cmac_mbox_read(void) -{ -#if MYNEWT_VAL(BLE_CONTROLLER) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_s2c_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); -#else - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_c2s_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); -#endif - uint16_t rd_off; - uint16_t wr_off; - uint16_t chunk; - int len = 0; - - if (!g_cmac_mbox_read_cb) { - return 0; - } - - do { - rd_off = mbox->rd_off; - wr_off = mbox->wr_off; - - if (rd_off <= wr_off) { - chunk = wr_off - rd_off; - } else { - chunk = mbox_size - rd_off; - } - - while (chunk) { - len = g_cmac_mbox_read_cb(&mbox_buf[rd_off], chunk); - if (len < 0) { - break; - } - - rd_off += len; - chunk -= len; - } - - mbox->rd_off = rd_off == mbox_size ? 0 : rd_off; - } while ((mbox->rd_off != mbox->wr_off) && (len >= 0)); - - return 0; -} - -int -cmac_mbox_write(const void *data, uint16_t len) -{ -#if MYNEWT_VAL(BLE_CONTROLLER) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_c2s; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_c2s_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); -#else - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_s2c; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_s2c_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); -#endif - uint16_t rd_off; - uint16_t wr_off; - uint16_t max_wr; - uint16_t chunk; - - while (len) { - rd_off = mbox->rd_off; - wr_off = mbox->wr_off; - - /* - * Calculate maximum length to write, i.e. up to end of buffer or stop - * before rd_off to be able to detect full queue. - */ - if (rd_off > wr_off) { - /* - * |0|1|2|3|4|5|6|7| - * | | | |W| | |R| | - * `---^ - */ - max_wr = rd_off - wr_off - 1; - } else if (rd_off == 0) { - /* - * |0|1|2|3|4|5|6|7| - * |R| | |W| | | | | - * `-------^ - */ - max_wr = mbox_size - wr_off - 1; - } else { - /* - * |0|1|2|3|4|5|6|7| - * | |R| |W| | | | | - * `---------^ - */ - max_wr = mbox_size - wr_off; - } - - chunk = min(len, max_wr); - - if (chunk == 0) { - continue; - } - - memcpy(&mbox_buf[wr_off], data, chunk); - - wr_off += chunk; - mbox->wr_off = wr_off == mbox_size ? 0 : wr_off; - - g_cmac_mbox_write_notif_cb(); - - len -= chunk; - data = (uint8_t *)data + chunk; - } - - return 0; -} diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c deleted file mode 100644 index dbb93e92..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "mcu/mcu.h" -#include "os/os_arch.h" -#include "os/os.h" - -#if !MYNEWT_VAL(BLE_CONTROLLER) -int -cmac_rand_is_active(void) -{ - return g_cmac_shared_data->rand.cmr_active; -} - -int -cmac_rand_is_full(void) -{ - int next; - bool rc; - - next = cmac_rand_get_next(); - if (next == g_cmac_shared_data->rand.cmr_out) { - rc = 1; - } else { - rc = 0; - } - return rc; -} - -int -cmac_rand_get_next(void) -{ - int next; - - /* If active and not full, put event on queue to get random numbers */ - next = g_cmac_shared_data->rand.cmr_in + 1; - if (next == CMAC_RAND_BUF_ELEMS) { - next = 0; - } - return next; -} - -void -cmac_rand_fill(uint32_t *buf, int num_words) -{ - int next; - - /* XXX: if words is 0, is it possible we could get into a state - where we are waiting for random numbers but M33 does not know it - has to fill any? */ - - /* NOTE: we already know the buffer is not full first time through */ - next = g_cmac_shared_data->rand.cmr_in; - while (num_words) { - g_cmac_shared_data->rand.cmr_buf[next] = buf[0]; - next = cmac_rand_get_next(); - g_cmac_shared_data->rand.cmr_in = next; - next = cmac_rand_get_next(); - if (next == g_cmac_shared_data->rand.cmr_out) { - break; - } - --num_words; - ++buf; - } -} -#endif - -#if MYNEWT_VAL(BLE_CONTROLLER) -static cmac_rand_isr_cb_t g_cmac_rand_isr_cb; - -void -cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb) -{ - g_cmac_rand_isr_cb = cb; -} - -void -cmac_rand_start(void) -{ - g_cmac_shared_data.rand.cmr_active = 1; -} - -void -cmac_rand_stop(void) -{ - g_cmac_shared_data.rand.cmr_active = 0; -} - -/** - * cmac rnum read - * - * Called during the system to cmac isr to take random numbers - * from shared memory into the BLE stack. - */ -void -cmac_rand_read(void) -{ - uint8_t bytes_left; - uint32_t rnum; - - /* Just leave if no callback. */ - if (g_cmac_rand_isr_cb == NULL) { - return; - } - - bytes_left = 0; - while (g_cmac_shared_data.rand.cmr_active) { - if (bytes_left) { - --bytes_left; - rnum >>= 8; - } else if (g_cmac_shared_data.rand.cmr_out != g_cmac_shared_data.rand.cmr_in) { - bytes_left = 3; - rnum = g_cmac_shared_data.rand.cmr_buf[g_cmac_shared_data.rand.cmr_out]; - ++g_cmac_shared_data.rand.cmr_out; - if (g_cmac_shared_data.rand.cmr_out == CMAC_RAND_BUF_ELEMS) { - g_cmac_shared_data.rand.cmr_out = 0; - } - } else { - break; - } - (*g_cmac_rand_isr_cb)((uint8_t)rnum); - } -} -#endif diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c deleted file mode 100644 index cd7984af..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include "syscfg/syscfg.h" -#if MYNEWT_VAL(BLE_CONTROLLER) && !MYNEWT_VAL(MCU_DEBUG_DSER_CMAC_SHARED) -#define MCU_DIAG_SER_DISABLE -#endif - -#include -#include -#include -#include "mcu/mcu.h" -#include -#include "os/os_arch.h" -#include "os/os.h" - -#ifndef min -#define min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#endif - -#if MYNEWT_VAL(BLE_CONTROLLER) -volatile struct cmac_shared_data g_cmac_shared_data __attribute__((section(".shdata"))); -#else -volatile struct cmac_shared_data *g_cmac_shared_data; -#include "mcu/da1469x_clock.h" -#define MCU_DIAG_SER(_x) -#endif - -void -cmac_shared_init(void) -{ -#if !MYNEWT_VAL(BLE_CONTROLLER) - g_cmac_shared_data = (void *)(MCU_MEM_SYSRAM_START_ADDRESS + - MEMCTRL->CMI_SHARED_BASE_REG); - - memset((void *)g_cmac_shared_data, 0, sizeof(*g_cmac_shared_data)); - - g_cmac_shared_data->xtal32m_settle_us = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US); - - g_cmac_shared_data->dcdc.enabled = DCDC->DCDC_CTRL1_REG & DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk; - if (g_cmac_shared_data->dcdc.enabled) { - g_cmac_shared_data->dcdc.v18 = DCDC->DCDC_V18_REG; - g_cmac_shared_data->dcdc.v18p = DCDC->DCDC_V18P_REG; - g_cmac_shared_data->dcdc.vdd = DCDC->DCDC_VDD_REG; - g_cmac_shared_data->dcdc.v14 = DCDC->DCDC_V14_REG; - g_cmac_shared_data->dcdc.ctrl1 = DCDC->DCDC_CTRL1_REG; - } - -#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - g_cmac_shared_data->debug.tx_power_override = INT8_MAX; -#endif -#endif -} - - -void -cmac_shared_sync(void) -{ - /* - * We need to guarantee proper order of initialization here, i.e. SYS has - * to wait until CMAC finished initialization as otherwise host may start - * sending HCI packets which will timeout as there is no one to read them. - */ -#if MYNEWT_VAL(BLE_CONTROLLER) - assert(g_cmac_shared_data.magic_cmac == 0); - - g_cmac_shared_data.magic_cmac = CMAC_SHARED_MAGIC_CMAC; - while (g_cmac_shared_data.magic_sys != CMAC_SHARED_MAGIC_SYS); - - NVIC_SetPriority(SYS2CMAC_IRQn, 3); - NVIC_EnableIRQ(SYS2CMAC_IRQn); -#else - assert(g_cmac_shared_data->magic_sys == 0); - - while (g_cmac_shared_data->magic_cmac != CMAC_SHARED_MAGIC_CMAC); - g_cmac_shared_data->magic_sys = CMAC_SHARED_MAGIC_SYS; - - NVIC_EnableIRQ(CMAC2SYS_IRQn); -#endif -} diff --git a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml deleted file mode 100644 index 6ff3b440..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml +++ /dev/null @@ -1,104 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - CMAC_MBOX_SIZE_S2C: - description: > - Size of mailbox for SYS to CMAC data. The size - value should be power of 2 to allow for better - code optimization. - value: 128 - CMAC_MBOX_SIZE_C2S: - description: > - Size of mailbox for CMAC to SYS data. The size - value should be power of 2 to allow for better - code optimization. - value: 128 - - CMAC_TRIM_SIZE_RFCU: - description: > - Size of trim values for RFCU. This is maximum - number of trim values that can be read from - OTP and applied, all excessive values will be - discarded. - value: 10 - CMAC_TRIM_SIZE_SYNTH: - description: > - Size of trim values for RFCU. This is maximum - number of trim values that can be read from - OTP and applied, all excessive values will be - discarded. - value: 10 - - CMAC_DEBUG_SWD_ENABLE: - description: > - Enable CMAC SWD interface. - value: 0 - CMAC_DEBUG_DIAG_ENABLE: - description: > - Enable CMAC diagnostic lines. - value: 0 - CMAC_DEBUG_DATA_ENABLE: - description: > - Enable extra debugging data in shared segment. - value: 0 - CMAC_DEBUG_COREDUMP_ENABLE: - description: > - Enable dumping CMAC registers to shared segment - on fault. - value: 1 - CMAC_DEBUG_HOST_PRINT_ENABLE: - description: > - Enable some debug printouts to console from host side. - This will dump some settings during startup, useful to - check what is loaded to CMAC via shared data. - value: 0 - - CMAC_IMAGE_SINGLE: - description: > - When enable, CMAC binary is linked with application image - creating a single image build. See CMAC_IMAGE_TARGET_NAME. - When disabled, CMAC binary is built and flashed separately - to flash partition. See CMAC_IMAGE_PARTITION. - value: 1 - CMAC_IMAGE_TARGET_NAME: - description: > - Target name to build for CMAC binary for single image build. - value: "@apache-mynewt-nimble/targets/dialog_cmac" - CMAC_IMAGE_PARTITION: - description: > - Flash partition to load CMAC binary from if single image build - is disabled. - value: FLASH_AREA_IMAGE_1 - CMAC_IMAGE_RAM_SIZE: - description: > - Size of RAM area in bytes reserved for CMAC if single image - build is disabled. Unit suffix (K, M) is allowed. - Note: for single image build this setting is not applicable - since proper RAM area size is automatically calculated from - CMAC binary. - value: 128K - - CMAC_CMAC2SYS_IRQ_PRIORITY: - description: > - The priority of the CMAC2SYS IRQ. Default is 0, or highest - priority. - value: 0 - -syscfg.restrictions.!BLE_CONTROLLER: - - TRNG diff --git a/lib/bt/host/nimble/nimble/nimble/transport/esp_ipc/src/hci_esp_ipc.c b/lib/bt/host/nimble/nimble/nimble/transport/esp_ipc/src/hci_esp_ipc.c new file mode 100644 index 00000000..22f589a2 --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/transport/esp_ipc/src/hci_esp_ipc.c @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include "os/os_mbuf.h" +#include "nimble/transport.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" + +static int +ble_transport_dummy_host_recv_cb(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len) +{ + /* Dummy function */ + return 0; +} + +static int +ble_transport_host_recv_cb(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len) +{ + int rc; + + if (type == HCI_ACL_IND) { + rc = ble_transport_to_hs_acl((struct os_mbuf *)data); + } else { + rc = ble_transport_to_hs_evt(data); + } + return rc; +} + +int +ble_transport_to_ll_cmd_impl(void *buf) +{ + return hci_transport_host_cmd_tx(buf, 0); +} + +int +ble_transport_to_ll_acl_impl(struct os_mbuf *om) +{ + return hci_transport_host_acl_tx((uint8_t *)om, 0); +} + +void +ble_transport_ll_init(void) +{ + hci_transport_host_callback_register(ble_transport_host_recv_cb); +} + +void +ble_transport_ll_deinit(void) +{ + hci_transport_host_callback_register(ble_transport_dummy_host_recv_cb); +} + +void * +ble_transport_alloc_cmd(void) +{ + return r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD); +} + +void +ble_transport_free(void *buf) +{ + r_ble_hci_trans_buf_free(buf); +} diff --git a/lib/bt/host/nimble/nimble/nimble/transport/esp_ipc_legacy/src/hci_esp_ipc_legacy.c b/lib/bt/host/nimble/nimble/nimble/transport/esp_ipc_legacy/src/hci_esp_ipc_legacy.c new file mode 100644 index 00000000..323f4d75 --- /dev/null +++ b/lib/bt/host/nimble/nimble/nimble/transport/esp_ipc_legacy/src/hci_esp_ipc_legacy.c @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include "nimble/transport.h" +#include "esp_nimble_hci.h" + +/* This file is only used by ESP32, ESP32C3 and ESP32S3. */ +int +ble_transport_to_ll_cmd_impl(void *buf) +{ + return ble_hci_trans_hs_cmd_tx(buf); +} + +int +ble_transport_to_ll_acl_impl(struct os_mbuf *om) +{ + return ble_hci_trans_hs_acl_tx(om); +} + +void +ble_transport_ll_init(void) +{ + +} + +void +ble_transport_ll_deinit(void) +{ + +} + diff --git a/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport.h b/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport.h index b4ca3db2..dcdebcc0 100644 --- a/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport.h +++ b/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport.h @@ -76,154 +76,6 @@ void ble_transport_deinit(void); typedef int ble_hci_trans_rx_cmd_fn(uint8_t *cmd, void *arg); typedef int ble_hci_trans_rx_acl_fn(struct os_mbuf *om, void *arg); -#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED -#define ble_transport_alloc_cmd() ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD) -#define ble_transport_alloc_event(X) ble_hci_trans_buf_alloc(X ? BLE_HCI_TRANS_BUF_EVT_LO : BLE_HCI_TRANS_BUF_EVT_HI) -#define ble_transport_free ble_hci_trans_buf_free - -struct ble_hci_trans_funcs_t { - int(*_ble_hci_trans_hs_acl_tx)(struct os_mbuf *om); - int(*_ble_hci_trans_hs_cmd_tx)(uint8_t *cmd); - int(*_ble_hci_trans_ll_acl_tx)(struct os_mbuf *om); - int(*_ble_hci_trans_ll_evt_tx)(uint8_t *hci_ev); - int(*_ble_hci_trans_reset)(void); - int(*_ble_hci_trans_set_acl_free_cb)(os_mempool_put_fn *cb,void *arg); -}; - -extern struct ble_hci_trans_funcs_t *ble_hci_trans_funcs_ptr; - -/** - * Sends an HCI event from the controller to the host. - * - * @param cmd The HCI event to send. This buffer must be - * allocated via ble_hci_trans_buf_alloc(). - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ -extern int r_ble_hci_trans_ll_evt_tx(uint8_t *hci_ev); -#define ble_hci_trans_ll_evt_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_ll_evt_tx - -/** - * Sends ACL data from controller to host. - * - * @param om The ACL data packet to send. - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ -extern int r_ble_hci_trans_ll_acl_tx(struct os_mbuf *om); -#define ble_hci_trans_ll_acl_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_ll_acl_tx - -/** - * Sends an HCI command from the host to the controller. - * - * @param cmd The HCI command to send. This buffer must be - * allocated via ble_hci_trans_buf_alloc(). - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ -extern int r_ble_hci_trans_hs_cmd_tx(uint8_t *cmd); -#define ble_hci_trans_hs_cmd_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_hs_cmd_tx - -/** - * Sends ACL data from host to controller. - * - * @param om The ACL data packet to send. - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ -extern int r_ble_hci_trans_hs_acl_tx(struct os_mbuf *om); -#define ble_hci_trans_hs_acl_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_hs_acl_tx - -/** - * Allocates a flat buffer of the specified type. - * - * @param type The type of buffer to allocate; one of the - * BLE_HCI_TRANS_BUF_[...] constants. - * - * @return The allocated buffer on success; - * NULL on buffer exhaustion. - */ -extern uint8_t *r_ble_hci_trans_buf_alloc(int type); -#define ble_hci_trans_buf_alloc r_ble_hci_trans_buf_alloc - -/** - * Frees the specified flat buffer. The buffer must have been allocated via - * ble_hci_trans_buf_alloc(). - * - * @param buf The buffer to free. - */ -extern void r_ble_hci_trans_buf_free(uint8_t *buf); -#define ble_hci_trans_buf_free r_ble_hci_trans_buf_free - -/** - * Configures a callback to get executed whenever an ACL data packet is freed. - * The function is called immediately before the free occurs. - * - * @param cb The callback to configure. - * @param arg An optional argument to pass to the callback. - * - * @return 0 on success; - * BLE_ERR_UNSUPPORTED if the transport does not - * support this operation. - */ -extern int r_ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg); -#define ble_hci_trans_set_acl_free_cb ble_hci_trans_funcs_ptr->_ble_hci_trans_set_acl_free_cb - -/** - * Configures the HCI transport to operate with a controller. The transport - * will execute specified callbacks upon receiving HCI packets from the host. - * - * @param cmd_cb The callback to execute upon receiving an HCI - * command. - * @param cmd_arg Optional argument to pass to the command - * callback. - * @param acl_cb The callback to execute upon receiving ACL - * data. - * @param acl_arg Optional argument to pass to the ACL - * callback. - */ -extern void r_ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, - void *cmd_arg, - ble_hci_trans_rx_acl_fn *acl_cb, - void *acl_arg); -#define ble_hci_trans_cfg_ll r_ble_hci_trans_cfg_ll - -/** - * Configures the HCI transport to operate with a host. The transport will - * execute specified callbacks upon receiving HCI packets from the controller. - * - * @param evt_cb The callback to execute upon receiving an HCI - * event. - * @param evt_arg Optional argument to pass to the event - * callback. - * @param acl_cb The callback to execute upon receiving ACL - * data. - * @param acl_arg Optional argument to pass to the ACL - * callback. - */ -extern void r_ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, - void *evt_arg, - ble_hci_trans_rx_acl_fn *acl_cb, - void *acl_arg); -#define ble_hci_trans_cfg_hs r_ble_hci_trans_cfg_hs - -/** - * Resets the HCI module to a clean state. Frees all buffers and reinitializes - * the underlying transport. - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ -extern int r_ble_hci_trans_reset(void); -#define ble_hci_trans_reset ble_hci_trans_funcs_ptr->_ble_hci_trans_reset - -void esp_ble_hci_trans_init(uint8_t); - -#else /** * Sends an HCI event from the controller to the host. * @@ -332,14 +184,13 @@ void esp_ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, * A BLE_ERR_[...] error code on failure. */ int esp_ble_hci_trans_reset(void); -#endif + struct os_mbuf; /* Initialization */ void ble_transport_init(void); /* Allocators for supported data types */ -#if !SOC_ESP_NIMBLE_CONTROLLER || !CONFIG_BT_CONTROLLER_ENABLED void *ble_transport_alloc_cmd(void); void *ble_transport_alloc_evt(int discardable); struct os_mbuf *ble_transport_alloc_acl_from_hs(void); @@ -349,18 +200,13 @@ struct os_mbuf *ble_transport_alloc_iso_from_ll(void); /* Generic deallocator for cmd/evt buffers */ void ble_transport_free(void *buf); -#endif /* Register put callback on acl_from_ll mbufs (for ll-hs flow control) */ int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn *cb); -#if CONFIG_BT_CONTROLLER_ENABLED -#define ble_transport_to_ll_acl ble_hci_trans_hs_acl_tx -#define ble_transport_to_ll_cmd ble_hci_trans_hs_cmd_tx -#else + int ble_transport_to_ll_cmd(void *buf); int ble_transport_to_ll_acl(struct os_mbuf *om); -#endif /* Send data to hs/ll side */ int ble_transport_to_ll_iso(struct os_mbuf *om); diff --git a/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport_impl.h b/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport_impl.h index d5973378..1faec316 100644 --- a/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport_impl.h +++ b/lib/bt/host/nimble/nimble/nimble/transport/include/nimble/transport_impl.h @@ -31,6 +31,8 @@ extern "C" { extern void ble_transport_ll_init(void); extern void ble_transport_hs_init(void); +extern void ble_transport_ll_deinit(void); + /* APIs to be implemented by HS/LL side of transports */ extern int ble_transport_to_ll_cmd_impl(void *buf); extern int ble_transport_to_ll_acl_impl(struct os_mbuf *om); diff --git a/lib/bt/host/nimble/nimble/nimble/transport/nrf5340/syscfg.yml b/lib/bt/host/nimble/nimble/nimble/transport/nrf5340/syscfg.yml deleted file mode 100644 index e8334f2a..00000000 --- a/lib/bt/host/nimble/nimble/nimble/transport/nrf5340/syscfg.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_TRANSPORT_INT_FLOW_CTL: 1 diff --git a/lib/bt/host/nimble/nimble/nimble/transport/uart_ll/src/hci_uart.c b/lib/bt/host/nimble/nimble/nimble/transport/uart_ll/src/hci_uart.c index 95eae3f4..4cd9de3f 100644 --- a/lib/bt/host/nimble/nimble/nimble/transport/uart_ll/src/hci_uart.c +++ b/lib/bt/host/nimble/nimble/nimble/transport/uart_ll/src/hci_uart.c @@ -243,3 +243,13 @@ ble_transport_ll_init(void) STAILQ_INIT(&tx_q); } + +void +ble_transport_ll_deinit(void) +{ + memset(&hci_uart_h4sm, 0, sizeof(hci_uart_h4sm)); + + hal_uart_close(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + + hal_uart_deinit_cbs(); +} diff --git a/lib/bt/host/nimble/nimble/porting/examples/linux/include/logcfg/logcfg.h b/lib/bt/host/nimble/nimble/porting/examples/linux/include/logcfg/logcfg.h index 89af3530..9872da0b 100644 --- a/lib/bt/host/nimble/nimble/porting/examples/linux/include/logcfg/logcfg.h +++ b/lib/bt/host/nimble/nimble/porting/examples/linux/include/logcfg/logcfg.h @@ -8,6 +8,13 @@ #include "modlog/modlog.h" #include "log_common/log_common.h" +#define BLE_EATT_LOG_DEBUG(...) MODLOG_INFO(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) #define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) diff --git a/lib/bt/host/nimble/nimble/porting/examples/linux/include/syscfg/syscfg.h b/lib/bt/host/nimble/nimble/porting/examples/linux/include/syscfg/syscfg.h index d089d7e6..d825fd01 100644 --- a/lib/bt/host/nimble/nimble/porting/examples/linux/include/syscfg/syscfg.h +++ b/lib/bt/host/nimble/nimble/porting/examples/linux/include/syscfg/syscfg.h @@ -535,6 +535,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -575,6 +579,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif @@ -615,6 +635,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/logcfg/logcfg.h b/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/logcfg/logcfg.h index 520c658c..99afa084 100644 --- a/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/logcfg/logcfg.h +++ b/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/logcfg/logcfg.h @@ -8,6 +8,13 @@ #include "modlog/modlog.h" #include "log_common/log_common.h" +#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) #define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) diff --git a/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 1df8abaf..37742846 100644 --- a/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/lib/bt/host/nimble/nimble/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -536,6 +536,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -576,6 +580,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif @@ -616,6 +636,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/lib/bt/host/nimble/nimble/porting/examples/nuttx/include/syscfg/syscfg.h b/lib/bt/host/nimble/nimble/porting/examples/nuttx/include/syscfg/syscfg.h index 51f8c44b..a51319c0 100644 --- a/lib/bt/host/nimble/nimble/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/lib/bt/host/nimble/nimble/porting/examples/nuttx/include/syscfg/syscfg.h @@ -615,6 +615,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/lib/bt/host/nimble/nimble/porting/nimble/include/hal/hal_uart.h b/lib/bt/host/nimble/nimble/porting/nimble/include/hal/hal_uart.h index 424d296e..8673c776 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/include/hal/hal_uart.h +++ b/lib/bt/host/nimble/nimble/porting/nimble/include/hal/hal_uart.h @@ -50,6 +50,11 @@ typedef int (*hal_uart_rx_char)(void *arg, uint8_t byte); int hal_uart_init_cbs(int uart, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done, hal_uart_rx_char rx_func, void *arg); +/** + * De Initialize already registerd callbacks + */ +void hal_uart_deinit_cbs(void); + enum hal_uart_parity { /** No Parity */ HAL_UART_PARITY_NONE = 0, diff --git a/lib/bt/host/nimble/nimble/porting/nimble/include/logcfg/logcfg.h b/lib/bt/host/nimble/nimble/porting/nimble/include/logcfg/logcfg.h index f2f227c8..14633c52 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/include/logcfg/logcfg.h +++ b/lib/bt/host/nimble/nimble/porting/nimble/include/logcfg/logcfg.h @@ -166,4 +166,11 @@ #define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) #define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) +#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #endif diff --git a/lib/bt/host/nimble/nimble/porting/nimble/include/os/os.h b/lib/bt/host/nimble/nimble/porting/nimble/include/os/os.h index ec495df9..64800956 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/include/os/os.h +++ b/lib/bt/host/nimble/nimble/porting/nimble/include/os/os.h @@ -30,14 +30,6 @@ extern "C" { #define static_assert _Static_assert #endif -#ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) -#endif - -#ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) -#endif - #include "syscfg/syscfg.h" #include "nimble/nimble_npl.h" diff --git a/lib/bt/host/nimble/nimble/porting/nimble/include/syscfg/syscfg.h b/lib/bt/host/nimble/nimble/porting/nimble/include/syscfg/syscfg.h index cc8a60b3..158f3846 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/include/syscfg/syscfg.h +++ b/lib/bt/host/nimble/nimble/porting/nimble/include/syscfg/syscfg.h @@ -538,6 +538,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -578,6 +582,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif @@ -618,6 +638,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/lib/bt/host/nimble/nimble/porting/nimble/src/hal_uart.c b/lib/bt/host/nimble/nimble/porting/nimble/src/hal_uart.c index 8a2a957e..89ef558f 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/src/hal_uart.c +++ b/lib/bt/host/nimble/nimble/porting/nimble/src/hal_uart.c @@ -43,6 +43,14 @@ int hal_uart_init_cbs(int uart_no, hal_uart_tx_char tx_func, return 0; } +void hal_uart_deinit_cbs(void) +{ + hci_uart.tx_char = NULL; + hci_uart.rx_char = NULL; + hci_uart.tx_done = NULL; + hci_uart.u_func_arg = NULL; +} + static void IRAM_ATTR hci_uart_rx_task(void *pvParameters) { uart_event_t event; diff --git a/lib/bt/host/nimble/nimble/porting/nimble/src/nimble_port.c b/lib/bt/host/nimble/nimble/porting/nimble/src/nimble_port.c index 87059f23..224ffde8 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/src/nimble_port.c +++ b/lib/bt/host/nimble/nimble/porting/nimble/src/nimble_port.c @@ -122,11 +122,10 @@ esp_err_t esp_nimble_init(void) os_msys_init(); #endif + + ble_transport_ll_init(); /* Initialize the host */ ble_transport_hs_init(); -#if CONFIG_BT_CONTROLLER_DISABLED && CONFIG_BT_NIMBLE_TRANSPORT_UART - ble_transport_ll_init(); -#endif return ESP_OK; } @@ -158,6 +157,12 @@ esp_err_t esp_nimble_deinit(void) #if !SOC_ESP_NIMBLE_CONTROLLER || !CONFIG_BT_CONTROLLER_ENABLED npl_freertos_funcs_deinit(); #endif + +#if !SOC_ESP_NIMBLE_CONTROLLER + npl_freertos_mempool_deinit(); +#endif + + ble_transport_ll_deinit(); return ESP_OK; } @@ -213,7 +218,7 @@ nimble_port_init(void) return ret; } -#if (BT_HCI_LOG_INCLUDED == TRUE) +#if MYNEWT_VAL(BT_HCI_LOG_INCLUDED) bt_hci_log_init(); #endif // (BT_HCI_LOG_INCLUDED == TRUE) diff --git a/lib/bt/host/nimble/nimble/porting/nimble/src/os_mbuf.c b/lib/bt/host/nimble/nimble/porting/nimble/src/os_mbuf.c index 8832fd2d..0a94ee40 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/src/os_mbuf.c +++ b/lib/bt/host/nimble/nimble/porting/nimble/src/os_mbuf.c @@ -35,6 +35,8 @@ #include "os/os.h" #include "os/os_trace_api.h" +#include "modlog/modlog.h" +#include "esp_log.h" #include #include @@ -59,6 +61,7 @@ STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = STAILQ_HEAD_INITIALIZER(g_msys_pool_list); +static uint8_t log_count; int os_mqueue_init(struct os_mqueue *mq, ble_npl_event_fn *ev_cb, void *arg) @@ -186,6 +189,12 @@ os_msys_get(uint16_t dsize, uint16_t leadingspace) m = os_mbuf_get(pool, leadingspace); return (m); err: + log_count ++; + if ((log_count % 100) == 0) { + ESP_LOGI("ESP_LOG_INFO","_os_msys_find_pool failed (size %u)\n",dsize); + log_count = 0; + } + return (NULL); } @@ -205,6 +214,11 @@ os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len) m = os_mbuf_get_pkthdr(pool, user_hdr_len); return (m); err: + log_count ++; + if ((log_count % 100) == 0) { + ESP_LOGI("ESP_LOG_INFO","_os_msys_find_pool failed (size %u)\n",dsize); + log_count = 0; + } return (NULL); } diff --git a/lib/bt/host/nimble/nimble/porting/nimble/src/os_mempool.c b/lib/bt/host/nimble/nimble/porting/nimble/src/os_mempool.c index 79630bae..96b2992c 100644 --- a/lib/bt/host/nimble/nimble/porting/nimble/src/os_mempool.c +++ b/lib/bt/host/nimble/nimble/porting/nimble/src/os_mempool.c @@ -24,6 +24,7 @@ #include #include #include "syscfg/syscfg.h" +#include "modlog/modlog.h" #if !MYNEWT_VAL(OS_SYSVIEW_TRACE_MEMPOOL) #define OS_TRACE_DISABLE_FILE_API #endif diff --git a/lib/bt/host/nimble/nimble/porting/npl/freertos/include/nimble/nimble_port_freertos.h b/lib/bt/host/nimble/nimble/porting/npl/freertos/include/nimble/nimble_port_freertos.h index 4ac011f8..5bc86acb 100644 --- a/lib/bt/host/nimble/nimble/porting/npl/freertos/include/nimble/nimble_port_freertos.h +++ b/lib/bt/host/nimble/nimble/porting/npl/freertos/include/nimble/nimble_port_freertos.h @@ -48,6 +48,7 @@ void nimble_port_freertos_deinit(void); void npl_freertos_funcs_init(void); void npl_freertos_funcs_deinit(void); int npl_freertos_mempool_init(void); +void npl_freertos_mempool_deinit(void); struct npl_funcs_t * npl_freertos_funcs_get(void); #ifdef __cplusplus } diff --git a/lib/bt/host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c b/lib/bt/host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c index d72f0f6e..0a434e14 100644 --- a/lib/bt/host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c +++ b/lib/bt/host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c @@ -109,6 +109,17 @@ static const char *TAG = "Timer"; struct os_mempool ble_freertos_ev_pool; static os_membuf_t *ble_freertos_ev_buf = NULL; +#else + +struct os_mempool ble_freertos_ev_pool; +static os_membuf_t ble_freertos_ev_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) +]; + +#endif + +#if CONFIG_BT_CONTROLLER_ENABLED + struct os_mempool ble_freertos_evq_pool; static os_membuf_t *ble_freertos_evq_buf = NULL; @@ -123,11 +134,6 @@ static os_membuf_t *ble_freertos_mutex_buf = NULL; #else -struct os_mempool ble_freertos_ev_pool; -static os_membuf_t ble_freertos_ev_buf[ - OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) -]; - struct os_mempool ble_freertos_evq_pool; static os_membuf_t ble_freertos_evq_buf[ OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) @@ -1148,6 +1154,9 @@ int npl_freertos_mempool_init(void) if(!ble_freertos_ev_buf) { goto _error; } +#endif + +#if CONFIG_BT_CONTROLLER_ENABLED ble_freertos_evq_buf = malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) * sizeof(os_membuf_t)); if(!ble_freertos_evq_buf) { goto _error; @@ -1203,11 +1212,7 @@ int npl_freertos_mempool_init(void) } _error: -#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED - if(ble_freertos_ev_buf) { - free(ble_freertos_ev_buf); - ble_freertos_ev_buf = NULL; - } +#if CONFIG_BT_CONTROLLER_ENABLED if(ble_freertos_evq_buf) { free(ble_freertos_evq_buf); ble_freertos_evq_buf = NULL; @@ -1224,12 +1229,18 @@ _error: free(ble_freertos_mutex_buf); ble_freertos_mutex_buf = NULL; } +#endif + +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED + if(ble_freertos_ev_buf) { + free(ble_freertos_ev_buf); + ble_freertos_ev_buf = NULL; + } return -1; -#else +#endif BLE_LL_ASSERT(rc == 0); return rc; -#endif } void npl_freertos_mempool_deinit(void) @@ -1239,6 +1250,9 @@ void npl_freertos_mempool_deinit(void) free(ble_freertos_ev_buf); ble_freertos_ev_buf = NULL; } +#endif + +#if CONFIG_BT_CONTROLLER_ENABLED if(ble_freertos_evq_buf) { free(ble_freertos_evq_buf); ble_freertos_evq_buf = NULL; diff --git a/lib/bt/host/nimble/nimble/porting/npl/riot/include/logcfg/logcfg.h b/lib/bt/host/nimble/nimble/porting/npl/riot/include/logcfg/logcfg.h index 89af3530..4fe2ee01 100644 --- a/lib/bt/host/nimble/nimble/porting/npl/riot/include/logcfg/logcfg.h +++ b/lib/bt/host/nimble/nimble/porting/npl/riot/include/logcfg/logcfg.h @@ -8,6 +8,13 @@ #include "modlog/modlog.h" #include "log_common/log_common.h" +#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) #define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) diff --git a/lib/bt/host/nimble/nimble/porting/npl/riot/include/npl_syscfg/npl_sycfg.h b/lib/bt/host/nimble/nimble/porting/npl/riot/include/npl_syscfg/npl_sycfg.h deleted file mode 120000 index 53c55a90..00000000 --- a/lib/bt/host/nimble/nimble/porting/npl/riot/include/npl_syscfg/npl_sycfg.h +++ /dev/null @@ -1 +0,0 @@ -../syscfg/syscfg.h \ No newline at end of file diff --git a/lib/bt/host/nimble/nimble/porting/npl/riot/include/npl_syscfg/npl_sycfg.h b/lib/bt/host/nimble/nimble/porting/npl/riot/include/npl_syscfg/npl_sycfg.h new file mode 100644 index 00000000..a52b22c5 --- /dev/null +++ b/lib/bt/host/nimble/nimble/porting/npl/riot/include/npl_syscfg/npl_sycfg.h @@ -0,0 +1,1990 @@ +/** + * This file was generated by Apache newt version: 1.11.0-dev + */ + +#ifndef H_MYNEWT_SYSCFG_ +#define H_MYNEWT_SYSCFG_ + +/** + * This macro exists to ensure code includes this header when needed. If code + * checks the existence of a setting directly via ifdef without including this + * header, the setting macro will silently evaluate to 0. In contrast, an + * attempt to use these macros without including this header will result in a + * compiler error. + */ +#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name +#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val + +#ifndef MYNEWT_VAL_HARDFLOAT +#define MYNEWT_VAL_HARDFLOAT (0) +#endif + +/*** @apache-mynewt-core/crypto/tinycrypt */ +#ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE +#define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) +#endif + +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng" +#endif + +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) +#endif + +/*** @apache-mynewt-core/hw/bsp/nordic_pca10056 */ +#ifndef MYNEWT_VAL_BSP_NRF52840 +#define MYNEWT_VAL_BSP_NRF52840 (1) +#endif + +#ifndef MYNEWT_VAL_SOFT_PWM +#define MYNEWT_VAL_SOFT_PWM (0) +#endif + +/*** @apache-mynewt-core/hw/hal */ +#ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS +#define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT +#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ +#define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES (0) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) +#endif + +#ifndef MYNEWT_VAL_HAL_SBRK +#define MYNEWT_VAL_HAL_SBRK (1) +#endif + +#ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB +#define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) +#endif + +/*** @apache-mynewt-core/hw/mcu/nordic/nrf52xxx */ +#ifndef MYNEWT_VAL_ADC_0 +#define MYNEWT_VAL_ADC_0 (0) +#endif + +#ifndef MYNEWT_VAL_ADC_0_REFMV_0 +#define MYNEWT_VAL_ADC_0_REFMV_0 (0) +#endif + +#ifndef MYNEWT_VAL_CRYPTO +#define MYNEWT_VAL_CRYPTO (0) +#endif + +#ifndef MYNEWT_VAL_GPIO_AS_PIN_RESET +#define MYNEWT_VAL_GPIO_AS_PIN_RESET (0) +#endif + +#ifndef MYNEWT_VAL_I2C_0 +#define MYNEWT_VAL_I2C_0 (0) +#endif + +#ifndef MYNEWT_VAL_I2C_0_FREQ_KHZ +#define MYNEWT_VAL_I2C_0_FREQ_KHZ (100) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_I2C_0_PIN_SCL +#define MYNEWT_VAL_I2C_0_PIN_SCL (27) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_I2C_0_PIN_SDA +#define MYNEWT_VAL_I2C_0_PIN_SDA (26) +#endif + +#ifndef MYNEWT_VAL_I2C_1 +#define MYNEWT_VAL_I2C_1 (0) +#endif + +#ifndef MYNEWT_VAL_I2C_1_FREQ_KHZ +#define MYNEWT_VAL_I2C_1_FREQ_KHZ (100) +#endif + +#undef MYNEWT_VAL_I2C_1_PIN_SCL + +#undef MYNEWT_VAL_I2C_1_PIN_SDA + +#ifndef MYNEWT_VAL_MCU_BUS_DRIVER_I2C_USE_TWIM +#define MYNEWT_VAL_MCU_BUS_DRIVER_I2C_USE_TWIM (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_MCU_COMMON_STARTUP +#define MYNEWT_VAL_MCU_COMMON_STARTUP (1) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_MCU_DCDC_ENABLED +#define MYNEWT_VAL_MCU_DCDC_ENABLED (1) +#endif + +#ifndef MYNEWT_VAL_MCU_DEBUG_IGNORE_BKPT +#define MYNEWT_VAL_MCU_DEBUG_IGNORE_BKPT (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE +#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_GPIO_USE_PORT_EVENT +#define MYNEWT_VAL_MCU_GPIO_USE_PORT_EVENT (0) +#endif + +#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE__HFINT +#define MYNEWT_VAL_MCU_HFCLK_SOURCE__HFINT (0) +#endif +#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE__HFXO +#define MYNEWT_VAL_MCU_HFCLK_SOURCE__HFXO (1) +#endif +#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE +#define MYNEWT_VAL_MCU_HFCLK_SOURCE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_I2C_RECOVERY_DELAY_USEC +#define MYNEWT_VAL_MCU_I2C_RECOVERY_DELAY_USEC (100) +#endif + +#ifndef MYNEWT_VAL_MCU_ICACHE_ENABLED +#define MYNEWT_VAL_MCU_ICACHE_ENABLED (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC +#define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC (0) +#endif +#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFSYNTH +#define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFSYNTH (0) +#endif +#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFXO +#define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFXO (1) +#endif +#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE +#define MYNEWT_VAL_MCU_LFCLK_SOURCE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NRF52832 +#define MYNEWT_VAL_MCU_NRF52832 (0) +#endif + +#ifndef MYNEWT_VAL_MCU_NRF52840 +#define MYNEWT_VAL_MCU_NRF52840 (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_MCU_TARGET__nRF52810 +#define MYNEWT_VAL_MCU_TARGET__nRF52810 (0) +#endif +#ifndef MYNEWT_VAL_MCU_TARGET__nRF52811 +#define MYNEWT_VAL_MCU_TARGET__nRF52811 (0) +#endif +#ifndef MYNEWT_VAL_MCU_TARGET__nRF52832 +#define MYNEWT_VAL_MCU_TARGET__nRF52832 (0) +#endif +#ifndef MYNEWT_VAL_MCU_TARGET__nRF52840 +#define MYNEWT_VAL_MCU_TARGET__nRF52840 (1) +#endif +#ifndef MYNEWT_VAL_MCU_TARGET +#define MYNEWT_VAL_MCU_TARGET (1) +#endif + +#ifndef MYNEWT_VAL_NFC_PINS_AS_GPIO +#define MYNEWT_VAL_NFC_PINS_AS_GPIO (1) +#endif + +#ifndef MYNEWT_VAL_PWM_0 +#define MYNEWT_VAL_PWM_0 (0) +#endif + +#ifndef MYNEWT_VAL_PWM_1 +#define MYNEWT_VAL_PWM_1 (0) +#endif + +#ifndef MYNEWT_VAL_PWM_2 +#define MYNEWT_VAL_PWM_2 (0) +#endif + +#ifndef MYNEWT_VAL_PWM_3 +#define MYNEWT_VAL_PWM_3 (0) +#endif + +#ifndef MYNEWT_VAL_QSPI_ADDRMODE +#define MYNEWT_VAL_QSPI_ADDRMODE (0) +#endif + +#ifndef MYNEWT_VAL_QSPI_DPMCONFIG +#define MYNEWT_VAL_QSPI_DPMCONFIG (0) +#endif + +#ifndef MYNEWT_VAL_QSPI_ENABLE +#define MYNEWT_VAL_QSPI_ENABLE (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_FLASH_PAGE_SIZE +#define MYNEWT_VAL_QSPI_FLASH_PAGE_SIZE (256) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_FLASH_SECTOR_COUNT +#define MYNEWT_VAL_QSPI_FLASH_SECTOR_COUNT (4096) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_FLASH_SECTOR_SIZE +#define MYNEWT_VAL_QSPI_FLASH_SECTOR_SIZE (4096) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_PIN_CS +#define MYNEWT_VAL_QSPI_PIN_CS (17) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_PIN_DIO0 +#define MYNEWT_VAL_QSPI_PIN_DIO0 (20) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_PIN_DIO1 +#define MYNEWT_VAL_QSPI_PIN_DIO1 (21) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_PIN_DIO2 +#define MYNEWT_VAL_QSPI_PIN_DIO2 (22) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_PIN_DIO3 +#define MYNEWT_VAL_QSPI_PIN_DIO3 (23) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_QSPI_PIN_SCK +#define MYNEWT_VAL_QSPI_PIN_SCK (19) +#endif + +#ifndef MYNEWT_VAL_QSPI_READOC +#define MYNEWT_VAL_QSPI_READOC (0) +#endif + +#ifndef MYNEWT_VAL_QSPI_SCK_DELAY +#define MYNEWT_VAL_QSPI_SCK_DELAY (0) +#endif + +#ifndef MYNEWT_VAL_QSPI_SCK_FREQ +#define MYNEWT_VAL_QSPI_SCK_FREQ (0) +#endif + +#ifndef MYNEWT_VAL_QSPI_SPI_MODE +#define MYNEWT_VAL_QSPI_SPI_MODE (0) +#endif + +#ifndef MYNEWT_VAL_QSPI_WRITEOC +#define MYNEWT_VAL_QSPI_WRITEOC (0) +#endif + +#ifndef MYNEWT_VAL_SPI_0_MASTER +#define MYNEWT_VAL_SPI_0_MASTER (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MISO +#define MYNEWT_VAL_SPI_0_MASTER_PIN_MISO (47) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI +#define MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI (46) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_SCK +#define MYNEWT_VAL_SPI_0_MASTER_PIN_SCK (45) +#endif + +#ifndef MYNEWT_VAL_SPI_0_SLAVE +#define MYNEWT_VAL_SPI_0_SLAVE (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO +#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO (47) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI +#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI (46) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK +#define MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK (45) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_SS +#define MYNEWT_VAL_SPI_0_SLAVE_PIN_SS (44) +#endif + +#ifndef MYNEWT_VAL_SPI_1_MASTER +#define MYNEWT_VAL_SPI_1_MASTER (0) +#endif + +#undef MYNEWT_VAL_SPI_1_MASTER_PIN_MISO + +#undef MYNEWT_VAL_SPI_1_MASTER_PIN_MOSI + +#undef MYNEWT_VAL_SPI_1_MASTER_PIN_SCK + +#ifndef MYNEWT_VAL_SPI_1_SLAVE +#define MYNEWT_VAL_SPI_1_SLAVE (0) +#endif + +#undef MYNEWT_VAL_SPI_1_SLAVE_PIN_MISO + +#undef MYNEWT_VAL_SPI_1_SLAVE_PIN_MOSI + +#undef MYNEWT_VAL_SPI_1_SLAVE_PIN_SCK + +#undef MYNEWT_VAL_SPI_1_SLAVE_PIN_SS + +#ifndef MYNEWT_VAL_SPI_2_MASTER +#define MYNEWT_VAL_SPI_2_MASTER (0) +#endif + +#undef MYNEWT_VAL_SPI_2_MASTER_PIN_MISO + +#undef MYNEWT_VAL_SPI_2_MASTER_PIN_MOSI + +#undef MYNEWT_VAL_SPI_2_MASTER_PIN_SCK + +#ifndef MYNEWT_VAL_SPI_2_SLAVE +#define MYNEWT_VAL_SPI_2_SLAVE (0) +#endif + +#undef MYNEWT_VAL_SPI_2_SLAVE_PIN_MISO + +#undef MYNEWT_VAL_SPI_2_SLAVE_PIN_MOSI + +#undef MYNEWT_VAL_SPI_2_SLAVE_PIN_SCK + +#undef MYNEWT_VAL_SPI_2_SLAVE_PIN_SS + +#ifndef MYNEWT_VAL_SPI_3_MASTER +#define MYNEWT_VAL_SPI_3_MASTER (0) +#endif + +#undef MYNEWT_VAL_SPI_3_MASTER_PIN_MISO + +#undef MYNEWT_VAL_SPI_3_MASTER_PIN_MOSI + +#undef MYNEWT_VAL_SPI_3_MASTER_PIN_SCK + +#ifndef MYNEWT_VAL_TEMP +#define MYNEWT_VAL_TEMP (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_TIMER_0 +#define MYNEWT_VAL_TIMER_0 (0) +#endif + +#ifndef MYNEWT_VAL_TIMER_1 +#define MYNEWT_VAL_TIMER_1 (0) +#endif + +#ifndef MYNEWT_VAL_TIMER_2 +#define MYNEWT_VAL_TIMER_2 (0) +#endif + +#ifndef MYNEWT_VAL_TIMER_3 +#define MYNEWT_VAL_TIMER_3 (0) +#endif + +#ifndef MYNEWT_VAL_TIMER_4 +#define MYNEWT_VAL_TIMER_4 (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_TIMER_5 +#define MYNEWT_VAL_TIMER_5 (1) +#endif + +#ifndef MYNEWT_VAL_TRNG +#define MYNEWT_VAL_TRNG (0) +#endif + +#ifndef MYNEWT_VAL_UART_0 +#define MYNEWT_VAL_UART_0 (1) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_UART_0_PIN_CTS +#define MYNEWT_VAL_UART_0_PIN_CTS (7) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_UART_0_PIN_RTS +#define MYNEWT_VAL_UART_0_PIN_RTS (5) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_UART_0_PIN_RX +#define MYNEWT_VAL_UART_0_PIN_RX (8) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_UART_0_PIN_TX +#define MYNEWT_VAL_UART_0_PIN_TX (6) +#endif + +#ifndef MYNEWT_VAL_UART_1 +#define MYNEWT_VAL_UART_1 (0) +#endif + +#ifndef MYNEWT_VAL_UART_1_PIN_CTS +#define MYNEWT_VAL_UART_1_PIN_CTS (-1) +#endif + +#ifndef MYNEWT_VAL_UART_1_PIN_RTS +#define MYNEWT_VAL_UART_1_PIN_RTS (-1) +#endif + +#undef MYNEWT_VAL_UART_1_PIN_RX + +#undef MYNEWT_VAL_UART_1_PIN_TX + +#ifndef MYNEWT_VAL_XTAL_32768 +#define MYNEWT_VAL_XTAL_32768 (0) +#endif + +#ifndef MYNEWT_VAL_XTAL_32768_SYNTH +#define MYNEWT_VAL_XTAL_32768_SYNTH (0) +#endif + +#ifndef MYNEWT_VAL_XTAL_RC +#define MYNEWT_VAL_XTAL_RC (0) +#endif + +/*** @apache-mynewt-core/kernel/os */ +#ifndef MYNEWT_VAL_FLOAT_USER +#define MYNEWT_VAL_FLOAT_USER (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT +#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (5) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_MSYS_1_BLOCK_SIZE +#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (88) +#endif + +#ifndef MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT +#define MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT +#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_BLOCK_SIZE +#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT +#define MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_SANITY_TIMEOUT +#define MYNEWT_VAL_MSYS_SANITY_TIMEOUT (60000) +#endif + +#ifndef MYNEWT_VAL_OS_ASSERT_CB +#define MYNEWT_VAL_OS_ASSERT_CB (0) +#endif + +#ifndef MYNEWT_VAL_OS_CLI +#define MYNEWT_VAL_OS_CLI (0) +#endif + +#ifndef MYNEWT_VAL_OS_COREDUMP +#define MYNEWT_VAL_OS_COREDUMP (0) +#endif + +#ifndef MYNEWT_VAL_OS_COREDUMP_CB +#define MYNEWT_VAL_OS_COREDUMP_CB (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_CPUTIME_FREQ +#define MYNEWT_VAL_OS_CPUTIME_FREQ (32768) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM +#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (5) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE +#define MYNEWT_VAL_OS_CRASH_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_LOG +#define MYNEWT_VAL_OS_CRASH_LOG (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_RESTORE_REGS +#define MYNEWT_VAL_OS_CRASH_RESTORE_REGS (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_STACKTRACE +#define MYNEWT_VAL_OS_CRASH_STACKTRACE (0) +#endif + +#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_CHECK +#define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0) +#endif + +#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_GUARD +#define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4) +#endif + +#ifndef MYNEWT_VAL_OS_DEBUG_MODE +#define MYNEWT_VAL_OS_DEBUG_MODE (0) +#endif + +#ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG +#define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_OS_EVENTQ_MONITOR +#define MYNEWT_VAL_OS_EVENTQ_MONITOR (0) +#endif + +#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) +#endif + +#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (100) +#endif + +#ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE +#define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024) +#endif + +#ifndef MYNEWT_VAL_OS_MAIN_TASK_PRIO +#define MYNEWT_VAL_OS_MAIN_TASK_PRIO (127) +#endif + +#ifndef MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS +#define MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS (0) +#endif + +#ifndef MYNEWT_VAL_OS_MEMPOOL_CHECK +#define MYNEWT_VAL_OS_MEMPOOL_CHECK (0) +#endif + +#ifndef MYNEWT_VAL_OS_MEMPOOL_GUARD +#define MYNEWT_VAL_OS_MEMPOOL_GUARD (0) +#endif + +#ifndef MYNEWT_VAL_OS_MEMPOOL_POISON +#define MYNEWT_VAL_OS_MEMPOOL_POISON (0) +#endif + +#ifndef MYNEWT_VAL_OS_SCHEDULING +#define MYNEWT_VAL_OS_SCHEDULING (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSINIT_STAGE +#define MYNEWT_VAL_OS_SYSINIT_STAGE (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW +#define MYNEWT_VAL_OS_SYSVIEW (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM (1) +#endif + +#ifndef MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME +#define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC +#define MYNEWT_VAL_OS_TICKS_PER_SEC (128) +#endif + +#ifndef MYNEWT_VAL_OS_TIME_DEBUG +#define MYNEWT_VAL_OS_TIME_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_OS_WATCHDOG_MONITOR +#define MYNEWT_VAL_OS_WATCHDOG_MONITOR (0) +#endif + +#ifndef MYNEWT_VAL_SANITY_INTERVAL +#define MYNEWT_VAL_SANITY_INTERVAL (15000) +#endif + +#ifndef MYNEWT_VAL_WATCHDOG_INTERVAL +#define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) +#endif + +/*** @apache-mynewt-core/libc/baselibc */ +#ifndef MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE +#define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_BASELIBC_EXECUTE_GLOBAL_CONSTRUCTORS +#define MYNEWT_VAL_BASELIBC_EXECUTE_GLOBAL_CONSTRUCTORS (1) +#endif + +#ifndef MYNEWT_VAL_BASELIBC_PRESENT +#define MYNEWT_VAL_BASELIBC_PRESENT (1) +#endif + +#ifndef MYNEWT_VAL_BASELIBC_THREAD_SAFE_HEAP_ALLOCATION +#define MYNEWT_VAL_BASELIBC_THREAD_SAFE_HEAP_ALLOCATION (0) +#endif + +/*** @apache-mynewt-core/sys/console/stub */ +#ifndef MYNEWT_VAL_CONSOLE_UART_BAUD +#define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) +#endif + +#ifndef MYNEWT_VAL_CONSOLE_UART_DEV +#define MYNEWT_VAL_CONSOLE_UART_DEV "uart0" +#endif + +#ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL +#define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) +#endif + +/*** @apache-mynewt-core/sys/flash_map */ +#ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS +#define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) +#endif + +#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG +#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0) +#endif + +#ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) +#endif + +/*** @apache-mynewt-core/sys/log/common */ +#ifndef MYNEWT_VAL_DFLT_LOG_LVL +#define MYNEWT_VAL_DFLT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_DFLT_LOG_MOD +#define MYNEWT_VAL_DFLT_LOG_MOD (0) +#endif + +#ifndef MYNEWT_VAL_LOG_GLOBAL_IDX +#define MYNEWT_VAL_LOG_GLOBAL_IDX (1) +#endif + +/*** @apache-mynewt-core/sys/log/modlog */ +#ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT +#define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) +#endif + +#ifndef MYNEWT_VAL_MODLOG_LOG_MACROS +#define MYNEWT_VAL_MODLOG_LOG_MACROS (0) +#endif + +#ifndef MYNEWT_VAL_MODLOG_MAX_MAPPINGS +#define MYNEWT_VAL_MODLOG_MAX_MAPPINGS (16) +#endif + +#ifndef MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN +#define MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN (128) +#endif + +#ifndef MYNEWT_VAL_MODLOG_SYSINIT_STAGE +#define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) +#endif + +/*** @apache-mynewt-core/sys/log/stub */ +#ifndef MYNEWT_VAL_LOG_CONSOLE +#define MYNEWT_VAL_LOG_CONSOLE (1) +#endif + +#ifndef MYNEWT_VAL_LOG_FCB +#define MYNEWT_VAL_LOG_FCB (0) +#endif + +#ifndef MYNEWT_VAL_LOG_FCB_SLOT1 +#define MYNEWT_VAL_LOG_FCB_SLOT1 (0) +#endif + +#ifndef MYNEWT_VAL_LOG_LEVEL +#define MYNEWT_VAL_LOG_LEVEL (255) +#endif + +/*** @apache-mynewt-core/sys/sys */ +#ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED +#define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) +#endif + +/*** @apache-mynewt-core/sys/sysdown */ +#ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN +#define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE +#define MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE +#define MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE (0) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_TIMEOUT_MS +#define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) +#endif + +/*** @apache-mynewt-core/sys/sysinit */ +#ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT +#define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) +#endif + +#ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE +#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE +#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) +#endif + +/*** @apache-mynewt-core/util/rwlock */ +#ifndef MYNEWT_VAL_RWLOCK_DEBUG +#define MYNEWT_VAL_RWLOCK_DEBUG (0) +#endif + +/*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EXT_ADV +#define MYNEWT_VAL_BLE_EXT_ADV (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE +#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) +#endif + +#ifndef MYNEWT_VAL_ENC_ADV_DATA +#define MYNEWT_VAL_ENC_ADV_DATA (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble) */ +#ifndef MYNEWT_VAL_BLE_HCI_VS +#define MYNEWT_VAL_BLE_HCI_VS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO +#define MYNEWT_VAL_BLE_ISO (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_TEST +#define MYNEWT_VAL_BLE_ISO_TEST (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_CONNECTIONS +#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble) */ +#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS +#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES +#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV +#define MYNEWT_VAL_BLE_PERIODIC_ADV (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) +#endif + +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER +#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_CENTRAL +#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_OBSERVER +#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_PERIPHERAL +#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_VERSION +#define MYNEWT_VAL_BLE_VERSION (50) +#endif + +#ifndef MYNEWT_VAL_BLE_WHITELIST +#define MYNEWT_VAL_BLE_WHITELIST (1) +#endif + +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_BLOB_TRANSFER +#define MYNEWT_VAL_BLE_GATT_BLOB_TRANSFER (0) +#endif + +/*** @apache-mynewt-nimble/nimble/controller */ +#ifndef MYNEWT_VAL_BLE_CONTROLLER +#define MYNEWT_VAL_BLE_CONTROLLER (1) +#endif + +#ifndef MYNEWT_VAL_BLE_DEVICE +#define MYNEWT_VAL_BLE_DEVICE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_ANTENNA +#define MYNEWT_VAL_BLE_FEM_ANTENNA (0) +#endif + +/* Value copied from BLE_LL_LNA */ +#ifndef MYNEWT_VAL_BLE_FEM_LNA +#define MYNEWT_VAL_BLE_FEM_LNA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_LNA_GAIN +#define MYNEWT_VAL_BLE_FEM_LNA_GAIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_LNA_GAIN_TUNABLE +#define MYNEWT_VAL_BLE_FEM_LNA_GAIN_TUNABLE (0) +#endif + +/* Value copied from BLE_LL_LNA_GPIO */ +#ifndef MYNEWT_VAL_BLE_FEM_LNA_GPIO +#define MYNEWT_VAL_BLE_FEM_LNA_GPIO (-1) +#endif + +/* Value copied from BLE_LL_LNA_TURN_ON_US */ +#ifndef MYNEWT_VAL_BLE_FEM_LNA_TURN_ON_US +#define MYNEWT_VAL_BLE_FEM_LNA_TURN_ON_US (1) +#endif + +/* Value copied from BLE_LL_PA */ +#ifndef MYNEWT_VAL_BLE_FEM_PA +#define MYNEWT_VAL_BLE_FEM_PA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_PA_GAIN +#define MYNEWT_VAL_BLE_FEM_PA_GAIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_PA_GAIN_TUNABLE +#define MYNEWT_VAL_BLE_FEM_PA_GAIN_TUNABLE (0) +#endif + +/* Value copied from BLE_LL_PA_GPIO */ +#ifndef MYNEWT_VAL_BLE_FEM_PA_GPIO +#define MYNEWT_VAL_BLE_FEM_PA_GPIO (-1) +#endif + +/* Value copied from BLE_LL_PA_TURN_ON_US */ +#ifndef MYNEWT_VAL_BLE_FEM_PA_TURN_ON_US +#define MYNEWT_VAL_BLE_FEM_PA_TURN_ON_US (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE +#define MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS +#define MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING (MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE (0) +#endif + +/* Value copied from BLE_EXT_ADV */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (0) +#endif + +/* Value copied from BLE_ISO */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO (0) +#endif + +/* Value copied from BLE_ISO_TEST */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO_TEST +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO_TEST (0) +#endif + +/* Value copied from BLE_PERIODIC_ADV */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV (0) +#endif + +/* Value copied from BLE_MAX_PERIODIC_SYNCS */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT (0) +#endif + +/* Value copied from BLE_MAX_PERIODIC_SYNCS */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_LIST_CNT +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_LIST_CNT (0) +#endif + +/* Value copied from BLE_PERIODIC_ADV_SYNC_TRANSFER */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_SCA_UPDATE +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_SCA_UPDATE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG (MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_EVENT_END_MARGIN +#define MYNEWT_VAL_BLE_LL_CONN_EVENT_END_MARGIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_AUTO_DLE +#define MYNEWT_VAL_BLE_LL_CONN_INIT_AUTO_DLE (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES +#define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET +#define MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS +#define MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_PHY_DEFAULT_PREF_MASK +#define MYNEWT_VAL_BLE_LL_CONN_PHY_DEFAULT_PREF_MASK (0x07) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_PHY_INIT_UPDATE +#define MYNEWT_VAL_BLE_LL_CONN_PHY_INIT_UPDATE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_PHY_PREFER_2M +#define MYNEWT_VAL_BLE_LL_CONN_PHY_PREFER_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_FIXED +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_FIXED (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_SLOT_US +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_SLOT_US (3750) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_CMD +#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_CMD (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_EV +#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_EV (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_RFMGMT +#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_RFMGMT (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM +#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_RUN +#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_RUN (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE +#define MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE (0) +#endif + +/* Value copied from BLE_LL_DIRECT_TEST_MODE */ +#ifndef MYNEWT_VAL_BLE_LL_DTM +#define MYNEWT_VAL_BLE_LL_DTM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DTM_EXTENSIONS +#define MYNEWT_VAL_BLE_LL_DTM_EXTENSIONS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_EXT +#define MYNEWT_VAL_BLE_LL_EXT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT +#define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_HBD_FAKE_DUAL_MODE +#define MYNEWT_VAL_BLE_LL_HBD_FAKE_DUAL_MODE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE +#define MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE (0) +#endif + +/* Value copied from BLE_HCI_VS */ +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS +#define MYNEWT_VAL_BLE_LL_HCI_VS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_CONN_STRICT_SCHED +#define MYNEWT_VAL_BLE_LL_HCI_VS_CONN_STRICT_SCHED (0) +#endif + +/* Value copied from BLE_LL_VND_EVENT_ON_ASSERT */ +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT +#define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_LNA +#define MYNEWT_VAL_BLE_LL_LNA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_LNA_GPIO +#define MYNEWT_VAL_BLE_LL_LNA_GPIO (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_LNA_TURN_ON_US +#define MYNEWT_VAL_BLE_LL_LNA_TURN_ON_US (1) +#endif + +/* Value copied from BLE_LL_MFRG_ID */ +#ifndef MYNEWT_VAL_BLE_LL_MANUFACTURER_ID +#define MYNEWT_VAL_BLE_LL_MANUFACTURER_ID (0x0B65) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA +#define MYNEWT_VAL_BLE_LL_MASTER_SCA (4) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE +#define MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE (251) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_MFRG_ID +#define MYNEWT_VAL_BLE_LL_MFRG_ID (0x0B65) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_NUM_COMP_PKT_ITVL_MS +#define MYNEWT_VAL_BLE_LL_NUM_COMP_PKT_ITVL_MS (2000) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS +#define MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS +#define MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_OUR_SCA +#define MYNEWT_VAL_BLE_LL_OUR_SCA (60) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_PA +#define MYNEWT_VAL_BLE_LL_PA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_PA_GPIO +#define MYNEWT_VAL_BLE_LL_PA_GPIO (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_PA_TURN_ON_US +#define MYNEWT_VAL_BLE_LL_PA_TURN_ON_US (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_PRIO +#define MYNEWT_VAL_BLE_LL_PRIO (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_PUBLIC_DEV_ADDR +#define MYNEWT_VAL_BLE_LL_PUBLIC_DEV_ADDR (0x000000000000) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE +#define MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE (4) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME +#define MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME (1500) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_RNG_BUFSIZE +#define MYNEWT_VAL_BLE_LL_RNG_BUFSIZE (32) +#endif + +/* Value copied from BLE_ROLE_BROADCASTER */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_BROADCASTER +#define MYNEWT_VAL_BLE_LL_ROLE_BROADCASTER (1) +#endif + +/* Value copied from BLE_ROLE_CENTRAL */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_CENTRAL +#define MYNEWT_VAL_BLE_LL_ROLE_CENTRAL (1) +#endif + +/* Value copied from BLE_ROLE_OBSERVER */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_OBSERVER +#define MYNEWT_VAL_BLE_LL_ROLE_OBSERVER (1) +#endif + +/* Value copied from BLE_ROLE_PERIPHERAL */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL +#define MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL (1) +#endif + +/* Value copied from BLE_LL_OUR_SCA */ +#ifndef MYNEWT_VAL_BLE_LL_SCA +#define MYNEWT_VAL_BLE_LL_SCA (60) +#endif + +/* Value copied from BLE_LL_EXT_ADV_AUX_PTR_CNT */ +#ifndef MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT +#define MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY +#define MYNEWT_VAL_BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SCHED_AUX_MAFS_DELAY +#define MYNEWT_VAL_BLE_LL_SCHED_AUX_MAFS_DELAY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SCHED_SCAN_AUX_PDU_LEN +#define MYNEWT_VAL_BLE_LL_SCHED_SCAN_AUX_PDU_LEN (41) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SCHED_SCAN_SYNC_PDU_LEN +#define MYNEWT_VAL_BLE_LL_SCHED_SCAN_SYNC_PDU_LEN (32) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_STACK_SIZE +#define MYNEWT_VAL_BLE_LL_STACK_SIZE (120) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING +#define MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES +#define MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES +#define MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_LL_SYSINIT_STAGE (250) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SYSVIEW +#define MYNEWT_VAL_BLE_LL_SYSVIEW (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_TX_PWR_DBM +#define MYNEWT_VAL_BLE_LL_TX_PWR_DBM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_TX_PWR_MAX_DBM +#define MYNEWT_VAL_BLE_LL_TX_PWR_MAX_DBM (20) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD +#define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_VND_EVENT_ON_ASSERT +#define MYNEWT_VAL_BLE_LL_VND_EVENT_ON_ASSERT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_WHITELIST_SIZE +#define MYNEWT_VAL_BLE_LL_WHITELIST_SIZE (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LP_CLOCK +#define MYNEWT_VAL_BLE_LP_CLOCK (1) +#endif + +#ifndef MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE +#define MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE ((2 * OS_TICKS_PER_SEC)) +#endif + +#ifndef MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR +#define MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR ((uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) +#endif + +#ifndef MYNEWT_VAL_BLE_XTAL_SETTLE_TIME +#define MYNEWT_VAL_BLE_XTAL_SETTLE_TIME (0) +#endif + +/*** @apache-mynewt-nimble/nimble/drivers/nrf5x */ +#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN +#define MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_TXRXEN_READY_PIN +#define MYNEWT_VAL_BLE_PHY_DBG_TIME_TXRXEN_READY_PIN (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN +#define MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_NRF52_HEADERMASK_WORKAROUND +#define MYNEWT_VAL_BLE_PHY_NRF52_HEADERMASK_WORKAROUND (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_SYSVIEW +#define MYNEWT_VAL_BLE_PHY_SYSVIEW (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR +#define MYNEWT_VAL_BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_VARIABLE_TIFS +#define MYNEWT_VAL_BLE_PHY_VARIABLE_TIFS (0) +#endif + +/*** @apache-mynewt-nimble/nimble/host */ +#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU +#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO +#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_INDICATE +#define MYNEWT_VAL_BLE_ATT_SVR_INDICATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES +#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO +#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO (30000) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ +#define MYNEWT_VAL_BLE_ATT_SVR_READ (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB +#define MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT +#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP +#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + +#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE +#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID +#define MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID +#define MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS +#define MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_INDICATE +#define MYNEWT_VAL_BLE_GATT_INDICATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_MAX_PROCS +#define MYNEWT_VAL_BLE_GATT_MAX_PROCS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY +#define MYNEWT_VAL_BLE_GATT_NOTIFY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ +#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_LONG +#define MYNEWT_VAL_BLE_GATT_READ_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS +#define MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT +#define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_UUID +#define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_RESUME_RATE +#define MYNEWT_VAL_BLE_GATT_RESUME_RATE (1000) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_SIGNED_WRITE +#define MYNEWT_VAL_BLE_GATT_SIGNED_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE +#define MYNEWT_VAL_BLE_GATT_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_LONG +#define MYNEWT_VAL_BLE_GATT_WRITE_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS +#define MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP +#define MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE +#define MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_HOST +#define MYNEWT_VAL_BLE_HOST (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_AUTO_START +#define MYNEWT_VAL_BLE_HS_AUTO_START (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_DEBUG +#define MYNEWT_VAL_BLE_HS_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL (1000) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH (2) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_LOG_LVL +#define MYNEWT_VAL_BLE_HS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_LOG_MOD +#define MYNEWT_VAL_BLE_HS_LOG_MOD (4) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS +#define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_REQUIRE_OS +#define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT (2000) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM +#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MPS +#define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT +#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS +#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_MAX_CHANS +#define MYNEWT_VAL_BLE_L2CAP_MAX_CHANS (3*MYNEWT_VAL_BLE_MAX_CONNECTIONS) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT +#define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS +#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH +#define MYNEWT_VAL_BLE_MESH (0) +#endif + +#ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT +#define MYNEWT_VAL_BLE_RPA_TIMEOUT (300) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_BONDING +#define MYNEWT_VAL_BLE_SM_BONDING (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_IO_CAP +#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_KEYPRESS +#define MYNEWT_VAL_BLE_SM_KEYPRESS (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/host) */ +#ifndef MYNEWT_VAL_BLE_SM_LEGACY +#define MYNEWT_VAL_BLE_SM_LEGACY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS +#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_MITM +#define MYNEWT_VAL_BLE_SM_MITM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG +#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST +#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/host) */ +#ifndef MYNEWT_VAL_BLE_SM_SC +#define MYNEWT_VAL_BLE_SM_SC (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST +#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) +#endif + +#ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS +#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (3) +#endif + +#ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS +#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) +#endif + +#ifdef CONFIG_BT_NIMBLE_MAX_EADS +#define MYNEWT_VAL_BLE_STORE_MAX_EADS CONFIG_BT_NIMBLE_MAX_EADS +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/gap */ +#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE +#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION +#define MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble" +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH (31) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/gatt */ +#ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) +#endif + +/*** @apache-mynewt-nimble/nimble/transport */ +#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT + +#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_BRIDGE + +#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_TRANSPORT + +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor" +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0" +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT +#define MYNEWT_VAL_BLE_TRANSPORT (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (24) +#endif + +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (24) +#endif + +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (24) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc +#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom +#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native +#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart +#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb +#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS +#define MYNEWT_VAL_BLE_TRANSPORT_HS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom +#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi +#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native +#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (1) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket +#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL +#define MYNEWT_VAL_BLE_TRANSPORT_LL (1) +#endif + +/*** newt */ +#ifndef MYNEWT_VAL_APP_NAME +#define MYNEWT_VAL_APP_NAME "dummy_app" +#endif + +#ifndef MYNEWT_VAL_APP_dummy_app +#define MYNEWT_VAL_APP_dummy_app (1) +#endif + +#ifndef MYNEWT_VAL_ARCH_NAME +#define MYNEWT_VAL_ARCH_NAME "cortex_m4" +#endif + +#ifndef MYNEWT_VAL_ARCH_cortex_m4 +#define MYNEWT_VAL_ARCH_cortex_m4 (1) +#endif + +#ifndef MYNEWT_VAL_BSP_NAME +#define MYNEWT_VAL_BSP_NAME "nordic_pca10056" +#endif + +#ifndef MYNEWT_VAL_BSP_nordic_pca10056 +#define MYNEWT_VAL_BSP_nordic_pca10056 (1) +#endif + +#ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG +#define MYNEWT_VAL_NEWT_FEATURE_LOGCFG (1) +#endif + +#ifndef MYNEWT_VAL_NEWT_FEATURE_SYSDOWN +#define MYNEWT_VAL_NEWT_FEATURE_SYSDOWN (1) +#endif + +#ifndef MYNEWT_VAL_TARGET_NAME +#define MYNEWT_VAL_TARGET_NAME "riot" +#endif + +#ifndef MYNEWT_VAL_TARGET_riot +#define MYNEWT_VAL_TARGET_riot (1) +#endif + +/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__compiler_arm_none_eabi_m4 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_nordic_pca10056 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_cmsis_core 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic_nrf52xxx 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__libc_baselibc 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1 +#define MYNEWT_PKG_apache_mynewt_core__util_mem 1 +#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_controller 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_drivers_nrf5x 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_riot 1 + +#endif diff --git a/lib/bt/host/nimble/nimble/porting/npl/riot/include/syscfg/syscfg.h b/lib/bt/host/nimble/nimble/porting/npl/riot/include/syscfg/syscfg.h index c90322ea..a52b22c5 100644 --- a/lib/bt/host/nimble/nimble/porting/npl/riot/include/syscfg/syscfg.h +++ b/lib/bt/host/nimble/nimble/porting/npl/riot/include/syscfg/syscfg.h @@ -1406,6 +1406,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -1446,6 +1450,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif @@ -1486,6 +1506,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/lib/bt/host/nimble/nimble/sbom.yml b/lib/bt/host/nimble/nimble/sbom.yml index 214758da..c1eb6d63 100644 --- a/lib/bt/host/nimble/nimble/sbom.yml +++ b/lib/bt/host/nimble/nimble/sbom.yml @@ -1,5 +1,5 @@ name: 'Apache Mynewt Nimble' -version: '1.5.0' +version: '1.6.0' supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' originator: 'Organization: The Apache Software Foundation' description: An open-source Bluetooth 5.1 stack with additional features and patches from Espressif. diff --git a/lib/bt/host/nimble/port/include/esp_nimble_cfg.h b/lib/bt/host/nimble/port/include/esp_nimble_cfg.h index d2fa3338..6c80ae75 100644 --- a/lib/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/lib/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -98,6 +98,14 @@ #define MYNEWT_VAL_BLE_EXT_ADV (CONFIG_BT_NIMBLE_EXT_ADV) #endif +#ifndef MYNEWT_VAL_BLE_EXT_ADV_V2 +#ifdef CONFIG_BT_NIMBLE_EXT_ADV_V2 +#define MYNEWT_VAL_BLE_EXT_ADV_V2 (CONFIG_BT_NIMBLE_EXT_ADV_V2) +#else +#define MYNEWT_VAL_BLE_EXT_ADV_V2 (0) +#endif +#endif + #ifndef CONFIG_BT_NIMBLE_EXT_ADV_MAX_SIZE #define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) #else @@ -129,11 +137,27 @@ #define MYNEWT_VAL_BLE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_NIMBLE_MAX_PERIODIC_ADVERTISER_LIST) #endif +#ifndef MYNEWT_VAL_BLE_INCL_SVC_DISCOVERY +#ifdef CONFIG_BT_NIMBLE_INCL_SVC_DISCOVERY +#define MYNEWT_VAL_BLE_INCL_SVC_DISCOVERY (CONFIG_BT_NIMBLE_INCL_SVC_DISCOVERY) +#else +#define MYNEWT_VAL_BLE_INCL_SVC_DISCOVERY (0) +#endif +#endif + #ifndef CONFIG_BT_NIMBLE_GATT_CACHING #define MYNEWT_VAL_BLE_GATT_CACHING (0) #else #define MYNEWT_VAL_BLE_GATT_CACHING (CONFIG_BT_NIMBLE_GATT_CACHING) +#ifndef MYNEWT_VAL_BLE_GATT_CACHING_INCLUDE_SERVICES +#ifdef CONFIG_BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES +#define MYNEWT_VAL_BLE_GATT_CACHING_INCLUDE_SERVICES (CONFIG_BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING_INCLUDE_SERVICES (0) +#endif +#endif + #ifdef CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CONNS #define MYNEWT_VAL_BLE_GATT_CACHING_MAX_CONNS (CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CONNS) #else @@ -146,6 +170,14 @@ #define MYNEWT_VAL_BLE_GATT_CACHING_MAX_SVCS (0) #endif +#ifndef MYNEWT_VAL_BLE_GATT_CACHING_MAX_INCL_SVCS +#ifdef CONFIG_BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_INCL_SVCS (CONFIG_BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_INCL_SVCS (0) +#endif +#endif + #ifdef CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CHRS #define MYNEWT_VAL_BLE_GATT_CACHING_MAX_CHRS (CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CHRS) #else @@ -158,6 +190,16 @@ #define MYNEWT_VAL_BLE_GATT_CACHING_MAX_DSCS (0) #endif +#ifdef CONFIG_BT_NIMBLE_GATT_CACHING_DISABLE_AUTO +#define MYNEWT_VAL_BLE_GATT_CACHING_DISABLE_AUTO (CONFIG_BT_NIMBLE_GATT_CACHING_DISABLE_AUTO) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING_DISABLE_AUTO (0) +#endif + +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_CSFC_SIZE +#define MYNEWT_VAL_BLE_GATT_CSFC_SIZE (1) #endif #ifndef CONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES @@ -202,6 +244,18 @@ #define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif +#ifndef CONFIG_BT_NIMBLE_GATT_CLIENT +#define MYNEWT_VAL_BLE_GATTC (0) +#else +#define MYNEWT_VAL_BLE_GATTC (CONFIG_BT_NIMBLE_GATT_CLIENT) +#endif + +#ifndef CONFIG_BT_NIMBLE_GATT_SERVER +#define MYNEWT_VAL_BLE_GATTS (0) +#else +#define MYNEWT_VAL_BLE_GATTS (CONFIG_BT_NIMBLE_GATT_SERVER) +#endif + #ifndef MYNEWT_VAL_BLE_WHITELIST #define MYNEWT_VAL_BLE_WHITELIST (1) #endif @@ -234,7 +288,7 @@ #endif #ifndef MYNEWT_VAL_BLE_VERSION -#define MYNEWT_VAL_BLE_VERSION (50) +#define MYNEWT_VAL_BLE_VERSION (54) #endif #ifndef MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS @@ -511,6 +565,12 @@ #define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT #endif +#if CONFIG_BT_NIMBLE_L2CAP_ENHANCED_COC || CONFIG_BT_NIMBLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (1) +#else +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + #ifndef MYNEWT_VAL_BLE_DYNAMIC_SERVICE #ifdef CONFIG_BT_NIMBLE_DYNAMIC_SERVICE #define MYNEWT_VAL_BLE_DYNAMIC_SERVICE CONFIG_BT_NIMBLE_DYNAMIC_SERVICE @@ -536,13 +596,17 @@ #endif #ifndef MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES -#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64) +#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES CONFIG_BT_NIMBLE_ATT_MAX_PREP_ENTRIES #endif #ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (1) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -567,6 +631,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT_VAR +#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT_VAR (1) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE #define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1) #endif @@ -583,6 +651,49 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (CONFIG_BT_NIMBLE_EATT_CHAN_NUM) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + +#ifndef MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES + +#if MYNEWT_VAL_BLE_GATT_CACHING +#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_ROBUST_CACHING (1) +#else +#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_ROBUST_CACHING (0) +#endif //MYNEWT_VAL_BLE_GATT_CACHING + +#if CONFIG_BT_NIMBLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_EATT (2) +#else +#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_EATT (0) +#endif //CONFIG_BT_NIMBLE_EATT_CHAN_NUM + +#if MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_NOTIFY_MULTI (4) +#else +#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_NOTIFY_MULTI (0) +#endif //MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI + +#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES ( \ + MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_ROBUST_CACHING | \ + MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_EATT | \ + MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_NOTIFY_MULTI \ + ) +#endif //MYNEWT_VAL_CLIENT_SUPPORTED_FEATURES + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif @@ -623,6 +734,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif @@ -749,11 +864,15 @@ #define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) #endif +#if CONFIG_BT_NIMBLE_EATT_CHAN_NUM > CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM +#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (CONFIG_BT_NIMBLE_EATT_CHAN_NUM) +#else #ifndef CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (2) #else #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM -#endif +#endif //CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM +#endif //CONFIG_BT_NIMBLE_EATT_CHAN_NUM #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MPS #define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) @@ -771,7 +890,11 @@ #define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000) #endif -#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS +#if CONFIG_BT_NIMBLE_EATT_CHAN_NUM > CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM +#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (CONFIG_BT_NIMBLE_EATT_CHAN_NUM) +#elif CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM +#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM) +#else #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif @@ -885,13 +1008,25 @@ #endif #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#ifdef CONFIG_BT_NIMBLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (CONFIG_BT_NIMBLE_SM_SC_ONLY) +#else #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif +#endif #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST #define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) #endif +#ifndef MYNEWT_VAL_BLE_SMP_ID_RESET +#ifdef CONFIG_BT_NIMBLE_SMP_ID_RESET +#define MYNEWT_VAL_BLE_SMP_ID_RESET CONFIG_BT_NIMBLE_SMP_ID_RESET +#else +#define MYNEWT_VAL_BLE_SMP_ID_RESET (0) +#endif +#endif + #ifndef MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS #define MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS (CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS) #endif @@ -904,6 +1039,10 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS CONFIG_BT_NIMBLE_MAX_CCCDS #endif +#ifndef MYNEWT_VAL_BLE_STORE_MAX_CSFCS +#define MYNEWT_VAL_BLE_STORE_MAX_CSFCS CONFIG_BT_NIMBLE_MAX_BONDS +#endif + #ifdef CONFIG_BT_NIMBLE_MAX_EADS #define MYNEWT_VAL_BLE_STORE_MAX_EADS CONFIG_BT_NIMBLE_MAX_EADS #endif @@ -948,7 +1087,7 @@ /*** nimble/host/services/bas */ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE -#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY) #endif #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM @@ -1548,7 +1687,7 @@ /*** @apache-mynewt-nimble/nimble/host/services/bas */ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE -#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (CONFIG_BT_NIMBLE_SVC_BAS_BATTERY_LEVEL_NOTIFY) #endif #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM @@ -1565,29 +1704,34 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT ("0000") #endif /* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ -#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM +#if CONFIG_BT_NIMBLE_SVC_DIS_FIRMWARE_REVISION +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (0) +#else #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT ("0000") #endif /* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ -#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM +#if CONFIG_BT_NIMBLE_SVC_DIS_HARDWARE_REVISION +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (0) +#else #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT ("espressif") #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ -#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM +#if CONFIG_BT_NIMBLE_SVC_DIS_MANUFACTURER_NAME +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (0) +#else #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) #endif @@ -1600,20 +1744,24 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT ("0000") #endif /* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ -#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM +#if CONFIG_BT_NIMBLE_SVC_DIS_SERIAL_NUMBER +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (0) +#else #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT ("0000") #endif /* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ -#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM +#if CONFIG_BT_NIMBLE_SVC_DIS_SOFTWARE_REVISION +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (0) +#else #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) #endif @@ -1622,23 +1770,31 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT ("00000000") #endif /* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ -#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM +#if CONFIG_BT_NIMBLE_SVC_DIS_SYSTEM_ID +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (0) +#else #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_DEFAULT (NULL) +#define MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_DEFAULT ("000000") #endif /* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ -#ifndef MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_READ_PERM +#if CONFIG_BT_NIMBLE_SVC_DIS_PNP_ID +#define MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_READ_PERM (0) +#else #define MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_READ_PERM (-1) #endif +#ifndef MYNEWT_VAL_BLE_SVC_DIS_INCLUDED +#define MYNEWT_VAL_BLE_SVC_DIS_INCLUDED (CONFIG_BT_NIMBLE_SVC_DIS_INCLUDED) +#endif + /*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE @@ -1701,6 +1857,16 @@ CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO #endif +#ifndef MYNEWT_VAL_BLE_SVC_GAP_GATT_SECURITY_LEVEL +#define MYNEWT_VAL_BLE_SVC_GAP_GATT_SECURITY_LEVEL \ + CONFIG_BT_NIMBLE_SVC_GAP_GATT_SECURITY_LEVEL +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_RPA_ONLY +#define MYNEWT_VAL_BLE_SVC_GAP_RPA_ONLY \ + CONFIG_BT_NIMBLE_SVC_GAP_RPA_ONLY +#endif + /*** nimble/transport */ #ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI #define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) @@ -1816,7 +1982,7 @@ #ifdef CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK #define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK #else -#define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK FALSE +#define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK (0) #endif #endif @@ -1828,6 +1994,38 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_AOA_AOD +#ifdef CONFIG_BT_NIMBLE_AOA_AOD +#define MYNEWT_VAL_BLE_AOA_AOD CONFIG_BT_NIMBLE_AOA_AOD +#else +#define MYNEWT_VAL_BLE_AOA_AOD (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT +#ifdef CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT +#define MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT CONFIG_BT_NIMBLE_GATTC_PROC_PREEMPTION_PROTECT +#else +#define MYNEWT_VAL_BLE_GATTC_PROC_PREEMPTION_PROTECT (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN +#ifdef CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN +#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN +#else +#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BT_HCI_LOG_INCLUDED +#ifdef CONFIG_BT_HCI_LOG_DEBUG_EN +#define MYNEWT_VAL_BT_HCI_LOG_INCLUDED CONFIG_BT_HCI_LOG_DEBUG_EN +#else +#define MYNEWT_VAL_BT_HCI_LOG_INCLUDED (0) +#endif +#endif + #if CONFIG_BT_CONTROLLER_DISABLED && CONFIG_BT_NIMBLE_TRANSPORT_UART #ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_PORT #define MYNEWT_VAL_BLE_TRANSPORT_UART_PORT CONFIG_BT_NIMBLE_TRANSPORT_UART_PORT @@ -1862,4 +2060,32 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_WITH_RESPONSES +#ifdef CONFIG_BT_NIMBLE_PERIODIC_ADV_WITH_RESPONSES +#define MYNEWT_VAL_BLE_PERIODIC_ADV_WITH_RESPONSES (CONFIG_BT_NIMBLE_PERIODIC_ADV_WITH_RESPONSES) +#else +#define MYNEWT_VAL_BLE_PERIODIC_ADV_WITH_RESPONSES (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HANDLE_REPEAT_PAIRING_DELETION +#ifdef CONFIG_BT_NIMBLE_HANDLE_REPEAT_PAIRING_DELETION +#define MYNEWT_VAL_BLE_HANDLE_REPEAT_PAIRING_DELETION (CONFIG_BT_NIMBLE_HANDLE_REPEAT_PAIRING_DELETION) +#else +#define MYNEWT_VAL_BLE_HANDLE_REPEAT_PAIRING_DELETION (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_ERR_CHECK +#ifdef CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#define MYNEWT_VAL_BLE_ERR_CHECK CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#else +#define MYNEWT_VAL_BLE_ERR_CHECK (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_USED_IN_IDF +#define MYNEWT_VAL_BLE_USED_IN_IDF (1) +#endif + #endif -- cgit v1.2.3