blob: 77313336f2a4e22735c79edee67932e65cd7d20e [file] [log] [blame]
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mocks/hci_core.h"
#include "mocks/hci_core_expects.h"
#include "mocks/settings.h"
#include "mocks/settings_expects.h"
#include "mocks/smp.h"
#include "testing_common_defs.h"
#include <zephyr/bluetooth/hci.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <host/hci_core.h>
#include <host/id.h>
/* Hold data representing HCI command response for command BT_HCI_OP_READ_BD_ADDR */
static struct net_buf hci_cmd_rsp;
/* Hold data representing response data for HCI command BT_HCI_OP_READ_BD_ADDR */
static struct bt_hci_rp_read_bd_addr hci_rp_read_bd_addr;
static void tc_setup(void *f)
{
Z_TEST_SKIP_IFNDEF(CONFIG_BT_SETTINGS);
memset(&bt_dev, 0x00, sizeof(struct bt_dev));
memset(&hci_cmd_rsp, 0x00, sizeof(struct net_buf));
memset(&hci_rp_read_bd_addr, 0x00, sizeof(struct bt_hci_rp_read_bd_addr));
HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
SETTINGS_FFF_FAKES_LIST(RESET_FAKE);
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
SMP_FFF_FAKES_LIST(RESET_FAKE);
}
}
ZTEST_SUITE(bt_setup_public_id_addr_bt_settings_enabled, NULL, NULL, tc_setup, NULL, NULL);
/*
* Test reading controller public address fails and no attempt to store settings.
*
* Constraints:
* - bt_id_read_public_addr() returns zero
*
* Expected behaviour:
* - ID count is set to 0 and bt_setup_public_id_addr() returns 0
* - No expected calls to bt_settings_store_id()
*/
ZTEST(bt_setup_public_id_addr_bt_settings_enabled, test_bt_id_read_public_addr_returns_zero)
{
int err;
/* This will force bt_id_read_public_addr() to fail */
bt_hci_cmd_send_sync_fake.return_val = 1;
err = bt_setup_public_id_addr();
expect_not_called_bt_settings_store_id();
zassert_true(bt_dev.id_count == 0, "Incorrect value '%d' was set to bt_dev.id_count",
bt_dev.id_count);
zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
}
static int bt_hci_cmd_send_sync_custom_fake(uint16_t opcode, struct net_buf *buf,
struct net_buf **rsp)
{
const char *func_name = "bt_hci_cmd_send_sync";
zassert_equal(opcode, BT_HCI_OP_READ_BD_ADDR, "'%s()' was called with incorrect '%s' value",
func_name, "opcode");
zassert_is_null(buf, "'%s()' was called with incorrect '%s' value", func_name, "buf");
zassert_not_null(rsp, "'%s()' was called with incorrect '%s' value", func_name, "rsp");
*rsp = &hci_cmd_rsp;
hci_cmd_rsp.data = (void *)&hci_rp_read_bd_addr;
return 0;
}
/*
* Test reading controller public address through bt_hci_cmd_send_sync().
* Even if the operation succeeded, bt_settings_store_id() shouldn't be called to
* store settings as the 'BT_DEV_READY' bit isn't set.
*
* Constraints:
* - bt_hci_cmd_send_sync() returns zero
* - Response data contains a valid address
* - BT_DEV_READY bit isn't set in bt_dev.flags
*
* Expected behaviour:
* - Return value is 0
* - Public address is loaded to bt_dev.id_addr[]
* - No expected calls to bt_settings_save_id()
*/
ZTEST(bt_setup_public_id_addr_bt_settings_enabled,
test_bt_id_read_public_addr_succeeds_bt_dev_ready_cleared)
{
int err;
struct bt_hci_rp_read_bd_addr *rp = (void *)&hci_rp_read_bd_addr;
bt_addr_copy(&rp->bdaddr, BT_ADDR);
bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
atomic_clear_bit(bt_dev.flags, BT_DEV_READY);
err = bt_setup_public_id_addr();
expect_not_called_bt_settings_store_id();
zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
zassert_mem_equal(&bt_dev.id_addr[BT_ID_DEFAULT], BT_LE_ADDR, sizeof(bt_addr_le_t),
"Incorrect address was set");
zassert_true(bt_dev.id_count == 1, "Incorrect value '%d' was set to bt_dev.id_count",
bt_dev.id_count);
}
/*
* Test reading controller public address through bt_hci_cmd_send_sync(). With
* the 'BT_DEV_READY' bit set, bt_settings_store_id() should be called to store
* settings to persistent memory.
*
* Constraints:
* - bt_hci_cmd_send_sync() returns zero
* - Response data contains a valid address
* - BT_DEV_READY bit isn't set in bt_dev.flags
*
* Expected behaviour:
* - Return value is 0
* - Public address is loaded to bt_dev.id_addr[]
* - No expected calls to bt_settings_save_id()
*/
ZTEST(bt_setup_public_id_addr_bt_settings_enabled,
test_bt_id_read_public_addr_succeeds_bt_dev_ready_set)
{
int err;
struct bt_hci_rp_read_bd_addr *rp = (void *)&hci_rp_read_bd_addr;
bt_addr_copy(&rp->bdaddr, BT_ADDR);
bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
atomic_set_bit(bt_dev.flags, BT_DEV_READY);
err = bt_setup_public_id_addr();
expect_single_call_bt_settings_store_id();
zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
zassert_mem_equal(&bt_dev.id_addr[BT_ID_DEFAULT], BT_LE_ADDR, sizeof(bt_addr_le_t),
"Incorrect address was set");
zassert_true(bt_dev.id_count == 1, "Incorrect value '%d' was set to bt_dev.id_count",
bt_dev.id_count);
}
/*
* Test reading controller public address through bt_hci_cmd_send_sync().
* 'BT_DEV_STORE_ID' should be set when IRK isn't set.
*
* Constraints:
* - bt_hci_cmd_send_sync() returns zero
* - Response data contains a valid address
* - CONFIG_BT_PRIVACY is enabled
*
* Expected behaviour:
* - Return value is 0
* - 'BT_DEV_STORE_ID' bit is set inside bt_dev.flags
*/
ZTEST(bt_setup_public_id_addr_bt_settings_enabled, test_store_flag_set_correctly)
{
int err;
struct bt_hci_rp_read_bd_addr *rp = (void *)&hci_rp_read_bd_addr;
Z_TEST_SKIP_IFNDEF(CONFIG_BT_PRIVACY);
bt_addr_copy(&rp->bdaddr, BT_ADDR);
bt_smp_irk_get_fake.return_val = 1;
bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
err = bt_setup_public_id_addr();
zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
zassert_true(atomic_test_bit(bt_dev.flags, BT_DEV_STORE_ID),
"Flags were not correctly set");
}