1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "mesh_test.h"
7 #include "argparse.h"
8 #include <bs_pc_backchannel.h>
9 #include "mesh/crypto.h"
10 
11 #define LOG_MODULE_NAME mesh_test
12 
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
15 
16 #include "common/bt_str.h"
17 
18 /* Max number of messages that can be pending on RX at the same time */
19 #define RECV_QUEUE_SIZE 32
20 
21 const struct bt_mesh_test_cfg *cfg;
22 
23 K_MEM_SLAB_DEFINE_STATIC(msg_pool, sizeof(struct bt_mesh_test_msg),
24 			 RECV_QUEUE_SIZE, 4);
25 static K_QUEUE_DEFINE(recv);
26 struct bt_mesh_test_stats test_stats;
27 struct bt_mesh_msg_ctx test_send_ctx;
28 static void (*ra_cb)(uint8_t *, size_t);
29 
msg_rx(struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)30 static int msg_rx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
31 		   struct net_buf_simple *buf)
32 {
33 	size_t len = buf->len + BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1);
34 	static uint8_t prev_seq;
35 	struct bt_mesh_test_msg *msg;
36 	uint8_t seq = 0;
37 
38 	if (buf->len) {
39 		seq = net_buf_simple_pull_u8(buf);
40 		if (prev_seq == seq) {
41 			FAIL("Received same message twice");
42 			return -EINVAL;
43 		}
44 
45 		prev_seq = seq;
46 	}
47 
48 	LOG_INF("Received packet 0x%02x:", seq);
49 	LOG_INF("\tlen: %d bytes", len);
50 	LOG_INF("\tsrc: 0x%04x", ctx->addr);
51 	LOG_INF("\tdst: 0x%04x", ctx->recv_dst);
52 	LOG_INF("\tttl: %u", ctx->recv_ttl);
53 	LOG_INF("\trssi: %d", ctx->recv_rssi);
54 
55 	for (int i = 1; buf->len; i++) {
56 		if (net_buf_simple_pull_u8(buf) != (i & 0xff)) {
57 			FAIL("Invalid message content (byte %u)", i);
58 			return -EINVAL;
59 		}
60 	}
61 
62 	test_stats.received++;
63 
64 	if (k_mem_slab_alloc(&msg_pool, (void **)&msg, K_NO_WAIT)) {
65 		test_stats.recv_overflow++;
66 		return -EOVERFLOW;
67 	}
68 
69 	msg->len = len;
70 	msg->seq = seq;
71 	msg->ctx = *ctx;
72 
73 	k_queue_append(&recv, msg);
74 
75 	return 0;
76 }
77 
ra_rx(struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)78 static int ra_rx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
79 		 struct net_buf_simple *buf)
80 {
81 	LOG_INF("\tlen: %d bytes", buf->len);
82 	LOG_INF("\tsrc: 0x%04x", ctx->addr);
83 	LOG_INF("\tdst: 0x%04x", ctx->recv_dst);
84 	LOG_INF("\tttl: %u", ctx->recv_ttl);
85 	LOG_INF("\trssi: %d", ctx->recv_rssi);
86 
87 	if (ra_cb) {
88 		ra_cb(net_buf_simple_pull_mem(buf, buf->len), buf->len);
89 	}
90 
91 	return 0;
92 }
93 
94 static const struct bt_mesh_model_op model_op[] = {
95 	{ TEST_MSG_OP_1, 0, msg_rx },
96 	{ TEST_MSG_OP_2, 0, ra_rx },
97 	BT_MESH_MODEL_OP_END
98 };
99 
test_model_pub_update(struct bt_mesh_model * mod)100 int __weak test_model_pub_update(struct bt_mesh_model *mod)
101 {
102 	return -1;
103 }
104 
test_model_settings_set(struct bt_mesh_model * model,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)105 int __weak test_model_settings_set(struct bt_mesh_model *model,
106 				   const char *name, size_t len_rd,
107 				   settings_read_cb read_cb, void *cb_arg)
108 {
109 	return -1;
110 }
111 
test_model_reset(struct bt_mesh_model * model)112 void __weak test_model_reset(struct bt_mesh_model *model)
113 {
114 	/* No-op. */
115 }
116 
117 static const struct bt_mesh_model_cb test_model_cb = {
118 	.settings_set = test_model_settings_set,
119 	.reset = test_model_reset,
120 };
121 
122 static struct bt_mesh_model_pub pub = {
123 	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
124 	.update = test_model_pub_update,
125 };
126 
127 static const struct bt_mesh_model_op vnd_model_op[] = {
128 	BT_MESH_MODEL_OP_END,
129 };
130 
test_vnd_model_pub_update(struct bt_mesh_model * mod)131 int __weak test_vnd_model_pub_update(struct bt_mesh_model *mod)
132 {
133 	return -1;
134 }
135 
test_vnd_model_settings_set(struct bt_mesh_model * model,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)136 int __weak test_vnd_model_settings_set(struct bt_mesh_model *model,
137 				       const char *name, size_t len_rd,
138 				       settings_read_cb read_cb, void *cb_arg)
139 {
140 	return -1;
141 }
142 
test_vnd_model_reset(struct bt_mesh_model * model)143 void __weak test_vnd_model_reset(struct bt_mesh_model *model)
144 {
145 	/* No-op. */
146 }
147 
148 static const struct bt_mesh_model_cb test_vnd_model_cb = {
149 	.settings_set = test_vnd_model_settings_set,
150 	.reset = test_vnd_model_reset,
151 };
152 
153 static struct bt_mesh_model_pub vnd_pub = {
154 	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
155 	.update = test_vnd_model_pub_update,
156 };
157 
158 static struct bt_mesh_cfg_cli cfg_cli;
159 
160 static struct bt_mesh_health_srv health_srv;
161 static struct bt_mesh_model_pub health_pub = {
162 	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
163 };
164 
165 #if defined(CONFIG_BT_MESH_SAR_CFG)
166 static struct bt_mesh_sar_cfg_cli sar_cfg_cli;
167 #endif
168 
169 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
170 static struct bt_mesh_priv_beacon_cli priv_beacon_cli;
171 #endif
172 
173 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
174 static struct bt_mesh_od_priv_proxy_cli priv_proxy_cli;
175 #endif
176 
177 static struct bt_mesh_model models[] = {
178 	BT_MESH_MODEL_CFG_SRV,
179 	BT_MESH_MODEL_CFG_CLI(&cfg_cli),
180 	BT_MESH_MODEL_CB(TEST_MOD_ID, model_op, &pub, NULL, &test_model_cb),
181 	BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
182 #if defined(CONFIG_BT_MESH_SAR_CFG)
183 	BT_MESH_MODEL_SAR_CFG_SRV,
184 	BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli),
185 #endif
186 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
187 	BT_MESH_MODEL_PRIV_BEACON_SRV,
188 	BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli),
189 #endif
190 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
191 	BT_MESH_MODEL_OD_PRIV_PROXY_SRV,
192 #endif
193 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
194 	BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&priv_proxy_cli),
195 #endif
196 };
197 
198 struct bt_mesh_model *test_model = &models[2];
199 
200 static struct bt_mesh_model vnd_models[] = {
201 	BT_MESH_MODEL_VND_CB(TEST_VND_COMPANY_ID, TEST_VND_MOD_ID, vnd_model_op, &vnd_pub,
202 			     NULL, &test_vnd_model_cb),
203 };
204 
205 struct bt_mesh_model *test_vnd_model = &vnd_models[0];
206 
207 static struct bt_mesh_elem elems[] = {
208 	BT_MESH_ELEM(0, models, vnd_models),
209 };
210 
211 const struct bt_mesh_comp comp = {
212 	.elem = elems,
213 	.elem_count = ARRAY_SIZE(elems),
214 };
215 
216 const uint8_t test_net_key[16] = { 1, 2, 3 };
217 const uint8_t test_app_key[16] = { 4, 5, 6 };
218 const uint8_t test_va_uuid[16] = "Mesh Label UUID";
219 
bt_mesh_device_provision_and_configure(void)220 static void bt_mesh_device_provision_and_configure(void)
221 {
222 	uint8_t status;
223 	int err;
224 
225 	err = bt_mesh_provision(test_net_key, 0, 0, 0, cfg->addr, cfg->dev_key);
226 	if (err == -EALREADY) {
227 		LOG_INF("Using stored settings");
228 		return;
229 	} else if (err) {
230 		FAIL("Provisioning failed (err %d)", err);
231 		return;
232 	}
233 
234 	/* Self configure */
235 
236 	err = bt_mesh_cfg_cli_app_key_add(0, cfg->addr, 0, 0, test_app_key, &status);
237 	if (err || status) {
238 		FAIL("AppKey add failed (err %d, status %u)", err, status);
239 		return;
240 	}
241 
242 	err = bt_mesh_cfg_cli_mod_app_bind(0, cfg->addr, cfg->addr, 0, TEST_MOD_ID, &status);
243 	if (err || status) {
244 		FAIL("Mod app bind failed (err %d, status %u)", err, status);
245 		return;
246 	}
247 
248 	err = bt_mesh_cfg_cli_net_transmit_set(0, cfg->addr, BT_MESH_TRANSMIT(2, 20), &status);
249 	if (err || status != BT_MESH_TRANSMIT(2, 20)) {
250 		FAIL("Net transmit set failed (err %d, status %u)", err,
251 		     status);
252 		return;
253 	}
254 }
255 
bt_mesh_device_setup(const struct bt_mesh_prov * prov,const struct bt_mesh_comp * comp)256 void bt_mesh_device_setup(const struct bt_mesh_prov *prov, const struct bt_mesh_comp *comp)
257 {
258 	int err;
259 
260 	err = bt_enable(NULL);
261 	if (err) {
262 		FAIL("Bluetooth init failed (err %d)", err);
263 		return;
264 	}
265 
266 	LOG_INF("Bluetooth initialized");
267 
268 	err = bt_mesh_init(prov, comp);
269 	if (err) {
270 		FAIL("Initializing mesh failed (err %d)", err);
271 		return;
272 	}
273 
274 	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
275 		LOG_INF("Loading stored settings");
276 		if (IS_ENABLED(CONFIG_BT_MESH_USES_MBEDTLS_PSA)) {
277 			settings_load_subtree("itsemul");
278 		}
279 		settings_load_subtree("bt");
280 	}
281 
282 	LOG_INF("Mesh initialized");
283 }
284 
bt_mesh_test_setup(void)285 void bt_mesh_test_setup(void)
286 {
287 	static struct bt_mesh_prov prov;
288 
289 	net_buf_simple_init(pub.msg, 0);
290 	net_buf_simple_init(vnd_pub.msg, 0);
291 
292 	bt_mesh_device_setup(&prov, &comp);
293 	bt_mesh_device_provision_and_configure();
294 }
295 
bt_mesh_test_timeout(bs_time_t HW_device_time)296 void bt_mesh_test_timeout(bs_time_t HW_device_time)
297 {
298 	if (bst_result != Passed) {
299 		FAIL("Test timeout (not passed after %i seconds)",
300 		     HW_device_time / USEC_PER_SEC);
301 	}
302 
303 	bs_trace_silent_exit(0);
304 }
305 
bt_mesh_test_cfg_set(const struct bt_mesh_test_cfg * my_cfg,int wait_time)306 void bt_mesh_test_cfg_set(const struct bt_mesh_test_cfg *my_cfg, int wait_time)
307 {
308 	bst_ticker_set_next_tick_absolute(wait_time * USEC_PER_SEC);
309 	bst_result = In_progress;
310 	cfg = my_cfg;
311 
312 	/* Ensure those test devices will not drift more than
313 	 * 100ms for each other in emulated time
314 	 */
315 	tm_set_phy_max_resync_offset(100000);
316 }
317 
blocking_recv(k_timeout_t timeout)318 static struct bt_mesh_test_msg *blocking_recv(k_timeout_t timeout)
319 {
320 	if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
321 		return 0;
322 	}
323 
324 	return k_queue_get(&recv, timeout);
325 }
326 
bt_mesh_test_recv(uint16_t len,uint16_t dst,const uint8_t * uuid,k_timeout_t timeout)327 int bt_mesh_test_recv(uint16_t len, uint16_t dst, const uint8_t *uuid, k_timeout_t timeout)
328 {
329 	struct bt_mesh_test_msg *msg = blocking_recv(timeout);
330 
331 	if (!msg) {
332 		return -ETIMEDOUT;
333 	}
334 
335 	if (len != msg->len) {
336 		LOG_ERR("Recv: Invalid message length (%u, expected %u)", msg->len, len);
337 		return -EINVAL;
338 	}
339 
340 	if (dst != BT_MESH_ADDR_UNASSIGNED && dst != msg->ctx.recv_dst) {
341 		LOG_ERR("Recv: Invalid dst 0x%04x, expected 0x%04x", msg->ctx.recv_dst, dst);
342 		return -EINVAL;
343 	}
344 
345 	if (BT_MESH_ADDR_IS_VIRTUAL(msg->ctx.recv_dst) &&
346 	    ((uuid != NULL && msg->ctx.uuid == NULL) ||
347 	     (uuid == NULL && msg->ctx.uuid != NULL) ||
348 	     memcmp(uuid, msg->ctx.uuid, 16))) {
349 		LOG_ERR("Recv: Label UUID mismatch for virtual address 0x%04x");
350 		if (uuid && msg->ctx.uuid) {
351 			LOG_ERR("Got: %s", bt_hex(msg->ctx.uuid, 16));
352 			LOG_ERR("Expected: %s", bt_hex(uuid, 16));
353 		}
354 
355 		return -EINVAL;
356 	}
357 
358 	k_mem_slab_free(&msg_pool, (void *)msg);
359 
360 	return 0;
361 }
362 
bt_mesh_test_recv_msg(struct bt_mesh_test_msg * msg,k_timeout_t timeout)363 int bt_mesh_test_recv_msg(struct bt_mesh_test_msg *msg, k_timeout_t timeout)
364 {
365 	struct bt_mesh_test_msg *queued = blocking_recv(timeout);
366 
367 	if (!queued) {
368 		return -ETIMEDOUT;
369 	}
370 
371 	*msg = *queued;
372 
373 	k_mem_slab_free(&msg_pool, (void *)queued);
374 
375 	return 0;
376 }
377 
bt_mesh_test_recv_clear(void)378 int bt_mesh_test_recv_clear(void)
379 {
380 	struct bt_mesh_test_msg *queued;
381 	int count = 0;
382 
383 	while ((queued = k_queue_get(&recv, K_NO_WAIT))) {
384 		k_mem_slab_free(&msg_pool, (void *)queued);
385 		count++;
386 	}
387 
388 	return count;
389 }
390 
391 struct sync_send_ctx {
392 	struct k_sem sem;
393 	int err;
394 };
395 
tx_started(uint16_t dur,int err,void * data)396 static void tx_started(uint16_t dur, int err, void *data)
397 {
398 	struct sync_send_ctx *send_ctx = data;
399 
400 	if (err) {
401 		LOG_ERR("Couldn't start sending (err: %d)", err);
402 
403 		send_ctx->err = err;
404 		k_sem_give(&send_ctx->sem);
405 
406 		return;
407 	}
408 
409 	LOG_INF("Sending started");
410 }
411 
tx_ended(int err,void * data)412 static void tx_ended(int err, void *data)
413 {
414 	struct sync_send_ctx *send_ctx = data;
415 
416 	send_ctx->err = err;
417 
418 	if (err) {
419 		LOG_ERR("Send failed (%d)", err);
420 	} else {
421 		LOG_INF("Sending ended");
422 	}
423 
424 	k_sem_give(&send_ctx->sem);
425 }
426 
bt_mesh_test_send_async(uint16_t addr,const uint8_t * uuid,size_t len,enum bt_mesh_test_send_flags flags,const struct bt_mesh_send_cb * send_cb,void * cb_data)427 int bt_mesh_test_send_async(uint16_t addr, const uint8_t *uuid, size_t len,
428 			    enum bt_mesh_test_send_flags flags,
429 			    const struct bt_mesh_send_cb *send_cb,
430 			    void *cb_data)
431 {
432 	const size_t mic_len =
433 		(flags & LONG_MIC) ? BT_MESH_MIC_LONG : BT_MESH_MIC_SHORT;
434 	static uint8_t count = 1;
435 	int err;
436 
437 	test_send_ctx.addr = addr;
438 	test_send_ctx.send_rel = (flags & FORCE_SEGMENTATION);
439 	test_send_ctx.send_ttl = BT_MESH_TTL_DEFAULT;
440 	test_send_ctx.uuid = uuid;
441 
442 	BT_MESH_MODEL_BUF_DEFINE(buf, TEST_MSG_OP_1, BT_MESH_TX_SDU_MAX);
443 	bt_mesh_model_msg_init(&buf, TEST_MSG_OP_1);
444 
445 	if (len > BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1)) {
446 		net_buf_simple_add_u8(&buf, count);
447 	}
448 
449 	/* Subtract the length of the opcode and the sequence ID */
450 	for (int i = 1; i < len - BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1); i++) {
451 		net_buf_simple_add_u8(&buf, i);
452 	}
453 
454 	if (net_buf_simple_tailroom(&buf) < mic_len) {
455 		LOG_ERR("No room for MIC of len %u in %u byte buffer", mic_len,
456 			buf.len);
457 		return -EINVAL;
458 	}
459 
460 	/* Seal the buffer to prevent accidentally long MICs: */
461 	buf.size = buf.len + mic_len;
462 
463 	LOG_INF("Sending packet 0x%02x: %u %s to 0x%04x force seg: %u...",
464 		count, buf.len, (buf.len == 1 ? "byte" : "bytes"), addr,
465 		(flags & FORCE_SEGMENTATION));
466 
467 	err = bt_mesh_model_send(test_model, &test_send_ctx, &buf, send_cb,
468 				 cb_data);
469 	if (err) {
470 		LOG_ERR("bt_mesh_model_send failed (err: %d)", err);
471 		return err;
472 	}
473 
474 	count++;
475 	test_stats.sent++;
476 	return 0;
477 }
478 
bt_mesh_test_send(uint16_t addr,const uint8_t * uuid,size_t len,enum bt_mesh_test_send_flags flags,k_timeout_t timeout)479 int bt_mesh_test_send(uint16_t addr, const uint8_t *uuid, size_t len,
480 		      enum bt_mesh_test_send_flags flags, k_timeout_t timeout)
481 {
482 	if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
483 		return bt_mesh_test_send_async(addr, uuid, len, flags, NULL, NULL);
484 	}
485 
486 	static const struct bt_mesh_send_cb send_cb = {
487 		.start = tx_started,
488 		.end = tx_ended,
489 	};
490 	int64_t uptime = k_uptime_get();
491 	struct sync_send_ctx send_ctx;
492 	int err;
493 
494 	k_sem_init(&send_ctx.sem, 0, 1);
495 	err = bt_mesh_test_send_async(addr, uuid, len, flags, &send_cb, &send_ctx);
496 	if (err) {
497 		return err;
498 	}
499 
500 	err = k_sem_take(&send_ctx.sem, timeout);
501 	if (err) {
502 		LOG_ERR("Send timed out");
503 		return err;
504 	}
505 
506 	if (send_ctx.err) {
507 		return send_ctx.err;
508 	}
509 
510 	LOG_INF("Sending completed (%lld ms)", k_uptime_delta(&uptime));
511 
512 	return 0;
513 }
514 
bt_mesh_test_send_ra(uint16_t addr,uint8_t * data,size_t len,const struct bt_mesh_send_cb * send_cb,void * cb_data)515 int bt_mesh_test_send_ra(uint16_t addr, uint8_t *data, size_t len,
516 			 const struct bt_mesh_send_cb *send_cb,
517 			 void *cb_data)
518 {
519 	int err;
520 
521 	test_send_ctx.addr = addr;
522 	test_send_ctx.send_rel = 0;
523 	test_send_ctx.send_ttl = BT_MESH_TTL_DEFAULT;
524 
525 	BT_MESH_MODEL_BUF_DEFINE(buf, TEST_MSG_OP_2, BT_MESH_TX_SDU_MAX);
526 	bt_mesh_model_msg_init(&buf, TEST_MSG_OP_2);
527 
528 	net_buf_simple_add_mem(&buf, data, len);
529 
530 	err = bt_mesh_model_send(test_model, &test_send_ctx, &buf, send_cb, cb_data);
531 	if (err) {
532 		LOG_ERR("bt_mesh_model_send failed (err: %d)", err);
533 		return err;
534 	}
535 
536 	return 0;
537 }
538 
bt_mesh_test_ra_cb_setup(void (* cb)(uint8_t *,size_t))539 void bt_mesh_test_ra_cb_setup(void (*cb)(uint8_t *, size_t))
540 {
541 	ra_cb = cb;
542 }
543 
bt_mesh_test_own_addr_get(uint16_t start_addr)544 uint16_t bt_mesh_test_own_addr_get(uint16_t start_addr)
545 {
546 	return start_addr + get_device_nbr();
547 }
548 
549 #if defined(CONFIG_BT_MESH_SAR_CFG)
bt_mesh_test_sar_conf_set(struct bt_mesh_sar_tx * tx_set,struct bt_mesh_sar_rx * rx_set)550 void bt_mesh_test_sar_conf_set(struct bt_mesh_sar_tx *tx_set, struct bt_mesh_sar_rx *rx_set)
551 {
552 	int err;
553 
554 	if (tx_set) {
555 		struct bt_mesh_sar_tx tx_rsp;
556 
557 		err = bt_mesh_sar_cfg_cli_transmitter_set(0, cfg->addr, tx_set, &tx_rsp);
558 		if (err) {
559 			FAIL("Failed to configure SAR Transmitter state (err %d)", err);
560 		}
561 	}
562 
563 	if (rx_set) {
564 		struct bt_mesh_sar_rx rx_rsp;
565 
566 		err = bt_mesh_sar_cfg_cli_receiver_set(0, cfg->addr, rx_set, &rx_rsp);
567 		if (err) {
568 			FAIL("Failed to configure SAR Receiver state (err %d)", err);
569 		}
570 	}
571 }
572 #endif /* defined(CONFIG_BT_MESH_SAR_CFG) */
573