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