1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE 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