1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/bluetooth/bluetooth.h>
8
9 #include <assert.h>
10 #include <errno.h>
11 #include <zephyr/bluetooth/mesh.h>
12 #include <zephyr/bluetooth/mesh/cfg.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/settings/settings.h>
15 #include <app_keys.h>
16 #include <va.h>
17 #include <sar_cfg_internal.h>
18 #include <string.h>
19 #include "mesh/access.h"
20 #include "mesh/testing.h"
21
22 #include <zephyr/logging/log.h>
23 #define LOG_MODULE_NAME bttester_mesh
24 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
25
26 #include "btp/btp.h"
27 #include "dfu_slot.h"
28
29 #define CID_LOCAL 0x05F1
30 #define COMPANY_ID_LF 0x05F1
31 #define COMPANY_ID_NORDIC_SEMI 0x05F9
32
33 /* Health server data */
34 #define CUR_FAULTS_MAX 4
35 #define HEALTH_TEST_ID 0x00
36
37 static uint8_t cur_faults[CUR_FAULTS_MAX];
38 static uint8_t reg_faults[CUR_FAULTS_MAX * 2];
39
40 /* Provision node data */
41 static uint8_t net_key[16];
42 static uint16_t net_key_idx;
43 static uint8_t flags;
44 static uint32_t iv_index;
45 static uint16_t addr;
46 static uint8_t dev_key[16];
47 static uint8_t input_size;
48 static uint8_t pub_key[64];
49 static uint8_t priv_key[32];
50
51 /* Configured provisioning data */
52 static uint8_t dev_uuid[16];
53 static uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN];
54 static uint8_t static_auth_size;
55
56 /* Vendor Model data */
57 #define VND_MODEL_ID_1 0x1234
58 static uint8_t vnd_app_key[16];
59 static uint16_t vnd_app_key_idx = 0x000f;
60
61 /* Model send data */
62 #define MODEL_BOUNDS_MAX 100
63
64 #if defined(CONFIG_BT_MESH_BLOB_SRV) || defined(CONFIG_BT_MESH_BLOB_CLI)
65 /* BLOB Model data*/
66 static uint8_t blob_rx_sum;
67 static bool blob_valid;
68 static const char *blob_data = "11111111111111111111111111111111";
69
blob_io_open(const struct bt_mesh_blob_io * io,const struct bt_mesh_blob_xfer * xfer,enum bt_mesh_blob_io_mode mode)70 static int blob_io_open(const struct bt_mesh_blob_io *io,
71 const struct bt_mesh_blob_xfer *xfer,
72 enum bt_mesh_blob_io_mode mode)
73 {
74 blob_rx_sum = 0;
75 blob_valid = true;
76 return 0;
77 }
78
blob_chunk_wr(const struct bt_mesh_blob_io * io,const struct bt_mesh_blob_xfer * xfer,const struct bt_mesh_blob_block * block,const struct bt_mesh_blob_chunk * chunk)79 static int blob_chunk_wr(const struct bt_mesh_blob_io *io,
80 const struct bt_mesh_blob_xfer *xfer,
81 const struct bt_mesh_blob_block *block,
82 const struct bt_mesh_blob_chunk *chunk)
83 {
84 for (int i = 0; i < chunk->size; ++i) {
85 blob_rx_sum += chunk->data[i];
86 if (chunk->data[i] !=
87 blob_data[(i + chunk->offset) % strlen(blob_data)]) {
88 blob_valid = false;
89 }
90 }
91
92 return 0;
93 }
94
blob_chunk_rd(const struct bt_mesh_blob_io * io,const struct bt_mesh_blob_xfer * xfer,const struct bt_mesh_blob_block * block,const struct bt_mesh_blob_chunk * chunk)95 static int blob_chunk_rd(const struct bt_mesh_blob_io *io,
96 const struct bt_mesh_blob_xfer *xfer,
97 const struct bt_mesh_blob_block *block,
98 const struct bt_mesh_blob_chunk *chunk)
99 {
100 for (int i = 0; i < chunk->size; ++i) {
101 chunk->data[i] =
102 blob_data[(i + chunk->offset) % strlen(blob_data)];
103 }
104
105 return 0;
106 }
107
108 static const struct bt_mesh_blob_io dummy_blob_io = {
109 .open = blob_io_open,
110 .rd = blob_chunk_rd,
111 .wr = blob_chunk_wr,
112 };
113 #endif
114
115 #if defined(CONFIG_BT_MESH_DFD_SRV)
116 static const struct bt_mesh_dfu_slot *dfu_self_update_slot;
117
is_self_update(struct bt_mesh_dfd_srv * srv)118 static bool is_self_update(struct bt_mesh_dfd_srv *srv)
119 {
120 for (int i = 0; i < ARRAY_SIZE(srv->targets); i++) {
121 if (bt_mesh_has_addr(srv->targets[i].blob.addr)) {
122 return true;
123 }
124 }
125
126 return false;
127 }
128
129 /* DFD Model data*/
dfd_srv_recv(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot,const struct bt_mesh_blob_io ** io)130 static int dfd_srv_recv(struct bt_mesh_dfd_srv *srv,
131 const struct bt_mesh_dfu_slot *slot,
132 const struct bt_mesh_blob_io **io)
133 {
134 LOG_DBG("Uploading new firmware image to the distributor.");
135
136 *io = &dummy_blob_io;
137
138 return 0;
139 }
140
dfd_srv_del(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot)141 static void dfd_srv_del(struct bt_mesh_dfd_srv *srv,
142 const struct bt_mesh_dfu_slot *slot)
143 {
144 LOG_DBG("Deleting the firmware image from the distributor.");
145 }
146
dfd_srv_send(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot,const struct bt_mesh_blob_io ** io)147 static int dfd_srv_send(struct bt_mesh_dfd_srv *srv,
148 const struct bt_mesh_dfu_slot *slot,
149 const struct bt_mesh_blob_io **io)
150 {
151 LOG_DBG("Starting the firmware distribution.");
152
153 *io = &dummy_blob_io;
154
155 dfu_self_update_slot = NULL;
156
157 if (is_self_update(srv)) {
158 LOG_DBG("DFD server starts self-update...");
159 dfu_self_update_slot = slot;
160 }
161
162 return 0;
163 }
164
165 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
166 static struct {
167 uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN];
168 uint8_t uri_len;
169 uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
170 uint8_t fwid_len;
171 const struct bt_mesh_dfu_slot *slot;
172 uint8_t progress;
173 bool started;
174 } dfd_srv_oob_ctx;
175
176 static void oob_check_handler(struct k_work *work);
177 static K_WORK_DEFINE(oob_check, oob_check_handler);
178 static void oob_store_handler(struct k_work *work);
179 static K_WORK_DEFINE(oob_store, oob_store_handler);
180
dfd_srv_start_oob_upload(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot,const char * uri,uint8_t uri_len,const uint8_t * fwid,uint16_t fwid_len)181 static int dfd_srv_start_oob_upload(struct bt_mesh_dfd_srv *srv,
182 const struct bt_mesh_dfu_slot *slot,
183 const char *uri, uint8_t uri_len,
184 const uint8_t *fwid, uint16_t fwid_len)
185 {
186 LOG_DBG("Start OOB Upload");
187
188 memcpy(dfd_srv_oob_ctx.uri, uri, uri_len);
189 dfd_srv_oob_ctx.uri_len = uri_len;
190 memcpy(dfd_srv_oob_ctx.fwid, fwid, fwid_len);
191 dfd_srv_oob_ctx.fwid_len = fwid_len;
192 dfd_srv_oob_ctx.slot = slot;
193 dfd_srv_oob_ctx.progress = 0;
194 dfd_srv_oob_ctx.started = true;
195
196 k_work_submit(&oob_check);
197
198 return BT_MESH_DFD_SUCCESS;
199 }
200
dfd_srv_cancel_oob_upload(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot)201 static void dfd_srv_cancel_oob_upload(struct bt_mesh_dfd_srv *srv,
202 const struct bt_mesh_dfu_slot *slot)
203 {
204 LOG_DBG("Cancel OOB Upload");
205
206 dfd_srv_oob_ctx.started = false;
207 }
208
dfd_srv_oob_progress_get(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot)209 static uint8_t dfd_srv_oob_progress_get(struct bt_mesh_dfd_srv *srv,
210 const struct bt_mesh_dfu_slot *slot)
211 {
212 uint8_t progress;
213
214 if (dfd_srv_oob_ctx.started) {
215 progress = dfd_srv_oob_ctx.progress;
216
217 dfd_srv_oob_ctx.progress = MIN(dfd_srv_oob_ctx.progress + 25, 99);
218
219 if (dfd_srv_oob_ctx.progress == 99) {
220 k_work_submit(&oob_store);
221 }
222 } else {
223 progress = 0;
224 }
225
226 LOG_DBG("OOB Progress Get (%sstarted: %d %%)", dfd_srv_oob_ctx.started ? "" : "not ",
227 progress);
228 return progress;
229 }
230 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
231
232 static struct bt_mesh_dfd_srv_cb dfd_srv_cb = {
233 .recv = dfd_srv_recv,
234 .del = dfd_srv_del,
235 .send = dfd_srv_send,
236 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
237 .start_oob_upload = dfd_srv_start_oob_upload,
238 .cancel_oob_upload = dfd_srv_cancel_oob_upload,
239 .oob_progress_get = dfd_srv_oob_progress_get,
240 #endif
241 };
242
243 static struct bt_mesh_dfd_srv dfd_srv = BT_MESH_DFD_SRV_INIT(&dfd_srv_cb);
244
245 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
246 #define SUPPORTED_SCHEME "http"
247
oob_check_handler(struct k_work * work)248 static void oob_check_handler(struct k_work *work)
249 {
250 uint8_t scheme[10];
251 int i;
252 int status;
253 int err;
254
255 for (i = 0; i < MIN(dfd_srv_oob_ctx.uri_len, sizeof(scheme)); i++) {
256 if (IN_RANGE(dfd_srv_oob_ctx.uri[i], 48, 57) || /* DIGIT */
257 IN_RANGE(dfd_srv_oob_ctx.uri[i], 65, 90) || /* ALPHA UPPER CASE */
258 IN_RANGE(dfd_srv_oob_ctx.uri[i], 97, 122) || /* ALPHA LOWER CASE */
259 dfd_srv_oob_ctx.uri[i] == '.' ||
260 dfd_srv_oob_ctx.uri[i] == '+' ||
261 dfd_srv_oob_ctx.uri[i] == '-') {
262 scheme[i] = dfd_srv_oob_ctx.uri[i];
263 } else {
264 break;
265 }
266 }
267
268 if (i == dfd_srv_oob_ctx.uri_len || dfd_srv_oob_ctx.uri[i] != ':') {
269 status = BT_MESH_DFD_ERR_URI_MALFORMED;
270 } else if (i != strlen(SUPPORTED_SCHEME) ||
271 memcmp(scheme, SUPPORTED_SCHEME, strlen(SUPPORTED_SCHEME))) {
272 status = BT_MESH_DFD_ERR_URI_NOT_SUPPORTED;
273 } else {
274 status = BT_MESH_DFD_SUCCESS;
275 }
276
277 err = bt_mesh_dfd_srv_oob_check_complete(&dfd_srv, dfd_srv_oob_ctx.slot, status,
278 dfd_srv_oob_ctx.fwid, dfd_srv_oob_ctx.fwid_len);
279 LOG_DBG("OOB check completed (err %d)", err);
280 }
281
oob_store_handler(struct k_work * work)282 static void oob_store_handler(struct k_work *work)
283 {
284 int err;
285
286 err = bt_mesh_dfd_srv_oob_store_complete(&dfd_srv, dfd_srv_oob_ctx.slot, true,
287 10000, "metadata", 8);
288 LOG_DBG("OOB store completed (err %d)", err);
289 }
290 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
291 #endif
292
293 #if defined(CONFIG_BT_MESH_BLOB_CLI)
294 static struct {
295 struct bt_mesh_blob_cli_inputs inputs;
296 struct bt_mesh_blob_target targets[32];
297 struct bt_mesh_blob_target_pull pull[32];
298 uint8_t target_count;
299 struct bt_mesh_blob_xfer xfer;
300 } blob_cli_xfer;
301
blob_cli_lost_target(struct bt_mesh_blob_cli * cli,struct bt_mesh_blob_target * target,enum bt_mesh_blob_status reason)302 static void blob_cli_lost_target(struct bt_mesh_blob_cli *cli,
303 struct bt_mesh_blob_target *target,
304 enum bt_mesh_blob_status reason)
305 {
306 LOG_DBG("Mesh Blob: Lost target 0x%04x (reason: %u)", target->addr,
307 reason);
308 tester_event(BTP_SERVICE_ID_MESH, MESH_EV_BLOB_LOST_TARGET, NULL, 0);
309 }
310
blob_cli_caps(struct bt_mesh_blob_cli * cli,const struct bt_mesh_blob_cli_caps * caps)311 static void blob_cli_caps(struct bt_mesh_blob_cli *cli,
312 const struct bt_mesh_blob_cli_caps *caps)
313 {
314 const char *const modes[] = {
315 "none",
316 "push",
317 "pull",
318 "all",
319 };
320
321 if (!caps) {
322 LOG_DBG("None of the targets can be used for BLOB transfer");
323 return;
324 }
325
326 LOG_DBG("Mesh BLOB: capabilities:");
327 LOG_DBG("\tMax BLOB size: %u bytes", caps->max_size);
328 LOG_DBG("\tBlock size: %u-%u (%u-%u bytes)", caps->min_block_size_log,
329 caps->max_block_size_log, 1 << caps->min_block_size_log,
330 1 << caps->max_block_size_log);
331 LOG_DBG("\tMax chunks: %u", caps->max_chunks);
332 LOG_DBG("\tChunk size: %u", caps->max_chunk_size);
333 LOG_DBG("\tMTU size: %u", caps->mtu_size);
334 LOG_DBG("\tModes: %s", modes[caps->modes]);
335 }
336
blob_cli_end(struct bt_mesh_blob_cli * cli,const struct bt_mesh_blob_xfer * xfer,bool success)337 static void blob_cli_end(struct bt_mesh_blob_cli *cli,
338 const struct bt_mesh_blob_xfer *xfer, bool success)
339 {
340 if (success) {
341 LOG_DBG("Mesh BLOB transfer complete.");
342 } else {
343 LOG_DBG("Mesh BLOB transfer failed.");
344 }
345 }
346
347 static const struct bt_mesh_blob_cli_cb blob_cli_handlers = {
348 .lost_target = blob_cli_lost_target,
349 .caps = blob_cli_caps,
350 .end = blob_cli_end,
351 };
352
353 static struct bt_mesh_blob_cli blob_cli = { .cb = &blob_cli_handlers };
354 #endif
355
356 #if defined(CONFIG_BT_MESH_DFU_SRV)
357 const char *metadata_data = "1100000000000011";
358
359 static uint8_t dfu_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = {
360 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
361 };
362
363 static struct bt_mesh_dfu_img dfu_imgs[] = { {
364 .fwid = &dfu_fwid,
365 .fwid_len = sizeof(dfu_fwid),
366 } };
367
dfu_meta_check(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img,struct net_buf_simple * metadata,enum bt_mesh_dfu_effect * effect)368 static int dfu_meta_check(struct bt_mesh_dfu_srv *srv,
369 const struct bt_mesh_dfu_img *img,
370 struct net_buf_simple *metadata,
371 enum bt_mesh_dfu_effect *effect)
372 {
373 char string[2 * CONFIG_BT_MESH_DFU_METADATA_MAXLEN + 1];
374 int i;
375 size_t len;
376
377 len = bin2hex(metadata->data, metadata->len, string, sizeof(string));
378 string[len] = '\0';
379
380 for (i = 0; i <= len; i++) {
381 if (string[i] != metadata_data[i]) {
382 LOG_ERR("Wrong Firmware Metadata");
383 return -EINVAL;
384 }
385 }
386
387 return 0;
388 }
389
dfu_start(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img,struct net_buf_simple * metadata,const struct bt_mesh_blob_io ** io)390 static int dfu_start(struct bt_mesh_dfu_srv *srv,
391 const struct bt_mesh_dfu_img *img,
392 struct net_buf_simple *metadata,
393 const struct bt_mesh_blob_io **io)
394 {
395 LOG_DBG("DFU setup");
396
397 *io = &dummy_blob_io;
398
399 return 0;
400 }
401
dfu_end(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img,bool success)402 static void dfu_end(struct bt_mesh_dfu_srv *srv,
403 const struct bt_mesh_dfu_img *img, bool success)
404 {
405 if (!success) {
406 LOG_ERR("DFU failed");
407 return;
408 }
409
410 if (!blob_valid) {
411 bt_mesh_dfu_srv_rejected(srv);
412 return;
413 }
414
415 bt_mesh_dfu_srv_verified(srv);
416 }
417
dfu_apply(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img)418 static int dfu_apply(struct bt_mesh_dfu_srv *srv,
419 const struct bt_mesh_dfu_img *img)
420 {
421 if (!blob_valid) {
422 return -EINVAL;
423 }
424
425 LOG_DBG("Applying DFU transfer...");
426
427 #if defined(CONFIG_BT_MESH_DFD_SRV)
428 if (is_self_update(&dfd_srv) && dfu_self_update_slot != NULL) {
429 LOG_DBG("Swapping fwid for self-update");
430 /* Simulate self-update by swapping fwid. */
431 memcpy(&dfu_fwid[0], dfu_self_update_slot->fwid, dfu_self_update_slot->fwid_len);
432 dfu_imgs[0].fwid_len = dfu_self_update_slot->fwid_len;
433 }
434
435 #endif
436
437 return 0;
438 }
439
440 static const struct bt_mesh_dfu_srv_cb dfu_handlers = {
441 .check = dfu_meta_check,
442 .start = dfu_start,
443 .end = dfu_end,
444 .apply = dfu_apply,
445 };
446
447 static struct bt_mesh_dfu_srv dfu_srv =
448 BT_MESH_DFU_SRV_INIT(&dfu_handlers, dfu_imgs, ARRAY_SIZE(dfu_imgs));
449 #endif /* CONFIG_BT_MESH_DFU_SRV */
450
451 /* Model Authentication Method */
452 #define AUTH_METHOD_STATIC 0x01
453 #define AUTH_METHOD_OUTPUT 0x02
454 #define AUTH_METHOD_INPUT 0x03
455
456 static struct model_data {
457 const struct bt_mesh_model *model;
458 uint16_t addr;
459 uint16_t appkey_idx;
460 } model_bound[MODEL_BOUNDS_MAX];
461
462 static struct {
463 uint16_t local;
464 uint16_t dst;
465 uint16_t net_idx;
466 } net = {
467 .local = BT_MESH_ADDR_UNASSIGNED,
468 .dst = BT_MESH_ADDR_UNASSIGNED,
469 };
470
supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)471 static uint8_t supported_commands(const void *cmd, uint16_t cmd_len,
472 void *rsp, uint16_t *rsp_len)
473 {
474 struct btp_mesh_read_supported_commands_rp *rp = rsp;
475
476 /* octet 0 */
477 tester_set_bit(rp->data, BTP_MESH_READ_SUPPORTED_COMMANDS);
478 tester_set_bit(rp->data, BTP_MESH_CONFIG_PROVISIONING);
479 tester_set_bit(rp->data, BTP_MESH_PROVISION_NODE);
480 tester_set_bit(rp->data, BTP_MESH_INIT);
481 tester_set_bit(rp->data, BTP_MESH_RESET);
482 tester_set_bit(rp->data, BTP_MESH_INPUT_NUMBER);
483 tester_set_bit(rp->data, BTP_MESH_INPUT_STRING);
484
485 /* octet 1 */
486 tester_set_bit(rp->data, BTP_MESH_IVU_TEST_MODE);
487 tester_set_bit(rp->data, BTP_MESH_IVU_TOGGLE_STATE);
488 tester_set_bit(rp->data, BTP_MESH_NET_SEND);
489 tester_set_bit(rp->data, BTP_MESH_HEALTH_GENERATE_FAULTS);
490 tester_set_bit(rp->data, BTP_MESH_HEALTH_CLEAR_FAULTS);
491 tester_set_bit(rp->data, BTP_MESH_LPN);
492 tester_set_bit(rp->data, BTP_MESH_LPN_POLL);
493 tester_set_bit(rp->data, BTP_MESH_MODEL_SEND);
494
495 /* octet 2 */
496 #if defined(CONFIG_BT_TESTING)
497 tester_set_bit(rp->data, BTP_MESH_LPN_SUBSCRIBE);
498 tester_set_bit(rp->data, BTP_MESH_LPN_UNSUBSCRIBE);
499 tester_set_bit(rp->data, BTP_MESH_RPL_CLEAR);
500 #endif /* CONFIG_BT_TESTING */
501 tester_set_bit(rp->data, BTP_MESH_PROXY_IDENTITY);
502 tester_set_bit(rp->data, BTP_MESH_COMP_DATA_GET);
503 tester_set_bit(rp->data, BTP_MESH_CFG_BEACON_GET);
504 tester_set_bit(rp->data, BTP_MESH_CFG_BEACON_SET);
505
506 /* octet 3 */
507 tester_set_bit(rp->data, BTP_MESH_CFG_DEFAULT_TTL_GET);
508 tester_set_bit(rp->data, BTP_MESH_CFG_DEFAULT_TTL_SET);
509 tester_set_bit(rp->data, BTP_MESH_CFG_GATT_PROXY_GET);
510 tester_set_bit(rp->data, BTP_MESH_CFG_GATT_PROXY_SET);
511 tester_set_bit(rp->data, BTP_MESH_CFG_FRIEND_GET);
512 tester_set_bit(rp->data, BTP_MESH_CFG_FRIEND_SET);
513 tester_set_bit(rp->data, BTP_MESH_CFG_RELAY_GET);
514 tester_set_bit(rp->data, BTP_MESH_CFG_RELAY_SET);
515
516 /* octet 4 */
517 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_PUB_GET);
518 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_PUB_SET);
519 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_ADD);
520 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_DEL);
521 tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_ADD);
522 tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_GET);
523 tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_DEL);
524 tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_ADD);
525
526 /* octet 5 */
527 tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_DEL);
528 tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_GET);
529 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_BIND);
530 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_UNBIND);
531 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_GET);
532 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_VND_GET);
533 tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_PUB_SET);
534 tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_PUB_GET);
535
536 /* octet 6 */
537 tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_SUB_SET);
538 tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_SUB_GET);
539 tester_set_bit(rp->data, BTP_MESH_CFG_NET_TRANS_GET);
540 tester_set_bit(rp->data, BTP_MESH_CFG_NET_TRANS_SET);
541 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_OVW);
542 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_DEL_ALL);
543 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_GET);
544 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_GET_VND);
545
546 /* octet 7 */
547 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_VA_ADD);
548 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_VA_DEL);
549 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_VA_OVW);
550 tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_UPDATE);
551 tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_UPDATE);
552 tester_set_bit(rp->data, BTP_MESH_CFG_NODE_IDT_SET);
553 tester_set_bit(rp->data, BTP_MESH_CFG_NODE_IDT_GET);
554 tester_set_bit(rp->data, BTP_MESH_CFG_NODE_RESET);
555
556 /* octet 8 */
557 tester_set_bit(rp->data, BTP_MESH_CFG_LPN_TIMEOUT_GET);
558 tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_BIND_VND);
559 tester_set_bit(rp->data, BTP_MESH_HEALTH_FAULT_GET);
560 tester_set_bit(rp->data, BTP_MESH_HEALTH_FAULT_CLEAR);
561 tester_set_bit(rp->data, BTP_MESH_HEALTH_PERIOD_GET);
562 tester_set_bit(rp->data, BTP_MESH_HEALTH_PERIOD_SET);
563
564 /* octet 9 */
565 tester_set_bit(rp->data, BTP_MESH_HEALTH_ATTENTION_GET);
566 tester_set_bit(rp->data, BTP_MESH_HEALTH_ATTENTION_SET);
567 tester_set_bit(rp->data, BTP_MESH_PROVISION_ADV);
568 tester_set_bit(rp->data, BTP_MESH_CFG_KRP_GET);
569 tester_set_bit(rp->data, BTP_MESH_CFG_KRP_SET);
570 tester_set_bit(rp->data, BTP_MESH_VA_ADD);
571 tester_set_bit(rp->data, BTP_MESH_VA_DEL);
572
573 *rsp_len = sizeof(*rp) + 10;
574
575 return BTP_STATUS_SUCCESS;
576 }
577
get_faults(uint8_t * faults,uint8_t faults_size,uint8_t * dst,uint8_t * count)578 static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count)
579 {
580 uint8_t i, limit = *count;
581
582 for (i = 0U, *count = 0U; i < faults_size && *count < limit; i++) {
583 if (faults[i]) {
584 *dst++ = faults[i];
585 (*count)++;
586 }
587 }
588 }
589
fault_get_cur(const struct bt_mesh_model * model,uint8_t * test_id,uint16_t * company_id,uint8_t * faults,uint8_t * fault_count)590 static int fault_get_cur(const struct bt_mesh_model *model, uint8_t *test_id,
591 uint16_t *company_id, uint8_t *faults, uint8_t *fault_count)
592 {
593 LOG_DBG("");
594
595 *test_id = HEALTH_TEST_ID;
596 *company_id = CID_LOCAL;
597
598 get_faults(cur_faults, sizeof(cur_faults), faults, fault_count);
599
600 return 0;
601 }
602
fault_get_reg(const struct bt_mesh_model * model,uint16_t company_id,uint8_t * test_id,uint8_t * faults,uint8_t * fault_count)603 static int fault_get_reg(const struct bt_mesh_model *model, uint16_t company_id,
604 uint8_t *test_id, uint8_t *faults, uint8_t *fault_count)
605 {
606 LOG_DBG("company_id 0x%04x", company_id);
607
608 if (company_id != CID_LOCAL) {
609 return -EINVAL;
610 }
611
612 *test_id = HEALTH_TEST_ID;
613
614 get_faults(reg_faults, sizeof(reg_faults), faults, fault_count);
615
616 return 0;
617 }
618
fault_clear(const struct bt_mesh_model * model,uint16_t company_id)619 static int fault_clear(const struct bt_mesh_model *model, uint16_t company_id)
620 {
621 LOG_DBG("company_id 0x%04x", company_id);
622
623 if (company_id != CID_LOCAL) {
624 return -EINVAL;
625 }
626
627 (void)memset(reg_faults, 0, sizeof(reg_faults));
628
629 return 0;
630 }
631
fault_test(const struct bt_mesh_model * model,uint8_t test_id,uint16_t company_id)632 static int fault_test(const struct bt_mesh_model *model, uint8_t test_id,
633 uint16_t company_id)
634 {
635 LOG_DBG("test_id 0x%02x company_id 0x%04x", test_id, company_id);
636
637 if (company_id != CID_LOCAL || test_id != HEALTH_TEST_ID) {
638 return -EINVAL;
639 }
640
641 return 0;
642 }
643
644 static const struct bt_mesh_health_srv_cb health_srv_cb = {
645 .fault_get_cur = fault_get_cur,
646 .fault_get_reg = fault_get_reg,
647 .fault_clear = fault_clear,
648 .fault_test = fault_test,
649 };
650
show_faults(uint8_t test_id,uint16_t cid,uint8_t * faults,size_t fault_count)651 static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count)
652 {
653 size_t i;
654
655 if (!fault_count) {
656 LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x: no faults",
657 test_id, cid);
658 return;
659 }
660
661 LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu: ",
662 test_id, cid, fault_count);
663
664 for (i = 0; i < fault_count; i++) {
665 LOG_DBG("0x%02x", faults[i]);
666 }
667 }
668
health_current_status(struct bt_mesh_health_cli * cli,uint16_t addr,uint8_t test_id,uint16_t cid,uint8_t * faults,size_t fault_count)669 static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr,
670 uint8_t test_id, uint16_t cid, uint8_t *faults,
671 size_t fault_count)
672 {
673 LOG_DBG("Health Current Status from 0x%04x", addr);
674 show_faults(test_id, cid, faults, fault_count);
675 }
676
677 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
678 static struct bt_mesh_large_comp_data_cli lcd_cli = {
679 };
680 #endif
681
682 static struct bt_mesh_health_cli health_cli = {
683 .current_status = health_current_status,
684 };
685
686
687 static uint8_t health_tests[] = {
688 BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x01, 0x02, 0x03, 0x04, 0x34,
689 0x15),
690 BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03),
691 };
692
693 static const uint8_t zero_metadata[100];
694
695 static const struct bt_mesh_models_metadata_entry health_srv_meta[] = {
696 BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests),
697 {
698 .len = ARRAY_SIZE(zero_metadata),
699 .id = 0xABCD,
700 .data = zero_metadata,
701 },
702 BT_MESH_MODELS_METADATA_END,
703 };
704
705 static const uint8_t health_tests_alt[] = {
706 BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x11, 0x22, 0x33, 0x44, 0x55,
707 0x66),
708 BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x11, 0x22, 0x33),
709 };
710
711 static const struct bt_mesh_models_metadata_entry health_srv_meta_alt[] = {
712 BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests_alt),
713 {
714 .len = ARRAY_SIZE(zero_metadata),
715 .id = 0xFEED,
716 .data = zero_metadata,
717 },
718 BT_MESH_MODELS_METADATA_END,
719 };
720
721 static struct bt_mesh_health_srv health_srv = {
722 .cb = &health_srv_cb,
723 };
724
725 BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX);
726
727 static struct bt_mesh_cfg_cli cfg_cli = {
728 };
729
730 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
731 static struct bt_mesh_sar_cfg_cli sar_cfg_cli;
732 #endif
733
734 #if defined(CONFIG_BT_MESH_RPR_CLI)
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)735 static void rpr_scan_report(struct bt_mesh_rpr_cli *cli,
736 const struct bt_mesh_rpr_node *srv,
737 struct bt_mesh_rpr_unprov *unprov,
738 struct net_buf_simple *adv_data)
739 {
740 char uuid_hex_str[32 + 1];
741
742 bin2hex(unprov->uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
743
744 LOG_DBG("Server 0x%04x:\n"
745 "\tuuid: %s\n"
746 "\tOOB: 0x%04x",
747 srv->addr, uuid_hex_str, unprov->oob);
748
749 while (adv_data && adv_data->len > 2) {
750 uint8_t len, type;
751 uint8_t data[31];
752
753 len = net_buf_simple_pull_u8(adv_data) - 1;
754 type = net_buf_simple_pull_u8(adv_data);
755 memcpy(data, net_buf_simple_pull_mem(adv_data, len), len);
756 data[len] = '\0';
757
758 if (type == BT_DATA_URI) {
759 LOG_DBG("\tURI: \"\\x%02x%s\"",
760 data[0], &data[1]);
761 } else if (type == BT_DATA_NAME_COMPLETE) {
762 LOG_DBG("\tName: \"%s\"", data);
763 } else {
764 char string[64 + 1];
765
766 bin2hex(data, len, string, sizeof(string));
767 LOG_DBG("\t0x%02x: %s", type, string);
768 }
769 }
770 }
771
772 static struct bt_mesh_rpr_cli rpr_cli = {
773 .scan_report = rpr_scan_report,
774 };
775 #endif
776
777 #if defined(CONFIG_BT_MESH_DFU_SRV)
dfu_srv_apply(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)778 static uint8_t dfu_srv_apply(const void *cmd, uint16_t cmd_len,
779 void *rsp, uint16_t *rsp_len)
780 {
781 LOG_DBG("Applying image on server");
782 bt_mesh_dfu_srv_applied(&dfu_srv);
783 return BTP_STATUS_SUCCESS;
784 }
785 #endif
786
787 #ifdef CONFIG_BT_MESH_PRIV_BEACON_CLI
788 static struct bt_mesh_priv_beacon_cli priv_beacon_cli;
789
priv_beacon_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)790 static uint8_t priv_beacon_get(const void *cmd, uint16_t cmd_len,
791 void *rsp, uint16_t *rsp_len)
792 {
793 const struct btp_priv_beacon_get_cmd *cp = cmd;
794
795 struct bt_mesh_priv_beacon val;
796 int err;
797
798 err = bt_mesh_priv_beacon_cli_get(net.net_idx, cp->dst, &val);
799 if (err) {
800 LOG_ERR("Failed to send Private Beacon Get (err %d)", err);
801 return BTP_STATUS_FAILED;
802 }
803
804 LOG_DBG("Private Beacon state: %u, %u", val.enabled, val.rand_interval);
805 return BTP_STATUS_SUCCESS;
806 }
807
priv_beacon_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)808 static uint8_t priv_beacon_set(const void *cmd, uint16_t cmd_len,
809 void *rsp, uint16_t *rsp_len)
810 {
811 const struct btp_priv_beacon_set_cmd *cp = cmd;
812 struct bt_mesh_priv_beacon val;
813 int err;
814
815 val.enabled = cp->enabled;
816 val.rand_interval = cp->rand_interval;
817
818 err = bt_mesh_priv_beacon_cli_set(net.net_idx, cp->dst, &val, &val);
819 if (err) {
820 LOG_ERR("Failed to send Private Beacon Set (err %d)", err);
821 return BTP_STATUS_FAILED;
822 }
823
824 return BTP_STATUS_SUCCESS;
825 }
826
priv_gatt_proxy_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)827 static uint8_t priv_gatt_proxy_get(const void *cmd, uint16_t cmd_len,
828 void *rsp, uint16_t *rsp_len)
829 {
830 const struct btp_priv_gatt_proxy_get_cmd *cp = cmd;
831
832 uint8_t state;
833 int err;
834
835 err = bt_mesh_priv_beacon_cli_gatt_proxy_get(net.net_idx, cp->dst, &state);
836 if (err) {
837 LOG_ERR("Failed to send Private GATT Proxy Get (err %d)", err);
838 return BTP_STATUS_FAILED;
839 }
840
841 LOG_DBG("Private GATT Proxy state: %u", state);
842 return BTP_STATUS_SUCCESS;
843 }
844
priv_gatt_proxy_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)845 static uint8_t priv_gatt_proxy_set(const void *cmd, uint16_t cmd_len,
846 void *rsp, uint16_t *rsp_len)
847 {
848 const struct btp_priv_gatt_proxy_set_cmd *cp = cmd;
849
850 uint8_t state;
851 int err;
852
853 state = cp->state;
854
855 err = bt_mesh_priv_beacon_cli_gatt_proxy_set(net.net_idx, cp->dst, state, &state);
856 if (err) {
857 LOG_ERR("Failed to send Private GATT Proxy Set (err %d)", err);
858 return BTP_STATUS_FAILED;
859 }
860
861 return BTP_STATUS_SUCCESS;
862 }
863
priv_node_id_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)864 static uint8_t priv_node_id_get(const void *cmd, uint16_t cmd_len,
865 void *rsp, uint16_t *rsp_len)
866 {
867 const struct btp_priv_node_id_get_cmd *cp = cmd;
868 struct bt_mesh_priv_node_id val;
869 uint16_t key_net_idx;
870 int err;
871
872 key_net_idx = cp->key_net_idx;
873
874 err = bt_mesh_priv_beacon_cli_node_id_get(net.net_idx, cp->dst, key_net_idx, &val);
875 if (err) {
876 LOG_ERR("Failed to send Private Node Identity Get (err %d)", err);
877 return BTP_STATUS_FAILED;
878 }
879
880 LOG_DBG("Private Node Identity state: %u %u %u", val.net_idx, val.state, val.status);
881 return BTP_STATUS_SUCCESS;
882 }
883
priv_node_id_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)884 static uint8_t priv_node_id_set(const void *cmd, uint16_t cmd_len,
885 void *rsp, uint16_t *rsp_len)
886 {
887 const struct btp_priv_node_id_set_cmd *cp = cmd;
888 struct bt_mesh_priv_node_id val;
889 int err;
890
891 val.net_idx = cp->net_idx;
892 val.state = cp->state;
893
894 err = bt_mesh_priv_beacon_cli_node_id_set(net.net_idx, cp->dst, &val, &val);
895 if (err) {
896 LOG_ERR("Failed to send Private Node Identity Set (err %d)", err);
897 return BTP_STATUS_FAILED;
898 }
899
900 return BTP_STATUS_SUCCESS;
901 }
902
proxy_private_identity_enable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)903 static uint8_t proxy_private_identity_enable(const void *cmd, uint16_t cmd_len,
904 void *rsp, uint16_t *rsp_len)
905 {
906 int err;
907
908 LOG_DBG("");
909
910 err = bt_mesh_proxy_private_identity_enable();
911 if (err) {
912 LOG_ERR("Failed to enable proxy private identity (err %d)", err);
913 return BTP_STATUS_FAILED;
914 }
915
916 return BTP_STATUS_SUCCESS;
917 }
918 #endif
919
920 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
921 static struct bt_mesh_sol_pdu_rpl_cli srpl_cli;
922 #endif
923
924
925 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
926 static struct bt_mesh_od_priv_proxy_cli od_priv_proxy_cli;
927
od_priv_proxy_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)928 static uint8_t od_priv_proxy_get(const void *cmd, uint16_t cmd_len,
929 void *rsp, uint16_t *rsp_len)
930 {
931 const struct btp_od_priv_proxy_get_cmd *cp = cmd;
932 uint8_t val_rsp;
933 int err;
934
935 LOG_DBG("");
936
937 err = bt_mesh_od_priv_proxy_cli_get(net.net_idx, cp->dst, &val_rsp);
938 if (err) {
939 LOG_ERR("Failed to get On-Demand Private Proxy state (err %d)", err);
940 return BTP_STATUS_FAILED;
941 }
942
943 LOG_DBG("On-Demand Private Proxy state: %u", val_rsp);
944
945 return BTP_STATUS_SUCCESS;
946 }
947
od_priv_proxy_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)948 static uint8_t od_priv_proxy_set(const void *cmd, uint16_t cmd_len,
949 void *rsp, uint16_t *rsp_len)
950 {
951 const struct btp_od_priv_proxy_set_cmd *cp = cmd;
952 uint8_t val_rsp;
953 int err;
954
955 LOG_DBG("");
956
957 err = bt_mesh_od_priv_proxy_cli_set(net.net_idx, cp->dst, cp->val, &val_rsp);
958 if (err) {
959 LOG_ERR("Failed to set On-Demand Private Proxy state (err %d)", err);
960 return BTP_STATUS_FAILED;
961 }
962
963 LOG_DBG("On-Demand Private Proxy set state: %u", val_rsp);
964
965 return BTP_STATUS_SUCCESS;
966 }
967
968 #endif
969
970 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
srpl_clear(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)971 static uint8_t srpl_clear(const void *cmd, uint16_t cmd_len,
972 void *rsp, uint16_t *rsp_len)
973 {
974 const struct btp_srpl_clear_cmd *cp = cmd;
975 uint16_t app_idx = BT_MESH_KEY_UNUSED;
976 uint16_t start_rsp;
977 uint8_t len_rsp;
978 int err;
979
980 /* Lookup source address */
981 for (int i = 0; i < ARRAY_SIZE(model_bound); i++) {
982 if (model_bound[i].model->id == BT_MESH_MODEL_ID_SOL_PDU_RPL_CLI) {
983 app_idx = model_bound[i].appkey_idx;
984 break;
985 }
986 }
987
988 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(app_idx, cp->dst);
989
990 if (cp->acked) {
991 err = bt_mesh_sol_pdu_rpl_clear(&ctx, cp->range_start, cp->range_len, &start_rsp,
992 &len_rsp);
993 } else {
994 err = bt_mesh_sol_pdu_rpl_clear_unack(&ctx, cp->range_start, cp->range_len);
995 }
996 if (err) {
997 LOG_ERR("Failed to clear SRPL (err %d)", err);
998 return BTP_STATUS_FAILED;
999 }
1000
1001 return BTP_STATUS_SUCCESS;
1002 }
1003 #endif
1004
1005 #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION)
proxy_solicit(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1006 static uint8_t proxy_solicit(const void *cmd, uint16_t cmd_len,
1007 void *rsp, uint16_t *rsp_len)
1008 {
1009 const struct btp_proxy_solicit_cmd *cp = cmd;
1010 int err;
1011
1012 err = bt_mesh_proxy_solicit(cp->net_idx);
1013 if (err) {
1014 LOG_ERR("Failed to advertise solicitation PDU (err %d)", err);
1015 return BTP_STATUS_FAILED;
1016 }
1017
1018 return BTP_STATUS_SUCCESS;
1019 }
1020 #endif /* CONFIG_BT_MESH_PROXY_SOLICITATION */
1021
1022 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
1023 static struct bt_mesh_brg_cfg_cli brg_cfg_cli;
1024 #endif /* CONFIG_BT_MESH_BRG_CFG_CLI */
1025
1026 static const struct bt_mesh_model primary_models[] = {
1027 BT_MESH_MODEL_CFG_SRV,
1028 BT_MESH_MODEL_CFG_CLI(&cfg_cli),
1029 BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub, health_srv_meta),
1030 BT_MESH_MODEL_HEALTH_CLI(&health_cli),
1031 #if defined(CONFIG_BT_MESH_SAR_CFG_SRV)
1032 BT_MESH_MODEL_SAR_CFG_SRV,
1033 #endif
1034 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
1035 BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli),
1036 #endif
1037 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
1038 BT_MESH_MODEL_LARGE_COMP_DATA_SRV,
1039 #endif
1040 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
1041 BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli),
1042 #endif
1043 #if defined(CONFIG_BT_MESH_OP_AGG_SRV)
1044 BT_MESH_MODEL_OP_AGG_SRV,
1045 #endif
1046 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
1047 BT_MESH_MODEL_OP_AGG_CLI,
1048 #endif
1049 #if defined(CONFIG_BT_MESH_RPR_CLI)
1050 BT_MESH_MODEL_RPR_CLI(&rpr_cli),
1051 #endif
1052 #if defined(CONFIG_BT_MESH_RPR_SRV)
1053 BT_MESH_MODEL_RPR_SRV,
1054 #endif
1055 #if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV)
1056 BT_MESH_MODEL_PRIV_BEACON_SRV,
1057 #endif
1058 #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI)
1059 BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli),
1060 #endif
1061 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
1062 BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&od_priv_proxy_cli),
1063 #endif
1064 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
1065 BT_MESH_MODEL_SOL_PDU_RPL_CLI(&srpl_cli),
1066 #endif
1067 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
1068 BT_MESH_MODEL_OD_PRIV_PROXY_SRV,
1069 #endif
1070 #if defined(CONFIG_BT_MESH_BRG_CFG_SRV)
1071 BT_MESH_MODEL_BRG_CFG_SRV,
1072 #endif
1073 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
1074 BT_MESH_MODEL_BRG_CFG_CLI(&brg_cfg_cli),
1075 #endif
1076
1077 };
1078
1079 #if defined(CONFIG_BT_MESH_DFD_SRV)
1080 static const struct bt_mesh_model dfu_distributor_models[] = {BT_MESH_MODEL_DFD_SRV(&dfd_srv)};
1081 #endif
1082
1083 #if defined(CONFIG_BT_MESH_DFU_SRV)
1084 static const struct bt_mesh_model dfu_target_models[] = {
1085 BT_MESH_MODEL_DFU_SRV(&dfu_srv),
1086 };
1087 #endif
1088
1089 #if defined(CONFIG_BT_MESH_BLOB_CLI)
1090 static const struct bt_mesh_model blob_client_models[] = {
1091 BT_MESH_MODEL_BLOB_CLI(&blob_cli),
1092 };
1093 #endif
1094
1095 static const struct bt_mesh_model primary_models_alt[] = {
1096 BT_MESH_MODEL_CFG_SRV,
1097 BT_MESH_MODEL_CFG_CLI(&cfg_cli),
1098 BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub, health_srv_meta_alt),
1099 BT_MESH_MODEL_HEALTH_CLI(&health_cli),
1100 #if defined(CONFIG_BT_MESH_SAR_CFG_SRV)
1101 BT_MESH_MODEL_SAR_CFG_SRV,
1102 #endif
1103 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
1104 BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli),
1105 #endif
1106 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
1107 BT_MESH_MODEL_LARGE_COMP_DATA_SRV,
1108 #endif
1109 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
1110 BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli),
1111 #endif
1112 #if defined(CONFIG_BT_MESH_OP_AGG_SRV)
1113 BT_MESH_MODEL_OP_AGG_SRV,
1114 #endif
1115 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
1116 BT_MESH_MODEL_OP_AGG_CLI,
1117 #endif
1118 #if defined(CONFIG_BT_MESH_RPR_CLI)
1119 BT_MESH_MODEL_RPR_CLI(&rpr_cli),
1120 #endif
1121 #if defined(CONFIG_BT_MESH_RPR_SRV)
1122 BT_MESH_MODEL_RPR_SRV,
1123 #endif
1124 #if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV)
1125 BT_MESH_MODEL_PRIV_BEACON_SRV,
1126 #endif
1127 #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI)
1128 BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli),
1129 #endif
1130 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
1131 BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&od_priv_proxy_cli),
1132 #endif
1133 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
1134 BT_MESH_MODEL_SOL_PDU_RPL_CLI(&srpl_cli),
1135 #endif
1136 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
1137 BT_MESH_MODEL_OD_PRIV_PROXY_SRV,
1138 #endif
1139 #if defined(CONFIG_BT_MESH_BRG_CFG_SRV)
1140 BT_MESH_MODEL_BRG_CFG_SRV,
1141 #endif
1142 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
1143 BT_MESH_MODEL_BRG_CFG_CLI(&brg_cfg_cli),
1144 #endif
1145
1146 };
1147
lookup_model_bound(uint16_t id)1148 struct model_data *lookup_model_bound(uint16_t id)
1149 {
1150 int i;
1151
1152 for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
1153 if (model_bound[i].model && model_bound[i].model->id == id) {
1154 return &model_bound[i];
1155 }
1156 }
1157
1158 return NULL;
1159 }
1160 static const struct bt_mesh_model vnd_models[] = {
1161 BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL,
1162 NULL),
1163 };
1164
1165 static const struct bt_mesh_elem elements[] = {
1166 BT_MESH_ELEM(0, primary_models, vnd_models),
1167 #if defined(CONFIG_BT_MESH_DFD_SRV)
1168 BT_MESH_ELEM(0, dfu_distributor_models, BT_MESH_MODEL_NONE),
1169 #endif
1170 #if defined(CONFIG_BT_MESH_DFU_SRV)
1171 BT_MESH_ELEM(0, dfu_target_models, BT_MESH_MODEL_NONE),
1172 #endif
1173 #if defined(CONFIG_BT_MESH_BLOB_CLI)
1174 BT_MESH_ELEM(0, blob_client_models, BT_MESH_MODEL_NONE),
1175 #endif
1176 };
1177
1178 static const struct bt_mesh_elem elements_alt[] = {
1179 BT_MESH_ELEM(0, primary_models_alt, vnd_models),
1180 #if defined(CONFIG_BT_MESH_DFD_SRV)
1181 BT_MESH_ELEM(0, dfu_distributor_models, BT_MESH_MODEL_NONE),
1182 #endif
1183 #if defined(CONFIG_BT_MESH_DFU_SRV)
1184 BT_MESH_ELEM(0, dfu_target_models, BT_MESH_MODEL_NONE),
1185 #endif
1186 #if defined(CONFIG_BT_MESH_BLOB_CLI)
1187 BT_MESH_ELEM(0, blob_client_models, BT_MESH_MODEL_NONE),
1188 #endif
1189 };
1190
link_open(bt_mesh_prov_bearer_t bearer)1191 static void link_open(bt_mesh_prov_bearer_t bearer)
1192 {
1193 struct btp_mesh_prov_link_open_ev ev;
1194
1195 LOG_DBG("bearer 0x%02x", bearer);
1196
1197 switch (bearer) {
1198 case BT_MESH_PROV_ADV:
1199 ev.bearer = BTP_MESH_PROV_BEARER_PB_ADV;
1200 break;
1201 case BT_MESH_PROV_GATT:
1202 ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT;
1203 break;
1204 case BT_MESH_PROV_REMOTE:
1205 ev.bearer = BTP_MESH_PROV_BEARER_REMOTE;
1206 break;
1207 default:
1208 LOG_ERR("Invalid bearer");
1209
1210 return;
1211 }
1212
1213 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_OPEN, &ev, sizeof(ev));
1214 }
1215
link_close(bt_mesh_prov_bearer_t bearer)1216 static void link_close(bt_mesh_prov_bearer_t bearer)
1217 {
1218 struct btp_mesh_prov_link_closed_ev ev;
1219
1220 LOG_DBG("bearer 0x%02x", bearer);
1221
1222 switch (bearer) {
1223 case BT_MESH_PROV_ADV:
1224 ev.bearer = BTP_MESH_PROV_BEARER_PB_ADV;
1225 break;
1226 case BT_MESH_PROV_GATT:
1227 ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT;
1228 break;
1229 case BT_MESH_PROV_REMOTE:
1230 ev.bearer = BTP_MESH_PROV_BEARER_REMOTE;
1231 break;
1232 default:
1233 LOG_ERR("Invalid bearer");
1234
1235 return;
1236 }
1237
1238 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_CLOSED, &ev, sizeof(ev));
1239 }
1240
output_number(bt_mesh_output_action_t action,uint32_t number)1241 static int output_number(bt_mesh_output_action_t action, uint32_t number)
1242 {
1243 struct btp_mesh_out_number_action_ev ev;
1244
1245 LOG_DBG("action 0x%04x number 0x%08x", action, number);
1246
1247 ev.action = sys_cpu_to_le16(action);
1248 ev.number = sys_cpu_to_le32(number);
1249
1250 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_NUMBER_ACTION, &ev, sizeof(ev));
1251
1252 return 0;
1253 }
1254
output_string(const char * str)1255 static int output_string(const char *str)
1256 {
1257 struct btp_mesh_out_string_action_ev *ev;
1258 struct net_buf_simple *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE);
1259
1260 LOG_DBG("str %s", str);
1261
1262 net_buf_simple_init(buf, 0);
1263
1264 ev = net_buf_simple_add(buf, sizeof(*ev));
1265 ev->string_len = strlen(str);
1266
1267 net_buf_simple_add_mem(buf, str, ev->string_len);
1268
1269 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_STRING_ACTION,
1270 buf->data, buf->len);
1271
1272 return 0;
1273 }
1274
input(bt_mesh_input_action_t action,uint8_t size)1275 static int input(bt_mesh_input_action_t action, uint8_t size)
1276 {
1277 struct btp_mesh_in_action_ev ev;
1278
1279 LOG_DBG("action 0x%04x number 0x%02x", action, size);
1280
1281 input_size = size;
1282
1283 ev.action = sys_cpu_to_le16(action);
1284 ev.size = size;
1285
1286 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, &ev, sizeof(ev));
1287
1288 return 0;
1289 }
1290
prov_complete(uint16_t net_idx,uint16_t addr)1291 static void prov_complete(uint16_t net_idx, uint16_t addr)
1292 {
1293 LOG_DBG("net_idx 0x%04x addr 0x%04x", net_idx, addr);
1294
1295 net.net_idx = net_idx,
1296 net.local = addr;
1297 net.dst = addr;
1298
1299 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROVISIONED, NULL, 0);
1300 }
1301
prov_node_added(uint16_t net_idx,uint8_t uuid[16],uint16_t addr,uint8_t num_elem)1302 static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
1303 uint8_t num_elem)
1304 {
1305 struct btp_mesh_prov_node_added_ev ev;
1306
1307 LOG_DBG("net_idx 0x%04x addr 0x%04x num_elem %d", net_idx, addr,
1308 num_elem);
1309
1310 ev.net_idx = net_idx;
1311 ev.addr = addr;
1312 ev.num_elems = num_elem;
1313 memcpy(&ev.uuid, uuid, sizeof(ev.uuid));
1314
1315 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_NODE_ADDED, &ev, sizeof(ev));
1316 }
1317
prov_reset(void)1318 static void prov_reset(void)
1319 {
1320 LOG_DBG("");
1321
1322 bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
1323
1324 if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) {
1325 bt_mesh_prov_enable(BT_MESH_PROV_REMOTE);
1326 }
1327 }
1328
1329 static const struct bt_mesh_comp comp = {
1330 .cid = CID_LOCAL,
1331 .elem = elements,
1332 .elem_count = ARRAY_SIZE(elements),
1333 .vid = 1,
1334 };
1335
1336 static const struct bt_mesh_comp comp_alt = {
1337 .cid = CID_LOCAL,
1338 .elem = elements_alt,
1339 .elem_count = ARRAY_SIZE(elements_alt),
1340 .vid = 2,
1341 };
1342
1343 #if defined(CONFIG_BT_MESH_COMP_PAGE_2)
1344 static const uint8_t cmp2_elem_offset[1] = {0};
1345
1346 static const struct bt_mesh_comp2_record comp_rec = {
1347 .id = 0x1600,
1348 .version.x = 1,
1349 .version.y = 0,
1350 .version.z = 0,
1351 .elem_offset_cnt = 1,
1352 .elem_offset = cmp2_elem_offset,
1353 .data_len = 0
1354 };
1355
1356 static const struct bt_mesh_comp2 comp_p2 = {.record_cnt = 1, .record = &comp_rec};
1357 #endif
1358
1359 static struct bt_mesh_prov prov = {
1360 .uuid = dev_uuid,
1361 .static_val = static_auth,
1362 .static_val_len = sizeof(static_auth),
1363 .output_number = output_number,
1364 .output_string = output_string,
1365 .input = input,
1366 .link_open = link_open,
1367 .link_close = link_close,
1368 .complete = prov_complete,
1369 .node_added = prov_node_added,
1370 .reset = prov_reset,
1371 .uri = "Tester",
1372 };
1373
config_prov(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1374 static uint8_t config_prov(const void *cmd, uint16_t cmd_len,
1375 void *rsp, uint16_t *rsp_len)
1376 {
1377 const struct btp_mesh_config_provisioning_cmd *cp = cmd;
1378 const struct btp_mesh_config_provisioning_cmd_v2 *cp2 = cmd;
1379 int err = 0;
1380
1381 /* TODO consider fix BTP commands to avoid this */
1382 if (cmd_len != sizeof(*cp) && cmd_len != (sizeof(*cp2))) {
1383 LOG_DBG("wrong cmd size");
1384 return BTP_STATUS_FAILED;
1385 }
1386
1387 LOG_DBG("");
1388
1389 static_auth_size = cp->static_auth_size;
1390
1391 if (static_auth_size > BTP_MESH_PROV_AUTH_MAX_LEN || static_auth_size == 0) {
1392 LOG_DBG("wrong static auth length");
1393 return BTP_STATUS_FAILED;
1394 }
1395
1396 memcpy(dev_uuid, cp->uuid, sizeof(dev_uuid));
1397 memcpy(static_auth, cp->static_auth, cp->static_auth_size);
1398
1399 prov.output_size = cp->out_size;
1400 prov.output_actions = sys_le16_to_cpu(cp->out_actions);
1401 prov.input_size = cp->in_size;
1402 prov.input_actions = sys_le16_to_cpu(cp->in_actions);
1403
1404 if (cmd_len == sizeof(*cp2)) {
1405 memcpy(pub_key, cp2->set_pub_key, sizeof(cp2->set_pub_key));
1406 memcpy(priv_key, cp2->set_priv_key, sizeof(cp2->set_priv_key));
1407 prov.public_key_be = pub_key;
1408 prov.private_key_be = priv_key;
1409 }
1410
1411 if (cp->auth_method == AUTH_METHOD_OUTPUT) {
1412 err = bt_mesh_auth_method_set_output(prov.output_actions, prov.output_size);
1413 } else if (cp->auth_method == AUTH_METHOD_INPUT) {
1414 err = bt_mesh_auth_method_set_input(prov.input_actions, prov.input_size);
1415 } else if (cp->auth_method == AUTH_METHOD_STATIC) {
1416 err = bt_mesh_auth_method_set_static(static_auth, static_auth_size);
1417 }
1418
1419 if (err) {
1420 LOG_ERR("err %d", err);
1421 return BTP_STATUS_FAILED;
1422 }
1423
1424 return BTP_STATUS_SUCCESS;
1425 }
1426
provision_node(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1427 static uint8_t provision_node(const void *cmd, uint16_t cmd_len,
1428 void *rsp, uint16_t *rsp_len)
1429 {
1430 const struct btp_mesh_provision_node_cmd *cp = cmd;
1431 const struct btp_mesh_provision_node_cmd_v2 *cp2 = cmd;
1432 int err;
1433
1434 /* TODO consider fix BTP commands to avoid this */
1435 if (cmd_len != sizeof(*cp) && cmd_len != (sizeof(*cp2))) {
1436 return BTP_STATUS_FAILED;
1437 }
1438
1439 LOG_DBG("");
1440
1441 memcpy(dev_key, cp->dev_key, sizeof(dev_key));
1442 memcpy(net_key, cp->net_key, sizeof(net_key));
1443
1444 addr = sys_le16_to_cpu(cp->addr);
1445 flags = cp->flags;
1446 iv_index = sys_le32_to_cpu(cp->iv_index);
1447 net_key_idx = sys_le16_to_cpu(cp->net_key_idx);
1448
1449 if (cmd_len == sizeof(*cp2)) {
1450 memcpy(pub_key, cp2->pub_key, sizeof(pub_key));
1451
1452 err = bt_mesh_prov_remote_pub_key_set(pub_key);
1453 if (err) {
1454 LOG_ERR("err %d", err);
1455 return BTP_STATUS_FAILED;
1456 }
1457 }
1458 #if defined(CONFIG_BT_MESH_PROVISIONER)
1459 err = bt_mesh_cdb_create(net_key);
1460 if (err) {
1461 LOG_ERR("err %d", err);
1462 return BTP_STATUS_FAILED;
1463 }
1464 #endif
1465 err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, addr,
1466 dev_key);
1467 if (err) {
1468 LOG_ERR("err %d", err);
1469 return BTP_STATUS_FAILED;
1470 }
1471
1472 return BTP_STATUS_SUCCESS;
1473 }
1474
provision_adv(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1475 static uint8_t provision_adv(const void *cmd, uint16_t cmd_len,
1476 void *rsp, uint16_t *rsp_len)
1477 {
1478 const struct btp_mesh_provision_adv_cmd *cp = cmd;
1479 int err;
1480
1481 LOG_DBG("");
1482
1483 err = bt_mesh_provision_adv(cp->uuid, sys_le16_to_cpu(cp->net_idx),
1484 sys_le16_to_cpu(cp->address),
1485 cp->attention_duration);
1486 if (err) {
1487 LOG_ERR("err %d", err);
1488 return BTP_STATUS_FAILED;
1489 }
1490
1491 return BTP_STATUS_SUCCESS;
1492 }
1493
init(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1494 static uint8_t init(const void *cmd, uint16_t cmd_len,
1495 void *rsp, uint16_t *rsp_len)
1496 {
1497 const struct btp_mesh_init_cmd *cp = cmd;
1498 int err;
1499
1500 if (cp->comp == 0) {
1501 LOG_WRN("Loading default comp data");
1502 err = bt_mesh_init(&prov, &comp);
1503 } else {
1504 LOG_WRN("Loading alternative comp data");
1505 err = bt_mesh_init(&prov, &comp_alt);
1506 }
1507
1508 if (err) {
1509 return BTP_STATUS_FAILED;
1510 }
1511
1512 return BTP_STATUS_SUCCESS;
1513 }
1514
start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1515 static uint8_t start(const void *cmd, uint16_t cmd_len,
1516 void *rsp, uint16_t *rsp_len)
1517 {
1518 int err;
1519
1520 LOG_DBG("");
1521
1522 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1523 printk("Loading stored settings\n");
1524 settings_load();
1525 }
1526
1527 if (addr) {
1528 err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index,
1529 addr, dev_key);
1530 if (err && err != -EALREADY) {
1531 return BTP_STATUS_FAILED;
1532 }
1533 } else {
1534 err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
1535 if (err && err != -EALREADY) {
1536 return BTP_STATUS_FAILED;
1537 }
1538 }
1539
1540 if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) {
1541 err = bt_mesh_prov_enable(BT_MESH_PROV_REMOTE);
1542 if (err) {
1543 return BTP_STATUS_FAILED;
1544 }
1545 }
1546
1547 return BTP_STATUS_SUCCESS;
1548 }
1549
reset(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1550 static uint8_t reset(const void *cmd, uint16_t cmd_len,
1551 void *rsp, uint16_t *rsp_len)
1552 {
1553 LOG_DBG("");
1554
1555 bt_mesh_reset();
1556
1557 return BTP_STATUS_SUCCESS;
1558 }
1559
input_number(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1560 static uint8_t input_number(const void *cmd, uint16_t cmd_len,
1561 void *rsp, uint16_t *rsp_len)
1562 {
1563 const struct btp_mesh_input_number_cmd *cp = cmd;
1564 uint32_t number;
1565 int err;
1566
1567 number = sys_le32_to_cpu(cp->number);
1568
1569 LOG_DBG("number 0x%04x", number);
1570
1571 err = bt_mesh_input_number(number);
1572 if (err) {
1573 return BTP_STATUS_FAILED;
1574 }
1575
1576 return BTP_STATUS_SUCCESS;
1577 }
1578
input_string(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1579 static uint8_t input_string(const void *cmd, uint16_t cmd_len,
1580 void *rsp, uint16_t *rsp_len)
1581 {
1582 const struct btp_mesh_input_string_cmd *cp = cmd;
1583 uint8_t status = BTP_STATUS_SUCCESS;
1584 int err;
1585
1586 LOG_DBG("");
1587
1588 if (cmd_len < sizeof(*cp) &&
1589 cmd_len != (sizeof(*cp) + cp->string_len)) {
1590 return BTP_STATUS_FAILED;
1591 }
1592
1593 /* for historical reasons this commands must send NULL terminated
1594 * string
1595 */
1596 if (cp->string[cp->string_len] != '\0') {
1597 return BTP_STATUS_FAILED;
1598 }
1599
1600 if (strlen(cp->string) < input_size) {
1601 LOG_ERR("Too short input (%u chars required)", input_size);
1602 return BTP_STATUS_FAILED;
1603 }
1604
1605 err = bt_mesh_input_string(cp->string);
1606 if (err) {
1607 status = BTP_STATUS_FAILED;
1608 }
1609
1610 return BTP_STATUS_SUCCESS;
1611 }
1612
ivu_test_mode(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1613 static uint8_t ivu_test_mode(const void *cmd, uint16_t cmd_len,
1614 void *rsp, uint16_t *rsp_len)
1615 {
1616 const struct btp_mesh_ivu_test_mode_cmd *cp = cmd;
1617
1618 LOG_DBG("enable 0x%02x", cp->enable);
1619
1620 bt_mesh_iv_update_test(cp->enable ? true : false);
1621
1622 return BTP_STATUS_SUCCESS;
1623 }
1624
ivu_toggle_state(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1625 static uint8_t ivu_toggle_state(const void *cmd, uint16_t cmd_len,
1626 void *rsp, uint16_t *rsp_len)
1627 {
1628 bool result;
1629
1630 LOG_DBG("");
1631
1632 result = bt_mesh_iv_update();
1633 if (!result) {
1634 LOG_ERR("Failed to toggle the IV Update state");
1635 return BTP_STATUS_FAILED;
1636 }
1637
1638 return BTP_STATUS_SUCCESS;
1639 }
1640
1641 #if defined(CONFIG_BT_MESH_LOW_POWER)
lpn(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1642 static uint8_t lpn(const void *cmd, uint16_t cmd_len,
1643 void *rsp, uint16_t *rsp_len)
1644 {
1645 const struct btp_mesh_lpn_set_cmd *cp = cmd;
1646 int err;
1647
1648 LOG_DBG("enable 0x%02x", cp->enable);
1649
1650 err = bt_mesh_lpn_set(cp->enable ? true : false);
1651 if (err) {
1652 LOG_ERR("Failed to toggle LPN (err %d)", err);
1653 return BTP_STATUS_FAILED;
1654 }
1655
1656 return BTP_STATUS_SUCCESS;
1657 }
1658
lpn_poll(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1659 static uint8_t lpn_poll(const void *cmd, uint16_t cmd_len,
1660 void *rsp, uint16_t *rsp_len)
1661 {
1662 int err;
1663
1664 LOG_DBG("");
1665
1666 err = bt_mesh_lpn_poll();
1667 if (err) {
1668 LOG_ERR("Failed to send poll msg (err %d)", err);
1669 }
1670
1671 return BTP_STATUS_SUCCESS;
1672 }
1673 #endif /* CONFIG_BT_MESH_LOW_POWER */
1674
net_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1675 static uint8_t net_send(const void *cmd, uint16_t cmd_len,
1676 void *rsp, uint16_t *rsp_len)
1677 {
1678 const struct btp_mesh_net_send_cmd *cp = cmd;
1679 NET_BUF_SIMPLE_DEFINE(msg, UINT8_MAX);
1680 int err;
1681
1682 if (cmd_len < sizeof(*cp) &&
1683 cmd_len != (sizeof(*cp) + cp->payload_len)) {
1684 return BTP_STATUS_FAILED;
1685 }
1686
1687 struct bt_mesh_msg_ctx ctx = {
1688 .net_idx = net.net_idx,
1689 .app_idx = vnd_app_key_idx,
1690 .addr = sys_le16_to_cpu(cp->dst),
1691 .send_ttl = cp->ttl,
1692 };
1693
1694 if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) {
1695 ctx.uuid = bt_mesh_va_uuid_get(ctx.addr, NULL, NULL);
1696 }
1697
1698 LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl,
1699 ctx.addr, cp->payload_len);
1700
1701 if (!bt_mesh_app_key_exists(vnd_app_key_idx)) {
1702 (void)bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx,
1703 vnd_app_key);
1704 vnd_models[0].keys[0] = vnd_app_key_idx;
1705 }
1706
1707 net_buf_simple_add_mem(&msg, cp->payload, cp->payload_len);
1708
1709 err = bt_mesh_model_send(&vnd_models[0], &ctx, &msg, NULL, NULL);
1710 if (err) {
1711 LOG_ERR("Failed to send (err %d)", err);
1712 return BTP_STATUS_FAILED;
1713 }
1714
1715 return BTP_STATUS_SUCCESS;
1716 }
1717
va_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1718 static uint8_t va_add(const void *cmd, uint16_t cmd_len,
1719 void *rsp, uint16_t *rsp_len)
1720 {
1721 const struct btp_mesh_va_add_cmd *cp = cmd;
1722 struct btp_mesh_va_add_rp *rp = rsp;
1723 const struct bt_mesh_va *va;
1724 int err;
1725
1726 err = bt_mesh_va_add(cp->label_uuid, &va);
1727 if (err) {
1728 LOG_ERR("Failed to add Label UUID (err %d)", err);
1729 return BTP_STATUS_FAILED;
1730 }
1731
1732 rp->addr = sys_cpu_to_le16(va->addr);
1733 *rsp_len = sizeof(*rp);
1734
1735 return BTP_STATUS_SUCCESS;
1736 }
1737
va_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1738 static uint8_t va_del(const void *cmd, uint16_t cmd_len,
1739 void *rsp, uint16_t *rsp_len)
1740 {
1741 const struct btp_mesh_va_del_cmd *cp = cmd;
1742 const struct bt_mesh_va *va;
1743 int err;
1744
1745 va = bt_mesh_va_find(cp->label_uuid);
1746 if (!va) {
1747 LOG_ERR("Failed to find Label UUID");
1748 return BTP_STATUS_FAILED;
1749 }
1750
1751 err = bt_mesh_va_del(va->uuid);
1752 if (err) {
1753 LOG_ERR("Failed to delete Label UUID (err %d)", err);
1754 return BTP_STATUS_FAILED;
1755 }
1756
1757 return BTP_STATUS_SUCCESS;
1758 }
1759
health_generate_faults(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1760 static uint8_t health_generate_faults(const void *cmd, uint16_t cmd_len,
1761 void *rsp, uint16_t *rsp_len)
1762 {
1763 struct btp_mesh_health_generate_faults_rp *rp = rsp;
1764 uint8_t some_faults[] = { 0x01, 0x02, 0x03, 0xff, 0x06 };
1765 uint8_t cur_faults_count;
1766 uint8_t reg_faults_count;
1767
1768 cur_faults_count = MIN(sizeof(cur_faults), sizeof(some_faults));
1769 memcpy(cur_faults, some_faults, cur_faults_count);
1770 memcpy(rp->faults, cur_faults, cur_faults_count);
1771 rp->cur_faults_count = cur_faults_count;
1772
1773 reg_faults_count = MIN(sizeof(reg_faults), sizeof(some_faults));
1774 memcpy(reg_faults, some_faults, reg_faults_count);
1775 memcpy(rp->faults + cur_faults_count, reg_faults, reg_faults_count);
1776 rp->reg_faults_count = reg_faults_count;
1777
1778 bt_mesh_health_srv_fault_update(&elements[0]);
1779
1780 *rsp_len = sizeof(*rp) + cur_faults_count + reg_faults_count;
1781
1782 return BTP_STATUS_SUCCESS;
1783 }
1784
health_clear_faults(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1785 static uint8_t health_clear_faults(const void *cmd, uint16_t cmd_len,
1786 void *rsp, uint16_t *rsp_len)
1787 {
1788 LOG_DBG("");
1789
1790 (void)memset(cur_faults, 0, sizeof(cur_faults));
1791 (void)memset(reg_faults, 0, sizeof(reg_faults));
1792
1793 bt_mesh_health_srv_fault_update(&elements[0]);
1794
1795 return BTP_STATUS_SUCCESS;
1796 }
1797
model_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1798 static uint8_t model_send(const void *cmd, uint16_t cmd_len,
1799 void *rsp, uint16_t *rsp_len)
1800 {
1801 const struct btp_mesh_model_send_cmd *cp = cmd;
1802 NET_BUF_SIMPLE_DEFINE(msg, UINT8_MAX);
1803 const struct bt_mesh_model *model = NULL;
1804 uint16_t src;
1805 int err;
1806
1807 if (cmd_len < sizeof(*cp) &&
1808 cmd_len != (sizeof(*cp) + cp->payload_len)) {
1809 return BTP_STATUS_FAILED;
1810 }
1811
1812 struct bt_mesh_msg_ctx ctx = {
1813 .net_idx = net.net_idx,
1814 .app_idx = BT_MESH_KEY_DEV,
1815 .addr = sys_le16_to_cpu(cp->dst),
1816 .send_ttl = cp->ttl,
1817 };
1818
1819 if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) {
1820 ctx.uuid = bt_mesh_va_uuid_get(ctx.addr, NULL, NULL);
1821 }
1822
1823 src = sys_le16_to_cpu(cp->src);
1824
1825 /* Lookup source address */
1826 for (int i = 0; i < ARRAY_SIZE(model_bound); i++) {
1827 if (bt_mesh_model_elem(model_bound[i].model)->rt->addr == src) {
1828 model = model_bound[i].model;
1829 ctx.app_idx = model_bound[i].appkey_idx;
1830
1831 break;
1832 }
1833 }
1834
1835 if (!model) {
1836 LOG_ERR("Model not found");
1837 return BTP_STATUS_FAILED;
1838 }
1839
1840 LOG_DBG("src 0x%04x dst 0x%04x model %p payload_len %d", src,
1841 ctx.addr, model, cp->payload_len);
1842
1843 net_buf_simple_add_mem(&msg, cp->payload, cp->payload_len);
1844
1845 err = bt_mesh_model_send(model, &ctx, &msg, NULL, NULL);
1846 if (err) {
1847 LOG_ERR("Failed to send (err %d)", err);
1848 return BTP_STATUS_FAILED;
1849 }
1850
1851 return BTP_STATUS_SUCCESS;
1852 }
1853
1854 #if defined(CONFIG_BT_TESTING)
1855 #if defined(CONFIG_BT_MESH_LOW_POWER)
lpn_subscribe(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1856 static uint8_t lpn_subscribe(const void *cmd, uint16_t cmd_len,
1857 void *rsp, uint16_t *rsp_len)
1858 {
1859 const struct btp_mesh_lpn_subscribe_cmd *cp = cmd;
1860 uint16_t address = sys_le16_to_cpu(cp->address);
1861 int err;
1862
1863 LOG_DBG("address 0x%04x", address);
1864
1865 err = bt_mesh_test_lpn_group_add(address);
1866 if (err) {
1867 LOG_ERR("Failed to subscribe (err %d)", err);
1868 return BTP_STATUS_FAILED;
1869 }
1870
1871 return BTP_STATUS_SUCCESS;
1872 }
1873
lpn_unsubscribe(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1874 static uint8_t lpn_unsubscribe(const void *cmd, uint16_t cmd_len,
1875 void *rsp, uint16_t *rsp_len)
1876 {
1877 const struct btp_mesh_lpn_unsubscribe_cmd *cp = cmd;
1878 uint16_t address = sys_le16_to_cpu(cp->address);
1879 int err;
1880
1881 LOG_DBG("address 0x%04x", address);
1882
1883 err = bt_mesh_test_lpn_group_remove(&address, 1);
1884 if (err) {
1885 LOG_ERR("Failed to unsubscribe (err %d)", err);
1886 return BTP_STATUS_FAILED;
1887 }
1888
1889 return BTP_STATUS_SUCCESS;
1890 }
1891 #endif /* CONFIG_BT_MESH_LOW_POWER */
1892
rpl_clear(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1893 static uint8_t rpl_clear(const void *cmd, uint16_t cmd_len,
1894 void *rsp, uint16_t *rsp_len)
1895 {
1896 int err;
1897
1898 LOG_DBG("");
1899
1900 err = bt_mesh_test_rpl_clear();
1901 if (err) {
1902 LOG_ERR("Failed to clear RPL (err %d)", err);
1903 return BTP_STATUS_FAILED;
1904 }
1905
1906 return BTP_STATUS_SUCCESS;
1907 }
1908 #endif /* CONFIG_BT_TESTING */
1909
proxy_identity_enable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1910 static uint8_t proxy_identity_enable(const void *cmd, uint16_t cmd_len,
1911 void *rsp, uint16_t *rsp_len)
1912 {
1913 int err;
1914
1915 LOG_DBG("");
1916
1917 err = bt_mesh_proxy_identity_enable();
1918 if (err) {
1919 LOG_ERR("Failed to enable proxy identity (err %d)", err);
1920 return BTP_STATUS_FAILED;
1921 }
1922
1923 return BTP_STATUS_SUCCESS;
1924 }
1925
1926 #if defined(CONFIG_BT_MESH_PROXY_CLIENT)
proxy_connect(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1927 static uint8_t proxy_connect(const void *cmd, uint16_t cmd_len,
1928 void *rsp, uint16_t *rsp_len)
1929 {
1930 const struct btp_proxy_connect_cmd *cp = cmd;
1931 int err;
1932
1933 err = bt_mesh_proxy_connect(cp->net_idx);
1934 if (err) {
1935 LOG_ERR("Failed to connect to GATT Proxy (err %d)", err);
1936 return BTP_STATUS_FAILED;
1937 }
1938
1939 return BTP_STATUS_SUCCESS;
1940 }
1941 #endif
1942
1943 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
sar_transmitter_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1944 static uint8_t sar_transmitter_get(const void *cmd, uint16_t cmd_len,
1945 void *rsp, uint16_t *rsp_len)
1946 {
1947 const struct btp_mesh_sar_transmitter_get_cmd *cp = cmd;
1948 struct bt_mesh_sar_tx tx_rsp;
1949 int err;
1950
1951 LOG_DBG("");
1952
1953 bt_mesh_sar_cfg_cli_timeout_set(5000);
1954
1955 err = bt_mesh_sar_cfg_cli_transmitter_get(
1956 net_key_idx, sys_le16_to_cpu(cp->dst), &tx_rsp);
1957 if (err) {
1958 LOG_ERR("err=%d", err);
1959 return BTP_STATUS_FAILED;
1960 }
1961
1962 return BTP_STATUS_SUCCESS;
1963 }
1964
sar_transmitter_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1965 static uint8_t sar_transmitter_set(const void *cmd, uint16_t cmd_len,
1966 void *rsp, uint16_t *rsp_len)
1967 {
1968 const struct btp_mesh_sar_transmitter_set_cmd *cp = cmd;
1969 struct bt_mesh_sar_tx set, tx_rsp;
1970 int err;
1971
1972 LOG_DBG("");
1973
1974 bt_mesh_sar_cfg_cli_timeout_set(5000);
1975
1976 set.seg_int_step = cp->tx.seg_int_step;
1977 set.unicast_retrans_count = cp->tx.unicast_retrans_count;
1978 set.unicast_retrans_int_inc = cp->tx.unicast_retrans_int_inc;
1979 set.unicast_retrans_int_step = cp->tx.unicast_retrans_int_step;
1980 set.unicast_retrans_without_prog_count =
1981 cp->tx.unicast_retrans_without_prog_count;
1982 set.multicast_retrans_count = cp->tx.multicast_retrans_count;
1983 set.multicast_retrans_int = cp->tx.multicast_retrans_int;
1984
1985 err = bt_mesh_sar_cfg_cli_transmitter_set(net_key_idx,
1986 sys_le16_to_cpu(cp->dst),
1987 &set, &tx_rsp);
1988 if (err) {
1989 LOG_ERR("err=%d", err);
1990 return BTP_STATUS_FAILED;
1991 }
1992
1993 return BTP_STATUS_SUCCESS;
1994 }
1995
sar_receiver_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1996 static uint8_t sar_receiver_get(const void *cmd, uint16_t cmd_len,
1997 void *rsp, uint16_t *rsp_len)
1998 {
1999 const struct btp_mesh_sar_receiver_get_cmd *cp = cmd;
2000 struct bt_mesh_sar_rx rx_rsp;
2001 int err;
2002
2003 LOG_DBG("");
2004
2005 err = bt_mesh_sar_cfg_cli_receiver_get(net_key_idx,
2006 sys_le16_to_cpu(cp->dst), &rx_rsp);
2007 if (err) {
2008 LOG_ERR("err=%d", err);
2009 return BTP_STATUS_FAILED;
2010 }
2011
2012 return BTP_STATUS_SUCCESS;
2013 }
2014
sar_receiver_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2015 static uint8_t sar_receiver_set(const void *cmd, uint16_t cmd_len,
2016 void *rsp, uint16_t *rsp_len)
2017 {
2018 const struct btp_mesh_sar_receiver_set_cmd *cp = cmd;
2019 struct bt_mesh_sar_rx set, rx_rsp;
2020 int err;
2021
2022 LOG_DBG("");
2023
2024 set.ack_delay_inc = cp->rx.ack_delay_inc;
2025 set.ack_retrans_count = cp->rx.ack_retrans_count;
2026 set.discard_timeout = cp->rx.discard_timeout;
2027 set.seg_thresh = cp->rx.seg_thresh;
2028 set.rx_seg_int_step = cp->rx.rx_seg_int_step;
2029
2030 err = bt_mesh_sar_cfg_cli_receiver_set(net_key_idx,
2031 sys_le16_to_cpu(cp->dst), &set,
2032 &rx_rsp);
2033 if (err) {
2034 LOG_ERR("err=%d", err);
2035 return BTP_STATUS_FAILED;
2036 }
2037
2038 return BTP_STATUS_SUCCESS;
2039 }
2040 #endif
2041
2042 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
large_comp_data_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2043 static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len,
2044 void *rsp, uint16_t *rsp_len)
2045 {
2046 const struct btp_mesh_large_comp_data_get_cmd *cp = cmd;
2047 struct btp_mesh_large_comp_data_get_rp *rp = rsp;
2048 int err;
2049
2050 NET_BUF_SIMPLE_DEFINE(data, 500);
2051 net_buf_simple_init(&data, 0);
2052
2053 struct bt_mesh_large_comp_data_rsp comp = {
2054 .data = &data,
2055 };
2056
2057 err = bt_mesh_large_comp_data_get(sys_le16_to_cpu(cp->net_idx),
2058 sys_le16_to_cpu(cp->addr), cp->page,
2059 sys_le16_to_cpu(cp->offset), &comp);
2060 if (err) {
2061 LOG_ERR("Large Composition Data Get failed (err %d)", err);
2062
2063 return BTP_STATUS_FAILED;
2064 }
2065
2066 memcpy(rp->data, comp.data->data, comp.data->len);
2067 *rsp_len = comp.data->len;
2068
2069 return BTP_STATUS_SUCCESS;
2070 }
2071
models_metadata_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2072 static uint8_t models_metadata_get(const void *cmd, uint16_t cmd_len,
2073 void *rsp, uint16_t *rsp_len)
2074 {
2075 const struct btp_mesh_models_metadata_get_cmd *cp = cmd;
2076 struct btp_mesh_models_metadata_get_rp *rp = rsp;
2077 int err;
2078
2079 NET_BUF_SIMPLE_DEFINE(data, 500);
2080 net_buf_simple_init(&data, 0);
2081
2082 struct bt_mesh_large_comp_data_rsp metadata = {
2083 .data = &data,
2084 };
2085
2086 err = bt_mesh_models_metadata_get(sys_le16_to_cpu(cp->net_idx),
2087 sys_le16_to_cpu(cp->addr), cp->page,
2088 sys_le16_to_cpu(cp->offset), &metadata);
2089
2090 if (err) {
2091 LOG_ERR("Models Metadata Get failed (err %d)", err);
2092 return BTP_STATUS_FAILED;
2093 }
2094
2095 memcpy(rp->data, metadata.data->data, metadata.data->len);
2096 *rsp_len = metadata.data->len;
2097
2098 return BTP_STATUS_SUCCESS;
2099 }
2100 #endif
2101
2102 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
subnet_bridge_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2103 static uint8_t subnet_bridge_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2104 {
2105 const struct btp_mesh_subnet_bridge_get_cmd *cp = cmd;
2106 enum bt_mesh_brg_cfg_state state;
2107 int err;
2108
2109 err = bt_mesh_brg_cfg_cli_get(net.net_idx, sys_le16_to_cpu(cp->addr), &state);
2110 if (err) {
2111 LOG_ERR("err=%d", err);
2112 return BTP_STATUS_FAILED;
2113 }
2114
2115 LOG_DBG("Subnet Bridge state: %u", state);
2116
2117 return BTP_STATUS_SUCCESS;
2118 }
2119
subnet_bridge_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2120 static uint8_t subnet_bridge_set(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2121 {
2122 const struct btp_mesh_subnet_bridge_set_cmd *cp = cmd;
2123 enum bt_mesh_brg_cfg_state state;
2124 int err;
2125
2126 state = cp->val;
2127
2128 err = bt_mesh_brg_cfg_cli_set(net.net_idx, sys_le16_to_cpu(cp->addr), state, &state);
2129 if (err) {
2130 LOG_ERR("err=%d", err);
2131 return BTP_STATUS_FAILED;
2132 }
2133
2134 LOG_DBG("Subnet Bridge state: %u", state);
2135
2136 return BTP_STATUS_SUCCESS;
2137 }
2138
bridging_table_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2139 static uint8_t bridging_table_add(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2140 {
2141 const struct btp_mesh_bridging_table_add_cmd *cp = cmd;
2142 struct bt_mesh_brg_cfg_table_entry entry;
2143 struct bt_mesh_brg_cfg_table_status rp;
2144 int err;
2145
2146 LOG_DBG("");
2147
2148 entry.directions = cp->directions;
2149 entry.net_idx1 = sys_le16_to_cpu(cp->net_idx1);
2150 entry.net_idx2 = sys_le16_to_cpu(cp->net_idx2);
2151 entry.addr1 = sys_le16_to_cpu(cp->addr1);
2152 entry.addr2 = sys_le16_to_cpu(cp->addr2);
2153
2154 err = bt_mesh_brg_cfg_cli_table_add(net_key_idx, sys_le16_to_cpu(cp->addr), &entry, &rp);
2155 if (err) {
2156 LOG_ERR("err=%d", err);
2157 return BTP_STATUS_FAILED;
2158 }
2159
2160 return BTP_STATUS_SUCCESS;
2161 }
2162
bridging_table_remove(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2163 static uint8_t bridging_table_remove(const void *cmd, uint16_t cmd_len, void *rsp,
2164 uint16_t *rsp_len)
2165 {
2166 const struct btp_mesh_bridging_table_remove_cmd *cp = cmd;
2167 struct bt_mesh_brg_cfg_table_status rp;
2168 int err;
2169
2170 LOG_DBG("");
2171
2172 err = bt_mesh_brg_cfg_cli_table_remove(
2173 net_key_idx, sys_le16_to_cpu(cp->addr), sys_le16_to_cpu(cp->net_idx1),
2174 sys_le16_to_cpu(cp->net_idx2), sys_le16_to_cpu(cp->addr1),
2175 sys_le16_to_cpu(cp->addr2), &rp);
2176
2177 if (err) {
2178 LOG_ERR("err=%d", err);
2179 return BTP_STATUS_FAILED;
2180 }
2181
2182 return BTP_STATUS_SUCCESS;
2183 }
2184
bridged_subnets_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2185 static uint8_t bridged_subnets_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2186 {
2187 const struct btp_mesh_bridged_subnets_get_cmd *cp = cmd;
2188 struct bt_mesh_brg_cfg_filter_netkey filter_net_idx;
2189 struct bt_mesh_brg_cfg_subnets_list rp;
2190 int err;
2191
2192 LOG_DBG("");
2193
2194 /* Initialize list ptr to NULL to prevent the client copying response to whatever was
2195 * on the stack where `rp` was allocated.
2196 */
2197 rp.list = NULL;
2198
2199 filter_net_idx.filter = cp->filter;
2200 filter_net_idx.net_idx = sys_le16_to_cpu(cp->net_idx);
2201
2202 err = bt_mesh_brg_cfg_cli_subnets_get(net_key_idx, sys_le16_to_cpu(cp->addr),
2203 filter_net_idx, cp->start_idx, &rp);
2204 if (err) {
2205 LOG_ERR("err=%d", err);
2206 return BTP_STATUS_FAILED;
2207 }
2208
2209 return BTP_STATUS_SUCCESS;
2210 }
2211
bridging_table_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2212 static uint8_t bridging_table_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2213 {
2214 const struct btp_mesh_bridging_table_get_cmd *cp = cmd;
2215 struct bt_mesh_brg_cfg_table_list rp;
2216 int err;
2217
2218 LOG_DBG("");
2219
2220 /* Initialize list ptr to NULL to prevent the client copying response to whatever was
2221 * on the stack where `rp` was allocated.
2222 */
2223 rp.list = NULL;
2224
2225 err = bt_mesh_brg_cfg_cli_table_get(
2226 net_key_idx, sys_le16_to_cpu(cp->addr), sys_le16_to_cpu(cp->net_idx1),
2227 sys_le16_to_cpu(cp->net_idx2), sys_le16_to_cpu(cp->start_idx), &rp);
2228 if (err) {
2229 LOG_ERR("err=%d", err);
2230 return BTP_STATUS_FAILED;
2231 }
2232
2233 return BTP_STATUS_SUCCESS;
2234 }
2235
bridging_table_size_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2236 static uint8_t bridging_table_size_get(const void *cmd, uint16_t cmd_len, void *rsp,
2237 uint16_t *rsp_len)
2238 {
2239 const struct btp_mesh_bridging_table_size_get_cmd *cp = cmd;
2240 uint16_t size;
2241 int err;
2242
2243 LOG_DBG("");
2244
2245 err = bt_mesh_brg_cfg_cli_table_size_get(net_key_idx, sys_le16_to_cpu(cp->addr), &size);
2246 if (err) {
2247 LOG_ERR("err=%d", err);
2248 return BTP_STATUS_FAILED;
2249 }
2250
2251 return BTP_STATUS_SUCCESS;
2252 }
2253
2254 #endif
2255
composition_data_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2256 static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2257 {
2258 const struct btp_mesh_comp_data_get_cmd *cp = cmd;
2259 struct btp_mesh_comp_data_get_rp *rp = rsp;
2260 uint8_t page;
2261 struct net_buf_simple *comp = NET_BUF_SIMPLE(128);
2262 int err;
2263
2264 LOG_DBG("");
2265
2266 bt_mesh_cfg_cli_timeout_set(10 * MSEC_PER_SEC);
2267
2268 net_buf_simple_init(comp, 0);
2269
2270 err = bt_mesh_cfg_cli_comp_data_get(sys_le16_to_cpu(cp->net_idx),
2271 sys_le16_to_cpu(cp->address),
2272 cp->page, &page, comp);
2273 if (err) {
2274 LOG_ERR("err %d", err);
2275 return BTP_STATUS_FAILED;
2276 }
2277
2278 rp->data[0] = page;
2279 memcpy(rp->data + 1, comp->data, comp->len);
2280 *rsp_len = comp->len + 1;
2281
2282 return BTP_STATUS_SUCCESS;
2283 }
2284
change_prepare(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2285 static uint8_t change_prepare(const void *cmd, uint16_t cmd_len,
2286 void *rsp, uint16_t *rsp_len)
2287 {
2288 int err;
2289
2290 LOG_DBG("");
2291
2292 err = bt_mesh_comp_change_prepare();
2293 if (err < 0) {
2294 return BTP_STATUS_FAILED;
2295 }
2296
2297 #if CONFIG_BT_MESH_LARGE_COMP_DATA_SRV
2298 err = bt_mesh_models_metadata_change_prepare();
2299 if (err < 0) {
2300 return BTP_STATUS_FAILED;
2301 }
2302 #endif
2303
2304 return BTP_STATUS_SUCCESS;
2305 }
2306
config_krp_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2307 static uint8_t config_krp_get(const void *cmd, uint16_t cmd_len,
2308 void *rsp, uint16_t *rsp_len)
2309 {
2310 const struct btp_mesh_cfg_krp_get_cmd *cp = cmd;
2311 struct btp_mesh_cfg_krp_get_rp *rp = rsp;
2312 uint8_t status;
2313 uint8_t phase;
2314 int err;
2315
2316 LOG_DBG("");
2317
2318 err = bt_mesh_cfg_cli_krp_get(sys_le16_to_cpu(cp->net_idx),
2319 sys_le16_to_cpu(cp->address),
2320 sys_le16_to_cpu(cp->key_net_idx),
2321 &status, &phase);
2322
2323 if (err) {
2324 LOG_ERR("err %d", err);
2325 return BTP_STATUS_FAILED;
2326 }
2327
2328 rp->status = status;
2329 rp->phase = phase;
2330
2331 *rsp_len = sizeof(*rp);
2332
2333 return BTP_STATUS_SUCCESS;
2334 }
2335
config_krp_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2336 static uint8_t config_krp_set(const void *cmd, uint16_t cmd_len,
2337 void *rsp, uint16_t *rsp_len)
2338 {
2339 const struct btp_mesh_cfg_krp_set_cmd *cp = cmd;
2340 struct btp_mesh_cfg_krp_set_rp *rp = rsp;
2341 uint8_t status;
2342 uint8_t phase;
2343 int err;
2344
2345 LOG_DBG("");
2346
2347 err = bt_mesh_cfg_cli_krp_set(sys_le16_to_cpu(cp->net_idx),
2348 sys_le16_to_cpu(cp->address),
2349 sys_le16_to_cpu(cp->key_net_idx),
2350 cp->transition, &status, &phase);
2351 if (err) {
2352 LOG_ERR("err %d", err);
2353 return BTP_STATUS_FAILED;
2354 }
2355
2356 rp->status = status;
2357 rp->phase = phase;
2358
2359 *rsp_len = sizeof(*rp);
2360
2361 return BTP_STATUS_SUCCESS;
2362 }
2363
config_beacon_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2364 static uint8_t config_beacon_get(const void *cmd, uint16_t cmd_len,
2365 void *rsp, uint16_t *rsp_len)
2366 {
2367 const struct btp_mesh_cfg_beacon_get_cmd *cp = cmd;
2368 struct btp_mesh_cfg_beacon_get_rp *rp = rsp;
2369 uint8_t status;
2370 int err;
2371
2372 LOG_DBG("");
2373
2374 err = bt_mesh_cfg_cli_beacon_get(sys_le16_to_cpu(cp->net_idx),
2375 sys_le16_to_cpu(cp->address), &status);
2376 if (err) {
2377 LOG_ERR("err %d", err);
2378 return BTP_STATUS_FAILED;
2379 }
2380
2381 rp->status = status;
2382 *rsp_len = sizeof(*rp);
2383
2384 return BTP_STATUS_SUCCESS;
2385 }
2386
config_beacon_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2387 static uint8_t config_beacon_set(const void *cmd, uint16_t cmd_len,
2388 void *rsp, uint16_t *rsp_len)
2389 {
2390 const struct btp_mesh_cfg_beacon_set_cmd *cp = cmd;
2391 struct btp_mesh_cfg_beacon_set_rp *rp = rsp;
2392 uint8_t status;
2393 int err;
2394
2395 LOG_DBG("");
2396
2397 err = bt_mesh_cfg_cli_beacon_set(sys_le16_to_cpu(cp->net_idx),
2398 sys_le16_to_cpu(cp->address), cp->val,
2399 &status);
2400 if (err) {
2401 LOG_ERR("err %d", err);
2402 return BTP_STATUS_FAILED;
2403 }
2404
2405 rp->status = status;
2406 *rsp_len = sizeof(*rp);
2407
2408 return BTP_STATUS_SUCCESS;
2409 }
2410
config_default_ttl_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2411 static uint8_t config_default_ttl_get(const void *cmd, uint16_t cmd_len,
2412 void *rsp, uint16_t *rsp_len)
2413 {
2414 const struct btp_mesh_cfg_default_ttl_get_cmd *cp = cmd;
2415 struct btp_mesh_cfg_default_ttl_get_rp *rp = rsp;
2416 uint8_t status;
2417 int err;
2418
2419 LOG_DBG("");
2420
2421 err = bt_mesh_cfg_cli_ttl_get(sys_le16_to_cpu(cp->net_idx),
2422 sys_le16_to_cpu(cp->address), &status);
2423
2424 if (err) {
2425 LOG_ERR("err %d", err);
2426 return BTP_STATUS_FAILED;
2427 }
2428
2429 rp->status = status;
2430 *rsp_len = sizeof(*rp);
2431
2432 return BTP_STATUS_SUCCESS;
2433 }
2434
config_default_ttl_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2435 static uint8_t config_default_ttl_set(const void *cmd, uint16_t cmd_len,
2436 void *rsp, uint16_t *rsp_len)
2437 {
2438 const struct btp_mesh_cfg_default_ttl_set_cmd *cp = cmd;
2439 struct btp_mesh_cfg_default_ttl_set_rp *rp = rsp;
2440 uint8_t status;
2441 int err;
2442
2443 LOG_DBG("");
2444
2445 err = bt_mesh_cfg_cli_ttl_set(sys_le16_to_cpu(cp->net_idx),
2446 sys_le16_to_cpu(cp->address), cp->val,
2447 &status);
2448
2449 if (err) {
2450 LOG_ERR("err %d", err);
2451 return BTP_STATUS_FAILED;
2452 }
2453
2454 rp->status = status;
2455 *rsp_len = sizeof(*rp);
2456
2457 return BTP_STATUS_SUCCESS;
2458 }
2459
config_gatt_proxy_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2460 static uint8_t config_gatt_proxy_get(const void *cmd, uint16_t cmd_len,
2461 void *rsp, uint16_t *rsp_len)
2462 {
2463 const struct btp_mesh_cfg_gatt_proxy_get_cmd *cp = cmd;
2464 struct btp_mesh_cfg_gatt_proxy_get_rp *rp = rsp;
2465 uint8_t status;
2466 int err;
2467
2468 LOG_DBG("");
2469
2470 err = bt_mesh_cfg_cli_gatt_proxy_get(sys_le16_to_cpu(cp->net_idx),
2471 sys_le16_to_cpu(cp->address),
2472 &status);
2473 if (err) {
2474 LOG_ERR("err %d", err);
2475 return BTP_STATUS_FAILED;
2476 }
2477
2478 rp->status = status;
2479 *rsp_len = sizeof(*rp);
2480
2481 return BTP_STATUS_SUCCESS;
2482 }
2483
config_gatt_proxy_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2484 static uint8_t config_gatt_proxy_set(const void *cmd, uint16_t cmd_len,
2485 void *rsp, uint16_t *rsp_len)
2486 {
2487 const struct btp_mesh_cfg_gatt_proxy_set_cmd *cp = cmd;
2488 struct btp_mesh_cfg_gatt_proxy_set_rp *rp = rsp;
2489 uint8_t status;
2490 int err;
2491
2492 LOG_DBG("");
2493
2494 err = bt_mesh_cfg_cli_gatt_proxy_set(sys_le16_to_cpu(cp->net_idx),
2495 sys_le16_to_cpu(cp->address),
2496 cp->val, &status);
2497 if (err) {
2498 LOG_ERR("err %d", err);
2499 return BTP_STATUS_FAILED;
2500 }
2501
2502 rp->status = status;
2503 *rsp_len = sizeof(*rp);
2504
2505 return BTP_STATUS_SUCCESS;
2506 }
2507
config_friend_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2508 static uint8_t config_friend_get(const void *cmd, uint16_t cmd_len,
2509 void *rsp, uint16_t *rsp_len)
2510 {
2511 const struct btp_mesh_cfg_friend_get_cmd *cp = cmd;
2512 struct btp_mesh_cfg_friend_get_rp *rp = rsp;
2513 uint8_t status;
2514 int err;
2515
2516 LOG_DBG("");
2517
2518 err = bt_mesh_cfg_cli_friend_get(sys_le16_to_cpu(cp->net_idx),
2519 sys_le16_to_cpu(cp->address),
2520 &status);
2521
2522 if (err) {
2523 LOG_ERR("err %d", err);
2524 return BTP_STATUS_FAILED;
2525 }
2526
2527 rp->status = status;
2528 *rsp_len = sizeof(*rp);
2529
2530 return BTP_STATUS_SUCCESS;
2531 }
2532
config_friend_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2533 static uint8_t config_friend_set(const void *cmd, uint16_t cmd_len,
2534 void *rsp, uint16_t *rsp_len)
2535 {
2536 const struct btp_mesh_cfg_friend_set_cmd *cp = cmd;
2537 struct btp_mesh_cfg_friend_set_rp *rp = rsp;
2538 uint8_t status;
2539 int err;
2540
2541 LOG_DBG("");
2542
2543 err = bt_mesh_cfg_cli_friend_set(sys_le16_to_cpu(cp->net_idx),
2544 sys_le16_to_cpu(cp->address),
2545 cp->val, &status);
2546
2547 if (err) {
2548 LOG_ERR("err %d", err);
2549 return BTP_STATUS_FAILED;
2550 }
2551
2552 rp->status = status;
2553 *rsp_len = sizeof(*rp);
2554
2555 return BTP_STATUS_SUCCESS;
2556 }
2557
config_relay_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2558 static uint8_t config_relay_get(const void *cmd, uint16_t cmd_len,
2559 void *rsp, uint16_t *rsp_len)
2560 {
2561 const struct btp_mesh_cfg_relay_get_cmd *cp = cmd;
2562 struct btp_mesh_cfg_relay_get_rp *rp = rsp;
2563 uint8_t status;
2564 uint8_t transmit;
2565 int err;
2566
2567 LOG_DBG("");
2568
2569 err = bt_mesh_cfg_cli_relay_get(sys_le16_to_cpu(cp->net_idx),
2570 sys_le16_to_cpu(cp->address), &status,
2571 &transmit);
2572
2573 if (err) {
2574 LOG_ERR("err %d", err);
2575 return BTP_STATUS_FAILED;
2576 }
2577
2578 rp->status = status;
2579 *rsp_len = sizeof(*rp);
2580
2581 return BTP_STATUS_SUCCESS;
2582 }
2583
config_relay_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2584 static uint8_t config_relay_set(const void *cmd, uint16_t cmd_len,
2585 void *rsp, uint16_t *rsp_len)
2586 {
2587 const struct btp_mesh_cfg_relay_set_cmd *cp = cmd;
2588 struct btp_mesh_cfg_relay_set_rp *rp = rsp;
2589 uint8_t status;
2590 uint8_t transmit;
2591 int err;
2592
2593 LOG_DBG("");
2594
2595 err = bt_mesh_cfg_cli_relay_set(sys_le16_to_cpu(cp->net_idx),
2596 sys_le16_to_cpu(cp->address),
2597 cp->new_relay, cp->new_transmit,
2598 &status, &transmit);
2599
2600 if (err) {
2601 LOG_ERR("err %d", err);
2602 return BTP_STATUS_FAILED;
2603 }
2604
2605 rp->status = status;
2606 *rsp_len = sizeof(*rp);
2607
2608 return BTP_STATUS_SUCCESS;
2609 }
2610
config_mod_pub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2611 static uint8_t config_mod_pub_get(const void *cmd, uint16_t cmd_len,
2612 void *rsp, uint16_t *rsp_len)
2613 {
2614 const struct btp_mesh_cfg_model_pub_get_cmd *cp = cmd;
2615 struct btp_mesh_cfg_model_pub_get_rp *rp = rsp;
2616 struct bt_mesh_cfg_cli_mod_pub pub;
2617 uint8_t status;
2618 int err;
2619
2620 LOG_DBG("");
2621
2622 err = bt_mesh_cfg_cli_mod_pub_get(sys_le16_to_cpu(cp->net_idx),
2623 sys_le16_to_cpu(cp->address),
2624 sys_le16_to_cpu(cp->elem_address),
2625 sys_le16_to_cpu(cp->model_id),
2626 &pub, &status);
2627
2628 if (err) {
2629 LOG_ERR("err %d", err);
2630 return BTP_STATUS_FAILED;
2631 }
2632
2633 rp->status = status;
2634 *rsp_len = sizeof(*rp);
2635
2636 return BTP_STATUS_SUCCESS;
2637 }
2638
config_mod_pub_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2639 static uint8_t config_mod_pub_set(const void *cmd, uint16_t cmd_len,
2640 void *rsp, uint16_t *rsp_len)
2641 {
2642 const struct btp_mesh_cfg_model_pub_set_cmd *cp = cmd;
2643 struct btp_mesh_cfg_model_pub_set_rp *rp = rsp;
2644 struct bt_mesh_cfg_cli_mod_pub pub;
2645 uint8_t status;
2646 int err;
2647
2648 LOG_DBG("");
2649
2650 pub.addr = sys_le16_to_cpu(cp->pub_addr);
2651 pub.uuid = NULL;
2652 pub.app_idx = sys_le16_to_cpu(cp->app_idx);
2653 pub.cred_flag = cp->cred_flag;
2654 pub.ttl = cp->ttl;
2655 pub.period = cp->period;
2656 pub.transmit = cp->transmit;
2657
2658 err = bt_mesh_cfg_cli_mod_pub_set(sys_le16_to_cpu(cp->net_idx),
2659 sys_le16_to_cpu(cp->address),
2660 sys_le16_to_cpu(cp->elem_address),
2661 sys_le16_to_cpu(cp->model_id),
2662 &pub, &status);
2663
2664 if (err) {
2665 LOG_ERR("err %d", err);
2666 return BTP_STATUS_FAILED;
2667 }
2668
2669 rp->status = status;
2670 *rsp_len = sizeof(*rp);
2671
2672 return BTP_STATUS_SUCCESS;
2673 }
2674
config_mod_pub_va_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2675 static uint8_t config_mod_pub_va_set(const void *cmd, uint16_t cmd_len,
2676 void *rsp, uint16_t *rsp_len)
2677 {
2678 const struct btp_mesh_cfg_model_pub_va_set_cmd *cp = cmd;
2679 struct btp_mesh_cfg_model_pub_va_set_rp *rp = rsp;
2680 uint8_t status;
2681 struct bt_mesh_cfg_cli_mod_pub pub;
2682 int err;
2683
2684 LOG_DBG("");
2685
2686 pub.uuid = cp->uuid;
2687 pub.app_idx = sys_le16_to_cpu(cp->app_idx);
2688 pub.cred_flag = cp->cred_flag;
2689 pub.ttl = cp->ttl;
2690 pub.period = cp->period;
2691 pub.transmit = cp->transmit;
2692
2693 err = bt_mesh_cfg_cli_mod_pub_set(sys_le16_to_cpu(cp->net_idx),
2694 sys_le16_to_cpu(cp->address),
2695 sys_le16_to_cpu(cp->elem_address),
2696 sys_le16_to_cpu(cp->model_id),
2697 &pub, &status);
2698
2699 if (err) {
2700 LOG_ERR("err %d", err);
2701 return BTP_STATUS_FAILED;
2702 }
2703
2704 rp->status = status;
2705 *rsp_len = sizeof(*rp);
2706
2707 return BTP_STATUS_SUCCESS;
2708 }
2709
config_mod_sub_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2710 static uint8_t config_mod_sub_add(const void *cmd, uint16_t cmd_len,
2711 void *rsp, uint16_t *rsp_len)
2712 {
2713 const struct btp_mesh_cfg_model_sub_add_cmd *cp = cmd;
2714 struct btp_mesh_cfg_model_sub_add_rp *rp = rsp;
2715 uint8_t status;
2716 int err;
2717
2718 LOG_DBG("");
2719
2720 err = bt_mesh_cfg_cli_mod_sub_add(sys_le16_to_cpu(cp->net_idx),
2721 sys_le16_to_cpu(cp->address),
2722 sys_le16_to_cpu(cp->elem_address),
2723 sys_le16_to_cpu(cp->sub_addr),
2724 sys_le16_to_cpu(cp->model_id),
2725 &status);
2726
2727 if (err) {
2728 LOG_ERR("err %d", err);
2729 return BTP_STATUS_FAILED;
2730 }
2731
2732 rp->status = status;
2733 *rsp_len = sizeof(*rp);
2734
2735 return BTP_STATUS_SUCCESS;
2736 }
2737
config_mod_sub_ovw(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2738 static uint8_t config_mod_sub_ovw(const void *cmd, uint16_t cmd_len,
2739 void *rsp, uint16_t *rsp_len)
2740 {
2741 const struct btp_mesh_cfg_model_sub_ovw_cmd *cp = cmd;
2742 struct btp_mesh_cfg_model_sub_add_rp *rp = rsp;
2743 uint8_t status;
2744 int err;
2745
2746 LOG_DBG("");
2747
2748 err = bt_mesh_cfg_cli_mod_sub_overwrite(sys_le16_to_cpu(cp->net_idx),
2749 sys_le16_to_cpu(cp->address),
2750 sys_le16_to_cpu(cp->elem_address),
2751 sys_le16_to_cpu(cp->sub_addr),
2752 sys_le16_to_cpu(cp->model_id),
2753 &status);
2754 if (err) {
2755 LOG_ERR("err %d", err);
2756 return BTP_STATUS_FAILED;
2757 }
2758
2759 rp->status = status;
2760 *rsp_len = sizeof(*rp);
2761
2762 return BTP_STATUS_SUCCESS;
2763 }
2764
config_mod_sub_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2765 static uint8_t config_mod_sub_del(const void *cmd, uint16_t cmd_len,
2766 void *rsp, uint16_t *rsp_len)
2767 {
2768 const struct btp_mesh_cfg_model_sub_del_cmd *cp = cmd;
2769 struct btp_mesh_cfg_model_sub_del_rp *rp = rsp;
2770 uint8_t status;
2771 int err;
2772
2773 LOG_DBG("");
2774
2775 err = bt_mesh_cfg_cli_mod_sub_del(sys_le16_to_cpu(cp->net_idx),
2776 sys_le16_to_cpu(cp->address),
2777 sys_le16_to_cpu(cp->elem_address),
2778 sys_le16_to_cpu(cp->sub_addr),
2779 sys_le16_to_cpu(cp->model_id),
2780 &status);
2781 if (err) {
2782 LOG_ERR("err %d", err);
2783 return BTP_STATUS_FAILED;
2784 }
2785
2786 rp->status = status;
2787 *rsp_len = sizeof(*rp);
2788
2789 return BTP_STATUS_SUCCESS;
2790 }
2791
config_mod_sub_del_all(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2792 static uint8_t config_mod_sub_del_all(const void *cmd, uint16_t cmd_len,
2793 void *rsp, uint16_t *rsp_len)
2794 {
2795 const struct btp_mesh_cfg_model_sub_del_all_cmd *cp = cmd;
2796 struct btp_mesh_cfg_model_sub_del_all_rp *rp = rsp;
2797 uint8_t status;
2798 int err;
2799
2800 LOG_DBG("");
2801
2802 err = bt_mesh_cfg_cli_mod_sub_del_all(sys_le16_to_cpu(cp->net_idx),
2803 sys_le16_to_cpu(cp->address),
2804 sys_le16_to_cpu(cp->elem_address),
2805 sys_le16_to_cpu(cp->model_id),
2806 &status);
2807
2808 if (err) {
2809 LOG_ERR("err %d", err);
2810 return BTP_STATUS_FAILED;
2811 }
2812
2813 rp->status = status;
2814 *rsp_len = sizeof(*rp);
2815
2816 return BTP_STATUS_SUCCESS;
2817 }
2818
config_mod_sub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2819 static uint8_t config_mod_sub_get(const void *cmd, uint16_t cmd_len,
2820 void *rsp, uint16_t *rsp_len)
2821 {
2822 const struct btp_mesh_cfg_model_sub_get_cmd *cp = cmd;
2823 struct btp_mesh_cfg_model_sub_get_rp *rp = rsp;
2824 uint8_t status;
2825 int16_t subs;
2826 size_t sub_cn;
2827 int err;
2828
2829 LOG_DBG("");
2830
2831 err = bt_mesh_cfg_cli_mod_sub_get(sys_le16_to_cpu(cp->net_idx),
2832 sys_le16_to_cpu(cp->address),
2833 sys_le16_to_cpu(cp->elem_address),
2834 sys_le16_to_cpu(cp->model_id),
2835 &status, &subs, &sub_cn);
2836 if (err) {
2837 LOG_ERR("err %d", err);
2838 return BTP_STATUS_FAILED;
2839 }
2840
2841 rp->status = status;
2842 *rsp_len = sizeof(*rp);
2843
2844 return BTP_STATUS_SUCCESS;
2845 }
2846
config_mod_sub_get_vnd(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2847 static uint8_t config_mod_sub_get_vnd(const void *cmd, uint16_t cmd_len,
2848 void *rsp, uint16_t *rsp_len)
2849 {
2850 const struct btp_mesh_cfg_model_sub_get_vnd_cmd *cp = cmd;
2851 struct btp_mesh_cfg_model_sub_get_vnd_rp *rp = rsp;
2852 uint8_t status;
2853 uint16_t subs;
2854 size_t sub_cn;
2855 int err;
2856
2857 LOG_DBG("");
2858
2859 err = bt_mesh_cfg_cli_mod_sub_get_vnd(sys_le16_to_cpu(cp->net_idx),
2860 sys_le16_to_cpu(cp->address),
2861 sys_le16_to_cpu(cp->elem_address),
2862 sys_le16_to_cpu(cp->model_id),
2863 sys_le16_to_cpu(cp->cid),
2864 &status, &subs, &sub_cn);
2865 if (err) {
2866 LOG_ERR("err %d", err);
2867 return BTP_STATUS_FAILED;
2868 }
2869
2870 rp->status = status;
2871 *rsp_len = sizeof(*rp);
2872
2873 return BTP_STATUS_SUCCESS;
2874 }
2875
config_mod_sub_va_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2876 static uint8_t config_mod_sub_va_add(const void *cmd, uint16_t cmd_len,
2877 void *rsp, uint16_t *rsp_len)
2878 {
2879 const struct btp_mesh_cfg_model_sub_va_add_cmd *cp = cmd;
2880 struct btp_mesh_cfg_model_sub_va_add_rp *rp = rsp;
2881 uint8_t status;
2882 uint16_t virt_addr_rcv;
2883 int err;
2884
2885 LOG_DBG("");
2886
2887 err = bt_mesh_cfg_cli_mod_sub_va_add(sys_le16_to_cpu(cp->net_idx),
2888 sys_le16_to_cpu(cp->address),
2889 sys_le16_to_cpu(cp->elem_address),
2890 sys_le16_to_cpu(cp->uuid),
2891 sys_le16_to_cpu(cp->model_id),
2892 &virt_addr_rcv, &status);
2893
2894 if (err) {
2895 LOG_ERR("err %d", err);
2896 return BTP_STATUS_FAILED;
2897 }
2898
2899 rp->status = status;
2900 *rsp_len = sizeof(*rp);
2901
2902 return BTP_STATUS_SUCCESS;
2903 }
2904
config_mod_sub_va_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2905 static uint8_t config_mod_sub_va_del(const void *cmd, uint16_t cmd_len,
2906 void *rsp, uint16_t *rsp_len)
2907 {
2908 const struct btp_mesh_cfg_model_sub_va_del_cmd *cp = cmd;
2909 struct btp_mesh_cfg_model_sub_va_del_rp *rp = rsp;
2910 uint8_t status;
2911 uint16_t virt_addr_rcv;
2912 int err;
2913
2914 LOG_DBG("");
2915
2916 err = bt_mesh_cfg_cli_mod_sub_va_del(sys_le16_to_cpu(cp->net_idx),
2917 sys_le16_to_cpu(cp->address),
2918 sys_le16_to_cpu(cp->elem_address),
2919 sys_le16_to_cpu(cp->uuid),
2920 sys_le16_to_cpu(cp->model_id),
2921 &virt_addr_rcv, &status);
2922
2923 if (err) {
2924 LOG_ERR("err %d", err);
2925 return BTP_STATUS_FAILED;
2926 }
2927
2928 rp->status = status;
2929 *rsp_len = sizeof(*rp);
2930
2931 return BTP_STATUS_SUCCESS;
2932 }
2933
config_mod_sub_va_ovw(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2934 static uint8_t config_mod_sub_va_ovw(const void *cmd, uint16_t cmd_len,
2935 void *rsp, uint16_t *rsp_len)
2936 {
2937 const struct btp_mesh_cfg_model_sub_va_ovw_cmd *cp = cmd;
2938 struct btp_mesh_cfg_model_sub_va_ovw_rp *rp = rsp;
2939 uint8_t status;
2940 uint16_t virt_addr_rcv;
2941 int err;
2942
2943 LOG_DBG("");
2944
2945 err = bt_mesh_cfg_cli_mod_sub_va_overwrite(sys_le16_to_cpu(cp->net_idx),
2946 sys_le16_to_cpu(cp->address),
2947 sys_le16_to_cpu(cp->elem_address),
2948 sys_le16_to_cpu(cp->uuid),
2949 sys_le16_to_cpu(cp->model_id),
2950 &virt_addr_rcv, &status);
2951
2952 if (err) {
2953 LOG_ERR("err %d", err);
2954 return BTP_STATUS_FAILED;
2955 }
2956
2957 rp->status = status;
2958 *rsp_len = sizeof(*rp);
2959
2960 return BTP_STATUS_SUCCESS;
2961 }
2962
config_netkey_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2963 static uint8_t config_netkey_add(const void *cmd, uint16_t cmd_len,
2964 void *rsp, uint16_t *rsp_len)
2965 {
2966 const struct btp_mesh_cfg_netkey_add_cmd *cp = cmd;
2967 struct btp_mesh_cfg_netkey_add_rp *rp = rsp;
2968 uint8_t status;
2969 int err;
2970
2971 LOG_DBG("");
2972
2973 err = bt_mesh_cfg_cli_net_key_add(sys_le16_to_cpu(cp->net_idx),
2974 sys_le16_to_cpu(cp->address),
2975 sys_le16_to_cpu(cp->net_key_idx),
2976 cp->net_key, &status);
2977
2978 if (err) {
2979 LOG_ERR("err %d", err);
2980 return BTP_STATUS_FAILED;
2981 }
2982
2983 rp->status = status;
2984 *rsp_len = sizeof(*rp);
2985
2986 return BTP_STATUS_SUCCESS;
2987 }
2988
config_netkey_update(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2989 static uint8_t config_netkey_update(const void *cmd, uint16_t cmd_len,
2990 void *rsp, uint16_t *rsp_len)
2991 {
2992 const struct btp_mesh_cfg_netkey_update_cmd *cp = cmd;
2993 struct btp_mesh_cfg_netkey_update_rp *rp = rsp;
2994 uint8_t status;
2995 int err;
2996
2997 LOG_DBG("");
2998
2999 err = bt_mesh_cfg_cli_net_key_update(sys_le16_to_cpu(cp->net_idx),
3000 sys_le16_to_cpu(cp->address),
3001 sys_le16_to_cpu(cp->net_key_idx),
3002 cp->net_key,
3003 &status);
3004
3005 if (err) {
3006 LOG_ERR("err %d", err);
3007 return BTP_STATUS_FAILED;
3008 }
3009
3010 rp->status = status;
3011 *rsp_len = sizeof(*rp);
3012
3013 return BTP_STATUS_SUCCESS;
3014 }
3015
config_netkey_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3016 static uint8_t config_netkey_get(const void *cmd, uint16_t cmd_len,
3017 void *rsp, uint16_t *rsp_len)
3018 {
3019 const struct btp_mesh_cfg_netkey_get_cmd *cp = cmd;
3020 struct btp_mesh_cfg_netkey_get_rp *rp = rsp;
3021 size_t key_cnt = 1;
3022 uint16_t keys;
3023 int err;
3024
3025 LOG_DBG("");
3026
3027 err = bt_mesh_cfg_cli_net_key_get(sys_le16_to_cpu(cp->net_idx),
3028 sys_le16_to_cpu(cp->address),
3029 &keys, &key_cnt);
3030 if (err) {
3031 LOG_ERR("err %d", err);
3032 return BTP_STATUS_FAILED;
3033 }
3034
3035 /* for historical reasons this command has status in response */
3036 rp->status = 0;
3037 *rsp_len = sizeof(*rp);
3038
3039 return BTP_STATUS_SUCCESS;
3040 }
3041
config_netkey_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3042 static uint8_t config_netkey_del(const void *cmd, uint16_t cmd_len,
3043 void *rsp, uint16_t *rsp_len)
3044 {
3045 const struct btp_mesh_cfg_netkey_del_cmd *cp = cmd;
3046 struct btp_mesh_cfg_netkey_del_rp *rp = rsp;
3047 uint8_t status;
3048 int err;
3049
3050 LOG_DBG("");
3051
3052 err = bt_mesh_cfg_cli_net_key_del(sys_le16_to_cpu(cp->net_idx),
3053 sys_le16_to_cpu(cp->address),
3054 sys_le16_to_cpu(cp->net_key_idx),
3055 &status);
3056
3057 if (err) {
3058 LOG_ERR("err %d", err);
3059 return BTP_STATUS_FAILED;
3060 }
3061
3062 rp->status = status;
3063 *rsp_len = sizeof(*rp);
3064
3065 return BTP_STATUS_SUCCESS;
3066 }
3067
config_appkey_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3068 static uint8_t config_appkey_add(const void *cmd, uint16_t cmd_len,
3069 void *rsp, uint16_t *rsp_len)
3070 {
3071 const struct btp_mesh_cfg_appkey_add_cmd *cp = cmd;
3072 struct btp_mesh_cfg_appkey_add_rp *rp = rsp;
3073 uint8_t status;
3074 int err;
3075
3076 LOG_DBG("");
3077
3078 err = bt_mesh_cfg_cli_app_key_add(sys_le16_to_cpu(cp->net_idx),
3079 sys_le16_to_cpu(cp->address),
3080 sys_le16_to_cpu(cp->net_key_idx),
3081 sys_le16_to_cpu(cp->app_key_idx),
3082 sys_le16_to_cpu(cp->app_key),
3083 &status);
3084
3085 if (err) {
3086 LOG_ERR("err %d", err);
3087 return BTP_STATUS_FAILED;
3088 }
3089
3090 rp->status = status;
3091 *rsp_len = sizeof(*rp);
3092
3093 return BTP_STATUS_SUCCESS;
3094 }
3095
config_appkey_update(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3096 static uint8_t config_appkey_update(const void *cmd, uint16_t cmd_len,
3097 void *rsp, uint16_t *rsp_len)
3098 {
3099 const struct btp_mesh_cfg_appkey_update_cmd *cp = cmd;
3100 struct btp_mesh_cfg_appkey_update_rp *rp = rsp;
3101 uint8_t status;
3102 int err;
3103
3104 LOG_DBG("");
3105
3106 err = bt_mesh_cfg_cli_app_key_update(sys_le16_to_cpu(cp->net_idx),
3107 sys_le16_to_cpu(cp->address),
3108 sys_le16_to_cpu(cp->net_key_idx),
3109 sys_le16_to_cpu(cp->app_key_idx),
3110 sys_le16_to_cpu(cp->app_key),
3111 &status);
3112
3113 if (err) {
3114 LOG_ERR("err %d", err);
3115 return BTP_STATUS_FAILED;
3116 }
3117
3118 rp->status = status;
3119 *rsp_len = sizeof(*rp);
3120
3121 return BTP_STATUS_SUCCESS;
3122 }
3123
config_appkey_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3124 static uint8_t config_appkey_del(const void *cmd, uint16_t cmd_len,
3125 void *rsp, uint16_t *rsp_len)
3126 {
3127 const struct btp_mesh_cfg_appkey_del_cmd *cp = cmd;
3128 struct btp_mesh_cfg_appkey_del_rp *rp = rsp;
3129 uint8_t status;
3130 int err;
3131
3132 LOG_DBG("");
3133
3134 err = bt_mesh_cfg_cli_app_key_del(sys_le16_to_cpu(cp->net_idx),
3135 sys_le16_to_cpu(cp->address),
3136 sys_le16_to_cpu(cp->net_key_idx),
3137 sys_le16_to_cpu(cp->app_key_idx),
3138 &status);
3139
3140 if (err) {
3141 LOG_ERR("err %d", err);
3142 return BTP_STATUS_FAILED;
3143 }
3144
3145 rp->status = status;
3146 *rsp_len = sizeof(*rp);
3147
3148 return BTP_STATUS_SUCCESS;
3149 }
3150
config_appkey_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3151 static uint8_t config_appkey_get(const void *cmd, uint16_t cmd_len,
3152 void *rsp, uint16_t *rsp_len)
3153 {
3154 const struct btp_mesh_cfg_appkey_get_cmd *cp = cmd;
3155 struct btp_mesh_cfg_appkey_get_rp *rp = rsp;
3156 uint8_t status;
3157 uint16_t keys;
3158 size_t key_cnt = 1;
3159 int err;
3160
3161 LOG_DBG("");
3162
3163 err = bt_mesh_cfg_cli_app_key_get(sys_le16_to_cpu(cp->net_idx),
3164 sys_le16_to_cpu(cp->address),
3165 sys_le16_to_cpu(cp->net_key_idx),
3166 &status, &keys, &key_cnt);
3167
3168 if (err) {
3169 LOG_ERR("err %d", err);
3170 return BTP_STATUS_FAILED;
3171 }
3172
3173 rp->status = status;
3174 *rsp_len = sizeof(*rp);
3175
3176 return BTP_STATUS_SUCCESS;
3177 }
3178
3179
config_model_app_bind(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3180 static uint8_t config_model_app_bind(const void *cmd, uint16_t cmd_len,
3181 void *rsp, uint16_t *rsp_len)
3182 {
3183 const struct btp_mesh_cfg_model_app_bind_cmd *cp = cmd;
3184 struct btp_mesh_cfg_model_app_bind_rp *rp = rsp;
3185 uint8_t status;
3186 int err;
3187
3188 LOG_DBG("");
3189
3190 bt_mesh_cfg_cli_timeout_set(5000);
3191
3192 err = bt_mesh_cfg_cli_mod_app_bind(sys_le16_to_cpu(cp->net_idx),
3193 sys_le16_to_cpu(cp->address),
3194 sys_le16_to_cpu(cp->elem_address),
3195 sys_le16_to_cpu(cp->app_key_idx),
3196 sys_le16_to_cpu(cp->mod_id),
3197 &status);
3198
3199 if (err) {
3200 LOG_ERR("err %d", err);
3201 return BTP_STATUS_FAILED;
3202 }
3203
3204 rp->status = status;
3205 *rsp_len = sizeof(*rp);
3206
3207 return BTP_STATUS_SUCCESS;
3208 }
3209
config_model_app_bind_vnd(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3210 static uint8_t config_model_app_bind_vnd(const void *cmd, uint16_t cmd_len,
3211 void *rsp, uint16_t *rsp_len)
3212 {
3213 const struct btp_mesh_cfg_model_app_bind_vnd_cmd *cp = cmd;
3214 struct btp_mesh_cfg_model_app_bind_vnd_rp *rp = rsp;
3215 uint8_t status;
3216 int err;
3217
3218 LOG_DBG("");
3219
3220 err = bt_mesh_cfg_cli_mod_app_bind_vnd(sys_le16_to_cpu(cp->net_idx),
3221 sys_le16_to_cpu(cp->address),
3222 sys_le16_to_cpu(cp->elem_address),
3223 sys_le16_to_cpu(cp->app_key_idx),
3224 sys_le16_to_cpu(cp->mod_id),
3225 sys_le16_to_cpu(cp->cid),
3226 &status);
3227
3228 if (err) {
3229 LOG_ERR("err %d", err);
3230 return BTP_STATUS_FAILED;
3231 }
3232
3233 rp->status = status;
3234 *rsp_len = sizeof(*rp);
3235
3236 return BTP_STATUS_SUCCESS;
3237 }
3238
config_model_app_unbind(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3239 static uint8_t config_model_app_unbind(const void *cmd, uint16_t cmd_len,
3240 void *rsp, uint16_t *rsp_len)
3241 {
3242 const struct btp_mesh_cfg_model_app_unbind_cmd *cp = cmd;
3243 struct btp_mesh_cfg_model_app_unbind_rp *rp = rsp;
3244 uint8_t status;
3245 int err;
3246
3247 LOG_DBG("");
3248
3249 err = bt_mesh_cfg_cli_mod_app_unbind(sys_le16_to_cpu(cp->net_idx),
3250 sys_le16_to_cpu(cp->address),
3251 sys_le16_to_cpu(cp->elem_address),
3252 sys_le16_to_cpu(cp->app_key_idx),
3253 sys_le16_to_cpu(cp->mod_id),
3254 &status);
3255 if (err) {
3256 LOG_ERR("err %d", err);
3257 return BTP_STATUS_FAILED;
3258 }
3259
3260 rp->status = status;
3261 *rsp_len = sizeof(*rp);
3262
3263 return BTP_STATUS_SUCCESS;
3264 }
3265
3266
config_model_app_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3267 static uint8_t config_model_app_get(const void *cmd, uint16_t cmd_len,
3268 void *rsp, uint16_t *rsp_len)
3269 {
3270 const struct btp_mesh_cfg_model_app_get_cmd *cp = cmd;
3271 struct btp_mesh_cfg_model_app_get_rp *rp = rsp;
3272 uint8_t status;
3273 uint16_t apps;
3274 size_t app_cnt;
3275 int err;
3276
3277 LOG_DBG("");
3278
3279 err = bt_mesh_cfg_cli_mod_app_get(sys_le16_to_cpu(cp->net_idx),
3280 sys_le16_to_cpu(cp->address),
3281 sys_le16_to_cpu(cp->elem_address),
3282 sys_le16_to_cpu(cp->mod_id),
3283 &status, &apps, &app_cnt);
3284
3285 if (err) {
3286 LOG_ERR("err %d", err);
3287 return BTP_STATUS_FAILED;
3288 }
3289
3290 rp->status = status;
3291 *rsp_len = sizeof(*rp);
3292
3293 return BTP_STATUS_SUCCESS;
3294 }
3295
config_model_app_vnd_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3296 static uint8_t config_model_app_vnd_get(const void *cmd, uint16_t cmd_len,
3297 void *rsp, uint16_t *rsp_len)
3298 {
3299 const struct btp_mesh_cfg_model_app_vnd_get_cmd *cp = cmd;
3300 struct btp_mesh_cfg_model_app_vnd_get_rp *rp = rsp;
3301 uint8_t status;
3302 uint16_t apps;
3303 size_t app_cnt;
3304 int err;
3305
3306 LOG_DBG("");
3307
3308 err = bt_mesh_cfg_cli_mod_app_get_vnd(sys_le16_to_cpu(cp->net_idx),
3309 sys_le16_to_cpu(cp->address),
3310 sys_le16_to_cpu(cp->elem_address),
3311 sys_le16_to_cpu(cp->mod_id),
3312 sys_le16_to_cpu(cp->cid),
3313 &status, &apps, &app_cnt);
3314 if (err) {
3315 LOG_ERR("err %d", err);
3316 return BTP_STATUS_FAILED;
3317 }
3318
3319 rp->status = status;
3320 *rsp_len = sizeof(*rp);
3321
3322 return BTP_STATUS_SUCCESS;
3323 }
3324
config_hb_pub_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3325 static uint8_t config_hb_pub_set(const void *cmd, uint16_t cmd_len,
3326 void *rsp, uint16_t *rsp_len)
3327 {
3328 const struct btp_mesh_cfg_heartbeat_pub_set_cmd *cp = cmd;
3329 struct btp_mesh_cfg_heartbeat_pub_set_rp *rp = rsp;
3330 uint8_t status;
3331 struct bt_mesh_cfg_cli_hb_pub pub;
3332 int err;
3333
3334 LOG_DBG("");
3335
3336 pub.net_idx = sys_le16_to_cpu(cp->net_key_idx);
3337 pub.dst = sys_le16_to_cpu(cp->destination);
3338 pub.count = cp->count_log;
3339 pub.period = cp->period_log;
3340 pub.ttl = cp->ttl;
3341 pub.feat = sys_le16_to_cpu(cp->features);
3342
3343 err = bt_mesh_cfg_cli_hb_pub_set(sys_le16_to_cpu(cp->net_idx),
3344 sys_le16_to_cpu(cp->address),
3345 &pub, &status);
3346
3347 if (err) {
3348 LOG_ERR("err %d", err);
3349 return BTP_STATUS_FAILED;
3350 }
3351
3352 rp->status = status;
3353 *rsp_len = sizeof(*rp);
3354
3355 return BTP_STATUS_SUCCESS;
3356 }
3357
config_hb_pub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3358 static uint8_t config_hb_pub_get(const void *cmd, uint16_t cmd_len,
3359 void *rsp, uint16_t *rsp_len)
3360 {
3361 const struct btp_mesh_cfg_heartbeat_pub_get_cmd *cp = cmd;
3362 struct btp_mesh_cfg_heartbeat_pub_get_rp *rp = rsp;
3363 uint8_t status;
3364 struct bt_mesh_cfg_cli_hb_pub pub;
3365 int err;
3366
3367 LOG_DBG("");
3368
3369 err = bt_mesh_cfg_cli_hb_pub_get(sys_le16_to_cpu(cp->net_idx),
3370 sys_le16_to_cpu(cp->address),
3371 &pub, &status);
3372
3373 if (err) {
3374 LOG_ERR("err %d", err);
3375 return BTP_STATUS_FAILED;
3376 }
3377
3378 rp->status = status;
3379 *rsp_len = sizeof(*rp);
3380
3381 return BTP_STATUS_SUCCESS;
3382 }
3383
config_hb_sub_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3384 static uint8_t config_hb_sub_set(const void *cmd, uint16_t cmd_len,
3385 void *rsp, uint16_t *rsp_len)
3386 {
3387 const struct btp_mesh_cfg_heartbeat_sub_set_cmd *cp = cmd;
3388 struct btp_mesh_cfg_heartbeat_sub_set_rp *rp = rsp;
3389 uint8_t status;
3390 struct bt_mesh_cfg_cli_hb_sub sub;
3391 int err;
3392
3393 LOG_DBG("");
3394
3395 sub.src = sys_le16_to_cpu(cp->source);
3396 sub.dst = sys_le16_to_cpu(cp->destination);
3397 sub.period = cp->period_log;
3398
3399 err = bt_mesh_cfg_cli_hb_sub_set(sys_le16_to_cpu(cp->net_idx),
3400 sys_le16_to_cpu(cp->address),
3401 &sub, &status);
3402
3403 if (err) {
3404 LOG_ERR("err %d", err);
3405 return BTP_STATUS_FAILED;
3406 }
3407
3408 rp->status = status;
3409 *rsp_len = sizeof(*rp);
3410
3411 return BTP_STATUS_SUCCESS;
3412 }
3413
config_hb_sub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3414 static uint8_t config_hb_sub_get(const void *cmd, uint16_t cmd_len,
3415 void *rsp, uint16_t *rsp_len)
3416 {
3417 const struct btp_mesh_cfg_heartbeat_sub_get_cmd *cp = cmd;
3418 struct btp_mesh_cfg_heartbeat_sub_get_rp *rp = rsp;
3419 uint8_t status;
3420 struct bt_mesh_cfg_cli_hb_sub sub;
3421 int err;
3422
3423 LOG_DBG("");
3424
3425 err = bt_mesh_cfg_cli_hb_sub_get(sys_le16_to_cpu(cp->net_idx),
3426 sys_le16_to_cpu(cp->address),
3427 &sub, &status);
3428
3429 if (err) {
3430 LOG_ERR("err %d", err);
3431 return BTP_STATUS_FAILED;
3432 }
3433
3434 rp->status = status;
3435 *rsp_len = sizeof(*rp);
3436
3437 return BTP_STATUS_SUCCESS;
3438 }
3439
config_net_trans_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3440 static uint8_t config_net_trans_get(const void *cmd, uint16_t cmd_len,
3441 void *rsp, uint16_t *rsp_len)
3442 {
3443 const struct btp_mesh_cfg_net_trans_get_cmd *cp = cmd;
3444 struct btp_mesh_cfg_net_trans_get_rp *rp = rsp;
3445 uint8_t transmit;
3446 int err;
3447
3448 LOG_DBG("");
3449
3450 err = bt_mesh_cfg_cli_net_transmit_get(sys_le16_to_cpu(cp->net_idx),
3451 sys_le16_to_cpu(cp->address),
3452 &transmit);
3453
3454 if (err) {
3455 LOG_ERR("err %d", err);
3456 return BTP_STATUS_FAILED;
3457 }
3458
3459 rp->transmit = transmit;
3460 *rsp_len = sizeof(*rp);
3461
3462 return BTP_STATUS_SUCCESS;
3463 }
3464
config_net_trans_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3465 static uint8_t config_net_trans_set(const void *cmd, uint16_t cmd_len,
3466 void *rsp, uint16_t *rsp_len)
3467 {
3468 const struct btp_mesh_cfg_net_trans_set_cmd *cp = cmd;
3469 struct btp_mesh_cfg_net_trans_set_rp *rp = rsp;
3470 uint8_t transmit;
3471 int err;
3472
3473 LOG_DBG("");
3474
3475 err = bt_mesh_cfg_cli_net_transmit_set(sys_le16_to_cpu(cp->net_idx),
3476 sys_le16_to_cpu(cp->address),
3477 cp->transmit, &transmit);
3478
3479 if (err) {
3480 LOG_ERR("err %d", err);
3481 return BTP_STATUS_FAILED;
3482 }
3483
3484 rp->transmit = transmit;
3485 *rsp_len = sizeof(*rp);
3486
3487 return BTP_STATUS_SUCCESS;
3488 }
3489
config_node_identity_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3490 static uint8_t config_node_identity_set(const void *cmd, uint16_t cmd_len,
3491 void *rsp, uint16_t *rsp_len)
3492 {
3493 const struct btp_mesh_cfg_node_idt_set_cmd *cp = cmd;
3494 struct btp_mesh_cfg_node_idt_set_rp *rp = rsp;
3495 uint8_t identity;
3496 uint8_t status;
3497 int err;
3498
3499 LOG_DBG("");
3500
3501 err = bt_mesh_cfg_cli_node_identity_set(sys_le16_to_cpu(cp->net_idx),
3502 sys_le16_to_cpu(cp->address),
3503 sys_le16_to_cpu(cp->net_key_idx),
3504 cp->new_identity,
3505 &status, &identity);
3506
3507 if (err) {
3508 LOG_ERR("err %d", err);
3509 return BTP_STATUS_FAILED;
3510 }
3511
3512 rp->status = status;
3513 rp->identity = identity;
3514
3515 *rsp_len = sizeof(*rp);
3516 return BTP_STATUS_SUCCESS;
3517 }
3518
config_node_identity_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3519 static uint8_t config_node_identity_get(const void *cmd, uint16_t cmd_len,
3520 void *rsp, uint16_t *rsp_len)
3521 {
3522 const struct btp_mesh_cfg_node_idt_get_cmd *cp = cmd;
3523 struct btp_mesh_cfg_node_idt_get_rp *rp = rsp;
3524 uint8_t identity;
3525 uint8_t status;
3526 int err;
3527
3528 LOG_DBG("");
3529
3530 err = bt_mesh_cfg_cli_node_identity_get(sys_le16_to_cpu(cp->net_idx),
3531 sys_le16_to_cpu(cp->address),
3532 sys_le16_to_cpu(cp->net_key_idx),
3533 &status, &identity);
3534
3535 if (err) {
3536 LOG_ERR("err %d", err);
3537 return BTP_STATUS_FAILED;
3538 }
3539
3540 rp->status = status;
3541 rp->identity = identity;
3542
3543 *rsp_len = sizeof(*rp);
3544 return BTP_STATUS_SUCCESS;
3545 }
3546
config_node_reset(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3547 static uint8_t config_node_reset(const void *cmd, uint16_t cmd_len,
3548 void *rsp, uint16_t *rsp_len)
3549 {
3550 const struct btp_mesh_cfg_node_reset_cmd *cp = cmd;
3551 struct btp_mesh_cfg_node_reset_rp *rp = rsp;
3552 bool status;
3553 int err;
3554
3555 LOG_DBG("");
3556
3557 err = bt_mesh_cfg_cli_node_reset(sys_le16_to_cpu(cp->net_idx),
3558 sys_le16_to_cpu(cp->address),
3559 &status);
3560
3561 if (err) {
3562 LOG_ERR("err %d", err);
3563 return BTP_STATUS_FAILED;
3564 }
3565
3566 rp->status = status;
3567
3568 *rsp_len = sizeof(*rp);
3569 return BTP_STATUS_SUCCESS;
3570 }
3571
config_lpn_timeout_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3572 static uint8_t config_lpn_timeout_get(const void *cmd, uint16_t cmd_len,
3573 void *rsp, uint16_t *rsp_len)
3574 {
3575 const struct btp_mesh_cfg_lpn_timeout_cmd *cp = cmd;
3576 struct btp_mesh_cfg_lpn_timeout_rp *rp = rsp;
3577 int32_t polltimeout;
3578 int err;
3579
3580 LOG_DBG("");
3581
3582 err = bt_mesh_cfg_cli_lpn_timeout_get(sys_le16_to_cpu(cp->net_idx),
3583 sys_le16_to_cpu(cp->address),
3584 sys_le16_to_cpu(cp->unicast_addr),
3585 &polltimeout);
3586
3587 if (err) {
3588 LOG_ERR("err %d", err);
3589 return BTP_STATUS_FAILED;
3590 }
3591
3592 rp->timeout = sys_cpu_to_le32(polltimeout);
3593
3594 *rsp_len = sizeof(*rp);
3595 return BTP_STATUS_SUCCESS;
3596 }
3597
health_fault_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3598 static uint8_t health_fault_get(const void *cmd, uint16_t cmd_len,
3599 void *rsp, uint16_t *rsp_len)
3600 {
3601 const struct btp_mesh_health_fault_get_cmd *cp = cmd;
3602 struct bt_mesh_msg_ctx ctx = {
3603 .net_idx = net.net_idx,
3604 .addr = sys_le16_to_cpu(cp->address),
3605 .app_idx = sys_le16_to_cpu(cp->app_idx),
3606 };
3607 uint8_t test_id;
3608 size_t fault_count = 16;
3609 uint8_t faults[fault_count];
3610 int err;
3611
3612 LOG_DBG("");
3613
3614 err = bt_mesh_health_cli_fault_get(&health_cli, &ctx,
3615 sys_le16_to_cpu(cp->cid), &test_id,
3616 faults, &fault_count);
3617
3618 if (err) {
3619 LOG_ERR("err %d", err);
3620 return BTP_STATUS_FAILED;
3621 }
3622
3623 return BTP_STATUS_SUCCESS;
3624 }
3625
health_fault_clear(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3626 static uint8_t health_fault_clear(const void *cmd, uint16_t cmd_len,
3627 void *rsp, uint16_t *rsp_len)
3628 {
3629 const struct btp_mesh_health_fault_clear_cmd *cp = cmd;
3630 struct bt_mesh_msg_ctx ctx = {
3631 .net_idx = net.net_idx,
3632 .addr = sys_le16_to_cpu(cp->address),
3633 .app_idx = sys_le16_to_cpu(cp->app_idx),
3634 };
3635 uint8_t test_id = 0;
3636 size_t fault_count = 16;
3637 uint8_t faults[fault_count];
3638 int err;
3639
3640 LOG_DBG("");
3641
3642 if (cp->ack) {
3643 err = bt_mesh_health_cli_fault_clear(&health_cli, &ctx,
3644 sys_le16_to_cpu(cp->cid),
3645 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3646 bt_mesh_op_agg_cli_seq_is_started() ?
3647 NULL :
3648 #endif
3649 &test_id,
3650 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3651 bt_mesh_op_agg_cli_seq_is_started() ?
3652 NULL :
3653 #endif
3654 faults,
3655 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3656 bt_mesh_op_agg_cli_seq_is_started() ?
3657 NULL :
3658 #endif
3659 &fault_count);
3660 } else {
3661 err = bt_mesh_health_cli_fault_clear_unack(&health_cli, &ctx,
3662 sys_le16_to_cpu(cp->cid));
3663 }
3664
3665 if (err) {
3666 LOG_ERR("err %d", err);
3667 return BTP_STATUS_FAILED;
3668 }
3669
3670 if (cp->ack) {
3671 struct btp_mesh_health_fault_clear_rp *rp = rsp;
3672
3673 rp->test_id = test_id;
3674 *rsp_len = sizeof(*rp);
3675 }
3676
3677 return BTP_STATUS_SUCCESS;
3678 }
3679
health_fault_test(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3680 static uint8_t health_fault_test(const void *cmd, uint16_t cmd_len,
3681 void *rsp, uint16_t *rsp_len)
3682 {
3683 const struct btp_mesh_health_fault_test_cmd *cp = cmd;
3684 struct bt_mesh_msg_ctx ctx = {
3685 .net_idx = net.net_idx,
3686 .addr = sys_le16_to_cpu(cp->address),
3687 .app_idx = sys_le16_to_cpu(cp->app_idx),
3688 };
3689 size_t fault_count = 16;
3690 uint8_t faults[fault_count];
3691 int err;
3692
3693 LOG_DBG("");
3694
3695 if (cp->ack) {
3696 err = bt_mesh_health_cli_fault_test(&health_cli, &ctx,
3697 sys_le16_to_cpu(cp->cid),
3698 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3699 bt_mesh_op_agg_cli_seq_is_started() ?
3700 0 :
3701 #endif
3702 cp->test_id,
3703 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3704 bt_mesh_op_agg_cli_seq_is_started() ?
3705 NULL :
3706 #endif
3707 faults,
3708 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3709 bt_mesh_op_agg_cli_seq_is_started() ?
3710 NULL :
3711 #endif
3712 &fault_count);
3713 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3714 if (bt_mesh_op_agg_cli_seq_is_started()) {
3715 fault_count = 0;
3716 }
3717 #endif
3718 } else {
3719 err = bt_mesh_health_cli_fault_test_unack(&health_cli, &ctx,
3720 sys_le16_to_cpu(cp->cid),
3721 cp->test_id);
3722 }
3723
3724 if (err) {
3725 LOG_ERR("err %d", err);
3726 return BTP_STATUS_FAILED;
3727 }
3728
3729 if (cp->ack) {
3730 struct btp_mesh_health_fault_test_rp *rp = rsp;
3731
3732 rp->test_id = cp->test_id;
3733 rp->cid = cp->cid;
3734 (void)memcpy(rp->faults, faults, fault_count);
3735
3736 *rsp_len = sizeof(*rp) + fault_count;
3737 }
3738
3739 return BTP_STATUS_SUCCESS;
3740 }
3741
health_period_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3742 static uint8_t health_period_get(const void *cmd, uint16_t cmd_len,
3743 void *rsp, uint16_t *rsp_len)
3744 {
3745 const struct btp_mesh_health_period_get_cmd *cp = cmd;
3746 struct bt_mesh_msg_ctx ctx = {
3747 .net_idx = net.net_idx,
3748 .addr = sys_le16_to_cpu(cp->address),
3749 .app_idx = sys_le16_to_cpu(cp->app_idx),
3750 };
3751 uint8_t divisor;
3752 int err;
3753
3754 LOG_DBG("");
3755
3756 err = bt_mesh_health_cli_period_get(&health_cli, &ctx, &divisor);
3757
3758 if (err) {
3759 LOG_ERR("err %d", err);
3760 return BTP_STATUS_FAILED;
3761 }
3762
3763 return BTP_STATUS_SUCCESS;
3764 }
3765
health_period_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3766 static uint8_t health_period_set(const void *cmd, uint16_t cmd_len,
3767 void *rsp, uint16_t *rsp_len)
3768 {
3769 const struct btp_mesh_health_period_set_cmd *cp = cmd;
3770 struct bt_mesh_msg_ctx ctx = {
3771 .net_idx = net.net_idx,
3772 .addr = sys_le16_to_cpu(cp->address),
3773 .app_idx = sys_le16_to_cpu(cp->app_idx),
3774 };
3775 uint8_t updated_divisor;
3776 int err;
3777
3778 LOG_DBG("");
3779
3780 if (cp->ack) {
3781 err = bt_mesh_health_cli_period_set(&health_cli, &ctx, cp->divisor,
3782 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3783 bt_mesh_op_agg_cli_seq_is_started() ?
3784 NULL :
3785 #endif
3786 &updated_divisor);
3787 } else {
3788 err = bt_mesh_health_cli_period_set_unack(&health_cli, &ctx, cp->divisor);
3789 }
3790
3791 if (err) {
3792 LOG_ERR("err %d", err);
3793 return BTP_STATUS_FAILED;
3794 }
3795
3796 if (cp->ack) {
3797 struct btp_mesh_health_period_set_rp *rp = rsp;
3798
3799 rp->divisor = updated_divisor;
3800
3801 *rsp_len = sizeof(*rp);
3802 }
3803
3804 return BTP_STATUS_SUCCESS;
3805 }
3806
health_attention_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3807 static uint8_t health_attention_get(const void *cmd, uint16_t cmd_len,
3808 void *rsp, uint16_t *rsp_len)
3809 {
3810 const struct btp_mesh_health_attention_get_cmd *cp = cmd;
3811 struct bt_mesh_msg_ctx ctx = {
3812 .net_idx = net.net_idx,
3813 .addr = sys_le16_to_cpu(cp->address),
3814 .app_idx = sys_le16_to_cpu(cp->app_idx),
3815 };
3816 uint8_t attention;
3817 int err;
3818
3819 LOG_DBG("");
3820
3821 err = bt_mesh_health_cli_attention_get(&health_cli, &ctx, &attention);
3822
3823 if (err) {
3824 LOG_ERR("err %d", err);
3825 return BTP_STATUS_FAILED;
3826 }
3827
3828 return BTP_STATUS_SUCCESS;
3829 }
3830
health_attention_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3831 static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len,
3832 void *rsp, uint16_t *rsp_len)
3833 {
3834 const struct btp_mesh_health_attention_set_cmd *cp = cmd;
3835 struct bt_mesh_msg_ctx ctx = {
3836 .net_idx = net.net_idx,
3837 .addr = sys_le16_to_cpu(cp->address),
3838 .app_idx = sys_le16_to_cpu(cp->app_idx),
3839 };
3840 uint8_t updated_attention;
3841 int err;
3842
3843 LOG_DBG("");
3844
3845 if (cp->ack) {
3846 err = bt_mesh_health_cli_attention_set(&health_cli, &ctx, cp->attention,
3847 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3848 bt_mesh_op_agg_cli_seq_is_started() ?
3849 NULL :
3850 #endif
3851 &updated_attention);
3852 } else {
3853 err = bt_mesh_health_cli_attention_set_unack(&health_cli, &ctx, cp->attention);
3854 }
3855
3856 if (err) {
3857 LOG_ERR("err %d", err);
3858 return BTP_STATUS_FAILED;
3859 }
3860
3861 if (cp->ack) {
3862 struct btp_mesh_health_attention_set_rp *rp = rsp;
3863
3864 rp->attention = updated_attention;
3865
3866 *rsp_len = sizeof(*rp);
3867 }
3868
3869 return BTP_STATUS_SUCCESS;
3870 }
3871
3872 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
opcodes_aggregator_init(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3873 static uint8_t opcodes_aggregator_init(const void *cmd, uint16_t cmd_len,
3874 void *rsp, uint16_t *rsp_len)
3875 {
3876 const struct btp_mesh_opcodes_aggregator_init_cmd *cp = cmd;
3877 int err;
3878
3879 LOG_DBG("");
3880
3881 err = bt_mesh_op_agg_cli_seq_start(cp->net_idx, cp->app_idx, cp->dst, cp->elem_addr);
3882 if (err) {
3883 LOG_ERR("Failed to init Opcodes Aggregator Context (err %d)", err);
3884 return BTP_STATUS_FAILED;
3885 }
3886
3887 return BTP_STATUS_SUCCESS;
3888 }
3889
opcodes_aggregator_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3890 static uint8_t opcodes_aggregator_send(const void *cmd, uint16_t cmd_len,
3891 void *rsp, uint16_t *rsp_len)
3892 {
3893 int err;
3894
3895 LOG_DBG("");
3896
3897 err = bt_mesh_op_agg_cli_seq_send();
3898 if (err) {
3899 LOG_ERR("Failed to send Opcodes Aggregator message (err %d)", err);
3900 return BTP_STATUS_FAILED;
3901 }
3902
3903 return BTP_STATUS_SUCCESS;
3904 }
3905 #endif
3906
3907 #if defined(CONFIG_BT_MESH_RPR_CLI)
rpr_scan_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3908 static uint8_t rpr_scan_start(const void *cmd, uint16_t cmd_len,
3909 void *rsp, uint16_t *rsp_len)
3910 {
3911 const struct btp_rpr_scan_start_cmd *cp = cmd;
3912
3913 struct bt_mesh_rpr_scan_status status;
3914 const struct bt_mesh_rpr_node srv = {
3915 .addr = cp->dst,
3916 .net_idx = net.net_idx,
3917 .ttl = BT_MESH_TTL_DEFAULT,
3918 };
3919 uint8_t uuid[16] = {0};
3920 int err;
3921
3922 err = bt_mesh_rpr_scan_start(&rpr_cli, &srv,
3923 memcmp(uuid, cp->uuid, 16) ? cp->uuid : NULL,
3924 cp->timeout,
3925 BT_MESH_RPR_SCAN_MAX_DEVS_ANY, &status);
3926
3927 if (err) {
3928 LOG_ERR("Scan start failed: %d", err);
3929 return BTP_STATUS_FAILED;
3930 }
3931
3932 return BTP_STATUS_SUCCESS;
3933 }
3934
rpr_ext_scan_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3935 static uint8_t rpr_ext_scan_start(const void *cmd, uint16_t cmd_len,
3936 void *rsp, uint16_t *rsp_len)
3937 {
3938 const struct btp_rpr_ext_scan_start_cmd *cp = cmd;
3939 const struct bt_mesh_rpr_node srv = {
3940 .addr = cp->dst,
3941 .net_idx = net.net_idx,
3942 .ttl = BT_MESH_TTL_DEFAULT,
3943 };
3944 int err;
3945
3946 err = bt_mesh_rpr_scan_start_ext(&rpr_cli, &srv, cp->uuid,
3947 cp->timeout, cp->ad_types,
3948 cp->ad_count);
3949 if (err) {
3950 LOG_ERR("Scan start failed: %d", err);
3951 return BTP_STATUS_FAILED;
3952 }
3953
3954 return BTP_STATUS_SUCCESS;
3955 }
3956
rpr_scan_caps_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3957 static uint8_t rpr_scan_caps_get(const void *cmd, uint16_t cmd_len,
3958 void *rsp, uint16_t *rsp_len)
3959 {
3960 const struct btp_rpr_scan_caps_get_cmd *cp = cmd;
3961 struct bt_mesh_rpr_caps caps;
3962 const struct bt_mesh_rpr_node srv = {
3963 .addr = cp->dst,
3964 .net_idx = net.net_idx,
3965 .ttl = BT_MESH_TTL_DEFAULT,
3966 };
3967 int err;
3968
3969 err = bt_mesh_rpr_scan_caps_get(&rpr_cli, &srv, &caps);
3970 if (err) {
3971 LOG_ERR("Scan capabilities get failed: %d", err);
3972 return BTP_STATUS_FAILED;
3973 }
3974
3975 LOG_DBG("Remote Provisioning scan capabilities of 0x%04x:",
3976 net.dst);
3977 LOG_DBG("\tMax devices: %u", caps.max_devs);
3978 LOG_DBG("\tActive scanning: %s",
3979 caps.active_scan ? "true" : "false");
3980
3981 return BTP_STATUS_SUCCESS;
3982 }
3983
rpr_scan_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3984 static uint8_t rpr_scan_get(const void *cmd, uint16_t cmd_len,
3985 void *rsp, uint16_t *rsp_len)
3986 {
3987 const struct btp_rpr_scan_get_cmd *cp = cmd;
3988 struct bt_mesh_rpr_scan_status status;
3989 const struct bt_mesh_rpr_node srv = {
3990 .addr = cp->dst,
3991 .net_idx = net.net_idx,
3992 .ttl = BT_MESH_TTL_DEFAULT,
3993 };
3994 int err;
3995
3996 err = bt_mesh_rpr_scan_get(&rpr_cli, &srv, &status);
3997 if (err) {
3998 LOG_ERR("Scan get failed: %d", err);
3999 return BTP_STATUS_FAILED;
4000 }
4001
4002 LOG_DBG("Remote Provisioning scan on 0x%04x:", cp->dst);
4003 LOG_DBG("\tStatus: %u", status.status);
4004 LOG_DBG("\tScan type: %u", status.scan);
4005 LOG_DBG("\tMax devices: %u", status.max_devs);
4006 LOG_DBG("\tRemaining time: %u", status.timeout);
4007
4008 return BTP_STATUS_SUCCESS;
4009 }
4010
rpr_scan_stop(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4011 static uint8_t rpr_scan_stop(const void *cmd, uint16_t cmd_len,
4012 void *rsp, uint16_t *rsp_len)
4013 {
4014 const struct btp_rpr_scan_stop_cmd *cp = cmd;
4015 struct bt_mesh_rpr_scan_status status;
4016 const struct bt_mesh_rpr_node srv = {
4017 .addr = cp->dst,
4018 .net_idx = net.net_idx,
4019 .ttl = BT_MESH_TTL_DEFAULT,
4020 };
4021 int err;
4022
4023 err = bt_mesh_rpr_scan_stop(&rpr_cli, &srv, &status);
4024 if (err || status.status) {
4025 LOG_DBG("Scan stop failed: %d %u", err, status.status);
4026 return BTP_STATUS_FAILED;
4027 }
4028
4029 LOG_DBG("Remote Provisioning scan on 0x%04x stopped.",
4030 net.dst);
4031
4032 return BTP_STATUS_SUCCESS;
4033 }
4034
rpr_link_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4035 static uint8_t rpr_link_get(const void *cmd, uint16_t cmd_len,
4036 void *rsp, uint16_t *rsp_len)
4037 {
4038 const struct btp_rpr_link_get_cmd *cp = cmd;
4039 struct bt_mesh_rpr_link link;
4040 const struct bt_mesh_rpr_node srv = {
4041 .addr = cp->dst,
4042 .net_idx = net.net_idx,
4043 .ttl = BT_MESH_TTL_DEFAULT,
4044 };
4045 int err;
4046
4047 err = bt_mesh_rpr_link_get(&rpr_cli, &srv, &link);
4048 if (err) {
4049 LOG_ERR("Link get failed: %d %u", err, link.status);
4050 return BTP_STATUS_FAILED;
4051 }
4052
4053 LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst);
4054 LOG_DBG("\tStatus: %u", link.status);
4055 LOG_DBG("\tState: %u", link.state);
4056
4057 return BTP_STATUS_SUCCESS;
4058 }
4059
rpr_link_close(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4060 static uint8_t rpr_link_close(const void *cmd, uint16_t cmd_len,
4061 void *rsp, uint16_t *rsp_len)
4062 {
4063 const struct btp_rpr_link_close_cmd *cp = cmd;
4064 struct bt_mesh_rpr_link link;
4065 const struct bt_mesh_rpr_node srv = {
4066 .addr = cp->dst,
4067 .net_idx = net.net_idx,
4068 .ttl = BT_MESH_TTL_DEFAULT,
4069 };
4070 int err;
4071
4072 err = bt_mesh_rpr_link_close(&rpr_cli, &srv, &link);
4073 if (err) {
4074 LOG_ERR("Link close failed: %d %u", err, link.status);
4075 return BTP_STATUS_FAILED;
4076 }
4077
4078 LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst);
4079 LOG_DBG("\tStatus: %u", link.status);
4080 LOG_DBG("\tState: %u", link.state);
4081
4082 return BTP_STATUS_SUCCESS;
4083 }
4084
rpr_prov_remote(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4085 static uint8_t rpr_prov_remote(const void *cmd, uint16_t cmd_len,
4086 void *rsp, uint16_t *rsp_len)
4087 {
4088 const struct btp_rpr_prov_remote_cmd *cp = cmd;
4089 struct bt_mesh_rpr_node srv = {
4090 .addr = cp->dst,
4091 .net_idx = net.net_idx,
4092 .ttl = BT_MESH_TTL_DEFAULT,
4093 };
4094 int err;
4095
4096 err = bt_mesh_provision_remote(&rpr_cli, &srv, cp->uuid,
4097 cp->net_idx, cp->addr);
4098 if (err) {
4099 LOG_ERR("Prov remote start failed: %d", err);
4100 return BTP_STATUS_FAILED;
4101 }
4102
4103 return BTP_STATUS_SUCCESS;
4104 }
4105
rpr_reprov_remote(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4106 static uint8_t rpr_reprov_remote(const void *cmd, uint16_t cmd_len,
4107 void *rsp, uint16_t *rsp_len)
4108 {
4109 const struct btp_rpr_reprov_remote_cmd *cp = cmd;
4110 struct bt_mesh_rpr_node srv = {
4111 .addr = cp->dst,
4112 .net_idx = net.net_idx,
4113 .ttl = BT_MESH_TTL_DEFAULT,
4114 };
4115 int err;
4116
4117 if (!BT_MESH_ADDR_IS_UNICAST(cp->addr)) {
4118 LOG_ERR("Must be a valid unicast address");
4119 err = -EINVAL;
4120 return BTP_STATUS_FAILED;
4121 }
4122
4123 err = bt_mesh_reprovision_remote(&rpr_cli, &srv, cp->addr,
4124 cp->comp_change);
4125 if (err) {
4126 LOG_ERR("Reprovisioning failed: %d", err);
4127 return BTP_STATUS_FAILED;
4128 }
4129
4130 return BTP_STATUS_SUCCESS;
4131 }
4132 #endif
4133
4134 #if defined(CONFIG_BT_MESH_DFD_SRV)
4135 static struct {
4136 struct bt_mesh_dfu_target targets[32];
4137 struct bt_mesh_blob_target_pull pull[32];
4138 size_t target_cnt;
4139 struct bt_mesh_blob_cli_inputs inputs;
4140 } dfu_tx;
4141
dfu_tx_prepare(void)4142 static void dfu_tx_prepare(void)
4143 {
4144 sys_slist_init(&dfu_tx.inputs.targets);
4145
4146 for (int i = 0; i < dfu_tx.target_cnt; i++) {
4147 /* Reset target context. */
4148 uint16_t addr = dfu_tx.targets[i].blob.addr;
4149
4150 memset(&dfu_tx.targets[i].blob, 0,
4151 sizeof(struct bt_mesh_blob_target));
4152 memset(&dfu_tx.pull[i], 0,
4153 sizeof(struct bt_mesh_blob_target_pull));
4154 dfu_tx.targets[i].blob.addr = addr;
4155 dfu_tx.targets[i].blob.pull = &dfu_tx.pull[i];
4156
4157 sys_slist_append(&dfu_tx.inputs.targets,
4158 &dfu_tx.targets[i].blob.n);
4159 }
4160 }
4161
dfu_target(uint8_t img_idx,uint16_t addr)4162 static void dfu_target(uint8_t img_idx, uint16_t addr)
4163 {
4164 if (dfu_tx.target_cnt == ARRAY_SIZE(dfu_tx.targets)) {
4165 LOG_ERR("No room.");
4166 return;
4167 }
4168
4169 for (int i = 0; i < dfu_tx.target_cnt; i++) {
4170 if (dfu_tx.targets[i].blob.addr == addr) {
4171 LOG_ERR("Target 0x%04x already exists", addr);
4172 return;
4173 }
4174 }
4175
4176 dfu_tx.targets[dfu_tx.target_cnt].blob.addr = addr;
4177 dfu_tx.targets[dfu_tx.target_cnt].img_idx = img_idx;
4178 sys_slist_append(&dfu_tx.inputs.targets,
4179 &dfu_tx.targets[dfu_tx.target_cnt].blob.n);
4180 dfu_tx.target_cnt++;
4181
4182 LOG_DBG("Added target 0x%04x", addr);
4183 }
dfu_slot_add(size_t size,uint8_t * fwid,size_t fwid_len,uint8_t * metadata,size_t metadata_len)4184 static void dfu_slot_add(size_t size, uint8_t *fwid, size_t fwid_len,
4185 uint8_t *metadata, size_t metadata_len)
4186 {
4187 struct bt_mesh_dfu_slot *slot;
4188 int err;
4189
4190 slot = bt_mesh_dfu_slot_reserve();
4191 err = bt_mesh_dfu_slot_info_set(slot, size, metadata, metadata_len);
4192 if (err) {
4193 LOG_ERR("Failed to set slot info: %d", err);
4194 return;
4195 }
4196
4197 err = bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len);
4198 if (err) {
4199 LOG_ERR("Failed to set slot fwid: %d", err);
4200 return;
4201 }
4202
4203 err = bt_mesh_dfu_slot_commit(slot);
4204 if (err) {
4205 LOG_ERR("Failed to commit slot: %d", err);
4206 return;
4207 }
4208
4209 LOG_DBG("Slot added.");
4210 }
dfu_img_cb(struct bt_mesh_dfu_cli * cli,struct bt_mesh_msg_ctx * ctx,uint8_t idx,uint8_t total,const struct bt_mesh_dfu_img * img,void * cb_data)4211 static enum bt_mesh_dfu_iter dfu_img_cb(struct bt_mesh_dfu_cli *cli,
4212 struct bt_mesh_msg_ctx *ctx,
4213 uint8_t idx, uint8_t total,
4214 const struct bt_mesh_dfu_img *img,
4215 void *cb_data)
4216 {
4217 char fwid[2 * CONFIG_BT_MESH_DFU_FWID_MAXLEN + 1];
4218 size_t len;
4219
4220 idx = 0xff;
4221
4222 if (img->fwid_len <= sizeof(fwid)) {
4223 len = bin2hex(img->fwid, img->fwid_len, fwid, sizeof(fwid));
4224 } else {
4225 LOG_ERR("FWID is too big");
4226 return BT_MESH_DFU_ITER_STOP;
4227 }
4228
4229 fwid[len] = '\0';
4230
4231 LOG_DBG("Image %u:", idx);
4232 LOG_DBG("\tFWID: ");
4233 if (img->uri) {
4234 LOG_DBG("\tURI: ");
4235 }
4236
4237 return BT_MESH_DFU_ITER_CONTINUE;
4238 }
4239
dfu_info_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4240 static uint8_t dfu_info_get(const void *cmd, uint16_t cmd_len,
4241 void *rsp, uint16_t *rsp_len)
4242 {
4243 const struct btp_mmdl_dfu_info_get_cmd *cp = cmd;
4244 struct model_data *model_bound;
4245 struct bt_mesh_msg_ctx ctx = {
4246 .net_idx = net.net_idx,
4247 .send_ttl = BT_MESH_TTL_DEFAULT,
4248 };
4249 uint8_t max_count;
4250 int err = 0;
4251
4252 LOG_DBG("");
4253
4254 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4255 if (!model_bound) {
4256 LOG_ERR("Model not found");
4257 return BTP_STATUS_FAILED;
4258 }
4259 ctx.addr = model_bound->addr;
4260 ctx.app_idx = model_bound->appkey_idx;
4261
4262 max_count = cp->limit;
4263
4264 err = bt_mesh_dfu_cli_imgs_get(&dfd_srv.dfu, &ctx, dfu_img_cb, NULL,
4265 max_count);
4266 if (err) {
4267 return BTP_STATUS_FAILED;
4268 }
4269
4270 return BTP_STATUS_SUCCESS;
4271 }
4272
dfu_update_metadata_check(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4273 static uint8_t dfu_update_metadata_check(const void *cmd, uint16_t cmd_len,
4274 void *rsp, uint16_t *rsp_len)
4275 {
4276 const struct btp_mmdl_dfu_metadata_check_cmd *cp = cmd;
4277 struct btp_mmdl_dfu_metadata_check_rp *rp = rsp;
4278 const struct bt_mesh_dfu_slot *slot;
4279 struct model_data *model_bound;
4280 struct bt_mesh_msg_ctx ctx = {
4281 .net_idx = net.net_idx,
4282 .send_ttl = BT_MESH_TTL_DEFAULT,
4283 };
4284 struct bt_mesh_dfu_metadata_status rsp_data;
4285 uint8_t img_idx, slot_idx;
4286 size_t size;
4287 size_t fwid_len;
4288 size_t metadata_len;
4289 uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
4290 uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN];
4291 int err;
4292
4293 LOG_DBG("");
4294
4295 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4296 if (!model_bound) {
4297 LOG_ERR("Model not found");
4298 return BTP_STATUS_FAILED;
4299 }
4300
4301 ctx.addr = model_bound->addr;
4302 ctx.app_idx = model_bound->appkey_idx;
4303 img_idx = cp->index;
4304 slot_idx = cp->slot_idx;
4305 size = cp->slot_size;
4306 fwid_len = cp->fwid_len;
4307 metadata_len = cp->metadata_len;
4308
4309 if ((metadata_len > 0) &&
4310 (metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) {
4311 memcpy(&metadata, cp->data, metadata_len);
4312 }
4313
4314 dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len);
4315
4316 slot = bt_mesh_dfu_slot_at(slot_idx);
4317 if (!slot) {
4318 LOG_ERR("No image in slot %u", slot_idx);
4319 return BTP_STATUS_FAILED;
4320 }
4321
4322 err = bt_mesh_dfu_cli_metadata_check(&dfd_srv.dfu, &ctx, img_idx, slot,
4323 &rsp_data);
4324
4325 if (err) {
4326 LOG_ERR("ERR %d", err);
4327 return BTP_STATUS_FAILED;
4328 }
4329
4330 rp->idx = rsp_data.idx;
4331 rp->status = rsp_data.status;
4332 rp->effect = rsp_data.effect;
4333
4334 *rsp_len = sizeof(struct btp_mmdl_dfu_metadata_check_rp);
4335
4336 return BTP_STATUS_SUCCESS;
4337 }
4338
dfu_firmware_update_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4339 static uint8_t dfu_firmware_update_get(const void *cmd, uint16_t cmd_len,
4340 void *rsp, uint16_t *rsp_len)
4341 {
4342 struct model_data *model_bound;
4343 struct bt_mesh_msg_ctx ctx = {
4344 .net_idx = net.net_idx,
4345 .send_ttl = BT_MESH_TTL_DEFAULT,
4346 };
4347 struct bt_mesh_dfu_target_status rsp_data;
4348 struct btp_mmdl_dfu_firmware_update_rp *rp = rsp;
4349 int err;
4350
4351 LOG_DBG("");
4352
4353 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4354 if (!model_bound) {
4355 LOG_ERR("Model not found");
4356 return BTP_STATUS_FAILED;
4357 }
4358
4359 ctx.addr = model_bound->addr;
4360 ctx.app_idx = model_bound->appkey_idx;
4361
4362 err = bt_mesh_dfu_cli_status_get(&dfd_srv.dfu, &ctx, &rsp_data);
4363 if (err) {
4364 LOG_ERR("err %d", err);
4365 return BTP_STATUS_FAILED;
4366 }
4367
4368 rp->status = rsp_data.status;
4369 *rsp_len = sizeof(struct btp_mmdl_dfu_firmware_update_rp);
4370 return BTP_STATUS_SUCCESS;
4371 }
4372
dfu_firmware_update_cancel(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4373 static uint8_t dfu_firmware_update_cancel(const void *cmd, uint16_t cmd_len,
4374 void *rsp, uint16_t *rsp_len)
4375 {
4376 struct model_data *model_bound;
4377 struct bt_mesh_msg_ctx ctx = {
4378 .net_idx = net.net_idx,
4379 .send_ttl = BT_MESH_TTL_DEFAULT,
4380 };
4381 int err;
4382
4383 LOG_DBG("");
4384
4385 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4386 if (!model_bound) {
4387 LOG_ERR("Model not found");
4388 return BTP_STATUS_FAILED;
4389 }
4390
4391 ctx.addr = model_bound->addr;
4392 ctx.app_idx = model_bound->appkey_idx;
4393
4394 err = bt_mesh_dfu_cli_cancel(&dfd_srv.dfu, &ctx);
4395 if (err) {
4396 LOG_ERR("err %d", err);
4397 return BTP_STATUS_FAILED;
4398 }
4399
4400 return BTP_STATUS_SUCCESS;
4401 }
4402
dfu_firmware_update_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4403 static uint8_t dfu_firmware_update_start(const void *cmd, uint16_t cmd_len,
4404 void *rsp, uint16_t *rsp_len)
4405 {
4406 const struct btp_mmdl_dfu_firmware_update_cmd *cp = cmd;
4407 struct model_data *model_bound;
4408 struct bt_mesh_dfu_cli_xfer xfer;
4409 uint8_t addr_cnt;
4410 uint16_t addr = BT_MESH_ADDR_UNASSIGNED;
4411 uint8_t slot_idx;
4412 size_t size;
4413 size_t fwid_len;
4414 size_t metadata_len;
4415 uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
4416 uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN];
4417 int err = 0;
4418 int i = 0;
4419
4420 LOG_DBG("");
4421
4422 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4423 if (!model_bound) {
4424 LOG_ERR("Model not found");
4425 return BTP_STATUS_FAILED;
4426 }
4427
4428 struct bt_mesh_dfu_cli_xfer_blob_params blob = {
4429 .block_size_log = cp->block_size,
4430 .chunk_size = cp->chunk_size,
4431 };
4432
4433 addr_cnt = cp->addr_cnt;
4434 slot_idx = cp->slot_idx;
4435 size = cp->slot_size;
4436 fwid_len = cp->fwid_len;
4437 metadata_len = cp->metadata_len;
4438 xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH;
4439 xfer.blob_params = &blob;
4440
4441 if ((metadata_len > 0) &&
4442 (metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) {
4443 memcpy(&metadata, cp->data, metadata_len);
4444 }
4445
4446 bt_mesh_dfu_slot_del_all();
4447
4448 dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len);
4449
4450 xfer.slot = bt_mesh_dfu_slot_at(slot_idx);
4451 if (!xfer.slot) {
4452 LOG_ERR("No image in slot %u", slot_idx);
4453 return BTP_STATUS_FAILED;
4454 }
4455
4456 for (i = 0; i < addr_cnt; i++) {
4457 addr = cp->data[metadata_len + 1 + i * sizeof(uint16_t)] |
4458 (cp->data[metadata_len + i * sizeof(uint16_t)] << 8);
4459 dfu_target(slot_idx, addr);
4460 }
4461
4462 dfu_tx_prepare();
4463
4464 if (!dfu_tx.target_cnt) {
4465 LOG_ERR("No targets.");
4466 return BTP_STATUS_FAILED;
4467 }
4468
4469 if (addr_cnt > 1) {
4470 dfu_tx.inputs.group = BT_MESH_ADDR_UNASSIGNED;
4471 } else {
4472 dfu_tx.inputs.group = addr;
4473 }
4474
4475 dfu_tx.inputs.app_idx = model_bound->appkey_idx;
4476 dfu_tx.inputs.ttl = BT_MESH_TTL_DEFAULT;
4477
4478 err = bt_mesh_dfu_cli_send(&dfd_srv.dfu, &dfu_tx.inputs, &dummy_blob_io, &xfer);
4479
4480 if (err) {
4481 LOG_ERR("err %d", err);
4482 return BTP_STATUS_FAILED;
4483 }
4484
4485 return BTP_STATUS_SUCCESS;
4486 }
4487
dfu_firmware_update_apply(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4488 static uint8_t dfu_firmware_update_apply(const void *cmd, uint16_t cmd_len,
4489 void *rsp, uint16_t *rsp_len)
4490 {
4491 struct model_data *model_bound;
4492 int err;
4493
4494 LOG_DBG("");
4495
4496 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4497 if (!model_bound) {
4498 LOG_ERR("Model not found");
4499 return BTP_STATUS_FAILED;
4500 }
4501
4502 err = bt_mesh_dfu_cli_apply(&dfd_srv.dfu);
4503 if (err) {
4504 LOG_ERR("err %d", err);
4505 return BTP_STATUS_FAILED;
4506 }
4507
4508 return BTP_STATUS_SUCCESS;
4509 }
4510 #endif
4511
4512 #if defined(CONFIG_BT_MESH_BLOB_CLI)
blob_cli_inputs_prepare(uint16_t group,uint16_t app_idx)4513 static void blob_cli_inputs_prepare(uint16_t group, uint16_t app_idx)
4514 {
4515 int i;
4516
4517 blob_cli_xfer.inputs.ttl = BT_MESH_TTL_DEFAULT;
4518 blob_cli_xfer.inputs.group = group;
4519 blob_cli_xfer.inputs.app_idx = app_idx;
4520 sys_slist_init(&blob_cli_xfer.inputs.targets);
4521
4522 for (i = 0; i < blob_cli_xfer.target_count; ++i) {
4523 /* Reset target context. */
4524 uint16_t addr = blob_cli_xfer.targets[i].addr;
4525
4526 memset(&blob_cli_xfer.targets[i], 0,
4527 sizeof(struct bt_mesh_blob_target));
4528 memset(&blob_cli_xfer.pull[i], 0,
4529 sizeof(struct bt_mesh_blob_target_pull));
4530 blob_cli_xfer.targets[i].addr = addr;
4531 blob_cli_xfer.targets[i].pull = &blob_cli_xfer.pull[i];
4532
4533 sys_slist_append(&blob_cli_xfer.inputs.targets,
4534 &blob_cli_xfer.targets[i].n);
4535 }
4536 }
4537
cmd_blob_target(uint16_t addr)4538 static int cmd_blob_target(uint16_t addr)
4539 {
4540 struct bt_mesh_blob_target *t;
4541
4542 if (blob_cli_xfer.target_count == ARRAY_SIZE(blob_cli_xfer.targets)) {
4543 LOG_ERR("No more room");
4544 return 0;
4545 }
4546
4547 t = &blob_cli_xfer.targets[blob_cli_xfer.target_count];
4548
4549 t->addr = addr;
4550
4551 LOG_DBG("Added target 0x%04x", t->addr);
4552
4553 blob_cli_xfer.target_count++;
4554 return 0;
4555 }
4556
blob_info_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4557 static uint8_t blob_info_get(const void *cmd, uint16_t cmd_len,
4558 void *rsp, uint16_t *rsp_len)
4559 {
4560 const struct btp_mmdl_blob_info_get_cmd *cp = cmd;
4561 struct model_data *model_bound;
4562 uint16_t addr = BT_MESH_ADDR_UNASSIGNED;
4563 uint16_t group = BT_MESH_ADDR_UNASSIGNED;
4564 int err;
4565
4566 LOG_DBG("");
4567
4568 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI);
4569 if (!model_bound) {
4570 LOG_ERR("Model not found");
4571 return BTP_STATUS_FAILED;
4572 }
4573
4574 for (int i = 0; i < cp->addr_cnt; i++) {
4575 addr = cp->addr[1 + i * sizeof(uint16_t)] |
4576 (cp->addr[i * sizeof(uint16_t)] << 8);
4577 err = cmd_blob_target(addr);
4578 if (err) {
4579 LOG_ERR("err target %d", err);
4580 return BTP_STATUS_FAILED;
4581 }
4582 }
4583
4584 if (cp->addr_cnt > 1) {
4585 group = BT_MESH_ADDR_UNASSIGNED;
4586 } else {
4587 group = addr;
4588 }
4589
4590 if (!blob_cli_xfer.target_count) {
4591 LOG_ERR("Failed: No targets");
4592 return BTP_STATUS_FAILED;
4593 }
4594
4595 blob_cli_inputs_prepare(group, model_bound->appkey_idx);
4596
4597 err = bt_mesh_blob_cli_caps_get(&blob_cli, &blob_cli_xfer.inputs);
4598
4599 if (err) {
4600 return BTP_STATUS_FAILED;
4601 }
4602
4603 return BTP_STATUS_SUCCESS;
4604 }
4605
blob_transfer_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4606 static uint8_t blob_transfer_start(const void *cmd, uint16_t cmd_len,
4607 void *rsp, uint16_t *rsp_len)
4608 {
4609 const struct btp_mmdl_blob_transfer_start_cmd *cp = cmd;
4610 struct model_data *model_bound;
4611 int err = 0;
4612
4613 LOG_DBG("");
4614
4615 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI);
4616 if (!model_bound) {
4617 LOG_ERR("Model not found");
4618 return BTP_STATUS_FAILED;
4619 }
4620
4621 if (!blob_cli_xfer.target_count) {
4622 LOG_ERR("Failed: No targets");
4623 return BTP_STATUS_FAILED;
4624 }
4625 blob_cli_xfer.xfer.id = cp->id;
4626 blob_cli_xfer.xfer.size = cp->size;
4627 blob_cli_xfer.xfer.block_size_log = cp->block_size;
4628 blob_cli_xfer.xfer.chunk_size = cp->chunk_size;
4629
4630 if (blob_cli.caps.modes) {
4631 blob_cli_xfer.xfer.mode = blob_cli.caps.modes;
4632 } else {
4633 blob_cli_xfer.xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH;
4634 }
4635
4636 if (cp->timeout) {
4637 blob_cli_xfer.inputs.timeout_base = cp->timeout;
4638 }
4639
4640 if (cp->ttl) {
4641 blob_cli_xfer.inputs.ttl = cp->ttl;
4642 }
4643
4644 err = bt_mesh_blob_cli_send(&blob_cli, &blob_cli_xfer.inputs,
4645 &blob_cli_xfer.xfer, &dummy_blob_io);
4646
4647 if (err) {
4648 return BTP_STATUS_FAILED;
4649 }
4650
4651 return BTP_STATUS_SUCCESS;
4652 }
4653
blob_transfer_cancel(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4654 static uint8_t blob_transfer_cancel(const void *cmd, uint16_t cmd_len,
4655 void *rsp, uint16_t *rsp_len)
4656 {
4657 LOG_DBG("");
4658
4659 bt_mesh_blob_cli_cancel(&blob_cli);
4660
4661 return BTP_STATUS_SUCCESS;
4662 }
4663
blob_transfer_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4664 static uint8_t blob_transfer_get(const void *cmd, uint16_t cmd_len,
4665 void *rsp, uint16_t *rsp_len)
4666 {
4667 struct model_data *model_bound;
4668 uint16_t group;
4669 int err;
4670
4671 LOG_DBG("");
4672
4673 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI);
4674 if (!model_bound) {
4675 LOG_ERR("Model not found");
4676 return BTP_STATUS_FAILED;
4677 }
4678
4679 group = model_bound->addr;
4680
4681 err = cmd_blob_target(group);
4682 if (err) {
4683 LOG_ERR("err target %d", err);
4684 return BTP_STATUS_FAILED;
4685 }
4686
4687 if (!blob_cli_xfer.target_count) {
4688 LOG_ERR("Failed: No targets");
4689 return BTP_STATUS_FAILED;
4690 }
4691
4692 blob_cli_inputs_prepare(group, model_bound->appkey_idx);
4693
4694 err = bt_mesh_blob_cli_xfer_progress_get(&blob_cli, &blob_cli_xfer.inputs);
4695
4696 if (err) {
4697 LOG_ERR("ERR %d", err);
4698 return BTP_STATUS_FAILED;
4699 }
4700
4701 return BTP_STATUS_SUCCESS;
4702 }
4703 #endif /* CONFIG_BT_MESH_BLOB_CLI */
4704
4705 #if defined(CONFIG_BT_MESH_BLOB_SRV)
blob_srv_recv(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4706 static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len,
4707 void *rsp, uint16_t *rsp_len)
4708 {
4709 const struct btp_mmdl_blob_srv_recv_cmd *cp = cmd;
4710 struct model_data *model_bound;
4711 int err;
4712
4713 #if defined(CONFIG_BT_MESH_DFD_SRV)
4714 struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob;
4715 #elif defined(CONFIG_BT_MESH_DFU_SRV)
4716 struct bt_mesh_blob_srv *srv = &dfu_srv.blob;
4717 #endif
4718
4719 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV);
4720 if (!model_bound) {
4721 LOG_ERR("Model not found");
4722 return BTP_STATUS_FAILED;
4723 }
4724
4725 uint16_t timeout_base;
4726 uint64_t id;
4727 uint8_t ttl;
4728
4729 LOG_DBG("");
4730
4731 id = cp->id;
4732 timeout_base = cp->timeout;
4733 ttl = cp->ttl;
4734
4735 err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, ttl,
4736 timeout_base);
4737
4738 if (err) {
4739 LOG_ERR("ERR %d", err);
4740 return BTP_STATUS_FAILED;
4741 }
4742
4743 return BTP_STATUS_SUCCESS;
4744 }
4745
blob_srv_cancel(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4746 static uint8_t blob_srv_cancel(const void *cmd, uint16_t cmd_len,
4747 void *rsp, uint16_t *rsp_len)
4748 {
4749 struct model_data *model_bound;
4750 int err;
4751
4752 #if defined(CONFIG_BT_MESH_DFU_SRV)
4753 struct bt_mesh_blob_srv *srv = &dfu_srv.blob;
4754 #elif defined(CONFIG_BT_MESH_DFD_SRV)
4755 struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob;
4756 #endif
4757
4758 model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV);
4759 if (!model_bound) {
4760 LOG_ERR("Model not found");
4761 return BTP_STATUS_FAILED;
4762 }
4763
4764 LOG_DBG("");
4765
4766 err = bt_mesh_blob_srv_cancel(srv);
4767
4768 if (err) {
4769 LOG_ERR("ERR %d", err);
4770 return BTP_STATUS_FAILED;
4771 }
4772
4773 return BTP_STATUS_SUCCESS;
4774 }
4775 #endif
4776
4777 static const struct btp_handler handlers[] = {
4778 {
4779 .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS,
4780 .index = BTP_INDEX_NONE,
4781 .expect_len = 0,
4782 .func = supported_commands,
4783 },
4784 {
4785 .opcode = BTP_MESH_CONFIG_PROVISIONING,
4786 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4787 .func = config_prov,
4788 },
4789 {
4790 .opcode = BTP_MESH_PROVISION_NODE,
4791 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4792 .func = provision_node,
4793 },
4794 {
4795 .opcode = BTP_MESH_INIT,
4796 .expect_len = sizeof(struct btp_mesh_init_cmd),
4797 .func = init,
4798 },
4799 {
4800 .opcode = BTP_MESH_RESET,
4801 .expect_len = 0,
4802 .func = reset,
4803 },
4804 {
4805 .opcode = BTP_MESH_INPUT_NUMBER,
4806 .expect_len = sizeof(struct btp_mesh_input_number_cmd),
4807 .func = input_number,
4808 },
4809 {
4810 .opcode = BTP_MESH_INPUT_STRING,
4811 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4812 .func = input_string,
4813 },
4814 {
4815 .opcode = BTP_MESH_IVU_TEST_MODE,
4816 .expect_len = sizeof(struct btp_mesh_ivu_test_mode_cmd),
4817 .func = ivu_test_mode,
4818 },
4819 {
4820 .opcode = BTP_MESH_IVU_TOGGLE_STATE,
4821 .expect_len = 0,
4822 .func = ivu_toggle_state,
4823 },
4824 #if defined(CONFIG_BT_MESH_LOW_POWER)
4825 {
4826 .opcode = BTP_MESH_LPN,
4827 .expect_len = sizeof(struct btp_mesh_lpn_set_cmd),
4828 .func = lpn,
4829 },
4830 {
4831 .opcode = BTP_MESH_LPN_POLL,
4832 .expect_len = 0,
4833 .func = lpn_poll,
4834 },
4835 #endif /* CONFIG_BT_MESH_LOW_POWER */
4836 {
4837 .opcode = BTP_MESH_NET_SEND,
4838 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4839 .func = net_send,
4840 },
4841 {
4842 .opcode = BTP_MESH_HEALTH_GENERATE_FAULTS,
4843 .expect_len = 0,
4844 .func = health_generate_faults,
4845 },
4846 {
4847 .opcode = BTP_MESH_HEALTH_CLEAR_FAULTS,
4848 .expect_len = 0,
4849 .func = health_clear_faults,
4850 },
4851 {
4852 .opcode = BTP_MESH_MODEL_SEND,
4853 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4854 .func = model_send,
4855 },
4856 {
4857 .opcode = BTP_MESH_COMP_DATA_GET,
4858 .expect_len = sizeof(struct btp_mesh_comp_data_get_cmd),
4859 .func = composition_data_get,
4860 },
4861 {
4862 .opcode = BTP_MESH_CFG_BEACON_GET,
4863 .expect_len = sizeof(struct btp_mesh_cfg_beacon_get_cmd),
4864 .func = config_beacon_get,
4865 },
4866 {
4867 .opcode = BTP_MESH_CFG_BEACON_SET,
4868 .expect_len = sizeof(struct btp_mesh_cfg_beacon_set_cmd),
4869 .func = config_beacon_set,
4870 },
4871 {
4872 .opcode = BTP_MESH_CFG_DEFAULT_TTL_GET,
4873 .expect_len = sizeof(struct btp_mesh_cfg_default_ttl_get_cmd),
4874 .func = config_default_ttl_get,
4875 },
4876 {
4877 .opcode = BTP_MESH_CFG_DEFAULT_TTL_SET,
4878 .expect_len = sizeof(struct btp_mesh_cfg_default_ttl_set_cmd),
4879 .func = config_default_ttl_set,
4880 },
4881 {
4882 .opcode = BTP_MESH_CFG_GATT_PROXY_GET,
4883 .expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_get_cmd),
4884 .func = config_gatt_proxy_get,
4885 },
4886 {
4887 .opcode = BTP_MESH_CFG_GATT_PROXY_SET,
4888 .expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_set_cmd),
4889 .func = config_gatt_proxy_set,
4890 },
4891 {
4892 .opcode = BTP_MESH_CFG_FRIEND_GET,
4893 .expect_len = sizeof(struct btp_mesh_cfg_friend_get_cmd),
4894 .func = config_friend_get,
4895 },
4896 {
4897 .opcode = BTP_MESH_CFG_FRIEND_SET,
4898 .expect_len = sizeof(struct btp_mesh_cfg_friend_set_cmd),
4899 .func = config_friend_set,
4900 },
4901 {
4902 .opcode = BTP_MESH_CFG_RELAY_GET,
4903 .expect_len = sizeof(struct btp_mesh_cfg_relay_get_cmd),
4904 .func = config_relay_get,
4905 },
4906 {
4907 .opcode = BTP_MESH_CFG_RELAY_SET,
4908 .expect_len = sizeof(struct btp_mesh_cfg_relay_set_cmd),
4909 .func = config_relay_set,
4910 },
4911 {
4912 .opcode = BTP_MESH_CFG_MODEL_PUB_GET,
4913 .expect_len = sizeof(struct btp_mesh_cfg_model_pub_get_cmd),
4914 .func = config_mod_pub_get,
4915 },
4916 {
4917 .opcode = BTP_MESH_CFG_MODEL_PUB_SET,
4918 .expect_len = sizeof(struct btp_mesh_cfg_model_pub_set_cmd),
4919 .func = config_mod_pub_set,
4920 },
4921 {
4922 .opcode = BTP_MESH_CFG_MODEL_SUB_ADD,
4923 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_add_cmd),
4924 .func = config_mod_sub_add,
4925 },
4926 {
4927 .opcode = BTP_MESH_CFG_MODEL_SUB_DEL,
4928 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_del_cmd),
4929 .func = config_mod_sub_del,
4930 },
4931 {
4932 .opcode = BTP_MESH_CFG_MODEL_SUB_OVW,
4933 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_ovw_cmd),
4934 .func = config_mod_sub_ovw,
4935 },
4936 {
4937 .opcode = BTP_MESH_CFG_MODEL_SUB_DEL_ALL,
4938 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_del_all_cmd),
4939 .func = config_mod_sub_del_all,
4940 },
4941 {
4942 .opcode = BTP_MESH_CFG_MODEL_SUB_GET,
4943 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_get_cmd),
4944 .func = config_mod_sub_get,
4945 },
4946 {
4947 .opcode = BTP_MESH_CFG_MODEL_SUB_GET_VND,
4948 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_get_vnd_cmd),
4949 .func = config_mod_sub_get_vnd,
4950 },
4951 {
4952 .opcode = BTP_MESH_CFG_MODEL_SUB_VA_ADD,
4953 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_va_add_cmd),
4954 .func = config_mod_sub_va_add,
4955 },
4956 {
4957 .opcode = BTP_MESH_CFG_MODEL_SUB_VA_DEL,
4958 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_va_del_cmd),
4959 .func = config_mod_sub_va_del,
4960 },
4961 {
4962 .opcode = BTP_MESH_CFG_MODEL_SUB_VA_OVW,
4963 .expect_len = sizeof(struct btp_mesh_cfg_model_sub_va_ovw_cmd),
4964 .func = config_mod_sub_va_ovw,
4965 },
4966 {
4967 .opcode = BTP_MESH_CFG_NETKEY_ADD,
4968 .expect_len = sizeof(struct btp_mesh_cfg_netkey_add_cmd),
4969 .func = config_netkey_add,
4970 },
4971 {
4972 .opcode = BTP_MESH_CFG_NETKEY_GET,
4973 .expect_len = sizeof(struct btp_mesh_cfg_netkey_get_cmd),
4974 .func = config_netkey_get,
4975 },
4976 {
4977 .opcode = BTP_MESH_CFG_NETKEY_DEL,
4978 .expect_len = sizeof(struct btp_mesh_cfg_netkey_del_cmd),
4979 .func = config_netkey_del,
4980 },
4981 {
4982 .opcode = BTP_MESH_CFG_NETKEY_UPDATE,
4983 .expect_len = sizeof(struct btp_mesh_cfg_netkey_update_cmd),
4984 .func = config_netkey_update,
4985 },
4986 {
4987 .opcode = BTP_MESH_CFG_APPKEY_ADD,
4988 .expect_len = sizeof(struct btp_mesh_cfg_appkey_add_cmd),
4989 .func = config_appkey_add,
4990 },
4991 {
4992 .opcode = BTP_MESH_CFG_APPKEY_GET,
4993 .expect_len = sizeof(struct btp_mesh_cfg_appkey_get_cmd),
4994 .func = config_appkey_get,
4995 },
4996 {
4997 .opcode = BTP_MESH_CFG_APPKEY_DEL,
4998 .expect_len = sizeof(struct btp_mesh_cfg_appkey_del_cmd),
4999 .func = config_appkey_del,
5000 },
5001 {
5002 .opcode = BTP_MESH_CFG_APPKEY_UPDATE,
5003 .expect_len = sizeof(struct btp_mesh_cfg_appkey_update_cmd),
5004 .func = config_appkey_update,
5005 },
5006 {
5007 .opcode = BTP_MESH_CFG_MODEL_APP_BIND,
5008 .expect_len = sizeof(struct btp_mesh_cfg_model_app_bind_cmd),
5009 .func = config_model_app_bind,
5010 },
5011 {
5012 .opcode = BTP_MESH_CFG_MODEL_APP_UNBIND,
5013 .expect_len = sizeof(struct btp_mesh_cfg_model_app_unbind_cmd),
5014 .func = config_model_app_unbind,
5015 },
5016 {
5017 .opcode = BTP_MESH_CFG_MODEL_APP_GET,
5018 .expect_len = sizeof(struct btp_mesh_cfg_model_app_get_cmd),
5019 .func = config_model_app_get,
5020 },
5021 {
5022 .opcode = BTP_MESH_CFG_MODEL_APP_VND_GET,
5023 .expect_len = sizeof(struct btp_mesh_cfg_model_app_vnd_get_cmd),
5024 .func = config_model_app_vnd_get,
5025 },
5026 {
5027 .opcode = BTP_MESH_CFG_HEARTBEAT_PUB_SET,
5028 .expect_len = sizeof(struct btp_mesh_cfg_heartbeat_pub_set_cmd),
5029 .func = config_hb_pub_set,
5030 },
5031 {
5032 .opcode = BTP_MESH_CFG_HEARTBEAT_PUB_GET,
5033 .expect_len = sizeof(struct btp_mesh_cfg_heartbeat_pub_get_cmd),
5034 .func = config_hb_pub_get,
5035 },
5036 {
5037 .opcode = BTP_MESH_CFG_HEARTBEAT_SUB_SET,
5038 .expect_len = sizeof(struct btp_mesh_cfg_heartbeat_sub_set_cmd),
5039 .func = config_hb_sub_set,
5040 },
5041 {
5042 .opcode = BTP_MESH_CFG_HEARTBEAT_SUB_GET,
5043 .expect_len = sizeof(struct btp_mesh_cfg_heartbeat_sub_get_cmd),
5044 .func = config_hb_sub_get,
5045 },
5046 {
5047 .opcode = BTP_MESH_CFG_NET_TRANS_GET,
5048 .expect_len = sizeof(struct btp_mesh_cfg_net_trans_get_cmd),
5049 .func = config_net_trans_get,
5050 },
5051 {
5052 .opcode = BTP_MESH_CFG_NET_TRANS_SET,
5053 .expect_len = sizeof(struct btp_mesh_cfg_net_trans_set_cmd),
5054 .func = config_net_trans_set,
5055 },
5056 {
5057 .opcode = BTP_MESH_CFG_NODE_IDT_SET,
5058 .expect_len = sizeof(struct btp_mesh_cfg_node_idt_set_cmd),
5059 .func = config_node_identity_set,
5060 },
5061 {
5062 .opcode = BTP_MESH_CFG_NODE_IDT_GET,
5063 .expect_len = sizeof(struct btp_mesh_cfg_node_idt_get_cmd),
5064 .func = config_node_identity_get,
5065 },
5066 {
5067 .opcode = BTP_MESH_CFG_NODE_RESET,
5068 .expect_len = sizeof(struct btp_mesh_cfg_node_reset_cmd),
5069 .func = config_node_reset,
5070 },
5071 {
5072 .opcode = BTP_MESH_CFG_LPN_TIMEOUT_GET,
5073 .expect_len = sizeof(struct btp_mesh_cfg_lpn_timeout_cmd),
5074 .func = config_lpn_timeout_get,
5075 },
5076 {
5077 .opcode = BTP_MESH_CFG_MODEL_PUB_VA_SET,
5078 .expect_len = sizeof(struct btp_mesh_cfg_model_pub_va_set_cmd),
5079 .func = config_mod_pub_va_set,
5080 },
5081 {
5082 .opcode = BTP_MESH_CFG_MODEL_APP_BIND_VND,
5083 .expect_len = sizeof(struct btp_mesh_cfg_model_app_bind_vnd_cmd),
5084 .func = config_model_app_bind_vnd,
5085 },
5086 {
5087 .opcode = BTP_MESH_HEALTH_FAULT_GET,
5088 .expect_len = sizeof(struct btp_mesh_health_fault_get_cmd),
5089 .func = health_fault_get,
5090 },
5091 {
5092 .opcode = BTP_MESH_HEALTH_FAULT_CLEAR,
5093 .expect_len = sizeof(struct btp_mesh_health_fault_clear_cmd),
5094 .func = health_fault_clear,
5095 },
5096 {
5097 .opcode = BTP_MESH_HEALTH_FAULT_TEST,
5098 .expect_len = sizeof(struct btp_mesh_health_fault_test_cmd),
5099 .func = health_fault_test,
5100 },
5101 {
5102 .opcode = BTP_MESH_HEALTH_PERIOD_GET,
5103 .expect_len = sizeof(struct btp_mesh_health_period_get_cmd),
5104 .func = health_period_get,
5105 },
5106 {
5107 .opcode = BTP_MESH_HEALTH_PERIOD_SET,
5108 .expect_len = sizeof(struct btp_mesh_health_period_set_cmd),
5109 .func = health_period_set,
5110 },
5111 {
5112 .opcode = BTP_MESH_HEALTH_ATTENTION_GET,
5113 .expect_len = sizeof(struct btp_mesh_health_attention_get_cmd),
5114 .func = health_attention_get,
5115 },
5116 {
5117 .opcode = BTP_MESH_HEALTH_ATTENTION_SET,
5118 .expect_len = sizeof(struct btp_mesh_health_attention_set_cmd),
5119 .func = health_attention_set,
5120 },
5121 {
5122 .opcode = BTP_MESH_PROVISION_ADV,
5123 .expect_len = sizeof(struct btp_mesh_provision_adv_cmd),
5124 .func = provision_adv,
5125 },
5126 {
5127 .opcode = BTP_MESH_CFG_KRP_GET,
5128 .expect_len = sizeof(struct btp_mesh_cfg_krp_get_cmd),
5129 .func = config_krp_get,
5130 },
5131 {
5132 .opcode = BTP_MESH_CFG_KRP_SET,
5133 .expect_len = sizeof(struct btp_mesh_cfg_krp_set_cmd),
5134 .func = config_krp_set,
5135 },
5136 {
5137 .opcode = BTP_MESH_VA_ADD,
5138 .expect_len = sizeof(struct btp_mesh_va_add_cmd),
5139 .func = va_add,
5140 },
5141 {
5142 .opcode = BTP_MESH_VA_DEL,
5143 .expect_len = sizeof(struct btp_mesh_va_del_cmd),
5144 .func = va_del,
5145 },
5146 #if defined(CONFIG_BT_TESTING)
5147 #if defined(CONFIG_BT_MESH_LOW_POWER)
5148 {
5149 .opcode = BTP_MESH_LPN_SUBSCRIBE,
5150 .expect_len = sizeof(struct btp_mesh_lpn_subscribe_cmd),
5151 .func = lpn_subscribe,
5152 },
5153 {
5154 .opcode = BTP_MESH_LPN_UNSUBSCRIBE,
5155 .expect_len = sizeof(struct btp_mesh_lpn_unsubscribe_cmd),
5156 .func = lpn_unsubscribe,
5157 },
5158 #endif /* CONFIG_BT_MESH_LOW_POWER */
5159 {
5160 .opcode = BTP_MESH_RPL_CLEAR,
5161 .expect_len = 0,
5162 .func = rpl_clear,
5163 },
5164 #endif /* CONFIG_BT_TESTING */
5165 {
5166 .opcode = BTP_MESH_PROXY_IDENTITY,
5167 .expect_len = 0,
5168 .func = proxy_identity_enable,
5169 },
5170 #if defined(CONFIG_BT_MESH_PROXY_CLIENT)
5171 {.opcode = BTP_MESH_PROXY_CONNECT,
5172 .expect_len = sizeof(struct btp_proxy_connect_cmd),
5173 .func = proxy_connect},
5174 #endif
5175 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
5176 {.opcode = BTP_MESH_SAR_TRANSMITTER_GET,
5177 .expect_len = sizeof(struct btp_mesh_sar_transmitter_get_cmd),
5178 .func = sar_transmitter_get},
5179 {.opcode = BTP_MESH_SAR_TRANSMITTER_SET,
5180 .expect_len = sizeof(struct btp_mesh_sar_transmitter_set_cmd),
5181 .func = sar_transmitter_set},
5182 {.opcode = BTP_MESH_SAR_RECEIVER_GET,
5183 .expect_len = sizeof(struct btp_mesh_sar_receiver_get_cmd),
5184 .func = sar_receiver_get},
5185 {.opcode = BTP_MESH_SAR_RECEIVER_SET,
5186 .expect_len = sizeof(struct btp_mesh_sar_receiver_set_cmd),
5187 .func = sar_receiver_set},
5188 #endif
5189 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
5190 {.opcode = BTP_MESH_LARGE_COMP_DATA_GET,
5191 .expect_len = sizeof(struct btp_mesh_large_comp_data_get_cmd),
5192 .func = large_comp_data_get},
5193 {.opcode = BTP_MESH_MODELS_METADATA_GET,
5194 .expect_len = sizeof(struct btp_mesh_models_metadata_get_cmd),
5195 .func = models_metadata_get},
5196 #endif
5197 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
5198 {.opcode = BTP_MESH_OPCODES_AGGREGATOR_INIT,
5199 .expect_len = sizeof(struct btp_mesh_opcodes_aggregator_init_cmd),
5200 .func = opcodes_aggregator_init},
5201 {.opcode = BTP_MESH_OPCODES_AGGREGATOR_SEND,
5202 .expect_len = 0,
5203 .func = opcodes_aggregator_send},
5204 #endif
5205 {.opcode = BTP_MESH_COMP_CHANGE_PREPARE, .expect_len = 0, .func = change_prepare},
5206 #if defined(CONFIG_BT_MESH_RPR_CLI)
5207 {.opcode = BTP_MESH_RPR_SCAN_START,
5208 .expect_len = sizeof(struct btp_rpr_scan_start_cmd),
5209 .func = rpr_scan_start},
5210 {.opcode = BTP_MESH_RPR_EXT_SCAN_START,
5211 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5212 .func = rpr_ext_scan_start},
5213 {.opcode = BTP_MESH_RPR_SCAN_CAPS_GET,
5214 .expect_len = sizeof(struct btp_rpr_scan_caps_get_cmd),
5215 .func = rpr_scan_caps_get},
5216 {.opcode = BTP_MESH_RPR_SCAN_GET,
5217 .expect_len = sizeof(struct btp_rpr_scan_get_cmd),
5218 .func = rpr_scan_get},
5219 {.opcode = BTP_MESH_RPR_SCAN_STOP,
5220 .expect_len = sizeof(struct btp_rpr_scan_stop_cmd),
5221 .func = rpr_scan_stop},
5222 {.opcode = BTP_MESH_RPR_LINK_GET,
5223 .expect_len = sizeof(struct btp_rpr_link_get_cmd),
5224 .func = rpr_link_get},
5225 {.opcode = BTP_MESH_RPR_LINK_CLOSE,
5226 .expect_len = sizeof(struct btp_rpr_link_close_cmd),
5227 .func = rpr_link_close},
5228 {.opcode = BTP_MESH_RPR_PROV_REMOTE,
5229 .expect_len = sizeof(struct btp_rpr_prov_remote_cmd),
5230 .func = rpr_prov_remote},
5231 {.opcode = BTP_MESH_RPR_REPROV_REMOTE,
5232 .expect_len = sizeof(struct btp_rpr_reprov_remote_cmd),
5233 .func = rpr_reprov_remote},
5234 #endif
5235 #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI)
5236 {.opcode = BTP_MESH_PRIV_BEACON_GET,
5237 .expect_len = sizeof(struct btp_priv_beacon_get_cmd),
5238 .func = priv_beacon_get},
5239 {.opcode = BTP_MESH_PRIV_BEACON_SET,
5240 .expect_len = sizeof(struct btp_priv_beacon_set_cmd),
5241 .func = priv_beacon_set},
5242 {.opcode = BTP_MESH_PRIV_GATT_PROXY_GET,
5243 .expect_len = sizeof(struct btp_priv_gatt_proxy_get_cmd),
5244 .func = priv_gatt_proxy_get},
5245 {.opcode = BTP_MESH_PRIV_GATT_PROXY_SET,
5246 .expect_len = sizeof(struct btp_priv_gatt_proxy_set_cmd),
5247 .func = priv_gatt_proxy_set},
5248 {.opcode = BTP_MESH_PRIV_NODE_ID_GET,
5249 .expect_len = sizeof(struct btp_priv_node_id_get_cmd),
5250 .func = priv_node_id_get},
5251 {.opcode = BTP_MESH_PRIV_NODE_ID_SET,
5252 .expect_len = sizeof(struct btp_priv_node_id_set_cmd),
5253 .func = priv_node_id_set},
5254 {.opcode = BTP_MESH_PROXY_PRIVATE_IDENTITY,
5255 .expect_len = 0,
5256 .func = proxy_private_identity_enable},
5257 #endif
5258 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
5259 {.opcode = BTP_MESH_OD_PRIV_PROXY_GET,
5260 .expect_len = sizeof(struct btp_od_priv_proxy_get_cmd),
5261 .func = od_priv_proxy_get},
5262 {.opcode = BTP_MESH_OD_PRIV_PROXY_SET,
5263 .expect_len = sizeof(struct btp_od_priv_proxy_set_cmd),
5264 .func = od_priv_proxy_set},
5265 #endif
5266 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
5267 {.opcode = BTP_MESH_SRPL_CLEAR,
5268 .expect_len = sizeof(struct btp_srpl_clear_cmd),
5269 .func = srpl_clear},
5270 #endif
5271 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
5272 {.opcode = BTP_MESH_SUBNET_BRIDGE_GET,
5273 .expect_len = sizeof(struct btp_mesh_subnet_bridge_get_cmd),
5274 .func = subnet_bridge_get},
5275 {.opcode = BTP_MESH_SUBNET_BRIDGE_SET,
5276 .expect_len = sizeof(struct btp_mesh_subnet_bridge_set_cmd),
5277 .func = subnet_bridge_set},
5278 {.opcode = BTP_MESH_BRIDGING_TABLE_ADD,
5279 .expect_len = sizeof(struct btp_mesh_bridging_table_add_cmd),
5280 .func = bridging_table_add},
5281 {.opcode = BTP_MESH_BRIDGING_TABLE_REMOVE,
5282 .expect_len = sizeof(struct btp_mesh_bridging_table_remove_cmd),
5283 .func = bridging_table_remove},
5284 {.opcode = BTP_MESH_BRIDGED_SUBNETS_GET,
5285 .expect_len = sizeof(struct btp_mesh_bridged_subnets_get_cmd),
5286 .func = bridged_subnets_get},
5287 {.opcode = BTP_MESH_BRIDGING_TABLE_GET,
5288 .expect_len = sizeof(struct btp_mesh_bridging_table_get_cmd),
5289 .func = bridging_table_get},
5290 {.opcode = BTP_MESH_BRIDGING_TABLE_SIZE_GET,
5291 .expect_len = sizeof(struct btp_mesh_bridging_table_size_get_cmd),
5292 .func = bridging_table_size_get},
5293 #endif
5294 #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION)
5295 {.opcode = BTP_MESH_PROXY_SOLICIT,
5296 .expect_len = sizeof(struct btp_proxy_solicit_cmd),
5297 .func = proxy_solicit},
5298 #endif
5299 {.opcode = BTP_MESH_START, .expect_len = 0, .func = start},
5300 };
5301
5302 static const struct btp_handler mdl_handlers[] = {
5303 #if defined(CONFIG_BT_MESH_DFD_SRV)
5304 {
5305 .opcode = BTP_MMDL_DFU_INFO_GET,
5306 .expect_len = sizeof(struct btp_mmdl_dfu_info_get_cmd),
5307 .func = dfu_info_get,
5308 },
5309 {
5310 .opcode = BTP_MMDL_DFU_UPDATE_METADATA_CHECK,
5311 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5312 .func = dfu_update_metadata_check,
5313 },
5314 {
5315 .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_GET,
5316 .expect_len = 0,
5317 .func = dfu_firmware_update_get,
5318 },
5319 {
5320 .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_CANCEL,
5321 .expect_len = 0,
5322 .func = dfu_firmware_update_cancel,
5323 },
5324 {
5325 .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_START,
5326 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5327 .func = dfu_firmware_update_start,
5328 },
5329 {
5330 .opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY,
5331 .expect_len = 0,
5332 .func = dfu_firmware_update_apply,
5333 },
5334 #endif
5335 #if defined(CONFIG_BT_MESH_BLOB_CLI)
5336 {
5337 .opcode = BTP_MMDL_BLOB_INFO_GET,
5338 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5339 .func = blob_info_get,
5340 },
5341 {
5342 .opcode = BTP_MMDL_BLOB_TRANSFER_START,
5343 .expect_len = sizeof(struct btp_mmdl_blob_transfer_start_cmd),
5344 .func = blob_transfer_start,
5345 },
5346 {
5347 .opcode = BTP_MMDL_BLOB_TRANSFER_CANCEL,
5348 .expect_len = 0,
5349 .func = blob_transfer_cancel,
5350 },
5351 {
5352 .opcode = BTP_MMDL_BLOB_TRANSFER_GET,
5353 .expect_len = 0,
5354 .func = blob_transfer_get,
5355 },
5356 #endif
5357 #if defined(CONFIG_BT_MESH_BLOB_SRV)
5358 {.opcode = BTP_MMDL_BLOB_SRV_RECV,
5359 .expect_len = sizeof(struct btp_mmdl_blob_srv_recv_cmd),
5360 .func = blob_srv_recv},
5361 {.opcode = BTP_MMDL_BLOB_SRV_CANCEL, .expect_len = 0, .func = blob_srv_cancel},
5362 #endif
5363 #if defined(CONFIG_BT_MESH_DFU_SRV)
5364 {.opcode = BTP_MMDL_DFU_SRV_APPLY, .expect_len = 0, .func = dfu_srv_apply},
5365 #endif
5366 };
5367
net_recv_ev(uint8_t ttl,uint8_t ctl,uint16_t src,uint16_t dst,const void * payload,size_t payload_len)5368 void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload,
5369 size_t payload_len)
5370 {
5371 NET_BUF_SIMPLE_DEFINE(buf, UINT8_MAX);
5372 struct btp_mesh_net_recv_ev *ev;
5373
5374 LOG_DBG("ttl 0x%02x ctl 0x%02x src 0x%04x dst 0x%04x payload_len %zu",
5375 ttl, ctl, src, dst, payload_len);
5376
5377 if (payload_len > net_buf_simple_tailroom(&buf)) {
5378 LOG_ERR("Payload size exceeds buffer size");
5379 return;
5380 }
5381
5382 ev = net_buf_simple_add(&buf, sizeof(*ev));
5383 ev->ttl = ttl;
5384 ev->ctl = ctl;
5385 ev->src = sys_cpu_to_le16(src);
5386 ev->dst = sys_cpu_to_le16(dst);
5387 ev->payload_len = payload_len;
5388 net_buf_simple_add_mem(&buf, payload, payload_len);
5389
5390 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_NET_RECV, buf.data, buf.len);
5391 }
5392
model_recv_ev(uint16_t src,uint16_t dst,const void * payload,size_t payload_len)5393 void model_recv_ev(uint16_t src, uint16_t dst, const void *payload,
5394 size_t payload_len)
5395 {
5396 NET_BUF_SIMPLE_DEFINE(buf, UINT8_MAX);
5397 struct btp_mesh_model_recv_ev *ev;
5398
5399 LOG_DBG("src 0x%04x dst 0x%04x payload_len %zu", src, dst, payload_len);
5400
5401 if (payload_len > net_buf_simple_tailroom(&buf)) {
5402 LOG_ERR("Payload size exceeds buffer size");
5403 return;
5404 }
5405
5406 ev = net_buf_simple_add(&buf, sizeof(*ev));
5407 ev->src = sys_cpu_to_le16(src);
5408 ev->dst = sys_cpu_to_le16(dst);
5409 ev->payload_len = payload_len;
5410 net_buf_simple_add_mem(&buf, payload, payload_len);
5411
5412 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_MODEL_RECV, buf.data, buf.len);
5413 }
5414
model_bound_cb(uint16_t addr,const struct bt_mesh_model * model,uint16_t key_idx)5415 static void model_bound_cb(uint16_t addr, const struct bt_mesh_model *model,
5416 uint16_t key_idx)
5417 {
5418 int i;
5419
5420 LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p",
5421 addr, key_idx, model);
5422
5423 for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
5424 if (!model_bound[i].model) {
5425 model_bound[i].model = model;
5426 model_bound[i].addr = addr;
5427 model_bound[i].appkey_idx = key_idx;
5428
5429 return;
5430 }
5431 }
5432
5433 LOG_ERR("model_bound is full");
5434 }
5435
model_unbound_cb(uint16_t addr,const struct bt_mesh_model * model,uint16_t key_idx)5436 static void model_unbound_cb(uint16_t addr, const struct bt_mesh_model *model,
5437 uint16_t key_idx)
5438 {
5439 int i;
5440
5441 LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p",
5442 addr, key_idx, model);
5443
5444 for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
5445 if (model_bound[i].model == model) {
5446 model_bound[i].model = NULL;
5447 model_bound[i].addr = 0x0000;
5448 model_bound[i].appkey_idx = BT_MESH_KEY_UNUSED;
5449
5450 return;
5451 }
5452 }
5453
5454 LOG_INF("model not found");
5455 }
5456
invalid_bearer_cb(uint8_t opcode)5457 static void invalid_bearer_cb(uint8_t opcode)
5458 {
5459 struct btp_mesh_invalid_bearer_ev ev = {
5460 .opcode = opcode,
5461 };
5462
5463 LOG_DBG("opcode 0x%02x", opcode);
5464
5465 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INVALID_BEARER, &ev, sizeof(ev));
5466 }
5467
incomp_timer_exp_cb(void)5468 static void incomp_timer_exp_cb(void)
5469 {
5470 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INCOMP_TIMER_EXP, NULL, 0);
5471 }
5472
5473 static struct bt_mesh_test_cb bt_mesh_test_cb = {
5474 .net_recv = net_recv_ev,
5475 .model_recv = model_recv_ev,
5476 .model_bound = model_bound_cb,
5477 .model_unbound = model_unbound_cb,
5478 .prov_invalid_bearer = invalid_bearer_cb,
5479 .trans_incomp_timer_exp = incomp_timer_exp_cb,
5480 };
5481
friend_established(uint16_t net_idx,uint16_t lpn_addr,uint8_t recv_delay,uint32_t polltimeout)5482 static void friend_established(uint16_t net_idx, uint16_t lpn_addr,
5483 uint8_t recv_delay, uint32_t polltimeout)
5484 {
5485 struct btp_mesh_frnd_established_ev ev = { net_idx, lpn_addr, recv_delay,
5486 polltimeout };
5487
5488 LOG_DBG("Friendship (as Friend) established with "
5489 "LPN 0x%04x Receive Delay %u Poll Timeout %u",
5490 lpn_addr, recv_delay, polltimeout);
5491
5492
5493 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_FRND_ESTABLISHED, &ev, sizeof(ev));
5494 }
5495
friend_terminated(uint16_t net_idx,uint16_t lpn_addr)5496 static void friend_terminated(uint16_t net_idx, uint16_t lpn_addr)
5497 {
5498 struct btp_mesh_frnd_terminated_ev ev = { net_idx, lpn_addr };
5499
5500 LOG_DBG("Friendship (as Friend) lost with LPN "
5501 "0x%04x", lpn_addr);
5502
5503 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_FRND_TERMINATED, &ev, sizeof(ev));
5504 }
5505
5506 BT_MESH_FRIEND_CB_DEFINE(friend_cb) = {
5507 .established = friend_established,
5508 .terminated = friend_terminated,
5509 };
5510
lpn_established(uint16_t net_idx,uint16_t friend_addr,uint8_t queue_size,uint8_t recv_win)5511 static void lpn_established(uint16_t net_idx, uint16_t friend_addr,
5512 uint8_t queue_size, uint8_t recv_win)
5513 {
5514 struct btp_mesh_lpn_established_ev ev = { net_idx, friend_addr, queue_size,
5515 recv_win };
5516
5517 LOG_DBG("Friendship (as LPN) established with "
5518 "Friend 0x%04x Queue Size %d Receive Window %d",
5519 friend_addr, queue_size, recv_win);
5520
5521 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_ESTABLISHED, &ev, sizeof(ev));
5522 }
5523
lpn_terminated(uint16_t net_idx,uint16_t friend_addr)5524 static void lpn_terminated(uint16_t net_idx, uint16_t friend_addr)
5525 {
5526 struct btp_mesh_lpn_polled_ev ev = { net_idx, friend_addr };
5527
5528 LOG_DBG("Friendship (as LPN) lost with Friend "
5529 "0x%04x", friend_addr);
5530
5531 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_TERMINATED, &ev, sizeof(ev));
5532 }
5533
lpn_polled(uint16_t net_idx,uint16_t friend_addr,bool retry)5534 static void lpn_polled(uint16_t net_idx, uint16_t friend_addr, bool retry)
5535 {
5536 struct btp_mesh_lpn_polled_ev ev = { net_idx, friend_addr, (uint8_t)retry };
5537
5538 LOG_DBG("LPN polled 0x%04x %s", friend_addr, retry ? "(retry)" : "");
5539
5540 tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_POLLED, &ev, sizeof(ev));
5541 }
5542
5543 BT_MESH_LPN_CB_DEFINE(lpn_cb) = {
5544 .established = lpn_established,
5545 .terminated = lpn_terminated,
5546 .polled = lpn_polled,
5547 };
5548
tester_init_mesh(void)5549 uint8_t tester_init_mesh(void)
5550 {
5551 if (IS_ENABLED(CONFIG_BT_TESTING)) {
5552 bt_mesh_test_cb_register(&bt_mesh_test_cb);
5553 }
5554
5555 #if defined(CONFIG_BT_MESH_COMP_PAGE_2)
5556 bt_mesh_comp2_register(&comp_p2);
5557 #endif
5558
5559 tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers,
5560 ARRAY_SIZE(handlers));
5561
5562 return BTP_STATUS_SUCCESS;
5563 }
5564
tester_unregister_mesh(void)5565 uint8_t tester_unregister_mesh(void)
5566 {
5567 return BTP_STATUS_SUCCESS;
5568 }
5569
tester_init_mmdl(void)5570 uint8_t tester_init_mmdl(void)
5571 {
5572 tester_register_command_handlers(BTP_SERVICE_ID_MESH_MDL, mdl_handlers,
5573 ARRAY_SIZE(mdl_handlers));
5574 return BTP_STATUS_SUCCESS;
5575 }
5576
tester_unregister_mmdl(void)5577 uint8_t tester_unregister_mmdl(void)
5578 {
5579 return BTP_STATUS_SUCCESS;
5580 }
5581