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