1 /* Copyright (c) 2020 Nordic Semiconductor ASA
2  *
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <zephyr/sys/byteorder.h>
7 
8 #include <zephyr/bluetooth/addr.h>
9 #include <zephyr/bluetooth/hci_vs.h>
10 
11 #include <soc.h>
12 
hci_vendor_read_static_addr(struct bt_hci_vs_static_addr addrs[],uint8_t size)13 uint8_t hci_vendor_read_static_addr(struct bt_hci_vs_static_addr addrs[],
14 				 uint8_t size)
15 {
16 	/* only one supported */
17 	ARG_UNUSED(size);
18 
19 	if (((NRF_FICR->DEVICEADDR[0] != UINT32_MAX) ||
20 	    ((NRF_FICR->DEVICEADDR[1] & UINT16_MAX) != UINT16_MAX)) &&
21 	     (NRF_FICR->DEVICEADDRTYPE & 0x01)) {
22 		sys_put_le32(NRF_FICR->DEVICEADDR[0], &addrs[0].bdaddr.val[0]);
23 		sys_put_le16(NRF_FICR->DEVICEADDR[1], &addrs[0].bdaddr.val[4]);
24 
25 		/* The FICR value is a just a random number, with no knowledge
26 		 * of the Bluetooth Specification requirements for random
27 		 * static addresses.
28 		 */
29 		BT_ADDR_SET_STATIC(&addrs[0].bdaddr);
30 
31 		/* If no public address is provided and a static address is
32 		 * available, then it is recommended to return an identity root
33 		 * key (if available) from this command.
34 		 */
35 		if ((NRF_FICR->IR[0] != UINT32_MAX) &&
36 		    (NRF_FICR->IR[1] != UINT32_MAX) &&
37 		    (NRF_FICR->IR[2] != UINT32_MAX) &&
38 		    (NRF_FICR->IR[3] != UINT32_MAX)) {
39 			sys_put_le32(NRF_FICR->IR[0], &addrs[0].ir[0]);
40 			sys_put_le32(NRF_FICR->IR[1], &addrs[0].ir[4]);
41 			sys_put_le32(NRF_FICR->IR[2], &addrs[0].ir[8]);
42 			sys_put_le32(NRF_FICR->IR[3], &addrs[0].ir[12]);
43 		} else {
44 			/* Mark IR as invalid */
45 			(void)memset(addrs[0].ir, 0x00, sizeof(addrs[0].ir));
46 		}
47 
48 		return 1;
49 	}
50 
51 	return 0;
52 }
53 
hci_vendor_read_key_hierarchy_roots(uint8_t ir[16],uint8_t er[16])54 void hci_vendor_read_key_hierarchy_roots(uint8_t ir[16], uint8_t er[16])
55 {
56 	/* Mark IR as invalid.
57 	 * No public address is available, and static address IR should be read
58 	 * using Read Static Addresses command.
59 	 */
60 	(void)memset(ir, 0x00, 16);
61 
62 	/* Fill in ER if present */
63 	if ((NRF_FICR->ER[0] != UINT32_MAX) &&
64 	    (NRF_FICR->ER[1] != UINT32_MAX) &&
65 	    (NRF_FICR->ER[2] != UINT32_MAX) &&
66 	    (NRF_FICR->ER[3] != UINT32_MAX)) {
67 		sys_put_le32(NRF_FICR->ER[0], &er[0]);
68 		sys_put_le32(NRF_FICR->ER[1], &er[4]);
69 		sys_put_le32(NRF_FICR->ER[2], &er[8]);
70 		sys_put_le32(NRF_FICR->ER[3], &er[12]);
71 	} else {
72 		/* Mark ER as invalid */
73 		(void)memset(er, 0x00, 16);
74 	}
75 }
76