1 /*
2  * Copyright (c) 2016 Nordic Semiconductor ASA
3  * Copyright (c) 2016 Vinayak Kariappa Chettimada
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/types.h>
9 #include <zephyr/sys/byteorder.h>
10 #include <zephyr/ztest.h>
11 #include "util.h"
12 
13 #include "pdu_df.h"
14 #include "lll/pdu_vendor.h"
15 #include "pdu.h"
16 
17 #include "util/mem.h"
18 #include "util/memq.h"
19 #include "util/mayfly.h"
20 #include "lll.h"
21 
22 /**
23  * @brief Population count: Count the number of bits set to 1
24  *
25  * @param octets     Data to count over
26  * @param octets_len Must not be bigger than 255/8 = 31 bytes
27  *
28  * @return popcnt of 'octets'
29  */
util_ones_count_get(uint8_t * octets,uint8_t octets_len)30 uint8_t util_ones_count_get(uint8_t *octets, uint8_t octets_len)
31 {
32 	uint8_t one_count = 0U;
33 
34 	while (octets_len--) {
35 		uint8_t bite;
36 
37 		bite = *octets;
38 		while (bite) {
39 			bite &= (bite - 1);
40 			one_count++;
41 		}
42 		octets++;
43 	}
44 
45 	return one_count;
46 }
47 
util_rand(void * buf,size_t len)48 int util_rand(void *buf, size_t len)
49 {
50 	return 0xDEADBEEF;
51 }
52 
53 /** @brief Prepare access address as per BT Spec.
54  *
55  * - It shall have no more than six consecutive zeros or ones.
56  * - It shall not be the advertising channel packets' Access Address.
57  * - It shall not be a sequence that differs from the advertising channel
58  *   packets Access Address by only one bit.
59  * - It shall not have all four octets equal.
60  * - It shall have no more than 24 transitions.
61  * - It shall have a minimum of two transitions in the most significant six
62  *   bits.
63  *
64  * LE Coded PHY requirements:
65  * - It shall have at least three ones in the least significant 8 bits.
66  * - It shall have no more than eleven transitions in the least significant 16
67  *   bits.
68  */
util_aa_le32(uint8_t * dst)69 int util_aa_le32(uint8_t *dst)
70 {
71 #if defined(CONFIG_BT_CTLR_PHY_CODED)
72 	uint8_t transitions_lsb16;
73 	uint8_t ones_count_lsb8;
74 #endif /* CONFIG_BT_CTLR_PHY_CODED */
75 	uint8_t consecutive_cnt;
76 	uint8_t consecutive_bit;
77 	uint32_t adv_aa_check;
78 	uint32_t aa;
79 	uint8_t transitions;
80 	uint8_t bit_idx;
81 	uint8_t retry;
82 
83 	retry = 3U;
84 again:
85 	if (!retry) {
86 		return -EFAULT;
87 	}
88 	retry--;
89 
90 	*dst = lll_csrand_get(dst, sizeof(uint32_t));
91 	aa = sys_get_le32(dst);
92 
93 	bit_idx = 31U;
94 	transitions = 0U;
95 	consecutive_cnt = 1U;
96 #if defined(CONFIG_BT_CTLR_PHY_CODED)
97 	ones_count_lsb8 = 0U;
98 	transitions_lsb16 = 0U;
99 #endif /* CONFIG_BT_CTLR_PHY_CODED */
100 	consecutive_bit = (aa >> bit_idx) & 0x01;
101 	while (bit_idx--) {
102 #if defined(CONFIG_BT_CTLR_PHY_CODED)
103 		uint8_t transitions_lsb16_prev = transitions_lsb16;
104 #endif /* CONFIG_BT_CTLR_PHY_CODED */
105 		uint8_t consecutive_cnt_prev = consecutive_cnt;
106 		uint8_t transitions_prev = transitions;
107 		uint8_t bit;
108 
109 		bit = (aa >> bit_idx) & 0x01;
110 		if (bit == consecutive_bit) {
111 			consecutive_cnt++;
112 		} else {
113 			consecutive_cnt = 1U;
114 			consecutive_bit = bit;
115 			transitions++;
116 
117 #if defined(CONFIG_BT_CTLR_PHY_CODED)
118 			if (bit_idx < 15) {
119 				transitions_lsb16++;
120 			}
121 #endif /* CONFIG_BT_CTLR_PHY_CODED */
122 		}
123 
124 #if defined(CONFIG_BT_CTLR_PHY_CODED)
125 		if ((bit_idx < 8) && consecutive_bit) {
126 			ones_count_lsb8++;
127 		}
128 #endif /* CONFIG_BT_CTLR_PHY_CODED */
129 
130 		/* It shall have no more than six consecutive zeros or ones. */
131 		/* It shall have a minimum of two transitions in the most
132 		 * significant six bits.
133 		 */
134 		if ((consecutive_cnt > 6) ||
135 #if defined(CONFIG_BT_CTLR_PHY_CODED)
136 		    (!consecutive_bit && (((bit_idx < 6) && (ones_count_lsb8 < 1)) ||
137 					  ((bit_idx < 5) && (ones_count_lsb8 < 2)) ||
138 					  ((bit_idx < 4) && (ones_count_lsb8 < 3)))) ||
139 #endif /* CONFIG_BT_CTLR_PHY_CODED */
140 		    ((consecutive_cnt < 6) && (((bit_idx < 29) && (transitions < 1)) ||
141 					       ((bit_idx < 28) && (transitions < 2))))) {
142 			if (consecutive_bit) {
143 				consecutive_bit = 0U;
144 				aa &= ~BIT(bit_idx);
145 #if defined(CONFIG_BT_CTLR_PHY_CODED)
146 				if (bit_idx < 8) {
147 					ones_count_lsb8--;
148 				}
149 #endif /* CONFIG_BT_CTLR_PHY_CODED */
150 			} else {
151 				consecutive_bit = 1U;
152 				aa |= BIT(bit_idx);
153 #if defined(CONFIG_BT_CTLR_PHY_CODED)
154 				if (bit_idx < 8) {
155 					ones_count_lsb8++;
156 				}
157 #endif /* CONFIG_BT_CTLR_PHY_CODED */
158 			}
159 
160 			if (transitions != transitions_prev) {
161 				consecutive_cnt = consecutive_cnt_prev;
162 				transitions = transitions_prev;
163 			} else {
164 				consecutive_cnt = 1U;
165 				transitions++;
166 			}
167 
168 #if defined(CONFIG_BT_CTLR_PHY_CODED)
169 			if (bit_idx < 15) {
170 				if (transitions_lsb16 != transitions_lsb16_prev) {
171 					transitions_lsb16 = transitions_lsb16_prev;
172 				} else {
173 					transitions_lsb16++;
174 				}
175 			}
176 #endif /* CONFIG_BT_CTLR_PHY_CODED */
177 		}
178 
179 		/* It shall have no more than 24 transitions
180 		 * It shall have no more than eleven transitions in the least
181 		 * significant 16 bits.
182 		 */
183 		if ((transitions > 24) ||
184 #if defined(CONFIG_BT_CTLR_PHY_CODED)
185 		    (transitions_lsb16 > 11) ||
186 #endif /* CONFIG_BT_CTLR_PHY_CODED */
187 		    0) {
188 			if (consecutive_bit) {
189 				aa &= ~(BIT(bit_idx + 1) - 1);
190 			} else {
191 				aa |= (BIT(bit_idx + 1) - 1);
192 			}
193 
194 			break;
195 		}
196 	}
197 
198 	/* It shall not be the advertising channel packets Access Address.
199 	 * It shall not be a sequence that differs from the advertising channel
200 	 * packets Access Address by only one bit.
201 	 */
202 	adv_aa_check = aa ^ PDU_AC_ACCESS_ADDR;
203 	if (util_ones_count_get((uint8_t *)&adv_aa_check, sizeof(adv_aa_check)) <= 1) {
204 		goto again;
205 	}
206 
207 	/* It shall not have all four octets equal. */
208 	if (!((aa & 0xFFFF) ^ (aa >> 16)) && !((aa & 0xFF) ^ (aa >> 24))) {
209 		goto again;
210 	}
211 
212 	sys_put_le32(aa, dst);
213 
214 	return 0;
215 }
216