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