1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "mocks/hci_core.h"
8 #include "mocks/hci_core_expects.h"
9 #include "mocks/net_buf.h"
10 #include "mocks/net_buf_expects.h"
11 #include "testing_common_defs.h"
12
13 #include <zephyr/bluetooth/hci.h>
14 #include <zephyr/fff.h>
15 #include <zephyr/kernel.h>
16
17 #include <host/hci_core.h>
18 #include <host/id.h>
19
20 DEFINE_FFF_GLOBALS;
21
22 /* Hold data representing HCI command response for command BT_HCI_OP_READ_BD_ADDR */
23 static struct net_buf hci_cmd_rsp;
24
25 /* Hold data representing response data for HCI command BT_HCI_OP_READ_BD_ADDR */
26 static struct bt_hci_rp_read_bd_addr hci_rp_read_bd_addr;
27
tc_setup(void * f)28 static void tc_setup(void *f)
29 {
30 memset(&bt_dev, 0x00, sizeof(struct bt_dev));
31 memset(&hci_cmd_rsp, 0x00, sizeof(struct net_buf));
32 memset(&hci_rp_read_bd_addr, 0x00, sizeof(struct bt_hci_rp_read_bd_addr));
33 NET_BUF_FFF_FAKES_LIST(RESET_FAKE);
34 HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
35 }
36
37 ZTEST_SUITE(bt_id_read_public_addr, NULL, NULL, tc_setup, NULL, NULL);
38
39 /*
40 * Test reading controller public address through bt_hci_cmd_send_sync(), but
41 * operation fails and a non-success error code is returned.
42 *
43 * Constraints:
44 * - A valid address reference is passed to bt_id_read_public_addr()
45 * - bt_hci_cmd_send_sync() returns a non-zero error code
46 *
47 * Expected behaviour:
48 * - Execution stops and a zero return value is returned which represents failure
49 */
ZTEST(bt_id_read_public_addr,test_bt_hci_cmd_send_sync_returns_err)50 ZTEST(bt_id_read_public_addr, test_bt_hci_cmd_send_sync_returns_err)
51 {
52 int err;
53 bt_addr_le_t addr;
54
55 bt_hci_cmd_send_sync_fake.return_val = 1;
56
57 err = bt_id_read_public_addr(&addr);
58
59 expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_READ_BD_ADDR);
60 expect_not_called_net_buf_unref();
61
62 zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
63 }
64
bt_hci_cmd_send_sync_custom_fake(uint16_t opcode,struct net_buf * buf,struct net_buf ** rsp)65 static int bt_hci_cmd_send_sync_custom_fake(uint16_t opcode, struct net_buf *buf,
66 struct net_buf **rsp)
67 {
68 const char *func_name = "bt_hci_cmd_send_sync";
69
70 zassert_equal(opcode, BT_HCI_OP_READ_BD_ADDR, "'%s()' was called with incorrect '%s' value",
71 func_name, "opcode");
72 zassert_is_null(buf, "'%s()' was called with incorrect '%s' value", func_name, "buf");
73 zassert_not_null(rsp, "'%s()' was called with incorrect '%s' value", func_name, "rsp");
74
75 *rsp = &hci_cmd_rsp;
76 hci_cmd_rsp.data = (void *)&hci_rp_read_bd_addr;
77
78 return 0;
79 }
80
81 /*
82 * Test reading controller public address through bt_hci_cmd_send_sync().
83 * Although, bt_hci_cmd_send_sync() return value is success but response data contains
84 * an invalid BT address
85 *
86 * Constraints:
87 * - A valid address reference is passed to bt_id_read_public_addr()
88 * - bt_hci_cmd_send_sync() returns zero
89 * - Response data contains invalid address
90 *
91 * Expected behaviour:
92 * - Execution stops and a zero return value is returned which represents failure
93 */
ZTEST(bt_id_read_public_addr,test_bt_hci_cmd_send_sync_response_has_invalid_bt_address)94 ZTEST(bt_id_read_public_addr, test_bt_hci_cmd_send_sync_response_has_invalid_bt_address)
95 {
96 int err;
97 bt_addr_le_t addr;
98 const bt_addr_t *invalid_bt_address[] = {BT_ADDR_ANY, BT_ADDR_NONE};
99 struct bt_hci_rp_read_bd_addr *rp = (void *)&hci_rp_read_bd_addr;
100
101 for (size_t i = 0; i < ARRAY_SIZE(invalid_bt_address); i++) {
102
103 memset(&bt_dev, 0x00, sizeof(struct bt_dev));
104 memset(&hci_cmd_rsp, 0x00, sizeof(struct net_buf));
105 memset(&hci_rp_read_bd_addr, 0x00, sizeof(struct bt_hci_rp_read_bd_addr));
106 NET_BUF_FFF_FAKES_LIST(RESET_FAKE);
107 HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
108
109 bt_addr_copy(&rp->bdaddr, invalid_bt_address[i]);
110 bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
111
112 err = bt_id_read_public_addr(&addr);
113
114 expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_READ_BD_ADDR);
115 expect_single_call_net_buf_unref(&hci_cmd_rsp);
116
117 zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
118 }
119 }
120
121 /*
122 * Test reading controller public address through bt_hci_cmd_send_sync().
123 * bt_hci_cmd_send_sync() return value is success and response data contains a valid BT address.
124 *
125 * Constraints:
126 * - A valid address reference is passed to bt_id_read_public_addr()
127 * - bt_hci_cmd_send_sync() returns zero
128 * - Response data contains a valid address
129 *
130 * Expected behaviour:
131 * - Return value is success
132 */
ZTEST(bt_id_read_public_addr,test_bt_hci_cmd_send_sync_response_has_valid_bt_address)133 ZTEST(bt_id_read_public_addr, test_bt_hci_cmd_send_sync_response_has_valid_bt_address)
134 {
135 int err;
136 bt_addr_le_t addr;
137 struct bt_hci_rp_read_bd_addr *rp = (void *)&hci_rp_read_bd_addr;
138
139 bt_addr_copy(&rp->bdaddr, &BT_LE_ADDR->a);
140 bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
141
142 err = bt_id_read_public_addr(&addr);
143
144 expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_READ_BD_ADDR);
145 expect_single_call_net_buf_unref(&hci_cmd_rsp);
146
147 zassert_true(err == 1, "Unexpected error code '%d' was returned", err);
148 zassert_mem_equal(&addr, BT_LE_ADDR, sizeof(bt_addr_le_t), "Incorrect address was set");
149 }
150