| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #include "testutil/testutil.h" |
| #include "ble_hs_test.h" |
| #include "ble_hs_test_util.h" |
| |
| static struct ble_store_status_event ble_store_test_status_event; |
| |
| static void |
| ble_store_test_util_verify_peer_deleted(const ble_addr_t *addr) |
| { |
| union ble_store_value value; |
| union ble_store_key key; |
| ble_addr_t addrs[64]; |
| int num_addrs; |
| int rc; |
| int i; |
| |
| memset(&key, 0, sizeof key); |
| key.sec.peer_addr = *addr; |
| rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, &key, &value); |
| TEST_ASSERT(rc == BLE_HS_ENOENT); |
| rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_SEC, &key, &value); |
| TEST_ASSERT(rc == BLE_HS_ENOENT); |
| |
| memset(&key, 0, sizeof key); |
| key.cccd.peer_addr = *addr; |
| rc = ble_store_read(BLE_STORE_OBJ_TYPE_CCCD, &key, &value); |
| TEST_ASSERT(rc == BLE_HS_ENOENT); |
| |
| rc = ble_store_util_bonded_peers(addrs, &num_addrs, |
| sizeof addrs / sizeof addrs[0]); |
| TEST_ASSERT_FATAL(rc == 0); |
| for (i = 0; i < num_addrs; i++) { |
| TEST_ASSERT(ble_addr_cmp(addr, addrs + i) != 0); |
| } |
| } |
| |
| static int |
| ble_store_test_util_status_overflow(struct ble_store_status_event *event, |
| void *arg) |
| { |
| int *status; |
| |
| status = arg; |
| |
| ble_store_test_status_event = *event; |
| return *status; |
| } |
| |
| static void |
| ble_store_test_util_overflow_sec(int is_our_sec) |
| { |
| union ble_store_value val; |
| int obj_type; |
| int status; |
| int rc; |
| int i; |
| |
| ble_hs_test_util_init(); |
| |
| ble_hs_cfg.store_status_cb = ble_store_test_util_status_overflow; |
| ble_hs_cfg.store_status_arg = &status; |
| |
| if (is_our_sec) { |
| obj_type = BLE_STORE_OBJ_TYPE_OUR_SEC; |
| } else { |
| obj_type = BLE_STORE_OBJ_TYPE_PEER_SEC; |
| } |
| |
| memset(&ble_store_test_status_event, 0, |
| sizeof ble_store_test_status_event); |
| memset(&val, 0, sizeof val); |
| |
| val.sec.peer_addr = |
| (ble_addr_t){ BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } }; |
| val.sec.ltk_present = 1, |
| |
| status = BLE_HS_ESTORE_CAP; |
| for (i = 0; ; i++) { |
| rc = ble_store_write(obj_type, &val); |
| if (i < MYNEWT_VAL(BLE_STORE_MAX_BONDS)) { |
| TEST_ASSERT_FATAL(rc == 0); |
| } else { |
| /* This record should have caused an overflow. */ |
| TEST_ASSERT(rc == BLE_HS_ESTORE_CAP); |
| TEST_ASSERT(ble_store_test_status_event.event_code == |
| BLE_STORE_EVENT_OVERFLOW); |
| TEST_ASSERT(ble_store_test_status_event.overflow.obj_type == |
| obj_type); |
| TEST_ASSERT(ble_store_test_status_event.overflow.value == &val); |
| break; |
| } |
| |
| val.sec.peer_addr.val[0]++; |
| } |
| } |
| |
| 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_SELF(ble_store_test_peers) |
| { |
| struct ble_store_value_sec secs[3] = { |
| { |
| .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, |
| }, |
| { |
| .peer_addr = { BLE_ADDR_PUBLIC, { 2, 3, 4, 5, 6, 7 } }, |
| .ltk_present = 1, |
| }, |
| }; |
| ble_addr_t peer_addrs[3]; |
| int num_addrs; |
| 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); |
| } |
| |
| rc = ble_store_util_bonded_peers(peer_addrs, &num_addrs, |
| sizeof peer_addrs / sizeof peer_addrs[0]); |
| TEST_ASSERT_FATAL(rc == 0); |
| |
| TEST_ASSERT(num_addrs == sizeof secs / sizeof secs[0]); |
| for (i = 0; i < num_addrs; i++) { |
| TEST_ASSERT(ble_addr_cmp(&peer_addrs[i], &secs[i].peer_addr) == 0); |
| } |
| |
| ble_hs_test_util_assert_mbufs_freed(NULL); |
| } |
| |
| TEST_CASE_SELF(ble_store_test_delete_peer) |
| { |
| 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, |
| }, |
| }; |
| 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, |
| }, |
| }; |
| union ble_store_value value; |
| union ble_store_key key; |
| int count; |
| 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); |
| } |
| |
| /* Delete first peer. */ |
| rc = ble_store_util_delete_peer(&secs[0].peer_addr); |
| TEST_ASSERT_FATAL(rc == 0); |
| |
| /* Ensure all traces of first peer have been removed. */ |
| ble_store_test_util_verify_peer_deleted(&secs[0].peer_addr); |
| |
| /* Ensure second peer data is still intact. */ |
| ble_store_key_from_value_sec(&key.sec, secs + 1); |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 1); |
| |
| rc = ble_store_read_our_sec(&key.sec, &value.sec); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0); |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 1); |
| |
| rc = ble_store_read_peer_sec(&key.sec, &value.sec); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0); |
| |
| ble_store_key_from_value_cccd(&key.cccd, cccds + 2); |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 1); |
| |
| rc = ble_store_read_cccd(&key.cccd, &value.cccd); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(memcmp(&value.cccd, cccds + 2, sizeof value.cccd) == 0); |
| |
| /* Delete second peer. */ |
| rc = ble_store_util_delete_peer(&secs[1].peer_addr); |
| TEST_ASSERT_FATAL(rc == 0); |
| |
| /* Ensure all traces of first peer have been removed. */ |
| ble_store_test_util_verify_peer_deleted(&secs[1].peer_addr); |
| |
| ble_hs_test_util_assert_mbufs_freed(NULL); |
| } |
| |
| TEST_CASE_SELF(ble_store_test_count) |
| { |
| struct ble_store_value_sec secs[4] = { |
| { |
| .peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } }, |
| .ltk_present = 1, |
| }, |
| { |
| .peer_addr = { BLE_ADDR_RANDOM, { 1, 2, 3, 4, 5, 6 } }, |
| .ltk_present = 1, |
| }, |
| { |
| .peer_addr = { BLE_ADDR_PUBLIC, { 2, 3, 4, 5, 6, 7 } }, |
| .ltk_present = 1, |
| }, |
| { |
| .peer_addr = { BLE_ADDR_RANDOM, { 3, 4, 5, 6, 7, 8 } }, |
| .ltk_present = 1, |
| }, |
| }; |
| struct ble_store_value_cccd cccds[2] = { |
| { |
| .peer_addr = secs[0].peer_addr, |
| .chr_val_handle = 5, |
| }, |
| { |
| .peer_addr = secs[0].peer_addr, |
| .chr_val_handle = 8, |
| }, |
| }; |
| int count; |
| int rc; |
| int i; |
| |
| ble_hs_test_util_init(); |
| |
| /*** Verify initial counts are 0. */ |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 0); |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 0); |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 0); |
| |
| /* Write some test data. */ |
| |
| for (i = 0; i < 3; i++) { |
| rc = ble_store_write_our_sec(secs + i); |
| TEST_ASSERT_FATAL(rc == 0); |
| } |
| for (i = 0; i < 2; i++) { |
| rc = ble_store_write_peer_sec(secs + i); |
| TEST_ASSERT_FATAL(rc == 0); |
| } |
| for (i = 0; i < 1; i++) { |
| rc = ble_store_write_cccd(cccds + i); |
| TEST_ASSERT_FATAL(rc == 0); |
| } |
| |
| /*** Verify counts after populating store. */ |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 3); |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 2); |
| |
| rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count); |
| TEST_ASSERT_FATAL(rc == 0); |
| TEST_ASSERT(count == 1); |
| |
| ble_hs_test_util_assert_mbufs_freed(NULL); |
| } |
| |
| TEST_CASE_SELF(ble_store_test_overflow) |
| { |
| ble_store_test_util_overflow_sec(0); |
| ble_store_test_util_overflow_sec(1); |
| |
| ble_hs_test_util_assert_mbufs_freed(NULL); |
| } |
| |
| TEST_CASE_SELF(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); |
| |
| ble_hs_test_util_assert_mbufs_freed(NULL); |
| } |
| |
| TEST_SUITE(ble_store_suite) |
| { |
| ble_store_test_peers(); |
| ble_store_test_delete_peer(); |
| ble_store_test_count(); |
| ble_store_test_overflow(); |
| ble_store_test_clear(); |
| } |