1 /* Bluetooth Mesh */
2
3 /*
4 * SPDX-FileCopyrightText: 2017 Intel Corporation
5 * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <string.h>
11 #include <errno.h>
12 #include <stdbool.h>
13
14 #include "btc_ble_mesh_config_model.h"
15
16 #include "mesh.h"
17 #include "mesh_config.h"
18 #include "foundation.h"
19 #include "mesh_common.h"
20 #include "cfg_cli.h"
21
22 #if CONFIG_BLE_MESH_CFG_CLI
23
24 static const bt_mesh_client_op_pair_t cfg_op_pair[] = {
25 { OP_BEACON_GET, OP_BEACON_STATUS },
26 { OP_BEACON_SET, OP_BEACON_STATUS },
27 { OP_DEV_COMP_DATA_GET, OP_DEV_COMP_DATA_STATUS },
28 { OP_DEFAULT_TTL_GET, OP_DEFAULT_TTL_STATUS },
29 { OP_DEFAULT_TTL_SET, OP_DEFAULT_TTL_STATUS },
30 { OP_GATT_PROXY_GET, OP_GATT_PROXY_STATUS },
31 { OP_GATT_PROXY_SET, OP_GATT_PROXY_STATUS },
32 { OP_RELAY_GET, OP_RELAY_STATUS },
33 { OP_RELAY_SET, OP_RELAY_STATUS },
34 { OP_MOD_PUB_GET, OP_MOD_PUB_STATUS },
35 { OP_MOD_PUB_SET, OP_MOD_PUB_STATUS },
36 { OP_MOD_PUB_VA_SET, OP_MOD_PUB_STATUS },
37 { OP_MOD_SUB_ADD, OP_MOD_SUB_STATUS },
38 { OP_MOD_SUB_VA_ADD, OP_MOD_SUB_STATUS },
39 { OP_MOD_SUB_DEL, OP_MOD_SUB_STATUS },
40 { OP_MOD_SUB_VA_DEL, OP_MOD_SUB_STATUS },
41 { OP_MOD_SUB_OVERWRITE, OP_MOD_SUB_STATUS },
42 { OP_MOD_SUB_VA_OVERWRITE, OP_MOD_SUB_STATUS },
43 { OP_MOD_SUB_DEL_ALL, OP_MOD_SUB_STATUS },
44 { OP_MOD_SUB_GET, OP_MOD_SUB_LIST },
45 { OP_MOD_SUB_GET_VND, OP_MOD_SUB_LIST_VND },
46 { OP_NET_KEY_ADD, OP_NET_KEY_STATUS },
47 { OP_NET_KEY_UPDATE, OP_NET_KEY_STATUS },
48 { OP_NET_KEY_DEL, OP_NET_KEY_STATUS },
49 { OP_NET_KEY_GET, OP_NET_KEY_LIST },
50 { OP_APP_KEY_ADD, OP_APP_KEY_STATUS },
51 { OP_APP_KEY_UPDATE, OP_APP_KEY_STATUS },
52 { OP_APP_KEY_DEL, OP_APP_KEY_STATUS },
53 { OP_APP_KEY_GET, OP_APP_KEY_LIST },
54 { OP_NODE_IDENTITY_GET, OP_NODE_IDENTITY_STATUS },
55 { OP_NODE_IDENTITY_SET, OP_NODE_IDENTITY_STATUS },
56 { OP_MOD_APP_BIND, OP_MOD_APP_STATUS },
57 { OP_MOD_APP_UNBIND, OP_MOD_APP_STATUS },
58 { OP_SIG_MOD_APP_GET, OP_SIG_MOD_APP_LIST },
59 { OP_VND_MOD_APP_GET, OP_VND_MOD_APP_LIST },
60 { OP_NODE_RESET, OP_NODE_RESET_STATUS },
61 { OP_FRIEND_GET, OP_FRIEND_STATUS },
62 { OP_FRIEND_SET, OP_FRIEND_STATUS },
63 { OP_KRP_GET, OP_KRP_STATUS },
64 { OP_KRP_SET, OP_KRP_STATUS },
65 { OP_HEARTBEAT_PUB_GET, OP_HEARTBEAT_PUB_STATUS },
66 { OP_HEARTBEAT_PUB_SET, OP_HEARTBEAT_PUB_STATUS },
67 { OP_HEARTBEAT_SUB_GET, OP_HEARTBEAT_SUB_STATUS },
68 { OP_HEARTBEAT_SUB_SET, OP_HEARTBEAT_SUB_STATUS },
69 { OP_LPN_TIMEOUT_GET, OP_LPN_TIMEOUT_STATUS },
70 { OP_NET_TRANSMIT_GET, OP_NET_TRANSMIT_STATUS },
71 { OP_NET_TRANSMIT_SET, OP_NET_TRANSMIT_STATUS },
72 };
73
74 static bt_mesh_mutex_t cfg_client_lock;
75
bt_mesh_cfg_client_mutex_new(void)76 static inline void bt_mesh_cfg_client_mutex_new(void)
77 {
78 if (!cfg_client_lock.mutex) {
79 bt_mesh_mutex_create(&cfg_client_lock);
80 }
81 }
82
83 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_cfg_client_mutex_free(void)84 static inline void bt_mesh_cfg_client_mutex_free(void)
85 {
86 bt_mesh_mutex_free(&cfg_client_lock);
87 }
88 #endif /* CONFIG_BLE_MESH_DEINIT */
89
bt_mesh_cfg_client_lock(void)90 static inline void bt_mesh_cfg_client_lock(void)
91 {
92 bt_mesh_mutex_lock(&cfg_client_lock);
93 }
94
bt_mesh_cfg_client_unlock(void)95 static inline void bt_mesh_cfg_client_unlock(void)
96 {
97 bt_mesh_mutex_unlock(&cfg_client_lock);
98 }
99
timeout_handler(struct k_work * work)100 static void timeout_handler(struct k_work *work)
101 {
102 struct k_delayed_work *timer = NULL;
103 bt_mesh_client_node_t *node = NULL;
104 struct bt_mesh_msg_ctx ctx = {0};
105 uint32_t opcode = 0U;
106
107 BT_WARN("Receive configuration status message timeout");
108
109 bt_mesh_cfg_client_lock();
110
111 timer = CONTAINER_OF(work, struct k_delayed_work, work);
112
113 if (timer && !k_delayed_work_free(timer)) {
114 node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
115 if (node) {
116 memcpy(&ctx, &node->ctx, sizeof(ctx));
117 opcode = node->opcode;
118 bt_mesh_client_free_node(node);
119 bt_mesh_config_client_cb_evt_to_btc(
120 opcode, BTC_BLE_MESH_EVT_CONFIG_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0);
121 }
122 }
123
124 bt_mesh_cfg_client_unlock();
125
126 return;
127 }
128
cfg_client_recv_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,void * status,size_t len)129 static void cfg_client_recv_status(struct bt_mesh_model *model,
130 struct bt_mesh_msg_ctx *ctx,
131 void *status, size_t len)
132 {
133 bt_mesh_client_node_t *node = NULL;
134 struct net_buf_simple buf = {0};
135 uint8_t evt_type = 0xFF;
136
137 if (!model || !ctx) {
138 BT_ERR("%s, Invalid parameter", __func__);
139 return;
140 }
141
142 /* If it is a publish message, sent to the user directly. */
143 buf.data = (uint8_t *)status;
144 buf.len = (uint16_t)len;
145
146 bt_mesh_cfg_client_lock();
147
148 node = bt_mesh_is_client_recv_publish_msg(model, ctx, &buf, true);
149 if (!node) {
150 BT_DBG("Unexpected Config Status 0x%04x", ctx->recv_op);
151 } else {
152 switch (node->opcode) {
153 case OP_BEACON_GET:
154 case OP_DEV_COMP_DATA_GET:
155 case OP_DEFAULT_TTL_GET:
156 case OP_GATT_PROXY_GET:
157 case OP_RELAY_GET:
158 case OP_MOD_PUB_GET:
159 case OP_MOD_SUB_GET:
160 case OP_MOD_SUB_GET_VND:
161 case OP_NET_KEY_GET:
162 case OP_APP_KEY_GET:
163 case OP_NODE_IDENTITY_GET:
164 case OP_SIG_MOD_APP_GET:
165 case OP_VND_MOD_APP_GET:
166 case OP_FRIEND_GET:
167 case OP_KRP_GET:
168 case OP_HEARTBEAT_PUB_GET:
169 case OP_HEARTBEAT_SUB_GET:
170 case OP_LPN_TIMEOUT_GET:
171 case OP_NET_TRANSMIT_GET:
172 evt_type = BTC_BLE_MESH_EVT_CONFIG_CLIENT_GET_STATE;
173 break;
174 case OP_BEACON_SET:
175 case OP_DEFAULT_TTL_SET:
176 case OP_GATT_PROXY_SET:
177 case OP_RELAY_SET:
178 case OP_MOD_PUB_SET:
179 case OP_MOD_PUB_VA_SET:
180 case OP_MOD_SUB_ADD:
181 case OP_MOD_SUB_VA_ADD:
182 case OP_MOD_SUB_DEL:
183 case OP_MOD_SUB_VA_DEL:
184 case OP_MOD_SUB_OVERWRITE:
185 case OP_MOD_SUB_VA_OVERWRITE:
186 case OP_MOD_SUB_DEL_ALL:
187 case OP_NET_KEY_ADD:
188 case OP_NET_KEY_UPDATE:
189 case OP_NET_KEY_DEL:
190 case OP_APP_KEY_ADD:
191 case OP_APP_KEY_UPDATE:
192 case OP_APP_KEY_DEL:
193 case OP_NODE_IDENTITY_SET:
194 case OP_MOD_APP_BIND:
195 case OP_MOD_APP_UNBIND:
196 case OP_NODE_RESET:
197 case OP_FRIEND_SET:
198 case OP_KRP_SET:
199 case OP_HEARTBEAT_PUB_SET:
200 case OP_HEARTBEAT_SUB_SET:
201 case OP_NET_TRANSMIT_SET:
202 evt_type = BTC_BLE_MESH_EVT_CONFIG_CLIENT_SET_STATE;
203 break;
204 default:
205 break;
206 }
207
208 if (!k_delayed_work_free(&node->timer)) {
209 uint32_t opcode = node->opcode;
210 bt_mesh_client_free_node(node);
211 bt_mesh_config_client_cb_evt_to_btc(
212 opcode, evt_type, model, ctx, (const uint8_t *)status, len);
213 }
214 }
215
216 bt_mesh_cfg_client_unlock();
217
218 switch (ctx->recv_op) {
219 case OP_DEV_COMP_DATA_STATUS: {
220 struct bt_mesh_cfg_comp_data_status *val = status;
221 bt_mesh_free_buf(val->comp_data);
222 break;
223 }
224 case OP_MOD_SUB_LIST:
225 case OP_MOD_SUB_LIST_VND: {
226 struct bt_mesh_cfg_mod_sub_list *val = status;
227 bt_mesh_free_buf(val->addr);
228 break;
229 }
230 case OP_NET_KEY_LIST: {
231 struct bt_mesh_cfg_net_key_list *val = status;
232 bt_mesh_free_buf(val->net_idx);
233 break;
234 }
235 case OP_APP_KEY_LIST: {
236 struct bt_mesh_cfg_app_key_list *val = status;
237 bt_mesh_free_buf(val->app_idx);
238 break;
239 }
240 case OP_SIG_MOD_APP_LIST:
241 case OP_VND_MOD_APP_LIST: {
242 struct bt_mesh_cfg_mod_app_list *val = status;
243 bt_mesh_free_buf(val->app_idx);
244 break;
245 }
246 default:
247 break;
248 }
249 }
250
comp_data_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)251 static void comp_data_status(struct bt_mesh_model *model,
252 struct bt_mesh_msg_ctx *ctx,
253 struct net_buf_simple *buf)
254 {
255 struct bt_mesh_cfg_comp_data_status status = {0};
256
257 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
258 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
259 bt_hex(buf->data, buf->len));
260
261 status.page = net_buf_simple_pull_u8(buf);
262 status.comp_data = bt_mesh_alloc_buf(buf->len);
263 if (!status.comp_data) {
264 BT_ERR("%s, Out of memory", __func__);
265 return;
266 }
267
268 net_buf_simple_add_mem(status.comp_data, buf->data, buf->len);
269
270 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_comp_data_status));
271 }
272
state_status_u8(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)273 static void state_status_u8(struct bt_mesh_model *model,
274 struct bt_mesh_msg_ctx *ctx,
275 struct net_buf_simple *buf)
276 {
277 uint8_t status = 0U;
278
279 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
280 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
281 bt_hex(buf->data, buf->len));
282
283 status = net_buf_simple_pull_u8(buf);
284
285 cfg_client_recv_status(model, ctx, &status, sizeof(uint8_t));
286 }
287
beacon_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)288 static void beacon_status(struct bt_mesh_model *model,
289 struct bt_mesh_msg_ctx *ctx,
290 struct net_buf_simple *buf)
291 {
292 state_status_u8(model, ctx, buf);
293 }
294
ttl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)295 static void ttl_status(struct bt_mesh_model *model,
296 struct bt_mesh_msg_ctx *ctx,
297 struct net_buf_simple *buf)
298 {
299 state_status_u8(model, ctx, buf);
300 }
301
friend_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)302 static void friend_status(struct bt_mesh_model *model,
303 struct bt_mesh_msg_ctx *ctx,
304 struct net_buf_simple *buf)
305 {
306 state_status_u8(model, ctx, buf);
307 }
308
gatt_proxy_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)309 static void gatt_proxy_status(struct bt_mesh_model *model,
310 struct bt_mesh_msg_ctx *ctx,
311 struct net_buf_simple *buf)
312 {
313 state_status_u8(model, ctx, buf);
314 }
315
relay_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)316 static void relay_status(struct bt_mesh_model *model,
317 struct bt_mesh_msg_ctx *ctx,
318 struct net_buf_simple *buf)
319 {
320 struct bt_mesh_cfg_relay_status status = {0};
321
322 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
323 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
324 bt_hex(buf->data, buf->len));
325
326 status.relay = net_buf_simple_pull_u8(buf);
327 status.retransmit = net_buf_simple_pull_u8(buf);
328
329 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_relay_status));
330 }
331
net_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)332 static void net_key_status(struct bt_mesh_model *model,
333 struct bt_mesh_msg_ctx *ctx,
334 struct net_buf_simple *buf)
335 {
336 struct bt_mesh_cfg_netkey_status status = {0};
337
338 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
339 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
340 bt_hex(buf->data, buf->len));
341
342 status.status = net_buf_simple_pull_u8(buf);
343 status.net_idx = net_buf_simple_pull_le16(buf) & 0xfff;
344
345 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_netkey_status));
346 }
347
app_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)348 static void app_key_status(struct bt_mesh_model *model,
349 struct bt_mesh_msg_ctx *ctx,
350 struct net_buf_simple *buf)
351 {
352 struct bt_mesh_cfg_appkey_status status = {0};
353
354 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
355 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
356 bt_hex(buf->data, buf->len));
357
358 status.status = net_buf_simple_pull_u8(buf);
359 key_idx_unpack(buf, &status.net_idx, &status.app_idx);
360
361 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_appkey_status));
362 }
363
mod_app_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)364 static void mod_app_status(struct bt_mesh_model *model,
365 struct bt_mesh_msg_ctx *ctx,
366 struct net_buf_simple *buf)
367 {
368 struct bt_mesh_cfg_mod_app_status status = {0};
369
370 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
371 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
372 bt_hex(buf->data, buf->len));
373
374 status.status = net_buf_simple_pull_u8(buf);
375 status.elem_addr = net_buf_simple_pull_le16(buf);
376 status.app_idx = net_buf_simple_pull_le16(buf);
377 if (buf->len >= 4) {
378 status.cid = net_buf_simple_pull_le16(buf);
379 } else {
380 status.cid = BLE_MESH_CID_NVAL;
381 }
382 status.mod_id = net_buf_simple_pull_le16(buf);
383
384 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_mod_app_status));
385 }
386
mod_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)387 static void mod_pub_status(struct bt_mesh_model *model,
388 struct bt_mesh_msg_ctx *ctx,
389 struct net_buf_simple *buf)
390 {
391 struct bt_mesh_cfg_mod_pub_status status = {0};
392
393 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
394 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
395 bt_hex(buf->data, buf->len));
396
397 status.status = net_buf_simple_pull_u8(buf);
398 status.elem_addr = net_buf_simple_pull_le16(buf);
399 status.addr = net_buf_simple_pull_le16(buf);
400 status.app_idx = net_buf_simple_pull_le16(buf);
401 status.cred_flag = (status.app_idx & BIT(12));
402 status.app_idx &= BIT_MASK(12);
403 status.ttl = net_buf_simple_pull_u8(buf);
404 status.period = net_buf_simple_pull_u8(buf);
405 status.transmit = net_buf_simple_pull_u8(buf);
406 if (buf->len >= 4) {
407 status.cid = net_buf_simple_pull_le16(buf);
408 } else {
409 status.cid = BLE_MESH_CID_NVAL;
410 }
411 status.mod_id = net_buf_simple_pull_le16(buf);
412
413 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_mod_pub_status));
414 }
415
mod_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)416 static void mod_sub_status(struct bt_mesh_model *model,
417 struct bt_mesh_msg_ctx *ctx,
418 struct net_buf_simple *buf)
419 {
420 struct bt_mesh_cfg_mod_sub_status status = {0};
421
422 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
423 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
424 bt_hex(buf->data, buf->len));
425
426 status.status = net_buf_simple_pull_u8(buf);
427 status.elem_addr = net_buf_simple_pull_le16(buf);
428 status.sub_addr = net_buf_simple_pull_le16(buf);
429 if (buf->len >= 4) {
430 status.cid = net_buf_simple_pull_le16(buf);
431 } else {
432 status.cid = BLE_MESH_CID_NVAL;
433 }
434 status.mod_id = net_buf_simple_pull_le16(buf);
435
436 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_mod_sub_status));
437 }
438
hb_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)439 static void hb_sub_status(struct bt_mesh_model *model,
440 struct bt_mesh_msg_ctx *ctx,
441 struct net_buf_simple *buf)
442 {
443 struct bt_mesh_cfg_hb_sub_status status = {0};
444
445 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
446 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
447 bt_hex(buf->data, buf->len));
448
449 status.status = net_buf_simple_pull_u8(buf);
450 status.src = net_buf_simple_pull_le16(buf);
451 status.dst = net_buf_simple_pull_le16(buf);
452 status.period = net_buf_simple_pull_u8(buf);
453 status.count = net_buf_simple_pull_u8(buf);
454 status.min = net_buf_simple_pull_u8(buf);
455 status.max = net_buf_simple_pull_u8(buf);
456
457 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_hb_sub_status));
458 }
459
hb_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)460 static void hb_pub_status(struct bt_mesh_model *model,
461 struct bt_mesh_msg_ctx *ctx,
462 struct net_buf_simple *buf)
463 {
464 struct bt_mesh_cfg_hb_pub_status status = {0};
465
466 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
467 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
468 bt_hex(buf->data, buf->len));
469
470 status.status = net_buf_simple_pull_u8(buf);
471 status.dst = net_buf_simple_pull_le16(buf);
472 status.count = net_buf_simple_pull_u8(buf);
473 status.period = net_buf_simple_pull_u8(buf);
474 status.ttl = net_buf_simple_pull_u8(buf);
475 status.feat = net_buf_simple_pull_u8(buf);
476 status.net_idx = net_buf_simple_pull_u8(buf);
477
478 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_hb_sub_status));
479 }
480
node_reset_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)481 static void node_reset_status(struct bt_mesh_model *model,
482 struct bt_mesh_msg_ctx *ctx,
483 struct net_buf_simple *buf)
484 {
485 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
486 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
487 bt_hex(buf->data, buf->len));
488
489 cfg_client_recv_status(model, ctx, NULL, 0);
490 }
491
mod_sub_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)492 static void mod_sub_list(struct bt_mesh_model *model,
493 struct bt_mesh_msg_ctx *ctx,
494 struct net_buf_simple *buf)
495 {
496 struct bt_mesh_cfg_mod_sub_list list = {0};
497
498 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
499 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
500 bt_hex(buf->data, buf->len));
501
502 list.status = net_buf_simple_pull_u8(buf);
503 list.elem_addr = net_buf_simple_pull_le16(buf);
504 if (ctx->recv_op == OP_MOD_SUB_LIST_VND) {
505 list.cid = net_buf_simple_pull_le16(buf);
506 } else {
507 list.cid = BLE_MESH_CID_NVAL;
508 }
509 list.mod_id = net_buf_simple_pull_le16(buf);
510
511 list.addr = bt_mesh_alloc_buf(buf->len);
512 if (!list.addr) {
513 BT_ERR("%s, Out of memory", __func__);
514 return;
515 }
516 net_buf_simple_add_mem(list.addr, buf->data, buf->len);
517
518 cfg_client_recv_status(model, ctx, &list, sizeof(struct bt_mesh_cfg_mod_sub_list));
519 }
520
net_key_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)521 static void net_key_list(struct bt_mesh_model *model,
522 struct bt_mesh_msg_ctx *ctx,
523 struct net_buf_simple *buf)
524 {
525 struct bt_mesh_cfg_net_key_list list = {0};
526
527 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
528 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
529 bt_hex(buf->data, buf->len));
530
531 list.net_idx = bt_mesh_alloc_buf(buf->len);
532 if (!list.net_idx) {
533 BT_ERR("%s, Out of memory", __func__);
534 return;
535 }
536 net_buf_simple_add_mem(list.net_idx, buf->data, buf->len);
537
538 cfg_client_recv_status(model, ctx, &list, sizeof(struct bt_mesh_cfg_net_key_list));
539 }
540
app_key_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)541 static void app_key_list(struct bt_mesh_model *model,
542 struct bt_mesh_msg_ctx *ctx,
543 struct net_buf_simple *buf)
544 {
545 struct bt_mesh_cfg_app_key_list list = {0};
546
547 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
548 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
549 bt_hex(buf->data, buf->len));
550
551 list.status = net_buf_simple_pull_u8(buf);
552 list.net_idx = net_buf_simple_pull_le16(buf);
553 list.app_idx = bt_mesh_alloc_buf(buf->len);
554 if (!list.app_idx) {
555 BT_ERR("%s, Out of memory", __func__);
556 return;
557 }
558 net_buf_simple_add_mem(list.app_idx, buf->data, buf->len);
559
560 cfg_client_recv_status(model, ctx, &list, sizeof(struct bt_mesh_cfg_app_key_list));
561 }
562
node_id_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)563 static void node_id_status(struct bt_mesh_model *model,
564 struct bt_mesh_msg_ctx *ctx,
565 struct net_buf_simple *buf)
566 {
567 struct bt_mesh_cfg_node_id_status status = {0};
568
569 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
570 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
571 bt_hex(buf->data, buf->len));
572
573 status.status = net_buf_simple_pull_u8(buf);
574 status.net_idx = net_buf_simple_pull_le16(buf);
575 status.identity = net_buf_simple_pull_u8(buf);
576
577 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_node_id_status));
578 }
579
mod_app_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)580 static void mod_app_list(struct bt_mesh_model *model,
581 struct bt_mesh_msg_ctx *ctx,
582 struct net_buf_simple *buf)
583 {
584 struct bt_mesh_cfg_mod_app_list list = {0};
585
586 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
587 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
588 bt_hex(buf->data, buf->len));
589
590 list.status = net_buf_simple_pull_u8(buf);
591 list.elem_addr = net_buf_simple_pull_le16(buf);
592 if (ctx->recv_op == OP_VND_MOD_APP_LIST) {
593 list.cid = net_buf_simple_pull_le16(buf);
594 } else {
595 list.cid = BLE_MESH_CID_NVAL;
596 }
597 list.mod_id = net_buf_simple_pull_le16(buf);
598
599 list.app_idx = bt_mesh_alloc_buf(buf->len);
600 if (!list.app_idx) {
601 BT_ERR("%s, Out of memory", __func__);
602 return;
603 }
604 net_buf_simple_add_mem(list.app_idx, buf->data, buf->len);
605
606 cfg_client_recv_status(model, ctx, &list, sizeof(struct bt_mesh_cfg_mod_app_list));
607 }
608
kr_phase_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)609 static void kr_phase_status(struct bt_mesh_model *model,
610 struct bt_mesh_msg_ctx *ctx,
611 struct net_buf_simple *buf)
612 {
613 struct bt_mesh_cfg_key_refresh_status status = {0};
614
615 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
616 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
617 bt_hex(buf->data, buf->len));
618
619 status.status = net_buf_simple_pull_u8(buf);
620 status.net_idx = net_buf_simple_pull_le16(buf);
621 status.phase = net_buf_simple_pull_u8(buf);
622
623 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_key_refresh_status));
624 }
625
lpn_pollto_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)626 static void lpn_pollto_status(struct bt_mesh_model *model,
627 struct bt_mesh_msg_ctx *ctx,
628 struct net_buf_simple *buf)
629 {
630 struct bt_mesh_cfg_lpn_pollto_status status = {0};
631
632 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
633 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
634 bt_hex(buf->data, buf->len));
635
636 status.lpn_addr = net_buf_simple_pull_le16(buf);
637 status.timeout = net_buf_simple_pull_u8(buf);
638 status.timeout |= net_buf_simple_pull_u8(buf) << 8;
639 status.timeout |= net_buf_simple_pull_u8(buf) << 16;
640
641 cfg_client_recv_status(model, ctx, &status, sizeof(struct bt_mesh_cfg_lpn_pollto_status));
642 }
643
net_trans_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)644 static void net_trans_status(struct bt_mesh_model *model,
645 struct bt_mesh_msg_ctx *ctx,
646 struct net_buf_simple *buf)
647 {
648 state_status_u8(model, ctx, buf);
649 }
650
651 const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = {
652 { OP_DEV_COMP_DATA_STATUS, 15, comp_data_status },
653 { OP_BEACON_STATUS, 1, beacon_status },
654 { OP_DEFAULT_TTL_STATUS, 1, ttl_status },
655 { OP_FRIEND_STATUS, 1, friend_status },
656 { OP_GATT_PROXY_STATUS, 1, gatt_proxy_status },
657 { OP_RELAY_STATUS, 2, relay_status },
658 { OP_NET_KEY_STATUS, 3, net_key_status },
659 { OP_APP_KEY_STATUS, 4, app_key_status },
660 { OP_MOD_APP_STATUS, 7, mod_app_status },
661 { OP_MOD_PUB_STATUS, 12, mod_pub_status },
662 { OP_MOD_SUB_STATUS, 7, mod_sub_status },
663 { OP_HEARTBEAT_SUB_STATUS, 9, hb_sub_status },
664 { OP_HEARTBEAT_PUB_STATUS, 10, hb_pub_status },
665 { OP_NODE_RESET_STATUS, 0, node_reset_status },
666 { OP_MOD_SUB_LIST, 5, mod_sub_list },
667 { OP_MOD_SUB_LIST_VND, 7, mod_sub_list },
668 { OP_NET_KEY_LIST, 2, net_key_list },
669 { OP_APP_KEY_LIST, 3, app_key_list },
670 { OP_NODE_IDENTITY_STATUS, 4, node_id_status },
671 { OP_SIG_MOD_APP_LIST, 5, mod_app_list },
672 { OP_VND_MOD_APP_LIST, 7, mod_app_list },
673 { OP_KRP_STATUS, 4, kr_phase_status },
674 { OP_LPN_TIMEOUT_STATUS, 5, lpn_pollto_status },
675 { OP_NET_TRANSMIT_STATUS, 1, net_trans_status },
676 BLE_MESH_MODEL_OP_END,
677 };
678
send_msg_with_none(bt_mesh_client_common_param_t * param,uint32_t op)679 static int send_msg_with_none(bt_mesh_client_common_param_t *param, uint32_t op)
680 {
681 BLE_MESH_MODEL_BUF_DEFINE(msg, op, 0);
682
683 bt_mesh_model_msg_init(&msg, op);
684
685 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
686 }
687
send_msg_with_u8(bt_mesh_client_common_param_t * param,uint32_t op,uint8_t val)688 static int send_msg_with_u8(bt_mesh_client_common_param_t *param, uint32_t op, uint8_t val)
689 {
690 BLE_MESH_MODEL_BUF_DEFINE(msg, op, 1);
691
692 bt_mesh_model_msg_init(&msg, op);
693 net_buf_simple_add_u8(&msg, val);
694
695 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
696 }
697
send_msg_with_le16(bt_mesh_client_common_param_t * param,uint32_t op,uint16_t val)698 static int send_msg_with_le16(bt_mesh_client_common_param_t *param, uint32_t op, uint16_t val)
699 {
700 BLE_MESH_MODEL_BUF_DEFINE(msg, op, 2);
701
702 bt_mesh_model_msg_init(&msg, op);
703 net_buf_simple_add_le16(&msg, val);
704
705 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
706 }
707
bt_mesh_cfg_comp_data_get(bt_mesh_client_common_param_t * param,uint8_t page)708 int bt_mesh_cfg_comp_data_get(bt_mesh_client_common_param_t *param, uint8_t page)
709 {
710 return send_msg_with_u8(param, OP_DEV_COMP_DATA_GET, page);
711 }
712
bt_mesh_cfg_beacon_get(bt_mesh_client_common_param_t * param)713 int bt_mesh_cfg_beacon_get(bt_mesh_client_common_param_t *param)
714 {
715 return send_msg_with_none(param, OP_BEACON_GET);
716 }
717
bt_mesh_cfg_beacon_set(bt_mesh_client_common_param_t * param,uint8_t val)718 int bt_mesh_cfg_beacon_set(bt_mesh_client_common_param_t *param, uint8_t val)
719 {
720 if (val > 0x01) {
721 BT_ERR("Invalid beacon state 0x%02x", val);
722 return -EINVAL;
723 }
724 return send_msg_with_u8(param, OP_BEACON_SET, val);
725 }
726
bt_mesh_cfg_ttl_get(bt_mesh_client_common_param_t * param)727 int bt_mesh_cfg_ttl_get(bt_mesh_client_common_param_t *param)
728 {
729 return send_msg_with_none(param, OP_DEFAULT_TTL_GET);
730 }
731
bt_mesh_cfg_ttl_set(bt_mesh_client_common_param_t * param,uint8_t val)732 int bt_mesh_cfg_ttl_set(bt_mesh_client_common_param_t *param, uint8_t val)
733 {
734 return send_msg_with_u8(param, OP_DEFAULT_TTL_SET, val);
735 }
736
bt_mesh_cfg_friend_get(bt_mesh_client_common_param_t * param)737 int bt_mesh_cfg_friend_get(bt_mesh_client_common_param_t *param)
738 {
739 return send_msg_with_none(param, OP_FRIEND_GET);
740 }
741
bt_mesh_cfg_friend_set(bt_mesh_client_common_param_t * param,uint8_t val)742 int bt_mesh_cfg_friend_set(bt_mesh_client_common_param_t *param, uint8_t val)
743 {
744 return send_msg_with_u8(param, OP_FRIEND_SET, val);
745 }
746
bt_mesh_cfg_gatt_proxy_get(bt_mesh_client_common_param_t * param)747 int bt_mesh_cfg_gatt_proxy_get(bt_mesh_client_common_param_t *param)
748 {
749 return send_msg_with_none(param, OP_GATT_PROXY_GET);
750 }
751
bt_mesh_cfg_gatt_proxy_set(bt_mesh_client_common_param_t * param,uint8_t val)752 int bt_mesh_cfg_gatt_proxy_set(bt_mesh_client_common_param_t *param, uint8_t val)
753 {
754 return send_msg_with_u8(param, OP_GATT_PROXY_SET, val);
755 }
756
bt_mesh_cfg_relay_get(bt_mesh_client_common_param_t * param)757 int bt_mesh_cfg_relay_get(bt_mesh_client_common_param_t *param)
758 {
759 return send_msg_with_none(param, OP_RELAY_GET);
760 }
761
bt_mesh_cfg_relay_set(bt_mesh_client_common_param_t * param,uint8_t relay,uint8_t retransmit)762 int bt_mesh_cfg_relay_set(bt_mesh_client_common_param_t *param,
763 uint8_t relay, uint8_t retransmit)
764 {
765 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_SET, 2);
766
767 bt_mesh_model_msg_init(&msg, OP_RELAY_SET);
768 net_buf_simple_add_u8(&msg, relay);
769 net_buf_simple_add_u8(&msg, retransmit);
770
771 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
772 }
773
bt_mesh_cfg_net_key_add(bt_mesh_client_common_param_t * param,uint16_t net_idx,const uint8_t net_key[16])774 int bt_mesh_cfg_net_key_add(bt_mesh_client_common_param_t *param,
775 uint16_t net_idx, const uint8_t net_key[16])
776 {
777 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_ADD, 18);
778
779 if (!net_key) {
780 BT_ERR("Invalid NetKey");
781 return -EINVAL;
782 }
783
784 bt_mesh_model_msg_init(&msg, OP_NET_KEY_ADD);
785 net_buf_simple_add_le16(&msg, net_idx);
786 net_buf_simple_add_mem(&msg, net_key, 16);
787
788 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
789 }
790
bt_mesh_cfg_app_key_add(bt_mesh_client_common_param_t * param,uint16_t net_idx,uint16_t app_idx,const uint8_t app_key[16])791 int bt_mesh_cfg_app_key_add(bt_mesh_client_common_param_t *param,
792 uint16_t net_idx, uint16_t app_idx,
793 const uint8_t app_key[16])
794 {
795 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_ADD, 19);
796
797 if (!app_key) {
798 BT_ERR("Invalid AppKey");
799 return -EINVAL;
800 }
801
802 bt_mesh_model_msg_init(&msg, OP_APP_KEY_ADD);
803 key_idx_pack(&msg, net_idx, app_idx);
804 net_buf_simple_add_mem(&msg, app_key, 16);
805
806 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
807 }
808
bt_mesh_cfg_mod_app_bind(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t app_idx,uint16_t mod_id,uint16_t cid)809 int bt_mesh_cfg_mod_app_bind(bt_mesh_client_common_param_t *param,
810 uint16_t elem_addr, uint16_t app_idx,
811 uint16_t mod_id, uint16_t cid)
812 {
813 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_BIND, 8);
814
815 bt_mesh_model_msg_init(&msg, OP_MOD_APP_BIND);
816 net_buf_simple_add_le16(&msg, elem_addr);
817 net_buf_simple_add_le16(&msg, app_idx);
818 if (cid != BLE_MESH_CID_NVAL) {
819 net_buf_simple_add_le16(&msg, cid);
820 }
821 net_buf_simple_add_le16(&msg, mod_id);
822
823 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
824 }
825
mod_sub(bt_mesh_client_common_param_t * param,uint32_t op,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid)826 static int mod_sub(bt_mesh_client_common_param_t *param, uint32_t op,
827 uint16_t elem_addr, uint16_t sub_addr,
828 uint16_t mod_id, uint16_t cid)
829 {
830 BLE_MESH_MODEL_BUF_DEFINE(msg, op, 8);
831
832 bt_mesh_model_msg_init(&msg, op);
833 net_buf_simple_add_le16(&msg, elem_addr);
834 net_buf_simple_add_le16(&msg, sub_addr);
835 if (cid != BLE_MESH_CID_NVAL) {
836 net_buf_simple_add_le16(&msg, cid);
837 }
838 net_buf_simple_add_le16(&msg, mod_id);
839
840 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
841 }
842
bt_mesh_cfg_mod_sub_add(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid)843 int bt_mesh_cfg_mod_sub_add(bt_mesh_client_common_param_t *param,
844 uint16_t elem_addr, uint16_t sub_addr,
845 uint16_t mod_id, uint16_t cid)
846 {
847 return mod_sub(param, OP_MOD_SUB_ADD, elem_addr, sub_addr, mod_id, cid);
848 }
849
bt_mesh_cfg_mod_sub_del(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid)850 int bt_mesh_cfg_mod_sub_del(bt_mesh_client_common_param_t *param,
851 uint16_t elem_addr, uint16_t sub_addr,
852 uint16_t mod_id, uint16_t cid)
853 {
854 return mod_sub(param, OP_MOD_SUB_DEL, elem_addr, sub_addr, mod_id, cid);
855 }
856
bt_mesh_cfg_mod_sub_overwrite(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid)857 int bt_mesh_cfg_mod_sub_overwrite(bt_mesh_client_common_param_t *param,
858 uint16_t elem_addr, uint16_t sub_addr,
859 uint16_t mod_id, uint16_t cid)
860 {
861 return mod_sub(param, OP_MOD_SUB_OVERWRITE, elem_addr, sub_addr, mod_id, cid);
862 }
863
mod_sub_va(bt_mesh_client_common_param_t * param,uint32_t op,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid)864 static int mod_sub_va(bt_mesh_client_common_param_t *param, uint32_t op,
865 uint16_t elem_addr, const uint8_t label[16],
866 uint16_t mod_id, uint16_t cid)
867 {
868 BLE_MESH_MODEL_BUF_DEFINE(msg, op, 22);
869
870 if (!label) {
871 BT_ERR("Invalid label uuid");
872 return -EINVAL;
873 }
874
875 BT_DBG("elem_addr 0x%04x label %s", elem_addr, bt_hex(label, 16));
876 BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid);
877
878 bt_mesh_model_msg_init(&msg, op);
879 net_buf_simple_add_le16(&msg, elem_addr);
880 net_buf_simple_add_mem(&msg, label, 16);
881 if (cid != BLE_MESH_CID_NVAL) {
882 net_buf_simple_add_le16(&msg, cid);
883 }
884 net_buf_simple_add_le16(&msg, mod_id);
885
886 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
887 }
888
bt_mesh_cfg_mod_sub_va_add(bt_mesh_client_common_param_t * param,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid)889 int bt_mesh_cfg_mod_sub_va_add(bt_mesh_client_common_param_t *param,
890 uint16_t elem_addr, const uint8_t label[16],
891 uint16_t mod_id, uint16_t cid)
892 {
893 return mod_sub_va(param, OP_MOD_SUB_VA_ADD, elem_addr, label, mod_id, cid);
894 }
895
bt_mesh_cfg_mod_sub_va_del(bt_mesh_client_common_param_t * param,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid)896 int bt_mesh_cfg_mod_sub_va_del(bt_mesh_client_common_param_t *param,
897 uint16_t elem_addr, const uint8_t label[16],
898 uint16_t mod_id, uint16_t cid)
899 {
900 return mod_sub_va(param, OP_MOD_SUB_VA_DEL, elem_addr, label, mod_id, cid);
901 }
902
bt_mesh_cfg_mod_sub_va_overwrite(bt_mesh_client_common_param_t * param,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid)903 int bt_mesh_cfg_mod_sub_va_overwrite(bt_mesh_client_common_param_t *param,
904 uint16_t elem_addr, const uint8_t label[16],
905 uint16_t mod_id, uint16_t cid)
906 {
907 return mod_sub_va(param, OP_MOD_SUB_VA_OVERWRITE, elem_addr, label, mod_id, cid);
908 }
909
bt_mesh_cfg_mod_pub_get(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id,uint16_t cid)910 int bt_mesh_cfg_mod_pub_get(bt_mesh_client_common_param_t *param,
911 uint16_t elem_addr, uint16_t mod_id, uint16_t cid)
912 {
913 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_GET, 6);
914
915 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_GET);
916 net_buf_simple_add_le16(&msg, elem_addr);
917 if (cid != BLE_MESH_CID_NVAL) {
918 net_buf_simple_add_le16(&msg, cid);
919 }
920 net_buf_simple_add_le16(&msg, mod_id);
921
922 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
923 }
924
bt_mesh_cfg_mod_pub_set(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,struct bt_mesh_cfg_mod_pub * pub)925 int bt_mesh_cfg_mod_pub_set(bt_mesh_client_common_param_t *param,
926 uint16_t elem_addr, uint16_t mod_id, uint16_t cid,
927 struct bt_mesh_cfg_mod_pub *pub)
928 {
929 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_SET, 13);
930
931 if (!pub) {
932 BT_ERR("Invalid model pub set");
933 return -EINVAL;
934 }
935
936 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_SET);
937 net_buf_simple_add_le16(&msg, elem_addr);
938 net_buf_simple_add_le16(&msg, pub->addr);
939 net_buf_simple_add_le16(&msg, (pub->app_idx | (pub->cred_flag << 12)));
940 net_buf_simple_add_u8(&msg, pub->ttl);
941 net_buf_simple_add_u8(&msg, pub->period);
942 net_buf_simple_add_u8(&msg, pub->transmit);
943 if (cid != BLE_MESH_CID_NVAL) {
944 net_buf_simple_add_le16(&msg, cid);
945 }
946 net_buf_simple_add_le16(&msg, mod_id);
947
948 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
949 }
950
bt_mesh_cfg_hb_sub_set(bt_mesh_client_common_param_t * param,struct bt_mesh_cfg_hb_sub * sub)951 int bt_mesh_cfg_hb_sub_set(bt_mesh_client_common_param_t *param,
952 struct bt_mesh_cfg_hb_sub *sub)
953 {
954 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_SET, 5);
955
956 if (!sub) {
957 BT_ERR("Invalid heartbeat sub set");
958 return -EINVAL;
959 }
960
961 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_SET);
962 net_buf_simple_add_le16(&msg, sub->src);
963 net_buf_simple_add_le16(&msg, sub->dst);
964 net_buf_simple_add_u8(&msg, sub->period);
965
966 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
967 }
968
bt_mesh_cfg_hb_sub_get(bt_mesh_client_common_param_t * param)969 int bt_mesh_cfg_hb_sub_get(bt_mesh_client_common_param_t *param)
970 {
971 return send_msg_with_none(param, OP_HEARTBEAT_SUB_GET);
972 }
973
bt_mesh_cfg_hb_pub_set(bt_mesh_client_common_param_t * param,struct bt_mesh_cfg_hb_pub * pub)974 int bt_mesh_cfg_hb_pub_set(bt_mesh_client_common_param_t *param,
975 struct bt_mesh_cfg_hb_pub *pub)
976 {
977 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_SET, 9);
978
979 if (!pub) {
980 BT_ERR("Invalid heartbeat pub set");
981 return -EINVAL;
982 }
983
984 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_SET);
985 net_buf_simple_add_le16(&msg, pub->dst);
986 net_buf_simple_add_u8(&msg, pub->count);
987 net_buf_simple_add_u8(&msg, pub->period);
988 net_buf_simple_add_u8(&msg, pub->ttl);
989 net_buf_simple_add_le16(&msg, pub->feat);
990 net_buf_simple_add_le16(&msg, pub->net_idx);
991
992 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
993 }
994
bt_mesh_cfg_hb_pub_get(bt_mesh_client_common_param_t * param)995 int bt_mesh_cfg_hb_pub_get(bt_mesh_client_common_param_t *param)
996 {
997 return send_msg_with_none(param, OP_HEARTBEAT_PUB_GET);
998 }
999
bt_mesh_cfg_node_reset(bt_mesh_client_common_param_t * param)1000 int bt_mesh_cfg_node_reset(bt_mesh_client_common_param_t *param)
1001 {
1002 return send_msg_with_none(param, OP_NODE_RESET);
1003 }
1004
bt_mesh_cfg_mod_pub_va_set(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,const uint8_t label[16],struct bt_mesh_cfg_mod_pub * pub)1005 int bt_mesh_cfg_mod_pub_va_set(bt_mesh_client_common_param_t *param,
1006 uint16_t elem_addr, uint16_t mod_id,
1007 uint16_t cid, const uint8_t label[16],
1008 struct bt_mesh_cfg_mod_pub *pub)
1009 {
1010 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_VA_SET, 27);
1011
1012 if (!label || !pub) {
1013 BT_ERR("%s, Invalid parameter", __func__);
1014 return -EINVAL;
1015 }
1016
1017 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_VA_SET);
1018 net_buf_simple_add_le16(&msg, elem_addr);
1019 net_buf_simple_add_mem(&msg, label, 16);
1020 net_buf_simple_add_le16(&msg, (pub->app_idx | (pub->cred_flag << 12)));
1021 net_buf_simple_add_u8(&msg, pub->ttl);
1022 net_buf_simple_add_u8(&msg, pub->period);
1023 net_buf_simple_add_u8(&msg, pub->transmit);
1024 if (cid != BLE_MESH_CID_NVAL) {
1025 net_buf_simple_add_le16(&msg, cid);
1026 }
1027 net_buf_simple_add_le16(&msg, mod_id);
1028
1029 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1030 }
1031
bt_mesh_cfg_mod_sub_del_all(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id,uint16_t cid)1032 int bt_mesh_cfg_mod_sub_del_all(bt_mesh_client_common_param_t *param,
1033 uint16_t elem_addr, uint16_t mod_id, uint16_t cid)
1034 {
1035 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_DEL_ALL, 6);
1036
1037 bt_mesh_model_msg_init(&msg, OP_MOD_SUB_DEL_ALL);
1038 net_buf_simple_add_le16(&msg, elem_addr);
1039 if (cid != BLE_MESH_CID_NVAL) {
1040 net_buf_simple_add_le16(&msg, cid);
1041 }
1042 net_buf_simple_add_le16(&msg, mod_id);
1043
1044 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1045 }
1046
mod_sub_get(bt_mesh_client_common_param_t * param,uint32_t op,uint16_t elem_addr,uint16_t mod_id,uint16_t cid)1047 static int mod_sub_get(bt_mesh_client_common_param_t *param, uint32_t op,
1048 uint16_t elem_addr, uint16_t mod_id, uint16_t cid)
1049 {
1050 BLE_MESH_MODEL_BUF_DEFINE(msg, op, 6);
1051
1052 bt_mesh_model_msg_init(&msg, op);
1053 net_buf_simple_add_le16(&msg, elem_addr);
1054 if (cid != BLE_MESH_CID_NVAL) {
1055 net_buf_simple_add_le16(&msg, cid);
1056 }
1057 net_buf_simple_add_le16(&msg, mod_id);
1058
1059 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1060 }
1061
bt_mesh_cfg_mod_sub_get(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id)1062 int bt_mesh_cfg_mod_sub_get(bt_mesh_client_common_param_t *param,
1063 uint16_t elem_addr, uint16_t mod_id)
1064 {
1065 return mod_sub_get(param, OP_MOD_SUB_GET, elem_addr, mod_id, BLE_MESH_CID_NVAL);
1066 }
1067
bt_mesh_cfg_mod_sub_get_vnd(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id,uint16_t cid)1068 int bt_mesh_cfg_mod_sub_get_vnd(bt_mesh_client_common_param_t *param,
1069 uint16_t elem_addr, uint16_t mod_id, uint16_t cid)
1070 {
1071 if (cid == BLE_MESH_CID_NVAL) {
1072 BT_ERR("Invalid company id");
1073 return -EINVAL;
1074 }
1075 return mod_sub_get(param, OP_MOD_SUB_GET_VND, elem_addr, mod_id, cid);
1076 }
1077
bt_mesh_cfg_net_key_update(bt_mesh_client_common_param_t * param,uint16_t net_idx,const uint8_t net_key[16])1078 int bt_mesh_cfg_net_key_update(bt_mesh_client_common_param_t *param,
1079 uint16_t net_idx, const uint8_t net_key[16])
1080 {
1081 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_UPDATE, 18);
1082
1083 if (!net_key) {
1084 BT_ERR("Invalid NetKey");
1085 return -EINVAL;
1086 }
1087
1088 bt_mesh_model_msg_init(&msg, OP_NET_KEY_UPDATE);
1089 net_buf_simple_add_le16(&msg, net_idx);
1090 net_buf_simple_add_mem(&msg, net_key, 16);
1091
1092 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1093 }
1094
bt_mesh_cfg_net_key_delete(bt_mesh_client_common_param_t * param,uint16_t net_idx)1095 int bt_mesh_cfg_net_key_delete(bt_mesh_client_common_param_t *param, uint16_t net_idx)
1096 {
1097 return send_msg_with_le16(param, OP_NET_KEY_DEL, net_idx);
1098 }
1099
bt_mesh_cfg_net_key_get(bt_mesh_client_common_param_t * param)1100 int bt_mesh_cfg_net_key_get(bt_mesh_client_common_param_t *param)
1101 {
1102 return send_msg_with_none(param, OP_NET_KEY_GET);
1103 }
1104
bt_mesh_cfg_app_key_update(bt_mesh_client_common_param_t * param,uint16_t net_idx,uint16_t app_idx,const uint8_t app_key[16])1105 int bt_mesh_cfg_app_key_update(bt_mesh_client_common_param_t *param,
1106 uint16_t net_idx, uint16_t app_idx,
1107 const uint8_t app_key[16])
1108 {
1109 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_UPDATE, 19);
1110
1111 if (!app_key) {
1112 BT_ERR("Invalid AppKey");
1113 return -EINVAL;
1114 }
1115
1116 bt_mesh_model_msg_init(&msg, OP_APP_KEY_UPDATE);
1117 key_idx_pack(&msg, net_idx, app_idx);
1118 net_buf_simple_add_mem(&msg, app_key, 16);
1119
1120 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1121 }
1122
bt_mesh_cfg_app_key_delete(bt_mesh_client_common_param_t * param,uint16_t net_idx,uint16_t app_idx)1123 int bt_mesh_cfg_app_key_delete(bt_mesh_client_common_param_t *param,
1124 uint16_t net_idx, uint16_t app_idx)
1125 {
1126 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_DEL, 3);
1127
1128 bt_mesh_model_msg_init(&msg, OP_APP_KEY_DEL);
1129 key_idx_pack(&msg, net_idx, app_idx);
1130
1131 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1132 }
1133
bt_mesh_cfg_app_key_get(bt_mesh_client_common_param_t * param,uint16_t net_idx)1134 int bt_mesh_cfg_app_key_get(bt_mesh_client_common_param_t *param, uint16_t net_idx)
1135 {
1136 return send_msg_with_le16(param, OP_APP_KEY_GET, net_idx);
1137 }
1138
bt_mesh_cfg_node_identity_get(bt_mesh_client_common_param_t * param,uint16_t net_idx)1139 int bt_mesh_cfg_node_identity_get(bt_mesh_client_common_param_t *param, uint16_t net_idx)
1140 {
1141 return send_msg_with_le16(param, OP_NODE_IDENTITY_GET, net_idx);
1142 }
1143
bt_mesh_cfg_node_identity_set(bt_mesh_client_common_param_t * param,uint16_t net_idx,uint8_t identity)1144 int bt_mesh_cfg_node_identity_set(bt_mesh_client_common_param_t *param,
1145 uint16_t net_idx, uint8_t identity)
1146 {
1147 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_SET, 3);
1148
1149 if (identity > 0x02) {
1150 BT_ERR("Invalid node identity 0x%02x", identity);
1151 return -EINVAL;
1152 }
1153
1154 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_SET);
1155 net_buf_simple_add_le16(&msg, net_idx);
1156 net_buf_simple_add_u8(&msg, identity);
1157
1158 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1159 }
1160
bt_mesh_cfg_mod_app_unbind(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t app_idx,uint16_t mod_id,uint16_t cid)1161 int bt_mesh_cfg_mod_app_unbind(bt_mesh_client_common_param_t *param,
1162 uint16_t elem_addr, uint16_t app_idx,
1163 uint16_t mod_id, uint16_t cid)
1164 {
1165 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_UNBIND, 8);
1166
1167 bt_mesh_model_msg_init(&msg, OP_MOD_APP_UNBIND);
1168 net_buf_simple_add_le16(&msg, elem_addr);
1169 net_buf_simple_add_le16(&msg, app_idx);
1170 if (cid != BLE_MESH_CID_NVAL) {
1171 net_buf_simple_add_le16(&msg, cid);
1172 }
1173 net_buf_simple_add_le16(&msg, mod_id);
1174
1175 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1176 }
1177
mod_app_get(bt_mesh_client_common_param_t * param,uint32_t op,uint16_t elem_addr,uint16_t mod_id,uint16_t cid)1178 static int mod_app_get(bt_mesh_client_common_param_t *param, uint32_t op,
1179 uint16_t elem_addr, uint16_t mod_id, uint16_t cid)
1180 {
1181 BLE_MESH_MODEL_BUF_DEFINE(msg, op, 6);
1182
1183 bt_mesh_model_msg_init(&msg, op);
1184 net_buf_simple_add_le16(&msg, elem_addr);
1185 if (cid != BLE_MESH_CID_NVAL) {
1186 net_buf_simple_add_le16(&msg, cid);
1187 }
1188 net_buf_simple_add_le16(&msg, mod_id);
1189
1190 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1191 }
1192
bt_mesh_cfg_mod_app_get(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id)1193 int bt_mesh_cfg_mod_app_get(bt_mesh_client_common_param_t *param,
1194 uint16_t elem_addr, uint16_t mod_id)
1195 {
1196 return mod_app_get(param, OP_SIG_MOD_APP_GET, elem_addr, mod_id, BLE_MESH_CID_NVAL);
1197 }
1198
bt_mesh_cfg_mod_app_get_vnd(bt_mesh_client_common_param_t * param,uint16_t elem_addr,uint16_t mod_id,uint16_t cid)1199 int bt_mesh_cfg_mod_app_get_vnd(bt_mesh_client_common_param_t *param,
1200 uint16_t elem_addr, uint16_t mod_id, uint16_t cid)
1201 {
1202 if (cid == BLE_MESH_CID_NVAL) {
1203 BT_ERR("Invalid company id");
1204 return -EINVAL;
1205 }
1206 return mod_app_get(param, OP_VND_MOD_APP_GET, elem_addr, mod_id, cid);
1207 }
1208
bt_mesh_cfg_kr_phase_get(bt_mesh_client_common_param_t * param,uint16_t net_idx)1209 int bt_mesh_cfg_kr_phase_get(bt_mesh_client_common_param_t *param, uint16_t net_idx)
1210 {
1211 return send_msg_with_le16(param, OP_KRP_GET, net_idx);
1212 }
1213
bt_mesh_cfg_kr_phase_set(bt_mesh_client_common_param_t * param,uint16_t net_idx,uint8_t transition)1214 int bt_mesh_cfg_kr_phase_set(bt_mesh_client_common_param_t *param,
1215 uint16_t net_idx, uint8_t transition)
1216 {
1217 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_SET, 3);
1218
1219 if (transition > 0x03) {
1220 BT_ERR("Invalid kr phase transition 0x%02x", transition);
1221 return -EINVAL;
1222 }
1223
1224 bt_mesh_model_msg_init(&msg, OP_KRP_SET);
1225 net_buf_simple_add_le16(&msg, net_idx);
1226 net_buf_simple_add_u8(&msg, transition);
1227
1228 return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
1229 }
1230
bt_mesh_cfg_lpn_timeout_get(bt_mesh_client_common_param_t * param,uint16_t lpn_addr)1231 int bt_mesh_cfg_lpn_timeout_get(bt_mesh_client_common_param_t *param, uint16_t lpn_addr)
1232 {
1233 return send_msg_with_le16(param, OP_LPN_TIMEOUT_GET, lpn_addr);
1234 }
1235
bt_mesh_cfg_net_transmit_get(bt_mesh_client_common_param_t * param)1236 int bt_mesh_cfg_net_transmit_get(bt_mesh_client_common_param_t *param)
1237 {
1238 return send_msg_with_none(param, OP_NET_TRANSMIT_GET);
1239 }
1240
bt_mesh_cfg_net_transmit_set(bt_mesh_client_common_param_t * param,uint8_t transmit)1241 int bt_mesh_cfg_net_transmit_set(bt_mesh_client_common_param_t *param, uint8_t transmit)
1242 {
1243 return send_msg_with_u8(param, OP_NET_TRANSMIT_SET, transmit);
1244 }
1245
cfg_cli_init(struct bt_mesh_model * model)1246 static int cfg_cli_init(struct bt_mesh_model *model)
1247 {
1248 config_internal_data_t *internal = NULL;
1249 bt_mesh_config_client_t *client = NULL;
1250
1251 if (!model) {
1252 BT_ERR("Invalid Configuration Client model");
1253 return -EINVAL;
1254 }
1255
1256 if (!bt_mesh_model_in_primary(model)) {
1257 BT_ERR("Configuration Client only allowed in primary element");
1258 return -EINVAL;
1259 }
1260
1261 client = (bt_mesh_config_client_t *)model->user_data;
1262 if (!client) {
1263 BT_ERR("No Configuration Client context provided");
1264 return -EINVAL;
1265 }
1266
1267 if (!client->internal_data) {
1268 internal = bt_mesh_calloc(sizeof(config_internal_data_t));
1269 if (!internal) {
1270 BT_ERR("Allocate memory for Configuration Client internal data fail");
1271 return -ENOMEM;
1272 }
1273
1274 sys_slist_init(&internal->queue);
1275
1276 client->model = model;
1277 client->op_pair_size = ARRAY_SIZE(cfg_op_pair);
1278 client->op_pair = cfg_op_pair;
1279 client->internal_data = internal;
1280 } else {
1281 bt_mesh_client_clear_list(client->internal_data);
1282 }
1283
1284 /* Configuration Model security is device-key based */
1285 model->keys[0] = BLE_MESH_KEY_DEV;
1286
1287 bt_mesh_cfg_client_mutex_new();
1288
1289 return 0;
1290 }
1291
1292 #if CONFIG_BLE_MESH_DEINIT
cfg_cli_deinit(struct bt_mesh_model * model)1293 static int cfg_cli_deinit(struct bt_mesh_model *model)
1294 {
1295 bt_mesh_config_client_t *client = NULL;
1296
1297 if (!model) {
1298 BT_ERR("Invalid Configuration Client model");
1299 return -EINVAL;
1300 }
1301
1302 if (!bt_mesh_model_in_primary(model)) {
1303 BT_ERR("Configuration Client only allowed in primary element");
1304 return -EINVAL;
1305 }
1306
1307 client = (bt_mesh_config_client_t *)model->user_data;
1308 if (!client) {
1309 BT_ERR("No Configuration Client context provided");
1310 return -EINVAL;
1311 }
1312
1313 if (client->internal_data) {
1314 /* Remove items from the list */
1315 bt_mesh_client_clear_list(client->internal_data);
1316
1317 /* Free the allocated internal data */
1318 bt_mesh_free(client->internal_data);
1319 client->internal_data = NULL;
1320 }
1321
1322 bt_mesh_cfg_client_mutex_free();
1323
1324 return 0;
1325 }
1326 #endif /* CONFIG_BLE_MESH_DEINIT */
1327
1328 const struct bt_mesh_model_cb bt_mesh_cfg_cli_cb = {
1329 .init = cfg_cli_init,
1330 #if CONFIG_BLE_MESH_DEINIT
1331 .deinit = cfg_cli_deinit,
1332 #endif /* CONFIG_BLE_MESH_DEINIT */
1333 };
1334
1335 #endif /* CONFIG_BLE_MESH_CFG_CLI */
1336