From e4538c6807c34735a3ed5ed76999d5e98b39dee0 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 3 Mar 2020 13:39:06 +0100 Subject: [PATCH] Bluetooth: HCI: Re-organize vendor read static address handling Add header definition for bt_read_static_addr function. Declaring it without a header definition will not give any compilation error when function definition changes. Refactor nRF SoC specific code into nRF specific source files and provide weak definitions when these are not implemented. This will make it easier to add handlers per vendor. Signed-off-by: Joakim Andersson --- include/bluetooth/addr.h | 1 + include/drivers/bluetooth/hci_driver.h | 10 ++ subsys/bluetooth/controller/hci/hci.c | 147 ++++-------------- .../bluetooth/controller/hci/hci_internal.h | 3 + .../controller/hci/nordic/hci_vendor.c | 76 +++++++++ subsys/bluetooth/controller/ll_sw/nrf.cmake | 5 + subsys/bluetooth/host/hci_core.c | 8 +- 7 files changed, 129 insertions(+), 121 deletions(-) create mode 100644 subsys/bluetooth/controller/hci/nordic/hci_vendor.c diff --git a/include/bluetooth/addr.h b/include/bluetooth/addr.h index 02135037ba4..394427e3181 100644 --- a/include/bluetooth/addr.h +++ b/include/bluetooth/addr.h @@ -10,6 +10,7 @@ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_ADDR_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_ADDR_H_ +#include #include #ifdef __cplusplus diff --git a/include/drivers/bluetooth/hci_driver.h b/include/drivers/bluetooth/hci_driver.h index 753e16f7c8f..83c9dda348a 100644 --- a/include/drivers/bluetooth/hci_driver.h +++ b/include/drivers/bluetooth/hci_driver.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -95,6 +96,15 @@ int bt_recv(struct net_buf *buf); */ int bt_recv_prio(struct net_buf *buf); +/** @brief Read static addresses from the controller. + * + * @param addrs Random static address and Identity Root (IR) array. + * @param size Size of array. + * + * @return Number of addresses read. + */ +u8_t bt_read_static_addr(struct bt_hci_vs_static_addr addrs[], u8_t size); + /** Possible values for the 'bus' member of the bt_hci_driver struct */ enum bt_hci_driver_bus { BT_HCI_DRIVER_BUS_VIRTUAL = 0, diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 4d447708fd0..1e5648d8710 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -1897,6 +1897,24 @@ static void vs_read_supported_features(struct net_buf *buf, (void)memset(&rp->features[0], 0x00, sizeof(rp->features)); } +u8_t __weak hci_vendor_read_static_addr(struct bt_hci_vs_static_addr addrs[], + u8_t size) +{ + ARG_UNUSED(addrs); + ARG_UNUSED(size); + + return 0; +} + +/* If Zephyr VS HCI commands are not enabled provide this functionality directly + */ +#if !defined(CONFIG_BT_HCI_VS_EXT) +u8_t bt_read_static_addr(struct bt_hci_vs_static_addr addrs[], u8_t size) +{ + return hci_vendor_read_static_addr(addrs, size); +} +#endif /* !defined(CONFIG_BT_HCI_VS_EXT) */ + #if defined(CONFIG_BT_HCI_VS_EXT) static void vs_write_bd_addr(struct net_buf *buf, struct net_buf **evt) { @@ -1930,58 +1948,23 @@ static void vs_read_build_info(struct net_buf *buf, struct net_buf **evt) memcpy(rp->info, build_info, sizeof(build_info)); } +void __weak hci_vendor_read_key_hierarchy_roots(u8_t ir[16], u8_t er[16]) +{ + /* Mark IR as invalid */ + (void)memset(ir, 0x00, 16); + + /* Mark ER as invalid */ + (void)memset(er, 0x00, 16); +} + static void vs_read_static_addrs(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_rp_vs_read_static_addrs *rp; -#if defined(CONFIG_SOC_COMPATIBLE_NRF) - /* Read address from nRF5-specific storage - * Non-initialized FICR values default to 0xFF, skip if no address - * present. Also if a public address lives in FICR, do not use in this - * function. - */ - if (((NRF_FICR->DEVICEADDR[0] != UINT32_MAX) || - ((NRF_FICR->DEVICEADDR[1] & UINT16_MAX) != UINT16_MAX)) && - (NRF_FICR->DEVICEADDRTYPE & 0x01)) { - struct bt_hci_vs_static_addr *addr; - - rp = hci_cmd_complete(evt, sizeof(*rp) + sizeof(*addr)); - rp->status = 0x00; - rp->num_addrs = 1U; - - addr = &rp->a[0]; - sys_put_le32(NRF_FICR->DEVICEADDR[0], &addr->bdaddr.val[0]); - sys_put_le16(NRF_FICR->DEVICEADDR[1], &addr->bdaddr.val[4]); - /* The FICR value is a just a random number, with no knowledge - * of the Bluetooth Specification requirements for random - * static addresses. - */ - BT_ADDR_SET_STATIC(&addr->bdaddr); - - /* If no public address is provided and a static address is - * available, then it is recommended to return an identity root - * key (if available) from this command. - */ - if ((NRF_FICR->IR[0] != UINT32_MAX) && - (NRF_FICR->IR[1] != UINT32_MAX) && - (NRF_FICR->IR[2] != UINT32_MAX) && - (NRF_FICR->IR[3] != UINT32_MAX)) { - sys_put_le32(NRF_FICR->IR[0], &addr->ir[0]); - sys_put_le32(NRF_FICR->IR[1], &addr->ir[4]); - sys_put_le32(NRF_FICR->IR[2], &addr->ir[8]); - sys_put_le32(NRF_FICR->IR[3], &addr->ir[12]); - } else { - /* Mark IR as invalid */ - (void)memset(addr->ir, 0x00, sizeof(addr->ir)); - } - - return; - } -#endif /* CONFIG_SOC_FAMILY_NRF */ - - rp = hci_cmd_complete(evt, sizeof(*rp)); + rp = hci_cmd_complete(evt, sizeof(*rp) + + sizeof(struct bt_hci_vs_static_addr)); rp->status = 0x00; - rp->num_addrs = 0U; + rp->num_addrs = hci_vendor_read_static_addr(rp->a, 1); } static void vs_read_key_hierarchy_roots(struct net_buf *buf, @@ -1991,35 +1974,7 @@ static void vs_read_key_hierarchy_roots(struct net_buf *buf, rp = hci_cmd_complete(evt, sizeof(*rp)); rp->status = 0x00; - -#if defined(CONFIG_SOC_COMPATIBLE_NRF) - /* Mark IR as invalid. - * No public address is available, and static address IR should be read - * using Read Static Addresses command. - */ - (void)memset(rp->ir, 0x00, sizeof(rp->ir)); - - /* Fill in ER if present */ - if ((NRF_FICR->ER[0] != UINT32_MAX) && - (NRF_FICR->ER[1] != UINT32_MAX) && - (NRF_FICR->ER[2] != UINT32_MAX) && - (NRF_FICR->ER[3] != UINT32_MAX)) { - sys_put_le32(NRF_FICR->ER[0], &rp->er[0]); - sys_put_le32(NRF_FICR->ER[1], &rp->er[4]); - sys_put_le32(NRF_FICR->ER[2], &rp->er[8]); - sys_put_le32(NRF_FICR->ER[3], &rp->er[12]); - } else { - /* Mark ER as invalid */ - (void)memset(rp->er, 0x00, sizeof(rp->er)); - } - - return; -#else - /* Mark IR as invalid */ - (void)memset(rp->ir, 0x00, sizeof(rp->ir)); - /* Mark ER as invalid */ - (void)memset(rp->er, 0x00, sizeof(rp->er)); -#endif /* CONFIG_SOC_FAMILY_NRF */ + hci_vendor_read_key_hierarchy_roots(rp->ir, rp->er); } #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) @@ -2276,46 +2231,6 @@ int hci_vendor_cmd_handle_common(u16_t ocf, struct net_buf *cmd, } #endif -#if !defined(CONFIG_BT_HCI_VS_EXT) -uint8_t bt_read_static_addr(struct bt_hci_vs_static_addr *addr) -{ -#if defined(CONFIG_SOC_FAMILY_NRF) - if (((NRF_FICR->DEVICEADDR[0] != UINT32_MAX) || - ((NRF_FICR->DEVICEADDR[1] & UINT16_MAX) != UINT16_MAX)) && - (NRF_FICR->DEVICEADDRTYPE & 0x01)) { - sys_put_le32(NRF_FICR->DEVICEADDR[0], &addr->bdaddr.val[0]); - sys_put_le16(NRF_FICR->DEVICEADDR[1], &addr->bdaddr.val[4]); - - /* The FICR value is a just a random number, with no knowledge - * of the Bluetooth Specification requirements for random - * static addresses. - */ - BT_ADDR_SET_STATIC(&addr->bdaddr); - - /* If no public address is provided and a static address is - * available, then it is recommended to return an identity root - * key (if available) from this command. - */ - if ((NRF_FICR->IR[0] != UINT32_MAX) && - (NRF_FICR->IR[1] != UINT32_MAX) && - (NRF_FICR->IR[2] != UINT32_MAX) && - (NRF_FICR->IR[3] != UINT32_MAX)) { - sys_put_le32(NRF_FICR->IR[0], &addr->ir[0]); - sys_put_le32(NRF_FICR->IR[1], &addr->ir[4]); - sys_put_le32(NRF_FICR->IR[2], &addr->ir[8]); - sys_put_le32(NRF_FICR->IR[3], &addr->ir[12]); - } else { - /* Mark IR as invalid */ - (void)memset(addr->ir, 0x00, sizeof(addr->ir)); - } - - return 1; - } -#endif /* CONFIG_SOC_FAMILY_NRF */ - return 0; -} -#endif /* !CONFIG_BT_HCI_VS_EXT */ - struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx) { struct bt_hci_evt_cc_status *ccst; diff --git a/subsys/bluetooth/controller/hci/hci_internal.h b/subsys/bluetooth/controller/hci/hci_internal.h index fcd22a9fb2e..3afd11d8a63 100644 --- a/subsys/bluetooth/controller/hci/hci_internal.h +++ b/subsys/bluetooth/controller/hci/hci_internal.h @@ -49,6 +49,9 @@ void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num); #endif int hci_vendor_cmd_handle(u16_t ocf, struct net_buf *cmd, struct net_buf **evt); +u8_t hci_vendor_read_static_addr(struct bt_hci_vs_static_addr addrs[], + u8_t size); +void hci_vendor_read_key_hierarchy_roots(u8_t ir[16], u8_t er[16]); int hci_vendor_cmd_handle_common(u16_t ocf, struct net_buf *cmd, struct net_buf **evt); void *hci_cmd_complete(struct net_buf **buf, u8_t plen); diff --git a/subsys/bluetooth/controller/hci/nordic/hci_vendor.c b/subsys/bluetooth/controller/hci/nordic/hci_vendor.c new file mode 100644 index 00000000000..4bdf2849096 --- /dev/null +++ b/subsys/bluetooth/controller/hci/nordic/hci_vendor.c @@ -0,0 +1,76 @@ +/* Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include + +u8_t hci_vendor_read_static_addr(struct bt_hci_vs_static_addr addrs[], + u8_t size) +{ + /* only one supported */ + ARG_UNUSED(size); + + if (((NRF_FICR->DEVICEADDR[0] != UINT32_MAX) || + ((NRF_FICR->DEVICEADDR[1] & UINT16_MAX) != UINT16_MAX)) && + (NRF_FICR->DEVICEADDRTYPE & 0x01)) { + sys_put_le32(NRF_FICR->DEVICEADDR[0], &addrs[0].bdaddr.val[0]); + sys_put_le16(NRF_FICR->DEVICEADDR[1], &addrs[0].bdaddr.val[4]); + + /* The FICR value is a just a random number, with no knowledge + * of the Bluetooth Specification requirements for random + * static addresses. + */ + BT_ADDR_SET_STATIC(&addrs[0].bdaddr); + + /* If no public address is provided and a static address is + * available, then it is recommended to return an identity root + * key (if available) from this command. + */ + if ((NRF_FICR->IR[0] != UINT32_MAX) && + (NRF_FICR->IR[1] != UINT32_MAX) && + (NRF_FICR->IR[2] != UINT32_MAX) && + (NRF_FICR->IR[3] != UINT32_MAX)) { + sys_put_le32(NRF_FICR->IR[0], &addrs[0].ir[0]); + sys_put_le32(NRF_FICR->IR[1], &addrs[0].ir[4]); + sys_put_le32(NRF_FICR->IR[2], &addrs[0].ir[8]); + sys_put_le32(NRF_FICR->IR[3], &addrs[0].ir[12]); + } else { + /* Mark IR as invalid */ + (void)memset(addrs[0].ir, 0x00, sizeof(addrs[0].ir)); + } + + return 1; + } + + return 0; +} + +void hci_vendor_read_key_hierarchy_roots(u8_t ir[16], u8_t er[16]) +{ + /* Mark IR as invalid. + * No public address is available, and static address IR should be read + * using Read Static Addresses command. + */ + (void)memset(ir, 0x00, 16); + + /* Fill in ER if present */ + if ((NRF_FICR->ER[0] != UINT32_MAX) && + (NRF_FICR->ER[1] != UINT32_MAX) && + (NRF_FICR->ER[2] != UINT32_MAX) && + (NRF_FICR->ER[3] != UINT32_MAX)) { + sys_put_le32(NRF_FICR->ER[0], &er[0]); + sys_put_le32(NRF_FICR->ER[1], &er[4]); + sys_put_le32(NRF_FICR->ER[2], &er[8]); + sys_put_le32(NRF_FICR->ER[3], &er[12]); + } else { + /* Mark ER as invalid */ + (void)memset(er, 0x00, 16); + } +} diff --git a/subsys/bluetooth/controller/ll_sw/nrf.cmake b/subsys/bluetooth/controller/ll_sw/nrf.cmake index 6f31911d9fd..1109c4a7432 100644 --- a/subsys/bluetooth/controller/ll_sw/nrf.cmake +++ b/subsys/bluetooth/controller/ll_sw/nrf.cmake @@ -84,6 +84,11 @@ zephyr_library_sources( ll_sw/nordic/hal/nrf5/ticker.c ) +zephyr_library_sources_ifdef( + CONFIG_SOC_FAMILY_NRF + hci/nordic/hci_vendor.c + ) + zephyr_library_include_directories( ll_sw/nordic hci/nordic diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 07a5d7c4f2f..ea1eacbfe0e 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -5737,7 +5737,7 @@ void bt_setup_public_id_addr(void) } #if defined(CONFIG_BT_HCI_VS_EXT) -static uint8_t bt_read_static_addr(struct bt_hci_vs_static_addr *addrs) +u8_t bt_read_static_addr(struct bt_hci_vs_static_addr addrs[], u8_t size) { struct bt_hci_rp_vs_read_static_addrs *rp; struct net_buf *rsp; @@ -5763,7 +5763,7 @@ static uint8_t bt_read_static_addr(struct bt_hci_vs_static_addr *addrs) } rp = (void *)rsp->data; - cnt = MIN(rp->num_addrs, CONFIG_BT_ID_MAX); + cnt = MIN(rp->num_addrs, size); if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) && rsp->len != (sizeof(struct bt_hci_rp_vs_read_static_addrs) + @@ -5785,8 +5785,6 @@ static uint8_t bt_read_static_addr(struct bt_hci_vs_static_addr *addrs) return cnt; } -#elif defined(CONFIG_BT_CTLR) -uint8_t bt_read_static_addr(struct bt_hci_vs_static_addr *addrs); #endif /* CONFIG_BT_HCI_VS_EXT */ int bt_setup_random_id_addr(void) @@ -5798,7 +5796,7 @@ int bt_setup_random_id_addr(void) if (!bt_dev.id_count) { struct bt_hci_vs_static_addr addrs[CONFIG_BT_ID_MAX]; - bt_dev.id_count = bt_read_static_addr(addrs); + bt_dev.id_count = bt_read_static_addr(addrs, CONFIG_BT_ID_MAX); if (bt_dev.id_count) { for (u8_t i = 0; i < bt_dev.id_count; i++) {