1 /*
2 * Copyright (c) 2021 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/kernel.h>
7 #include "mesh_test.h"
8 #include "mesh/net.h"
9 #include "mesh/mesh.h"
10 #include "mesh/foundation.h"
11
12 #define LOG_MODULE_NAME test_scanner
13
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
16
17 #define WAIT_TIME 60 /*seconds*/
18 #define ADV_INT_FAST_MS 20
19 #define ADV_DURATION 120
20
21 extern enum bst_result_t bst_result;
22
23 /* Create a valid message */
24 static const uint8_t valid_message[28] = {
25 0x0d, 0x10, 0xca, 0x54, 0xd0,
26 0x00, 0x24, 0x00, 0xaa, 0x8c,
27 0xcc, 0x6b, 0x6a, 0xc8, 0x51,
28 0x69, 0x16, 0x4d, 0xf6, 0x9b,
29 0xce, 0xbd, 0xc7, 0xa3, 0xf0,
30 0x28, 0xdf, 0xae
31 };
32
33 static const struct bt_mesh_test_cfg tx_cfg = {
34 .addr = 0x0001,
35 .dev_key = { 0x01 },
36 };
37 static const struct bt_mesh_test_cfg rx_cfg = {
38 .addr = 0x0002,
39 .dev_key = { 0x02 },
40 };
41
test_tx_init(void)42 static void test_tx_init(void)
43 {
44 bt_mesh_test_cfg_set(&tx_cfg, WAIT_TIME);
45 }
46
test_rx_init(void)47 static void test_rx_init(void)
48 {
49 bt_mesh_test_cfg_set(&rx_cfg, WAIT_TIME);
50 }
51
52 /* Setup the tx device by enabling Bluetooth, but no scanner is needed. */
test_tx_device_setup(void)53 static void test_tx_device_setup(void)
54 {
55 int err;
56
57 err = bt_enable(NULL);
58 if (err) {
59 FAIL("Bluetooth init failed (err %d)", err);
60 return;
61 }
62
63 LOG_INF("Bluetooth initialized");
64 }
65
66 /** Bypassing setting up transmission, and will try to send the raw data that is
67 * provided to the function.
68 */
test_tx_send_ad_type_msg(uint8_t type,const uint8_t * data,uint8_t len)69 static void test_tx_send_ad_type_msg(uint8_t type, const uint8_t *data, uint8_t len)
70 {
71 struct bt_le_adv_param param = {};
72 uint16_t duration, adv_int;
73 struct bt_data ad;
74 int err;
75
76 adv_int = ADV_INT_FAST_MS;
77 duration = ADV_DURATION;
78
79 ad.type = type;
80 ad.data_len = len;
81 ad.data = data;
82
83 param.id = BT_ID_DEFAULT;
84 param.interval_min = BT_MESH_ADV_SCAN_UNIT(adv_int);
85 param.interval_max = param.interval_min;
86
87 LOG_DBG("ad.type %u len %u", ad.type, ad.data_len);
88 LOG_HEXDUMP_DBG(ad.data, ad.data_len, "ad.data");
89
90 uint64_t st = k_uptime_get();
91
92 err = bt_le_adv_start(¶m, &ad, 1, NULL, 0);
93 if (err) {
94 FAIL("Advertising failed: err %d", err);
95 return;
96 }
97 LOG_DBG("Advertising started. Sleeping %u ms", duration);
98
99 k_sleep(K_MSEC(duration));
100 err = bt_le_adv_stop();
101 if (err) {
102 FAIL("Stopping advertising failed: err %d", err);
103 return;
104 }
105 LOG_DBG("Advertising stopped (%u ms)", (uint32_t) k_uptime_delta(&st));
106 }
107
108 /** Test sending message with not supported ad type for mesh.
109 *
110 * First message send message with an ad data type not supported by mesh, and
111 * verify that the receiver is disregarding message. Then send the same message
112 * with correct ad type to verify that the message is received.
113 */
test_tx_invalid_ad_type(void)114 static void test_tx_invalid_ad_type(void)
115 {
116 test_tx_device_setup();
117
118 LOG_DBG("TX Invalid AD Type");
119
120 k_sleep(K_SECONDS(1));
121
122 /* Send message with invalid ad type. */
123 test_tx_send_ad_type_msg(BT_DATA_BIG_INFO, valid_message,
124 ARRAY_SIZE(valid_message));
125
126 /* Wait for no message receive window to end. */
127 k_sleep(K_SECONDS(10));
128
129 /* Send message with valid ad type to verify message. */
130 test_tx_send_ad_type_msg(BT_DATA_MESH_MESSAGE, valid_message,
131 ARRAY_SIZE(valid_message));
132
133 PASS();
134 }
135
136 /** Test sending message with invalid/valid ad type and wrong packet length.
137 *
138 * Send messages with wrong packet length, and verify that the receiver is
139 * disregarding message. Then send the same message with correct packet length
140 * to verify that the message is received.
141 */
test_tx_wrong_packet_length(void)142 static void test_tx_wrong_packet_length(void)
143 {
144 test_tx_device_setup();
145
146 LOG_DBG("TX wrong packet length");
147
148 k_sleep(K_SECONDS(1));
149
150 /* Send message with to long data length. */
151 test_tx_send_ad_type_msg(BT_DATA_MESH_MESSAGE, valid_message,
152 ARRAY_SIZE(valid_message)+1);
153 /* Send message with to short data length. */
154 test_tx_send_ad_type_msg(BT_DATA_MESH_MESSAGE, valid_message,
155 ARRAY_SIZE(valid_message)-1);
156 /* Send message with invalid ad type and wrong data length. */
157 test_tx_send_ad_type_msg(BT_DATA_BIG_INFO, valid_message,
158 ARRAY_SIZE(valid_message)+1);
159
160 /* Wait for no message receive window to end. */
161 k_sleep(K_SECONDS(10));
162
163 /* Send message with valid ad type to verify message. */
164 test_tx_send_ad_type_msg(BT_DATA_MESH_MESSAGE, valid_message,
165 ARRAY_SIZE(valid_message));
166
167 PASS();
168 }
169
170 /** Test receiving message with invalid ad type or packet length for mesh. */
test_rx_invalid_packet(void)171 static void test_rx_invalid_packet(void)
172 {
173 struct bt_mesh_test_msg msg;
174 int err;
175
176 bt_mesh_test_setup();
177
178 LOG_DBG("RX Invalid packet");
179
180 /* Wait to check that no valid messages is received. */
181 err = bt_mesh_test_recv_msg(&msg, K_SECONDS(10));
182 if (!err) {
183 FAIL("Unexpected rx from 0x%04x", msg.ctx.addr);
184 }
185
186 /* Verify that test data is received correct. */
187 err = bt_mesh_test_recv(10, cfg->addr, NULL, K_SECONDS(10));
188 ASSERT_OK_MSG(err, "Failed receiving with valid ad_type");
189
190 PASS();
191 }
192
193 #define TEST_CASE(role, name, description) \
194 { \
195 .test_id = "scanner_" #role "_" #name, \
196 .test_descr = description, \
197 .test_post_init_f = test_##role##_init, \
198 .test_tick_f = bt_mesh_test_timeout, \
199 .test_main_f = test_##role##_##name, \
200 }
201
202 static const struct bst_test_instance test_scanner[] = {
203 TEST_CASE(tx, invalid_ad_type, "Scanner: Invalid AD Type"),
204 TEST_CASE(tx, wrong_packet_length, "Scanner: Wrong data length"),
205
206 TEST_CASE(rx, invalid_packet, "Scanner: Invalid packet"),
207 BSTEST_END_MARKER
208 };
209
test_scanner_install(struct bst_test_list * tests)210 struct bst_test_list *test_scanner_install(struct bst_test_list *tests)
211 {
212 tests = bst_add_tests(tests, test_scanner);
213 return tests;
214 }
215