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