1 /* Bluetooth: Mesh Lighting Server Models
2  *
3  * Copyright (c) 2018 Vikrant More
4  * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <errno.h>
10 
11 #include "btc_ble_mesh_lighting_model.h"
12 
13 #include "mesh_config.h"
14 #include "access.h"
15 #include "transport.h"
16 #include "model_opcode.h"
17 #include "state_transition.h"
18 #include "device_property.h"
19 
20 #if CONFIG_BLE_MESH_LIGHTING_SERVER
21 
22 static bt_mesh_mutex_t light_server_lock;
23 
bt_mesh_light_server_mutex_new(void)24 static inline void bt_mesh_light_server_mutex_new(void)
25 {
26     if (!light_server_lock.mutex) {
27         bt_mesh_mutex_create(&light_server_lock);
28     }
29 }
30 
31 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_light_server_mutex_free(void)32 static inline void bt_mesh_light_server_mutex_free(void)
33 {
34     bt_mesh_mutex_free(&light_server_lock);
35 }
36 #endif /* CONFIG_BLE_MESH_DEINIT */
37 
bt_mesh_light_server_lock(void)38 void bt_mesh_light_server_lock(void)
39 {
40     bt_mesh_mutex_lock(&light_server_lock);
41 }
42 
bt_mesh_light_server_unlock(void)43 void bt_mesh_light_server_unlock(void)
44 {
45     bt_mesh_mutex_unlock(&light_server_lock);
46 }
47 
48 /* message handlers (Start) */
49 
50 /* Light Lightness Server/Setup Server message handlers */
51 
send_light_lightness_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)52 static void send_light_lightness_status(struct bt_mesh_model *model,
53                                         struct bt_mesh_msg_ctx *ctx,
54                                         bool publish, uint16_t opcode)
55 {
56     struct net_buf_simple *msg = NULL;
57     uint8_t length = 2 + 5;
58 
59     if (ctx == NULL && publish == false) {
60         BT_ERR("%s, Invalid parameter", __func__);
61         return;
62     }
63 
64     if (publish == false) {
65         msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
66         if (msg == NULL) {
67             BT_ERR("%s, Out of memory", __func__);
68             return;
69         }
70     } else {
71         msg = bt_mesh_server_get_pub_msg(model, length);
72         if (msg == NULL) {
73             return;
74         }
75     }
76 
77     bt_mesh_model_msg_init(msg, opcode);
78     switch (opcode) {
79     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS: {
80         struct bt_mesh_light_lightness_srv *srv = model->user_data;
81         net_buf_simple_add_le16(msg, srv->state->lightness_actual);
82         if (srv->actual_transition.counter) {
83             bt_mesh_server_calc_remain_time(&srv->actual_transition);
84             net_buf_simple_add_le16(msg, srv->state->target_lightness_actual);
85             net_buf_simple_add_u8(msg, srv->actual_transition.remain_time);
86         }
87         break;
88     }
89     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS: {
90         struct bt_mesh_light_lightness_srv *srv = model->user_data;
91         net_buf_simple_add_le16(msg, srv->state->lightness_linear);
92         if (srv->linear_transition.counter) {
93             bt_mesh_server_calc_remain_time(&srv->linear_transition);
94             net_buf_simple_add_le16(msg, srv->state->target_lightness_linear);
95             net_buf_simple_add_u8(msg, srv->linear_transition.remain_time);
96         }
97         break;
98     }
99     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS: {
100         struct bt_mesh_light_lightness_srv *srv = model->user_data;
101         net_buf_simple_add_le16(msg, srv->state->lightness_last);
102         break;
103     }
104     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS:
105         if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
106             struct bt_mesh_light_lightness_srv *srv = model->user_data;
107             net_buf_simple_add_le16(msg, srv->state->lightness_default);
108         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV) {
109             struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
110             net_buf_simple_add_le16(msg, srv->state->lightness_default);
111         }
112         break;
113     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS:
114         if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
115             struct bt_mesh_light_lightness_srv *srv = model->user_data;
116             net_buf_simple_add_u8(msg, srv->state->status_code);
117             net_buf_simple_add_le16(msg, srv->state->lightness_range_min);
118             net_buf_simple_add_le16(msg, srv->state->lightness_range_max);
119         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV) {
120             struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
121             net_buf_simple_add_u8(msg, srv->state->status_code);
122             net_buf_simple_add_le16(msg, srv->state->lightness_range_min);
123             net_buf_simple_add_le16(msg, srv->state->lightness_range_max);
124         }
125         break;
126     default:
127         BT_WARN("Unknown Light Lightness status opcode 0x%04x", opcode);
128         if (publish == false) {
129             bt_mesh_free_buf(msg);
130         }
131         return;
132     }
133 
134     if (publish == false) {
135         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
136         bt_mesh_free_buf(msg);
137     } else {
138         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
139     }
140     return;
141 }
142 
light_lightness_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)143 static void light_lightness_get(struct bt_mesh_model *model,
144                                 struct bt_mesh_msg_ctx *ctx,
145                                 struct net_buf_simple *buf)
146 {
147     struct bt_mesh_light_lightness_srv *srv = model->user_data;
148     uint16_t opcode = 0U;
149 
150     if (srv == NULL || srv->state == NULL) {
151         BT_ERR("%s, Invalid model user data", __func__);
152         return;
153     }
154 
155     /* Callback the received message to the application layer */
156     if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
157         bt_mesh_lighting_server_cb_evt_to_btc(
158             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
159         return;
160     }
161 
162     switch (ctx->recv_op) {
163     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET:
164         opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS;
165         break;
166     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET:
167         opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS;
168         break;
169     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET:
170         opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS;
171         break;
172     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET:
173         opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS;
174         break;
175     case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET:
176         opcode = BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS;
177         break;
178     default:
179         BT_WARN("Unknown Light Lightness Get opcode 0x%04x", ctx->recv_op);
180         return;
181     }
182 
183     send_light_lightness_status(model, ctx, false, opcode);
184     return;
185 }
186 
light_lightness_publish(struct bt_mesh_model * model,uint16_t opcode)187 void light_lightness_publish(struct bt_mesh_model *model, uint16_t opcode)
188 {
189     if (model->user_data == NULL) {
190         BT_ERR("%s, Invalid model user data", __func__);
191         return;
192     }
193 
194     switch (model->id) {
195     case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV: {
196         struct bt_mesh_light_lightness_srv *srv = model->user_data;
197         if (srv->state == NULL) {
198             BT_ERR("Invalid Light Lightness Server state");
199             return;
200         }
201         break;
202     }
203     case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV: {
204         struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
205         if (srv->state == NULL) {
206             BT_ERR("Invalid Light Lightness Setup Server state");
207             return;
208         }
209         break;
210     }
211     default:
212         BT_ERR("Invalid Light Lightness Server model 0x%04x", model->id);
213         return;
214     }
215 
216     send_light_lightness_status(model, NULL, true, opcode);
217     return;
218 }
219 
light_lightness_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)220 static void light_lightness_set(struct bt_mesh_model *model,
221                                 struct bt_mesh_msg_ctx *ctx,
222                                 struct net_buf_simple *buf)
223 {
224     struct bt_mesh_light_lightness_srv *srv = model->user_data;
225     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
226     bool optional = false;
227     uint16_t actual = 0U;
228     int64_t now = 0;
229 
230     if (srv == NULL || srv->state == NULL) {
231         BT_ERR("%s, Invalid model user data", __func__);
232         return;
233     }
234 
235     actual = net_buf_simple_pull_le16(buf);
236     tid = net_buf_simple_pull_u8(buf);
237 
238     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
239         return;
240     }
241 
242     /* Callback the received message to the application layer */
243     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
244         bt_mesh_light_server_recv_set_msg_t set = {
245             .lightness_set.op_en = optional,
246             .lightness_set.lightness = actual,
247             .lightness_set.tid = tid,
248             .lightness_set.trans_time = trans_time,
249             .lightness_set.delay = delay,
250         };
251         bt_mesh_lighting_server_cb_evt_to_btc(
252             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
253         return;
254     }
255 
256     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
257         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET) {
258             send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
259         }
260         send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
261         /* In this condition, no event will be callback to application layer */
262         return;
263     }
264 
265     bt_mesh_light_server_lock();
266 
267     bt_mesh_server_stop_transition(&srv->actual_transition);
268     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
269 
270     if (actual) {
271         if (srv->state->lightness_range_min && actual < srv->state->lightness_range_min) {
272             actual = srv->state->lightness_range_min;
273         } else if (srv->state->lightness_range_max && actual > srv->state->lightness_range_max) {
274             actual = srv->state->lightness_range_max;
275         }
276     }
277     srv->state->target_lightness_actual = actual;
278 
279     /**
280      * If the target state is equal to the current state, the transition shall not be
281      * started and is considered complete.
282      */
283     if (srv->state->target_lightness_actual != srv->state->lightness_actual) {
284         light_lightness_actual_tt_values(srv, trans_time, delay);
285     } else {
286         bt_mesh_light_server_state_change_t change = {
287             .lightness_set.lightness = srv->state->lightness_actual,
288         };
289         bt_mesh_lighting_server_cb_evt_to_btc(
290             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
291 
292         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET) {
293             send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
294         }
295         send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
296 
297         bt_mesh_light_server_unlock();
298         return;
299     }
300 
301     /* Copy the ctx of the received message */
302     if (srv->actual_transition.timer.work._reserved) {
303         memcpy(srv->actual_transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
304     }
305 
306     /* For Instantaneous Transition */
307     if (srv->actual_transition.counter == 0U) {
308         srv->state->lightness_actual = srv->state->target_lightness_actual;
309         /**
310          * Whenever the Light Lightness Actual state is changed with a non-transactional
311          * message or a completed sequence of transactional messages to a non-zero value,
312          * the value of the Light Lightness Last shall be set to the value of the Light
313          * Lightness Actual.
314          */
315         if (srv->state->lightness_actual) {
316             srv->state->lightness_last = srv->state->lightness_actual;
317         }
318     }
319 
320     srv->actual_transition.just_started = true;
321     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET) {
322         send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
323     }
324     send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
325 
326     bt_mesh_light_server_unlock();
327 
328     bt_mesh_server_start_transition(&srv->actual_transition);
329     return;
330 }
331 
light_lightness_linear_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)332 static void light_lightness_linear_set(struct bt_mesh_model *model,
333                                        struct bt_mesh_msg_ctx *ctx,
334                                        struct net_buf_simple *buf)
335 {
336     struct bt_mesh_light_lightness_srv *srv = model->user_data;
337     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
338     bool optional = false;
339     uint16_t linear = 0U;
340     int64_t now = 0;
341 
342     if (srv == NULL || srv->state == NULL) {
343         BT_ERR("%s, Invalid model user data", __func__);
344         return;
345     }
346 
347     linear = net_buf_simple_pull_le16(buf);
348     tid = net_buf_simple_pull_u8(buf);
349 
350     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
351         return;
352     }
353 
354     /* Callback the received message to the application layer */
355     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
356         bt_mesh_light_server_recv_set_msg_t set = {
357             .lightness_linear_set.op_en = optional,
358             .lightness_linear_set.lightness = linear,
359             .lightness_linear_set.tid = tid,
360             .lightness_linear_set.trans_time = trans_time,
361             .lightness_linear_set.delay = delay,
362         };
363         bt_mesh_lighting_server_cb_evt_to_btc(
364             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
365         return;
366     }
367 
368     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
369         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET) {
370             send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
371         }
372         send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
373         /* In this condition, no event will be callback to application layer */
374         return;
375     }
376 
377     bt_mesh_light_server_lock();
378 
379     bt_mesh_server_stop_transition(&srv->linear_transition);
380     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
381 
382     srv->state->target_lightness_linear = linear;
383 
384     /**
385      * If the target state is equal to the current state, the transition shall not
386      * be started and is considered complete.
387      */
388     if (srv->state->target_lightness_linear != srv->state->lightness_linear) {
389         light_lightness_linear_tt_values(srv, trans_time, delay);
390     } else {
391         bt_mesh_light_server_state_change_t change = {
392             .lightness_linear_set.lightness = srv->state->lightness_actual,
393         };
394         bt_mesh_lighting_server_cb_evt_to_btc(
395             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
396 
397         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET) {
398             send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
399         }
400         send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
401 
402         bt_mesh_light_server_unlock();
403         return;
404     }
405 
406     /* Copy the ctx of the received message */
407     if (srv->linear_transition.timer.work._reserved) {
408         memcpy(srv->linear_transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
409     }
410 
411     /* For Instantaneous Transition */
412     if (srv->linear_transition.counter == 0U) {
413         srv->state->lightness_linear = srv->state->target_lightness_linear;
414     }
415 
416     srv->linear_transition.just_started = true;
417     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET) {
418         send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
419     }
420     send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
421 
422     bt_mesh_light_server_unlock();
423 
424     bt_mesh_server_start_transition(&srv->linear_transition);
425     return;
426 }
427 
light_lightness_default_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)428 static void light_lightness_default_set(struct bt_mesh_model *model,
429                                         struct bt_mesh_msg_ctx *ctx,
430                                         struct net_buf_simple *buf)
431 {
432     struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
433     uint16_t lightness = 0U;
434 
435     if (srv == NULL || srv->state == NULL) {
436         BT_ERR("%s, Invalid model user data", __func__);
437         return;
438     }
439 
440     lightness = net_buf_simple_pull_le16(buf);
441 
442     /* Callback the received message to the application layer */
443     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
444         bt_mesh_light_server_recv_set_msg_t set = {
445             .lightness_default_set.lightness = lightness,
446         };
447         bt_mesh_lighting_server_cb_evt_to_btc(
448             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
449         return;
450     }
451 
452     if (srv->state->lightness_default != lightness) {
453         srv->state->lightness_default = lightness;
454 
455         bt_mesh_light_server_state_change_t change = {
456             .lightness_default_set.lightness = lightness,
457         };
458         bt_mesh_lighting_server_cb_evt_to_btc(
459             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
460     }
461 
462     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET) {
463         send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS);
464     }
465     send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS);
466 
467     return;
468 }
469 
light_lightness_range_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)470 static void light_lightness_range_set(struct bt_mesh_model *model,
471                                       struct bt_mesh_msg_ctx *ctx,
472                                       struct net_buf_simple *buf)
473 {
474     struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
475     uint16_t range_min = 0U, range_max = 0U;
476 
477     if (srv == NULL || srv->state == NULL) {
478         BT_ERR("%s, Invalid model user data", __func__);
479         return;
480     }
481 
482     range_min = net_buf_simple_pull_le16(buf);
483     range_max = net_buf_simple_pull_le16(buf);
484 
485     if (range_min > range_max) {
486         BT_ERR("Range min 0x%04x is greater than range max 0x%04x",
487                 range_min, range_max);
488         return;
489     }
490 
491     /* Callback the received message to the application layer */
492     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
493         bt_mesh_light_server_recv_set_msg_t set = {
494             .lightness_range_set.range_min = range_min,
495             .lightness_range_set.range_max = range_max,
496         };
497         bt_mesh_lighting_server_cb_evt_to_btc(
498             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
499         return;
500     }
501 
502     /**
503      * When a Light Lightness Setup Server receives a Light Lightness Range Set
504      * message or a Light Lightness Range Set Unacknowledged message with values
505      * that cannot be accepted, it shall set the status of the operation to a
506      * value representing the reason why the values cannot be accepted.
507      *
508      * TODO: 0x0000 for Light Range Min/Max is prohibited, but BQB test case
509      * MMDL/SR/LLNS/BI-01-C requires 'SUCCESS' when it sends a set message with
510      * Light Range Min set to 0x0000.
511      */
512 #if 0
513     srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
514 #else
515     if (range_min == 0x0000) {
516         srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MIN;
517     } else if (range_max == 0x0000) {
518         srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MAX;
519     } else {
520         srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
521     }
522 #endif
523 
524     if (range_min && srv->state->lightness_range_min != range_min) {
525         srv->state->lightness_range_min = range_min;
526     }
527 
528     if (range_max && srv->state->lightness_range_max != range_max) {
529         srv->state->lightness_range_max = range_max;
530     }
531 
532     bt_mesh_light_server_state_change_t change = {
533         .lightness_range_set.range_min = srv->state->lightness_range_min,
534         .lightness_range_set.range_max = srv->state->lightness_range_max,
535     };
536     bt_mesh_lighting_server_cb_evt_to_btc(
537         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
538 
539     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET) {
540         send_light_lightness_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS);
541     }
542     send_light_lightness_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS);
543 
544     return;
545 }
546 
547 /* Light CTL Server/Temperature Server/Setup Server message handlers */
548 
send_light_ctl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)549 static void send_light_ctl_status(struct bt_mesh_model *model,
550                                   struct bt_mesh_msg_ctx *ctx,
551                                   bool publish, uint16_t opcode)
552 {
553     struct net_buf_simple *msg = NULL;
554     uint8_t length = 2 + 9;
555 
556     if (ctx == NULL && publish == false) {
557         BT_ERR("%s, Invalid parameter", __func__);
558         return;
559     }
560 
561     if (publish == false) {
562         msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
563         if (msg == NULL) {
564             BT_ERR("%s, Out of memory", __func__);
565             return;
566         }
567     } else {
568         msg = bt_mesh_server_get_pub_msg(model, length);
569         if (msg == NULL) {
570             return;
571         }
572     }
573 
574     bt_mesh_model_msg_init(msg, opcode);
575     switch (opcode) {
576     case BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS: {
577         struct bt_mesh_light_ctl_srv *srv = model->user_data;
578         net_buf_simple_add_le16(msg, srv->state->lightness);
579         net_buf_simple_add_le16(msg, srv->state->temperature);
580         if (srv->transition.counter) {
581             bt_mesh_server_calc_remain_time(&srv->transition);
582             net_buf_simple_add_le16(msg, srv->state->target_lightness);
583             net_buf_simple_add_le16(msg, srv->state->target_temperature);
584             net_buf_simple_add_u8(msg, srv->transition.remain_time);
585         }
586         break;
587     }
588     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS:
589         if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SRV) {
590             struct bt_mesh_light_ctl_srv *srv = model->user_data;
591             net_buf_simple_add_u8(msg, srv->state->status_code);
592             net_buf_simple_add_le16(msg, srv->state->temperature_range_min);
593             net_buf_simple_add_le16(msg, srv->state->temperature_range_max);
594         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV) {
595             struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
596             net_buf_simple_add_u8(msg, srv->state->status_code);
597             net_buf_simple_add_le16(msg, srv->state->temperature_range_min);
598             net_buf_simple_add_le16(msg, srv->state->temperature_range_max);
599         }
600         break;
601     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS: {
602         if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SRV) {
603             struct bt_mesh_light_ctl_srv *srv = model->user_data;
604             net_buf_simple_add_le16(msg, srv->state->lightness_default);
605             net_buf_simple_add_le16(msg, srv->state->temperature_default);
606             net_buf_simple_add_le16(msg, srv->state->delta_uv_default);
607         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV) {
608             struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
609             net_buf_simple_add_le16(msg, srv->state->lightness_default);
610             net_buf_simple_add_le16(msg, srv->state->temperature_default);
611             net_buf_simple_add_le16(msg, srv->state->delta_uv_default);
612         }
613         break;
614     }
615     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS: {
616         struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
617         net_buf_simple_add_le16(msg, srv->state->temperature);
618         net_buf_simple_add_le16(msg, srv->state->delta_uv);
619         if (srv->transition.counter) {
620             bt_mesh_server_calc_remain_time(&srv->transition);
621             net_buf_simple_add_le16(msg, srv->state->target_temperature);
622             net_buf_simple_add_le16(msg, srv->state->target_delta_uv);
623             net_buf_simple_add_u8(msg, srv->transition.remain_time);
624         }
625         break;
626     }
627     default:
628         BT_WARN("Unknown Light CTL status opcode 0x%04x", opcode);
629         if (publish == false) {
630             bt_mesh_free_buf(msg);
631         }
632         return;
633     }
634 
635     if (publish == false) {
636         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
637         bt_mesh_free_buf(msg);
638     } else {
639         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
640     }
641     return;
642 }
643 
light_ctl_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)644 static void light_ctl_get(struct bt_mesh_model *model,
645                           struct bt_mesh_msg_ctx *ctx,
646                           struct net_buf_simple *buf)
647 {
648     struct bt_mesh_server_rsp_ctrl *rsp_ctrl = NULL;
649     uint16_t opcode = 0U;
650 
651     if (model->user_data == NULL) {
652         BT_ERR("%s, Invalid model user data", __func__);
653         return;
654     }
655 
656     switch (model->id) {
657     case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
658         struct bt_mesh_light_ctl_srv *srv = model->user_data;
659         if (srv->state == NULL) {
660             BT_ERR("Invalid Light CTL Server state");
661             return;
662         }
663         rsp_ctrl = &srv->rsp_ctrl;
664         break;
665     }
666     case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
667         struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
668         if (srv->state == NULL) {
669             BT_ERR("Invalid Light CTL Temperature Server state");
670             return;
671         }
672         rsp_ctrl = &srv->rsp_ctrl;
673         break;
674     }
675     default:
676         BT_ERR("Invalid Light CTL Server model 0x%04x", model->id);
677         return;
678     }
679 
680     /* Callback the received message to the application layer */
681     if (rsp_ctrl->get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
682         bt_mesh_lighting_server_cb_evt_to_btc(
683             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
684         return;
685     }
686 
687     switch (ctx->recv_op) {
688     case BLE_MESH_MODEL_OP_LIGHT_CTL_GET:
689         opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS;
690         break;
691     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET:
692         opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS;
693         break;
694     case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET:
695         opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS;
696         break;
697     case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET:
698         opcode = BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS;
699         break;
700     default:
701         BT_WARN("Unknown Light CTL Get opcode 0x%04x", ctx->recv_op);
702         return;
703     }
704 
705     send_light_ctl_status(model, ctx, false, opcode);
706     return;
707 }
708 
light_ctl_publish(struct bt_mesh_model * model,uint16_t opcode)709 void light_ctl_publish(struct bt_mesh_model *model, uint16_t opcode)
710 {
711     if (model->user_data == NULL) {
712         BT_ERR("%s, Invalid model user data", __func__);
713         return;
714     }
715 
716     switch (model->id) {
717     case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
718         struct bt_mesh_light_ctl_srv *srv = model->user_data;
719         if (srv->state == NULL) {
720             BT_ERR("Invalid Light CTL Server state");
721             return;
722         }
723         break;
724     }
725     case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
726         struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
727         if (srv->state == NULL) {
728             BT_ERR("Invalid Light CTL Temperature Server state");
729             return;
730         }
731         break;
732     }
733     case BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV: {
734         struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
735         if (srv->state == NULL) {
736             BT_ERR("Invalid Light CTL Setup Server state");
737             return;
738         }
739         break;
740     }
741     default:
742         BT_ERR("Invalid Light CTL Server model 0x%04x", model->id);
743         return;
744     }
745 
746     send_light_ctl_status(model, NULL, true, opcode);
747     return;
748 }
749 
light_ctl_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)750 static void light_ctl_set(struct bt_mesh_model *model,
751                           struct bt_mesh_msg_ctx *ctx,
752                           struct net_buf_simple *buf)
753 {
754     struct bt_mesh_light_ctl_srv *srv = model->user_data;
755     uint16_t lightness = 0U, temperature = 0U;
756     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
757     int16_t delta_uv = 0;
758     bool optional = false;
759     int64_t now = 0;
760 
761     if (srv == NULL || srv->state == NULL) {
762         BT_ERR("%s, Invalid model user data", __func__);
763         return;
764     }
765 
766     lightness = net_buf_simple_pull_le16(buf);
767     temperature = net_buf_simple_pull_le16(buf);
768     delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
769     tid = net_buf_simple_pull_u8(buf);
770 
771     if (temperature < BLE_MESH_TEMPERATURE_MIN || temperature > BLE_MESH_TEMPERATURE_MAX) {
772         BT_ERR("Invalid temperature 0x%04x", temperature);
773         return;
774     }
775 
776     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
777         return;
778     }
779 
780     /* Callback the received message to the application layer */
781     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
782         bt_mesh_light_server_recv_set_msg_t set = {
783             .ctl_set.op_en = optional,
784             .ctl_set.lightness = lightness,
785             .ctl_set.temperature = temperature,
786             .ctl_set.delta_uv = delta_uv,
787             .ctl_set.tid = tid,
788             .ctl_set.trans_time = trans_time,
789             .ctl_set.delay = delay,
790         };
791         bt_mesh_lighting_server_cb_evt_to_btc(
792             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
793         return;
794     }
795 
796     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
797         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_SET) {
798             send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
799         }
800         send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
801         /* In this condition, no event will be callback to application layer */
802         return;
803     }
804 
805     bt_mesh_light_server_lock();
806 
807     bt_mesh_server_stop_transition(&srv->transition);
808     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
809 
810     srv->state->target_lightness = lightness;
811     if (srv->state->temperature_range_min &&
812             srv->state->temperature_range_min != BLE_MESH_TEMPERATURE_UNKNOWN &&
813             temperature < srv->state->temperature_range_min) {
814         temperature = srv->state->temperature_range_min;
815     } else if (srv->state->temperature_range_max &&
816                srv->state->temperature_range_max != BLE_MESH_TEMPERATURE_UNKNOWN &&
817                temperature > srv->state->temperature_range_max) {
818         temperature = srv->state->temperature_range_max;
819     }
820     srv->state->target_temperature = temperature;
821     srv->state->target_delta_uv = delta_uv;
822 
823     if (srv->state->target_lightness != srv->state->lightness ||
824             srv->state->target_temperature != srv->state->temperature ||
825             srv->state->target_delta_uv != srv->state->delta_uv) {
826         light_ctl_tt_values(srv, trans_time, delay);
827     } else {
828         bt_mesh_light_server_state_change_t change = {
829             .ctl_set.lightness = srv->state->lightness,
830             .ctl_set.temperature = srv->state->temperature,
831             .ctl_set.delta_uv = srv->state->delta_uv,
832         };
833         bt_mesh_lighting_server_cb_evt_to_btc(
834             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
835 
836         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_SET) {
837             send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
838         }
839         send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
840 
841         bt_mesh_light_server_unlock();
842         return;
843     }
844 
845     /* Copy the ctx of the received message */
846     if (srv->transition.timer.work._reserved) {
847         memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
848     }
849 
850     /* For Instantaneous Transition */
851     if (srv->transition.counter == 0U) {
852         srv->state->lightness = srv->state->target_lightness;
853         srv->state->temperature = srv->state->target_temperature;
854         srv->state->delta_uv = srv->state->target_delta_uv;
855     }
856 
857     srv->transition.just_started = true;
858     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_SET) {
859         send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
860     }
861     send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
862 
863     bt_mesh_light_server_unlock();
864 
865     bt_mesh_server_start_transition(&srv->transition);
866     return;
867 }
868 
light_ctl_default_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)869 static void light_ctl_default_set(struct bt_mesh_model *model,
870                                   struct bt_mesh_msg_ctx *ctx,
871                                   struct net_buf_simple *buf)
872 {
873     struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
874     uint16_t lightness = 0U, temperature = 0U;
875     int16_t delta_uv = 0;
876 
877     if (srv == NULL || srv->state == NULL) {
878         BT_ERR("%s, Invalid model user data", __func__);
879         return;
880     }
881 
882     lightness = net_buf_simple_pull_le16(buf);
883     temperature = net_buf_simple_pull_le16(buf);
884     delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
885 
886     if (temperature < BLE_MESH_TEMPERATURE_MIN || temperature > BLE_MESH_TEMPERATURE_MAX) {
887         BT_ERR("Invalid temperature 0x%04x", temperature);
888         return;
889     }
890 
891     /* Callback the received message to the application layer */
892     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
893         bt_mesh_light_server_recv_set_msg_t set = {
894             .ctl_default_set.lightness = lightness,
895             .ctl_default_set.temperature = temperature,
896             .ctl_default_set.delta_uv = delta_uv,
897         };
898         bt_mesh_lighting_server_cb_evt_to_btc(
899             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
900         return;
901     }
902 
903     if (srv->state->temperature_range_min &&
904             srv->state->temperature_range_min != BLE_MESH_TEMPERATURE_UNKNOWN &&
905             temperature < srv->state->temperature_range_min) {
906         temperature = srv->state->temperature_range_min;
907     } else if (srv->state->temperature_range_max &&
908                srv->state->temperature_range_max != BLE_MESH_TEMPERATURE_UNKNOWN &&
909                temperature > srv->state->temperature_range_max) {
910         temperature = srv->state->temperature_range_max;
911     }
912 
913     srv->state->lightness_default = lightness;
914     srv->state->temperature_default = temperature;
915     srv->state->delta_uv_default = delta_uv;
916 
917     bt_mesh_light_server_state_change_t change = {
918         .ctl_default_set.lightness = srv->state->lightness_default,
919         .ctl_default_set.temperature = srv->state->temperature_default,
920         .ctl_default_set.delta_uv = srv->state->delta_uv_default,
921     };
922     bt_mesh_lighting_server_cb_evt_to_btc(
923         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
924 
925     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET) {
926         send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS);
927     }
928     send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS);
929 
930     return;
931 }
932 
light_ctl_temp_range_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)933 static void light_ctl_temp_range_set(struct bt_mesh_model *model,
934                                      struct bt_mesh_msg_ctx *ctx,
935                                      struct net_buf_simple *buf)
936 {
937     struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
938     uint16_t min = 0U, max = 0U;
939 
940     if (srv == NULL || srv->state == NULL) {
941         BT_ERR("%s, Invalid model user data", __func__);
942         return;
943     }
944 
945     min = net_buf_simple_pull_le16(buf);
946     max = net_buf_simple_pull_le16(buf);
947 
948     /* This is as per 6.1.3.1 in Mesh Model Specification */
949     if (min > max ||
950             min < BLE_MESH_TEMPERATURE_MIN || (min != BLE_MESH_TEMPERATURE_UNKNOWN && min > BLE_MESH_TEMPERATURE_MAX) ||
951             max < BLE_MESH_TEMPERATURE_MIN || (max != BLE_MESH_TEMPERATURE_UNKNOWN && max > BLE_MESH_TEMPERATURE_MAX)) {
952         BT_ERR("Invalid parameter, range min 0x%04x, range max 0x%04x",
953                 min, max);
954         return;
955     }
956 
957     /* Callback the received message to the application layer */
958     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
959         bt_mesh_light_server_recv_set_msg_t set = {
960             .ctl_temp_range_set.range_min = min,
961             .ctl_temp_range_set.range_max = max,
962         };
963         bt_mesh_lighting_server_cb_evt_to_btc(
964             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
965         return;
966     }
967 
968     if (min == BLE_MESH_TEMPERATURE_UNKNOWN) {
969         srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MIN;
970     } else if (max == BLE_MESH_TEMPERATURE_UNKNOWN ) {
971         srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MAX;
972     } else {
973         srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
974     }
975 
976     if (min != BLE_MESH_TEMPERATURE_UNKNOWN && srv->state->temperature_range_min != min) {
977         srv->state->temperature_range_min = min;
978     }
979 
980     if (max != BLE_MESH_TEMPERATURE_UNKNOWN && srv->state->temperature_range_max != max) {
981         srv->state->temperature_range_max = max;
982     }
983 
984     bt_mesh_light_server_state_change_t change = {
985         .ctl_temp_range_set.range_min = srv->state->temperature_range_min,
986         .ctl_temp_range_set.range_max = srv->state->temperature_range_max,
987     };
988     bt_mesh_lighting_server_cb_evt_to_btc(
989         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
990 
991     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET) {
992         send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS);
993     }
994     send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS);
995 
996     return;
997 }
998 
light_ctl_temp_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)999 static void light_ctl_temp_set(struct bt_mesh_model *model,
1000                                struct bt_mesh_msg_ctx *ctx,
1001                                struct net_buf_simple *buf)
1002 {
1003     struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
1004     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
1005     uint16_t temperature = 0U;
1006     int16_t delta_uv = 0;
1007     bool optional = false;
1008     int64_t now = 0;
1009 
1010     if (srv == NULL || srv->state == NULL) {
1011         BT_ERR("%s, Invalid model user data", __func__);
1012         return;
1013     }
1014 
1015     temperature = net_buf_simple_pull_le16(buf);
1016     delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
1017     tid = net_buf_simple_pull_u8(buf);
1018 
1019     if (temperature < BLE_MESH_TEMPERATURE_MIN || temperature > BLE_MESH_TEMPERATURE_MAX) {
1020         BT_ERR("Invalid temperature 0x%04x", temperature);
1021         return;
1022     }
1023 
1024     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
1025         return;
1026     }
1027 
1028     /* Callback the received message to the application layer */
1029     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1030         bt_mesh_light_server_recv_set_msg_t set = {
1031             .ctl_temp_set.op_en = optional,
1032             .ctl_temp_set.temperature = temperature,
1033             .ctl_temp_set.delta_uv = delta_uv,
1034             .ctl_temp_set.tid = tid,
1035             .ctl_temp_set.trans_time = trans_time,
1036             .ctl_temp_set.delay = delay,
1037         };
1038         bt_mesh_lighting_server_cb_evt_to_btc(
1039             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1040         return;
1041     }
1042 
1043     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
1044         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET) {
1045             send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
1046         }
1047         send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
1048         /* In this condition, no event will be callback to application layer */
1049         return;
1050     }
1051 
1052     bt_mesh_light_server_lock();
1053 
1054     bt_mesh_server_stop_transition(&srv->transition);
1055     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
1056 
1057     if (srv->state->temperature_range_min &&
1058             srv->state->temperature_range_min != BLE_MESH_TEMPERATURE_UNKNOWN &&
1059             temperature < srv->state->temperature_range_min) {
1060         temperature = srv->state->temperature_range_min;
1061     } else if (srv->state->temperature_range_max &&
1062                srv->state->temperature_range_max != BLE_MESH_TEMPERATURE_UNKNOWN &&
1063                temperature > srv->state->temperature_range_max) {
1064         temperature = srv->state->temperature_range_max;
1065     }
1066     srv->state->target_temperature = temperature;
1067     srv->state->target_delta_uv = delta_uv;
1068 
1069     if (srv->state->target_temperature != srv->state->temperature ||
1070             srv->state->target_delta_uv != srv->state->delta_uv) {
1071         light_ctl_temp_tt_values(srv, trans_time, delay);
1072     } else {
1073         bt_mesh_light_server_state_change_t change = {
1074             .ctl_temp_set.temperature = srv->state->temperature,
1075             .ctl_temp_set.delta_uv = srv->state->delta_uv,
1076         };
1077         bt_mesh_lighting_server_cb_evt_to_btc(
1078             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1079 
1080         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET) {
1081             send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
1082         }
1083         send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
1084 
1085         bt_mesh_light_server_unlock();
1086         return;
1087     }
1088 
1089     /* Copy the ctx of the received message */
1090     if (srv->transition.timer.work._reserved) {
1091         memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
1092     }
1093 
1094     /* For Instantaneous Transition */
1095     if (srv->transition.counter == 0U) {
1096         srv->state->temperature = srv->state->target_temperature;
1097         srv->state->delta_uv = srv->state->target_delta_uv;
1098     }
1099 
1100     srv->transition.just_started = true;
1101     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET) {
1102         send_light_ctl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
1103     }
1104     send_light_ctl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
1105 
1106     bt_mesh_light_server_unlock();
1107 
1108     bt_mesh_server_start_transition(&srv->transition);
1109     return;
1110 }
1111 
1112 /* Light HSL Server/Hue Server/Saturation Server/Setup Server message handlers */
1113 
send_light_hsl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)1114 static void send_light_hsl_status(struct bt_mesh_model *model,
1115                                   struct bt_mesh_msg_ctx *ctx,
1116                                   bool publish, uint16_t opcode)
1117 {
1118     struct net_buf_simple *msg = NULL;
1119     uint8_t length = 2 + 9;
1120 
1121     if (ctx == NULL && publish == false) {
1122         BT_ERR("%s, Invalid parameter", __func__);
1123         return;
1124     }
1125 
1126     if (publish == false) {
1127         msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1128         if (msg == NULL) {
1129             BT_ERR("%s, Out of memory", __func__);
1130             return;
1131         }
1132     } else {
1133         msg = bt_mesh_server_get_pub_msg(model, length);
1134         if (msg == NULL) {
1135             return;
1136         }
1137     }
1138 
1139     bt_mesh_model_msg_init(msg, opcode);
1140     switch (opcode) {
1141     case BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS:
1142     case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS: {
1143         struct bt_mesh_light_hsl_srv *srv = model->user_data;
1144         if (opcode == BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS) {
1145             net_buf_simple_add_le16(msg, srv->state->lightness);
1146             net_buf_simple_add_le16(msg, srv->state->hue);
1147             net_buf_simple_add_le16(msg, srv->state->saturation);
1148             if (srv->transition.counter) {
1149                 bt_mesh_server_calc_remain_time(&srv->transition);
1150                 net_buf_simple_add_u8(msg, srv->transition.remain_time);
1151             }
1152         } else if (opcode == BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS) {
1153             net_buf_simple_add_le16(msg, srv->state->target_lightness);
1154             net_buf_simple_add_le16(msg, srv->state->target_hue);
1155             net_buf_simple_add_le16(msg, srv->state->target_saturation);
1156             if (srv->transition.counter) {
1157                 bt_mesh_server_calc_remain_time(&srv->transition);
1158                 net_buf_simple_add_u8(msg, srv->transition.remain_time);
1159             }
1160         }
1161         break;
1162     }
1163     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS:
1164         if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SRV) {
1165             struct bt_mesh_light_hsl_srv *srv = model->user_data;
1166             net_buf_simple_add_le16(msg, srv->state->lightness_default);
1167             net_buf_simple_add_le16(msg, srv->state->hue_default);
1168             net_buf_simple_add_le16(msg, srv->state->saturation_default);
1169         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV) {
1170             struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
1171             net_buf_simple_add_le16(msg, srv->state->lightness_default);
1172             net_buf_simple_add_le16(msg, srv->state->hue_default);
1173             net_buf_simple_add_le16(msg, srv->state->saturation_default);
1174         }
1175         break;
1176     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS:
1177         if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SRV) {
1178             struct bt_mesh_light_hsl_srv *srv = model->user_data;
1179             net_buf_simple_add_u8(msg, srv->state->status_code);
1180             net_buf_simple_add_le16(msg, srv->state->hue_range_min);
1181             net_buf_simple_add_le16(msg, srv->state->hue_range_max);
1182             net_buf_simple_add_le16(msg, srv->state->saturation_range_min);
1183             net_buf_simple_add_le16(msg, srv->state->saturation_range_max);
1184         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV) {
1185             struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
1186             net_buf_simple_add_u8(msg, srv->state->status_code);
1187             net_buf_simple_add_le16(msg, srv->state->hue_range_min);
1188             net_buf_simple_add_le16(msg, srv->state->hue_range_max);
1189             net_buf_simple_add_le16(msg, srv->state->saturation_range_min);
1190             net_buf_simple_add_le16(msg, srv->state->saturation_range_max);
1191         }
1192         break;
1193     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS: {
1194         struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
1195         net_buf_simple_add_le16(msg, srv->state->hue);
1196         if (srv->transition.counter) {
1197             bt_mesh_server_calc_remain_time(&srv->transition);
1198             net_buf_simple_add_le16(msg, srv->state->target_hue);
1199             net_buf_simple_add_u8(msg, srv->transition.remain_time);
1200         }
1201         break;
1202     }
1203     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS: {
1204         struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
1205         net_buf_simple_add_le16(msg, srv->state->saturation);
1206         if (srv->transition.counter) {
1207             bt_mesh_server_calc_remain_time(&srv->transition);
1208             net_buf_simple_add_le16(msg, srv->state->target_saturation);
1209             net_buf_simple_add_u8(msg, srv->transition.remain_time);
1210         }
1211         break;
1212     }
1213     default:
1214         BT_WARN("Unknown Light HSL status opcode 0x%04x", opcode);
1215         if (publish == false) {
1216             bt_mesh_free_buf(msg);
1217         }
1218         return;
1219     }
1220 
1221     if (publish == false) {
1222         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
1223         bt_mesh_free_buf(msg);
1224     } else {
1225         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
1226     }
1227     return;
1228 }
1229 
light_hsl_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1230 static void light_hsl_get(struct bt_mesh_model *model,
1231                           struct bt_mesh_msg_ctx *ctx,
1232                           struct net_buf_simple *buf)
1233 {
1234     struct bt_mesh_server_rsp_ctrl *rsp_ctrl = NULL;
1235     uint16_t opcode = 0U;
1236 
1237     if (model->user_data == NULL) {
1238         BT_ERR("%s, Invalid model user data", __func__);
1239         return;
1240     }
1241 
1242     switch (model->id) {
1243     case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
1244         struct bt_mesh_light_hsl_srv *srv = model->user_data;
1245         if (srv->state == NULL) {
1246             BT_ERR("Invalid Light HSL Server state");
1247             return;
1248         }
1249         rsp_ctrl = &srv->rsp_ctrl;
1250         break;
1251     }
1252     case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
1253         struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
1254         if (srv->state == NULL) {
1255             BT_ERR("Invalid Light HSL Hue Server state");
1256             return;
1257         }
1258         rsp_ctrl = &srv->rsp_ctrl;
1259         break;
1260     }
1261     case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
1262         struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
1263         if (srv->state == NULL) {
1264             BT_ERR("Invalid Light HSL Saturation Server state");
1265             return;
1266         }
1267         rsp_ctrl = &srv->rsp_ctrl;
1268         break;
1269     }
1270     default:
1271         BT_ERR("Invalid Light HSL Server model 0x%04x", model->id);
1272         return;
1273     }
1274 
1275     /* Callback the received message to the application layer */
1276     if (rsp_ctrl->get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1277         bt_mesh_lighting_server_cb_evt_to_btc(
1278             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
1279         return;
1280     }
1281 
1282     switch (ctx->recv_op) {
1283     case BLE_MESH_MODEL_OP_LIGHT_HSL_GET:
1284         opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS;
1285         break;
1286     case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET:
1287         opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS;
1288         break;
1289     case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET:
1290         opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS;
1291         break;
1292     case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET:
1293         opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS;
1294         break;
1295     case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET:
1296         opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS;
1297         break;
1298     case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET:
1299         opcode = BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS;
1300         break;
1301     default:
1302         BT_WARN("Unknown Light HSL Get opcode 0x%04x", ctx->recv_op);
1303         return;
1304     }
1305 
1306     send_light_hsl_status(model, ctx, false, opcode);
1307     return;
1308 }
1309 
light_hsl_publish(struct bt_mesh_model * model,uint16_t opcode)1310 void light_hsl_publish(struct bt_mesh_model *model, uint16_t opcode)
1311 {
1312     if (model->user_data == NULL) {
1313         BT_ERR("%s, Invalid model user data", __func__);
1314         return;
1315     }
1316 
1317     switch (model->id) {
1318     case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
1319         struct bt_mesh_light_hsl_srv *srv = model->user_data;
1320         if (srv->state == NULL) {
1321             BT_ERR("Invalid Light HSL Server state");
1322             return;
1323         }
1324         break;
1325     }
1326     case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
1327         struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
1328         if (srv->state == NULL) {
1329             BT_ERR("Invalid Light HSL Hue Server state");
1330             return;
1331         }
1332         break;
1333     }
1334     case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
1335         struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
1336         if (srv->state == NULL) {
1337             BT_ERR("Invalid Light HSL Saturation Server state");
1338             return;
1339         }
1340         break;
1341     }
1342     case BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV: {
1343         struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
1344         if (srv->state == NULL) {
1345             BT_ERR("Invalid Light HSL Setup Server state");
1346             return;
1347         }
1348         break;
1349     }
1350     default:
1351         BT_ERR("Invalid Light HSL Server model 0x%04x", model->id);
1352         return;
1353     }
1354 
1355     send_light_hsl_status(model, NULL, true, opcode);
1356     return;
1357 }
1358 
light_hsl_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1359 static void light_hsl_set(struct bt_mesh_model *model,
1360                           struct bt_mesh_msg_ctx *ctx,
1361                           struct net_buf_simple *buf)
1362 {
1363     struct bt_mesh_light_hsl_srv *srv = model->user_data;
1364     uint16_t lightness = 0U, hue = 0U, saturation = 0U;
1365     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
1366     bool optional = false;
1367     int64_t now = 0;
1368 
1369     if (srv == NULL || srv->state == NULL) {
1370         BT_ERR("%s, Invalid model user data", __func__);
1371         return;
1372     }
1373 
1374     lightness = net_buf_simple_pull_le16(buf);
1375     hue = net_buf_simple_pull_le16(buf);
1376     saturation = net_buf_simple_pull_le16(buf);
1377     tid = net_buf_simple_pull_u8(buf);
1378 
1379     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
1380         return;
1381     }
1382 
1383     /* Callback the received message to the application layer */
1384     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1385         bt_mesh_light_server_recv_set_msg_t set = {
1386             .hsl_set.op_en = optional,
1387             .hsl_set.lightness = lightness,
1388             .hsl_set.hue = hue,
1389             .hsl_set.saturation = saturation,
1390             .hsl_set.tid = tid,
1391             .hsl_set.trans_time = trans_time,
1392             .hsl_set.delay = delay,
1393         };
1394         bt_mesh_lighting_server_cb_evt_to_btc(
1395             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1396         return;
1397     }
1398 
1399     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
1400         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SET) {
1401             send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
1402         }
1403         send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
1404         /* In this condition, no event will be callback to application layer */
1405         return;
1406     }
1407 
1408     bt_mesh_light_server_lock();
1409 
1410     bt_mesh_server_stop_transition(&srv->transition);
1411     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
1412 
1413     srv->state->target_lightness = lightness;
1414     if (srv->state->hue_range_min && hue < srv->state->hue_range_min) {
1415         hue = srv->state->hue_range_min;
1416     } else if (srv->state->hue_range_max && hue > srv->state->hue_range_max) {
1417         hue = srv->state->hue_range_max;
1418     }
1419     srv->state->target_hue = hue;
1420     if (srv->state->saturation_range_min && saturation < srv->state->saturation_range_min) {
1421         saturation = srv->state->saturation_range_min;
1422     } else if (srv->state->saturation_range_max && saturation > srv->state->saturation_range_max) {
1423         saturation = srv->state->saturation_range_max;
1424     }
1425     srv->state->target_saturation = saturation;
1426 
1427     /**
1428      * If the target state is equal to the current state, the transition shall not
1429      * be started and is considered complete.
1430      */
1431     if (srv->state->target_lightness != srv->state->lightness ||
1432             srv->state->target_hue != srv->state->hue ||
1433             srv->state->target_saturation != srv->state->saturation) {
1434         light_hsl_tt_values(srv, trans_time, delay);
1435     } else {
1436         bt_mesh_light_server_state_change_t change = {
1437             .hsl_set.lightness = srv->state->lightness,
1438             .hsl_set.hue = srv->state->hue,
1439             .hsl_set.saturation = srv->state->saturation,
1440         };
1441         bt_mesh_lighting_server_cb_evt_to_btc(
1442             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1443 
1444         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SET) {
1445             send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
1446         }
1447         send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
1448 
1449         bt_mesh_light_server_unlock();
1450         return;
1451     }
1452 
1453     /* Copy the ctx of the received message */
1454     if (srv->transition.timer.work._reserved) {
1455         memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
1456     }
1457 
1458     /* For Instantaneous Transition */
1459     if (srv->transition.counter == 0U) {
1460         srv->state->lightness = srv->state->target_lightness;
1461         srv->state->hue = srv->state->target_hue;
1462         srv->state->saturation = srv->state->target_saturation;
1463     }
1464 
1465     srv->transition.just_started = true;
1466     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SET) {
1467         send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
1468     }
1469     send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
1470 
1471     bt_mesh_light_server_unlock();
1472 
1473     bt_mesh_server_start_transition(&srv->transition);
1474     return;
1475 }
1476 
light_hsl_default_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1477 static void light_hsl_default_set(struct bt_mesh_model *model,
1478                                   struct bt_mesh_msg_ctx *ctx,
1479                                   struct net_buf_simple *buf)
1480 {
1481     struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
1482     uint16_t lightness = 0U, hue = 0U, saturation = 0U;
1483 
1484     if (srv == NULL || srv->state == NULL) {
1485         BT_ERR("%s, Invalid model user data", __func__);
1486         return;
1487     }
1488 
1489     lightness = net_buf_simple_pull_le16(buf);
1490     hue = net_buf_simple_pull_le16(buf);
1491     saturation = net_buf_simple_pull_le16(buf);
1492 
1493     /* Callback the received message to the application layer */
1494     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1495         bt_mesh_light_server_recv_set_msg_t set = {
1496             .hsl_default_set.lightness = lightness,
1497             .hsl_default_set.hue = hue,
1498             .hsl_default_set.saturation = saturation,
1499         };
1500         bt_mesh_lighting_server_cb_evt_to_btc(
1501             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1502         return;
1503     }
1504 
1505     if (srv->state->hue_range_min && hue < srv->state->hue_range_min) {
1506         hue = srv->state->hue_range_min;
1507     } else if (srv->state->hue_range_max && hue > srv->state->hue_range_max) {
1508         hue = srv->state->hue_range_max;
1509     }
1510 
1511     if (srv->state->saturation_range_min && saturation < srv->state->saturation_range_min) {
1512         saturation = srv->state->saturation_range_min;
1513     } else if (srv->state->saturation_range_max && saturation > srv->state->saturation_range_max) {
1514         saturation = srv->state->saturation_range_max;
1515     }
1516 
1517     srv->state->lightness_default = lightness;
1518     srv->state->hue_default = hue;
1519     srv->state->saturation_default = saturation;
1520 
1521     bt_mesh_light_server_state_change_t change = {
1522         .hsl_default_set.lightness = srv->state->lightness_default,
1523         .hsl_default_set.hue = srv->state->hue_default,
1524         .hsl_default_set.saturation = srv->state->saturation_default,
1525     };
1526     bt_mesh_lighting_server_cb_evt_to_btc(
1527         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1528 
1529     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET) {
1530         send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS);
1531     }
1532     send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS);
1533 
1534     return;
1535 }
1536 
light_hsl_range_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1537 static void light_hsl_range_set(struct bt_mesh_model *model,
1538                                 struct bt_mesh_msg_ctx *ctx,
1539                                 struct net_buf_simple *buf)
1540 {
1541     struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
1542     uint16_t hue_min = 0U, hue_max = 0U, saturation_min = 0U, saturation_max = 0U;
1543 
1544     if (srv == NULL || srv->state == NULL) {
1545         BT_ERR("%s, Invalid model user data", __func__);
1546         return;
1547     }
1548 
1549     hue_min = net_buf_simple_pull_le16(buf);
1550     hue_max = net_buf_simple_pull_le16(buf);
1551     saturation_min = net_buf_simple_pull_le16(buf);
1552     saturation_max = net_buf_simple_pull_le16(buf);
1553 
1554     if (hue_min > hue_max) {
1555         BT_ERR("Invalid parameter, hue min 0x%04x, hue max 0x%04x",
1556                 hue_min, hue_max);
1557         return;
1558     }
1559 
1560     if (saturation_min > saturation_max) {
1561         BT_ERR("Invalid parameter, saturation min 0x%04x, saturation max 0x%04x",
1562                 saturation_min, saturation_max);
1563         return;
1564     }
1565 
1566     /* Callback the received message to the application layer */
1567     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1568         bt_mesh_light_server_recv_set_msg_t set = {
1569             .hsl_range_set.hue_range_min = hue_min,
1570             .hsl_range_set.hue_range_max = hue_max,
1571             .hsl_range_set.sat_range_min = saturation_min,
1572             .hsl_range_set.sat_range_max = saturation_max,
1573         };
1574         bt_mesh_lighting_server_cb_evt_to_btc(
1575             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1576         return;
1577     }
1578 
1579     srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
1580     srv->state->hue_range_min = hue_min;
1581     srv->state->hue_range_max = hue_max;
1582     srv->state->saturation_range_min = saturation_min;
1583     srv->state->saturation_range_max = saturation_max;
1584 
1585     bt_mesh_light_server_state_change_t change = {
1586         .hsl_range_set.hue_range_min = srv->state->hue_range_min,
1587         .hsl_range_set.hue_range_max = srv->state->hue_range_max,
1588         .hsl_range_set.sat_range_min = srv->state->saturation_range_min,
1589         .hsl_range_set.sat_range_max = srv->state->saturation_range_max,
1590     };
1591     bt_mesh_lighting_server_cb_evt_to_btc(
1592         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1593 
1594     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET) {
1595         send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS);
1596     }
1597     send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS);
1598 
1599     return;
1600 }
1601 
light_hsl_hue_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1602 static void light_hsl_hue_set(struct bt_mesh_model *model,
1603                               struct bt_mesh_msg_ctx *ctx,
1604                               struct net_buf_simple *buf)
1605 {
1606     struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
1607     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
1608     bool optional = false;
1609     uint16_t hue = 0U;
1610     int64_t now = 0;
1611 
1612     if (srv == NULL || srv->state == NULL) {
1613         BT_ERR("%s, Invalid model user data", __func__);
1614         return;
1615     }
1616 
1617     hue = net_buf_simple_pull_le16(buf);
1618     tid = net_buf_simple_pull_u8(buf);
1619 
1620     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
1621         return;
1622     }
1623 
1624     /* Callback the received message to the application layer */
1625     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1626         bt_mesh_light_server_recv_set_msg_t set = {
1627             .hsl_hue_set.op_en = optional,
1628             .hsl_hue_set.hue = hue,
1629             .hsl_hue_set.tid = tid,
1630             .hsl_hue_set.trans_time = trans_time,
1631             .hsl_hue_set.delay = delay,
1632         };
1633         bt_mesh_lighting_server_cb_evt_to_btc(
1634             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1635         return;
1636     }
1637 
1638     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
1639         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET) {
1640             send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
1641         }
1642         send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
1643         /* In this condition, no event will be callback to application layer */
1644         return;
1645     }
1646 
1647     bt_mesh_light_server_lock();
1648 
1649     bt_mesh_server_stop_transition(&srv->transition);
1650     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
1651 
1652     if (srv->state->hue_range_min && hue < srv->state->hue_range_min) {
1653         hue = srv->state->hue_range_min;
1654     } else if (srv->state->hue_range_max && hue > srv->state->hue_range_max) {
1655         hue = srv->state->hue_range_max;
1656     }
1657     srv->state->target_hue = hue;
1658 
1659     /**
1660      * If the target state is equal to the current state, the transition shall not
1661      * be started and is considered complete.
1662      */
1663     if (srv->state->target_hue != srv->state->hue) {
1664         light_hsl_hue_tt_values(srv, trans_time, delay);
1665     } else {
1666         bt_mesh_light_server_state_change_t change = {
1667             .hsl_hue_set.hue = srv->state->hue,
1668         };
1669         bt_mesh_lighting_server_cb_evt_to_btc(
1670             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1671 
1672         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET) {
1673             send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
1674         }
1675         send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
1676 
1677         bt_mesh_light_server_unlock();
1678         return;
1679     }
1680 
1681     /* Copy the ctx of the received message */
1682     if (srv->transition.timer.work._reserved) {
1683         memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
1684     }
1685 
1686     /* For Instantaneous Transition */
1687     if (srv->transition.counter == 0U) {
1688         srv->state->hue = srv->state->target_hue;
1689     }
1690 
1691     srv->transition.just_started = true;
1692     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET) {
1693         send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
1694     }
1695     send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
1696 
1697     bt_mesh_light_server_unlock();
1698 
1699     bt_mesh_server_start_transition(&srv->transition);
1700     return;
1701 }
1702 
light_hsl_sat_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1703 static void light_hsl_sat_set(struct bt_mesh_model *model,
1704                               struct bt_mesh_msg_ctx *ctx,
1705                               struct net_buf_simple *buf)
1706 {
1707     struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
1708     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
1709     uint16_t saturation = 0U;
1710     bool optional = false;
1711     int64_t now = 0;
1712 
1713     if (srv == NULL || srv->state == NULL) {
1714         BT_ERR("%s, Invalid model user data", __func__);
1715         return;
1716     }
1717 
1718     saturation = net_buf_simple_pull_le16(buf);
1719     tid = net_buf_simple_pull_u8(buf);
1720 
1721     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
1722         return;
1723     }
1724 
1725     /* Callback the received message to the application layer */
1726     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1727         bt_mesh_light_server_recv_set_msg_t set = {
1728             .hsl_saturation_set.op_en = optional,
1729             .hsl_saturation_set.saturation = saturation,
1730             .hsl_saturation_set.tid = tid,
1731             .hsl_saturation_set.trans_time = trans_time,
1732             .hsl_saturation_set.delay = delay,
1733         };
1734         bt_mesh_lighting_server_cb_evt_to_btc(
1735             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1736         return;
1737     }
1738 
1739     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
1740         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET) {
1741             send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
1742         }
1743         send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
1744         /* In this condition, no event will be callback to application layer */
1745         return;
1746     }
1747 
1748     bt_mesh_light_server_lock();
1749 
1750     bt_mesh_server_stop_transition(&srv->transition);
1751     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
1752 
1753     if (srv->state->saturation_range_min && saturation < srv->state->saturation_range_min) {
1754         saturation = srv->state->saturation_range_min;
1755     } else if (srv->state->saturation_range_max && saturation > srv->state->saturation_range_max) {
1756         saturation = srv->state->saturation_range_max;
1757     }
1758     srv->state->target_saturation = saturation;
1759 
1760     /**
1761      * If the target state is equal to the current state, the transition shall not
1762      * be started and is considered complete.
1763      */
1764     if (srv->state->target_saturation != srv->state->saturation) {
1765         light_hsl_sat_tt_values(srv, trans_time, delay);
1766     } else {
1767         bt_mesh_light_server_state_change_t change = {
1768             .hsl_saturation_set.saturation = srv->state->saturation,
1769         };
1770         bt_mesh_lighting_server_cb_evt_to_btc(
1771             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1772 
1773         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET) {
1774             send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
1775         }
1776         send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
1777 
1778         bt_mesh_light_server_unlock();
1779         return;
1780     }
1781 
1782     /* Copy the ctx of the received message */
1783     if (srv->transition.timer.work._reserved) {
1784         memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
1785     }
1786 
1787     /* For Instantaneous Transition */
1788     if (srv->transition.counter == 0U) {
1789         srv->state->saturation = srv->state->target_saturation;
1790     }
1791 
1792     srv->transition.just_started = true;
1793     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET) {
1794         send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
1795     }
1796     send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
1797 
1798     bt_mesh_light_server_unlock();
1799 
1800     bt_mesh_server_start_transition(&srv->transition);
1801     return;
1802 }
1803 
1804 /* Light xyL Server/Setup Server message handlers */
1805 
send_light_xyl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)1806 static void send_light_xyl_status(struct bt_mesh_model *model,
1807                                   struct bt_mesh_msg_ctx *ctx,
1808                                   bool publish, uint16_t opcode)
1809 {
1810     struct net_buf_simple *msg = NULL;
1811     uint8_t length = 2 + 9;
1812 
1813     if (ctx == NULL && publish == false) {
1814         BT_ERR("%s, Invalid parameter", __func__);
1815         return;
1816     }
1817 
1818     if (publish == false) {
1819         msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1820         if (msg == NULL) {
1821             BT_ERR("%s, Out of memory", __func__);
1822             return;
1823         }
1824     } else {
1825         msg = bt_mesh_server_get_pub_msg(model, length);
1826         if (msg == NULL) {
1827             return;
1828         }
1829     }
1830 
1831     bt_mesh_model_msg_init(msg, opcode);
1832     switch (opcode) {
1833     case BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS:
1834     case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS: {
1835         struct bt_mesh_light_xyl_srv *srv = model->user_data;
1836         if (opcode == BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS) {
1837             net_buf_simple_add_le16(msg, srv->state->lightness);
1838             net_buf_simple_add_le16(msg, srv->state->x);
1839             net_buf_simple_add_le16(msg, srv->state->y);
1840             if (srv->transition.counter) {
1841                 bt_mesh_server_calc_remain_time(&srv->transition);
1842                 net_buf_simple_add_u8(msg, srv->transition.remain_time);
1843             }
1844         } else if (opcode == BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS) {
1845             net_buf_simple_add_le16(msg, srv->state->target_lightness);
1846             net_buf_simple_add_le16(msg, srv->state->target_x);
1847             net_buf_simple_add_le16(msg, srv->state->target_y);
1848             if (srv->transition.counter) {
1849                 bt_mesh_server_calc_remain_time(&srv->transition);
1850                 net_buf_simple_add_u8(msg, srv->transition.remain_time);
1851             }
1852         }
1853         break;
1854     }
1855     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS:
1856         if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SRV) {
1857             struct bt_mesh_light_xyl_srv *srv = model->user_data;
1858             net_buf_simple_add_le16(msg, srv->state->lightness_default);
1859             net_buf_simple_add_le16(msg, srv->state->x_default);
1860             net_buf_simple_add_le16(msg, srv->state->y_default);
1861         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV) {
1862             struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
1863             net_buf_simple_add_le16(msg, srv->state->lightness_default);
1864             net_buf_simple_add_le16(msg, srv->state->x_default);
1865             net_buf_simple_add_le16(msg, srv->state->y_default);
1866         }
1867         break;
1868     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS:
1869         if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SRV) {
1870             struct bt_mesh_light_xyl_srv *srv = model->user_data;
1871             net_buf_simple_add_u8(msg, srv->state->status_code);
1872             net_buf_simple_add_le16(msg, srv->state->x_range_min);
1873             net_buf_simple_add_le16(msg, srv->state->x_range_max);
1874             net_buf_simple_add_le16(msg, srv->state->y_range_min);
1875             net_buf_simple_add_le16(msg, srv->state->y_range_max);
1876         } else if (model->id == BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV) {
1877             struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
1878             net_buf_simple_add_u8(msg, srv->state->status_code);
1879             net_buf_simple_add_le16(msg, srv->state->x_range_min);
1880             net_buf_simple_add_le16(msg, srv->state->x_range_max);
1881             net_buf_simple_add_le16(msg, srv->state->y_range_min);
1882             net_buf_simple_add_le16(msg, srv->state->y_range_max);
1883         }
1884         break;
1885     default:
1886         BT_WARN("Unknown Light xyL status opcode 0x%04x", opcode);
1887         if (publish == false) {
1888             bt_mesh_free_buf(msg);
1889         }
1890         return;
1891     }
1892 
1893     if (publish == false) {
1894         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
1895         bt_mesh_free_buf(msg);
1896     } else {
1897         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
1898     }
1899     return;
1900 }
1901 
light_xyl_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1902 static void light_xyl_get(struct bt_mesh_model *model,
1903                           struct bt_mesh_msg_ctx *ctx,
1904                           struct net_buf_simple *buf)
1905 {
1906     struct bt_mesh_light_xyl_srv *srv = model->user_data;
1907     uint16_t opcode = 0U;
1908 
1909     if (srv == NULL || srv->state == NULL) {
1910         BT_ERR("%s, Invalid model user data", __func__);
1911         return;
1912     }
1913 
1914     /* Callback the received message to the application layer */
1915     if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1916         bt_mesh_lighting_server_cb_evt_to_btc(
1917             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
1918         return;
1919     }
1920 
1921     switch (ctx->recv_op) {
1922     case BLE_MESH_MODEL_OP_LIGHT_XYL_GET:
1923         opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS;
1924         break;
1925     case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET:
1926         opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS;
1927         break;
1928     case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET:
1929         opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS;
1930         break;
1931     case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET:
1932         opcode = BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS;
1933         break;
1934     default:
1935         BT_WARN("Unknown Light xyL Get opcode 0x%04x", ctx->recv_op);
1936         return;
1937     }
1938 
1939     send_light_xyl_status(model, ctx, false, opcode);
1940     return;
1941 }
1942 
light_xyl_publish(struct bt_mesh_model * model,uint16_t opcode)1943 void light_xyl_publish(struct bt_mesh_model *model, uint16_t opcode)
1944 {
1945     if (model->user_data == NULL) {
1946         BT_ERR("%s, Invalid model user data", __func__);
1947         return;
1948     }
1949 
1950     switch (model->id) {
1951     case BLE_MESH_MODEL_ID_LIGHT_XYL_SRV: {
1952         struct bt_mesh_light_xyl_srv *srv = model->user_data;
1953         if (srv->state == NULL) {
1954             BT_ERR("Invalid Light xyL Server state");
1955             return;
1956         }
1957         break;
1958     }
1959     case BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV: {
1960         struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
1961         if (srv->state == NULL) {
1962             BT_ERR("Invalid Light xyL Setup Server state");
1963             return;
1964         }
1965         break;
1966     }
1967     default:
1968         BT_ERR("Invalid Light xyL Server model 0x%04x", model->id);
1969         return;
1970     }
1971 
1972     send_light_xyl_status(model, NULL, true, opcode);
1973     return;
1974 }
1975 
light_xyl_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1976 static void light_xyl_set(struct bt_mesh_model *model,
1977                           struct bt_mesh_msg_ctx *ctx,
1978                           struct net_buf_simple *buf)
1979 {
1980     struct bt_mesh_light_xyl_srv *srv = model->user_data;
1981     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
1982     uint16_t lightness = 0U, x = 0U, y = 0U;
1983     bool optional = false;
1984     int64_t now = 0;
1985 
1986     if (srv == NULL || srv->state == NULL) {
1987         BT_ERR("%s, Invalid model user data", __func__);
1988         return;
1989     }
1990 
1991     lightness = net_buf_simple_pull_le16(buf);
1992     x = net_buf_simple_pull_le16(buf);
1993     y = net_buf_simple_pull_le16(buf);
1994     tid = net_buf_simple_pull_u8(buf);
1995 
1996     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
1997         return;
1998     }
1999 
2000     /* Callback the received message to the application layer */
2001     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2002         bt_mesh_light_server_recv_set_msg_t set = {
2003             .xyl_set.op_en = optional,
2004             .xyl_set.lightness = lightness,
2005             .xyl_set.x = x,
2006             .xyl_set.y = y,
2007             .xyl_set.tid = tid,
2008             .xyl_set.trans_time = trans_time,
2009             .xyl_set.delay = delay,
2010         };
2011         bt_mesh_lighting_server_cb_evt_to_btc(
2012             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2013         return;
2014     }
2015 
2016     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
2017         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_SET) {
2018             send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
2019         }
2020         send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
2021         /* In this condition, no event will be callback to application layer */
2022         return;
2023     }
2024 
2025     bt_mesh_light_server_lock();
2026 
2027     bt_mesh_server_stop_transition(&srv->transition);
2028     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
2029 
2030     srv->state->target_lightness = lightness;
2031     if (srv->state->x_range_min && x < srv->state->x_range_min) {
2032         x = srv->state->x_range_min;
2033     } else if (srv->state->x_range_max && x > srv->state->x_range_max) {
2034         x = srv->state->x_range_max;
2035     }
2036     srv->state->target_x = x;
2037     if (srv->state->y_range_min && y < srv->state->y_range_min) {
2038         y = srv->state->y_range_min;
2039     } else if (srv->state->y_range_max && y > srv->state->y_range_max) {
2040         y = srv->state->y_range_max;
2041     }
2042     srv->state->target_y = y;
2043 
2044     /**
2045      * If the target state is equal to the current state, the transition shall not
2046      * be started and is considered complete.
2047      */
2048     if (srv->state->target_lightness != srv->state->lightness ||
2049             srv->state->target_x != srv->state->x ||
2050             srv->state->target_y != srv->state->y) {
2051         light_xyl_tt_values(srv, trans_time, delay);
2052     } else {
2053         bt_mesh_light_server_state_change_t change = {
2054             .xyl_set.lightness = srv->state->lightness,
2055             .xyl_set.x = srv->state->x,
2056             .xyl_set.y = srv->state->y,
2057         };
2058         bt_mesh_lighting_server_cb_evt_to_btc(
2059             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2060 
2061         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_SET) {
2062             send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
2063         }
2064         send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
2065 
2066         bt_mesh_light_server_unlock();
2067         return;
2068     }
2069 
2070     /* Copy the ctx of the received message */
2071     if (srv->transition.timer.work._reserved) {
2072         memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
2073     }
2074 
2075     /* For Instantaneous Transition */
2076     if (srv->transition.counter == 0U) {
2077         srv->state->lightness = srv->state->target_lightness;
2078         srv->state->x = srv->state->target_x;
2079         srv->state->y = srv->state->target_y;
2080     }
2081 
2082     srv->transition.just_started = true;
2083     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_SET) {
2084         send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
2085     }
2086     send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
2087 
2088     bt_mesh_light_server_unlock();
2089 
2090     bt_mesh_server_start_transition(&srv->transition);
2091     return;
2092 }
2093 
light_xyl_default_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2094 static void light_xyl_default_set(struct bt_mesh_model *model,
2095                                   struct bt_mesh_msg_ctx *ctx,
2096                                   struct net_buf_simple *buf)
2097 {
2098     struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
2099     uint16_t lightness = 0U, x = 0U, y = 0U;
2100 
2101     if (srv == NULL || srv->state == NULL) {
2102         BT_ERR("%s, Invalid model user data", __func__);
2103         return;
2104     }
2105 
2106     lightness = net_buf_simple_pull_le16(buf);
2107     x = net_buf_simple_pull_le16(buf);
2108     y = net_buf_simple_pull_le16(buf);
2109 
2110     /* Callback the received message to the application layer */
2111     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2112         bt_mesh_light_server_recv_set_msg_t set = {
2113             .xyl_default_set.lightness = lightness,
2114             .xyl_default_set.x = x,
2115             .xyl_default_set.y = y,
2116         };
2117         bt_mesh_lighting_server_cb_evt_to_btc(
2118             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2119         return;
2120     }
2121 
2122     if (srv->state->x_range_min && x < srv->state->x_range_min) {
2123         x = srv->state->x_range_min;
2124     } else if (srv->state->x_range_max && x > srv->state->x_range_max) {
2125         x = srv->state->x_range_max;
2126     }
2127 
2128     if (srv->state->y_range_min && y < srv->state->y_range_min) {
2129         y = srv->state->y_range_min;
2130     } else if (srv->state->y_range_max && y > srv->state->y_range_max) {
2131         y = srv->state->y_range_max;
2132     }
2133 
2134     srv->state->lightness_default = lightness;
2135     srv->state->x_default = x;
2136     srv->state->y_default = y;
2137 
2138     bt_mesh_light_server_state_change_t change = {
2139         .xyl_default_set.lightness = srv->state->lightness_default,
2140         .xyl_default_set.x = srv->state->x_default,
2141         .xyl_default_set.y = srv->state->y_default,
2142     };
2143     bt_mesh_lighting_server_cb_evt_to_btc(
2144         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2145 
2146     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET) {
2147         send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS);
2148     }
2149     send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS);
2150 
2151     return;
2152 }
2153 
light_xyl_range_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2154 static void light_xyl_range_set(struct bt_mesh_model *model,
2155                                 struct bt_mesh_msg_ctx *ctx,
2156                                 struct net_buf_simple *buf)
2157 {
2158     struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
2159     uint16_t x_min = 0U, x_max = 0U, y_min = 0U, y_max = 0U;
2160 
2161     if (srv == NULL || srv->state == NULL) {
2162         BT_ERR("%s, Invalid model user data", __func__);
2163         return;
2164     }
2165 
2166     x_min = net_buf_simple_pull_le16(buf);
2167     x_max = net_buf_simple_pull_le16(buf);
2168     y_min = net_buf_simple_pull_le16(buf);
2169     y_max = net_buf_simple_pull_le16(buf);
2170 
2171     if (x_min > x_max) {
2172         BT_ERR("Invalid parameter, x min 0x%04x, x max 0x%04x",
2173                 x_min, x_max);
2174         return;
2175     }
2176 
2177     if (y_min > y_max) {
2178         BT_ERR("Invalid parameter, y min 0x%04x, y max 0x%04x",
2179                 y_min, y_max);
2180         return;
2181     }
2182 
2183     /* Callback the received message to the application layer */
2184     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2185         bt_mesh_light_server_recv_set_msg_t set = {
2186             .xyl_range_set.x_range_min = x_min,
2187             .xyl_range_set.x_range_max = x_max,
2188             .xyl_range_set.y_range_min = y_min,
2189             .xyl_range_set.y_range_max = y_max,
2190         };
2191         bt_mesh_lighting_server_cb_evt_to_btc(
2192             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2193         return;
2194     }
2195 
2196     srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
2197     srv->state->x_range_min = x_min;
2198     srv->state->x_range_max = x_max;
2199     srv->state->y_range_min = y_min;
2200     srv->state->y_range_max = y_max;
2201 
2202     bt_mesh_light_server_state_change_t change = {
2203         .xyl_range_set.x_range_min = srv->state->x_range_min,
2204         .xyl_range_set.x_range_max = srv->state->x_range_max,
2205         .xyl_range_set.y_range_min = srv->state->y_range_min,
2206         .xyl_range_set.y_range_max = srv->state->y_range_max,
2207     };
2208     bt_mesh_lighting_server_cb_evt_to_btc(
2209         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2210 
2211     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET) {
2212         send_light_xyl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS);
2213     }
2214     send_light_xyl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS);
2215 
2216     return;
2217 }
2218 
2219 /* Light LC Server/Setup Server message handlers */
send_light_lc_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)2220 static void send_light_lc_status(struct bt_mesh_model *model,
2221                                  struct bt_mesh_msg_ctx *ctx,
2222                                  bool publish, uint16_t opcode)
2223 {
2224     struct bt_mesh_light_lc_srv *srv = model->user_data;
2225     struct net_buf_simple *msg = NULL;
2226     uint8_t length = 2 + 3;
2227 
2228     if (ctx == NULL && publish == false) {
2229         BT_ERR("%s, Invalid parameter", __func__);
2230         return;
2231     }
2232 
2233     if (publish == false) {
2234         msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
2235         if (msg == NULL) {
2236             BT_ERR("%s, Out of memory", __func__);
2237             return;
2238         }
2239     } else {
2240         msg = bt_mesh_server_get_pub_msg(model, length);
2241         if (msg == NULL) {
2242             return;
2243         }
2244     }
2245 
2246     bt_mesh_model_msg_init(msg, opcode);
2247     switch (opcode) {
2248     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS:
2249         net_buf_simple_add_u8(msg, srv->lc->state.mode);
2250         break;
2251     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS:
2252         net_buf_simple_add_u8(msg, srv->lc->state.occupancy_mode);
2253         break;
2254     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS:
2255         net_buf_simple_add_u8(msg, srv->lc->state.light_onoff);
2256         if (srv->transition.counter) {
2257             bt_mesh_server_calc_remain_time(&srv->transition);
2258             net_buf_simple_add_u8(msg, srv->lc->state.target_light_onoff);
2259             net_buf_simple_add_u8(msg, srv->transition.remain_time);
2260         }
2261         break;
2262     default:
2263         BT_WARN("Unknown Light LC status opcode 0x%04x", opcode);
2264         if (publish == false) {
2265             bt_mesh_free_buf(msg);
2266         }
2267         return;
2268     }
2269 
2270     if (publish == false) {
2271         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
2272         bt_mesh_free_buf(msg);
2273     } else {
2274         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
2275     }
2276     return;
2277 }
2278 
light_lc_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2279 static void light_lc_get(struct bt_mesh_model *model,
2280                          struct bt_mesh_msg_ctx *ctx,
2281                          struct net_buf_simple *buf)
2282 {
2283     struct bt_mesh_light_lc_srv *srv = model->user_data;
2284     uint16_t opcode = 0U;
2285 
2286     if (srv == NULL || srv->lc == NULL) {
2287         BT_ERR("%s, Invalid model user data", __func__);
2288         return;
2289     }
2290 
2291     /* Callback the received message to the application layer */
2292     if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2293         bt_mesh_lighting_server_cb_evt_to_btc(
2294             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
2295         return;
2296     }
2297 
2298     switch (ctx->recv_op) {
2299     case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET:
2300         opcode = BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS;
2301         break;
2302     case BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET:
2303         opcode = BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS;
2304         break;
2305     case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET:
2306         opcode = BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS;
2307         break;
2308     default:
2309         BT_WARN("Unknown Light LC Get opcode 0x%04x", ctx->recv_op);
2310         return;
2311     }
2312 
2313     send_light_lc_status(model, ctx, false, opcode);
2314     return;
2315 }
2316 
light_lc_publish(struct bt_mesh_model * model,uint16_t opcode)2317 void light_lc_publish(struct bt_mesh_model *model, uint16_t opcode)
2318 {
2319     struct bt_mesh_light_lc_srv *srv = model->user_data;
2320 
2321     if (srv == NULL || srv->lc == NULL) {
2322         BT_ERR("%s, Invalid model user data", __func__);
2323         return;
2324     }
2325 
2326     send_light_lc_status(model, NULL, true, opcode);
2327     return;
2328 }
2329 
light_lc_mode_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2330 static void light_lc_mode_set(struct bt_mesh_model *model,
2331                               struct bt_mesh_msg_ctx *ctx,
2332                               struct net_buf_simple *buf)
2333 {
2334     struct bt_mesh_light_lc_srv *srv = model->user_data;
2335     uint8_t mode = 0U;
2336 
2337     if (srv == NULL || srv->lc == NULL) {
2338         BT_ERR("%s, Invalid model user data", __func__);
2339         return;
2340     }
2341 
2342     mode = net_buf_simple_pull_u8(buf);
2343     if (mode > BLE_MESH_STATE_ON) {
2344         BT_ERR("Invalid LC Mode 0x%02x", mode);
2345         return;
2346     }
2347 
2348     /* Callback the received message to the application layer */
2349     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2350         bt_mesh_light_server_recv_set_msg_t set = {
2351             .lc_mode_set.mode = mode,
2352         };
2353         bt_mesh_lighting_server_cb_evt_to_btc(
2354             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2355         return;
2356     }
2357 
2358     srv->lc->state.mode = mode;
2359 
2360     bt_mesh_light_server_state_change_t change = {
2361         .lc_mode_set.mode = srv->lc->state.mode,
2362     };
2363     bt_mesh_lighting_server_cb_evt_to_btc(
2364         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2365 
2366     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET) {
2367         send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS);
2368     }
2369     send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS);
2370 
2371     return;
2372 }
2373 
light_lc_om_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2374 static void light_lc_om_set(struct bt_mesh_model *model,
2375                             struct bt_mesh_msg_ctx *ctx,
2376                             struct net_buf_simple *buf)
2377 {
2378     struct bt_mesh_light_lc_srv *srv = model->user_data;
2379     uint8_t om = 0U;
2380 
2381     if (srv == NULL || srv->lc == NULL) {
2382         BT_ERR("%s, Invalid model user data", __func__);
2383         return;
2384     }
2385 
2386     om = net_buf_simple_pull_u8(buf);
2387     if (om > BLE_MESH_STATE_ON) {
2388         BT_ERR("Invalid LC Occupancy Mode 0x%02x", om);
2389         return;
2390     }
2391 
2392     /* Callback the received message to the application layer */
2393     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2394         bt_mesh_light_server_recv_set_msg_t set = {
2395             .lc_om_set.mode = om,
2396         };
2397         bt_mesh_lighting_server_cb_evt_to_btc(
2398             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2399         return;
2400     }
2401 
2402     srv->lc->state.occupancy_mode = om;
2403 
2404     bt_mesh_light_server_state_change_t change = {
2405         .lc_om_set.mode = srv->lc->state.occupancy_mode,
2406     };
2407     bt_mesh_lighting_server_cb_evt_to_btc(
2408         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2409 
2410     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET) {
2411         send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS);
2412     }
2413     send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS);
2414 
2415     return;
2416 }
2417 
light_lc_light_onoff_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2418 static void light_lc_light_onoff_set(struct bt_mesh_model *model,
2419                                      struct bt_mesh_msg_ctx *ctx,
2420                                      struct net_buf_simple *buf)
2421 {
2422     struct bt_mesh_light_lc_srv *srv = model->user_data;
2423     uint8_t tid = 0U, trans_time = 0U, delay = 0U;
2424     bool optional = false;
2425     uint8_t onoff = 0U;
2426     int64_t now = 0;
2427 
2428     if (srv == NULL || srv->lc == NULL) {
2429         BT_ERR("%s, Invalid model user data", __func__);
2430         return;
2431     }
2432 
2433     onoff = net_buf_simple_pull_u8(buf);
2434     tid = net_buf_simple_pull_u8(buf);
2435 
2436     if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
2437         return;
2438     }
2439 
2440     /* Callback the received message to the application layer */
2441     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2442         bt_mesh_light_server_recv_set_msg_t set = {
2443             .lc_light_onoff_set.op_en = optional,
2444             .lc_light_onoff_set.light_onoff = onoff,
2445             .lc_light_onoff_set.tid = tid,
2446             .lc_light_onoff_set.trans_time = trans_time,
2447             .lc_light_onoff_set.delay = delay,
2448         };
2449         bt_mesh_lighting_server_cb_evt_to_btc(
2450             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2451         return;
2452     }
2453 
2454     if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
2455         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET) {
2456             send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
2457         }
2458         send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
2459         /* In this condition, no event will be callback to application layer */
2460         return;
2461     }
2462 
2463     bt_mesh_light_server_lock();
2464 
2465     bt_mesh_server_stop_transition(&srv->transition);
2466     bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
2467 
2468     srv->lc->state.target_light_onoff = onoff;
2469 
2470     if (srv->lc->state.target_light_onoff != srv->lc->state.light_onoff) {
2471         light_lc_tt_values(srv, trans_time, delay);
2472     } else {
2473         bt_mesh_light_server_state_change_t change = {
2474             .lc_light_onoff_set.onoff = srv->lc->state.light_onoff,
2475         };
2476         bt_mesh_lighting_server_cb_evt_to_btc(
2477             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2478 
2479         if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET) {
2480             send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
2481         }
2482         send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
2483 
2484         bt_mesh_light_server_unlock();
2485         return;
2486     }
2487 
2488     /* Copy the ctx of the received message */
2489     if (srv->transition.timer.work._reserved) {
2490         memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
2491     }
2492 
2493     /* For Instantaneous Transition */
2494     if (srv->transition.counter == 0U) {
2495         srv->lc->state.light_onoff = srv->lc->state.target_light_onoff;
2496     }
2497 
2498     srv->transition.just_started = true;
2499     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET) {
2500         send_light_lc_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
2501     }
2502     send_light_lc_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
2503 
2504     bt_mesh_light_server_unlock();
2505 
2506     bt_mesh_server_start_transition(&srv->transition);
2507     return;
2508 }
2509 
light_lc_sensor_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2510 static void light_lc_sensor_status(struct bt_mesh_model *model,
2511                                    struct bt_mesh_msg_ctx *ctx,
2512                                    struct net_buf_simple *buf)
2513 {
2514     /**
2515      * When a Light LC Server receives a Sensor Status message, and if the message
2516      * Raw field contains a Raw Value for the Motion Sensed Property, and the value
2517      * is greater than 0, or a Raw Value for the People Count Property, and the
2518      * value is greater than 0, or a Raw Value for the Presence Detected Property,
2519      * and the value is greater than 0, then it shall set the Light LC Occupancy
2520      * state to 0b1.
2521      * If the message Raw field contains a Raw Value for the Time Since Motion Sensed
2522      * device property, which represents a value less than or equal to the value of
2523      * the Light LC Occupancy Delay state, it shall delay setting the Light LC Occupancy
2524      * state to 0b1 by the difference between the value of the Light LC Occupancy Delay
2525      * state and the received Time Since Motion value.
2526      * When a Light LC Server receives a Sensor Status message, and if the message Raw
2527      * field contains a Raw Value for the Present Ambient Light Level device property,
2528      * it shall set the Light LC Ambient LuxLevel state to the Represented Value of the
2529      * received Present Ambient Light Level.
2530      *
2531      * Motion Sensed: 1 octet, 0x0042
2532      * People Count: 2 octets, 0x004C
2533      * Presence Detected: 1 octet, 0x004D
2534      *
2535      * Time Since Motion Sensed: 2 octets, 0x0068
2536      *
2537      * Present Ambient Light Level: 4 octets, 0x004E
2538      */
2539     struct bt_mesh_light_lc_srv *srv = model->user_data;
2540     bt_mesh_light_server_state_change_t change = {0};
2541     uint16_t mpid = 0U, prop_id = 0U;
2542     uint8_t length = 0U;
2543 
2544     if (srv == NULL || srv->lc == NULL) {
2545         BT_ERR("%s, Invalid model user data", __func__);
2546         return;
2547     }
2548 
2549     if (srv->rsp_ctrl.status_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2550         bt_mesh_light_server_recv_status_msg_t status = {
2551             .sensor_status.data = buf,
2552         };
2553         bt_mesh_lighting_server_cb_evt_to_btc(
2554             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_STATUS_MSG, model, ctx, (const uint8_t *)&status, sizeof(status));
2555         return;
2556     }
2557 
2558     mpid = net_buf_simple_pull_le16(buf);
2559     if (mpid & BIT(0)) {
2560         length = (uint8_t)((mpid & 0xff) >> 1);
2561         uint8_t msb = net_buf_simple_pull_u8(buf);
2562         prop_id = (uint16_t)(msb << 8) | (uint16_t)(mpid >> 8);
2563     } else {
2564         length = (uint8_t)((mpid & 0x1f) >> 1);
2565         prop_id = (uint16_t)(mpid >> 5);
2566     }
2567 
2568     change.sensor_status.property_id = prop_id;
2569 
2570     switch (prop_id) {
2571     case BLE_MESH_MOTION_SENSED: {
2572         if (length != BLE_MESH_MOTION_SENSED_LEN || length != buf->len) {
2573             BT_WARN("Invalid Motion Sensed Property length %d", length);
2574             return;
2575         }
2576         uint8_t val = net_buf_simple_pull_u8(buf);
2577         if (val > 0) {
2578             srv->lc->state.occupancy = BLE_MESH_STATE_ON;
2579 
2580             change.sensor_status.state.occupancy = srv->lc->state.occupancy;
2581             bt_mesh_lighting_server_cb_evt_to_btc(
2582                 BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2583         }
2584         break;
2585     }
2586     case BLE_MESH_PEOPLE_COUNT: {
2587         if (length != BLE_MESH_PEOPLE_COUNT_LEN || length != buf->len) {
2588             BT_WARN("Invalid Motion Sensed Property length %d", length);
2589             return;
2590         }
2591         uint16_t val = net_buf_simple_pull_le16(buf);
2592         if (val > 0) {
2593             srv->lc->state.occupancy = BLE_MESH_STATE_ON;
2594 
2595             change.sensor_status.state.occupancy = srv->lc->state.occupancy;
2596             bt_mesh_lighting_server_cb_evt_to_btc(
2597                 BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2598         }
2599         break;
2600     }
2601     case BLE_MESH_PRESENCE_DETECTED: {
2602         if (length != BLE_MESH_PRESENCE_DETECTED_LEN || length != buf->len) {
2603             BT_WARN("Invalid Motion Sensed Property length %d", length);
2604             return;
2605         }
2606         uint8_t val = net_buf_simple_pull_u8(buf);
2607         if (val > 0) {
2608             srv->lc->state.occupancy = BLE_MESH_STATE_ON;
2609 
2610             change.sensor_status.state.occupancy = srv->lc->state.occupancy;
2611             bt_mesh_lighting_server_cb_evt_to_btc(
2612                 BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2613         }
2614         break;
2615     }
2616     case BLE_MESH_TIME_SINCE_MOTION_SENSED: {
2617         if (length != BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN || length != buf->len) {
2618             BT_WARN("Invalid Motion Sensed Property length %d", length);
2619             return;
2620         }
2621         uint16_t val = net_buf_simple_pull_le16(buf);
2622         if (val <= srv->lc->prop_state.time_occupancy_delay) {
2623             srv->lc->prop_state.set_occupancy_to_1_delay =
2624                 srv->lc->prop_state.time_occupancy_delay - val;
2625 
2626             change.sensor_status.state.set_occupancy_to_1_delay = srv->lc->prop_state.set_occupancy_to_1_delay;
2627             bt_mesh_lighting_server_cb_evt_to_btc(
2628                 BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2629         }
2630         break;
2631     }
2632     case BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL: {
2633         /**
2634          * Present Ambient Light Level device property is 4 octets, but ambient
2635          * luxlevel length is 3 octets, and other devices may send Sensor Status
2636          * which only contains 3 octets just for Light LC Server.
2637          * Here we just check if the length is larger than 3.
2638          */
2639         if (buf->len < 3) {
2640             BT_WARN("Invalid Motion Sensed Property length %d", buf->len);
2641             return;
2642         }
2643         uint16_t lsb = net_buf_simple_pull_le16(buf);
2644         uint8_t msb = net_buf_simple_pull_u8(buf);
2645         srv->lc->state.ambient_luxlevel = (msb << 16) | lsb;
2646 
2647         change.sensor_status.state.ambient_luxlevel = srv->lc->state.ambient_luxlevel;
2648         bt_mesh_lighting_server_cb_evt_to_btc(
2649             BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2650         break;
2651     }
2652     default:
2653         break;
2654     }
2655 }
2656 
get_light_lc_prop_val(struct bt_mesh_model * model,uint16_t prop_id)2657 static uint8_t *get_light_lc_prop_val(struct bt_mesh_model *model, uint16_t prop_id)
2658 {
2659     struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
2660     uint8_t *val = NULL;
2661 
2662     switch (prop_id) {
2663     case BLE_MESH_LIGHT_CONTROL_TIME_OCCUPANCY_DELAY:
2664         val = (uint8_t *)&srv->lc->prop_state.time_occupancy_delay;
2665         break;
2666     case BLE_MESH_LIGHT_CONTROL_TIME_FADE_ON:
2667         val = (uint8_t *)&srv->lc->prop_state.time_fade_on;
2668         break;
2669     case BLE_MESH_LIGHT_CONTROL_TIME_RUN_ON:
2670         val = (uint8_t *)&srv->lc->prop_state.time_run_on;
2671         break;
2672     case BLE_MESH_LIGHT_CONTROL_TIME_FADE:
2673         val = (uint8_t *)&srv->lc->prop_state.time_fade;
2674         break;
2675     case BLE_MESH_LIGHT_CONTROL_TIME_PROLONG:
2676         val = (uint8_t *)&srv->lc->prop_state.time_prolong;
2677         break;
2678     case BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_AUTO:
2679         val = (uint8_t *)&srv->lc->prop_state.time_fade_standby_auto;
2680         break;
2681     case BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_MANUAL:
2682         val = (uint8_t *)&srv->lc->prop_state.time_fade_standby_manual;
2683         break;
2684     case BLE_MESH_LIGHT_CONTROL_LIGHTNESS_ON:
2685         val = (uint8_t *)&srv->lc->prop_state.lightness_on;
2686         break;
2687     case BLE_MESH_LIGHT_CONTROL_LIGHTNESS_PROLONG:
2688         val = (uint8_t *)&srv->lc->prop_state.lightness_prolong;
2689         break;
2690     case BLE_MESH_LIGHT_CONTROL_LIGHTNESS_STANDBY:
2691         val = (uint8_t *)&srv->lc->prop_state.lightness_standby;
2692         break;
2693     case BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_ON:
2694         val = (uint8_t *)&srv->lc->prop_state.ambient_luxlevel_on;
2695         break;
2696     case BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_PROLONG:
2697         val = (uint8_t *)&srv->lc->prop_state.ambient_luxlevel_prolong;
2698         break;
2699     case BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_STANDBY:
2700         val = (uint8_t *)&srv->lc->prop_state.ambient_luxlevel_standby;
2701         break;
2702     case BLE_MESH_LIGHT_CONTROL_REGULATOR_KIU:
2703         val = (uint8_t *)&srv->lc->prop_state.regulator_kiu;
2704         break;
2705     case BLE_MESH_LIGHT_CONTROL_REGULATOR_KID:
2706         val = (uint8_t *)&srv->lc->prop_state.regulator_kid;
2707         break;
2708     case BLE_MESH_LIGHT_CONTROL_REGULATOR_KPU:
2709         val = (uint8_t *)&srv->lc->prop_state.regulator_kpu;
2710         break;
2711     case BLE_MESH_LIGHT_CONTROL_REGULATOR_KPD:
2712         val = (uint8_t *)&srv->lc->prop_state.regulator_kpd;
2713         break;
2714     case BLE_MESH_LIGHT_CONTROL_REGULATOR_ACCURACY:
2715         val = (uint8_t *)&srv->lc->prop_state.regulator_accuracy;
2716         break;
2717     }
2718 
2719     return val;
2720 }
2721 
bt_mesh_get_lc_prop_value(struct bt_mesh_model * model,uint16_t prop_id)2722 uint8_t *bt_mesh_get_lc_prop_value(struct bt_mesh_model *model, uint16_t prop_id)
2723 {
2724     if (model == NULL) {
2725         BT_ERR("%s, Invalid parameter", __func__);
2726         return NULL;
2727     }
2728 
2729     return get_light_lc_prop_val(model, prop_id);
2730 }
2731 
send_light_lc_prop_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t prop_id,bool publish)2732 static void send_light_lc_prop_status(struct bt_mesh_model *model,
2733                                       struct bt_mesh_msg_ctx *ctx,
2734                                       uint16_t prop_id, bool publish)
2735 {
2736     struct net_buf_simple *msg = NULL;
2737     uint8_t length = 1 + 2 + 4;
2738     uint8_t *prop_val = NULL;
2739 
2740     prop_val = get_light_lc_prop_val(model, prop_id);
2741     if (prop_val == NULL) {
2742         BT_ERR("Failed to get Light LC Property value");
2743         return;
2744     }
2745 
2746     if (publish == false) {
2747         msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
2748         if (msg == NULL) {
2749             BT_ERR("%s, Out of memory", __func__);
2750             return;
2751         }
2752     } else {
2753         msg = bt_mesh_server_get_pub_msg(model, length);
2754         if (msg == NULL) {
2755             return;
2756         }
2757     }
2758 
2759     bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS);
2760     net_buf_simple_add_le16(msg, prop_id);
2761     net_buf_simple_add_mem(msg, prop_val, bt_mesh_get_dev_prop_len(prop_id));
2762 
2763     if (publish == false) {
2764         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
2765         bt_mesh_free_buf(msg);
2766     } else {
2767         BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
2768     }
2769     return;
2770 }
2771 
light_lc_prop_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2772 static void light_lc_prop_get(struct bt_mesh_model *model,
2773                               struct bt_mesh_msg_ctx *ctx,
2774                               struct net_buf_simple *buf)
2775 {
2776     struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
2777     uint16_t prop_id = 0U;
2778 
2779     if (srv == NULL || srv->lc == NULL) {
2780         BT_ERR("%s, Invalid model user data", __func__);
2781         return;
2782     }
2783 
2784     prop_id = net_buf_simple_pull_le16(buf);
2785     if (prop_id < 0x002B || prop_id > 0x003C) {
2786         BT_ERR("Invalid Light LC Property ID 0x%04x", prop_id);
2787         return;
2788     }
2789 
2790     /* Callback the received message to the application layer */
2791     if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2792         bt_mesh_light_server_recv_get_msg_t get = {
2793             .lc_property_get.id = net_buf_simple_pull_le16(buf),
2794         };
2795         bt_mesh_lighting_server_cb_evt_to_btc(
2796             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG, model, ctx, (const uint8_t *)&get, sizeof(get));
2797         return;
2798     }
2799 
2800     send_light_lc_prop_status(model, ctx, prop_id, false);
2801     return;
2802 }
2803 
light_lc_prop_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2804 static void light_lc_prop_set(struct bt_mesh_model *model,
2805                               struct bt_mesh_msg_ctx *ctx,
2806                               struct net_buf_simple *buf)
2807 {
2808     struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
2809     uint8_t *prop_val = NULL, expect_len = 0U;
2810     uint16_t prop_id = 0U;
2811 
2812     if (srv == NULL || srv->lc == NULL) {
2813         BT_ERR("%s, Invalid model user data", __func__);
2814         return;
2815     }
2816 
2817     prop_id = net_buf_simple_pull_le16(buf);
2818     if (prop_id < 0x002B || prop_id > 0x003C) {
2819         BT_ERR("Invalid Light LC Property ID 0x%04x", prop_id);
2820         return;
2821     }
2822 
2823     if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2824         bt_mesh_light_server_recv_set_msg_t set = {
2825             .lc_property_set.id = net_buf_simple_pull_le16(buf),
2826             .lc_property_set.value = buf,
2827         };
2828         bt_mesh_lighting_server_cb_evt_to_btc(
2829             BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2830         return;
2831     }
2832 
2833     expect_len = bt_mesh_get_dev_prop_len(prop_id);
2834     if (buf->len != expect_len) {
2835         BT_ERR("Invalid Light LC Property 0x%04x length, expect %d, actual %d",
2836                 prop_id, expect_len, buf->len);
2837         return;
2838     }
2839 
2840     prop_val = get_light_lc_prop_val(model, prop_id);
2841     if (prop_val == NULL) {
2842         BT_ERR("Failed to get Light LC Property value");
2843         return;
2844     }
2845 
2846     memcpy(prop_val, buf->data, buf->len);
2847 
2848     bt_mesh_light_server_state_change_t change = {
2849         .lc_property_set.id = prop_id,
2850         .lc_property_set.value = buf,
2851     };
2852     bt_mesh_lighting_server_cb_evt_to_btc(
2853         BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2854 
2855     if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET) {
2856         send_light_lc_prop_status(model, ctx, prop_id, false);
2857     }
2858     send_light_lc_prop_status(model, ctx, prop_id, true);
2859 
2860     return;
2861 }
2862 
2863 /* message handlers (End) */
2864 
2865 /* Mapping of message handlers for Light Lightness Server (0x1300) */
2866 const struct bt_mesh_model_op bt_mesh_light_lightness_srv_op[] = {
2867     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET,              0, light_lightness_get        },
2868     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET,              3, light_lightness_set        },
2869     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK,        3, light_lightness_set        },
2870     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET,       0, light_lightness_get        },
2871     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET,       3, light_lightness_linear_set },
2872     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK, 3, light_lightness_linear_set },
2873     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET,         0, light_lightness_get        },
2874     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET,      0, light_lightness_get        },
2875     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET,        0, light_lightness_get        },
2876     BLE_MESH_MODEL_OP_END,
2877 };
2878 
2879 /* Mapping of message handlers for Light Lightness Setup Server (0x1301) */
2880 const struct bt_mesh_model_op bt_mesh_light_lightness_setup_srv_op[] = {
2881     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET,       2, light_lightness_default_set },
2882     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK, 2, light_lightness_default_set },
2883     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET,         4, light_lightness_range_set   },
2884     { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK,   4, light_lightness_range_set   },
2885     BLE_MESH_MODEL_OP_END,
2886 };
2887 
2888 /* Mapping of message handlers for Light CTL Server (0x1303) */
2889 const struct bt_mesh_model_op bt_mesh_light_ctl_srv_op[] = {
2890     { BLE_MESH_MODEL_OP_LIGHT_CTL_GET,                   0, light_ctl_get },
2891     { BLE_MESH_MODEL_OP_LIGHT_CTL_SET,                   7, light_ctl_set },
2892     { BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK,             7, light_ctl_set },
2893     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET, 0, light_ctl_get },
2894     { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET,           0, light_ctl_get },
2895     BLE_MESH_MODEL_OP_END,
2896 };
2897 
2898 /* Mapping of message handlers for Light CTL Setup Server (0x1304) */
2899 const struct bt_mesh_model_op bt_mesh_light_ctl_setup_srv_op[] = {
2900     { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET,                 6, light_ctl_default_set    },
2901     { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK,           6, light_ctl_default_set    },
2902     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET,       4, light_ctl_temp_range_set },
2903     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK, 4, light_ctl_temp_range_set },
2904     BLE_MESH_MODEL_OP_END,
2905 };
2906 
2907 /* Mapping of message handlers for Light CTL Temperature Server (0x1306) */
2908 const struct bt_mesh_model_op bt_mesh_light_ctl_temp_srv_op[] = {
2909     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET,       0, light_ctl_get      },
2910     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET,       5, light_ctl_temp_set },
2911     { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK, 5, light_ctl_temp_set },
2912     BLE_MESH_MODEL_OP_END,
2913 };
2914 
2915 /* Mapping of message handlers for Light HSL Server (0x1307) */
2916 const struct bt_mesh_model_op bt_mesh_light_hsl_srv_op[] = {
2917     { BLE_MESH_MODEL_OP_LIGHT_HSL_GET,         0, light_hsl_get },
2918     { BLE_MESH_MODEL_OP_LIGHT_HSL_SET,         7, light_hsl_set },
2919     { BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK,   7, light_hsl_set },
2920     { BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET,  0, light_hsl_get },
2921     { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET, 0, light_hsl_get },
2922     { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET,   0, light_hsl_get },
2923     BLE_MESH_MODEL_OP_END,
2924 };
2925 
2926 /* Mapping of message handlers for Light HSL Setup Server (0x1308) */
2927 const struct bt_mesh_model_op bt_mesh_light_hsl_setup_srv_op[] = {
2928     { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET,       6, light_hsl_default_set },
2929     { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK, 6, light_hsl_default_set },
2930     { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET,         8, light_hsl_range_set   },
2931     { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK,   8, light_hsl_range_set   },
2932     BLE_MESH_MODEL_OP_END,
2933 };
2934 
2935 /* Mapping of message handlers for Light HSL Hue Server (0x130A) */
2936 const struct bt_mesh_model_op bt_mesh_light_hsl_hue_srv_op[] = {
2937     { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET,       0, light_hsl_get     },
2938     { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET,       3, light_hsl_hue_set },
2939     { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK, 3, light_hsl_hue_set },
2940     BLE_MESH_MODEL_OP_END,
2941 };
2942 
2943 /* Mapping of message handlers for Light HSL Saturation Server (0x130B) */
2944 const struct bt_mesh_model_op bt_mesh_light_hsl_sat_srv_op[] = {
2945     { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET,       0, light_hsl_get     },
2946     { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET,       3, light_hsl_sat_set },
2947     { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK, 3, light_hsl_sat_set },
2948     BLE_MESH_MODEL_OP_END,
2949 };
2950 
2951 /* Mapping of message handlers for Light xyL Server (0x130C) */
2952 const struct bt_mesh_model_op bt_mesh_light_xyl_srv_op[] = {
2953     { BLE_MESH_MODEL_OP_LIGHT_XYL_GET,         0, light_xyl_get },
2954     { BLE_MESH_MODEL_OP_LIGHT_XYL_SET,         7, light_xyl_set },
2955     { BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK,   7, light_xyl_set },
2956     { BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET,  0, light_xyl_get },
2957     { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET, 0, light_xyl_get },
2958     { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET,   0, light_xyl_get },
2959     BLE_MESH_MODEL_OP_END,
2960 };
2961 
2962 /* Mapping of message handlers for Light xyL Setup Server (0x130D) */
2963 const struct bt_mesh_model_op bt_mesh_light_xyl_setup_srv_op[] = {
2964     { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET,       6, light_xyl_default_set },
2965     { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK, 6, light_xyl_default_set },
2966     { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET,         8, light_xyl_range_set   },
2967     { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK,   8, light_xyl_range_set   },
2968     BLE_MESH_MODEL_OP_END,
2969 };
2970 
2971 /* Mapping of message handlers for Light LC Server (0x130F) */
2972 const struct bt_mesh_model_op bt_mesh_light_lc_srv_op[] = {
2973     { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET,              0, light_lc_get             },
2974     { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET,              1, light_lc_mode_set        },
2975     { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK,        1, light_lc_mode_set        },
2976     { BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET,                0, light_lc_get             },
2977     { BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET,                1, light_lc_om_set          },
2978     { BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK,          1, light_lc_om_set          },
2979     { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET,       0, light_lc_get             },
2980     { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET,       2, light_lc_light_onoff_set },
2981     { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK, 2, light_lc_light_onoff_set },
2982     { BLE_MESH_MODEL_OP_SENSOR_STATUS,                  3, light_lc_sensor_status   },
2983     BLE_MESH_MODEL_OP_END,
2984 };
2985 
2986 /* Mapping of message handlers for Light LC Setup Server (0x1310) */
2987 const struct bt_mesh_model_op bt_mesh_light_lc_setup_srv_op[] = {
2988     { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET,       2, light_lc_prop_get },
2989     { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET,       3, light_lc_prop_set },
2990     { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK, 3, light_lc_prop_set },
2991     BLE_MESH_MODEL_OP_END,
2992 };
2993 
light_server_init(struct bt_mesh_model * model)2994 static int light_server_init(struct bt_mesh_model *model)
2995 {
2996     if (model->user_data == NULL) {
2997         BT_ERR("Invalid Lighting Server user data, model id 0x%04x", model->id);
2998         return -EINVAL;
2999     }
3000 
3001     switch (model->id) {
3002     case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV: {
3003         struct bt_mesh_light_lightness_srv *srv = model->user_data;
3004         if (srv->state == NULL) {
3005             BT_ERR("Invalid Light Lightness State");
3006             return -EINVAL;
3007         }
3008         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3009             bt_mesh_server_alloc_ctx(&srv->actual_transition.timer.work);
3010             bt_mesh_server_alloc_ctx(&srv->linear_transition.timer.work);
3011             k_delayed_work_init(&srv->actual_transition.timer, light_lightness_actual_work_handler);
3012             k_delayed_work_init(&srv->linear_transition.timer, light_lightness_linear_work_handler);
3013         }
3014         srv->model = model;
3015         break;
3016     }
3017     case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV: {
3018         struct bt_mesh_light_lightness_setup_srv *srv = model->user_data;
3019         if (srv->state == NULL) {
3020             BT_ERR("Invalid Light Lightness State");
3021             return -EINVAL;
3022         }
3023         srv->model = model;
3024         break;
3025     }
3026     case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
3027         struct bt_mesh_light_ctl_srv *srv = model->user_data;
3028         if (srv->state == NULL) {
3029             BT_ERR("Invalid Light CTL State");
3030             return -EINVAL;
3031         }
3032         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3033             bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
3034             k_delayed_work_init(&srv->transition.timer, light_ctl_work_handler);
3035         }
3036         srv->model = model;
3037         break;
3038     }
3039     case BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV: {
3040         struct bt_mesh_light_ctl_setup_srv *srv = model->user_data;
3041         if (srv->state == NULL) {
3042             BT_ERR("Invalid Light CTL State");
3043             return -EINVAL;
3044         }
3045         srv->model = model;
3046         break;
3047     }
3048     case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
3049         struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
3050         if (srv->state == NULL) {
3051             BT_ERR("Invalid Light CTL State");
3052             return -EINVAL;
3053         }
3054         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3055             bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
3056             k_delayed_work_init(&srv->transition.timer, light_ctl_temp_work_handler);
3057         }
3058         srv->model = model;
3059         break;
3060     }
3061     case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
3062         struct bt_mesh_light_hsl_srv *srv = model->user_data;
3063         if (srv->state == NULL) {
3064             BT_ERR("Invalid Light HSL State");
3065             return -EINVAL;
3066         }
3067         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3068             bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
3069             k_delayed_work_init(&srv->transition.timer, light_hsl_work_handler);
3070         }
3071         srv->model = model;
3072         break;
3073     }
3074     case BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV: {
3075         struct bt_mesh_light_hsl_setup_srv *srv = model->user_data;
3076         if (srv->state == NULL) {
3077             BT_ERR("Invalid Light HSL State");
3078             return -EINVAL;
3079         }
3080         srv->model = model;
3081         break;
3082     }
3083     case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
3084         struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
3085         if (srv->state == NULL) {
3086             BT_ERR("Invalid Light HSL State");
3087             return -EINVAL;
3088         }
3089         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3090             bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
3091             k_delayed_work_init(&srv->transition.timer, light_hsl_hue_work_handler);
3092         }
3093         srv->model = model;
3094         break;
3095     }
3096     case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
3097         struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
3098         if (srv->state == NULL) {
3099             BT_ERR("Invalid Light HSL State");
3100             return -EINVAL;
3101         }
3102         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3103             bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
3104             k_delayed_work_init(&srv->transition.timer, light_hsl_sat_work_handler);
3105         }
3106         srv->model = model;
3107         break;
3108     }
3109     case BLE_MESH_MODEL_ID_LIGHT_XYL_SRV: {
3110         struct bt_mesh_light_xyl_srv *srv = model->user_data;
3111         if (srv->state == NULL) {
3112             BT_ERR("Invalid Light xyL State");
3113             return -EINVAL;
3114         }
3115         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3116             bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
3117             k_delayed_work_init(&srv->transition.timer, light_xyl_work_handler);
3118         }
3119         srv->model = model;
3120         break;
3121     }
3122     case BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV: {
3123         struct bt_mesh_light_xyl_setup_srv *srv = model->user_data;
3124         if (srv->state == NULL) {
3125             BT_ERR("Invalid Light xyL State");
3126             return -EINVAL;
3127         }
3128         srv->model = model;
3129         break;
3130     }
3131     case BLE_MESH_MODEL_ID_LIGHT_LC_SRV: {
3132         struct bt_mesh_light_lc_srv *srv = model->user_data;
3133         if (srv->lc == NULL) {
3134             BT_ERR("Invalid Light LC State");
3135             return -EINVAL;
3136         }
3137         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3138             bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
3139             k_delayed_work_init(&srv->transition.timer, light_lc_work_handler);
3140         }
3141         srv->model = model;
3142         break;
3143     }
3144     case BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV: {
3145         struct bt_mesh_light_lc_setup_srv *srv = model->user_data;
3146         if (srv->lc == NULL) {
3147             BT_ERR("Invalid Light LC State");
3148             return -EINVAL;
3149         }
3150         srv->model = model;
3151         break;
3152     }
3153     default:
3154         BT_WARN("Unknown Light Server, model id 0x%04x", model->id);
3155         return -EINVAL;
3156     }
3157 
3158     bt_mesh_light_server_mutex_new();
3159 
3160     return 0;
3161 }
3162 
light_lightness_srv_init(struct bt_mesh_model * model)3163 static int light_lightness_srv_init(struct bt_mesh_model *model)
3164 {
3165     if (model->pub == NULL) {
3166         BT_ERR("Light Lightness Server has no publication support");
3167         return -EINVAL;
3168     }
3169 
3170     /* When this model is present on an Element, the corresponding Light Lightness
3171      * Setup Server model shall also be present.
3172      */
3173     struct bt_mesh_elem *element = bt_mesh_model_elem(model);
3174     if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV) == NULL) {
3175         BT_WARN("Light Lightness Setup Server not present");
3176         /* Just give a warning here, continue with the initialization */
3177     }
3178     return light_server_init(model);
3179 }
3180 
light_lightness_setup_srv_init(struct bt_mesh_model * model)3181 static int light_lightness_setup_srv_init(struct bt_mesh_model *model)
3182 {
3183     return light_server_init(model);
3184 }
3185 
light_ctl_srv_init(struct bt_mesh_model * model)3186 static int light_ctl_srv_init(struct bt_mesh_model *model)
3187 {
3188     if (model->pub == NULL) {
3189         BT_ERR("Light CTL Server has no publication support");
3190         return -EINVAL;
3191     }
3192 
3193     /**
3194      * When this model is present on an Element, the corresponding Light CTL
3195      * Temperature Server model and the corresponding Light CTL Setup Server
3196      * model shall also be present.
3197      * The model requires two elements: the main element and the Temperature
3198      * element. The Temperature element contains the corresponding Light CTL
3199      * Temperature Server model.
3200      */
3201     struct bt_mesh_elem *element = bt_mesh_model_elem(model);
3202     if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV) == NULL) {
3203         BT_WARN("Light CTL Setup Server not present");
3204         /* Just give a warning here, continue with the initialization */
3205     }
3206     if (bt_mesh_elem_count() < 2) {
3207         BT_WARN("Light CTL Server requires two elements");
3208         /* Just give a warning here, continue with the initialization */
3209     }
3210     return light_server_init(model);
3211 }
3212 
light_ctl_setup_srv_init(struct bt_mesh_model * model)3213 static int light_ctl_setup_srv_init(struct bt_mesh_model *model)
3214 {
3215     return light_server_init(model);
3216 }
3217 
light_ctl_temp_srv_init(struct bt_mesh_model * model)3218 static int light_ctl_temp_srv_init(struct bt_mesh_model *model)
3219 {
3220     if (model->pub == NULL) {
3221         BT_ERR("Light CTL Temperature Server has no publication support");
3222         return -EINVAL;
3223     }
3224 
3225     return light_server_init(model);
3226 }
3227 
light_hsl_srv_init(struct bt_mesh_model * model)3228 static int light_hsl_srv_init(struct bt_mesh_model *model)
3229 {
3230     if (model->pub == NULL) {
3231         BT_ERR("Light HSL Server has no publication support");
3232         return -EINVAL;
3233     }
3234 
3235     /**
3236      * When this model is present on an Element, the corresponding Light HSL Hue
3237      * Server model and the corresponding Light HSL Saturation Server model and
3238      * the corresponding Light HSL Setup Server model shall also be present.
3239      * The model requires three elements: the main element and the Hue element
3240      * and the Saturation element. The Hue element contains the corresponding
3241      * Light HSL Hue Server model, and the Saturation element contains the corr-
3242      * esponding Light HSL Saturation Server model.
3243      */
3244     struct bt_mesh_elem *element = bt_mesh_model_elem(model);
3245     if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV) == NULL) {
3246         BT_WARN("Light HSL Setup Server not present");
3247         /* Just give a warning here, continue with the initialization */
3248     }
3249     if (bt_mesh_elem_count() < 3) {
3250         BT_WARN("Light HSL Server requires three elements");
3251         /* Just give a warning here, continue with the initialization */
3252     }
3253     return light_server_init(model);
3254 }
3255 
light_hsl_setup_srv_init(struct bt_mesh_model * model)3256 static int light_hsl_setup_srv_init(struct bt_mesh_model *model)
3257 {
3258     return light_server_init(model);
3259 }
3260 
light_hsl_hue_srv_init(struct bt_mesh_model * model)3261 static int light_hsl_hue_srv_init(struct bt_mesh_model *model)
3262 {
3263     if (model->pub == NULL) {
3264         BT_ERR("Light HSL Hue Server has no publication support");
3265         return -EINVAL;
3266     }
3267 
3268     return light_server_init(model);
3269 }
3270 
light_hsl_sat_srv_init(struct bt_mesh_model * model)3271 static int light_hsl_sat_srv_init(struct bt_mesh_model *model)
3272 {
3273     if (model->pub == NULL) {
3274         BT_ERR("Light HSL Saturation Server has no publication support");
3275         return -EINVAL;
3276     }
3277 
3278     return light_server_init(model);
3279 }
3280 
light_xyl_srv_init(struct bt_mesh_model * model)3281 static int light_xyl_srv_init(struct bt_mesh_model *model)
3282 {
3283     if (model->pub == NULL) {
3284         BT_ERR("Light xyL Server has no publication support");
3285         return -EINVAL;
3286     }
3287 
3288     /**
3289      * When this model is present on an Element, the corresponding Light xyL
3290      * Setup Server model shall also be present.
3291      */
3292     struct bt_mesh_elem *element = bt_mesh_model_elem(model);
3293     if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV) == NULL) {
3294         BT_WARN("Light xyL Setup Server not present");
3295         /* Just give a warning here, continue with the initialization */
3296     }
3297     return light_server_init(model);
3298 }
3299 
light_xyl_setup_srv_init(struct bt_mesh_model * model)3300 static int light_xyl_setup_srv_init(struct bt_mesh_model *model)
3301 {
3302     return light_server_init(model);
3303 }
3304 
light_lc_srv_init(struct bt_mesh_model * model)3305 static int light_lc_srv_init(struct bt_mesh_model *model)
3306 {
3307     if (model->pub == NULL) {
3308         BT_ERR("Light LC Server has no publication support");
3309         return -EINVAL;
3310     }
3311 
3312     return light_server_init(model);
3313 }
3314 
light_lc_setup_srv_init(struct bt_mesh_model * model)3315 static int light_lc_setup_srv_init(struct bt_mesh_model *model)
3316 {
3317     if (model->pub == NULL) {
3318         BT_ERR("Light LC Setup Server has no publication support");
3319         return -EINVAL;
3320     }
3321 
3322     /**
3323      * When this model is present on an Element, the corresponding Light LC
3324      * Setup Server model shall also be present.
3325      */
3326     struct bt_mesh_elem *element = bt_mesh_model_elem(model);
3327     if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV) == NULL) {
3328         BT_WARN("Light LC Setup Server not present");
3329         /* Just give a warning here, continue with the initialization */
3330     }
3331     return light_server_init(model);
3332 }
3333 
3334 #if CONFIG_BLE_MESH_DEINIT
light_server_deinit(struct bt_mesh_model * model)3335 static int light_server_deinit(struct bt_mesh_model *model)
3336 {
3337     if (model->user_data == NULL) {
3338         BT_ERR("Invalid Lighting Server user data, model id 0x%04x", model->id);
3339         return -EINVAL;
3340     }
3341 
3342     switch (model->id) {
3343     case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV: {
3344         struct bt_mesh_light_lightness_srv *srv = model->user_data;
3345         if (srv->state == NULL) {
3346             BT_ERR("Invalid Light Lightness State");
3347             return -EINVAL;
3348         }
3349         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3350             bt_mesh_server_free_ctx(&srv->actual_transition.timer.work);
3351             bt_mesh_server_free_ctx(&srv->linear_transition.timer.work);
3352             k_delayed_work_free(&srv->actual_transition.timer);
3353             k_delayed_work_free(&srv->linear_transition.timer);
3354         }
3355         break;
3356     }
3357     case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: {
3358         struct bt_mesh_light_ctl_srv *srv = model->user_data;
3359         if (srv->state == NULL) {
3360             BT_ERR("Invalid Light CTL State");
3361             return -EINVAL;
3362         }
3363         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3364             bt_mesh_server_free_ctx(&srv->transition.timer.work);
3365             k_delayed_work_free(&srv->transition.timer);
3366         }
3367         break;
3368     }
3369     case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: {
3370         struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
3371         if (srv->state == NULL) {
3372             BT_ERR("Invalid Light CTL State");
3373             return -EINVAL;
3374         }
3375         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3376             bt_mesh_server_free_ctx(&srv->transition.timer.work);
3377             k_delayed_work_free(&srv->transition.timer);
3378         }
3379         break;
3380     }
3381     case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: {
3382         struct bt_mesh_light_hsl_srv *srv = model->user_data;
3383         if (srv->state == NULL) {
3384             BT_ERR("Invalid Light HSL State");
3385             return -EINVAL;
3386         }
3387         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3388             bt_mesh_server_free_ctx(&srv->transition.timer.work);
3389             k_delayed_work_free(&srv->transition.timer);
3390         }
3391         break;
3392     }
3393     case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: {
3394         struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
3395         if (srv->state == NULL) {
3396             BT_ERR("Invalid Light HSL State");
3397             return -EINVAL;
3398         }
3399         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3400             bt_mesh_server_free_ctx(&srv->transition.timer.work);
3401             k_delayed_work_free(&srv->transition.timer);
3402         }
3403         break;
3404     }
3405     case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: {
3406         struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
3407         if (srv->state == NULL) {
3408             BT_ERR("Invalid Light HSL State");
3409             return -EINVAL;
3410         }
3411         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3412             bt_mesh_server_free_ctx(&srv->transition.timer.work);
3413             k_delayed_work_free(&srv->transition.timer);
3414         }
3415         break;
3416     }
3417     case BLE_MESH_MODEL_ID_LIGHT_XYL_SRV: {
3418         struct bt_mesh_light_xyl_srv *srv = model->user_data;
3419         if (srv->state == NULL) {
3420             BT_ERR("Invalid Light xyL State");
3421             return -EINVAL;
3422         }
3423         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3424             bt_mesh_server_free_ctx(&srv->transition.timer.work);
3425             k_delayed_work_free(&srv->transition.timer);
3426         }
3427         break;
3428     }
3429     case BLE_MESH_MODEL_ID_LIGHT_LC_SRV: {
3430         struct bt_mesh_light_lc_srv *srv = model->user_data;
3431         if (srv->lc == NULL) {
3432             BT_ERR("Invalid Light LC State");
3433             return -EINVAL;
3434         }
3435         if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
3436             bt_mesh_server_free_ctx(&srv->transition.timer.work);
3437             k_delayed_work_free(&srv->transition.timer);
3438         }
3439         break;
3440     }
3441     case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV:
3442     case BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV:
3443     case BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV:
3444     case BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV:
3445     case BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV:
3446         break;
3447     default:
3448         BT_WARN("Unknown Light Server, model id 0x%04x", model->id);
3449         return -EINVAL;
3450     }
3451 
3452     bt_mesh_light_server_mutex_free();
3453 
3454     return 0;
3455 }
3456 
light_lightness_srv_deinit(struct bt_mesh_model * model)3457 static int light_lightness_srv_deinit(struct bt_mesh_model *model)
3458 {
3459     if (model->pub == NULL) {
3460         BT_ERR("Light Lightness Server has no publication support");
3461         return -EINVAL;
3462     }
3463 
3464     return light_server_deinit(model);
3465 }
3466 
light_lightness_setup_srv_deinit(struct bt_mesh_model * model)3467 static int light_lightness_setup_srv_deinit(struct bt_mesh_model *model)
3468 {
3469     return light_server_deinit(model);
3470 }
3471 
light_ctl_srv_deinit(struct bt_mesh_model * model)3472 static int light_ctl_srv_deinit(struct bt_mesh_model *model)
3473 {
3474     if (model->pub == NULL) {
3475         BT_ERR("Light CTL Server has no publication support");
3476         return -EINVAL;
3477     }
3478 
3479     return light_server_deinit(model);
3480 }
3481 
light_ctl_setup_srv_deinit(struct bt_mesh_model * model)3482 static int light_ctl_setup_srv_deinit(struct bt_mesh_model *model)
3483 {
3484     return light_server_deinit(model);
3485 }
3486 
light_ctl_temp_srv_deinit(struct bt_mesh_model * model)3487 static int light_ctl_temp_srv_deinit(struct bt_mesh_model *model)
3488 {
3489     if (model->pub == NULL) {
3490         BT_ERR("Light CTL Temperature Server has no publication support");
3491         return -EINVAL;
3492     }
3493 
3494     return light_server_deinit(model);
3495 }
3496 
light_hsl_srv_deinit(struct bt_mesh_model * model)3497 static int light_hsl_srv_deinit(struct bt_mesh_model *model)
3498 {
3499     if (model->pub == NULL) {
3500         BT_ERR("Light HSL Server has no publication support");
3501         return -EINVAL;
3502     }
3503 
3504     return light_server_deinit(model);
3505 }
3506 
light_hsl_setup_srv_deinit(struct bt_mesh_model * model)3507 static int light_hsl_setup_srv_deinit(struct bt_mesh_model *model)
3508 {
3509     return light_server_deinit(model);
3510 }
3511 
light_hsl_hue_srv_deinit(struct bt_mesh_model * model)3512 static int light_hsl_hue_srv_deinit(struct bt_mesh_model *model)
3513 {
3514     if (model->pub == NULL) {
3515         BT_ERR("Light HSL Hue Server has no publication support");
3516         return -EINVAL;
3517     }
3518 
3519     return light_server_deinit(model);
3520 }
3521 
light_hsl_sat_srv_deinit(struct bt_mesh_model * model)3522 static int light_hsl_sat_srv_deinit(struct bt_mesh_model *model)
3523 {
3524     if (model->pub == NULL) {
3525         BT_ERR("Light HSL Saturation Server has no publication support");
3526         return -EINVAL;
3527     }
3528 
3529     return light_server_deinit(model);
3530 }
3531 
light_xyl_srv_deinit(struct bt_mesh_model * model)3532 static int light_xyl_srv_deinit(struct bt_mesh_model *model)
3533 {
3534     if (model->pub == NULL) {
3535         BT_ERR("Light xyL Server has no publication support");
3536         return -EINVAL;
3537     }
3538 
3539     return light_server_deinit(model);
3540 }
3541 
light_xyl_setup_srv_deinit(struct bt_mesh_model * model)3542 static int light_xyl_setup_srv_deinit(struct bt_mesh_model *model)
3543 {
3544     return light_server_deinit(model);
3545 }
3546 
light_lc_srv_deinit(struct bt_mesh_model * model)3547 static int light_lc_srv_deinit(struct bt_mesh_model *model)
3548 {
3549     if (model->pub == NULL) {
3550         BT_ERR("Light LC Server has no publication support");
3551         return -EINVAL;
3552     }
3553 
3554     return light_server_deinit(model);
3555 }
3556 
light_lc_setup_srv_deinit(struct bt_mesh_model * model)3557 static int light_lc_setup_srv_deinit(struct bt_mesh_model *model)
3558 {
3559     if (model->pub == NULL) {
3560         BT_ERR("Light LC Setup Server has no publication support");
3561         return -EINVAL;
3562     }
3563 
3564     return light_server_deinit(model);
3565 }
3566 #endif /* CONFIG_BLE_MESH_DEINIT */
3567 
3568 const struct bt_mesh_model_cb bt_mesh_light_lightness_srv_cb = {
3569     .init = light_lightness_srv_init,
3570 #if CONFIG_BLE_MESH_DEINIT
3571     .deinit = light_lightness_srv_deinit,
3572 #endif /* CONFIG_BLE_MESH_DEINIT */
3573 };
3574 
3575 const struct bt_mesh_model_cb bt_mesh_light_lightness_setup_srv_cb = {
3576     .init = light_lightness_setup_srv_init,
3577 #if CONFIG_BLE_MESH_DEINIT
3578     .deinit = light_lightness_setup_srv_deinit,
3579 #endif /* CONFIG_BLE_MESH_DEINIT */
3580 };
3581 
3582 const struct bt_mesh_model_cb bt_mesh_light_ctl_srv_cb = {
3583     .init = light_ctl_srv_init,
3584 #if CONFIG_BLE_MESH_DEINIT
3585     .deinit = light_ctl_srv_deinit,
3586 #endif /* CONFIG_BLE_MESH_DEINIT */
3587 };
3588 
3589 const struct bt_mesh_model_cb bt_mesh_light_ctl_setup_srv_cb = {
3590     .init = light_ctl_setup_srv_init,
3591 #if CONFIG_BLE_MESH_DEINIT
3592     .deinit = light_ctl_setup_srv_deinit,
3593 #endif /* CONFIG_BLE_MESH_DEINIT */
3594 };
3595 
3596 const struct bt_mesh_model_cb bt_mesh_light_ctl_temp_srv_cb = {
3597     .init = light_ctl_temp_srv_init,
3598 #if CONFIG_BLE_MESH_DEINIT
3599     .deinit = light_ctl_temp_srv_deinit,
3600 #endif /* CONFIG_BLE_MESH_DEINIT */
3601 };
3602 
3603 const struct bt_mesh_model_cb bt_mesh_light_hsl_srv_cb = {
3604     .init = light_hsl_srv_init,
3605 #if CONFIG_BLE_MESH_DEINIT
3606     .deinit = light_hsl_srv_deinit,
3607 #endif /* CONFIG_BLE_MESH_DEINIT */
3608 };
3609 
3610 const struct bt_mesh_model_cb bt_mesh_light_hsl_setup_srv_cb = {
3611     .init = light_hsl_setup_srv_init,
3612 #if CONFIG_BLE_MESH_DEINIT
3613     .deinit = light_hsl_setup_srv_deinit,
3614 #endif /* CONFIG_BLE_MESH_DEINIT */
3615 };
3616 
3617 const struct bt_mesh_model_cb bt_mesh_light_hsl_hue_srv_cb = {
3618     .init = light_hsl_hue_srv_init,
3619 #if CONFIG_BLE_MESH_DEINIT
3620     .deinit = light_hsl_hue_srv_deinit,
3621 #endif /* CONFIG_BLE_MESH_DEINIT */
3622 };
3623 
3624 const struct bt_mesh_model_cb bt_mesh_light_hsl_sat_srv_cb = {
3625     .init = light_hsl_sat_srv_init,
3626 #if CONFIG_BLE_MESH_DEINIT
3627     .deinit = light_hsl_sat_srv_deinit,
3628 #endif /* CONFIG_BLE_MESH_DEINIT */
3629 };
3630 
3631 const struct bt_mesh_model_cb bt_mesh_light_xyl_srv_cb = {
3632     .init = light_xyl_srv_init,
3633 #if CONFIG_BLE_MESH_DEINIT
3634     .deinit = light_xyl_srv_deinit,
3635 #endif /* CONFIG_BLE_MESH_DEINIT */
3636 };
3637 
3638 const struct bt_mesh_model_cb bt_mesh_light_xyl_setup_srv_cb = {
3639     .init = light_xyl_setup_srv_init,
3640 #if CONFIG_BLE_MESH_DEINIT
3641     .deinit = light_xyl_setup_srv_deinit,
3642 #endif /* CONFIG_BLE_MESH_DEINIT */
3643 };
3644 
3645 const struct bt_mesh_model_cb bt_mesh_light_lc_srv_cb = {
3646     .init = light_lc_srv_init,
3647 #if CONFIG_BLE_MESH_DEINIT
3648     .deinit = light_lc_srv_deinit,
3649 #endif /* CONFIG_BLE_MESH_DEINIT */
3650 };
3651 
3652 const struct bt_mesh_model_cb bt_mesh_light_lc_setup_srv_cb = {
3653     .init = light_lc_setup_srv_init,
3654 #if CONFIG_BLE_MESH_DEINIT
3655     .deinit = light_lc_setup_srv_deinit,
3656 #endif /* CONFIG_BLE_MESH_DEINIT */
3657 };
3658 
3659 #endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */
3660