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