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