1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include "testutil/testutil.h"
21 #include "host/ble_hs_test.h"
22 #include "ble_hs_test_util.h"
23
24 static struct ble_store_status_event ble_store_test_status_event;
25
26 static void
ble_store_test_util_verify_peer_deleted(const ble_addr_t * addr)27 ble_store_test_util_verify_peer_deleted(const ble_addr_t *addr)
28 {
29 union ble_store_value value;
30 union ble_store_key key;
31 ble_addr_t addrs[64];
32 int num_addrs;
33 int rc;
34 int i;
35
36 memset(&key, 0, sizeof key);
37 key.sec.peer_addr = *addr;
38 rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, &key, &value);
39 TEST_ASSERT(rc == BLE_HS_ENOENT);
40 rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_SEC, &key, &value);
41 TEST_ASSERT(rc == BLE_HS_ENOENT);
42
43 memset(&key, 0, sizeof key);
44 key.cccd.peer_addr = *addr;
45 rc = ble_store_read(BLE_STORE_OBJ_TYPE_CCCD, &key, &value);
46 TEST_ASSERT(rc == BLE_HS_ENOENT);
47
48 rc = ble_store_util_bonded_peers(addrs, &num_addrs,
49 sizeof addrs / sizeof addrs[0]);
50 TEST_ASSERT_FATAL(rc == 0);
51 for (i = 0; i < num_addrs; i++) {
52 TEST_ASSERT(ble_addr_cmp(addr, addrs + i) != 0);
53 }
54 }
55
56 static int
ble_store_test_util_status_overflow(struct ble_store_status_event * event,void * arg)57 ble_store_test_util_status_overflow(struct ble_store_status_event *event,
58 void *arg)
59 {
60 int *status;
61
62 status = arg;
63
64 ble_store_test_status_event = *event;
65 return *status;
66 }
67
68 static void
ble_store_test_util_overflow_sec(int is_our_sec)69 ble_store_test_util_overflow_sec(int is_our_sec)
70 {
71 union ble_store_value val;
72 int obj_type;
73 int status;
74 int rc;
75 int i;
76
77 ble_hs_test_util_init();
78
79 ble_hs_cfg.store_status_cb = ble_store_test_util_status_overflow;
80 ble_hs_cfg.store_status_arg = &status;
81
82 if (is_our_sec) {
83 obj_type = BLE_STORE_OBJ_TYPE_OUR_SEC;
84 } else {
85 obj_type = BLE_STORE_OBJ_TYPE_PEER_SEC;
86 }
87
88 memset(&ble_store_test_status_event, 0,
89 sizeof ble_store_test_status_event);
90 memset(&val, 0, sizeof val);
91
92 val.sec.peer_addr =
93 (ble_addr_t){ BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } };
94 val.sec.ltk_present = 1,
95
96 status = BLE_HS_ESTORE_CAP;
97 for (i = 0; ; i++) {
98 rc = ble_store_write(obj_type, &val);
99 if (i < MYNEWT_VAL(BLE_STORE_MAX_BONDS)) {
100 TEST_ASSERT_FATAL(rc == 0);
101 } else {
102 /* This record should have caused an overflow. */
103 TEST_ASSERT(rc == BLE_HS_ESTORE_CAP);
104 TEST_ASSERT(ble_store_test_status_event.event_code ==
105 BLE_STORE_EVENT_OVERFLOW);
106 TEST_ASSERT(ble_store_test_status_event.overflow.obj_type ==
107 obj_type);
108 TEST_ASSERT(ble_store_test_status_event.overflow.value == &val);
109 break;
110 }
111
112 val.sec.peer_addr.val[0]++;
113 }
114 }
115
116 static int
ble_store_test_util_count(int obj_type)117 ble_store_test_util_count(int obj_type)
118 {
119 int count;
120 int rc;
121
122 rc = ble_store_util_count(obj_type, &count);
123 TEST_ASSERT_FATAL(rc == 0);
124
125 return count;
126 }
127
TEST_CASE(ble_store_test_peers)128 TEST_CASE(ble_store_test_peers)
129 {
130 struct ble_store_value_sec secs[3] = {
131 {
132 .peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
133 .ltk_present = 1,
134 },
135 {
136 /* Address value is a duplicate of above, but type differs. */
137 .peer_addr = { BLE_ADDR_RANDOM, { 1, 2, 3, 4, 5, 6 } },
138 .ltk_present = 1,
139 },
140 {
141 .peer_addr = { BLE_ADDR_PUBLIC, { 2, 3, 4, 5, 6, 7 } },
142 .ltk_present = 1,
143 },
144 };
145 ble_addr_t peer_addrs[3];
146 int num_addrs;
147 int rc;
148 int i;
149
150 ble_hs_test_util_init();
151
152 for (i = 0; i < sizeof secs / sizeof secs[0]; i++) {
153 rc = ble_store_write_our_sec(secs + i);
154 TEST_ASSERT_FATAL(rc == 0);
155 rc = ble_store_write_peer_sec(secs + i);
156 TEST_ASSERT_FATAL(rc == 0);
157 }
158
159 rc = ble_store_util_bonded_peers(peer_addrs, &num_addrs,
160 sizeof peer_addrs / sizeof peer_addrs[0]);
161 TEST_ASSERT_FATAL(rc == 0);
162
163 TEST_ASSERT(num_addrs == sizeof secs / sizeof secs[0]);
164 for (i = 0; i < num_addrs; i++) {
165 TEST_ASSERT(ble_addr_cmp(&peer_addrs[i], &secs[i].peer_addr) == 0);
166 }
167 }
168
TEST_CASE(ble_store_test_delete_peer)169 TEST_CASE(ble_store_test_delete_peer)
170 {
171 struct ble_store_value_sec secs[2] = {
172 {
173 .peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
174 .ltk_present = 1,
175 },
176 {
177 /* Address value is a duplicate of above, but type differs. */
178 .peer_addr = { BLE_ADDR_RANDOM, { 1, 2, 3, 4, 5, 6 } },
179 .ltk_present = 1,
180 },
181 };
182 struct ble_store_value_cccd cccds[3] = {
183 /* First two belong to first peer. */
184 {
185 .peer_addr = secs[0].peer_addr,
186 .chr_val_handle = 5,
187 },
188 {
189 .peer_addr = secs[0].peer_addr,
190 .chr_val_handle = 8,
191 },
192
193 /* Last belongs to second peer. */
194 {
195 .peer_addr = secs[1].peer_addr,
196 .chr_val_handle = 5,
197 },
198 };
199 union ble_store_value value;
200 union ble_store_key key;
201 int count;
202 int rc;
203 int i;
204
205 ble_hs_test_util_init();
206
207 for (i = 0; i < sizeof secs / sizeof secs[0]; i++) {
208 rc = ble_store_write_our_sec(secs + i);
209 TEST_ASSERT_FATAL(rc == 0);
210 rc = ble_store_write_peer_sec(secs + i);
211 TEST_ASSERT_FATAL(rc == 0);
212 }
213
214 for (i = 0; i < sizeof cccds / sizeof cccds[0]; i++) {
215 rc = ble_store_write_cccd(cccds + i);
216 TEST_ASSERT_FATAL(rc == 0);
217 }
218
219 /* Delete first peer. */
220 rc = ble_store_util_delete_peer(&secs[0].peer_addr);
221 TEST_ASSERT_FATAL(rc == 0);
222
223 /* Ensure all traces of first peer have been removed. */
224 ble_store_test_util_verify_peer_deleted(&secs[0].peer_addr);
225
226 /* Ensure second peer data is still intact. */
227 ble_store_key_from_value_sec(&key.sec, secs + 1);
228
229 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
230 TEST_ASSERT_FATAL(rc == 0);
231 TEST_ASSERT(count == 1);
232
233 rc = ble_store_read_our_sec(&key.sec, &value.sec);
234 TEST_ASSERT_FATAL(rc == 0);
235 TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0);
236
237 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
238 TEST_ASSERT_FATAL(rc == 0);
239 TEST_ASSERT(count == 1);
240
241 rc = ble_store_read_peer_sec(&key.sec, &value.sec);
242 TEST_ASSERT_FATAL(rc == 0);
243 TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0);
244
245 ble_store_key_from_value_cccd(&key.cccd, cccds + 2);
246
247 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
248 TEST_ASSERT_FATAL(rc == 0);
249 TEST_ASSERT(count == 1);
250
251 rc = ble_store_read_cccd(&key.cccd, &value.cccd);
252 TEST_ASSERT_FATAL(rc == 0);
253 TEST_ASSERT(memcmp(&value.cccd, cccds + 2, sizeof value.cccd) == 0);
254
255 /* Delete second peer. */
256 rc = ble_store_util_delete_peer(&secs[1].peer_addr);
257 TEST_ASSERT_FATAL(rc == 0);
258
259 /* Ensure all traces of first peer have been removed. */
260 ble_store_test_util_verify_peer_deleted(&secs[1].peer_addr);
261 }
262
TEST_CASE(ble_store_test_count)263 TEST_CASE(ble_store_test_count)
264 {
265 struct ble_store_value_sec secs[4] = {
266 {
267 .peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
268 .ltk_present = 1,
269 },
270 {
271 .peer_addr = { BLE_ADDR_RANDOM, { 1, 2, 3, 4, 5, 6 } },
272 .ltk_present = 1,
273 },
274 {
275 .peer_addr = { BLE_ADDR_PUBLIC, { 2, 3, 4, 5, 6, 7 } },
276 .ltk_present = 1,
277 },
278 {
279 .peer_addr = { BLE_ADDR_RANDOM, { 3, 4, 5, 6, 7, 8 } },
280 .ltk_present = 1,
281 },
282 };
283 struct ble_store_value_cccd cccds[2] = {
284 {
285 .peer_addr = secs[0].peer_addr,
286 .chr_val_handle = 5,
287 },
288 {
289 .peer_addr = secs[0].peer_addr,
290 .chr_val_handle = 8,
291 },
292 };
293 int count;
294 int rc;
295 int i;
296
297 ble_hs_test_util_init();
298
299 /*** Verify initial counts are 0. */
300
301 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
302 TEST_ASSERT_FATAL(rc == 0);
303 TEST_ASSERT(count == 0);
304
305 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
306 TEST_ASSERT_FATAL(rc == 0);
307 TEST_ASSERT(count == 0);
308
309 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
310 TEST_ASSERT_FATAL(rc == 0);
311 TEST_ASSERT(count == 0);
312
313 /* Write some test data. */
314
315 for (i = 0; i < 3; i++) {
316 rc = ble_store_write_our_sec(secs + i);
317 TEST_ASSERT_FATAL(rc == 0);
318 }
319 for (i = 0; i < 2; i++) {
320 rc = ble_store_write_peer_sec(secs + i);
321 TEST_ASSERT_FATAL(rc == 0);
322 }
323 for (i = 0; i < 1; i++) {
324 rc = ble_store_write_cccd(cccds + i);
325 TEST_ASSERT_FATAL(rc == 0);
326 }
327
328 /*** Verify counts after populating store. */
329 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
330 TEST_ASSERT_FATAL(rc == 0);
331 TEST_ASSERT(count == 3);
332
333 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
334 TEST_ASSERT_FATAL(rc == 0);
335 TEST_ASSERT(count == 2);
336
337 rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
338 TEST_ASSERT_FATAL(rc == 0);
339 TEST_ASSERT(count == 1);
340 }
341
TEST_CASE(ble_store_test_overflow)342 TEST_CASE(ble_store_test_overflow)
343 {
344 ble_store_test_util_overflow_sec(0);
345 ble_store_test_util_overflow_sec(1);
346 }
347
TEST_CASE(ble_store_test_clear)348 TEST_CASE(ble_store_test_clear)
349 {
350 const struct ble_store_value_sec secs[2] = {
351 {
352 .peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
353 .ltk_present = 1,
354 },
355 {
356 /* Address value is a duplicate of above, but type differs. */
357 .peer_addr = { BLE_ADDR_RANDOM, { 1, 2, 3, 4, 5, 6 } },
358 .ltk_present = 1,
359 },
360 };
361 const struct ble_store_value_cccd cccds[3] = {
362 /* First two belong to first peer. */
363 {
364 .peer_addr = secs[0].peer_addr,
365 .chr_val_handle = 5,
366 },
367 {
368 .peer_addr = secs[0].peer_addr,
369 .chr_val_handle = 8,
370 },
371
372 /* Last belongs to second peer. */
373 {
374 .peer_addr = secs[1].peer_addr,
375 .chr_val_handle = 5,
376 },
377 };
378 int rc;
379 int i;
380
381 ble_hs_test_util_init();
382
383 for (i = 0; i < sizeof secs / sizeof secs[0]; i++) {
384 rc = ble_store_write_our_sec(secs + i);
385 TEST_ASSERT_FATAL(rc == 0);
386 rc = ble_store_write_peer_sec(secs + i);
387 TEST_ASSERT_FATAL(rc == 0);
388 }
389
390 for (i = 0; i < sizeof cccds / sizeof cccds[0]; i++) {
391 rc = ble_store_write_cccd(cccds + i);
392 TEST_ASSERT_FATAL(rc == 0);
393 }
394
395 /* Sanity check. */
396 TEST_ASSERT_FATAL(
397 ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 2);
398 TEST_ASSERT_FATAL(
399 ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 2);
400 TEST_ASSERT_FATAL(
401 ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 3);
402
403 /* Ensure store is empty after clear gets called. */
404 rc = ble_store_clear();
405 TEST_ASSERT_FATAL(rc == 0);
406 TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0);
407 TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0);
408 TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0);
409
410 /* Ensure second clear succeeds with no effect. */
411 rc = ble_store_clear();
412 TEST_ASSERT_FATAL(rc == 0);
413 TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0);
414 TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0);
415 TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0);
416 }
417
TEST_SUITE(ble_store_suite)418 TEST_SUITE(ble_store_suite)
419 {
420 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
421
422 ble_store_test_peers();
423 ble_store_test_delete_peer();
424 ble_store_test_count();
425 ble_store_test_overflow();
426 ble_store_test_clear();
427 }
428
429 int
ble_store_test_all(void)430 ble_store_test_all(void)
431 {
432 ble_store_suite();
433
434 return tu_any_failed;
435 }
436