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