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