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_lighting_model.h"
11 
12 #include "mesh_config.h"
13 #include "model_opcode.h"
14 
15 #if CONFIG_BLE_MESH_LIGHTING_CLIENT
16 #include "lighting_client.h"
17 
18 /* The followings are the macro definitions of Lighting client
19  * model message length, and a message is composed of 3 parts:
20  * Opcode + Payload + MIC
21  */
22 /* Light lightness client messages length */
23 #define BLE_MESH_LIGHT_LIGHTNESS_GET_MSG_LEN              (2 + 0 + 4)
24 #define BLE_MESH_LIGHT_LIGHTNESS_SET_MSG_LEN              (2 + 5 + 4)
25 #define BLE_MESH_LIGHT_LIGHTNESS_LINEAR_GET_MSG_LEN       (2 + 0 + 4)
26 #define BLE_MESH_LIGHT_LIGHTNESS_LINEAR_SET_MSG_LEN       (2 + 5 + 4)
27 #define BLE_MESH_LIGHT_LIGHTNESS_LAST_GET_MSG_LEN         (2 + 0 + 4)
28 #define BLE_MESH_LIGHT_LIGHTNESS_DEFAULT_GET_MSG_LEN      (2 + 0 + 4)
29 #define BLE_MESH_LIGHT_LIGHTNESS_DEFAULT_SET_MSG_LEN      (2 + 2 + 4)
30 #define BLE_MESH_LIGHT_LIGHTNESS_RANGE_GET_MSG_LEN        (2 + 0 + 4)
31 #define BLE_MESH_LIGHT_LIGHTNESS_RANGE_SET_MSG_LEN        (2 + 4 + 4)
32 
33 /* Light CTL client messages length */
34 #define BLE_MESH_LIGHT_CTL_GET_MSG_LEN                    (2 + 0 + 4)
35 #define BLE_MESH_LIGHT_CTL_SET_MSG_LEN                    (2 + 9 + 4)
36 #define BLE_MESH_LIGHT_CTL_TEMPERATURE_GET_MSG_LEN        (2 + 0 + 4)
37 #define BLE_MESH_LIGHT_CTL_TEMPERATURE_SET_MSG_LEN        (2 + 7 + 4)
38 #define BLE_MESH_LIGHT_CTL_TEMPERATURE_RANGE_GET_MSG_LEN  (2 + 0 + 4)
39 #define BLE_MESH_LIGHT_CTL_TEMPERATURE_RANGE_SET_MSG_LEN  (2 + 4 + 4)
40 #define BLE_MESH_LIGHT_CTL_DEFAULT_GET_MSG_LEN            (2 + 0 + 4)
41 #define BLE_MESH_LIGHT_CTL_DEFAULT_SET_MSG_LEN            (2 + 6 + 4)
42 
43 /* Light HSL client messages length */
44 #define BLE_MESH_LIGHT_HSL_GET_MSG_LEN                    (2 + 0 + 4)
45 #define BLE_MESH_LIGHT_HSL_SET_MSG_LEN                    (2 + 9 + 4)
46 #define BLE_MESH_LIGHT_HSL_TARGET_GET_MSG_LEN             (2 + 0 + 4)
47 #define BLE_MESH_LIGHT_HSL_HUE_GET_MSG_LEN                (2 + 0 + 4)
48 #define BLE_MESH_LIGHT_HSL_HUE_SET_MSG_LEN                (2 + 5 + 4)
49 #define BLE_MESH_LIGHT_HSL_SATURATION_GET_MSG_LEN         (2 + 0 + 4)
50 #define BLE_MESH_LIGHT_HSL_SATURATION_SET_MSG_LEN         (2 + 5 + 4)
51 #define BLE_MESH_LIGHT_HSL_DEFAULT_GET_MSG_LEN            (2 + 0 + 4)
52 #define BLE_MESH_LIGHT_HSL_DEFAULT_SET_MSG_LEN            (2 + 6 + 4)
53 #define BLE_MESH_LIGHT_HSL_RANGE_GET_MSG_LEN              (2 + 0 + 4)
54 #define BLE_MESH_LIGHT_HSL_RANGE_SET_MSG_LEN              (2 + 8 + 4)
55 
56 /* Light xyL client messages length */
57 #define BLE_MESH_LIGHT_XYL_SET_MSG_LEN                    (2 + 9 + 4)
58 #define BLE_MESH_LIGHT_XYL_DEFAULT_SET_MSG_LEN            (2 + 6 + 4)
59 #define BLE_MESH_LIGHT_XYL_RANGE_SET_MSG_LEN              (2 + 8 + 4)
60 
61 /* Light LC client messages length */
62 #define BLE_MESH_LIGHT_LC_MODE_SET_MSG_LEN                (2 + 1 + 4)
63 #define BLE_MESH_LIGHT_LC_OM_SET_MSG_LEN                  (2 + 1 + 4)
64 #define BLE_MESH_LIGHT_LC_LIGHT_ONOFF_SET_MSG_LEN         (2 + 4 + 4)
65 #define BLE_MESH_LIGHT_LC_PROPERTY_GET_MSG_LEN            (2 + 2 + 4)
66 #define BLE_MESH_LIGHT_LC_PROPERTY_SET_MSG_LEN            /* variable */
67 
68 #define BLE_MESH_LIGHT_GET_STATE_MSG_LEN                  (2 + 2 + 4)
69 
70 static const bt_mesh_client_op_pair_t light_op_pair[] = {
71     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET,             BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS             },
72     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET,             BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS             },
73     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET,      BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS      },
74     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET,      BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS      },
75     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET,        BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS        },
76     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET,     BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS     },
77     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET,     BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS     },
78     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET,       BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS       },
79     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET,       BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS       },
80     { BLE_MESH_MODEL_OP_LIGHT_CTL_GET,                   BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS                   },
81     { BLE_MESH_MODEL_OP_LIGHT_CTL_SET,                   BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS                   },
82     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET,       BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS       },
83     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET,       BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS       },
84     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS },
85     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS },
86     { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET,           BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS           },
87     { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET,           BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS           },
88     { BLE_MESH_MODEL_OP_LIGHT_HSL_GET,                   BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS                   },
89     { BLE_MESH_MODEL_OP_LIGHT_HSL_SET,                   BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS                   },
90     { BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET,            BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS            },
91     { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET,               BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS               },
92     { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET,               BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS               },
93     { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET,        BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS        },
94     { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET,        BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS        },
95     { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET,           BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS           },
96     { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET,           BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS           },
97     { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET,             BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS             },
98     { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET,             BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS             },
99     { BLE_MESH_MODEL_OP_LIGHT_XYL_GET,                   BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS                   },
100     { BLE_MESH_MODEL_OP_LIGHT_XYL_SET,                   BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS                   },
101     { BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET,            BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS            },
102     { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET,           BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS           },
103     { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET,           BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS           },
104     { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET,             BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS             },
105     { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET,             BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS             },
106     { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET,               BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS               },
107     { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET,               BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS               },
108     { BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET,                 BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS                 },
109     { BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET,                 BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS                 },
110     { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET,        BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS        },
111     { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET,        BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS        },
112     { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET,           BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS           },
113     { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET,           BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS           },
114 };
115 
116 static bt_mesh_mutex_t light_client_lock;
117 
bt_mesh_light_client_mutex_new(void)118 static void bt_mesh_light_client_mutex_new(void)
119 {
120     if (!light_client_lock.mutex) {
121         bt_mesh_mutex_create(&light_client_lock);
122     }
123 }
124 
125 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_light_client_mutex_free(void)126 static void bt_mesh_light_client_mutex_free(void)
127 {
128     bt_mesh_mutex_free(&light_client_lock);
129 }
130 #endif /* CONFIG_BLE_MESH_DEINIT */
131 
bt_mesh_light_client_lock(void)132 static void bt_mesh_light_client_lock(void)
133 {
134     bt_mesh_mutex_lock(&light_client_lock);
135 }
136 
bt_mesh_light_client_unlock(void)137 static void bt_mesh_light_client_unlock(void)
138 {
139     bt_mesh_mutex_unlock(&light_client_lock);
140 }
141 
timeout_handler(struct k_work * work)142 static void timeout_handler(struct k_work *work)
143 {
144     struct k_delayed_work *timer = NULL;
145     bt_mesh_client_node_t *node = NULL;
146     struct bt_mesh_msg_ctx ctx = {0};
147     uint32_t opcode = 0U;
148 
149     BT_WARN("Receive light status message timeout");
150 
151     bt_mesh_light_client_lock();
152 
153     timer = CONTAINER_OF(work, struct k_delayed_work, work);
154 
155     if (timer && !k_delayed_work_free(timer)) {
156         node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
157         if (node) {
158             memcpy(&ctx, &node->ctx, sizeof(ctx));
159             opcode = node->opcode;
160             bt_mesh_client_free_node(node);
161             bt_mesh_lighting_client_cb_evt_to_btc(
162                 opcode, BTC_BLE_MESH_EVT_LIGHTING_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0);
163         }
164     }
165 
166     bt_mesh_light_client_unlock();
167 
168     return;
169 }
170 
light_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)171 static void light_status(struct bt_mesh_model *model,
172                          struct bt_mesh_msg_ctx *ctx,
173                          struct net_buf_simple *buf)
174 {
175     bt_mesh_client_node_t *node = NULL;
176     uint8_t *val = NULL;
177     uint8_t evt = 0xFF;
178     size_t len = 0U;
179 
180     BT_DBG("len %d, bytes %s", buf->len, bt_hex(buf->data, buf->len));
181 
182     switch (ctx->recv_op) {
183     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS: {
184         struct bt_mesh_light_lightness_status *status = NULL;
185         if (buf->len != 2 && buf->len != 5) {
186             BT_ERR("Invalid Light Lightness Status length %d", buf->len);
187             return;
188         }
189         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_status));
190         if (!status) {
191             BT_ERR("%s, Out of memory", __func__);
192             return;
193         }
194         status->present_lightness = net_buf_simple_pull_le16(buf);
195         if (buf->len) {
196             status->op_en = true;
197             status->target_lightness = net_buf_simple_pull_le16(buf);
198             status->remain_time = net_buf_simple_pull_u8(buf);
199         }
200         val = (uint8_t *)status;
201         len = sizeof(struct bt_mesh_light_lightness_status);
202         break;
203     }
204     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS: {
205         struct bt_mesh_light_lightness_linear_status *status = NULL;
206         if (buf->len != 2 && buf->len != 5) {
207             BT_ERR("Invalid Light Lightness Linear Status length %d", buf->len);
208             return;
209         }
210         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_linear_status));
211         if (!status) {
212             BT_ERR("%s, Out of memory", __func__);
213             return;
214         }
215         status->present_lightness = net_buf_simple_pull_le16(buf);
216         if (buf->len) {
217             status->op_en = true;
218             status->target_lightness = net_buf_simple_pull_le16(buf);
219             status->remain_time = net_buf_simple_pull_u8(buf);
220         }
221         val = (uint8_t *)status;
222         len = sizeof(struct bt_mesh_light_lightness_linear_status);
223         break;
224     }
225     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS: {
226         struct bt_mesh_light_lightness_last_status *status = NULL;
227         if (buf->len != 2) {
228             BT_ERR("Invalid Light Lightness Last Status length %d", buf->len);
229             return;
230         }
231         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_last_status));
232         if (!status) {
233             BT_ERR("%s, Out of memory", __func__);
234             return;
235         }
236         status->lightness = net_buf_simple_pull_le16(buf);
237         val = (uint8_t *)status;
238         len = sizeof(struct bt_mesh_light_lightness_last_status);
239         break;
240     }
241     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS: {
242         struct bt_mesh_light_lightness_default_status *status = NULL;
243         if (buf->len != 2) {
244             BT_ERR("Invalid Light Lightness Default Status length %d", buf->len);
245             return;
246         }
247         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_default_status));
248         if (!status) {
249             BT_ERR("%s, Out of memory", __func__);
250             return;
251         }
252         status->lightness = net_buf_simple_pull_le16(buf);
253         val = (uint8_t *)status;
254         len = sizeof(struct bt_mesh_light_lightness_default_status);
255         break;
256     }
257     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS: {
258         struct bt_mesh_light_lightness_range_status *status = NULL;
259         if (buf->len != 5) {
260             BT_ERR("Invalid Light Lightness Range Status length %d", buf->len);
261             return;
262         }
263         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_range_status));
264         if (!status) {
265             BT_ERR("%s, Out of memory", __func__);
266             return;
267         }
268         status->status_code = net_buf_simple_pull_u8(buf);
269         status->range_min = net_buf_simple_pull_le16(buf);
270         status->range_max = net_buf_simple_pull_le16(buf);
271         val = (uint8_t *)status;
272         len = sizeof(struct bt_mesh_light_lightness_range_status);
273         break;
274     }
275     case BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS: {
276         struct bt_mesh_light_ctl_status *status = NULL;
277         if (buf->len != 4 && buf->len != 9) {
278             BT_ERR("Invalid Light CTL Status length %d", buf->len);
279             return;
280         }
281         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_status));
282         if (!status) {
283             BT_ERR("%s, Out of memory", __func__);
284             return;
285         }
286         status->present_ctl_lightness = net_buf_simple_pull_le16(buf);
287         status->present_ctl_temperature = net_buf_simple_pull_le16(buf);
288         if (buf->len) {
289             status->op_en = true;
290             status->target_ctl_lightness = net_buf_simple_pull_le16(buf);
291             status->target_ctl_temperature = net_buf_simple_pull_le16(buf);
292             status->remain_time = net_buf_simple_pull_u8(buf);
293         }
294         val = (uint8_t *)status;
295         len = sizeof(struct bt_mesh_light_ctl_status);
296         break;
297     }
298     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS: {
299         struct bt_mesh_light_ctl_temperature_status *status = NULL;
300         if (buf->len != 4 && buf->len != 9) {
301             BT_ERR("Invalid Light CTL Temperature Status length %d", buf->len);
302             return;
303         }
304         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_temperature_status));
305         if (!status) {
306             BT_ERR("%s, Out of memory", __func__);
307             return;
308         }
309         status->present_ctl_temperature = net_buf_simple_pull_le16(buf);
310         status->present_ctl_delta_uv = net_buf_simple_pull_le16(buf);
311         if (buf->len) {
312             status->op_en = true;
313             status->target_ctl_temperature = net_buf_simple_pull_le16(buf);
314             status->target_ctl_delta_uv = net_buf_simple_pull_le16(buf);
315             status->remain_time = net_buf_simple_pull_u8(buf);
316         }
317         val = (uint8_t *)status;
318         len = sizeof(struct bt_mesh_light_ctl_temperature_status);
319         break;
320     }
321     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS: {
322         struct bt_mesh_light_ctl_temperature_range_status *status = NULL;
323         if (buf->len != 5) {
324             BT_ERR("Invalid Light CTL Temperature Range Status length %d", buf->len);
325             return;
326         }
327         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_temperature_range_status));
328         if (!status) {
329             BT_ERR("%s, Out of memory", __func__);
330             return;
331         }
332         status->status_code = net_buf_simple_pull_u8(buf);
333         status->range_min = net_buf_simple_pull_le16(buf);
334         status->range_max = net_buf_simple_pull_le16(buf);
335         val = (uint8_t *)status;
336         len = sizeof(struct bt_mesh_light_ctl_temperature_range_status);
337         break;
338     }
339     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS: {
340         struct bt_mesh_light_ctl_default_status *status = NULL;
341         if (buf->len != 6) {
342             BT_ERR("Invalid Light CTL Default Status length %d", buf->len);
343             return;
344         }
345         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_default_status));
346         if (!status) {
347             BT_ERR("%s, Out of memory", __func__);
348             return;
349         }
350         status->lightness = net_buf_simple_pull_le16(buf);
351         status->temperature = net_buf_simple_pull_le16(buf);
352         status->delta_uv = net_buf_simple_pull_le16(buf);
353         val = (uint8_t *)status;
354         len = sizeof(struct bt_mesh_light_ctl_default_status);
355         break;
356     }
357     case BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS: {
358         struct bt_mesh_light_hsl_status *status = NULL;
359         if (buf->len != 6 && buf->len != 7) {
360             BT_ERR("Invalid Light HSL Status length %d", buf->len);
361             return;
362         }
363         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_status));
364         if (!status) {
365             BT_ERR("%s, Out of memory", __func__);
366             return;
367         }
368         status->hsl_lightness = net_buf_simple_pull_le16(buf);
369         status->hsl_hue = net_buf_simple_pull_le16(buf);
370         status->hsl_saturation = net_buf_simple_pull_le16(buf);
371         if (buf->len) {
372             status->op_en = true;
373             status->remain_time = net_buf_simple_pull_u8(buf);
374         }
375         val = (uint8_t *)status;
376         len = sizeof(struct bt_mesh_light_hsl_status);
377         break;
378     }
379     case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS: {
380         struct bt_mesh_light_hsl_target_status *status = NULL;
381         if (buf->len != 6 && buf->len != 7) {
382             BT_ERR("Invalid Light HSL Target Status length %d", buf->len);
383             return;
384         }
385         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_target_status));
386         if (!status) {
387             BT_ERR("%s, Out of memory", __func__);
388             return;
389         }
390         status->hsl_lightness_target = net_buf_simple_pull_le16(buf);
391         status->hsl_hue_target = net_buf_simple_pull_le16(buf);
392         status->hsl_saturation_target = net_buf_simple_pull_le16(buf);
393         if (buf->len) {
394             status->op_en = true;
395             status->remain_time = net_buf_simple_pull_u8(buf);
396         }
397         val = (uint8_t *)status;
398         len = sizeof(struct bt_mesh_light_hsl_target_status);
399         break;
400     }
401     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS: {
402         struct bt_mesh_light_hsl_hue_status *status = NULL;
403         if (buf->len != 2 && buf->len != 5) {
404             BT_ERR("Invalid Light HSL Hue Status length %d", buf->len);
405             return;
406         }
407         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_hue_status));
408         if (!status) {
409             BT_ERR("%s, Out of memory", __func__);
410             return;
411         }
412         status->present_hue = net_buf_simple_pull_le16(buf);
413         if (buf->len) {
414             status->op_en = true;
415             status->target_hue = net_buf_simple_pull_le16(buf);
416             status->remain_time = net_buf_simple_pull_u8(buf);
417         }
418         val = (uint8_t *)status;
419         len = sizeof(struct bt_mesh_light_hsl_hue_status);
420         break;
421     }
422     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS: {
423         struct bt_mesh_light_hsl_saturation_status *status = NULL;
424         if (buf->len != 2 && buf->len != 5) {
425             BT_ERR("Invalid Light HSL Saturation Status length %d", buf->len);
426             return;
427         }
428         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_saturation_status));
429         if (!status) {
430             BT_ERR("%s, Out of memory", __func__);
431             return;
432         }
433         status->present_saturation = net_buf_simple_pull_le16(buf);
434         if (buf->len) {
435             status->op_en = true;
436             status->target_saturation = net_buf_simple_pull_le16(buf);
437             status->remain_time = net_buf_simple_pull_u8(buf);
438         }
439         val = (uint8_t *)status;
440         len = sizeof(struct bt_mesh_light_hsl_saturation_status);
441         break;
442     }
443     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS: {
444         struct bt_mesh_light_hsl_default_status *status = NULL;
445         if (buf->len != 6) {
446             BT_ERR("Invalid Light HSL Default Status length %d", buf->len);
447             return;
448         }
449         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_default_status));
450         if (!status) {
451             BT_ERR("%s, Out of memory", __func__);
452             return;
453         }
454         status->lightness = net_buf_simple_pull_le16(buf);
455         status->hue = net_buf_simple_pull_le16(buf);
456         status->saturation = net_buf_simple_pull_le16(buf);
457         val = (uint8_t *)status;
458         len = sizeof(struct bt_mesh_light_hsl_default_status);
459         break;
460     }
461     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS: {
462         struct bt_mesh_light_hsl_range_status *status = NULL;
463         if (buf->len != 9) {
464             BT_ERR("Invalid Light HSL Range Status length %d", buf->len);
465             return;
466         }
467         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_range_status));
468         if (!status) {
469             BT_ERR("%s, Out of memory", __func__);
470             return;
471         }
472         status->status_code = net_buf_simple_pull_u8(buf);
473         status->hue_range_min = net_buf_simple_pull_le16(buf);
474         status->hue_range_max = net_buf_simple_pull_le16(buf);
475         status->saturation_range_min = net_buf_simple_pull_le16(buf);
476         status->saturation_range_max = net_buf_simple_pull_le16(buf);
477         val = (uint8_t *)status;
478         len = sizeof(struct bt_mesh_light_hsl_range_status);
479         break;
480     }
481     case BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS: {
482         struct bt_mesh_light_xyl_status *status = NULL;
483         if (buf->len != 6 && buf->len != 7) {
484             BT_ERR("Invalid Light xyL Status length %d", buf->len);
485             return;
486         }
487         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_status));
488         if (!status) {
489             BT_ERR("%s, Out of memory", __func__);
490             return;
491         }
492         status->xyl_lightness = net_buf_simple_pull_le16(buf);
493         status->xyl_x = net_buf_simple_pull_le16(buf);
494         status->xyl_y = net_buf_simple_pull_le16(buf);
495         if (buf->len) {
496             status->op_en = true;
497             status->remain_time = net_buf_simple_pull_u8(buf);
498         }
499         val = (uint8_t *)status;
500         len = sizeof(struct bt_mesh_light_xyl_status);
501         break;
502     }
503     case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS: {
504         struct bt_mesh_light_xyl_target_status *status = NULL;
505         if (buf->len != 6 && buf->len != 7) {
506             BT_ERR("Invalid Light xyL Target Status length %d", buf->len);
507             return;
508         }
509         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_target_status));
510         if (!status) {
511             BT_ERR("%s, Out of memory", __func__);
512             return;
513         }
514         status->target_xyl_lightness = net_buf_simple_pull_le16(buf);
515         status->target_xyl_x = net_buf_simple_pull_le16(buf);
516         status->target_xyl_y = net_buf_simple_pull_le16(buf);
517         if (buf->len) {
518             status->op_en = true;
519             status->remain_time = net_buf_simple_pull_u8(buf);
520         }
521         val = (uint8_t *)status;
522         len = sizeof(struct bt_mesh_light_xyl_target_status);
523         break;
524     }
525     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS: {
526         struct bt_mesh_light_xyl_default_status *status = NULL;
527         if (buf->len != 6) {
528             BT_ERR("Invalid Light xyL Default Status length %d", buf->len);
529             return;
530         }
531         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_default_status));
532         if (!status) {
533             BT_ERR("%s, Out of memory", __func__);
534             return;
535         }
536         status->lightness = net_buf_simple_pull_le16(buf);
537         status->xyl_x = net_buf_simple_pull_le16(buf);
538         status->xyl_y = net_buf_simple_pull_le16(buf);
539         val = (uint8_t *)status;
540         len = sizeof(struct bt_mesh_light_xyl_default_status);
541         break;
542     }
543     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS: {
544         struct bt_mesh_light_xyl_range_status *status = NULL;
545         if (buf->len != 9) {
546             BT_ERR("Invalid Light xyL Range Status length %d", buf->len);
547             return;
548         }
549         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_range_status));
550         if (!status) {
551             BT_ERR("%s, Out of memory", __func__);
552             return;
553         }
554         status->status_code = net_buf_simple_pull_u8(buf);
555         status->xyl_x_range_min = net_buf_simple_pull_le16(buf);
556         status->xyl_x_range_max = net_buf_simple_pull_le16(buf);
557         status->xyl_y_range_min = net_buf_simple_pull_le16(buf);
558         status->xyl_y_range_max = net_buf_simple_pull_le16(buf);
559         val = (uint8_t *)status;
560         len = sizeof(struct bt_mesh_light_xyl_range_status);
561         break;
562     }
563     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS: {
564         struct bt_mesh_light_lc_mode_status *status = NULL;
565         if (buf->len != 1) {
566             BT_ERR("Invalid Light LC Mode Status length %d", buf->len);
567             return;
568         }
569         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_mode_status));
570         if (!status) {
571             BT_ERR("%s, Out of memory", __func__);
572             return;
573         }
574         status->mode = net_buf_simple_pull_u8(buf);
575         val = (uint8_t *)status;
576         len = sizeof(struct bt_mesh_light_lc_mode_status);
577         break;
578     }
579     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS: {
580         struct bt_mesh_light_lc_om_status *status = NULL;
581         if (buf->len != 1) {
582             BT_ERR("Invalid Light LC OM Status length %d", buf->len);
583             return;
584         }
585         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_om_status));
586         if (!status) {
587             BT_ERR("%s, Out of memory", __func__);
588             return;
589         }
590         status->mode = net_buf_simple_pull_u8(buf);
591         val = (uint8_t *)status;
592         len = sizeof(struct bt_mesh_light_lc_om_status);
593         break;
594     }
595     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS: {
596         struct bt_mesh_light_lc_light_onoff_status *status = NULL;
597         if (buf->len != 1 && buf->len != 3) {
598             BT_ERR("Invalid Light LC Light OnOff Status length %d", buf->len);
599             return;
600         }
601         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_light_onoff_status));
602         if (!status) {
603             BT_ERR("%s, Out of memory", __func__);
604             return;
605         }
606         status->present_light_onoff = net_buf_simple_pull_u8(buf);
607         if (buf->len) {
608             status->op_en = true;
609             status->target_light_onoff = net_buf_simple_pull_u8(buf);
610             status->remain_time = net_buf_simple_pull_u8(buf);
611         }
612         val = (uint8_t *)status;
613         len = sizeof(struct bt_mesh_light_lc_light_onoff_status);
614         break;
615     }
616     case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS: {
617         struct bt_mesh_light_lc_property_status *status = NULL;
618         status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_property_status));
619         if (!status) {
620             BT_ERR("%s, Out of memory", __func__);
621             return;
622         }
623         status->light_lc_property_id = net_buf_simple_pull_le16(buf);
624         status->light_lc_property_value = bt_mesh_alloc_buf(buf->len);
625         if (!status->light_lc_property_value) {
626             BT_ERR("%s, Out of memory", __func__);
627             bt_mesh_free(status);
628             return;
629         }
630         net_buf_simple_add_mem(status->light_lc_property_value, buf->data, buf->len);
631         val = (uint8_t *)status;
632         len = sizeof(struct bt_mesh_light_lc_property_status);
633         break;
634     }
635     default:
636         BT_ERR("Invalid Lighting Status opcode 0x%04x", ctx->recv_op);
637         return;
638     }
639 
640     buf->data = val;
641     buf->len  = len;
642 
643     bt_mesh_light_client_lock();
644 
645     node = bt_mesh_is_client_recv_publish_msg(model, ctx, buf, true);
646     if (!node) {
647         BT_DBG("Unexpected Lighting Status 0x%04x", ctx->recv_op);
648     } else {
649         switch (node->opcode) {
650         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET:
651         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET:
652         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET:
653         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET:
654         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET:
655         case BLE_MESH_MODEL_OP_LIGHT_CTL_GET:
656         case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET:
657         case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET:
658         case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET:
659         case BLE_MESH_MODEL_OP_LIGHT_HSL_GET:
660         case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET:
661         case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET:
662         case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET:
663         case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET:
664         case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET:
665         case BLE_MESH_MODEL_OP_LIGHT_XYL_GET:
666         case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET:
667         case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET:
668         case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET:
669         case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET:
670         case BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET:
671         case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET:
672         case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET:
673             evt = BTC_BLE_MESH_EVT_LIGHTING_CLIENT_GET_STATE;
674             break;
675         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET:
676         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET:
677         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET:
678         case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET:
679         case BLE_MESH_MODEL_OP_LIGHT_CTL_SET:
680         case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET:
681         case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET:
682         case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET:
683         case BLE_MESH_MODEL_OP_LIGHT_HSL_SET:
684         case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET:
685         case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET:
686         case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET:
687         case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET:
688         case BLE_MESH_MODEL_OP_LIGHT_XYL_SET:
689         case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET:
690         case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET:
691         case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET:
692         case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET:
693         case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET:
694         case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
695             evt = BTC_BLE_MESH_EVT_LIGHTING_CLIENT_SET_STATE;
696             break;
697         default:
698             break;
699         }
700 
701         if (!k_delayed_work_free(&node->timer)) {
702             uint32_t opcode = node->opcode;
703             bt_mesh_client_free_node(node);
704             bt_mesh_lighting_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len);
705         }
706     }
707 
708     bt_mesh_light_client_unlock();
709 
710     switch (ctx->recv_op) {
711     case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS: {
712         struct bt_mesh_light_lc_property_status *status;
713         status = (struct bt_mesh_light_lc_property_status *)val;
714         bt_mesh_free_buf(status->light_lc_property_value);
715         break;
716     }
717     default:
718         break;
719     }
720 
721     bt_mesh_free(val);
722 
723     return;
724 }
725 
726 const struct bt_mesh_model_op bt_mesh_light_lightness_cli_op[] = {
727     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS,         2, light_status },
728     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS,  2, light_status },
729     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS,    2, light_status },
730     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS, 2, light_status },
731     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS,   5, light_status },
732     BLE_MESH_MODEL_OP_END,
733 };
734 
735 const struct bt_mesh_model_op bt_mesh_light_ctl_cli_op[] = {
736     { BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS,                   4, light_status },
737     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS,       4, light_status },
738     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS, 5, light_status },
739     { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS,           6, light_status },
740     BLE_MESH_MODEL_OP_END,
741 };
742 
743 const struct bt_mesh_model_op bt_mesh_light_hsl_cli_op[] = {
744     { BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS,            6, light_status },
745     { BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS,     6, light_status },
746     { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS,        2, light_status },
747     { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS, 2, light_status },
748     { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS,    6, light_status },
749     { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS,      9, light_status },
750     BLE_MESH_MODEL_OP_END,
751 };
752 
753 const struct bt_mesh_model_op bt_mesh_light_xyl_cli_op[] = {
754     { BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS,         6, light_status },
755     { BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS,  6, light_status },
756     { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS, 6, light_status },
757     { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS,   9, light_status },
758     BLE_MESH_MODEL_OP_END,
759 };
760 
761 const struct bt_mesh_model_op bt_mesh_light_lc_cli_op[] = {
762     { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS,        1, light_status },
763     { BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS,          1, light_status },
764     { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS, 1, light_status },
765     { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS,    2, light_status },
766     BLE_MESH_MODEL_OP_END,
767 };
768 
light_get_state(bt_mesh_client_common_param_t * common,void * value)769 static int light_get_state(bt_mesh_client_common_param_t *common, void *value)
770 {
771     NET_BUF_SIMPLE_DEFINE(msg, BLE_MESH_LIGHT_GET_STATE_MSG_LEN);
772 
773     bt_mesh_model_msg_init(&msg, common->opcode);
774 
775     if (value) {
776         switch (common->opcode) {
777         case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET: {
778             struct bt_mesh_light_lc_property_get *get;
779             get = (struct bt_mesh_light_lc_property_get *)value;
780             net_buf_simple_add_le16(&msg, get->light_lc_property_id);
781             break;
782         }
783         default:
784             BT_DBG("No parameters for Lighting Get 0x%04x", common->opcode);
785             break;
786         }
787     }
788 
789     return bt_mesh_client_send_msg(common, &msg, true, timeout_handler);
790 }
791 
light_set_state(bt_mesh_client_common_param_t * common,void * value,uint16_t value_len,bool need_ack)792 static int light_set_state(bt_mesh_client_common_param_t *common,
793                            void *value, uint16_t value_len, bool need_ack)
794 {
795     struct net_buf_simple *msg = NULL;
796     int err = 0;
797 
798     msg = bt_mesh_alloc_buf(value_len);
799     if (!msg) {
800         BT_ERR("%s, Out of memory", __func__);
801         return -ENOMEM;
802     }
803 
804     bt_mesh_model_msg_init(msg, common->opcode);
805 
806     switch (common->opcode) {
807     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET:
808     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK: {
809         struct bt_mesh_light_lightness_set *set;
810         set = (struct bt_mesh_light_lightness_set *)value;
811         net_buf_simple_add_le16(msg, set->lightness);
812         net_buf_simple_add_u8(msg,   set->tid);
813         if (set->op_en) {
814             net_buf_simple_add_u8(msg, set->trans_time);
815             net_buf_simple_add_u8(msg, set->delay);
816         }
817         break;
818     }
819     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET:
820     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK: {
821         struct bt_mesh_light_lightness_linear_set *set;
822         set = (struct bt_mesh_light_lightness_linear_set *)value;
823         net_buf_simple_add_le16(msg, set->lightness);
824         net_buf_simple_add_u8(msg,   set->tid);
825         if (set->op_en) {
826             net_buf_simple_add_u8(msg, set->trans_time);
827             net_buf_simple_add_u8(msg, set->delay);
828         }
829         break;
830     }
831     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET:
832     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK: {
833         struct bt_mesh_light_lightness_default_set *set;
834         set = (struct bt_mesh_light_lightness_default_set *)value;
835         net_buf_simple_add_le16(msg, set->lightness);
836         break;
837     }
838     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET:
839     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK: {
840         struct bt_mesh_light_lightness_range_set *set;
841         set = (struct bt_mesh_light_lightness_range_set *)value;
842         net_buf_simple_add_le16(msg, set->range_min);
843         net_buf_simple_add_le16(msg, set->range_max);
844         break;
845     }
846     case BLE_MESH_MODEL_OP_LIGHT_CTL_SET:
847     case BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK: {
848         struct bt_mesh_light_ctl_set *set;
849         set = (struct bt_mesh_light_ctl_set *)value;
850         net_buf_simple_add_le16(msg, set->ctl_lightness);
851         net_buf_simple_add_le16(msg, set->ctl_temperature);
852         net_buf_simple_add_le16(msg, set->ctl_delta_uv);
853         net_buf_simple_add_u8(msg,   set->tid);
854         if (set->op_en) {
855             net_buf_simple_add_u8(msg, set->trans_time);
856             net_buf_simple_add_u8(msg, set->delay);
857         }
858         break;
859     }
860     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET:
861     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK: {
862         struct bt_mesh_light_ctl_temperature_set *set;
863         set = (struct bt_mesh_light_ctl_temperature_set *)value;
864         net_buf_simple_add_le16(msg, set->ctl_temperature);
865         net_buf_simple_add_le16(msg, set->ctl_delta_uv);
866         net_buf_simple_add_u8(msg,   set->tid);
867         if (set->op_en) {
868             net_buf_simple_add_u8(msg, set->trans_time);
869             net_buf_simple_add_u8(msg, set->delay);
870         }
871         break;
872     }
873     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET:
874     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK: {
875         struct bt_mesh_light_ctl_temperature_range_set *set;
876         set = (struct bt_mesh_light_ctl_temperature_range_set *)value;
877         net_buf_simple_add_le16(msg, set->range_min);
878         net_buf_simple_add_le16(msg, set->range_max);
879         break;
880     }
881     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET:
882     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK: {
883         struct bt_mesh_light_ctl_default_set *set;
884         set = (struct bt_mesh_light_ctl_default_set *)value;
885         net_buf_simple_add_le16(msg, set->lightness);
886         net_buf_simple_add_le16(msg, set->temperature);
887         net_buf_simple_add_le16(msg, set->delta_uv);
888         break;
889     }
890     case BLE_MESH_MODEL_OP_LIGHT_HSL_SET:
891     case BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK: {
892         struct bt_mesh_light_hsl_set *set;
893         set = (struct bt_mesh_light_hsl_set *)value;
894         net_buf_simple_add_le16(msg, set->hsl_lightness);
895         net_buf_simple_add_le16(msg, set->hsl_hue);
896         net_buf_simple_add_le16(msg, set->hsl_saturation);
897         net_buf_simple_add_u8(msg,   set->tid);
898         if (set->op_en) {
899             net_buf_simple_add_u8(msg, set->trans_time);
900             net_buf_simple_add_u8(msg, set->delay);
901         }
902         break;
903     }
904     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET:
905     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK: {
906         struct bt_mesh_light_hsl_hue_set *set;
907         set = (struct bt_mesh_light_hsl_hue_set *)value;
908         net_buf_simple_add_le16(msg, set->hue);
909         net_buf_simple_add_u8(msg,   set->tid);
910         if (set->op_en) {
911             net_buf_simple_add_u8(msg, set->trans_time);
912             net_buf_simple_add_u8(msg, set->delay);
913         }
914         break;
915     }
916     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET:
917     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK: {
918         struct bt_mesh_light_hsl_saturation_set *set;
919         set = (struct bt_mesh_light_hsl_saturation_set *)value;
920         net_buf_simple_add_le16(msg, set->saturation);
921         net_buf_simple_add_u8(msg,   set->tid);
922         if (set->op_en) {
923             net_buf_simple_add_u8(msg, set->trans_time);
924             net_buf_simple_add_u8(msg, set->delay);
925         }
926         break;
927     }
928     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET:
929     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK: {
930         struct bt_mesh_light_hsl_default_set *set;
931         set = (struct bt_mesh_light_hsl_default_set *)value;
932         net_buf_simple_add_le16(msg, set->lightness);
933         net_buf_simple_add_le16(msg, set->hue);
934         net_buf_simple_add_le16(msg, set->saturation);
935         break;
936     }
937     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET:
938     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK: {
939         struct bt_mesh_light_hsl_range_set *set;
940         set = (struct bt_mesh_light_hsl_range_set *)value;
941         net_buf_simple_add_le16(msg, set->hue_range_min);
942         net_buf_simple_add_le16(msg, set->hue_range_max);
943         net_buf_simple_add_le16(msg, set->saturation_range_min);
944         net_buf_simple_add_le16(msg, set->saturation_range_max);
945         break;
946     }
947     case BLE_MESH_MODEL_OP_LIGHT_XYL_SET:
948     case BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK: {
949         struct bt_mesh_light_xyl_set *set;
950         set = (struct bt_mesh_light_xyl_set *)value;
951         net_buf_simple_add_le16(msg, set->xyl_lightness);
952         net_buf_simple_add_le16(msg, set->xyl_x);
953         net_buf_simple_add_le16(msg, set->xyl_y);
954         net_buf_simple_add_u8(msg, set->tid);
955         if (set->op_en) {
956             net_buf_simple_add_u8(msg, set->trans_time);
957             net_buf_simple_add_u8(msg, set->delay);
958         }
959         break;
960     }
961     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET:
962     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK: {
963         struct bt_mesh_light_xyl_default_set *set;
964         set = (struct bt_mesh_light_xyl_default_set *)value;
965         net_buf_simple_add_le16(msg, set->lightness);
966         net_buf_simple_add_le16(msg, set->xyl_x);
967         net_buf_simple_add_le16(msg, set->xyl_y);
968         break;
969     }
970     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET:
971     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK: {
972         struct bt_mesh_light_xyl_range_set *set;
973         set = (struct bt_mesh_light_xyl_range_set *)value;
974         net_buf_simple_add_le16(msg, set->xyl_x_range_min);
975         net_buf_simple_add_le16(msg, set->xyl_x_range_max);
976         net_buf_simple_add_le16(msg, set->xyl_y_range_min);
977         net_buf_simple_add_le16(msg, set->xyl_y_range_max);
978         break;
979     }
980     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET:
981     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK: {
982         struct bt_mesh_light_lc_mode_set *set;
983         set = (struct bt_mesh_light_lc_mode_set *)value;
984         net_buf_simple_add_u8(msg, set->mode);
985         break;
986     }
987     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET:
988     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK: {
989         struct bt_mesh_light_lc_om_set *set;
990         set = (struct bt_mesh_light_lc_om_set *)value;
991         net_buf_simple_add_u8(msg, set->mode);
992         break;
993     }
994     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET:
995     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK: {
996         struct bt_mesh_light_lc_light_onoff_set *set;
997         set = (struct bt_mesh_light_lc_light_onoff_set *)value;
998         net_buf_simple_add_u8(msg, set->light_onoff);
999         net_buf_simple_add_u8(msg, set->tid);
1000         if (set->op_en) {
1001             net_buf_simple_add_u8(msg, set->trans_time);
1002             net_buf_simple_add_u8(msg, set->delay);
1003         }
1004         break;
1005     }
1006     case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
1007     case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK: {
1008         struct bt_mesh_light_lc_property_set *set;
1009         set = (struct bt_mesh_light_lc_property_set *)value;
1010         net_buf_simple_add_le16(msg, set->light_lc_property_id);
1011         net_buf_simple_add_mem(msg, set->light_lc_property_value->data, set->light_lc_property_value->len);
1012         break;
1013     }
1014     default:
1015         BT_ERR("Invalid Lighting Set opcode 0x%04x", common->opcode);
1016         err = -EINVAL;
1017         goto end;
1018     }
1019 
1020     err = bt_mesh_client_send_msg(common, msg, need_ack, timeout_handler);
1021 
1022 end:
1023     bt_mesh_free_buf(msg);
1024     return err;
1025 }
1026 
bt_mesh_light_client_get_state(bt_mesh_client_common_param_t * common,void * get)1027 int bt_mesh_light_client_get_state(bt_mesh_client_common_param_t *common, void *get)
1028 {
1029     bt_mesh_light_client_t *client = NULL;
1030 
1031     if (!common || !common->model) {
1032         BT_ERR("%s, Invalid parameter", __func__);
1033         return -EINVAL;
1034     }
1035 
1036     client = (bt_mesh_light_client_t *)common->model->user_data;
1037     if (!client || !client->internal_data) {
1038         BT_ERR("Invalid Lighting client data");
1039         return -EINVAL;
1040     }
1041 
1042     switch (common->opcode) {
1043     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET:
1044     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET:
1045     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET:
1046     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET:
1047     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET:
1048     case BLE_MESH_MODEL_OP_LIGHT_CTL_GET:
1049     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET:
1050     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET:
1051     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET:
1052     case BLE_MESH_MODEL_OP_LIGHT_HSL_GET:
1053     case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET:
1054     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET:
1055     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET:
1056     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET:
1057     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET:
1058     case BLE_MESH_MODEL_OP_LIGHT_XYL_GET:
1059     case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET:
1060     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET:
1061     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET:
1062     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET:
1063     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET:
1064     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET:
1065         break;
1066     case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET:
1067         if (!get) {
1068             BT_ERR("Invalid Lighting LC Property Get");
1069             return -EINVAL;
1070         }
1071         break;
1072     default:
1073         BT_ERR("Invalid Lighting Get opcode 0x%04x", common->opcode);
1074         return -EINVAL;
1075     }
1076 
1077     return light_get_state(common, get);
1078 }
1079 
bt_mesh_light_client_set_state(bt_mesh_client_common_param_t * common,void * set)1080 int bt_mesh_light_client_set_state(bt_mesh_client_common_param_t *common, void *set)
1081 {
1082     bt_mesh_light_client_t *client = NULL;
1083     uint16_t length = 0U;
1084     bool need_ack = false;
1085 
1086     if (!common || !common->model || !set) {
1087         BT_ERR("%s, Invalid parameter", __func__);
1088         return -EINVAL;
1089     }
1090 
1091     client = (bt_mesh_light_client_t *)common->model->user_data;
1092     if (!client || !client->internal_data) {
1093         BT_ERR("Invalid Lighting client data");
1094         return -EINVAL;
1095     }
1096 
1097     switch (common->opcode) {
1098     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET:
1099         need_ack = true;
1100     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK: {
1101         struct bt_mesh_light_lightness_set *value;
1102         value = (struct bt_mesh_light_lightness_set *)set;
1103         if (value->op_en) {
1104             if ((value->trans_time & 0x3F) > 0x3E) {
1105                 BT_ERR("Invalid Light Lightness Set transition time");
1106                 return -EINVAL;
1107             }
1108         }
1109         length = BLE_MESH_LIGHT_LIGHTNESS_SET_MSG_LEN;
1110         break;
1111     }
1112     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET:
1113         need_ack = true;
1114     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK: {
1115         struct bt_mesh_light_lightness_linear_set *value;
1116         value = (struct bt_mesh_light_lightness_linear_set *)set;
1117         if (value->op_en) {
1118             if ((value->trans_time & 0x3F) > 0x3E) {
1119                 BT_ERR("Invalid Light Lightness Linear Set transition time");
1120                 return -EINVAL;
1121             }
1122         }
1123         length = BLE_MESH_LIGHT_LIGHTNESS_LINEAR_SET_MSG_LEN;
1124         break;
1125     }
1126     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET:
1127         need_ack = true;
1128     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK:
1129         length = BLE_MESH_LIGHT_LIGHTNESS_DEFAULT_SET_MSG_LEN;
1130         break;
1131     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET:
1132         need_ack = true;
1133     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK: {
1134         struct bt_mesh_light_lightness_range_set *value;
1135         value = (struct bt_mesh_light_lightness_range_set *)set;
1136         if (value->range_min > value->range_max) {
1137             BT_ERR("Light Lightness Range Set range min is greater than range max");
1138             return -EINVAL;
1139         }
1140         length = BLE_MESH_LIGHT_LIGHTNESS_RANGE_SET_MSG_LEN;
1141         break;
1142     }
1143     case BLE_MESH_MODEL_OP_LIGHT_CTL_SET:
1144         need_ack = true;
1145     case BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK: {
1146         struct bt_mesh_light_ctl_set *value;
1147         value = (struct bt_mesh_light_ctl_set *)set;
1148         if (value->op_en) {
1149             if ((value->trans_time & 0x3F) > 0x3E) {
1150                 BT_ERR("Invalid Light CTL Set transition time");
1151                 return -EINVAL;
1152             }
1153         }
1154         length = BLE_MESH_LIGHT_CTL_SET_MSG_LEN;
1155         break;
1156     }
1157     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET:
1158         need_ack = true;
1159     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK: {
1160         struct bt_mesh_light_ctl_temperature_set *value;
1161         value = (struct bt_mesh_light_ctl_temperature_set *)set;
1162         if (value->op_en) {
1163             if ((value->trans_time & 0x3F) > 0x3E) {
1164                 BT_ERR("Invalid Light CTL Temperature Set transition time");
1165                 return -EINVAL;
1166             }
1167         }
1168         length = BLE_MESH_LIGHT_CTL_TEMPERATURE_SET_MSG_LEN;
1169         break;
1170     }
1171     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET:
1172         need_ack = true;
1173     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK: {
1174         struct bt_mesh_light_ctl_temperature_range_set *value;
1175         value = (struct bt_mesh_light_ctl_temperature_range_set *)set;
1176         if (value->range_min > value->range_max) {
1177             BT_ERR("Light CTL Temperature Range Set range min is greater than range max");
1178             return -EINVAL;
1179         }
1180         length = BLE_MESH_LIGHT_CTL_TEMPERATURE_RANGE_SET_MSG_LEN;
1181         break;
1182     }
1183     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET:
1184         need_ack = true;
1185     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK:
1186         length = BLE_MESH_LIGHT_CTL_DEFAULT_SET_MSG_LEN;
1187         break;
1188     case BLE_MESH_MODEL_OP_LIGHT_HSL_SET:
1189         need_ack = true;
1190     case BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK: {
1191         struct bt_mesh_light_hsl_set *value;
1192         value = (struct bt_mesh_light_hsl_set *)set;
1193         if (value->op_en) {
1194             if ((value->trans_time & 0x3F) > 0x3E) {
1195                 BT_ERR("Invalid Light HSL Set transition time");
1196                 return -EINVAL;
1197             }
1198         }
1199         length = BLE_MESH_LIGHT_HSL_SET_MSG_LEN;
1200         break;
1201     }
1202     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET:
1203         need_ack = true;
1204     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK: {
1205         struct bt_mesh_light_hsl_hue_set *value;
1206         value = (struct bt_mesh_light_hsl_hue_set *)set;
1207         if (value->op_en) {
1208             if ((value->trans_time & 0x3F) > 0x3E) {
1209                 BT_ERR("Invalid Light HSL Hue Set transition time");
1210                 return -EINVAL;
1211             }
1212         }
1213         length = BLE_MESH_LIGHT_HSL_HUE_SET_MSG_LEN;
1214         break;
1215     }
1216     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET:
1217         need_ack = true;
1218     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK: {
1219         struct bt_mesh_light_hsl_saturation_set *value;
1220         value = (struct bt_mesh_light_hsl_saturation_set *)set;
1221         if (value->op_en) {
1222             if ((value->trans_time & 0x3F) > 0x3E) {
1223                 BT_ERR("Invalid Light HSL Saturation Set transition time");
1224                 return -EINVAL;
1225             }
1226         }
1227         length = BLE_MESH_LIGHT_HSL_SATURATION_SET_MSG_LEN;
1228         break;
1229     }
1230     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET:
1231         need_ack = true;
1232     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK:
1233         length = BLE_MESH_LIGHT_HSL_DEFAULT_SET_MSG_LEN;
1234         break;
1235     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET:
1236         need_ack = true;
1237     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK: {
1238         struct bt_mesh_light_hsl_range_set *value;
1239         value = (struct bt_mesh_light_hsl_range_set *)set;
1240         if (value->hue_range_min > value->hue_range_max ||
1241                 value->saturation_range_min > value->saturation_range_max) {
1242             BT_ERR("Light HSL Range Set range min is greater than range max");
1243             return -EINVAL;
1244         }
1245         length = BLE_MESH_LIGHT_HSL_RANGE_SET_MSG_LEN;
1246         break;
1247     }
1248     case BLE_MESH_MODEL_OP_LIGHT_XYL_SET:
1249         need_ack = true;
1250     case BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK: {
1251         struct bt_mesh_light_xyl_set *value;
1252         value = (struct bt_mesh_light_xyl_set *)set;
1253         if (value->op_en) {
1254             if ((value->trans_time & 0x3F) > 0x3E) {
1255                 BT_ERR("Invalid Light xyL Set transition time");
1256                 return -EINVAL;
1257             }
1258         }
1259         length = BLE_MESH_LIGHT_XYL_SET_MSG_LEN;
1260         break;
1261     }
1262     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET:
1263         need_ack = true;
1264     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK:
1265         length = BLE_MESH_LIGHT_XYL_DEFAULT_SET_MSG_LEN;
1266         break;
1267     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET:
1268         need_ack = true;
1269     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK: {
1270         struct bt_mesh_light_xyl_range_set *value;
1271         value = (struct bt_mesh_light_xyl_range_set *)set;
1272         if (value->xyl_x_range_min > value->xyl_x_range_max ||
1273                 value->xyl_y_range_min > value->xyl_y_range_max) {
1274             BT_ERR("Light xyL Range Set range min is greater than range max");
1275             return -EINVAL;
1276         }
1277         length = BLE_MESH_LIGHT_XYL_RANGE_SET_MSG_LEN;
1278         break;
1279     }
1280     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET:
1281         need_ack = true;
1282     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK:
1283         length = BLE_MESH_LIGHT_LC_MODE_SET_MSG_LEN;
1284         break;
1285     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET:
1286         need_ack = true;
1287     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK:
1288         length = BLE_MESH_LIGHT_LC_OM_SET_MSG_LEN;
1289         break;
1290     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET:
1291         need_ack = true;
1292     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK: {
1293         struct bt_mesh_light_lc_light_onoff_set *value;
1294         value = (struct bt_mesh_light_lc_light_onoff_set *)set;
1295         if (value->op_en) {
1296             if ((value->trans_time & 0x3F) > 0x3E) {
1297                 BT_ERR("Invalid Light LC Light OnOff Set transition time");
1298                 return -EINVAL;
1299             }
1300         }
1301         length = BLE_MESH_LIGHT_LC_LIGHT_ONOFF_SET_MSG_LEN;
1302         break;
1303     }
1304     case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
1305         need_ack = true;
1306     case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK: {
1307         struct bt_mesh_light_lc_property_set *value;
1308         value = (struct bt_mesh_light_lc_property_set *)set;
1309         if (!value->light_lc_property_value) {
1310             BT_ERR("Invalid Lighting Light LC Property value");
1311             return -EINVAL;
1312         }
1313         length = (1 + 2 + value->light_lc_property_value->len + 4);
1314         break;
1315     }
1316     default:
1317         BT_ERR("Invalid Lighting Set opcode 0x%04x", common->opcode);
1318         return -EINVAL;
1319     }
1320 
1321     return light_set_state(common, set, length, need_ack);
1322 }
1323 
lighting_client_init(struct bt_mesh_model * model)1324 static int lighting_client_init(struct bt_mesh_model *model)
1325 {
1326     light_internal_data_t *internal = NULL;
1327     bt_mesh_light_client_t *client = NULL;
1328 
1329     if (!model) {
1330         BT_ERR("Invalid Lighting client model");
1331         return -EINVAL;
1332     }
1333 
1334     client = (bt_mesh_light_client_t *)model->user_data;
1335     if (!client) {
1336         BT_ERR("No Lighting client context provided");
1337         return -EINVAL;
1338     }
1339 
1340     if (!client->internal_data) {
1341         internal = bt_mesh_calloc(sizeof(light_internal_data_t));
1342         if (!internal) {
1343             BT_ERR("%s, Out of memory", __func__);
1344             return -ENOMEM;
1345         }
1346 
1347         sys_slist_init(&internal->queue);
1348 
1349         client->model = model;
1350         client->op_pair_size = ARRAY_SIZE(light_op_pair);
1351         client->op_pair = light_op_pair;
1352         client->internal_data = internal;
1353     } else {
1354         bt_mesh_client_clear_list(client->internal_data);
1355     }
1356 
1357     bt_mesh_light_client_mutex_new();
1358 
1359     return 0;
1360 }
1361 
1362 #if CONFIG_BLE_MESH_DEINIT
lighting_client_deinit(struct bt_mesh_model * model)1363 static int lighting_client_deinit(struct bt_mesh_model *model)
1364 {
1365     bt_mesh_light_client_t *client = NULL;
1366 
1367     if (!model) {
1368         BT_ERR("Invalid Lighting client model");
1369         return -EINVAL;
1370     }
1371 
1372     client = (bt_mesh_light_client_t *)model->user_data;
1373     if (!client) {
1374         BT_ERR("No Lighting client context provided");
1375         return -EINVAL;
1376     }
1377 
1378     if (client->internal_data) {
1379         /* Remove items from the list */
1380         bt_mesh_client_clear_list(client->internal_data);
1381 
1382         /* Free the allocated internal data */
1383         bt_mesh_free(client->internal_data);
1384         client->internal_data = NULL;
1385     }
1386 
1387     bt_mesh_light_client_mutex_free();
1388 
1389     return 0;
1390 }
1391 #endif /* CONFIG_BLE_MESH_DEINIT */
1392 
1393 const struct bt_mesh_model_cb bt_mesh_lighting_client_cb = {
1394     .init = lighting_client_init,
1395 #if CONFIG_BLE_MESH_DEINIT
1396     .deinit = lighting_client_deinit,
1397 #endif /* CONFIG_BLE_MESH_DEINIT */
1398 };
1399 
1400 #endif /* CONFIG_BLE_MESH_LIGHTING_CLIENT */
1401