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