1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "mocks/conn.h"
8 #include "mocks/hci_core.h"
9 #include "mocks/net_buf.h"
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/bluetooth/cs.h>
13 #include <zephyr/fff.h>
14 
15 DEFINE_FFF_GLOBALS;
16 
17 FAKE_VALUE_FUNC(bool, bt_le_cs_step_data_parse_func, struct bt_le_cs_subevent_step *, void *);
18 
fff_reset_rule_before(const struct ztest_unit_test * test,void * fixture)19 static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
20 {
21 	RESET_FAKE(bt_le_cs_step_data_parse_func);
22 	CONN_FFF_FAKES_LIST(RESET_FAKE);
23 }
24 
25 ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
26 
27 ZTEST_SUITE(bt_le_cs_step_data_parse, NULL, NULL, NULL, NULL, NULL);
28 
29 /*
30  *  Test empty data buffer
31  *
32  *  Constraints:
33  *   - buffer len set to 0
34  *
35  *  Expected behaviour:
36  *   - Callback function is not called
37  */
ZTEST(bt_le_cs_step_data_parse,test_parsing_empty_buf)38 ZTEST(bt_le_cs_step_data_parse, test_parsing_empty_buf)
39 {
40 	struct net_buf_simple *buf = NET_BUF_SIMPLE(0);
41 
42 	bt_le_cs_step_data_parse(buf, bt_le_cs_step_data_parse_func, NULL);
43 
44 	zassert_equal(bt_le_cs_step_data_parse_func_fake.call_count, 0);
45 }
46 
47 /*
48  *  Test malformed step data
49  *
50  *  Constraints:
51  *   - step data with a step length going out of bounds
52  *
53  *  Expected behaviour:
54  *   - Callback function is called once
55  */
ZTEST(bt_le_cs_step_data_parse,test_parsing_invalid_length)56 ZTEST(bt_le_cs_step_data_parse, test_parsing_invalid_length)
57 {
58 	struct net_buf_simple buf;
59 	uint8_t data[] = {
60 		0x00, 0x01, 0x01, 0x00,       /* mode 0 */
61 		0x03, 0x20, 0x03, 0x00, 0x11, /* mode 3 step with bad length */
62 	};
63 
64 	bt_le_cs_step_data_parse_func_fake.return_val = true;
65 
66 	net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data));
67 
68 	bt_le_cs_step_data_parse(&buf, bt_le_cs_step_data_parse_func, NULL);
69 
70 	zassert_equal(1, bt_le_cs_step_data_parse_func_fake.call_count, "called %d",
71 		      bt_le_cs_step_data_parse_func_fake.call_count);
72 }
73 
74 /*
75  *  Test parsing stopped
76  *
77  *  Constraints:
78  *   - Data contains valid step data
79  *   - Callback function returns false to stop parsing
80  *
81  *  Expected behaviour:
82  *   - Once parsing is stopped, the callback is not called anymore
83  */
ZTEST(bt_le_cs_step_data_parse,test_parsing_stopped)84 ZTEST(bt_le_cs_step_data_parse, test_parsing_stopped)
85 {
86 	struct net_buf_simple buf;
87 	uint8_t data[] = {
88 		0x00, 0x05, 0x01, 0x00,       /* mode 0 */
89 		0x01, 0x10, 0x02, 0x00, 0x11, /* mode 1 */
90 		0x02, 0x11, 0x02, 0x00, 0x11, /* mode 2 */
91 	};
92 
93 	bt_le_cs_step_data_parse_func_fake.return_val = false;
94 
95 	net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data));
96 
97 	bt_le_cs_step_data_parse(&buf, bt_le_cs_step_data_parse_func, NULL);
98 
99 	zassert_equal(1, bt_le_cs_step_data_parse_func_fake.call_count, "called %d",
100 		      bt_le_cs_step_data_parse_func_fake.call_count);
101 }
102 
103 struct custom_user_data {
104 	const uint8_t *data;
105 	size_t len;
106 };
107 
bt_le_cs_step_data_parse_func_custom_fake(struct bt_le_cs_subevent_step * step,void * user_data)108 static bool bt_le_cs_step_data_parse_func_custom_fake(struct bt_le_cs_subevent_step *step,
109 						      void *user_data)
110 {
111 	struct custom_user_data *ud = user_data;
112 
113 	/* mode check */
114 	zassert_true(ud->len-- > 0);
115 	zassert_equal(step->mode, *ud->data);
116 	ud->data++;
117 
118 	/* channel check */
119 	zassert_true(ud->len-- > 0);
120 	zassert_equal(step->channel, *ud->data);
121 	ud->data++;
122 
123 	/* step data length check */
124 	zassert_true(ud->len-- > 0);
125 	zassert_equal(step->data_len, *ud->data);
126 	ud->data++;
127 
128 	/* value check */
129 	zassert_true(ud->len >= step->data_len);
130 	zassert_mem_equal(step->data, ud->data, step->data_len);
131 	ud->data += step->data_len;
132 	ud->len -= step->data_len;
133 
134 	return true;
135 }
136 
137 /*
138  *  Test parsing successfully
139  *
140  *  Constraints:
141  *   - Data contains valid step data
142  *   - Callback function returns false to stop parsing
143  *
144  *  Expected behaviour:
145  *   - Data passed to the callback match the expected data
146  */
ZTEST(bt_le_cs_step_data_parse,test_parsing_success)147 ZTEST(bt_le_cs_step_data_parse, test_parsing_success)
148 {
149 	struct net_buf_simple buf;
150 	uint8_t data[] = {
151 		0x00, 0x05, 0x01, 0x00,       /* mode 0 */
152 		0x03, 0x11, 0x01, 0x11,       /* mode 3 */
153 		0x02, 0x12, 0x02, 0x00, 0x11, /* mode 2 */
154 		0x03, 0x13, 0x01, 0x11,       /* mode 3 */
155 		0x02, 0x14, 0x02, 0x00, 0x11, /* mode 2 */
156 	};
157 
158 	struct custom_user_data user_data = {
159 		.data = data,
160 		.len = ARRAY_SIZE(data),
161 	};
162 
163 	bt_le_cs_step_data_parse_func_fake.custom_fake = bt_le_cs_step_data_parse_func_custom_fake;
164 
165 	net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data));
166 
167 	bt_le_cs_step_data_parse(&buf, bt_le_cs_step_data_parse_func, &user_data);
168 
169 	zassert_equal(5, bt_le_cs_step_data_parse_func_fake.call_count, "called %d",
170 		      bt_le_cs_step_data_parse_func_fake.call_count);
171 }
172