xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/test/src/ble_store_test.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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