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