1 /*
2  * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <errno.h>
9 
10 #include "btc_ble_mesh_generic_model.h"
11 
12 #include "mesh_config.h"
13 #include "model_opcode.h"
14 
15 #if CONFIG_BLE_MESH_GENERIC_CLIENT
16 #include "generic_client.h"
17 
18 /* The followings are the macro definitions of Generic client
19  * model message length, and a message is composed of 3 parts:
20  * Opcode + Payload + MIC
21  */
22 /* Generic onoff client messages length */
23 #define BLE_MESH_GEN_ONOFF_GET_MSG_LEN              (2 + 0 + 4)
24 #define BLE_MESH_GEN_ONOFF_SET_MSG_LEN              (2 + 4 + 4)
25 
26 /* Generic level client messages length */
27 #define BLE_MESH_GEN_LEVEL_GET_MSG_LEN              (2 + 0 + 4)
28 #define BLE_MESH_GEN_LEVEL_SET_MSG_LEN              (2 + 5 + 4)
29 #define BLE_MESH_GEN_DELTA_SET_MSG_LEN              (2 + 7 + 4)
30 #define BLE_MESH_GEN_MOVE_SET_MSG_LEN               (2 + 5 + 4)
31 
32 /* Generic default transition time client messages length */
33 #define BLE_MESH_GEN_DEF_TRANS_TIME_GET_MSG_LEN     (2 + 0 + 4)
34 #define BLE_MESH_GEN_DEF_TRANS_TIME_SET_MSG_LEN     (2 + 1 + 4)
35 
36 /* Generic power onoff client messages length */
37 #define BLE_MESH_GEN_ONPOWERUP_GET_MSG_LEN          (2 + 0 + 4)
38 #define BLE_MESH_GEN_ONPOWERUP_SET_MSG_LEN          (2 + 1 + 4)
39 
40 /* Generic power level client messages length */
41 #define BLE_MESH_GEN_POWER_LEVEL_GET_MSG_LEN        (2 + 0 + 4)
42 #define BLE_MESH_GEN_POWER_LEVEL_SET_MSG_LEN        (2 + 5 + 4)
43 #define BLE_MESH_GEN_POWER_LAST_GET_MSG_LEN         (2 + 0 + 4)
44 #define BLE_MESH_GEN_POWER_DEFAULT_GET_MSG_LEN      (2 + 0 + 4)
45 #define BLE_MESH_GEN_POWER_DEFAULT_SET_MSG_LEN      (2 + 2 + 4)
46 #define BLE_MESH_GEN_POWER_RANGE_GET_MSG_LEN        (2 + 0 + 4)
47 #define BLE_MESH_GEN_POWER_RANGE_SET_MSG_LEN        (2 + 4 + 4)
48 
49 /* Generic battery client messages length */
50 #define BLE_MESH_GEN_BATTERY_GET_MSG_LEN            (2 + 0 + 4)
51 
52 /* Generic location client messages length */
53 #define BLE_MESH_GEN_LOC_GLOBAL_GET_MSG_LEN         (2 +  0 + 4)
54 #define BLE_MESH_GEN_LOC_GLOBAL_SET_MSG_LEN         (1 + 10 + 4)
55 #define BLE_MESH_GEN_LOC_LOCAL_GET_MSG_LEN          (2 +  0 + 4)
56 #define BLE_MESH_GEN_LOC_LOCAL_SET_MSG_LEN          (2 +  9 + 4)
57 
58 /* Generic property client messages length */
59 #define BLE_MESH_GEN_USER_PROPERTIES_GET_MSG_LEN    (2 + 0 + 4)
60 #define BLE_MESH_GEN_USER_PROPERTY_GET_MSG_LEN      (2 + 2 + 4)
61 #define BLE_MESH_GEN_USER_PROPERTY_SET_MSG_LEN      /* variable */
62 #define BLE_MESH_GEN_ADMIN_PROPERTIES_GET_MSG_LEN   (2 + 0 + 4)
63 #define BLE_MESH_GEN_ADMIN_PROPERTY_GET_MSG_LEN     (2 + 2 + 4)
64 #define BLE_MESH_GEN_ADMIN_PROPERTY_SET_MSG_LEN     /* variable */
65 #define BLE_MESH_GEN_MANU_PROPERTIES_GET_MSG_LEN    (2 + 0 + 4)
66 #define BLE_MESH_GEN_MANU_PROPERTY_GET_MSG_LEN      (2 + 2 + 4)
67 #define BLE_MESH_GEN_MANU_PROPERTY_SET_MSG_LEN      (1 + 3 + 4)
68 #define BLE_MESH_GEN_CLINET_PROPERTIES_GET_MSG_LEN  (1 + 2 + 4)
69 
70 #define BLE_MESH_GEN_GET_STATE_MSG_LEN              (2 + 2 + 4)
71 
72 static const bt_mesh_client_op_pair_t gen_op_pair[] = {
73     { BLE_MESH_MODEL_OP_GEN_ONOFF_GET,             BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS             },
74     { BLE_MESH_MODEL_OP_GEN_ONOFF_SET,             BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS             },
75     { BLE_MESH_MODEL_OP_GEN_LEVEL_GET,             BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS             },
76     { BLE_MESH_MODEL_OP_GEN_LEVEL_SET,             BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS             },
77     { BLE_MESH_MODEL_OP_GEN_DELTA_SET,             BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS             },
78     { BLE_MESH_MODEL_OP_GEN_MOVE_SET,              BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS             },
79     { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET,    BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS    },
80     { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET,    BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS    },
81     { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET,         BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS         },
82     { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET,         BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS         },
83     { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET,       BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS       },
84     { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET,       BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS       },
85     { BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET,        BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS        },
86     { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET,     BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS     },
87     { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET,     BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS     },
88     { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET,       BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS       },
89     { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET,       BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS       },
90     { BLE_MESH_MODEL_OP_GEN_BATTERY_GET,           BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS           },
91     { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET,        BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS        },
92     { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET,        BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS        },
93     { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET,         BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS         },
94     { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET,         BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS         },
95     { BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET,   BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS   },
96     { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET,     BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS     },
97     { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET,     BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS     },
98     { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET,  BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS  },
99     { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET,    BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS    },
100     { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET,    BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS    },
101     { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET,   BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS   },
102     { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET,     BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS     },
103     { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET,     BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS     },
104     { BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET, BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS },
105 };
106 
107 static bt_mesh_mutex_t generic_client_lock;
108 
bt_mesh_generic_client_mutex_new(void)109 static inline void bt_mesh_generic_client_mutex_new(void)
110 {
111     if (!generic_client_lock.mutex) {
112         bt_mesh_mutex_create(&generic_client_lock);
113     }
114 }
115 
116 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_generic_client_mutex_free(void)117 static inline void bt_mesh_generic_client_mutex_free(void)
118 {
119     bt_mesh_mutex_free(&generic_client_lock);
120 }
121 #endif /* CONFIG_BLE_MESH_DEINIT */
122 
bt_mesh_generic_client_lock(void)123 static inline void bt_mesh_generic_client_lock(void)
124 {
125     bt_mesh_mutex_lock(&generic_client_lock);
126 }
127 
bt_mesh_generic_client_unlock(void)128 static inline void bt_mesh_generic_client_unlock(void)
129 {
130     bt_mesh_mutex_unlock(&generic_client_lock);
131 }
132 
timeout_handler(struct k_work * work)133 static void timeout_handler(struct k_work *work)
134 {
135     struct k_delayed_work *timer = NULL;
136     bt_mesh_client_node_t *node = NULL;
137     struct bt_mesh_msg_ctx ctx = {0};
138     uint32_t opcode = 0U;
139 
140     BT_WARN("Receive generic status message timeout");
141 
142     bt_mesh_generic_client_lock();
143 
144     timer = CONTAINER_OF(work, struct k_delayed_work, work);
145 
146     if (timer && !k_delayed_work_free(timer)) {
147         node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
148         if (node) {
149             memcpy(&ctx, &node->ctx, sizeof(ctx));
150             opcode = node->opcode;
151             bt_mesh_client_free_node(node);
152             bt_mesh_generic_client_cb_evt_to_btc(
153                 opcode, BTC_BLE_MESH_EVT_GENERIC_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0);
154         }
155     }
156 
157     bt_mesh_generic_client_unlock();
158 
159     return;
160 }
161 
generic_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)162 static void generic_status(struct bt_mesh_model *model,
163                            struct bt_mesh_msg_ctx *ctx,
164                            struct net_buf_simple *buf)
165 {
166     bt_mesh_client_node_t *node = NULL;
167     uint8_t *val = NULL;
168     uint8_t evt = 0xFF;
169     size_t len = 0U;
170 
171     BT_DBG("len %d, bytes %s", buf->len, bt_hex(buf->data, buf->len));
172 
173     switch (ctx->recv_op) {
174     case BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS: {
175         struct bt_mesh_gen_onoff_status *status = NULL;
176         if (buf->len != 1 && buf->len != 3) {
177             BT_ERR("Invalid Generic OnOff Status length %d", buf->len);
178             return;
179         }
180         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_onoff_status));
181         if (!status) {
182             BT_ERR("%s, Out of memory", __func__);
183             return;
184         }
185         status->present_onoff = net_buf_simple_pull_u8(buf);
186         if (buf->len) {
187             status->op_en = true;
188             status->target_onoff = net_buf_simple_pull_u8(buf);
189             status->remain_time = net_buf_simple_pull_u8(buf);
190         }
191         val = (uint8_t *)status;
192         len = sizeof(struct bt_mesh_gen_onoff_status);
193         break;
194     }
195     case BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS: {
196         struct bt_mesh_gen_level_status *status = NULL;
197         if (buf->len != 2 && buf->len != 5) {
198             BT_ERR("Invalid Generic Level Status length %d", buf->len);
199             return;
200         }
201         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_level_status));
202         if (!status) {
203             BT_ERR("%s, Out of memory", __func__);
204             return;
205         }
206         status->present_level = net_buf_simple_pull_le16(buf);
207         if (buf->len) {
208             status->op_en = true;
209             status->target_level = net_buf_simple_pull_le16(buf);
210             status->remain_time = net_buf_simple_pull_u8(buf);
211         }
212         val = (uint8_t *)status;
213         len = sizeof(struct bt_mesh_gen_level_status);
214         break;
215     }
216     case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS: {
217         struct bt_mesh_gen_def_trans_time_status *status = NULL;
218         if (buf->len != 1) {
219             BT_ERR("Invalid Generic Default Trans Time Status length %d", buf->len);
220             return;
221         }
222         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_def_trans_time_status));
223         if (!status) {
224             BT_ERR("%s, Out of memory", __func__);
225             return;
226         }
227         status->trans_time = net_buf_simple_pull_u8(buf);
228         val = (uint8_t *)status;
229         len = sizeof(struct bt_mesh_gen_def_trans_time_status);
230         break;
231     }
232     case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS: {
233         struct bt_mesh_gen_onpowerup_status *status = NULL;
234         if (buf->len != 1) {
235             BT_ERR("Invalid Generic OnPowerUp Status length %d", buf->len);
236             return;
237         }
238         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_onpowerup_status));
239         if (!status) {
240             BT_ERR("%s, Out of memory", __func__);
241             return;
242         }
243         status->onpowerup = net_buf_simple_pull_u8(buf);
244         val = (uint8_t *)status;
245         len = sizeof(struct bt_mesh_gen_onpowerup_status);
246         break;
247     }
248     case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS: {
249         struct bt_mesh_gen_power_level_status *status = NULL;
250         if (buf->len != 2 && buf->len != 5) {
251             BT_ERR("Invalid Generic Power Level Status length %d", buf->len);
252             return;
253         }
254         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_level_status));
255         if (!status) {
256             BT_ERR("%s, Out of memory", __func__);
257             return;
258         }
259         status->present_power = net_buf_simple_pull_le16(buf);
260         if (buf->len) {
261             status->op_en = true;
262             status->target_power = net_buf_simple_pull_le16(buf);
263             status->remain_time = net_buf_simple_pull_u8(buf);
264         }
265         val = (uint8_t *)status;
266         len = sizeof(struct bt_mesh_gen_power_level_status);
267         break;
268     }
269     case BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS: {
270         struct bt_mesh_gen_power_last_status *status = NULL;
271         if (buf->len != 2) {
272             BT_ERR("Invalid Generic Power Last Status length %d", buf->len);
273             return;
274         }
275         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_last_status));
276         if (!status) {
277             BT_ERR("%s, Out of memory", __func__);
278             return;
279         }
280         status->power = net_buf_simple_pull_le16(buf);
281         val = (uint8_t *)status;
282         len = sizeof(struct bt_mesh_gen_power_last_status);
283         break;
284     }
285     case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS: {
286         struct bt_mesh_gen_power_default_status *status = NULL;
287         if (buf->len != 2) {
288             BT_ERR("Invalid Generic Power Default Status length %d", buf->len);
289             return;
290         }
291         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_default_status));
292         if (!status) {
293             BT_ERR("%s, Out of memory", __func__);
294             return;
295         }
296         status->power = net_buf_simple_pull_le16(buf);
297         val = (uint8_t *)status;
298         len = sizeof(struct bt_mesh_gen_power_default_status);
299         break;
300     }
301     case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS: {
302         struct bt_mesh_gen_power_range_status *status = NULL;
303         if (buf->len != 5) {
304             BT_ERR("Invalid Generic Power Range Status length %d", buf->len);
305             return;
306         }
307         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_range_status));
308         if (!status) {
309             BT_ERR("%s, Out of memory", __func__);
310             return;
311         }
312         status->status_code = net_buf_simple_pull_u8(buf);
313         status->range_min = net_buf_simple_pull_le16(buf);
314         status->range_max = net_buf_simple_pull_le16(buf);
315         val = (uint8_t *)status;
316         len = sizeof(struct bt_mesh_gen_power_range_status);
317         break;
318     }
319     case BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS: {
320         struct bt_mesh_gen_battery_status *status = NULL;
321         if (buf->len != 8) {
322             BT_ERR("Invalid Generic Battery Status length %d", buf->len);
323             return;
324         }
325         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_battery_status));
326         if (!status) {
327             BT_ERR("%s, Out of memory", __func__);
328             return;
329         }
330         uint32_t value = 0;
331         value = net_buf_simple_pull_le32(buf);
332         status->battery_level = (uint8_t)value;
333         status->time_to_discharge = (value >> 8);
334         value = net_buf_simple_pull_le32(buf);
335         status->time_to_charge = (value & 0xffffff);
336         status->flags = (uint8_t)(value >> 24);
337         val = (uint8_t *)status;
338         len = sizeof(struct bt_mesh_gen_battery_status);
339         break;
340     }
341     case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS: {
342         struct bt_mesh_gen_loc_global_status *status = NULL;
343         if (buf->len != 10) {
344             BT_ERR("Invalid Generic Location Global Status length %d", buf->len);
345             return;
346         }
347         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_loc_global_status));
348         if (!status) {
349             BT_ERR("%s, Out of memory", __func__);
350             return;
351         }
352         status->global_latitude = net_buf_simple_pull_le32(buf);
353         status->global_longitude = net_buf_simple_pull_le32(buf);
354         status->global_altitude = net_buf_simple_pull_le16(buf);
355         val = (uint8_t *)status;
356         len = sizeof(struct bt_mesh_gen_loc_global_status);
357         break;
358     }
359     case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS: {
360         struct bt_mesh_gen_loc_local_status *status = NULL;
361         if (buf->len != 9) {
362             BT_ERR("Invalid Generic Location Local Status length %d", buf->len);
363             return;
364         }
365         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_loc_local_status));
366         if (!status) {
367             BT_ERR("%s, Out of memory", __func__);
368             return;
369         }
370         status->local_north = net_buf_simple_pull_le16(buf);
371         status->local_east = net_buf_simple_pull_le16(buf);
372         status->local_altitude = net_buf_simple_pull_le16(buf);
373         status->floor_number = net_buf_simple_pull_u8(buf);
374         status->uncertainty = net_buf_simple_pull_le16(buf);
375         val = (uint8_t *)status;
376         len = sizeof(struct bt_mesh_gen_loc_local_status);
377         break;
378     }
379     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS: {
380         struct bt_mesh_gen_user_properties_status *status = NULL;
381         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_user_properties_status));
382         if (!status) {
383             BT_ERR("%s, Out of memory", __func__);
384             return;
385         }
386         status->user_property_ids = bt_mesh_alloc_buf(buf->len);
387         if (!status->user_property_ids) {
388             BT_ERR("%s, Out of memory", __func__);
389             bt_mesh_free(status);
390             return;
391         }
392         net_buf_simple_add_mem(status->user_property_ids, buf->data, buf->len);
393         val = (uint8_t *)status;
394         len = sizeof(struct bt_mesh_gen_user_properties_status);
395         break;
396     }
397     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS: {
398         struct bt_mesh_gen_user_property_status *status = NULL;
399         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_user_property_status));
400         if (!status) {
401             BT_ERR("%s, Out of memory", __func__);
402             return;
403         }
404         status->user_property_id = net_buf_simple_pull_le16(buf);
405         if (buf->len) {
406             status->op_en = true;
407             status->user_access = net_buf_simple_pull_u8(buf);
408             status->user_property_value = bt_mesh_alloc_buf(buf->len);
409             if (!status->user_property_value) {
410                 BT_ERR("%s, Out of memory", __func__);
411                 bt_mesh_free(status);
412                 return;
413             }
414             net_buf_simple_add_mem(status->user_property_value, buf->data, buf->len);
415         }
416         val = (uint8_t *)status;
417         len = sizeof(struct bt_mesh_gen_user_property_status);
418         break;
419     }
420     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS: {
421         struct bt_mesh_gen_admin_properties_status *status = NULL;
422         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_admin_properties_status));
423         if (!status) {
424             BT_ERR("%s, Out of memory", __func__);
425             return;
426         }
427         status->admin_property_ids = bt_mesh_alloc_buf(buf->len);
428         if (!status->admin_property_ids) {
429             BT_ERR("%s, Out of memory", __func__);
430             bt_mesh_free(status);
431             return;
432         }
433         net_buf_simple_add_mem(status->admin_property_ids, buf->data, buf->len);
434         val = (uint8_t *)status;
435         len = sizeof(struct bt_mesh_gen_admin_properties_status);
436         break;
437     }
438     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS: {
439         struct bt_mesh_gen_admin_property_status *status = NULL;
440         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_admin_property_status));
441         if (!status) {
442             BT_ERR("%s, Out of memory", __func__);
443             return;
444         }
445         status->admin_property_id = net_buf_simple_pull_le16(buf);
446         if (buf->len) {
447             status->op_en = true;
448             status->admin_user_access = net_buf_simple_pull_u8(buf);
449             status->admin_property_value = bt_mesh_alloc_buf(buf->len);
450             if (!status->admin_property_value) {
451                 BT_ERR("%s, Out of memory", __func__);
452                 bt_mesh_free(status);
453                 return;
454             }
455             net_buf_simple_add_mem(status->admin_property_value, buf->data, buf->len);
456         }
457         val = (uint8_t *)status;
458         len = sizeof(struct bt_mesh_gen_admin_property_status);
459         break;
460     }
461     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS: {
462         struct bt_mesh_gen_manu_properties_status *status = NULL;
463         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_manu_properties_status));
464         if (!status) {
465             BT_ERR("%s, Out of memory", __func__);
466             return;
467         }
468         status->manu_property_ids = bt_mesh_alloc_buf(buf->len);
469         if (!status->manu_property_ids) {
470             BT_ERR("%s, Out of memory", __func__);
471             bt_mesh_free(status);
472             return;
473         }
474         net_buf_simple_add_mem(status->manu_property_ids, buf->data, buf->len);
475         val = (uint8_t *)status;
476         len = sizeof(struct bt_mesh_gen_manu_properties_status);
477         break;
478     }
479     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS: {
480         struct bt_mesh_gen_manu_property_status *status = NULL;
481         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_manu_property_status));
482         if (!status) {
483             BT_ERR("%s, Out of memory", __func__);
484             return;
485         }
486         status->manu_property_id = net_buf_simple_pull_le16(buf);
487         if (buf->len) {
488             status->op_en = true;
489             status->manu_user_access = net_buf_simple_pull_u8(buf);
490             status->manu_property_value = bt_mesh_alloc_buf(buf->len);
491             if (!status->manu_property_value) {
492                 BT_ERR("%s, Out of memory", __func__);
493                 bt_mesh_free(status);
494                 return;
495             }
496             net_buf_simple_add_mem(status->manu_property_value, buf->data, buf->len);
497         }
498         val = (uint8_t *)status;
499         len = sizeof(struct bt_mesh_gen_manu_property_status);
500         break;
501     }
502     case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS: {
503         struct bt_mesh_gen_client_properties_status *status = NULL;
504         status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_client_properties_status));
505         if (!status) {
506             BT_ERR("%s, Out of memory", __func__);
507             return;
508         }
509         status->client_property_ids = bt_mesh_alloc_buf(buf->len);
510         if (!status->client_property_ids) {
511             BT_ERR("%s, Out of memory", __func__);
512             bt_mesh_free(status);
513             return;
514         }
515         net_buf_simple_add_mem(status->client_property_ids, buf->data, buf->len);
516         val = (uint8_t *)status;
517         len = sizeof(struct bt_mesh_gen_client_properties_status);
518         break;
519     }
520     default:
521         BT_ERR("Invalid Generic Status opcode 0x%04x", ctx->recv_op);
522         return;
523     }
524 
525     buf->data = val;
526     buf->len  = len;
527 
528     bt_mesh_generic_client_lock();
529 
530     node = bt_mesh_is_client_recv_publish_msg(model, ctx, buf, true);
531     if (!node) {
532         BT_DBG("Unexpected Generic Status 0x%04x", ctx->recv_op);
533     } else {
534         switch (node->opcode) {
535         case BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
536         case BLE_MESH_MODEL_OP_GEN_LEVEL_GET:
537         case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET:
538         case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET:
539         case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET:
540         case BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET:
541         case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET:
542         case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET:
543         case BLE_MESH_MODEL_OP_GEN_BATTERY_GET:
544         case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET:
545         case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET:
546         case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
547         case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
548         case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
549         case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
550         case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET:
551         case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET:
552         case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
553             evt = BTC_BLE_MESH_EVT_GENERIC_CLIENT_GET_STATE;
554             break;
555         case BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
556         case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
557         case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
558         case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
559         case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET:
560         case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET:
561         case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET:
562         case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET:
563         case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET:
564         case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET:
565         case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET:
566         case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
567         case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
568         case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET:
569             evt = BTC_BLE_MESH_EVT_GENERIC_CLIENT_SET_STATE;
570             break;
571         default:
572             break;
573         }
574 
575         if (!k_delayed_work_free(&node->timer)) {
576             uint32_t opcode = node->opcode;
577             bt_mesh_client_free_node(node);
578             bt_mesh_generic_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len);
579         }
580     }
581 
582     bt_mesh_generic_client_unlock();
583 
584     switch (ctx->recv_op) {
585     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS: {
586         struct bt_mesh_gen_user_properties_status *status;
587         status = (struct bt_mesh_gen_user_properties_status *)val;
588         bt_mesh_free_buf(status->user_property_ids);
589         break;
590     }
591     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS: {
592         struct bt_mesh_gen_user_property_status *status;
593         status = (struct bt_mesh_gen_user_property_status *)val;
594         bt_mesh_free_buf(status->user_property_value);
595         break;
596     }
597     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS: {
598         struct bt_mesh_gen_admin_properties_status *status;
599         status = (struct bt_mesh_gen_admin_properties_status *)val;
600         bt_mesh_free_buf(status->admin_property_ids);
601         break;
602     }
603     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS: {
604         struct bt_mesh_gen_admin_property_status *status;
605         status = (struct bt_mesh_gen_admin_property_status *)val;
606         bt_mesh_free_buf(status->admin_property_value);
607         break;
608     }
609     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS: {
610         struct bt_mesh_gen_manu_properties_status *status;
611         status = (struct bt_mesh_gen_manu_properties_status *)val;
612         bt_mesh_free_buf(status->manu_property_ids);
613         break;
614     }
615     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS: {
616         struct bt_mesh_gen_manu_property_status *status;
617         status = (struct bt_mesh_gen_manu_property_status *)val;
618         bt_mesh_free_buf(status->manu_property_value);
619         break;
620     }
621     case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS: {
622         struct bt_mesh_gen_client_properties_status *status;
623         status = (struct bt_mesh_gen_client_properties_status *)val;
624         bt_mesh_free_buf(status->client_property_ids);
625         break;
626     }
627     default:
628         break;
629     }
630 
631     bt_mesh_free(val);
632 
633     return;
634 }
635 
636 const struct bt_mesh_model_op bt_mesh_gen_onoff_cli_op[] = {
637     { BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, 1, generic_status },
638     BLE_MESH_MODEL_OP_END,
639 };
640 
641 const struct bt_mesh_model_op bt_mesh_gen_level_cli_op[] = {
642     { BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS, 2, generic_status },
643     BLE_MESH_MODEL_OP_END,
644 };
645 
646 const struct bt_mesh_model_op bt_mesh_gen_def_trans_time_cli_op[] = {
647     { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS, 1, generic_status },
648     BLE_MESH_MODEL_OP_END,
649 };
650 
651 const struct bt_mesh_model_op bt_mesh_gen_power_onoff_cli_op[] = {
652     { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS, 1, generic_status },
653     BLE_MESH_MODEL_OP_END,
654 };
655 
656 const struct bt_mesh_model_op bt_mesh_gen_power_level_cli_op[] = {
657     { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS,   2, generic_status   },
658     { BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS,    2, generic_status    },
659     { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS, 2, generic_status },
660     { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS,   5, generic_status   },
661     BLE_MESH_MODEL_OP_END,
662 };
663 
664 const struct bt_mesh_model_op bt_mesh_gen_battery_cli_op[] = {
665     { BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS, 8, generic_status },
666     BLE_MESH_MODEL_OP_END,
667 };
668 
669 const struct bt_mesh_model_op bt_mesh_gen_location_cli_op[] = {
670     { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS, 10, generic_status },
671     { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS,  9,  generic_status },
672     BLE_MESH_MODEL_OP_END,
673 };
674 
675 const struct bt_mesh_model_op bt_mesh_gen_property_cli_op[] = {
676     { BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS,   2, generic_status },
677     { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS,     2, generic_status },
678     { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS,  2, generic_status },
679     { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS,    2, generic_status },
680     { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS,   2, generic_status },
681     { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS,     2, generic_status },
682     { BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS, 2, generic_status },
683     BLE_MESH_MODEL_OP_END,
684 };
685 
gen_get_state(bt_mesh_client_common_param_t * common,void * value)686 static int gen_get_state(bt_mesh_client_common_param_t *common, void *value)
687 {
688     NET_BUF_SIMPLE_DEFINE(msg, BLE_MESH_GEN_GET_STATE_MSG_LEN);
689 
690     bt_mesh_model_msg_init(&msg, common->opcode);
691 
692     if (value) {
693         switch (common->opcode) {
694         case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET: {
695             struct bt_mesh_gen_user_property_get *get;
696             get = (struct bt_mesh_gen_user_property_get *)value;
697             net_buf_simple_add_le16(&msg, get->user_property_id);
698             break;
699         }
700         case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET: {
701             struct bt_mesh_gen_admin_property_get *get;
702             get = (struct bt_mesh_gen_admin_property_get *)value;
703             net_buf_simple_add_le16(&msg, get->admin_property_id);
704             break;
705         }
706         case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET: {
707             struct bt_mesh_gen_manu_property_get *get;
708             get = (struct bt_mesh_gen_manu_property_get *)value;
709             net_buf_simple_add_le16(&msg, get->manu_property_id);
710             break;
711         }
712         case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET: {
713             struct bt_mesh_gen_client_properties_get *get;
714             get = (struct bt_mesh_gen_client_properties_get *)value;
715             net_buf_simple_add_le16(&msg, get->client_property_id);
716             break;
717         }
718         default:
719             BT_DBG("No parameters for Generic Get 0x%04x", common->opcode);
720             break;
721         }
722     }
723 
724     return bt_mesh_client_send_msg(common, &msg, true, timeout_handler);
725 }
726 
gen_set_state(bt_mesh_client_common_param_t * common,void * value,uint16_t value_len,bool need_ack)727 static int gen_set_state(bt_mesh_client_common_param_t *common,
728                          void *value, uint16_t value_len, bool need_ack)
729 {
730     struct net_buf_simple *msg = NULL;
731     int err = 0;
732 
733     msg = bt_mesh_alloc_buf(value_len);
734     if (!msg) {
735         BT_ERR("%s, Out of memory", __func__);
736         return -ENOMEM;
737     }
738 
739     bt_mesh_model_msg_init(msg, common->opcode);
740 
741     switch (common->opcode) {
742     case BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
743     case BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK: {
744         struct bt_mesh_gen_onoff_set *set;
745         set = (struct bt_mesh_gen_onoff_set *)value;
746         net_buf_simple_add_u8(msg, set->onoff);
747         net_buf_simple_add_u8(msg, set->tid);
748         if (set->op_en) {
749             net_buf_simple_add_u8(msg, set->trans_time);
750             net_buf_simple_add_u8(msg, set->delay);
751         }
752         break;
753     }
754 
755     case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
756     case BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK: {
757         struct bt_mesh_gen_level_set *set;
758         set = (struct bt_mesh_gen_level_set *)value;
759         net_buf_simple_add_le16(msg, set->level);
760         net_buf_simple_add_u8(msg,   set->tid);
761         if (set->op_en) {
762             net_buf_simple_add_u8(msg, set->trans_time);
763             net_buf_simple_add_u8(msg, set->delay);
764         }
765         break;
766     }
767 
768     case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
769     case BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK: {
770         struct bt_mesh_gen_delta_set *set;
771         set = (struct bt_mesh_gen_delta_set *)value;
772         net_buf_simple_add_le32(msg, set->delta_level);
773         net_buf_simple_add_u8(msg, set->tid);
774         if (set->op_en) {
775             net_buf_simple_add_u8(msg, set->trans_time);
776             net_buf_simple_add_u8(msg, set->delay);
777         }
778         break;
779     }
780 
781     case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
782     case BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK: {
783         struct bt_mesh_gen_move_set *set;
784         set = (struct bt_mesh_gen_move_set *)value;
785         net_buf_simple_add_le16(msg, set->delta_level);
786         net_buf_simple_add_u8(msg,   set->tid);
787         if (set->op_en) {
788             net_buf_simple_add_u8(msg, set->trans_time);
789             net_buf_simple_add_u8(msg, set->delay);
790         }
791         break;
792     }
793 
794     case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET:
795     case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK: {
796         struct bt_mesh_gen_def_trans_time_set *set;
797         set = (struct bt_mesh_gen_def_trans_time_set *)value;
798         net_buf_simple_add_u8(msg, set->trans_time);
799         break;
800     }
801 
802     case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET:
803     case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK: {
804         struct bt_mesh_gen_onpowerup_set *set;
805         set = (struct bt_mesh_gen_onpowerup_set *)value;
806         net_buf_simple_add_u8(msg, set->onpowerup);
807         break;
808     }
809 
810     case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET:
811     case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK: {
812         struct bt_mesh_gen_power_level_set *set;
813         set = (struct bt_mesh_gen_power_level_set *)value;
814         net_buf_simple_add_le16(msg, set->power);
815         net_buf_simple_add_u8(msg,   set->tid);
816         if (set->op_en) {
817             net_buf_simple_add_u8(msg, set->trans_time);
818             net_buf_simple_add_u8(msg, set->delay);
819         }
820         break;
821     }
822 
823     case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET:
824     case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK: {
825         struct bt_mesh_gen_power_default_set *set;
826         set = (struct bt_mesh_gen_power_default_set *)value;
827         net_buf_simple_add_le16(msg, set->power);
828         break;
829     }
830 
831     case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET:
832     case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK: {
833         struct bt_mesh_gen_power_range_set *set;
834         set = (struct bt_mesh_gen_power_range_set *)value;
835         net_buf_simple_add_le16(msg, set->range_min);
836         net_buf_simple_add_le16(msg, set->range_max);
837         break;
838     }
839 
840     case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET:
841     case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK: {
842         struct bt_mesh_gen_loc_global_set *set;
843         set = (struct bt_mesh_gen_loc_global_set *)value;
844         net_buf_simple_add_le32(msg, set->global_latitude);
845         net_buf_simple_add_le32(msg, set->global_longitude);
846         net_buf_simple_add_le16(msg, set->global_altitude);
847         break;
848     }
849 
850     case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET:
851     case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK: {
852         struct bt_mesh_gen_loc_local_set *set;
853         set = (struct bt_mesh_gen_loc_local_set *)value;
854         net_buf_simple_add_le16(msg, set->local_north);
855         net_buf_simple_add_le16(msg, set->local_east);
856         net_buf_simple_add_le16(msg, set->local_altitude);
857         net_buf_simple_add_u8(msg,   set->floor_number);
858         net_buf_simple_add_le16(msg, set->uncertainty);
859         break;
860     }
861 
862     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
863     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK: {
864         struct bt_mesh_gen_user_property_set *set;
865         set = (struct bt_mesh_gen_user_property_set *)value;
866         net_buf_simple_add_le16(msg, set->user_property_id);
867         net_buf_simple_add_mem(msg,  set->user_property_value->data, set->user_property_value->len);
868         break;
869     }
870 
871     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
872     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK: {
873         struct bt_mesh_gen_admin_property_set *set;
874         set = (struct bt_mesh_gen_admin_property_set *)value;
875         net_buf_simple_add_le16(msg, set->admin_property_id);
876         net_buf_simple_add_u8(msg, set->admin_user_access);
877         net_buf_simple_add_mem(msg, set->admin_property_value->data, set->admin_property_value->len);
878         break;
879     }
880 
881     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET:
882     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET_UNACK: {
883         struct bt_mesh_gen_manu_property_set *set;
884         set = (struct bt_mesh_gen_manu_property_set *)value;
885         net_buf_simple_add_le16(msg, set->manu_property_id);
886         net_buf_simple_add_u8(msg, set->manu_user_access);
887         break;
888     }
889 
890     default:
891         BT_ERR("Invalid Generic Set opcode 0x%04x", common->opcode);
892         err = -EINVAL;
893         goto end;
894     }
895 
896     err = bt_mesh_client_send_msg(common, msg, need_ack, timeout_handler);
897 
898 end:
899     bt_mesh_free_buf(msg);
900     return err;
901 }
902 
bt_mesh_generic_client_get_state(bt_mesh_client_common_param_t * common,void * get)903 int bt_mesh_generic_client_get_state(bt_mesh_client_common_param_t *common, void *get)
904 {
905     bt_mesh_generic_client_t *client = NULL;
906 
907     if (!common || !common->model) {
908         BT_ERR("%s, Invalid parameter", __func__);
909         return -EINVAL;
910     }
911 
912     client = (bt_mesh_generic_client_t *)common->model->user_data;
913     if (!client || !client->internal_data) {
914         BT_ERR("Invalid Generic client data");
915         return -EINVAL;
916     }
917 
918     switch (common->opcode) {
919     case BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
920     case BLE_MESH_MODEL_OP_GEN_LEVEL_GET:
921     case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET:
922     case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET:
923     case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET:
924     case BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET:
925     case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET:
926     case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET:
927     case BLE_MESH_MODEL_OP_GEN_BATTERY_GET:
928     case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET:
929     case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET:
930     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
931     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
932     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET:
933         break;
934     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
935         if (!get) {
936             BT_ERR("Invalid Generic User Property Get");
937             return -EINVAL;
938         }
939         break;
940     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
941         if (!get) {
942             BT_ERR("Invalid Generic Admin Property Get");
943             return -EINVAL;
944         }
945         break;
946     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET:
947         if (!get) {
948             BT_ERR("Invalid Generic Manu Property Get");
949             return -EINVAL;
950         }
951         break;
952     case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
953         if (!get) {
954             BT_ERR("Invalid Generic Client Properties Get");
955             return -EINVAL;
956         }
957         break;
958     default:
959         BT_ERR("Invalid Generic Get opcode 0x%04x", common->opcode);
960         return -EINVAL;
961     }
962 
963     return gen_get_state(common, get);
964 }
965 
bt_mesh_generic_client_set_state(bt_mesh_client_common_param_t * common,void * set)966 int bt_mesh_generic_client_set_state(bt_mesh_client_common_param_t *common, void *set)
967 {
968     bt_mesh_generic_client_t *client = NULL;
969     uint16_t length = 0U;
970     bool need_ack = false;
971 
972     if (!common || !common->model || !set) {
973         BT_ERR("%s, Invalid parameter", __func__);
974         return -EINVAL;
975     }
976 
977     client = (bt_mesh_generic_client_t *)common->model->user_data;
978     if (!client || !client->internal_data) {
979         BT_ERR("Invalid Generic client data");
980         return -EINVAL;
981     }
982 
983     switch (common->opcode) {
984     case BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
985         need_ack = true;
986     case BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK: {
987         struct bt_mesh_gen_onoff_set *value;
988         value = (struct bt_mesh_gen_onoff_set *)set;
989         if (value->op_en) {
990             if ((value->trans_time & 0x3F) > 0x3E) {
991                 BT_ERR("Invalid Generic OnOff Set transition time");
992                 return -EINVAL;
993             }
994         }
995         length = BLE_MESH_GEN_ONOFF_SET_MSG_LEN;
996         break;
997     }
998     case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
999         need_ack = true;
1000     case BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK: {
1001         struct bt_mesh_gen_level_set *value;
1002         value = (struct bt_mesh_gen_level_set *)set;
1003         if (value->op_en) {
1004             if ((value->trans_time & 0x3F) > 0x3E) {
1005                 BT_ERR("Invalid Generic Level Set transition time");
1006                 return -EINVAL;
1007             }
1008         }
1009         length = BLE_MESH_GEN_LEVEL_SET_MSG_LEN;
1010         break;
1011     }
1012     case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
1013         need_ack = true;
1014     case BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK: {
1015         struct bt_mesh_gen_delta_set *value;
1016         value = (struct bt_mesh_gen_delta_set *)set;
1017         if (value->op_en) {
1018             if ((value->trans_time & 0x3F) > 0x3E) {
1019                 BT_ERR("Invalid Generic Delta Set transition time");
1020                 return -EINVAL;
1021             }
1022         }
1023         length = BLE_MESH_GEN_DELTA_SET_MSG_LEN;
1024         break;
1025     }
1026     case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
1027         need_ack = true;
1028     case BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK: {
1029         struct bt_mesh_gen_move_set *value;
1030         value = (struct bt_mesh_gen_move_set *)set;
1031         if (value->op_en) {
1032             if ((value->trans_time & 0x3F) > 0x3E) {
1033                 BT_ERR("Invalid Generic Move Set transition time");
1034                 return -EINVAL;
1035             }
1036         }
1037         length = BLE_MESH_GEN_MOVE_SET_MSG_LEN;
1038         break;
1039     }
1040     case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET:
1041         need_ack = true;
1042     case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK: {
1043         uint8_t value = *(uint8_t *)set;
1044         if ((value & 0x3F) > 0x3E) {
1045             BT_ERR("Invalid Generic Default Trans Time Set transition time");
1046             return -EINVAL;
1047         }
1048         length = BLE_MESH_GEN_DEF_TRANS_TIME_SET_MSG_LEN;
1049         break;
1050     }
1051     case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET:
1052         need_ack = true;
1053     case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK:
1054         length = BLE_MESH_GEN_ONPOWERUP_SET_MSG_LEN;
1055         break;
1056     case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET:
1057         need_ack = true;
1058     case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK: {
1059         struct bt_mesh_gen_power_level_set *value;
1060         value = (struct bt_mesh_gen_power_level_set *)set;
1061         if (value->op_en) {
1062             if ((value->trans_time & 0x3F) > 0x3E) {
1063                 BT_ERR("Invalid Generic Power Level Set transition time");
1064                 return -EINVAL;
1065             }
1066         }
1067         length = BLE_MESH_GEN_POWER_LEVEL_SET_MSG_LEN;
1068         break;
1069     }
1070     case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET:
1071         need_ack = true;
1072     case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK:
1073         length = BLE_MESH_GEN_POWER_DEFAULT_SET_MSG_LEN;
1074         break;
1075     case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET:
1076         need_ack = true;
1077     case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK: {
1078         struct bt_mesh_gen_power_range_set *value;
1079         value = (struct bt_mesh_gen_power_range_set *)set;
1080         if (value->range_min > value->range_max) {
1081             BT_ERR("Generic Power Level Set range min is greater than range max");
1082             return -EINVAL;
1083         }
1084         length = BLE_MESH_GEN_POWER_RANGE_SET_MSG_LEN;
1085         break;
1086     }
1087     case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET:
1088         need_ack = true;
1089     case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK:
1090         length = BLE_MESH_GEN_LOC_GLOBAL_SET_MSG_LEN;
1091         break;
1092     case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET:
1093         need_ack = true;
1094     case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK:
1095         length = BLE_MESH_GEN_LOC_LOCAL_SET_MSG_LEN;
1096         break;
1097     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
1098         need_ack = true;
1099     case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK: {
1100         struct bt_mesh_gen_user_property_set *value;
1101         value = (struct bt_mesh_gen_user_property_set *)set;
1102         if (!value->user_property_value) {
1103             BT_ERR("Invalid Generic User Property value");
1104             return -EINVAL;
1105         }
1106         length = (1 + 2 + value->user_property_value->len + 4);
1107         break;
1108     }
1109     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
1110         need_ack = true;
1111     case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK: {
1112         struct bt_mesh_gen_admin_property_set *value;
1113         value = (struct bt_mesh_gen_admin_property_set *)set;
1114         if (!value->admin_property_value) {
1115             BT_ERR("Invalid Generic Admin Property value");
1116             return -EINVAL;
1117         }
1118         length = (1 + 2 + 1 + value->admin_property_value->len + 4);
1119         break;
1120     }
1121     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET:
1122         need_ack = true;
1123     case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET_UNACK:
1124         length = BLE_MESH_GEN_MANU_PROPERTY_SET_MSG_LEN;
1125         break;
1126     default:
1127         BT_ERR("Invalid Generic Set opcode 0x%04x", common->opcode);
1128         return -EINVAL;
1129     }
1130 
1131     return gen_set_state(common, set, length, need_ack);
1132 }
1133 
generic_client_init(struct bt_mesh_model * model)1134 static int generic_client_init(struct bt_mesh_model *model)
1135 {
1136     generic_internal_data_t *internal = NULL;
1137     bt_mesh_generic_client_t *client = NULL;
1138 
1139     if (!model) {
1140         BT_ERR("Invalid Generic client model");
1141         return -EINVAL;
1142     }
1143 
1144     client = (bt_mesh_generic_client_t *)model->user_data;
1145     if (!client) {
1146         BT_ERR("No Generic client context provided");
1147         return -EINVAL;
1148     }
1149 
1150     if (!client->internal_data) {
1151         internal = bt_mesh_calloc(sizeof(generic_internal_data_t));
1152         if (!internal) {
1153             BT_ERR("%s, Out of memory", __func__);
1154             return -ENOMEM;
1155         }
1156 
1157         sys_slist_init(&internal->queue);
1158 
1159         client->model = model;
1160         client->op_pair_size = ARRAY_SIZE(gen_op_pair);
1161         client->op_pair = gen_op_pair;
1162         client->internal_data = internal;
1163     } else {
1164         bt_mesh_client_clear_list(client->internal_data);
1165     }
1166 
1167     bt_mesh_generic_client_mutex_new();
1168 
1169     return 0;
1170 }
1171 
1172 #if CONFIG_BLE_MESH_DEINIT
generic_client_deinit(struct bt_mesh_model * model)1173 static int generic_client_deinit(struct bt_mesh_model *model)
1174 {
1175     bt_mesh_generic_client_t *client = NULL;
1176 
1177     if (!model) {
1178         BT_ERR("Invalid Generic client model");
1179         return -EINVAL;
1180     }
1181 
1182     client = (bt_mesh_generic_client_t *)model->user_data;
1183     if (!client) {
1184         BT_ERR("No Generic client context provided");
1185         return -EINVAL;
1186     }
1187 
1188     if (client->internal_data) {
1189         /* Remove items from the list */
1190         bt_mesh_client_clear_list(client->internal_data);
1191 
1192         /* Free the allocated internal data */
1193         bt_mesh_free(client->internal_data);
1194         client->internal_data = NULL;
1195     }
1196 
1197     bt_mesh_generic_client_mutex_free();
1198 
1199     return 0;
1200 }
1201 #endif /* CONFIG_BLE_MESH_DEINIT */
1202 
1203 const struct bt_mesh_model_cb bt_mesh_generic_client_cb = {
1204     .init = generic_client_init,
1205 #if CONFIG_BLE_MESH_DEINIT
1206     .deinit = generic_client_deinit,
1207 #endif /* CONFIG_BLE_MESH_DEINIT */
1208 };
1209 
1210 #endif /* CONFIG_BLE_MESH_GENERIC_CLIENT */
1211