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:
parent
0095daefbc
commit
e4538c6807
7 changed files with 129 additions and 121 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
76
subsys/bluetooth/controller/hci/nordic/hci_vendor.c
Normal file
76
subsys/bluetooth/controller/hci/nordic/hci_vendor.c
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue