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