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