1 /*
2  * Copyright (c) 2021 Lingao Meng
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdlib.h>
7 
8 #include "mesh_test.h"
9 #include "mesh/access.h"
10 #include "mesh/net.h"
11 #include "mesh/crypto.h"
12 #include "argparse.h"
13 #include <bs_pc_backchannel.h>
14 #include <time_machine.h>
15 
16 #if defined CONFIG_BT_MESH_USES_MBEDTLS_PSA
17 #include <psa/crypto.h>
18 #elif defined CONFIG_BT_MESH_USES_TINYCRYPT
19 #include <tinycrypt/constants.h>
20 #include <tinycrypt/ecc.h>
21 #include <tinycrypt/ecc_dh.h>
22 #else
23 #error "Unknown crypto library has been chosen"
24 #endif
25 
26 #include <zephyr/sys/byteorder.h>
27 
28 #define LOG_MODULE_NAME mesh_prov
29 
30 #include <zephyr/logging/log.h>
31 #include "mesh/rpr.h"
32 
33 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
34 
35 /*
36  * Provision layer tests:
37  *   Tests both the provisioner and device role in various scenarios.
38  */
39 
40 #define PROV_MULTI_COUNT 3
41 #define PROV_REPROV_COUNT 3
42 #define WAIT_TIME 120 /*seconds*/
43 #define IS_RPR_PRESENT  (CONFIG_BT_MESH_RPR_SRV && CONFIG_BT_MESH_RPR_CLI)
44 #define IMPOSTER_MODEL_ID 0xe000
45 
46 enum test_flags {
47 	IS_PROVISIONER,
48 
49 	TEST_FLAGS,
50 };
51 
52 static uint8_t static_key1[] = {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F,
53 		0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x31};
54 static uint8_t static_key2[] = {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F};
55 static uint8_t static_key3[] = {0x45, 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x64, 0x20, 0x70, 0x72,
56 				0x6F, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x69, 0x6E, 0x67, 0x20,
57 				0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x4F, 0x4F, 0x42};
58 
59 static uint8_t private_key_be[32];
60 static uint8_t public_key_be[64];
61 
62 static struct oob_auth_test_vector_s {
63 	const uint8_t *static_val;
64 	uint8_t        static_val_len;
65 	uint8_t        output_size;
66 	uint16_t       output_actions;
67 	uint8_t        input_size;
68 	uint16_t       input_actions;
69 } oob_auth_test_vector[] = {
70 	{NULL, 0, 0, 0, 0, 0},
71 	{static_key1, sizeof(static_key1), 0, 0, 0, 0},
72 	{static_key2, sizeof(static_key2), 0, 0, 0, 0},
73 	{static_key3, sizeof(static_key3), 0, 0, 0, 0},
74 	{NULL, 0, 3, BT_MESH_BLINK, 0, 0},
75 	{NULL, 0, 5, BT_MESH_BEEP, 0, 0},
76 	{NULL, 0, 6, BT_MESH_VIBRATE, 0, 0},
77 	{NULL, 0, 7, BT_MESH_DISPLAY_NUMBER, 0, 0},
78 	{NULL, 0, 8, BT_MESH_DISPLAY_STRING, 0, 0},
79 	{NULL, 0, 0, 0, 4, BT_MESH_PUSH},
80 	{NULL, 0, 0, 0, 5, BT_MESH_TWIST},
81 	{NULL, 0, 0, 0, 8, BT_MESH_ENTER_NUMBER},
82 	{NULL, 0, 0, 0, 7, BT_MESH_ENTER_STRING},
83 };
84 
85 static ATOMIC_DEFINE(test_flags, TEST_FLAGS);
86 
87 extern const struct bt_mesh_comp comp;
88 extern const uint8_t test_net_key[16];
89 extern const uint8_t test_app_key[16];
90 
91 /* Timeout semaphore */
92 static struct k_sem prov_sem;
93 static K_SEM_DEFINE(link_open_sem, 0, 1);
94 static uint16_t prov_addr = 0x0002;
95 static uint16_t current_dev_addr;
96 static const uint8_t dev_key[16] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
97 static uint8_t dev_uuid[16] = { 0x6c, 0x69, 0x6e, 0x67, 0x61, 0x6f };
98 static uint8_t *uuid_to_provision;
99 static struct k_sem reprov_sem;
100 static uint32_t link_close_timestamp;
101 
102 #if IS_RPR_PRESENT
103 static struct k_sem pdu_send_sem;
104 static struct k_sem scan_sem;
105 /* Remote Provisioning models related variables. */
106 static uint8_t *uuid_to_provision_remote;
107 static void rpr_scan_report(struct bt_mesh_rpr_cli *cli, const struct bt_mesh_rpr_node *srv,
108 			    struct bt_mesh_rpr_unprov *unprov, struct net_buf_simple *adv_data);
109 
110 static struct bt_mesh_rpr_cli rpr_cli = {
111 	.scan_report = rpr_scan_report,
112 };
113 
114 static const struct bt_mesh_comp rpr_cli_comp = {
115 	.elem =
116 		(const struct bt_mesh_elem[]){
117 			BT_MESH_ELEM(1,
118 				     MODEL_LIST(BT_MESH_MODEL_CFG_SRV,
119 						BT_MESH_MODEL_CFG_CLI(&(struct bt_mesh_cfg_cli){}),
120 						BT_MESH_MODEL_RPR_CLI(&rpr_cli)),
121 				     BT_MESH_MODEL_NONE),
122 		},
123 	.elem_count = 1,
124 };
125 
126 static const struct bt_mesh_comp rpr_srv_comp = {
127 	.elem =
128 		(const struct bt_mesh_elem[]){
129 			BT_MESH_ELEM(1,
130 				     MODEL_LIST(BT_MESH_MODEL_CFG_SRV,
131 						BT_MESH_MODEL_RPR_SRV),
132 				     BT_MESH_MODEL_NONE),
133 		},
134 	.elem_count = 1,
135 };
136 
137 static const struct bt_mesh_comp rpr_cli_srv_comp = {
138 	.elem =
139 		(const struct bt_mesh_elem[]){
140 			BT_MESH_ELEM(1,
141 				     MODEL_LIST(BT_MESH_MODEL_CFG_SRV,
142 						BT_MESH_MODEL_CFG_CLI(&(struct bt_mesh_cfg_cli){}),
143 						BT_MESH_MODEL_RPR_CLI(&rpr_cli),
144 						BT_MESH_MODEL_RPR_SRV),
145 				     BT_MESH_MODEL_NONE),
146 		},
147 	.elem_count = 1,
148 };
149 
mock_pdu_send(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)150 static int mock_pdu_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
151 			       struct net_buf_simple *buf)
152 {
153 	/* Device becomes unresponsive and doesn't communicate with other nodes anymore */
154 	k_sleep(K_MSEC(10));
155 	bt_mesh_suspend();
156 
157 	k_sem_give(&pdu_send_sem);
158 
159 	return 0;
160 }
161 
162 static const struct bt_mesh_model_op model_rpr_op1[] = {
163 	{ RPR_OP_PDU_SEND, 0, mock_pdu_send },
164 	BT_MESH_MODEL_OP_END
165 };
166 
mock_model_init(const struct bt_mesh_model * mod)167 static int mock_model_init(const struct bt_mesh_model *mod)
168 {
169 	mod->keys[0] = BT_MESH_KEY_DEV_LOCAL;
170 	mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY;
171 
172 	return 0;
173 }
174 
175 const struct bt_mesh_model_cb mock_model_cb = {
176 	.init = mock_model_init
177 };
178 
179 static const struct bt_mesh_comp rpr_srv_comp_unresponsive = {
180 	.elem =
181 		(const struct bt_mesh_elem[]){
182 			BT_MESH_ELEM(1,
183 				     MODEL_LIST(BT_MESH_MODEL_CFG_SRV,
184 						BT_MESH_MODEL_CB(IMPOSTER_MODEL_ID,
185 								 model_rpr_op1, NULL, NULL,
186 								 &mock_model_cb),
187 						BT_MESH_MODEL_RPR_SRV,),
188 				     BT_MESH_MODEL_NONE),
189 		},
190 	.elem_count = 1,
191 };
192 
193 static const uint8_t elem_offset1[2] = {1, 2};
194 static const uint8_t elem_offset2[3] = {4, 5, 6};
195 static const uint8_t additional_data[2] = {100, 200};
196 
197 static const struct bt_mesh_comp2_record comp_rec[2] = {
198 	{.id = 1,
199 	 .version.x = 2,
200 	 .version.y = 3,
201 	 .version.z = 4,
202 	 .elem_offset_cnt = sizeof(elem_offset1),
203 	 .elem_offset = elem_offset1,
204 	 .data_len = 0},
205 	{.id = 10,
206 	 .version.x = 20,
207 	 .version.y = 30,
208 	 .version.z = 40,
209 	 .elem_offset_cnt = sizeof(elem_offset2),
210 	 .elem_offset = elem_offset2,
211 	 .data_len = sizeof(additional_data),
212 	 .data = additional_data},
213 };
214 
215 static const struct bt_mesh_comp2 comp_p2_1 = {.record_cnt = 1, .record = comp_rec};
216 static const struct bt_mesh_comp2 comp_p2_2 = {.record_cnt = 2, .record = comp_rec};
217 
218 static const struct bt_mesh_comp rpr_srv_comp_2_elem = {
219 	.elem =
220 		(const struct bt_mesh_elem[]){
221 			BT_MESH_ELEM(1,
222 				     MODEL_LIST(BT_MESH_MODEL_CFG_SRV,
223 						BT_MESH_MODEL_RPR_SRV),
224 				     BT_MESH_MODEL_NONE),
225 			BT_MESH_ELEM(2,
226 				     MODEL_LIST(BT_MESH_MODEL_CB(TEST_MOD_ID, BT_MESH_MODEL_NO_OPS,
227 								 NULL, NULL, NULL)),
228 				     BT_MESH_MODEL_NONE),
229 		},
230 	.elem_count = 2,
231 };
232 #endif /* IS_RPR_PRESENT */
233 
234 /* Delayed work to avoid requesting OOB info before generation of this. */
235 static struct k_work_delayable oob_timer;
236 static void delayed_input(struct k_work *work);
237 
238 static uint *oob_channel_id;
239 static bool is_oob_auth;
240 
test_device_init(void)241 static void test_device_init(void)
242 {
243 	/* Ensure that the UUID is unique: */
244 	dev_uuid[6] = '0' + get_device_nbr();
245 
246 	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
247 	k_work_init_delayable(&oob_timer, delayed_input);
248 }
249 
test_provisioner_init(void)250 static void test_provisioner_init(void)
251 {
252 	atomic_set_bit(test_flags, IS_PROVISIONER);
253 	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
254 	k_work_init_delayable(&oob_timer, delayed_input);
255 }
256 
test_terminate(void)257 static void test_terminate(void)
258 {
259 	if (oob_channel_id) {
260 		bs_clean_back_channels();
261 	}
262 }
263 
unprovisioned_beacon(uint8_t uuid[16],bt_mesh_prov_oob_info_t oob_info,uint32_t * uri_hash)264 static void unprovisioned_beacon(uint8_t uuid[16],
265 				 bt_mesh_prov_oob_info_t oob_info,
266 				 uint32_t *uri_hash)
267 {
268 	if (!atomic_test_bit(test_flags, IS_PROVISIONER)) {
269 		return;
270 	}
271 
272 	if (uuid_to_provision && memcmp(uuid, uuid_to_provision, 16)) {
273 		return;
274 	}
275 
276 	bt_mesh_provision_adv(uuid, 0, prov_addr, 0);
277 }
278 
prov_complete(uint16_t net_idx,uint16_t addr)279 static void prov_complete(uint16_t net_idx, uint16_t addr)
280 {
281 	if (!atomic_test_bit(test_flags, IS_PROVISIONER)) {
282 		k_sem_give(&prov_sem);
283 	}
284 }
285 
prov_link_open(bt_mesh_prov_bearer_t bearer)286 static void prov_link_open(bt_mesh_prov_bearer_t bearer)
287 {
288 	k_sem_give(&link_open_sem);
289 }
290 
prov_link_close(bt_mesh_prov_bearer_t bearer)291 static void prov_link_close(bt_mesh_prov_bearer_t bearer)
292 {
293 	link_close_timestamp = k_uptime_get_32();
294 }
295 
prov_node_added(uint16_t net_idx,uint8_t uuid[16],uint16_t addr,uint8_t num_elem)296 static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
297 			    uint8_t num_elem)
298 {
299 	LOG_INF("Device 0x%04x provisioned", prov_addr);
300 	current_dev_addr = prov_addr++;
301 	k_sem_give(&prov_sem);
302 }
303 
prov_reprovisioned(uint16_t addr)304 static void prov_reprovisioned(uint16_t addr)
305 {
306 	LOG_INF("Device reprovisioned. New address: 0x%04x", addr);
307 	k_sem_give(&reprov_sem);
308 }
309 
prov_reset(void)310 static void prov_reset(void)
311 {
312 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
313 }
314 
315 static bt_mesh_input_action_t gact;
316 static uint8_t gsize;
input(bt_mesh_input_action_t act,uint8_t size)317 static int input(bt_mesh_input_action_t act, uint8_t size)
318 {
319 	/* The test system requests the input OOB data earlier than
320 	 * the output OOB is generated. Need to release context here
321 	 * to allow output OOB creation. OOB will be inserted later
322 	 * after the delay.
323 	 */
324 	gact = act;
325 	gsize = size;
326 
327 	k_work_reschedule(&oob_timer, K_SECONDS(1));
328 
329 	return 0;
330 }
331 
delayed_input(struct k_work * work)332 static void delayed_input(struct k_work *work)
333 {
334 	char oob_str[16];
335 	uint32_t oob_number;
336 	int size = bs_bc_is_msg_received(*oob_channel_id);
337 
338 	if (size <= 0) {
339 		FAIL("OOB data is not gotten");
340 	}
341 
342 	switch (gact) {
343 	case BT_MESH_PUSH:
344 	case BT_MESH_TWIST:
345 	case BT_MESH_ENTER_NUMBER:
346 		ASSERT_TRUE(size == sizeof(uint32_t));
347 		bs_bc_receive_msg(*oob_channel_id, (uint8_t *)&oob_number, size);
348 		ASSERT_OK(bt_mesh_input_number(oob_number));
349 		break;
350 	case BT_MESH_ENTER_STRING:
351 		bs_bc_receive_msg(*oob_channel_id, (uint8_t *)oob_str, size);
352 		ASSERT_OK(bt_mesh_input_string(oob_str));
353 		break;
354 	default:
355 		FAIL("Unknown input action %u (size %u) requested!", gact, gsize);
356 	}
357 }
358 
prov_input_complete(void)359 static void prov_input_complete(void)
360 {
361 	LOG_INF("Input OOB data completed");
362 }
363 
364 static int output_number(bt_mesh_output_action_t action, uint32_t number);
365 static int output_string(const char *str);
366 static void capabilities(const struct bt_mesh_dev_capabilities *cap);
367 static struct bt_mesh_prov prov = {
368 	.uuid = dev_uuid,
369 	.unprovisioned_beacon = unprovisioned_beacon,
370 	.complete = prov_complete,
371 	.link_open = prov_link_open,
372 	.link_close = prov_link_close,
373 	.reprovisioned = prov_reprovisioned,
374 	.node_added = prov_node_added,
375 	.output_number = output_number,
376 	.output_string = output_string,
377 	.input = input,
378 	.input_complete = prov_input_complete,
379 	.capabilities = capabilities,
380 	.reset = prov_reset,
381 };
382 
output_number(bt_mesh_output_action_t action,uint32_t number)383 static int output_number(bt_mesh_output_action_t action, uint32_t number)
384 {
385 	LOG_INF("OOB Number: %u", number);
386 
387 	bs_bc_send_msg(*oob_channel_id, (uint8_t *)&number, sizeof(uint32_t));
388 	return 0;
389 }
390 
output_string(const char * str)391 static int output_string(const char *str)
392 {
393 	LOG_INF("OOB String: %s", str);
394 
395 	bs_bc_send_msg(*oob_channel_id, (uint8_t *)str, strlen(str) + 1);
396 	return 0;
397 }
398 
capabilities(const struct bt_mesh_dev_capabilities * cap)399 static void capabilities(const struct bt_mesh_dev_capabilities *cap)
400 {
401 	if (cap->oob_type & BT_MESH_STATIC_OOB_AVAILABLE) {
402 		LOG_INF("Static OOB authentication");
403 		ASSERT_OK(bt_mesh_auth_method_set_static(prov.static_val, prov.static_val_len));
404 	} else if (cap->output_actions) {
405 		LOG_INF("Output OOB authentication");
406 		ASSERT_OK(bt_mesh_auth_method_set_output(prov.output_actions, prov.output_size));
407 	} else if (cap->input_actions) {
408 		LOG_INF("Input OOB authentication");
409 		ASSERT_OK(bt_mesh_auth_method_set_input(prov.input_actions, prov.input_size));
410 	} else if (!is_oob_auth) {
411 		bt_mesh_auth_method_set_none();
412 	} else {
413 		FAIL("No OOB in capability frame");
414 	}
415 }
416 
oob_auth_set(int test_step)417 static void oob_auth_set(int test_step)
418 {
419 	struct oob_auth_test_vector_s dummy = {0};
420 
421 	ASSERT_TRUE(test_step < ARRAY_SIZE(oob_auth_test_vector));
422 
423 	if (memcmp(&oob_auth_test_vector[test_step], &dummy,
424 		sizeof(struct oob_auth_test_vector_s))) {
425 		is_oob_auth = true;
426 	} else {
427 		is_oob_auth = false;
428 	}
429 
430 	prov.static_val = oob_auth_test_vector[test_step].static_val;
431 	prov.static_val_len = oob_auth_test_vector[test_step].static_val_len;
432 	prov.output_size = oob_auth_test_vector[test_step].output_size;
433 	prov.output_actions = oob_auth_test_vector[test_step].output_actions;
434 	prov.input_size = oob_auth_test_vector[test_step].input_size;
435 	prov.input_actions = oob_auth_test_vector[test_step].input_actions;
436 }
437 
438 #if defined CONFIG_BT_MESH_USES_MBEDTLS_PSA
generate_oob_key_pair(void)439 static void generate_oob_key_pair(void)
440 {
441 	psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
442 	psa_key_id_t priv_key_id = PSA_KEY_ID_NULL;
443 	psa_status_t status;
444 	size_t key_len;
445 	uint8_t public_key_repr[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256)];
446 
447 	/* Crypto settings for ECDH using the SHA256 hashing algorithm,
448 	 * the secp256r1 curve
449 	 */
450 	psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
451 	psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
452 	psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
453 	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
454 	psa_set_key_bits(&key_attributes, 256);
455 
456 	/* Generate a key pair */
457 	status = psa_generate_key(&key_attributes, &priv_key_id);
458 	ASSERT_TRUE(status == PSA_SUCCESS);
459 
460 	status = psa_export_public_key(priv_key_id, public_key_repr, sizeof(public_key_repr),
461 				       &key_len);
462 	ASSERT_TRUE(status == PSA_SUCCESS);
463 
464 	ASSERT_TRUE(key_len == PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256));
465 
466 	status = psa_export_key(priv_key_id, private_key_be, sizeof(private_key_be), &key_len);
467 	ASSERT_TRUE(status == PSA_SUCCESS);
468 
469 	ASSERT_TRUE(key_len == sizeof(private_key_be));
470 
471 	memcpy(public_key_be, public_key_repr + 1, 64);
472 }
473 #elif defined CONFIG_BT_MESH_USES_TINYCRYPT
generate_oob_key_pair(void)474 static void generate_oob_key_pair(void)
475 {
476 	ASSERT_TRUE(uECC_make_key(public_key_be, private_key_be, uECC_secp256r1()));
477 }
478 #endif
479 
oob_device(bool use_oob_pk)480 static void oob_device(bool use_oob_pk)
481 {
482 	k_sem_init(&prov_sem, 0, 1);
483 
484 	bt_mesh_device_setup(&prov, &comp);
485 
486 	if (use_oob_pk) {
487 		generate_oob_key_pair();
488 		prov.public_key_be = public_key_be;
489 		prov.private_key_be = private_key_be;
490 		bs_bc_send_msg(*oob_channel_id, public_key_be, 64);
491 		LOG_HEXDUMP_INF(public_key_be, 64, "OOB Public Key:");
492 	}
493 
494 	for (int i = 0; i < ARRAY_SIZE(oob_auth_test_vector); i++) {
495 		oob_auth_set(i);
496 
497 		ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
498 
499 		/* Keep a long timeout so the prov multi case has time to finish: */
500 		ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(40)));
501 
502 		/* Delay to complete procedure with Provisioning Complete PDU frame.
503 		 * Device shall start later provisioner was able to set OOB public key.
504 		 */
505 		k_sleep(K_SECONDS(2));
506 
507 		bt_mesh_reset();
508 	}
509 }
510 
oob_provisioner(bool read_oob_pk,bool use_oob_pk)511 static void oob_provisioner(bool read_oob_pk, bool use_oob_pk)
512 {
513 	k_sem_init(&prov_sem, 0, 1);
514 
515 	bt_mesh_device_setup(&prov, &comp);
516 
517 	if (read_oob_pk) {
518 		/* Delay to complete procedure public key generation on provisioning device. */
519 		k_sleep(K_SECONDS(1));
520 
521 		int size = bs_bc_is_msg_received(*oob_channel_id);
522 
523 		if (size <= 0) {
524 			FAIL("OOB public key is not gotten");
525 		}
526 
527 		bs_bc_receive_msg(*oob_channel_id, public_key_be, 64);
528 		LOG_HEXDUMP_INF(public_key_be, 64, "OOB Public Key:");
529 	}
530 
531 	ASSERT_OK(bt_mesh_cdb_create(test_net_key));
532 
533 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
534 
535 	for (int i = 0; i < ARRAY_SIZE(oob_auth_test_vector); i++) {
536 		oob_auth_set(i);
537 
538 		if (use_oob_pk) {
539 			ASSERT_OK(bt_mesh_prov_remote_pub_key_set(public_key_be));
540 		}
541 
542 		ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(40)));
543 
544 		bt_mesh_cdb_node_del(bt_mesh_cdb_node_get(prov_addr - 1), true);
545 
546 		/* Delay to complete procedure with cleaning of the public key.
547 		 * This is important that the provisioner started the new cycle loop
548 		 * earlier than device to get OOB public key before capabilities frame.
549 		 */
550 		k_sleep(K_SECONDS(1));
551 	}
552 
553 	bt_mesh_reset();
554 }
555 
556 /** Configures the health server on a node at current_dev_addr address and sends node reset.
557  */
node_configure_and_reset(void)558 static void node_configure_and_reset(void)
559 {
560 	uint8_t status;
561 	size_t subs_count = 1;
562 	uint16_t sub;
563 	struct bt_mesh_cfg_cli_mod_pub healthpub = { 0 };
564 	struct bt_mesh_cdb_node *node;
565 
566 	/* Check that publication and subscription are reset after last iteration */
567 	ASSERT_OK(bt_mesh_cfg_cli_mod_sub_get(0, current_dev_addr, current_dev_addr,
568 					  BT_MESH_MODEL_ID_HEALTH_SRV, &status, &sub,
569 					  &subs_count));
570 	ASSERT_EQUAL(0, status);
571 	ASSERT_TRUE(subs_count == 0);
572 
573 	ASSERT_OK(bt_mesh_cfg_cli_mod_pub_get(0, current_dev_addr, current_dev_addr,
574 					  BT_MESH_MODEL_ID_HEALTH_SRV, &healthpub,
575 					  &status));
576 	ASSERT_EQUAL(0, status);
577 	ASSERT_TRUE_MSG(healthpub.addr == BT_MESH_ADDR_UNASSIGNED, "Pub not cleared\n");
578 
579 	/* Set pub and sub to check that they are reset */
580 	healthpub.addr = 0xc001;
581 	healthpub.app_idx = 0;
582 	healthpub.cred_flag = false;
583 	healthpub.ttl = 10;
584 	healthpub.period = BT_MESH_PUB_PERIOD_10SEC(1);
585 	healthpub.transmit = BT_MESH_TRANSMIT(3, 100);
586 
587 	ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key,
588 					  &status));
589 	ASSERT_EQUAL(0, status);
590 
591 	k_sleep(K_SECONDS(2));
592 
593 	ASSERT_OK(bt_mesh_cfg_cli_mod_app_bind(0, current_dev_addr, current_dev_addr, 0x0,
594 					   BT_MESH_MODEL_ID_HEALTH_SRV, &status));
595 	ASSERT_EQUAL(0, status);
596 
597 	k_sleep(K_SECONDS(2));
598 
599 	ASSERT_OK(bt_mesh_cfg_cli_mod_sub_add(0, current_dev_addr, current_dev_addr, 0xc000,
600 					  BT_MESH_MODEL_ID_HEALTH_SRV, &status));
601 	ASSERT_EQUAL(0, status);
602 
603 	k_sleep(K_SECONDS(2));
604 
605 	ASSERT_OK(bt_mesh_cfg_cli_mod_pub_set(0, current_dev_addr, current_dev_addr,
606 					  BT_MESH_MODEL_ID_HEALTH_SRV, &healthpub,
607 					  &status));
608 	ASSERT_EQUAL(0, status);
609 
610 	k_sleep(K_SECONDS(2));
611 
612 	ASSERT_OK(bt_mesh_cfg_cli_node_reset(0, current_dev_addr, (bool *)&status));
613 
614 	node = bt_mesh_cdb_node_get(current_dev_addr);
615 	bt_mesh_cdb_node_del(node, true);
616 }
617 
618 /** @brief Verify that this device pb-adv provision.
619  */
test_device_pb_adv_no_oob(void)620 static void test_device_pb_adv_no_oob(void)
621 {
622 	k_sem_init(&prov_sem, 0, 1);
623 
624 	bt_mesh_device_setup(&prov, &comp);
625 
626 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
627 
628 	LOG_INF("Mesh initialized\n");
629 
630 	/* Keep a long timeout so the prov multi case has time to finish: */
631 	ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(40)));
632 
633 	PASS();
634 }
635 
636 /** @brief Verify that this device can be reprovisioned after resets
637  */
test_device_pb_adv_reprovision(void)638 static void test_device_pb_adv_reprovision(void)
639 {
640 	k_sem_init(&prov_sem, 0, 1);
641 
642 	bt_mesh_device_setup(&prov, &comp);
643 
644 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
645 
646 	LOG_INF("Mesh initialized\n");
647 
648 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
649 		/* Keep a long timeout so the prov multi case has time to finish: */
650 		LOG_INF("Dev prov loop #%d, waiting for prov ...\n", i);
651 		ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
652 	}
653 
654 	PASS();
655 }
656 
657 /** @brief Verify that this provisioner pb-adv provision.
658  */
test_provisioner_pb_adv_no_oob(void)659 static void test_provisioner_pb_adv_no_oob(void)
660 {
661 	k_sem_init(&prov_sem, 0, 1);
662 
663 	bt_mesh_device_setup(&prov, &comp);
664 
665 	ASSERT_OK(bt_mesh_cdb_create(test_net_key));
666 
667 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
668 
669 	ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(5)));
670 
671 	PASS();
672 }
673 
test_device_pb_adv_oob_auth(void)674 static void test_device_pb_adv_oob_auth(void)
675 {
676 	oob_device(false);
677 
678 	PASS();
679 }
680 
test_provisioner_pb_adv_oob_auth(void)681 static void test_provisioner_pb_adv_oob_auth(void)
682 {
683 	oob_provisioner(false, false);
684 
685 	PASS();
686 }
687 
test_back_channel_pre_init(void)688 static void test_back_channel_pre_init(void)
689 {
690 	oob_channel_id = bs_open_back_channel(get_device_nbr(),
691 			(uint[]){(get_device_nbr() + 1) % 2}, (uint[]){0}, 1);
692 	if (!oob_channel_id) {
693 		FAIL("Can't open OOB interface\n");
694 	}
695 }
696 
test_device_pb_adv_oob_public_key(void)697 static void test_device_pb_adv_oob_public_key(void)
698 {
699 	oob_device(true);
700 
701 	PASS();
702 }
703 
test_provisioner_pb_adv_oob_public_key(void)704 static void test_provisioner_pb_adv_oob_public_key(void)
705 {
706 	oob_provisioner(true, true);
707 
708 	PASS();
709 }
710 
test_provisioner_pb_adv_oob_auth_no_oob_public_key(void)711 static void test_provisioner_pb_adv_oob_auth_no_oob_public_key(void)
712 {
713 	oob_provisioner(true, false);
714 
715 	PASS();
716 }
717 
718 /** @brief Verify that the provisioner can provision multiple devices in a row
719  */
test_provisioner_pb_adv_multi(void)720 static void test_provisioner_pb_adv_multi(void)
721 {
722 	k_sem_init(&prov_sem, 0, 1);
723 
724 	bt_mesh_device_setup(&prov, &comp);
725 
726 	ASSERT_OK(bt_mesh_cdb_create(test_net_key));
727 
728 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
729 
730 	for (int i = 0; i < PROV_MULTI_COUNT; i++) {
731 		ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
732 	}
733 
734 	PASS();
735 }
736 
737 /** @brief Verify that when the IV Update flag is set to zero at the
738  * time of provisioning, internal IV update counter is also zero.
739  */
test_provisioner_iv_update_flag_zero(void)740 static void test_provisioner_iv_update_flag_zero(void)
741 {
742 	uint8_t flags = 0x00;
743 
744 	bt_mesh_device_setup(&prov, &comp);
745 
746 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, flags, 0, 0x0001, dev_key));
747 
748 	if (bt_mesh.ivu_duration != 0) {
749 		FAIL("IV Update duration counter is not 0 when IV Update flag is zero");
750 	}
751 
752 	PASS();
753 }
754 
755 /** @brief Verify that when the IV Update flag is set to one at the
756  * time of provisioning, internal IV update counter is set to 96 hours.
757  */
test_provisioner_iv_update_flag_one(void)758 static void test_provisioner_iv_update_flag_one(void)
759 {
760 	uint8_t flags = 0x02; /* IV Update flag bit set to 1 */
761 
762 	bt_mesh_device_setup(&prov, &comp);
763 
764 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, flags, 0, 0x0001, dev_key));
765 
766 	if (bt_mesh.ivu_duration != 96) {
767 		FAIL("IV Update duration counter is not 96 when IV Update flag is one");
768 	}
769 
770 	bt_mesh_reset();
771 
772 	if (bt_mesh.ivu_duration != 0) {
773 		FAIL("IV Update duration counter is not reset to 0");
774 	}
775 
776 	PASS();
777 }
778 
779 /** @brief Verify that the provisioner can provision a device multiple times after resets
780  */
test_provisioner_pb_adv_reprovision(void)781 static void test_provisioner_pb_adv_reprovision(void)
782 {
783 	k_sem_init(&prov_sem, 0, 1);
784 
785 	bt_mesh_device_setup(&prov, &comp);
786 
787 	ASSERT_OK(bt_mesh_cdb_create(test_net_key));
788 
789 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
790 
791 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
792 		LOG_INF("Provisioner prov loop #%d, waiting for prov ...\n", i);
793 		ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
794 
795 		node_configure_and_reset();
796 	}
797 
798 	PASS();
799 }
800 
801 /** @brief Device starts unprovisioned. Stops being responsive to Mesh message after initial setup.
802  * Later becomes responsive but becomes unresponsive again after provisioning link opens.
803  * Then becomes responsive again allowing successful provisioning. Never stops advertising
804  * Unprovisioned Device beacons.
805  */
test_device_unresponsive(void)806 static void test_device_unresponsive(void)
807 {
808 	bt_mesh_device_setup(&prov, &comp);
809 
810 	k_sem_init(&prov_sem, 0, 1);
811 
812 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
813 
814 	/* stop responding for 30s to timeout PB-ADV link establishment. */
815 	bt_mesh_scan_disable();
816 	k_sleep(K_SECONDS(30));
817 	bt_mesh_scan_enable();
818 
819 	k_sem_take(&link_open_sem, K_SECONDS(20));
820 	/* stop responding for 60s to timeout protocol */
821 	bt_mesh_scan_disable();
822 	k_sleep(K_SECONDS(60));
823 	bt_mesh_scan_enable();
824 
825 	k_sem_take(&prov_sem, K_SECONDS(20));
826 	PASS();
827 }
828 
829 #if IS_RPR_PRESENT
provision_adv(uint8_t dev_idx,uint16_t * addr)830 static int provision_adv(uint8_t dev_idx, uint16_t *addr)
831 {
832 	static uint8_t uuid[16];
833 	int err;
834 
835 	memcpy(uuid, dev_uuid, 16);
836 	uuid[6] = '0' + dev_idx;
837 	uuid_to_provision = uuid;
838 
839 	LOG_INF("Waiting for a device with RPR Server to be provisioned over PB-Adv...");
840 	err = k_sem_take(&prov_sem, K_SECONDS(10));
841 	*addr = current_dev_addr;
842 
843 	return err;
844 }
845 
provision_remote(struct bt_mesh_rpr_node * srv,uint8_t dev_idx,uint16_t * addr)846 static int provision_remote(struct bt_mesh_rpr_node *srv, uint8_t dev_idx, uint16_t *addr)
847 {
848 	static uint8_t uuid[16];
849 	struct bt_mesh_rpr_scan_status scan_status;
850 	int err;
851 
852 	memcpy(uuid, dev_uuid, 16);
853 	uuid[6] = '0' + dev_idx;
854 	uuid_to_provision_remote = uuid;
855 
856 	LOG_INF("Starting scanning for an unprov device...");
857 	ASSERT_OK(bt_mesh_rpr_scan_start(&rpr_cli, srv, NULL, 5, 1, &scan_status));
858 	ASSERT_EQUAL(BT_MESH_RPR_SUCCESS, scan_status.status);
859 	ASSERT_EQUAL(BT_MESH_RPR_SCAN_MULTI, scan_status.scan);
860 	ASSERT_EQUAL(1, scan_status.max_devs);
861 	ASSERT_EQUAL(5, scan_status.timeout);
862 
863 	err = k_sem_take(&prov_sem, K_SECONDS(20));
864 	*addr = current_dev_addr;
865 
866 	return err;
867 }
868 
rpr_scan_report(struct bt_mesh_rpr_cli * cli,const struct bt_mesh_rpr_node * srv,struct bt_mesh_rpr_unprov * unprov,struct net_buf_simple * adv_data)869 static void rpr_scan_report(struct bt_mesh_rpr_cli *cli, const struct bt_mesh_rpr_node *srv,
870 			    struct bt_mesh_rpr_unprov *unprov, struct net_buf_simple *adv_data)
871 {
872 	if (!uuid_to_provision_remote || memcmp(uuid_to_provision_remote, unprov->uuid, 16)) {
873 		return;
874 	}
875 
876 	LOG_INF("Remote device discovered. Provisioning...");
877 	ASSERT_OK(bt_mesh_provision_remote(cli, srv, unprov->uuid, 0, prov_addr));
878 }
879 
prov_node_added_rpr(uint16_t net_idx,uint8_t uuid[16],uint16_t addr,uint8_t num_elem)880 static void prov_node_added_rpr(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
881 				uint8_t num_elem)
882 {
883 	LOG_INF("Device 0x%04x reprovisioned", addr);
884 	k_sem_give(&reprov_sem);
885 }
886 
provisioner_pb_remote_client_setup(void)887 static void provisioner_pb_remote_client_setup(void)
888 {
889 	k_sem_init(&prov_sem, 0, 1);
890 	k_sem_init(&reprov_sem, 0, 1);
891 
892 	bt_mesh_device_setup(&prov, &rpr_cli_comp);
893 
894 	ASSERT_OK(bt_mesh_cdb_create(test_net_key));
895 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
896 }
897 
device_pb_remote_server_setup(const struct bt_mesh_comp * comp,bool pb_adv_prov)898 static void device_pb_remote_server_setup(const struct bt_mesh_comp *comp, bool pb_adv_prov)
899 {
900 	k_sem_init(&prov_sem, 0, 1);
901 	k_sem_init(&reprov_sem, 0, 1);
902 
903 	bt_mesh_device_setup(&prov, comp);
904 
905 	if (pb_adv_prov) {
906 		ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
907 
908 		LOG_INF("Waiting for being provisioned...");
909 		ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
910 	} else {
911 		ASSERT_TRUE(bt_mesh_is_provisioned());
912 	}
913 
914 	LOG_INF("Enabling PB-Remote server");
915 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
916 }
917 
device_pb_remote_server_setup_unproved(const struct bt_mesh_comp * comp,const struct bt_mesh_comp2 * comp_p2)918 static void device_pb_remote_server_setup_unproved(const struct bt_mesh_comp *comp,
919 						   const struct bt_mesh_comp2 *comp_p2)
920 {
921 	device_pb_remote_server_setup(comp, true);
922 	bt_mesh_comp2_register(comp_p2);
923 }
924 
device_pb_remote_server_setup_proved(const struct bt_mesh_comp * comp,const struct bt_mesh_comp2 * comp_p2)925 static void device_pb_remote_server_setup_proved(const struct bt_mesh_comp *comp,
926 						 const struct bt_mesh_comp2 *comp_p2)
927 {
928 	device_pb_remote_server_setup(comp, false);
929 	bt_mesh_comp2_register(comp_p2);
930 }
931 
932 /** @brief Verify that the provisioner can provision a device multiple times after resets using
933  * PB-Remote and RPR models.
934  */
test_provisioner_pb_remote_client_reprovision(void)935 static void test_provisioner_pb_remote_client_reprovision(void)
936 {
937 	uint16_t pb_remote_server_addr;
938 
939 	provisioner_pb_remote_client_setup();
940 
941 	/* Provision the 2nd device over PB-Adv. */
942 	ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
943 
944 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
945 		struct bt_mesh_rpr_node srv = {
946 			.addr = pb_remote_server_addr,
947 			.net_idx = 0,
948 			.ttl = 3,
949 		};
950 
951 		LOG_INF("Provisioner prov loop #%d, waiting for prov ...\n", i);
952 		ASSERT_OK(provision_remote(&srv, 2, &srv.addr));
953 
954 		node_configure_and_reset();
955 	}
956 
957 	PASS();
958 }
959 
rpr_scan_report_parallel(struct bt_mesh_rpr_cli * cli,const struct bt_mesh_rpr_node * srv,struct bt_mesh_rpr_unprov * unprov,struct net_buf_simple * adv_data)960 static void rpr_scan_report_parallel(struct bt_mesh_rpr_cli *cli,
961 				const struct bt_mesh_rpr_node *srv,
962 				struct bt_mesh_rpr_unprov *unprov,
963 				struct net_buf_simple *adv_data)
964 {
965 	if (!uuid_to_provision_remote || memcmp(uuid_to_provision_remote, unprov->uuid, 16)) {
966 		return;
967 	}
968 
969 	LOG_INF("Scanning dev idx 2 succeeded.\n");
970 	k_sem_give(&scan_sem);
971 }
972 
test_provisioner_pb_remote_client_parallel(void)973 static void test_provisioner_pb_remote_client_parallel(void)
974 {
975 	static uint8_t uuid[16];
976 	uint16_t pb_remote_server_addr;
977 	struct bt_mesh_rpr_scan_status scan_status;
978 
979 	memcpy(uuid, dev_uuid, 16);
980 
981 	k_sem_init(&prov_sem, 0, 1);
982 	k_sem_init(&scan_sem, 0, 1);
983 
984 	bt_mesh_device_setup(&prov, &rpr_cli_comp);
985 
986 	ASSERT_OK(bt_mesh_cdb_create(test_net_key));
987 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
988 
989 	/* Provision the 2nd device over PB-Adv. */
990 	ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
991 
992 	struct bt_mesh_rpr_node srv = {
993 		.addr = pb_remote_server_addr,
994 		.net_idx = 0,
995 		.ttl = 3,
996 	};
997 
998 	rpr_cli.scan_report = rpr_scan_report_parallel;
999 
1000 	LOG_INF("Scanning dev idx 2 and provisioning dev idx 3 in parallel ...\n");
1001 	/* provisioning device with dev index 2 */
1002 	uuid[6] = '0' + 2;
1003 	ASSERT_OK(bt_mesh_provision_remote(&rpr_cli, &srv, uuid, 0, prov_addr));
1004 	/* scanning device with dev index 3 */
1005 	uuid[6] = '0' + 3;
1006 	uuid_to_provision_remote = uuid;
1007 	ASSERT_OK(bt_mesh_rpr_scan_start(&rpr_cli, &srv, uuid, 15, 1, &scan_status));
1008 	ASSERT_EQUAL(BT_MESH_RPR_SUCCESS, scan_status.status);
1009 	ASSERT_EQUAL(BT_MESH_RPR_SCAN_SINGLE, scan_status.scan);
1010 	ASSERT_EQUAL(1, scan_status.max_devs);
1011 	ASSERT_EQUAL(15, scan_status.timeout);
1012 
1013 	ASSERT_OK(k_sem_take(&scan_sem, K_SECONDS(20)));
1014 	ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
1015 
1016 	/* Provisioning device index 3. Need it to succeed provisionee test scenario. */
1017 	ASSERT_OK(bt_mesh_provision_remote(&rpr_cli, &srv, uuid, 0, prov_addr));
1018 	ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
1019 
1020 	PASS();
1021 }
1022 
1023 /** @brief Test Provisioning procedure on Remote Provisioning client:
1024  * - verify procedure timeouts on unresponsive unprovisioned device.
1025  */
test_provisioner_pb_remote_client_provision_timeout(void)1026 static void test_provisioner_pb_remote_client_provision_timeout(void)
1027 {
1028 	uint16_t pb_remote_server_addr;
1029 	uint8_t uuid[16];
1030 	uint32_t link_close_wait_start;
1031 	struct bt_mesh_rpr_scan_status scan_status;
1032 
1033 	k_sem_init(&scan_sem, 0, 1);
1034 
1035 	provisioner_pb_remote_client_setup();
1036 	bt_mesh_test_cfg_set(NULL, 300);
1037 
1038 	/* Provision the 2nd device over PB-Adv. */
1039 	ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
1040 
1041 	/* Provision the 3rd device over PB-Remote. */
1042 	struct bt_mesh_rpr_node srv = {
1043 		.addr = pb_remote_server_addr,
1044 		.net_idx = 0,
1045 		.ttl = 3,
1046 	};
1047 
1048 	rpr_cli.scan_report = rpr_scan_report_parallel;
1049 
1050 	/* Offset timeline of test to give some time to 3rd device to setup and disable scanning */
1051 	k_sleep(K_SECONDS(10));
1052 
1053 	memcpy(uuid, dev_uuid, 16);
1054 	uuid[6] = '0' + 2;
1055 	uuid_to_provision_remote = uuid;
1056 
1057 	LOG_INF("Starting scanning for an unprov device...");
1058 	ASSERT_OK(bt_mesh_rpr_scan_start(&rpr_cli, &srv, uuid, 5, 1, &scan_status));
1059 	ASSERT_EQUAL(BT_MESH_RPR_SUCCESS, scan_status.status);
1060 	ASSERT_EQUAL(BT_MESH_RPR_SCAN_SINGLE, scan_status.scan);
1061 	ASSERT_EQUAL(1, scan_status.max_devs);
1062 	ASSERT_EQUAL(5, scan_status.timeout);
1063 
1064 	ASSERT_OK(k_sem_take(&scan_sem, K_SECONDS(20)));
1065 
1066 	/* Invalidate earlier timestamp */
1067 	link_close_timestamp = -1;
1068 	ASSERT_OK(bt_mesh_provision_remote(&rpr_cli, &srv, uuid, 0, prov_addr));
1069 	link_close_wait_start = k_uptime_get_32();
1070 	ASSERT_EQUAL(k_sem_take(&prov_sem, K_SECONDS(20)), -EAGAIN);
1071 	ASSERT_EQUAL((link_close_timestamp - link_close_wait_start) / MSEC_PER_SEC, 10);
1072 
1073 	/* 3rd device should now respond but stop again after link is opened */
1074 	link_close_timestamp = -1;
1075 	ASSERT_OK(bt_mesh_provision_remote(&rpr_cli, &srv, uuid, 0, prov_addr));
1076 	ASSERT_OK(k_sem_take(&link_open_sem, K_SECONDS(20)));
1077 	link_close_wait_start = k_uptime_get_32();
1078 	ASSERT_EQUAL(k_sem_take(&prov_sem, K_SECONDS(61)), -EAGAIN);
1079 	ASSERT_EQUAL((link_close_timestamp - link_close_wait_start) / MSEC_PER_SEC, 60);
1080 
1081 	PASS();
1082 }
1083 
reprovision_remote_devkey_client(struct bt_mesh_rpr_node * srv,struct bt_mesh_cdb_node * node)1084 static void reprovision_remote_devkey_client(struct bt_mesh_rpr_node *srv,
1085 					     struct bt_mesh_cdb_node *node)
1086 {
1087 	uint8_t status;
1088 	uint8_t prev_node_dev_key[16];
1089 
1090 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
1091 		      "Can't export device key from cdb");
1092 
1093 	bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, false);
1094 
1095 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
1096 
1097 	/* Check that CDB has updated Device Key for the node. */
1098 	ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key));
1099 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
1100 			"Can't export device key from cdb");
1101 
1102 	/* Check device key by adding appkey. */
1103 	ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key,
1104 						&status));
1105 	ASSERT_OK(status);
1106 
1107 	/* Let RPR Server verify Device Key. */
1108 	k_sleep(K_SECONDS(2));
1109 }
1110 
reprovision_remote_comp_data_client(struct bt_mesh_rpr_node * srv,struct bt_mesh_cdb_node * node,struct net_buf_simple * dev_comp)1111 static void reprovision_remote_comp_data_client(struct bt_mesh_rpr_node *srv,
1112 						struct bt_mesh_cdb_node *node,
1113 						struct net_buf_simple *dev_comp)
1114 {
1115 	NET_BUF_SIMPLE_DEFINE(new_dev_comp, BT_MESH_RX_SDU_MAX);
1116 	uint8_t prev_node_dev_key[16];
1117 	uint8_t page;
1118 
1119 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
1120 		      "Can't export device key from cdb");
1121 
1122 	bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, true);
1123 
1124 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
1125 
1126 	/* Check that CDB has updated Device Key for the node. */
1127 	ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key));
1128 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
1129 			"Can't export device key from cdb");
1130 
1131 	/* Check that Composition Data Page 128 is now Page 0. */
1132 	net_buf_simple_reset(&new_dev_comp);
1133 	ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page,
1134 						&new_dev_comp));
1135 
1136 	ASSERT_EQUAL(0, page);
1137 	ASSERT_EQUAL(dev_comp->len, new_dev_comp.len);
1138 	if (memcmp(dev_comp->data, new_dev_comp.data, dev_comp->len)) {
1139 		FAIL("Wrong composition data page 0");
1140 	}
1141 
1142 	/* Let RPR Server verify Device Key. */
1143 	k_sleep(K_SECONDS(2));
1144 }
1145 
reprovision_remote_address_client(struct bt_mesh_rpr_node * srv,struct bt_mesh_cdb_node * node)1146 static void reprovision_remote_address_client(struct bt_mesh_rpr_node *srv,
1147 					      struct bt_mesh_cdb_node *node)
1148 {
1149 	uint8_t status;
1150 	uint8_t prev_node_dev_key[16];
1151 
1152 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
1153 		      "Can't export device key from cdb");
1154 
1155 	bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr + 1, false);
1156 
1157 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
1158 
1159 	current_dev_addr++;
1160 	srv->addr++;
1161 
1162 	/* Check that device doesn't respond to old address with old and new device key. */
1163 	struct bt_mesh_cdb_node *prev_node;
1164 	uint8_t tmp[16];
1165 
1166 	prev_node = bt_mesh_cdb_node_alloc((uint8_t[16]) {}, current_dev_addr - 1, 1, 0);
1167 	ASSERT_TRUE(node);
1168 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, prev_node_dev_key),
1169 			"Can't import device key into cdb");
1170 	ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0,
1171 								test_app_key, &status));
1172 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, tmp),
1173 			"Can't export device key from cdb");
1174 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_import(prev_node, tmp),
1175 			"Can't import device key into cdb");
1176 	ASSERT_EQUAL(-ETIMEDOUT, bt_mesh_cfg_cli_app_key_add(0, current_dev_addr - 1, 0, 0,
1177 								test_app_key, &status));
1178 	bt_mesh_cdb_node_del(prev_node, false);
1179 
1180 	/* Check that CDB has updated Device Key for the node. */
1181 	ASSERT_TRUE(bt_mesh_key_compare(prev_node_dev_key, &node->dev_key));
1182 	ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
1183 			"Can't export device key from cdb");
1184 
1185 	/* Check new device address by adding appkey. */
1186 	ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key,
1187 						&status));
1188 	ASSERT_OK(status);
1189 
1190 	/* Let RPR Server verify Device Key. */
1191 	k_sleep(K_SECONDS(2));
1192 
1193 }
1194 
1195 /** @brief Verify robustness of NPPI procedures on a RPR Client by running Device Key Refresh,
1196  * Node Composition Refresh and Node Address Refresh procedures.
1197  */
test_provisioner_pb_remote_client_nppi_robustness(void)1198 static void test_provisioner_pb_remote_client_nppi_robustness(void)
1199 {
1200 	NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX);
1201 	uint8_t page;
1202 	uint16_t pb_remote_server_addr;
1203 	uint8_t status;
1204 	struct bt_mesh_cdb_node *node;
1205 
1206 	provisioner_pb_remote_client_setup();
1207 
1208 	/* Provision the 2nd device over PB-Adv. */
1209 	ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
1210 
1211 	/* Provision a remote device with RPR Server. */
1212 	struct bt_mesh_rpr_node srv = {
1213 		.addr = pb_remote_server_addr,
1214 		.net_idx = 0,
1215 		.ttl = 3,
1216 	};
1217 
1218 	ASSERT_OK(provision_remote(&srv, 2, &srv.addr));
1219 
1220 	/* Check device key by adding appkey. */
1221 	ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, &status));
1222 	ASSERT_OK(status);
1223 
1224 	/* Swap callback to catch when device reprovisioned. */
1225 	prov.node_added = prov_node_added_rpr;
1226 
1227 	/* Store initial Composition Data Page 0. */
1228 	ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, &dev_comp));
1229 
1230 	node = bt_mesh_cdb_node_get(current_dev_addr);
1231 	ASSERT_TRUE(node);
1232 
1233 	LOG_INF("Testing DevKey refresh...");
1234 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
1235 		LOG_INF("Refreshing device key #%d...\n", i);
1236 		reprovision_remote_devkey_client(&srv, node);
1237 	}
1238 
1239 	LOG_INF("Testing Composition Data refresh...");
1240 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
1241 		LOG_INF("Changing Composition Data #%d...\n", i);
1242 		reprovision_remote_comp_data_client(&srv, node, &dev_comp);
1243 	}
1244 
1245 	LOG_INF("Testing address refresh...");
1246 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
1247 		LOG_INF("Changing address #%d...\n", i);
1248 		reprovision_remote_address_client(&srv, node);
1249 	}
1250 
1251 	PASS();
1252 }
1253 
1254 /** @brief A device running a Remote Provisioning server that is used to provision unprovisioned
1255  * devices over PB-Remote. Always starts unprovisioned.
1256  */
test_device_pb_remote_server_unproved(void)1257 static void test_device_pb_remote_server_unproved(void)
1258 {
1259 	device_pb_remote_server_setup_unproved(&rpr_srv_comp, &comp_p2_1);
1260 
1261 	PASS();
1262 }
1263 
1264 /** @brief A device running a Remote Provisioning server that is used to provision unprovisioned
1265  * devices over PB-Remote. Always starts unprovisioned. Stops being responsive after receives
1266  * Remote Provisioning PDU Send message from RPR Client
1267  */
test_device_pb_remote_server_unproved_unresponsive(void)1268 static void test_device_pb_remote_server_unproved_unresponsive(void)
1269 {
1270 	device_pb_remote_server_setup_unproved(&rpr_srv_comp_unresponsive, NULL);
1271 
1272 	k_sem_init(&pdu_send_sem, 0, 1);
1273 	ASSERT_OK(k_sem_take(&pdu_send_sem, K_SECONDS(200)));
1274 
1275 	PASS();
1276 }
1277 
1278 /** @brief A device running a Remote Provisioning server that is used to provision unprovisioned
1279  * devices over PB-Remote. Starts provisioned.
1280  */
test_device_pb_remote_server_proved(void)1281 static void test_device_pb_remote_server_proved(void)
1282 {
1283 	device_pb_remote_server_setup_proved(&rpr_srv_comp, &comp_p2_1);
1284 
1285 	PASS();
1286 }
1287 
reprovision_remote_devkey_server(const uint16_t initial_addr)1288 static void reprovision_remote_devkey_server(const uint16_t initial_addr)
1289 {
1290 	uint8_t prev_dev_key[16];
1291 	uint8_t dev_key[16];
1292 
1293 	ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
1294 
1295 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
1296 	ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr());
1297 
1298 	/* Let Configuration Client activate the new Device Key and verify that it has
1299 	 * been changed.
1300 	 */
1301 	k_sleep(K_SECONDS(2));
1302 	ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
1303 	ASSERT_TRUE(memcmp(&prev_dev_key, dev_key, sizeof(dev_key)));
1304 }
1305 
reprovision_remote_comp_data_server(const uint16_t initial_addr)1306 static void reprovision_remote_comp_data_server(const uint16_t initial_addr)
1307 {
1308 	u_int8_t prev_dev_key[16];
1309 	u_int8_t dev_key[16];
1310 
1311 	/* The RPR Server won't let to run Node Composition Refresh procedure without first
1312 	 * setting the BT_MESH_COMP_DIRTY flag. The flag is set on a boot if there is a
1313 	 * "bt/mesh/cmp" entry in settings. The entry is added by the
1314 	 * `bt_mesh_comp_change_prepare() call. The test suite is not compiled
1315 	 * with CONFIG_BT_SETTINGS, so the flag will never be set. Since the purpose of the
1316 	 * test is to check RPR Server behavior, but not the actual swap of the Composition
1317 	 * Data, the flag is toggled directly from the test.
1318 	 */
1319 	atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
1320 	ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
1321 
1322 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
1323 
1324 	/* Drop the flag manually as CONFIG_BT_SETTINGS is not enabled. */
1325 	atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
1326 
1327 	ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr());
1328 
1329 	/* Let Configuration Client activate the new Device Key and verify that it has
1330 	 * been changed.
1331 	 */
1332 	k_sleep(K_SECONDS(2));
1333 	ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
1334 	ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
1335 }
1336 
reprovision_remote_address_server(const uint16_t initial_addr)1337 static void reprovision_remote_address_server(const uint16_t initial_addr)
1338 {
1339 	uint8_t prev_dev_key[16];
1340 	uint8_t dev_key[16];
1341 
1342 	ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
1343 
1344 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
1345 	ASSERT_EQUAL(initial_addr + 1, bt_mesh_primary_addr());
1346 
1347 	/* Let Configuration Client activate the new Device Key and verify that it has
1348 	 * been changed.
1349 	 */
1350 	k_sleep(K_SECONDS(2));
1351 	ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
1352 	ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
1353 }
1354 
1355 /** @brief Verify robustness of NPPI procedures on a RPR Server by running Device Key Refresh,
1356  * Node Composition Refresh and Node Address Refresh procedures multiple times each.
1357  */
test_device_pb_remote_server_nppi_robustness(void)1358 static void test_device_pb_remote_server_nppi_robustness(void)
1359 {
1360 	k_sem_init(&prov_sem, 0, 1);
1361 	k_sem_init(&reprov_sem, 0, 1);
1362 
1363 	bt_mesh_device_setup(&prov, &rpr_srv_comp);
1364 
1365 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
1366 
1367 	LOG_INF("Mesh initialized\n");
1368 
1369 	ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
1370 	const uint16_t initial_addr = bt_mesh_primary_addr();
1371 
1372 	LOG_INF("Enabling PB-Remote server");
1373 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
1374 
1375 	/* Test Device Key Refresh procedure robustness. */
1376 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
1377 		LOG_INF("Devkey refresh loop #%d, waiting for being reprov ...\n", i);
1378 		reprovision_remote_devkey_server(initial_addr);
1379 	}
1380 
1381 	/* Test Node Composition Refresh procedure robustness. */
1382 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
1383 		LOG_INF("Composition data refresh loop #%d, waiting for being reprov ...\n", i);
1384 		reprovision_remote_comp_data_server(initial_addr);
1385 	}
1386 
1387 	/* Node Address Refresh robustness. */
1388 	for (int i = 0; i < PROV_REPROV_COUNT; i++) {
1389 		LOG_INF("Address refresh loop #%d, waiting for being reprov ...\n", i);
1390 		reprovision_remote_address_server(initial_addr+i);
1391 	}
1392 
1393 	PASS();
1394 }
1395 
1396 /** @brief Test Node Composition Refresh procedure on Remote Provisioning client:
1397  * - provision a device over PB-Adv,
1398  * - provision a remote device over PB-Remote.
1399  */
test_provisioner_pb_remote_client_ncrp_provision(void)1400 static void test_provisioner_pb_remote_client_ncrp_provision(void)
1401 {
1402 	uint16_t pb_remote_server_addr;
1403 	uint8_t status;
1404 
1405 	provisioner_pb_remote_client_setup();
1406 
1407 	/* Provision the 2nd device over PB-Adv. */
1408 	ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
1409 
1410 	/* Provision the 3rd device over PB-Remote. */
1411 	struct bt_mesh_rpr_node srv = {
1412 		.addr = pb_remote_server_addr,
1413 		.net_idx = 0,
1414 		.ttl = 3,
1415 	};
1416 
1417 	ASSERT_OK(provision_remote(&srv, 2, &srv.addr));
1418 
1419 	/* Check device key by adding appkey. */
1420 	ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, pb_remote_server_addr, 0, 0, test_app_key,
1421 					      &status));
1422 	ASSERT_OK(status);
1423 
1424 	PASS();
1425 }
1426 
1427 /** @brief A device running a Remote Provisioning client and server that is used to reprovision
1428  * another device and it self with the client.
1429  */
test_device_pb_remote_client_server_same_dev(void)1430 static void test_device_pb_remote_client_server_same_dev(void)
1431 {
1432 	NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX);
1433 	uint8_t status;
1434 	struct bt_mesh_cdb_node *node;
1435 	uint8_t page;
1436 	uint8_t prev_dev_key[16];
1437 	uint16_t test_vector[] = { 0x0002, 0x0001 };
1438 
1439 	k_sem_init(&prov_sem, 0, 1);
1440 	k_sem_init(&reprov_sem, 0, 1);
1441 
1442 	bt_mesh_device_setup(&prov, &rpr_cli_srv_comp);
1443 
1444 	ASSERT_OK(bt_mesh_cdb_create(test_net_key));
1445 	ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
1446 
1447 	LOG_INF("Enabling PB-Remote server");
1448 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
1449 
1450 	/* Provision a remote device with RPR Client and Server with local RPR Server. */
1451 	current_dev_addr = 0x0001;
1452 	struct bt_mesh_rpr_node srv = {
1453 		.addr = current_dev_addr,
1454 		.net_idx = 0,
1455 		.ttl = 3,
1456 	};
1457 
1458 	LOG_INF("Provisioner prov, waiting for prov ...\n");
1459 	ASSERT_OK(provision_remote(&srv, 1, &srv.addr));
1460 
1461 	ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
1462 
1463 	/* Check device key by adding bt_mesh_reprovision_remote appkey. */
1464 	ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, &status));
1465 	ASSERT_OK(status);
1466 
1467 	/* Swap callback to catch when device reprovisioned. */
1468 	prov.node_added = prov_node_added_rpr;
1469 
1470 	/* Reprovision a device with both RPR Client and Server. */
1471 	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
1472 		current_dev_addr = test_vector[i];
1473 		srv.addr = current_dev_addr;
1474 		bool self_reprov = (bool)(current_dev_addr == bt_mesh_primary_addr());
1475 
1476 		/* Store initial Composition Data Page 0. */
1477 		net_buf_simple_reset(&dev_comp);
1478 		ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, &dev_comp));
1479 
1480 		node = bt_mesh_cdb_node_get(current_dev_addr);
1481 		ASSERT_TRUE(node);
1482 
1483 		LOG_INF("Refreshing 0x%04x device key ...\n", srv.addr);
1484 		ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
1485 		reprovision_remote_devkey_client(&srv, node);
1486 		if (self_reprov) {
1487 			uint8_t dev_key[16];
1488 
1489 			ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr());
1490 
1491 			/* Let Configuration Client activate the new Device Key
1492 			 * and verify that it has been changed.
1493 			 */
1494 			ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
1495 			ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
1496 		}
1497 
1498 		LOG_INF("Changing 0x%04x Composition Data ...\n", srv.addr);
1499 		ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
1500 		reprovision_remote_comp_data_client(&srv, node, &dev_comp);
1501 		if (self_reprov) {
1502 			uint8_t dev_key[16];
1503 
1504 			ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr());
1505 
1506 			/* Let Configuration Client activate the new Device Key
1507 			 * and verify that it has been changed.
1508 			 */
1509 			ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
1510 			ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(struct bt_mesh_key)));
1511 		}
1512 
1513 		LOG_INF("Changing 0x%04x address ...\n", srv.addr);
1514 		ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
1515 		reprovision_remote_address_client(&srv, node);
1516 		if (self_reprov) {
1517 			uint8_t dev_key[16];
1518 
1519 			ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr());
1520 
1521 			/* Let Configuration Client activate the new Device Key
1522 			 * and verify that it has been changed.
1523 			 */
1524 			ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
1525 			ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
1526 		}
1527 	}
1528 
1529 	PASS();
1530 }
1531 
1532 /** @brief Verify that the Remote Provisioning client and server is able to be reprovision
1533  * by another device with a Remote Provisioning client and server.
1534  */
test_device_pb_remote_server_same_dev(void)1535 static void test_device_pb_remote_server_same_dev(void)
1536 {
1537 	k_sem_init(&prov_sem, 0, 1);
1538 	k_sem_init(&reprov_sem, 0, 1);
1539 
1540 	bt_mesh_device_setup(&prov, &rpr_cli_srv_comp);
1541 
1542 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
1543 
1544 	LOG_INF("Waiting for being provisioned...");
1545 	ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
1546 
1547 	LOG_INF("Enabling PB-Remote server");
1548 	ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
1549 
1550 	/* Swap callback to catch when device reprovisioned. */
1551 	prov.node_added = prov_node_added_rpr;
1552 
1553 	const uint16_t initial_addr = bt_mesh_primary_addr();
1554 
1555 	LOG_INF("Devkey refresh, waiting for being reprov ...\n");
1556 	reprovision_remote_devkey_server(initial_addr);
1557 
1558 	LOG_INF("Composition data refresh, waiting for being reprov ...\n");
1559 	reprovision_remote_comp_data_server(initial_addr);
1560 
1561 	LOG_INF("Address refresh, waiting for being reprov ...\n");
1562 	reprovision_remote_address_server(initial_addr);
1563 
1564 	PASS();
1565 }
1566 
comp_data_get(uint16_t server_addr,uint8_t page,struct net_buf_simple * comp)1567 static void comp_data_get(uint16_t server_addr, uint8_t page, struct net_buf_simple *comp)
1568 {
1569 	uint8_t page_rsp;
1570 
1571 	/* Let complete advertising of the transaction to prevent collisions. */
1572 	k_sleep(K_SECONDS(3));
1573 
1574 	net_buf_simple_reset(comp);
1575 	ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, server_addr, page, &page_rsp, comp));
1576 	ASSERT_EQUAL(page, page_rsp);
1577 }
1578 
comp_data_compare(struct net_buf_simple * comp1,struct net_buf_simple * comp2,bool expect_equal)1579 static void comp_data_compare(struct net_buf_simple *comp1, struct net_buf_simple *comp2,
1580 			      bool expect_equal)
1581 {
1582 	if (expect_equal) {
1583 		ASSERT_EQUAL(comp1->len, comp2->len);
1584 		if (memcmp(comp1->data, comp2->data, comp1->len)) {
1585 			FAIL("Composition data is not equal");
1586 		}
1587 	} else {
1588 		if (comp1->len == comp2->len) {
1589 			if (!memcmp(comp1->data, comp2->data, comp1->len)) {
1590 				FAIL("Composition data is equal");
1591 			}
1592 		}
1593 	}
1594 }
1595 
1596 /** @brief Test Node Composition Refresh procedure on Remote Provisioning client:
1597  * - initiate Node Composition Refresh procedure on a 3rd device.
1598  */
test_provisioner_pb_remote_client_ncrp(void)1599 static void test_provisioner_pb_remote_client_ncrp(void)
1600 {
1601 	NET_BUF_SIMPLE_DEFINE(dev_comp_p0, BT_MESH_RX_SDU_MAX);
1602 	NET_BUF_SIMPLE_DEFINE(dev_comp_p1, BT_MESH_RX_SDU_MAX);
1603 	NET_BUF_SIMPLE_DEFINE(dev_comp_p2, BT_MESH_RX_SDU_MAX);
1604 	NET_BUF_SIMPLE_DEFINE(dev_comp_p128, BT_MESH_RX_SDU_MAX);
1605 	NET_BUF_SIMPLE_DEFINE(dev_comp_p129, BT_MESH_RX_SDU_MAX);
1606 	NET_BUF_SIMPLE_DEFINE(dev_comp_p130, BT_MESH_RX_SDU_MAX);
1607 
1608 	uint16_t pb_remote_server_addr = 0x0003;
1609 
1610 	k_sem_init(&prov_sem, 0, 1);
1611 	k_sem_init(&reprov_sem, 0, 1);
1612 
1613 	bt_mesh_device_setup(&prov, &rpr_cli_comp);
1614 
1615 	/* Store Composition Data Page 0, 1, 2, 128, 129 and 130. */
1616 	comp_data_get(pb_remote_server_addr, 0, &dev_comp_p0);
1617 	comp_data_get(pb_remote_server_addr, 128, &dev_comp_p128);
1618 	comp_data_compare(&dev_comp_p0, &dev_comp_p128, false);
1619 
1620 	comp_data_get(pb_remote_server_addr, 1, &dev_comp_p1);
1621 	comp_data_get(pb_remote_server_addr, 129, &dev_comp_p129);
1622 	comp_data_compare(&dev_comp_p1, &dev_comp_p129, false);
1623 
1624 	comp_data_get(pb_remote_server_addr, 2, &dev_comp_p2);
1625 	comp_data_get(pb_remote_server_addr, 130, &dev_comp_p130);
1626 	comp_data_compare(&dev_comp_p2, &dev_comp_p130, false);
1627 
1628 
1629 	LOG_INF("Start Node Composition Refresh procedure...\n");
1630 	struct bt_mesh_rpr_node srv = {
1631 		.addr = pb_remote_server_addr,
1632 		.net_idx = 0,
1633 		.ttl = 3,
1634 	};
1635 
1636 	/* Swap callback to catch when device reprovisioned. */
1637 	prov.node_added = prov_node_added_rpr;
1638 
1639 	ASSERT_OK(bt_mesh_reprovision_remote(&rpr_cli, &srv, pb_remote_server_addr, true));
1640 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
1641 
1642 	/* Check that Composition Data Page 128 still exists and is now equal to Page 0. */
1643 	comp_data_get(pb_remote_server_addr, 0, &dev_comp_p0);
1644 	comp_data_compare(&dev_comp_p0, &dev_comp_p128, true);
1645 	comp_data_get(pb_remote_server_addr, 128, &dev_comp_p128);
1646 	comp_data_compare(&dev_comp_p0, &dev_comp_p128, true);
1647 
1648 	/* Check that Composition Data Page 129 still exists and is now equal to Page 1. */
1649 	comp_data_get(pb_remote_server_addr, 1, &dev_comp_p1);
1650 	comp_data_compare(&dev_comp_p1, &dev_comp_p129, true);
1651 	comp_data_get(pb_remote_server_addr, 129, &dev_comp_p129);
1652 	comp_data_compare(&dev_comp_p1, &dev_comp_p129, true);
1653 
1654 	/* Check that Composition Data Page 130 still exists and is now equal to Page 2. */
1655 	comp_data_get(pb_remote_server_addr, 2, &dev_comp_p2);
1656 	comp_data_compare(&dev_comp_p2, &dev_comp_p130, true);
1657 	comp_data_get(pb_remote_server_addr, 130, &dev_comp_p130);
1658 	comp_data_compare(&dev_comp_p2, &dev_comp_p130, true);
1659 
1660 	PASS();
1661 }
1662 
comp_data_pages_get_and_equal_check(uint16_t server_addr,uint8_t page1,uint8_t page2)1663 static void comp_data_pages_get_and_equal_check(uint16_t server_addr, uint8_t page1, uint8_t page2)
1664 {
1665 	NET_BUF_SIMPLE_DEFINE(comp_1, BT_MESH_RX_SDU_MAX);
1666 	NET_BUF_SIMPLE_DEFINE(comp_2, BT_MESH_RX_SDU_MAX);
1667 
1668 	comp_data_get(server_addr, page1, &comp_1);
1669 	comp_data_get(server_addr, page2, &comp_2);
1670 	comp_data_compare(&comp_1, &comp_2, true);
1671 }
1672 
1673 /** @brief Test Node Composition Refresh procedure on Remote Provisioning client:
1674  * - verify that Composition Data Page 0 is now equal to Page 128 after reboot.
1675  */
test_provisioner_pb_remote_client_ncrp_second_time(void)1676 static void test_provisioner_pb_remote_client_ncrp_second_time(void)
1677 {
1678 	uint16_t pb_remote_server_addr = 0x0003;
1679 	int err;
1680 
1681 	k_sem_init(&prov_sem, 0, 1);
1682 	k_sem_init(&reprov_sem, 0, 1);
1683 
1684 	bt_mesh_device_setup(&prov, &rpr_cli_comp);
1685 
1686 	comp_data_pages_get_and_equal_check(pb_remote_server_addr, 0, 128);
1687 	comp_data_pages_get_and_equal_check(pb_remote_server_addr, 1, 129);
1688 	comp_data_pages_get_and_equal_check(pb_remote_server_addr, 2, 130);
1689 
1690 	LOG_INF("Start Node Composition Refresh procedure...\n");
1691 	struct bt_mesh_rpr_node srv = {
1692 		.addr = pb_remote_server_addr,
1693 		.net_idx = 0,
1694 		.ttl = 3,
1695 	};
1696 
1697 	/* Swap callback to catch when device reprovisioned. */
1698 	prov.node_added = prov_node_added_rpr;
1699 
1700 	ASSERT_OK(bt_mesh_reprovision_remote(&rpr_cli, &srv, pb_remote_server_addr, true));
1701 	err = k_sem_take(&reprov_sem, K_SECONDS(20));
1702 	ASSERT_EQUAL(-EAGAIN, err);
1703 
1704 	PASS();
1705 }
1706 
1707 /** @brief Test Node Composition Refresh procedure on Remote Provisioning server:
1708  * - wait for being provisioned over PB-Adv,
1709  * - prepare Composition Data Page 128.
1710  */
test_device_pb_remote_server_ncrp_prepare(void)1711 static void test_device_pb_remote_server_ncrp_prepare(void)
1712 {
1713 	device_pb_remote_server_setup_unproved(&rpr_srv_comp, &comp_p2_1);
1714 
1715 	LOG_INF("Preparing for Composition Data change");
1716 	bt_mesh_comp_change_prepare();
1717 
1718 	PASS();
1719 }
1720 
1721 /** @brief Test Node Composition Refresh procedure on Remote Provisioning server:
1722  * - start device with new Composition Data
1723  * - wait for being re-provisioned.
1724  */
test_device_pb_remote_server_ncrp(void)1725 static void test_device_pb_remote_server_ncrp(void)
1726 {
1727 	device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem, &comp_p2_2);
1728 
1729 	LOG_INF("Waiting for being re-provisioned.");
1730 	ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
1731 
1732 	PASS();
1733 }
1734 
1735 /** @brief Test Node Composition Refresh procedure on Remote Provisioning server:
1736  * - verify that Composition Data Page 0 is replaced by Page 128 after being re-provisioned and
1737  *   rebooted.
1738  */
test_device_pb_remote_server_ncrp_second_time(void)1739 static void test_device_pb_remote_server_ncrp_second_time(void)
1740 {
1741 	int err;
1742 
1743 	device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem, &comp_p2_2);
1744 
1745 	LOG_INF("Wait to verify that node is not re-provisioned...");
1746 	err = k_sem_take(&reprov_sem, K_SECONDS(30));
1747 	ASSERT_EQUAL(-EAGAIN, err);
1748 
1749 	PASS();
1750 }
1751 #endif /* IS_RPR_PRESENT */
1752 
1753 #define TEST_CASE(role, name, description)                                     \
1754 	{                                                                      \
1755 		.test_id = "prov_" #role "_" #name, .test_descr = description, \
1756 		.test_post_init_f = test_##role##_init,                        \
1757 		.test_tick_f = bt_mesh_test_timeout,                           \
1758 		.test_main_f = test_##role##_##name,                           \
1759 		.test_delete_f = test_terminate                                \
1760 	}
1761 #define TEST_CASE_WBACKCHANNEL(role, name, description)                                     \
1762 	{                                                                      \
1763 		.test_id = "prov_" #role "_" #name, .test_descr = description, \
1764 		.test_post_init_f = test_##role##_init,                        \
1765 		.test_pre_init_f = test_back_channel_pre_init,                 \
1766 		.test_tick_f = bt_mesh_test_timeout,                           \
1767 		.test_main_f = test_##role##_##name,                           \
1768 		.test_delete_f = test_terminate                                \
1769 	}
1770 
1771 static const struct bst_test_instance test_connect[] = {
1772 	TEST_CASE(device, pb_adv_no_oob,
1773 		  "Device: pb-adv provisioning use no-oob method"),
1774 	TEST_CASE_WBACKCHANNEL(device, pb_adv_oob_auth,
1775 		  "Device: pb-adv provisioning use oob authentication"),
1776 	TEST_CASE_WBACKCHANNEL(device, pb_adv_oob_public_key,
1777 		  "Device: pb-adv provisioning use oob public key"),
1778 	TEST_CASE(device, pb_adv_reprovision,
1779 		  "Device: pb-adv provisioning, reprovision"),
1780 	TEST_CASE(device, unresponsive,
1781 		  "Device: pb-adv provisioning, stops and resumes responding to provisioning"),
1782 #if IS_RPR_PRESENT
1783 	TEST_CASE(device, pb_remote_server_unproved,
1784 		  "Device: used for remote provisioning, starts unprovisioned"),
1785 	TEST_CASE(device, pb_remote_server_nppi_robustness,
1786 		  "Device: pb-remote reprovisioning, NPPI robustness"),
1787 	TEST_CASE(device, pb_remote_server_unproved_unresponsive,
1788 		  "Device: used for remote provisioning, starts unprovisioned, stops responding"),
1789 	TEST_CASE(device, pb_remote_client_server_same_dev,
1790 		  "Device: used for remote provisioning, with both client and server"),
1791 	TEST_CASE(device, pb_remote_server_same_dev,
1792 		  "Device: used for remote reprovisioning, with both client and server"),
1793 #endif
1794 
1795 	TEST_CASE(provisioner, pb_adv_no_oob,
1796 		  "Provisioner: pb-adv provisioning use no-oob method"),
1797 	TEST_CASE(provisioner, pb_adv_multi,
1798 		  "Provisioner: pb-adv provisioning multiple devices"),
1799 	TEST_CASE(provisioner, iv_update_flag_zero,
1800 		  "Provisioner: effect on ivu_duration when IV Update flag is set to zero"),
1801 	TEST_CASE(provisioner, iv_update_flag_one,
1802 		  "Provisioner: effect on ivu_duration when IV Update flag is set to one"),
1803 	TEST_CASE_WBACKCHANNEL(provisioner, pb_adv_oob_auth,
1804 		  "Provisioner: pb-adv provisioning use oob authentication"),
1805 	TEST_CASE_WBACKCHANNEL(provisioner, pb_adv_oob_public_key,
1806 		  "Provisioner: pb-adv provisioning use oob public key"),
1807 	TEST_CASE_WBACKCHANNEL(provisioner, pb_adv_oob_auth_no_oob_public_key,
1808 		"Provisioner: pb-adv provisioning use oob authentication, ignore oob public key"),
1809 	TEST_CASE(provisioner, pb_adv_reprovision,
1810 		  "Provisioner: pb-adv provisioning, resetting and reprovisioning multiple times."),
1811 #if IS_RPR_PRESENT
1812 	TEST_CASE(provisioner, pb_remote_client_reprovision,
1813 		  "Provisioner: pb-remote provisioning, resetting and reprov-ing multiple times."),
1814 	TEST_CASE(provisioner, pb_remote_client_nppi_robustness,
1815 		  "Provisioner: pb-remote provisioning, NPPI robustness."),
1816 	TEST_CASE(provisioner, pb_remote_client_parallel,
1817 		  "Provisioner: pb-remote provisioning, parallel scanning and provisioning."),
1818 	TEST_CASE(provisioner, pb_remote_client_provision_timeout,
1819 		  "Provisioner: provisioning test, devices stop responding"),
1820 #endif
1821 
1822 	BSTEST_END_MARKER
1823 };
1824 
test_provision_install(struct bst_test_list * tests)1825 struct bst_test_list *test_provision_install(struct bst_test_list *tests)
1826 {
1827 	tests = bst_add_tests(tests, test_connect);
1828 	return tests;
1829 }
1830 
1831 #if IS_RPR_PRESENT
1832 static const struct bst_test_instance test_connect_pst[] = {
1833 	TEST_CASE(device, pb_remote_server_unproved,
1834 		  "Device: used for remote provisioning, starts unprovisioned"),
1835 	TEST_CASE(device, pb_remote_server_proved,
1836 		  "Device: used for remote provisioning, starts provisioned"),
1837 
1838 	TEST_CASE(device, pb_remote_server_ncrp_prepare,
1839 		  "Device: NCRP test, prepares for Composition Data change."),
1840 	TEST_CASE(device, pb_remote_server_ncrp,
1841 		  "Device: NCRP test, Composition Data change."),
1842 	TEST_CASE(device, pb_remote_server_ncrp_second_time,
1843 		  "Device: NCRP test, Composition Data change after reboot."),
1844 
1845 	TEST_CASE(provisioner, pb_remote_client_ncrp_provision,
1846 		  "Provisioner: NCRP test, devices provisioning."),
1847 	TEST_CASE(provisioner, pb_remote_client_ncrp,
1848 		  "Provisioner: NCRP test, initiates Node Composition Refresh procedure."),
1849 	TEST_CASE(provisioner, pb_remote_client_ncrp_second_time,
1850 		  "Provisioner: NCRP test, initiates NCR procedure the second time."),
1851 
1852 	BSTEST_END_MARKER
1853 };
1854 
test_provision_pst_install(struct bst_test_list * tests)1855 struct bst_test_list *test_provision_pst_install(struct bst_test_list *tests)
1856 {
1857 	tests = bst_add_tests(tests, test_connect_pst);
1858 	return tests;
1859 }
1860 #endif /* IS_RPR_PRESENT */
1861