diff --git a/nimble/host/include/host/ble_store.h b/nimble/host/include/host/ble_store.h index 5f9dea49c..cd815ade9 100644 --- a/nimble/host/include/host/ble_store.h +++ b/nimble/host/include/host/ble_store.h @@ -283,6 +283,8 @@ int ble_store_iterate(int obj_type, ble_store_iterator_fn *callback, void *cookie); +int ble_store_clear(void); + /*** Utility functions. */ int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, diff --git a/nimble/host/src/ble_store.c b/nimble/host/src/ble_store.c index 8e3923180..22e608947 100644 --- a/nimble/host/src/ble_store.c +++ b/nimble/host/src/ble_store.c @@ -381,3 +381,40 @@ ble_store_iterate(int obj_type, idx++; } } + +/** + * Deletes all objects from the BLE host store. + * + * @return 0 on success; nonzero on failure. + */ +int +ble_store_clear(void) +{ + const uint8_t obj_types[] = { + BLE_STORE_OBJ_TYPE_OUR_SEC, + BLE_STORE_OBJ_TYPE_PEER_SEC, + BLE_STORE_OBJ_TYPE_CCCD, + }; + union ble_store_key key; + int obj_type; + int rc; + int i; + + /* A zeroed key will always retrieve the first value. */ + memset(&key, 0, sizeof key); + + for (i = 0; i < sizeof obj_types / sizeof obj_types[0]; i++) { + obj_type = obj_types[i]; + + do { + rc = ble_store_delete(obj_type, &key); + } while (rc == 0); + + /* BLE_HS_ENOENT means we deleted everything. */ + if (rc != BLE_HS_ENOENT) { + return rc; + } + } + + return 0; +} diff --git a/nimble/host/test/src/ble_store_test.c b/nimble/host/test/src/ble_store_test.c index 6665900ce..e3abaa774 100644 --- a/nimble/host/test/src/ble_store_test.c +++ b/nimble/host/test/src/ble_store_test.c @@ -113,6 +113,18 @@ ble_store_test_util_overflow_sec(int is_our_sec) } } +static int +ble_store_test_util_count(int obj_type) +{ + int count; + int rc; + + rc = ble_store_util_count(obj_type, &count); + TEST_ASSERT_FATAL(rc == 0); + + return count; +} + TEST_CASE(ble_store_test_peers) { struct ble_store_value_sec secs[3] = { @@ -333,6 +345,76 @@ TEST_CASE(ble_store_test_overflow) ble_store_test_util_overflow_sec(1); } +TEST_CASE(ble_store_test_clear) +{ + const struct ble_store_value_sec secs[2] = { + { + .peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } }, + .ltk_present = 1, + }, + { + /* Address value is a duplicate of above, but type differs. */ + .peer_addr = { BLE_ADDR_RANDOM, { 1, 2, 3, 4, 5, 6 } }, + .ltk_present = 1, + }, + }; + const struct ble_store_value_cccd cccds[3] = { + /* First two belong to first peer. */ + { + .peer_addr = secs[0].peer_addr, + .chr_val_handle = 5, + }, + { + .peer_addr = secs[0].peer_addr, + .chr_val_handle = 8, + }, + + /* Last belongs to second peer. */ + { + .peer_addr = secs[1].peer_addr, + .chr_val_handle = 5, + }, + }; + int rc; + int i; + + ble_hs_test_util_init(); + + for (i = 0; i < sizeof secs / sizeof secs[0]; i++) { + rc = ble_store_write_our_sec(secs + i); + TEST_ASSERT_FATAL(rc == 0); + rc = ble_store_write_peer_sec(secs + i); + TEST_ASSERT_FATAL(rc == 0); + } + + for (i = 0; i < sizeof cccds / sizeof cccds[0]; i++) { + rc = ble_store_write_cccd(cccds + i); + TEST_ASSERT_FATAL(rc == 0); + } + + /* Sanity check. */ + TEST_ASSERT_FATAL( + ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 2); + TEST_ASSERT_FATAL( + ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 2); + TEST_ASSERT_FATAL( + ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 3); + + /* Ensure store is empty after clear gets called. */ + rc = ble_store_clear(); + TEST_ASSERT_FATAL(rc == 0); + TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0); + TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0); + TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0); + + /* Ensure second clear succeeds with no effect. */ + rc = ble_store_clear(); + TEST_ASSERT_FATAL(rc == 0); + TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0); + TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0); + TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0); +} + TEST_SUITE(ble_store_suite) { tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL); @@ -341,6 +423,7 @@ TEST_SUITE(ble_store_suite) ble_store_test_delete_peer(); ble_store_test_count(); ble_store_test_overflow(); + ble_store_test_clear(); } int