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 <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2020-03-03 13:39:06 +01:00 committed by Johan Hedberg
commit e4538c6807
7 changed files with 129 additions and 121 deletions

View file

@ -10,6 +10,7 @@
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_ADDR_H_
#define ZEPHYR_INCLUDE_BLUETOOTH_ADDR_H_
#include <string.h>
#include <zephyr/types.h>
#ifdef __cplusplus

View file

@ -20,6 +20,7 @@
#include <stdbool.h>
#include <net/buf.h>
#include <bluetooth/buf.h>
#include <bluetooth/hci_vs.h>
#include <device.h>
#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,

View file

@ -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;

View file

@ -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);

View file

@ -0,0 +1,76 @@
/* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/types.h>
#include <sys/byteorder.h>
#include <bluetooth/addr.h>
#include <bluetooth/hci_vs.h>
#include <nrf.h>
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);
}
}

View file

@ -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

View file

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