1 /* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
2  *
3  * Copyright (c) 2018 Vikrant More
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/drivers/gpio.h>
9 
10 #include "ble_mesh.h"
11 #include "common.h"
12 #include "device_composition.h"
13 #include "state_binding.h"
14 #include "transition.h"
15 #include "storage.h"
16 
17 static struct bt_mesh_health_srv health_srv = {
18 };
19 
20 BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0);
21 
22 /* Definitions of models publication context (Start) */
23 BT_MESH_MODEL_PUB_DEFINE(gen_onoff_srv_pub_root, NULL, 2 + 3);
24 BT_MESH_MODEL_PUB_DEFINE(gen_onoff_cli_pub_root, NULL, 2 + 4);
25 
26 BT_MESH_MODEL_PUB_DEFINE(gen_level_srv_pub_root, NULL, 2 + 5);
27 BT_MESH_MODEL_PUB_DEFINE(gen_level_cli_pub_root, NULL, 2 + 7);
28 
29 BT_MESH_MODEL_PUB_DEFINE(gen_def_trans_time_srv_pub, NULL, 2 + 1);
30 BT_MESH_MODEL_PUB_DEFINE(gen_def_trans_time_cli_pub, NULL, 2 + 1);
31 
32 BT_MESH_MODEL_PUB_DEFINE(gen_power_onoff_srv_pub, NULL, 2 + 1);
33 BT_MESH_MODEL_PUB_DEFINE(gen_power_onoff_cli_pub, NULL, 2 + 1);
34 
35 BT_MESH_MODEL_PUB_DEFINE(light_lightness_srv_pub, NULL, 2 + 5);
36 BT_MESH_MODEL_PUB_DEFINE(light_lightness_cli_pub, NULL, 2 + 5);
37 
38 BT_MESH_MODEL_PUB_DEFINE(light_ctl_srv_pub, NULL, 2 + 9);
39 BT_MESH_MODEL_PUB_DEFINE(light_ctl_cli_pub, NULL, 2 + 9);
40 
41 BT_MESH_MODEL_PUB_DEFINE(vnd_pub, NULL, 3 + 6);
42 
43 BT_MESH_MODEL_PUB_DEFINE(gen_level_srv_pub_s0, NULL, 2 + 5);
44 BT_MESH_MODEL_PUB_DEFINE(gen_level_cli_pub_s0, NULL, 2 + 7);
45 /* Definitions of models publication context (End) */
46 
47 struct lightness light;
48 struct temperature light_temp;
49 struct delta_uv duv;
50 
51 struct light_ctl_state light_state = {
52 	.light = &light,
53 	.temp = &light_temp,
54 	.duv = &duv,
55 	.transition = &onoff_transition,
56 };
57 
58 struct light_ctl_state *const ctl = &light_state;
59 
60 /* Definitions of models user data (Start) */
61 
62 struct vendor_state vnd_user_data;
63 
64 /* Definitions of models user data (End) */
65 
66 static const struct bt_mesh_elem elements[];
67 
68 /* message handlers (Start) */
69 
70 /* Generic OnOff Server message handlers */
gen_onoff_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)71 static int gen_onoff_get(const struct bt_mesh_model *model,
72 			 struct bt_mesh_msg_ctx *ctx,
73 			 struct net_buf_simple *buf)
74 {
75 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 3 + 4);
76 
77 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS);
78 	net_buf_simple_add_u8(msg, (uint8_t) get_current(ONOFF));
79 
80 	if (ctl->light->current == ctl->light->target) {
81 		goto send;
82 	}
83 
84 	if (ctl->transition->counter) {
85 		calculate_rt(ctl->transition);
86 		net_buf_simple_add_u8(msg, (uint8_t) get_target(ONOFF));
87 		net_buf_simple_add_u8(msg, ctl->transition->rt);
88 	}
89 
90 send:
91 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
92 		printk("Unable to send GEN_ONOFF_SRV Status response\n");
93 	}
94 
95 	return 0;
96 }
97 
gen_onoff_publish(const struct bt_mesh_model * model)98 void gen_onoff_publish(const struct bt_mesh_model *model)
99 {
100 	int err;
101 	struct net_buf_simple *msg = model->pub->msg;
102 
103 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
104 		return;
105 	}
106 
107 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS);
108 	net_buf_simple_add_u8(msg, (uint8_t) get_current(ONOFF));
109 
110 	if (ctl->transition->counter) {
111 		calculate_rt(ctl->transition);
112 		net_buf_simple_add_u8(msg, (uint8_t) get_target(ONOFF));
113 		net_buf_simple_add_u8(msg, ctl->transition->rt);
114 	}
115 
116 	err = bt_mesh_model_publish(model);
117 	if (err) {
118 		printk("bt_mesh_model_publish err %d\n", err);
119 	}
120 }
121 
gen_onoff_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)122 static int gen_onoff_set_unack(const struct bt_mesh_model *model,
123 			       struct bt_mesh_msg_ctx *ctx,
124 			       struct net_buf_simple *buf)
125 {
126 	uint8_t tid, onoff, tt, delay;
127 	int64_t now;
128 
129 	onoff = net_buf_simple_pull_u8(buf);
130 	tid = net_buf_simple_pull_u8(buf);
131 
132 	if (onoff > STATE_ON) {
133 		return 0;
134 	}
135 
136 	now = k_uptime_get();
137 	if (ctl->last_tid == tid &&
138 	    ctl->last_src_addr == ctx->addr &&
139 	    ctl->last_dst_addr == ctx->recv_dst &&
140 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
141 		return 0;
142 	}
143 
144 	switch (buf->len) {
145 	case 0x00:      /* No optional fields are available */
146 		tt = ctl->tt;
147 		delay = 0U;
148 		break;
149 	case 0x02:      /* Optional fields are available */
150 		tt = net_buf_simple_pull_u8(buf);
151 		if ((tt & 0x3F) == 0x3F) {
152 			return 0;
153 		}
154 
155 		delay = net_buf_simple_pull_u8(buf);
156 		break;
157 	default:
158 		return 0;
159 	}
160 
161 	ctl->transition->counter = 0U;
162 	k_timer_stop(&ctl->transition->timer);
163 
164 	ctl->last_tid = tid;
165 	ctl->last_src_addr = ctx->addr;
166 	ctl->last_dst_addr = ctx->recv_dst;
167 	ctl->last_msg_timestamp = now;
168 	ctl->transition->tt = tt;
169 	ctl->transition->delay = delay;
170 	ctl->transition->type = NON_MOVE;
171 	set_target(ONOFF, &onoff);
172 
173 	if (ctl->light->target != ctl->light->current) {
174 		set_transition_values(ONOFF);
175 	} else {
176 		return 0;
177 	}
178 
179 	/* For Instantaneous Transition */
180 	if (ctl->transition->counter == 0U) {
181 		ctl->light->current = ctl->light->target;
182 	}
183 
184 	ctl->transition->just_started = true;
185 	gen_onoff_publish(model);
186 	onoff_handler();
187 
188 	return 0;
189 }
190 
gen_onoff_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)191 static int gen_onoff_set(const struct bt_mesh_model *model,
192 			 struct bt_mesh_msg_ctx *ctx,
193 			 struct net_buf_simple *buf)
194 {
195 	uint8_t tid, onoff, tt, delay;
196 	int64_t now;
197 
198 	onoff = net_buf_simple_pull_u8(buf);
199 	tid = net_buf_simple_pull_u8(buf);
200 
201 	if (onoff > STATE_ON) {
202 		return 0;
203 	}
204 
205 	now = k_uptime_get();
206 	if (ctl->last_tid == tid &&
207 	    ctl->last_src_addr == ctx->addr &&
208 	    ctl->last_dst_addr == ctx->recv_dst &&
209 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
210 		(void)gen_onoff_get(model, ctx, buf);
211 		return 0;
212 	}
213 
214 	switch (buf->len) {
215 	case 0x00:      /* No optional fields are available */
216 		tt = ctl->tt;
217 		delay = 0U;
218 		break;
219 	case 0x02:      /* Optional fields are available */
220 		tt = net_buf_simple_pull_u8(buf);
221 		if ((tt & 0x3F) == 0x3F) {
222 			return 0;
223 		}
224 
225 		delay = net_buf_simple_pull_u8(buf);
226 		break;
227 	default:
228 		return 0;
229 	}
230 
231 	ctl->transition->counter = 0U;
232 	k_timer_stop(&ctl->transition->timer);
233 
234 	ctl->last_tid = tid;
235 	ctl->last_src_addr = ctx->addr;
236 	ctl->last_dst_addr = ctx->recv_dst;
237 	ctl->last_msg_timestamp = now;
238 	ctl->transition->tt = tt;
239 	ctl->transition->delay = delay;
240 	ctl->transition->type = NON_MOVE;
241 	set_target(ONOFF, &onoff);
242 
243 	if (ctl->light->target != ctl->light->current) {
244 		set_transition_values(ONOFF);
245 	} else {
246 		(void)gen_onoff_get(model, ctx, buf);
247 		return 0;
248 	}
249 
250 	/* For Instantaneous Transition */
251 	if (ctl->transition->counter == 0U) {
252 		ctl->light->current = ctl->light->target;
253 	}
254 
255 	ctl->transition->just_started = true;
256 	(void)gen_onoff_get(model, ctx, buf);
257 	gen_onoff_publish(model);
258 	onoff_handler();
259 
260 	return 0;
261 }
262 
263 /* Generic OnOff Client message handlers */
gen_onoff_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)264 static int gen_onoff_status(const struct bt_mesh_model *model,
265 			    struct bt_mesh_msg_ctx *ctx,
266 			    struct net_buf_simple *buf)
267 {
268 	printk("Acknowledgement from GEN_ONOFF_SRV\n");
269 	printk("Present OnOff = %02x\n", net_buf_simple_pull_u8(buf));
270 
271 	if (buf->len == 2U) {
272 		printk("Target OnOff = %02x\n", net_buf_simple_pull_u8(buf));
273 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
274 	}
275 
276 	return 0;
277 }
278 
279 /* Generic Level (LIGHTNESS) Server message handlers */
gen_level_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)280 static int gen_level_get(const struct bt_mesh_model *model,
281 			 struct bt_mesh_msg_ctx *ctx,
282 			 struct net_buf_simple *buf)
283 {
284 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4);
285 
286 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
287 	net_buf_simple_add_le16(msg, (int16_t) get_current(LEVEL_LIGHT));
288 
289 	if (ctl->light->current == ctl->light->target) {
290 		goto send;
291 	}
292 
293 	if (ctl->transition->counter) {
294 		calculate_rt(ctl->transition);
295 		net_buf_simple_add_le16(msg, (int16_t) get_target(LEVEL_LIGHT));
296 		net_buf_simple_add_u8(msg, ctl->transition->rt);
297 	}
298 
299 send:
300 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
301 		printk("Unable to send GEN_LEVEL_SRV Status response\n");
302 	}
303 
304 	return 0;
305 }
306 
gen_level_publish(const struct bt_mesh_model * model)307 void gen_level_publish(const struct bt_mesh_model *model)
308 {
309 	int err;
310 	struct net_buf_simple *msg = model->pub->msg;
311 
312 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
313 		return;
314 	}
315 
316 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
317 	net_buf_simple_add_le16(msg, (int16_t) get_current(LEVEL_LIGHT));
318 
319 	if (ctl->transition->counter) {
320 		calculate_rt(ctl->transition);
321 		net_buf_simple_add_le16(msg, (int16_t) get_target(LEVEL_LIGHT));
322 		net_buf_simple_add_u8(msg, ctl->transition->rt);
323 	}
324 
325 	err = bt_mesh_model_publish(model);
326 	if (err) {
327 		printk("bt_mesh_model_publish err %d\n", err);
328 	}
329 }
330 
gen_level_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)331 static int gen_level_set_unack(const struct bt_mesh_model *model,
332 			       struct bt_mesh_msg_ctx *ctx,
333 			       struct net_buf_simple *buf)
334 {
335 	uint8_t tid, tt, delay;
336 	int16_t level;
337 	int64_t now;
338 
339 	level = (int16_t) net_buf_simple_pull_le16(buf);
340 	tid = net_buf_simple_pull_u8(buf);
341 
342 	now = k_uptime_get();
343 	if (ctl->last_tid == tid &&
344 	    ctl->last_src_addr == ctx->addr &&
345 	    ctl->last_dst_addr == ctx->recv_dst &&
346 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
347 		return 0;
348 	}
349 
350 	switch (buf->len) {
351 	case 0x00:      /* No optional fields are available */
352 		tt = ctl->tt;
353 		delay = 0U;
354 		break;
355 	case 0x02:      /* Optional fields are available */
356 		tt = net_buf_simple_pull_u8(buf);
357 		if ((tt & 0x3F) == 0x3F) {
358 			return 0;
359 		}
360 
361 		delay = net_buf_simple_pull_u8(buf);
362 		break;
363 	default:
364 		return 0;
365 	}
366 
367 	ctl->transition->counter = 0U;
368 	k_timer_stop(&ctl->transition->timer);
369 
370 	ctl->last_tid = tid;
371 	ctl->last_src_addr = ctx->addr;
372 	ctl->last_dst_addr = ctx->recv_dst;
373 	ctl->last_msg_timestamp = now;
374 	ctl->transition->tt = tt;
375 	ctl->transition->delay = delay;
376 	ctl->transition->type = NON_MOVE;
377 	set_target(LEVEL_LIGHT, &level);
378 
379 	if (ctl->light->target != ctl->light->current) {
380 		set_transition_values(LEVEL_LIGHT);
381 	} else {
382 		return 0;
383 	}
384 
385 	/* For Instantaneous Transition */
386 	if (ctl->transition->counter == 0U) {
387 		ctl->light->current = ctl->light->target;
388 	}
389 
390 	ctl->transition->just_started = true;
391 	gen_level_publish(model);
392 	level_lightness_handler();
393 
394 	return 0;
395 }
396 
gen_level_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)397 static int gen_level_set(const struct bt_mesh_model *model,
398 			 struct bt_mesh_msg_ctx *ctx,
399 			 struct net_buf_simple *buf)
400 {
401 	uint8_t tid, tt, delay;
402 	int16_t level;
403 	int64_t now;
404 
405 	level = (int16_t) net_buf_simple_pull_le16(buf);
406 	tid = net_buf_simple_pull_u8(buf);
407 
408 	now = k_uptime_get();
409 	if (ctl->last_tid == tid &&
410 	    ctl->last_src_addr == ctx->addr &&
411 	    ctl->last_dst_addr == ctx->recv_dst &&
412 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
413 		(void)gen_level_get(model, ctx, buf);
414 		return 0;
415 	}
416 
417 	switch (buf->len) {
418 	case 0x00:      /* No optional fields are available */
419 		tt = ctl->tt;
420 		delay = 0U;
421 		break;
422 	case 0x02:      /* Optional fields are available */
423 		tt = net_buf_simple_pull_u8(buf);
424 		if ((tt & 0x3F) == 0x3F) {
425 			return 0;
426 		}
427 
428 		delay = net_buf_simple_pull_u8(buf);
429 		break;
430 	default:
431 		return 0;
432 	}
433 
434 	ctl->transition->counter = 0U;
435 	k_timer_stop(&ctl->transition->timer);
436 
437 	ctl->last_tid = tid;
438 	ctl->last_src_addr = ctx->addr;
439 	ctl->last_dst_addr = ctx->recv_dst;
440 	ctl->last_msg_timestamp = now;
441 	ctl->transition->tt = tt;
442 	ctl->transition->delay = delay;
443 	ctl->transition->type = NON_MOVE;
444 	set_target(LEVEL_LIGHT, &level);
445 
446 	if (ctl->light->target != ctl->light->current) {
447 		set_transition_values(LEVEL_LIGHT);
448 	} else {
449 		(void)gen_level_get(model, ctx, buf);
450 		return 0;
451 	}
452 
453 	/* For Instantaneous Transition */
454 	if (ctl->transition->counter == 0U) {
455 		ctl->light->current = ctl->light->target;
456 	}
457 
458 	ctl->transition->just_started = true;
459 	(void)gen_level_get(model, ctx, buf);
460 	gen_level_publish(model);
461 	level_lightness_handler();
462 
463 	return 0;
464 }
465 
gen_delta_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)466 static int gen_delta_set_unack(const struct bt_mesh_model *model,
467 			       struct bt_mesh_msg_ctx *ctx,
468 			       struct net_buf_simple *buf)
469 {
470 	uint8_t tid, tt, delay;
471 	static int16_t last_level;
472 	int32_t target, delta;
473 	int64_t now;
474 
475 	delta = (int32_t) net_buf_simple_pull_le32(buf);
476 	tid = net_buf_simple_pull_u8(buf);
477 
478 	now = k_uptime_get();
479 	if (ctl->last_tid == tid &&
480 	    ctl->last_src_addr == ctx->addr &&
481 	    ctl->last_dst_addr == ctx->recv_dst &&
482 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
483 
484 		if (ctl->light->delta == delta) {
485 			return 0;
486 		}
487 		target = last_level + delta;
488 
489 	} else {
490 		last_level = (int16_t) get_current(LEVEL_LIGHT);
491 		target = last_level + delta;
492 	}
493 
494 	switch (buf->len) {
495 	case 0x00:      /* No optional fields are available */
496 		tt = ctl->tt;
497 		delay = 0U;
498 		break;
499 	case 0x02:      /* Optional fields are available */
500 		tt = net_buf_simple_pull_u8(buf);
501 		if ((tt & 0x3F) == 0x3F) {
502 			return 0;
503 		}
504 
505 		delay = net_buf_simple_pull_u8(buf);
506 		break;
507 	default:
508 		return 0;
509 	}
510 
511 	ctl->transition->counter = 0U;
512 	k_timer_stop(&ctl->transition->timer);
513 
514 	ctl->last_tid = tid;
515 	ctl->last_src_addr = ctx->addr;
516 	ctl->last_dst_addr = ctx->recv_dst;
517 	ctl->last_msg_timestamp = now;
518 	ctl->transition->tt = tt;
519 	ctl->transition->delay = delay;
520 	ctl->transition->type = NON_MOVE;
521 
522 	if (target < INT16_MIN) {
523 		target = INT16_MIN;
524 	} else if (target > INT16_MAX) {
525 		target = INT16_MAX;
526 	}
527 
528 	set_target(DELTA_LEVEL_LIGHT, &target);
529 
530 	if (ctl->light->target != ctl->light->current) {
531 		set_transition_values(LEVEL_LIGHT);
532 	} else {
533 		return 0;
534 	}
535 
536 	/* For Instantaneous Transition */
537 	if (ctl->transition->counter == 0U) {
538 		ctl->light->current = ctl->light->target;
539 	}
540 
541 	ctl->transition->just_started = true;
542 	gen_level_publish(model);
543 	level_lightness_handler();
544 
545 	return 0;
546 }
547 
gen_delta_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)548 static int gen_delta_set(const struct bt_mesh_model *model,
549 			 struct bt_mesh_msg_ctx *ctx,
550 			 struct net_buf_simple *buf)
551 {
552 	uint8_t tid, tt, delay;
553 	static int16_t last_level;
554 	int32_t target, delta;
555 	int64_t now;
556 
557 	delta = (int32_t) net_buf_simple_pull_le32(buf);
558 	tid = net_buf_simple_pull_u8(buf);
559 
560 	now = k_uptime_get();
561 	if (ctl->last_tid == tid &&
562 	    ctl->last_src_addr == ctx->addr &&
563 	    ctl->last_dst_addr == ctx->recv_dst &&
564 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
565 
566 		if (ctl->light->delta == delta) {
567 			(void)gen_level_get(model, ctx, buf);
568 			return 0;
569 		}
570 		target = last_level + delta;
571 
572 	} else {
573 		last_level = (int16_t) get_current(LEVEL_LIGHT);
574 		target = last_level + delta;
575 	}
576 
577 	switch (buf->len) {
578 	case 0x00:      /* No optional fields are available */
579 		tt = ctl->tt;
580 		delay = 0U;
581 		break;
582 	case 0x02:      /* Optional fields are available */
583 		tt = net_buf_simple_pull_u8(buf);
584 		if ((tt & 0x3F) == 0x3F) {
585 			return 0;
586 		}
587 
588 		delay = net_buf_simple_pull_u8(buf);
589 		break;
590 	default:
591 		return 0;
592 	}
593 
594 	ctl->transition->counter = 0U;
595 	k_timer_stop(&ctl->transition->timer);
596 
597 	ctl->last_tid = tid;
598 	ctl->last_src_addr = ctx->addr;
599 	ctl->last_dst_addr = ctx->recv_dst;
600 	ctl->last_msg_timestamp = now;
601 	ctl->transition->tt = tt;
602 	ctl->transition->delay = delay;
603 	ctl->transition->type = NON_MOVE;
604 
605 	if (target < INT16_MIN) {
606 		target = INT16_MIN;
607 	} else if (target > INT16_MAX) {
608 		target = INT16_MAX;
609 	}
610 
611 	set_target(DELTA_LEVEL_LIGHT, &target);
612 
613 	if (ctl->light->target != ctl->light->current) {
614 		set_transition_values(LEVEL_LIGHT);
615 	} else {
616 		(void)gen_level_get(model, ctx, buf);
617 		return 0;
618 	}
619 
620 	/* For Instantaneous Transition */
621 	if (ctl->transition->counter == 0U) {
622 		ctl->light->current = ctl->light->target;
623 	}
624 
625 	ctl->transition->just_started = true;
626 	(void)gen_level_get(model, ctx, buf);
627 	gen_level_publish(model);
628 	level_lightness_handler();
629 
630 	return 0;
631 }
632 
gen_move_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)633 static int gen_move_set_unack(const struct bt_mesh_model *model,
634 			      struct bt_mesh_msg_ctx *ctx,
635 			      struct net_buf_simple *buf)
636 {
637 	uint8_t tid, tt, delay;
638 	int16_t delta;
639 	uint16_t target;
640 	int64_t now;
641 
642 	delta = (int16_t) net_buf_simple_pull_le16(buf);
643 	tid = net_buf_simple_pull_u8(buf);
644 
645 	now = k_uptime_get();
646 	if (ctl->last_tid == tid &&
647 	    ctl->last_src_addr == ctx->addr &&
648 	    ctl->last_dst_addr == ctx->recv_dst &&
649 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
650 		return 0;
651 	}
652 
653 	switch (buf->len) {
654 	case 0x00:      /* No optional fields are available */
655 		tt = ctl->tt;
656 		delay = 0U;
657 		break;
658 	case 0x02:      /* Optional fields are available */
659 		tt = net_buf_simple_pull_u8(buf);
660 		if ((tt & 0x3F) == 0x3F) {
661 			return 0;
662 		}
663 
664 		delay = net_buf_simple_pull_u8(buf);
665 		break;
666 	default:
667 		return 0;
668 	}
669 
670 	ctl->transition->counter = 0U;
671 	k_timer_stop(&ctl->transition->timer);
672 
673 	ctl->last_tid = tid;
674 	ctl->last_src_addr = ctx->addr;
675 	ctl->last_dst_addr = ctx->recv_dst;
676 	ctl->last_msg_timestamp = now;
677 	ctl->transition->tt = tt;
678 	ctl->transition->delay = delay;
679 	ctl->transition->type = MOVE;
680 	ctl->light->delta = delta;
681 
682 	if (delta < 0) {
683 		target = ctl->light->range_min;
684 	} else if (delta > 0) {
685 		target = ctl->light->range_max;
686 	} else if (delta == 0) {
687 		target = ctl->light->current;
688 	}
689 	set_target(MOVE_LIGHT, &target);
690 
691 	if (ctl->light->target != ctl->light->current) {
692 		set_transition_values(MOVE_LIGHT);
693 	} else {
694 		return 0;
695 	}
696 
697 	if (ctl->transition->counter == 0U) {
698 		return 0;
699 	}
700 
701 	ctl->transition->just_started = true;
702 	gen_level_publish(model);
703 	level_lightness_handler();
704 
705 	return 0;
706 }
707 
gen_move_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)708 static int gen_move_set(const struct bt_mesh_model *model,
709 			struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
710 {
711 	uint8_t tid, tt, delay;
712 	int16_t delta;
713 	uint16_t target;
714 	int64_t now;
715 
716 	delta = (int16_t) net_buf_simple_pull_le16(buf);
717 	tid = net_buf_simple_pull_u8(buf);
718 
719 	now = k_uptime_get();
720 	if (ctl->last_tid == tid &&
721 	    ctl->last_src_addr == ctx->addr &&
722 	    ctl->last_dst_addr == ctx->recv_dst &&
723 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
724 		(void)gen_level_get(model, ctx, buf);
725 		return 0;
726 	}
727 
728 	switch (buf->len) {
729 	case 0x00:      /* No optional fields are available */
730 		tt = ctl->tt;
731 		delay = 0U;
732 		break;
733 	case 0x02:      /* Optional fields are available */
734 		tt = net_buf_simple_pull_u8(buf);
735 		if ((tt & 0x3F) == 0x3F) {
736 			return 0;
737 		}
738 
739 		delay = net_buf_simple_pull_u8(buf);
740 		break;
741 	default:
742 		return 0;
743 	}
744 
745 	ctl->transition->counter = 0U;
746 	k_timer_stop(&ctl->transition->timer);
747 
748 	ctl->last_tid = tid;
749 	ctl->last_src_addr = ctx->addr;
750 	ctl->last_dst_addr = ctx->recv_dst;
751 	ctl->last_msg_timestamp = now;
752 	ctl->transition->tt = tt;
753 	ctl->transition->delay = delay;
754 	ctl->transition->type = MOVE;
755 	ctl->light->delta = delta;
756 
757 	if (delta < 0) {
758 		target = ctl->light->range_min;
759 	} else if (delta > 0) {
760 		target = ctl->light->range_max;
761 	} else if (delta == 0) {
762 		target = ctl->light->current;
763 	}
764 	set_target(MOVE_LIGHT, &target);
765 
766 	if (ctl->light->target != ctl->light->current) {
767 		set_transition_values(MOVE_LIGHT);
768 	} else {
769 		(void)gen_level_get(model, ctx, buf);
770 		return 0;
771 	}
772 
773 	if (ctl->transition->counter == 0U) {
774 		return 0;
775 	}
776 
777 	ctl->transition->just_started = true;
778 	(void)gen_level_get(model, ctx, buf);
779 	gen_level_publish(model);
780 	level_lightness_handler();
781 
782 	return 0;
783 }
784 
785 /* Generic Level Client message handlers */
gen_level_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)786 static int gen_level_status(const struct bt_mesh_model *model,
787 			    struct bt_mesh_msg_ctx *ctx,
788 			    struct net_buf_simple *buf)
789 {
790 	printk("Acknowledgement from GEN_LEVEL_SRV\n");
791 	printk("Present Level = %04x\n", net_buf_simple_pull_le16(buf));
792 
793 	if (buf->len == 3U) {
794 		printk("Target Level = %04x\n", net_buf_simple_pull_le16(buf));
795 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
796 	}
797 
798 	return 0;
799 }
800 
801 /* Generic Default Transition Time Server message handlers */
gen_def_trans_time_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)802 static int gen_def_trans_time_get(const struct bt_mesh_model *model,
803 				  struct bt_mesh_msg_ctx *ctx,
804 				  struct net_buf_simple *buf)
805 {
806 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
807 
808 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_GEN_DEF_TRANS_TIME_STATUS);
809 	net_buf_simple_add_u8(msg, ctl->tt);
810 
811 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
812 		printk("Unable to send GEN_DEF_TT_SRV Status response\n");
813 	}
814 
815 	return 0;
816 }
817 
gen_def_trans_time_publish(const struct bt_mesh_model * model)818 static void gen_def_trans_time_publish(const struct bt_mesh_model *model)
819 {
820 	int err;
821 	struct net_buf_simple *msg = model->pub->msg;
822 
823 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
824 		return;
825 	}
826 
827 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_GEN_DEF_TRANS_TIME_STATUS);
828 	net_buf_simple_add_u8(msg, ctl->tt);
829 
830 	err = bt_mesh_model_publish(model);
831 	if (err) {
832 		printk("bt_mesh_model_publish err %d\n", err);
833 	}
834 }
835 
gen_def_trans_time_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)836 static int gen_def_trans_time_set_unack(const struct bt_mesh_model *model,
837 					struct bt_mesh_msg_ctx *ctx,
838 					struct net_buf_simple *buf)
839 {
840 	uint8_t tt;
841 
842 	tt = net_buf_simple_pull_u8(buf);
843 
844 	if ((tt & 0x3F) == 0x3F) {
845 		return 0;
846 	}
847 
848 	if (ctl->tt != tt) {
849 		ctl->tt = tt;
850 
851 		gen_def_trans_time_publish(model);
852 		save_on_flash(GEN_DEF_TRANS_TIME_STATE);
853 	}
854 
855 	return 0;
856 }
857 
gen_def_trans_time_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)858 static int gen_def_trans_time_set(const struct bt_mesh_model *model,
859 				  struct bt_mesh_msg_ctx *ctx,
860 				  struct net_buf_simple *buf)
861 {
862 	uint8_t tt;
863 
864 	tt = net_buf_simple_pull_u8(buf);
865 
866 	if ((tt & 0x3F) == 0x3F) {
867 		return 0;
868 	}
869 
870 	if (ctl->tt != tt) {
871 		ctl->tt = tt;
872 
873 		(void)gen_def_trans_time_get(model, ctx, buf);
874 		gen_def_trans_time_publish(model);
875 		save_on_flash(GEN_DEF_TRANS_TIME_STATE);
876 	} else {
877 		(void)gen_def_trans_time_get(model, ctx, buf);
878 	}
879 
880 	return 0;
881 }
882 
883 /* Generic Default Transition Time Client message handlers */
gen_def_trans_time_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)884 static int gen_def_trans_time_status(const struct bt_mesh_model *model,
885 				     struct bt_mesh_msg_ctx *ctx,
886 				     struct net_buf_simple *buf)
887 {
888 	printk("Acknowledgement from GEN_DEF_TT_SRV\n");
889 	printk("Transition Time = %02x\n", net_buf_simple_pull_u8(buf));
890 
891 	return 0;
892 }
893 
894 /* Generic Power OnOff Server message handlers */
gen_onpowerup_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)895 static int gen_onpowerup_get(const struct bt_mesh_model *model,
896 			     struct bt_mesh_msg_ctx *ctx,
897 			     struct net_buf_simple *buf)
898 {
899 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
900 
901 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_GEN_ONPOWERUP_STATUS);
902 	net_buf_simple_add_u8(msg, ctl->onpowerup);
903 
904 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
905 		printk("Unable to send GEN_POWER_ONOFF_SRV Status response\n");
906 	}
907 
908 	return 0;
909 }
910 
911 /* Generic Power OnOff Client message handlers */
gen_onpowerup_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)912 static int gen_onpowerup_status(const struct bt_mesh_model *model,
913 				struct bt_mesh_msg_ctx *ctx,
914 				struct net_buf_simple *buf)
915 {
916 	printk("Acknowledgement from GEN_POWER_ONOFF_SRV\n");
917 	printk("OnPowerUp = %02x\n", net_buf_simple_pull_u8(buf));
918 
919 	return 0;
920 }
921 
922 /* Generic Power OnOff Setup Server message handlers */
923 
gen_onpowerup_publish(const struct bt_mesh_model * model)924 static void gen_onpowerup_publish(const struct bt_mesh_model *model)
925 {
926 	int err;
927 	struct net_buf_simple *msg = model->pub->msg;
928 
929 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
930 		return;
931 	}
932 
933 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_GEN_ONPOWERUP_STATUS);
934 	net_buf_simple_add_u8(msg, ctl->onpowerup);
935 
936 	err = bt_mesh_model_publish(model);
937 	if (err) {
938 		printk("bt_mesh_model_publish err %d\n", err);
939 	}
940 }
941 
gen_onpowerup_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)942 static int gen_onpowerup_set_unack(const struct bt_mesh_model *model,
943 				   struct bt_mesh_msg_ctx *ctx,
944 				   struct net_buf_simple *buf)
945 {
946 	uint8_t onpowerup;
947 
948 	onpowerup = net_buf_simple_pull_u8(buf);
949 
950 	if (onpowerup > STATE_RESTORE) {
951 		return 0;
952 	}
953 
954 	if (ctl->onpowerup != onpowerup) {
955 		ctl->onpowerup = onpowerup;
956 
957 		gen_onpowerup_publish(model);
958 		save_on_flash(GEN_ONPOWERUP_STATE);
959 	}
960 
961 	return 0;
962 }
963 
gen_onpowerup_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)964 static int gen_onpowerup_set(const struct bt_mesh_model *model,
965 			     struct bt_mesh_msg_ctx *ctx,
966 			     struct net_buf_simple *buf)
967 {
968 	uint8_t onpowerup;
969 
970 	onpowerup = net_buf_simple_pull_u8(buf);
971 
972 	if (onpowerup > STATE_RESTORE) {
973 		return 0;
974 	}
975 
976 	if (ctl->onpowerup != onpowerup) {
977 		ctl->onpowerup = onpowerup;
978 
979 		(void)gen_onpowerup_get(model, ctx, buf);
980 		gen_onpowerup_publish(model);
981 		save_on_flash(GEN_ONPOWERUP_STATE);
982 	} else {
983 		(void)gen_onpowerup_get(model, ctx, buf);
984 	}
985 
986 	return 0;
987 }
988 
989 /* Vendor Model message handlers*/
vnd_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)990 static int vnd_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
991 		   struct net_buf_simple *buf)
992 {
993 	struct net_buf_simple *msg = NET_BUF_SIMPLE(3 + 6 + 4);
994 	struct vendor_state *state = model->rt->user_data;
995 
996 	/* This is dummy response for demo purpose */
997 	state->response = 0xA578FEB3;
998 
999 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x04, CID_ZEPHYR));
1000 	net_buf_simple_add_le16(msg, state->current);
1001 	net_buf_simple_add_le32(msg, state->response);
1002 
1003 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1004 		printk("Unable to send VENDOR Status response\n");
1005 	}
1006 
1007 	return 0;
1008 }
1009 
vnd_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1010 static int vnd_set_unack(const struct bt_mesh_model *model,
1011 			 struct bt_mesh_msg_ctx *ctx,
1012 			 struct net_buf_simple *buf)
1013 {
1014 	uint8_t tid;
1015 	int current;
1016 	int64_t now;
1017 	struct vendor_state *state = model->rt->user_data;
1018 
1019 	current = net_buf_simple_pull_le16(buf);
1020 	tid = net_buf_simple_pull_u8(buf);
1021 
1022 	now = k_uptime_get();
1023 	if (state->last_tid == tid &&
1024 	    state->last_src_addr == ctx->addr &&
1025 	    state->last_dst_addr == ctx->recv_dst &&
1026 	    (now - state->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
1027 		return 0;
1028 	}
1029 
1030 	state->last_tid = tid;
1031 	state->last_src_addr = ctx->addr;
1032 	state->last_dst_addr = ctx->recv_dst;
1033 	state->last_msg_timestamp = now;
1034 	state->current = current;
1035 
1036 	printk("Vendor model message = %04x\n", state->current);
1037 
1038 	update_vnd_led_gpio();
1039 
1040 	return 0;
1041 }
1042 
vnd_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1043 static int vnd_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
1044 		   struct net_buf_simple *buf)
1045 {
1046 	(void)vnd_set_unack(model, ctx, buf);
1047 	(void)vnd_get(model, ctx, buf);
1048 
1049 	return 0;
1050 }
1051 
vnd_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1052 static int vnd_status(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
1053 		      struct net_buf_simple *buf)
1054 {
1055 	printk("Acknowledgement from Vendor\n");
1056 	printk("cmd = %04x\n", net_buf_simple_pull_le16(buf));
1057 	printk("response = %08x\n", net_buf_simple_pull_le32(buf));
1058 
1059 	return 0;
1060 }
1061 
1062 /* Light Lightness Server message handlers */
light_lightness_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1063 static int light_lightness_get(const struct bt_mesh_model *model,
1064 			       struct bt_mesh_msg_ctx *ctx,
1065 			       struct net_buf_simple *buf)
1066 {
1067 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4);
1068 
1069 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_LIGHTNESS_STATUS);
1070 	net_buf_simple_add_le16(msg, (uint16_t) get_current(ACTUAL));
1071 
1072 	if (ctl->light->current == ctl->light->target) {
1073 		goto send;
1074 	}
1075 
1076 	if (ctl->transition->counter) {
1077 		calculate_rt(ctl->transition);
1078 		net_buf_simple_add_le16(msg, (uint16_t) get_target(ACTUAL));
1079 		net_buf_simple_add_u8(msg, ctl->transition->rt);
1080 	}
1081 
1082 send:
1083 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1084 		printk("Unable to send LightLightnessAct Status response\n");
1085 	}
1086 
1087 	return 0;
1088 }
1089 
light_lightness_publish(const struct bt_mesh_model * model)1090 void light_lightness_publish(const struct bt_mesh_model *model)
1091 {
1092 	int err;
1093 	struct net_buf_simple *msg = model->pub->msg;
1094 
1095 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1096 		return;
1097 	}
1098 
1099 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_LIGHTNESS_STATUS);
1100 	net_buf_simple_add_le16(msg, (uint16_t) get_current(ACTUAL));
1101 
1102 	if (ctl->transition->counter) {
1103 		calculate_rt(ctl->transition);
1104 		net_buf_simple_add_le16(msg, (uint16_t) get_target(ACTUAL));
1105 		net_buf_simple_add_u8(msg, ctl->transition->rt);
1106 	}
1107 
1108 	err = bt_mesh_model_publish(model);
1109 	if (err) {
1110 		printk("bt_mesh_model_publish err %d\n", err);
1111 	}
1112 }
1113 
light_lightness_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1114 static int light_lightness_set_unack(const struct bt_mesh_model *model,
1115 				     struct bt_mesh_msg_ctx *ctx,
1116 				     struct net_buf_simple *buf)
1117 {
1118 	uint8_t tid, tt, delay;
1119 	uint16_t actual;
1120 	int64_t now;
1121 
1122 	actual = net_buf_simple_pull_le16(buf);
1123 	tid = net_buf_simple_pull_u8(buf);
1124 
1125 	now = k_uptime_get();
1126 	if (ctl->last_tid == tid &&
1127 	    ctl->last_src_addr == ctx->addr &&
1128 	    ctl->last_dst_addr == ctx->recv_dst &&
1129 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
1130 		return 0;
1131 	}
1132 
1133 	switch (buf->len) {
1134 	case 0x00:      /* No optional fields are available */
1135 		tt = ctl->tt;
1136 		delay = 0U;
1137 		break;
1138 	case 0x02:      /* Optional fields are available */
1139 		tt = net_buf_simple_pull_u8(buf);
1140 		if ((tt & 0x3F) == 0x3F) {
1141 			return 0;
1142 		}
1143 
1144 		delay = net_buf_simple_pull_u8(buf);
1145 		break;
1146 	default:
1147 		return 0;
1148 	}
1149 
1150 	ctl->transition->counter = 0U;
1151 	k_timer_stop(&ctl->transition->timer);
1152 
1153 	ctl->last_tid = tid;
1154 	ctl->last_src_addr = ctx->addr;
1155 	ctl->last_dst_addr = ctx->recv_dst;
1156 	ctl->last_msg_timestamp = now;
1157 	ctl->transition->tt = tt;
1158 	ctl->transition->delay = delay;
1159 	ctl->transition->type = NON_MOVE;
1160 	set_target(ACTUAL, &actual);
1161 
1162 	if (ctl->light->target != ctl->light->current) {
1163 		set_transition_values(ACTUAL);
1164 	} else {
1165 		return 0;
1166 	}
1167 
1168 	/* For Instantaneous Transition */
1169 	if (ctl->transition->counter == 0U) {
1170 		ctl->light->current = ctl->light->target;
1171 	}
1172 
1173 	ctl->transition->just_started = true;
1174 	light_lightness_publish(model);
1175 	light_lightness_actual_handler();
1176 
1177 	return 0;
1178 }
1179 
light_lightness_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1180 static int light_lightness_set(const struct bt_mesh_model *model,
1181 				struct bt_mesh_msg_ctx *ctx,
1182 				struct net_buf_simple *buf)
1183 {
1184 	uint8_t tid, tt, delay;
1185 	uint16_t actual;
1186 	int64_t now;
1187 
1188 	actual = net_buf_simple_pull_le16(buf);
1189 	tid = net_buf_simple_pull_u8(buf);
1190 
1191 	now = k_uptime_get();
1192 	if (ctl->last_tid == tid &&
1193 	    ctl->last_src_addr == ctx->addr &&
1194 	    ctl->last_dst_addr == ctx->recv_dst &&
1195 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
1196 		(void)light_lightness_get(model, ctx, buf);
1197 		return 0;
1198 	}
1199 
1200 	switch (buf->len) {
1201 	case 0x00:      /* No optional fields are available */
1202 		tt = ctl->tt;
1203 		delay = 0U;
1204 		break;
1205 	case 0x02:      /* Optional fields are available */
1206 		tt = net_buf_simple_pull_u8(buf);
1207 		if ((tt & 0x3F) == 0x3F) {
1208 			return 0;
1209 		}
1210 
1211 		delay = net_buf_simple_pull_u8(buf);
1212 		break;
1213 	default:
1214 		return 0;
1215 	}
1216 
1217 	ctl->transition->counter = 0U;
1218 	k_timer_stop(&ctl->transition->timer);
1219 
1220 	ctl->last_tid = tid;
1221 	ctl->last_src_addr = ctx->addr;
1222 	ctl->last_dst_addr = ctx->recv_dst;
1223 	ctl->last_msg_timestamp = now;
1224 	ctl->transition->tt = tt;
1225 	ctl->transition->delay = delay;
1226 	ctl->transition->type = NON_MOVE;
1227 	set_target(ACTUAL, &actual);
1228 
1229 	if (ctl->light->target != ctl->light->current) {
1230 		set_transition_values(ACTUAL);
1231 	} else {
1232 		(void)light_lightness_get(model, ctx, buf);
1233 		return 0;
1234 	}
1235 
1236 	/* For Instantaneous Transition */
1237 	if (ctl->transition->counter == 0U) {
1238 		ctl->light->current = ctl->light->target;
1239 	}
1240 
1241 	ctl->transition->just_started = true;
1242 	(void)light_lightness_get(model, ctx, buf);
1243 	light_lightness_publish(model);
1244 	light_lightness_actual_handler();
1245 
1246 	return 0;
1247 }
1248 
light_lightness_linear_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1249 static int light_lightness_linear_get(const struct bt_mesh_model *model,
1250 				      struct bt_mesh_msg_ctx *ctx,
1251 				      struct net_buf_simple *buf)
1252 {
1253 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4);
1254 
1255 	bt_mesh_model_msg_init(msg,
1256 			       BT_MESH_MODEL_LIGHT_LIGHTNESS_LINEAR_STATUS);
1257 	net_buf_simple_add_le16(msg, (uint16_t) get_current(LINEAR));
1258 
1259 	if (ctl->light->current == ctl->light->target) {
1260 		goto send;
1261 	}
1262 
1263 	if (ctl->transition->counter) {
1264 		calculate_rt(ctl->transition);
1265 		net_buf_simple_add_le16(msg, (uint16_t) get_target(LINEAR));
1266 		net_buf_simple_add_u8(msg, ctl->transition->rt);
1267 	}
1268 
1269 send:
1270 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1271 		printk("Unable to send LightLightnessLin Status response\n");
1272 	}
1273 
1274 	return 0;
1275 }
1276 
light_lightness_linear_publish(const struct bt_mesh_model * model)1277 void light_lightness_linear_publish(const struct bt_mesh_model *model)
1278 {
1279 	int err;
1280 	struct net_buf_simple *msg = model->pub->msg;
1281 
1282 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1283 		return;
1284 	}
1285 
1286 	bt_mesh_model_msg_init(msg,
1287 			       BT_MESH_MODEL_LIGHT_LIGHTNESS_LINEAR_STATUS);
1288 	net_buf_simple_add_le16(msg, (uint16_t) get_current(LINEAR));
1289 
1290 	if (ctl->transition->counter) {
1291 		calculate_rt(ctl->transition);
1292 		net_buf_simple_add_le16(msg, (uint16_t) get_target(LINEAR));
1293 		net_buf_simple_add_u8(msg, ctl->transition->rt);
1294 	}
1295 
1296 	err = bt_mesh_model_publish(model);
1297 	if (err) {
1298 		printk("bt_mesh_model_publish err %d\n", err);
1299 	}
1300 }
1301 
light_lightness_linear_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1302 static int light_lightness_linear_set_unack(const struct bt_mesh_model *model,
1303 					    struct bt_mesh_msg_ctx *ctx,
1304 					    struct net_buf_simple *buf)
1305 {
1306 	uint8_t tid, tt, delay;
1307 	uint16_t linear;
1308 	int64_t now;
1309 
1310 	linear = net_buf_simple_pull_le16(buf);
1311 	tid = net_buf_simple_pull_u8(buf);
1312 
1313 	now = k_uptime_get();
1314 	if (ctl->last_tid == tid &&
1315 	    ctl->last_src_addr == ctx->addr &&
1316 	    ctl->last_dst_addr == ctx->recv_dst &&
1317 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
1318 		return 0;
1319 	}
1320 
1321 	switch (buf->len) {
1322 	case 0x00:      /* No optional fields are available */
1323 		tt = ctl->tt;
1324 		delay = 0U;
1325 		break;
1326 	case 0x02:      /* Optional fields are available */
1327 		tt = net_buf_simple_pull_u8(buf);
1328 		if ((tt & 0x3F) == 0x3F) {
1329 			return 0;
1330 		}
1331 
1332 		delay = net_buf_simple_pull_u8(buf);
1333 		break;
1334 	default:
1335 		return 0;
1336 	}
1337 
1338 	ctl->transition->counter = 0U;
1339 	k_timer_stop(&ctl->transition->timer);
1340 
1341 	ctl->last_tid = tid;
1342 	ctl->last_src_addr = ctx->addr;
1343 	ctl->last_dst_addr = ctx->recv_dst;
1344 	ctl->last_msg_timestamp = now;
1345 	ctl->transition->tt = tt;
1346 	ctl->transition->delay = delay;
1347 	ctl->transition->type = NON_MOVE;
1348 	set_target(LINEAR, &linear);
1349 
1350 	if (ctl->light->target != ctl->light->current) {
1351 		set_transition_values(LINEAR);
1352 	} else {
1353 		return 0;
1354 	}
1355 
1356 	/* For Instantaneous Transition */
1357 	if (ctl->transition->counter == 0U) {
1358 		ctl->light->current = ctl->light->target;
1359 	}
1360 
1361 	ctl->transition->just_started = true;
1362 	light_lightness_linear_publish(model);
1363 	light_lightness_linear_handler();
1364 
1365 	return 0;
1366 }
1367 
light_lightness_linear_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1368 static int light_lightness_linear_set(const struct bt_mesh_model *model,
1369 				      struct bt_mesh_msg_ctx *ctx,
1370 				      struct net_buf_simple *buf)
1371 {
1372 	uint8_t tid, tt, delay;
1373 	uint16_t linear;
1374 	int64_t now;
1375 
1376 	linear = net_buf_simple_pull_le16(buf);
1377 	tid = net_buf_simple_pull_u8(buf);
1378 
1379 	now = k_uptime_get();
1380 	if (ctl->last_tid == tid &&
1381 	    ctl->last_src_addr == ctx->addr &&
1382 	    ctl->last_dst_addr == ctx->recv_dst &&
1383 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
1384 		(void)light_lightness_linear_get(model, ctx, buf);
1385 		return 0;
1386 	}
1387 
1388 	switch (buf->len) {
1389 	case 0x00:      /* No optional fields are available */
1390 		tt = ctl->tt;
1391 		delay = 0U;
1392 		break;
1393 	case 0x02:      /* Optional fields are available */
1394 		tt = net_buf_simple_pull_u8(buf);
1395 		if ((tt & 0x3F) == 0x3F) {
1396 			return 0;
1397 		}
1398 
1399 		delay = net_buf_simple_pull_u8(buf);
1400 		break;
1401 	default:
1402 		return 0;
1403 	}
1404 
1405 	ctl->transition->counter = 0U;
1406 	k_timer_stop(&ctl->transition->timer);
1407 
1408 	ctl->last_tid = tid;
1409 	ctl->last_src_addr = ctx->addr;
1410 	ctl->last_dst_addr = ctx->recv_dst;
1411 	ctl->last_msg_timestamp = now;
1412 	ctl->transition->tt = tt;
1413 	ctl->transition->delay = delay;
1414 	ctl->transition->type = NON_MOVE;
1415 	set_target(LINEAR, &linear);
1416 
1417 	if (ctl->light->target != ctl->light->current) {
1418 		set_transition_values(LINEAR);
1419 	} else {
1420 		(void)light_lightness_linear_get(model, ctx, buf);
1421 		return 0;
1422 	}
1423 
1424 	/* For Instantaneous Transition */
1425 	if (ctl->transition->counter == 0U) {
1426 		ctl->light->current = ctl->light->target;
1427 	}
1428 
1429 	ctl->transition->just_started = true;
1430 	(void)light_lightness_linear_get(model, ctx, buf);
1431 	light_lightness_linear_publish(model);
1432 	light_lightness_linear_handler();
1433 
1434 	return 0;
1435 }
1436 
light_lightness_last_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1437 static int light_lightness_last_get(const struct bt_mesh_model *model,
1438 				    struct bt_mesh_msg_ctx *ctx,
1439 				    struct net_buf_simple *buf)
1440 {
1441 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 2 + 4);
1442 
1443 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_LIGHTNESS_LAST_STATUS);
1444 	net_buf_simple_add_le16(msg, ctl->light->last);
1445 
1446 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1447 		printk("Unable to send LightLightnessLast Status response\n");
1448 	}
1449 
1450 	return 0;
1451 }
1452 
light_lightness_default_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1453 static int light_lightness_default_get(const struct bt_mesh_model *model,
1454 				       struct bt_mesh_msg_ctx *ctx,
1455 				       struct net_buf_simple *buf)
1456 {
1457 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 2 + 4);
1458 
1459 	bt_mesh_model_msg_init(msg,
1460 			       BT_MESH_MODEL_LIGHT_LIGHTNESS_DEFAULT_STATUS);
1461 	net_buf_simple_add_le16(msg, ctl->light->def);
1462 
1463 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1464 		printk("Unable to send LightLightnessDef Status response\n");
1465 	}
1466 
1467 	return 0;
1468 }
1469 
light_lightness_range_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1470 static int light_lightness_range_get(const struct bt_mesh_model *model,
1471 				     struct bt_mesh_msg_ctx *ctx,
1472 				     struct net_buf_simple *buf)
1473 {
1474 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4);
1475 
1476 	ctl->light->status_code = RANGE_SUCCESSFULLY_UPDATED;
1477 
1478 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_LIGHTNESS_RANGE_STATUS);
1479 	net_buf_simple_add_u8(msg, ctl->light->status_code);
1480 	net_buf_simple_add_le16(msg, ctl->light->range_min);
1481 	net_buf_simple_add_le16(msg, ctl->light->range_max);
1482 
1483 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1484 		printk("Unable to send LightLightnessRange Status response\n");
1485 	}
1486 
1487 	return 0;
1488 }
1489 
1490 /* Light Lightness Setup Server message handlers */
1491 
light_lightness_default_publish(const struct bt_mesh_model * model)1492 static void light_lightness_default_publish(const struct bt_mesh_model *model)
1493 {
1494 	int err;
1495 	struct net_buf_simple *msg = model->pub->msg;
1496 
1497 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1498 		return;
1499 	}
1500 
1501 	bt_mesh_model_msg_init(msg,
1502 			       BT_MESH_MODEL_LIGHT_LIGHTNESS_DEFAULT_STATUS);
1503 	net_buf_simple_add_le16(msg, ctl->light->def);
1504 
1505 	err = bt_mesh_model_publish(model);
1506 	if (err) {
1507 		printk("bt_mesh_model_publish err %d\n", err);
1508 	}
1509 }
1510 
light_lightness_default_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1511 static int light_lightness_default_set_unack(const struct bt_mesh_model *model,
1512 					     struct bt_mesh_msg_ctx *ctx,
1513 					     struct net_buf_simple *buf)
1514 {
1515 	uint16_t lightness;
1516 
1517 	lightness = net_buf_simple_pull_le16(buf);
1518 	lightness = constrain_lightness(lightness);
1519 
1520 	if (ctl->light->def != lightness) {
1521 		ctl->light->def = lightness;
1522 
1523 		light_lightness_default_publish(model);
1524 		save_on_flash(DEF_STATES);
1525 	}
1526 
1527 	return 0;
1528 }
1529 
light_lightness_default_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1530 static int light_lightness_default_set(const struct bt_mesh_model *model,
1531 				       struct bt_mesh_msg_ctx *ctx,
1532 				       struct net_buf_simple *buf)
1533 {
1534 	uint16_t lightness;
1535 
1536 	lightness = net_buf_simple_pull_le16(buf);
1537 	lightness = constrain_lightness(lightness);
1538 
1539 	if (ctl->light->def != lightness) {
1540 		ctl->light->def = lightness;
1541 
1542 		(void)light_lightness_default_get(model, ctx, buf);
1543 		light_lightness_default_publish(model);
1544 		save_on_flash(DEF_STATES);
1545 	} else {
1546 		(void)light_lightness_default_get(model, ctx, buf);
1547 	}
1548 
1549 	return 0;
1550 }
1551 
light_lightness_range_publish(const struct bt_mesh_model * model)1552 static void light_lightness_range_publish(const struct bt_mesh_model *model)
1553 {
1554 	int err;
1555 	struct net_buf_simple *msg = model->pub->msg;
1556 
1557 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1558 		return;
1559 	}
1560 
1561 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_LIGHTNESS_RANGE_STATUS);
1562 	net_buf_simple_add_u8(msg, ctl->light->status_code);
1563 	net_buf_simple_add_le16(msg, ctl->light->range_min);
1564 	net_buf_simple_add_le16(msg, ctl->light->range_max);
1565 
1566 	err = bt_mesh_model_publish(model);
1567 	if (err) {
1568 		printk("bt_mesh_model_publish err %d\n", err);
1569 	}
1570 }
1571 
light_lightness_range_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1572 static int light_lightness_range_set_unack(const struct bt_mesh_model *model,
1573 					   struct bt_mesh_msg_ctx *ctx,
1574 					   struct net_buf_simple *buf)
1575 {
1576 	uint16_t min, max;
1577 
1578 	min = net_buf_simple_pull_le16(buf);
1579 	max = net_buf_simple_pull_le16(buf);
1580 
1581 	if (min == 0U || max == 0U) {
1582 		return 0;
1583 	}
1584 
1585 	if (min <= max) {
1586 		ctl->light->status_code = RANGE_SUCCESSFULLY_UPDATED;
1587 
1588 		if (ctl->light->range_min != min ||
1589 		    ctl->light->range_max != max) {
1590 
1591 			ctl->light->range_min = min;
1592 			ctl->light->range_max = max;
1593 
1594 			light_lightness_range_publish(model);
1595 			save_on_flash(LIGHTNESS_RANGE);
1596 		}
1597 	} else {
1598 		/* The provided value for Range Max cannot be set */
1599 		ctl->light->status_code = CANNOT_SET_RANGE_MAX;
1600 		return 0;
1601 	}
1602 
1603 	return 0;
1604 }
1605 
light_lightness_range_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1606 static int light_lightness_range_set(const struct bt_mesh_model *model,
1607 				     struct bt_mesh_msg_ctx *ctx,
1608 				     struct net_buf_simple *buf)
1609 {
1610 	uint16_t min, max;
1611 
1612 	min = net_buf_simple_pull_le16(buf);
1613 	max = net_buf_simple_pull_le16(buf);
1614 
1615 	if (min == 0U || max == 0U) {
1616 		return 0;
1617 	}
1618 
1619 	if (min <= max) {
1620 		ctl->light->status_code = RANGE_SUCCESSFULLY_UPDATED;
1621 
1622 		if (ctl->light->range_min != min ||
1623 		    ctl->light->range_max != max) {
1624 
1625 			ctl->light->range_min = min;
1626 			ctl->light->range_max = max;
1627 
1628 			(void)light_lightness_range_get(model, ctx, buf);
1629 			light_lightness_range_publish(model);
1630 			save_on_flash(LIGHTNESS_RANGE);
1631 		} else {
1632 			(void)light_lightness_range_get(model, ctx, buf);
1633 		}
1634 	} else {
1635 		/* The provided value for Range Max cannot be set */
1636 		ctl->light->status_code = CANNOT_SET_RANGE_MAX;
1637 		return 0;
1638 	}
1639 
1640 	return 0;
1641 }
1642 
1643 /* Light Lightness Client message handlers */
light_lightness_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1644 static int light_lightness_status(const struct bt_mesh_model *model,
1645 				  struct bt_mesh_msg_ctx *ctx,
1646 				  struct net_buf_simple *buf)
1647 {
1648 	printk("Acknowledgement from LIGHT_LIGHTNESS_SRV (Actual)\n");
1649 	printk("Present Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1650 
1651 	if (buf->len == 3U) {
1652 		printk("Target Lightness = %04x\n",
1653 		       net_buf_simple_pull_le16(buf));
1654 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
1655 	}
1656 
1657 	return 0;
1658 }
1659 
light_lightness_linear_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1660 static int light_lightness_linear_status(const struct bt_mesh_model *model,
1661 					 struct bt_mesh_msg_ctx *ctx,
1662 					 struct net_buf_simple *buf)
1663 {
1664 	printk("Acknowledgement from LIGHT_LIGHTNESS_SRV (Linear)\n");
1665 	printk("Present Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1666 
1667 	if (buf->len == 3U) {
1668 		printk("Target Lightness = %04x\n",
1669 		       net_buf_simple_pull_le16(buf));
1670 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
1671 	}
1672 
1673 	return 0;
1674 }
1675 
light_lightness_last_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1676 static int light_lightness_last_status(const struct bt_mesh_model *model,
1677 				       struct bt_mesh_msg_ctx *ctx,
1678 				       struct net_buf_simple *buf)
1679 {
1680 	printk("Acknowledgement from LIGHT_LIGHTNESS_SRV (Last)\n");
1681 	printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1682 
1683 	return 0;
1684 }
1685 
light_lightness_default_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1686 static int light_lightness_default_status(const struct bt_mesh_model *model,
1687 					  struct bt_mesh_msg_ctx *ctx,
1688 					  struct net_buf_simple *buf)
1689 {
1690 	printk("Acknowledgement from LIGHT_LIGHTNESS_SRV (Default)\n");
1691 	printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1692 
1693 	return 0;
1694 }
1695 
light_lightness_range_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1696 static int light_lightness_range_status(const struct bt_mesh_model *model,
1697 					struct bt_mesh_msg_ctx *ctx,
1698 					struct net_buf_simple *buf)
1699 {
1700 	printk("Acknowledgement from LIGHT_LIGHTNESS_SRV (Lightness Range)\n");
1701 	printk("Status Code = %02x\n", net_buf_simple_pull_u8(buf));
1702 	printk("Range Min = %04x\n", net_buf_simple_pull_le16(buf));
1703 	printk("Range Max = %04x\n", net_buf_simple_pull_le16(buf));
1704 
1705 	return 0;
1706 }
1707 
1708 /* Light CTL Server message handlers */
light_ctl_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1709 static int light_ctl_get(const struct bt_mesh_model *model,
1710 			 struct bt_mesh_msg_ctx *ctx,
1711 			 struct net_buf_simple *buf)
1712 {
1713 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 9 + 4);
1714 
1715 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_STATUS);
1716 	net_buf_simple_add_le16(msg, (uint16_t) get_current(CTL_LIGHT));
1717 	net_buf_simple_add_le16(msg, (uint16_t) get_current(CTL_TEMP));
1718 
1719 	if (ctl->light->current == ctl->light->target &&
1720 	    ctl->temp->current == ctl->temp->target) {
1721 		goto send;
1722 	}
1723 
1724 	if (ctl->transition->counter) {
1725 		calculate_rt(ctl->transition);
1726 		net_buf_simple_add_le16(msg, (uint16_t) get_target(CTL_LIGHT));
1727 		net_buf_simple_add_le16(msg, (uint16_t) get_target(CTL_TEMP));
1728 		net_buf_simple_add_u8(msg, ctl->transition->rt);
1729 	}
1730 
1731 send:
1732 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1733 		printk("Unable to send LightCTL Status response\n");
1734 	}
1735 
1736 	return 0;
1737 }
1738 
light_ctl_publish(const struct bt_mesh_model * model)1739 void light_ctl_publish(const struct bt_mesh_model *model)
1740 {
1741 	int err;
1742 	struct net_buf_simple *msg = model->pub->msg;
1743 
1744 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1745 		return;
1746 	}
1747 
1748 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_STATUS);
1749 
1750 	/* Here, as per Model specification, status should be
1751 	 * made up of lightness & temperature values only
1752 	 */
1753 	net_buf_simple_add_le16(msg, (uint16_t) get_current(CTL_LIGHT));
1754 	net_buf_simple_add_le16(msg, (uint16_t) get_current(CTL_TEMP));
1755 
1756 	if (ctl->transition->counter) {
1757 		calculate_rt(ctl->transition);
1758 		net_buf_simple_add_le16(msg, (uint16_t) get_target(CTL_LIGHT));
1759 		net_buf_simple_add_le16(msg, (uint16_t) get_target(CTL_TEMP));
1760 		net_buf_simple_add_u8(msg, ctl->transition->rt);
1761 	}
1762 
1763 	err = bt_mesh_model_publish(model);
1764 	if (err) {
1765 		printk("bt_mesh_model_publish err %d\n", err);
1766 	}
1767 }
1768 
light_ctl_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1769 static int light_ctl_set_unack(const struct bt_mesh_model *model,
1770 			       struct bt_mesh_msg_ctx *ctx,
1771 			       struct net_buf_simple *buf)
1772 {
1773 	uint8_t tid, tt, delay;
1774 	int16_t delta_uv;
1775 	uint16_t lightness, temp;
1776 	int64_t now;
1777 
1778 	lightness = net_buf_simple_pull_le16(buf);
1779 	temp = net_buf_simple_pull_le16(buf);
1780 	delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
1781 	tid = net_buf_simple_pull_u8(buf);
1782 
1783 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
1784 		return 0;
1785 	}
1786 
1787 	now = k_uptime_get();
1788 	if (ctl->last_tid == tid &&
1789 	    ctl->last_src_addr == ctx->addr &&
1790 	    ctl->last_dst_addr == ctx->recv_dst &&
1791 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
1792 		return 0;
1793 	}
1794 
1795 	switch (buf->len) {
1796 	case 0x00:      /* No optional fields are available */
1797 		tt = ctl->tt;
1798 		delay = 0U;
1799 		break;
1800 	case 0x02:      /* Optional fields are available */
1801 		tt = net_buf_simple_pull_u8(buf);
1802 		if ((tt & 0x3F) == 0x3F) {
1803 			return 0;
1804 		}
1805 
1806 		delay = net_buf_simple_pull_u8(buf);
1807 		break;
1808 	default:
1809 		return 0;
1810 	}
1811 
1812 	ctl->transition->counter = 0U;
1813 	k_timer_stop(&ctl->transition->timer);
1814 
1815 	ctl->last_tid = tid;
1816 	ctl->last_src_addr = ctx->addr;
1817 	ctl->last_dst_addr = ctx->recv_dst;
1818 	ctl->last_msg_timestamp = now;
1819 	ctl->transition->tt = tt;
1820 	ctl->transition->delay = delay;
1821 	ctl->transition->type = NON_MOVE;
1822 	set_target(CTL_LIGHT, &lightness);
1823 	set_target(CTL_TEMP, &temp);
1824 	set_target(CTL_DELTA_UV, &delta_uv);
1825 
1826 	if (ctl->light->target != ctl->light->current ||
1827 	    ctl->temp->target != ctl->temp->current ||
1828 	    ctl->duv->target != ctl->duv->current) {
1829 		set_transition_values(CTL_LIGHT);
1830 	} else {
1831 		return 0;
1832 	}
1833 
1834 	/* For Instantaneous Transition */
1835 	if (ctl->transition->counter == 0U) {
1836 		ctl->light->current = ctl->light->target;
1837 		ctl->temp->current = ctl->temp->target;
1838 		ctl->duv->current = ctl->duv->target;
1839 	}
1840 
1841 	ctl->transition->just_started = true;
1842 	light_ctl_publish(model);
1843 	light_ctl_handler();
1844 
1845 	return 0;
1846 }
1847 
light_ctl_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1848 static int light_ctl_set(const struct bt_mesh_model *model,
1849 			 struct bt_mesh_msg_ctx *ctx,
1850 			 struct net_buf_simple *buf)
1851 {
1852 	uint8_t tid, tt, delay;
1853 	int16_t delta_uv;
1854 	uint16_t lightness, temp;
1855 	int64_t now;
1856 
1857 	lightness = net_buf_simple_pull_le16(buf);
1858 	temp = net_buf_simple_pull_le16(buf);
1859 	delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
1860 	tid = net_buf_simple_pull_u8(buf);
1861 
1862 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
1863 		return 0;
1864 	}
1865 
1866 	now = k_uptime_get();
1867 	if (ctl->last_tid == tid &&
1868 	    ctl->last_src_addr == ctx->addr &&
1869 	    ctl->last_dst_addr == ctx->recv_dst &&
1870 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
1871 		(void)light_ctl_get(model, ctx, buf);
1872 		return 0;
1873 	}
1874 
1875 	switch (buf->len) {
1876 	case 0x00:      /* No optional fields are available */
1877 		tt = ctl->tt;
1878 		delay = 0U;
1879 		break;
1880 	case 0x02:      /* Optional fields are available */
1881 		tt = net_buf_simple_pull_u8(buf);
1882 		if ((tt & 0x3F) == 0x3F) {
1883 			return 0;
1884 		}
1885 
1886 		delay = net_buf_simple_pull_u8(buf);
1887 		break;
1888 	default:
1889 		return 0;
1890 	}
1891 
1892 	ctl->transition->counter = 0U;
1893 	k_timer_stop(&ctl->transition->timer);
1894 
1895 	ctl->last_tid = tid;
1896 	ctl->last_src_addr = ctx->addr;
1897 	ctl->last_dst_addr = ctx->recv_dst;
1898 	ctl->last_msg_timestamp = now;
1899 	ctl->transition->tt = tt;
1900 	ctl->transition->delay = delay;
1901 	ctl->transition->type = NON_MOVE;
1902 	set_target(CTL_LIGHT, &lightness);
1903 	set_target(CTL_TEMP, &temp);
1904 	set_target(CTL_DELTA_UV, &delta_uv);
1905 
1906 	if (ctl->light->target != ctl->light->current ||
1907 	    ctl->temp->target != ctl->temp->current ||
1908 	    ctl->duv->target != ctl->duv->current) {
1909 		set_transition_values(CTL_LIGHT);
1910 	} else {
1911 		(void)light_ctl_get(model, ctx, buf);
1912 		return 0;
1913 	}
1914 
1915 	/* For Instantaneous Transition */
1916 	if (ctl->transition->counter == 0U) {
1917 		ctl->light->current = ctl->light->target;
1918 		ctl->temp->current = ctl->temp->target;
1919 		ctl->duv->current = ctl->duv->target;
1920 	}
1921 
1922 	ctl->transition->just_started = true;
1923 	(void)light_ctl_get(model, ctx, buf);
1924 	light_ctl_publish(model);
1925 	light_ctl_handler();
1926 
1927 	return 0;
1928 }
1929 
light_ctl_temp_range_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1930 static int light_ctl_temp_range_get(const struct bt_mesh_model *model,
1931 				    struct bt_mesh_msg_ctx *ctx,
1932 				    struct net_buf_simple *buf)
1933 {
1934 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4);
1935 
1936 	ctl->temp->status_code = RANGE_SUCCESSFULLY_UPDATED;
1937 
1938 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_TEMP_RANGE_STATUS);
1939 	net_buf_simple_add_u8(msg, ctl->temp->status_code);
1940 	net_buf_simple_add_le16(msg, ctl->temp->range_min);
1941 	net_buf_simple_add_le16(msg, ctl->temp->range_max);
1942 
1943 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1944 		printk("Unable to send LightCTL Temp Range Status response\n");
1945 	}
1946 
1947 	return 0;
1948 }
1949 
light_ctl_default_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1950 static int light_ctl_default_get(const struct bt_mesh_model *model,
1951 				 struct bt_mesh_msg_ctx *ctx,
1952 				 struct net_buf_simple *buf)
1953 {
1954 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 6 + 4);
1955 
1956 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_DEFAULT_STATUS);
1957 	net_buf_simple_add_le16(msg, ctl->light->def);
1958 	net_buf_simple_add_le16(msg, ctl->temp->def);
1959 	net_buf_simple_add_le16(msg, ctl->duv->def);
1960 
1961 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1962 		printk("Unable to send LightCTL Default Status response\n");
1963 	}
1964 
1965 	return 0;
1966 }
1967 
1968 /* Light CTL Setup Server message handlers */
1969 
light_ctl_default_publish(const struct bt_mesh_model * model)1970 static void light_ctl_default_publish(const struct bt_mesh_model *model)
1971 {
1972 	int err;
1973 	struct net_buf_simple *msg = model->pub->msg;
1974 
1975 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1976 		return;
1977 	}
1978 
1979 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_DEFAULT_STATUS);
1980 	net_buf_simple_add_le16(msg, ctl->light->def);
1981 	net_buf_simple_add_le16(msg, ctl->temp->def);
1982 	net_buf_simple_add_le16(msg, ctl->duv->def);
1983 
1984 	err = bt_mesh_model_publish(model);
1985 	if (err) {
1986 		printk("bt_mesh_model_publish err %d\n", err);
1987 	}
1988 }
1989 
light_ctl_default_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1990 static int light_ctl_default_set_unack(const struct bt_mesh_model *model,
1991 					struct bt_mesh_msg_ctx *ctx,
1992 					struct net_buf_simple *buf)
1993 {
1994 	uint16_t lightness, temp;
1995 	int16_t delta_uv;
1996 
1997 	lightness = net_buf_simple_pull_le16(buf);
1998 	temp = net_buf_simple_pull_le16(buf);
1999 	delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
2000 
2001 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
2002 		return 0;
2003 	}
2004 
2005 	lightness = constrain_lightness(lightness);
2006 	temp = constrain_temperature(temp);
2007 
2008 	if (ctl->light->def != lightness || ctl->temp->def != temp ||
2009 	    ctl->duv->def != delta_uv) {
2010 		ctl->light->def = lightness;
2011 		ctl->temp->def = temp;
2012 		ctl->duv->def = delta_uv;
2013 
2014 		light_ctl_default_publish(model);
2015 		save_on_flash(DEF_STATES);
2016 	}
2017 
2018 	return 0;
2019 }
2020 
light_ctl_default_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2021 static int light_ctl_default_set(const struct bt_mesh_model *model,
2022 				 struct bt_mesh_msg_ctx *ctx,
2023 				 struct net_buf_simple *buf)
2024 {
2025 	uint16_t lightness, temp;
2026 	int16_t delta_uv;
2027 
2028 	lightness = net_buf_simple_pull_le16(buf);
2029 	temp = net_buf_simple_pull_le16(buf);
2030 	delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
2031 
2032 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
2033 		return 0;
2034 	}
2035 
2036 	lightness = constrain_lightness(lightness);
2037 	temp = constrain_temperature(temp);
2038 
2039 	if (ctl->light->def != lightness || ctl->temp->def != temp ||
2040 	    ctl->duv->def != delta_uv) {
2041 		ctl->light->def = lightness;
2042 		ctl->temp->def = temp;
2043 		ctl->duv->def = delta_uv;
2044 
2045 		(void)light_ctl_default_get(model, ctx, buf);
2046 		light_ctl_default_publish(model);
2047 		save_on_flash(DEF_STATES);
2048 	} else {
2049 		(void)light_ctl_default_get(model, ctx, buf);
2050 	}
2051 
2052 	return 0;
2053 }
2054 
light_ctl_temp_range_publish(const struct bt_mesh_model * model)2055 static void light_ctl_temp_range_publish(const struct bt_mesh_model *model)
2056 {
2057 	int err;
2058 	struct net_buf_simple *msg = model->pub->msg;
2059 
2060 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
2061 		return;
2062 	}
2063 
2064 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_TEMP_RANGE_STATUS);
2065 	net_buf_simple_add_u8(msg, ctl->temp->status_code);
2066 	net_buf_simple_add_le16(msg, ctl->temp->range_min);
2067 	net_buf_simple_add_le16(msg, ctl->temp->range_max);
2068 
2069 	err = bt_mesh_model_publish(model);
2070 	if (err) {
2071 		printk("bt_mesh_model_publish err %d\n", err);
2072 	}
2073 }
2074 
light_ctl_temp_range_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2075 static int light_ctl_temp_range_set_unack(const struct bt_mesh_model *model,
2076 					  struct bt_mesh_msg_ctx *ctx,
2077 					  struct net_buf_simple *buf)
2078 {
2079 	uint16_t min, max;
2080 
2081 	min = net_buf_simple_pull_le16(buf);
2082 	max = net_buf_simple_pull_le16(buf);
2083 
2084 	/* This is as per 6.1.3.1 in Mesh Model Specification */
2085 	if (min < TEMP_MIN || min > TEMP_MAX ||
2086 	    max < TEMP_MIN || max > TEMP_MAX) {
2087 		return 0;
2088 	}
2089 
2090 	if (min <= max) {
2091 		ctl->temp->status_code = RANGE_SUCCESSFULLY_UPDATED;
2092 
2093 		if (ctl->temp->range_min != min ||
2094 		    ctl->temp->range_max != max) {
2095 
2096 			ctl->temp->range_min = min;
2097 			ctl->temp->range_max = max;
2098 
2099 			light_ctl_temp_range_publish(model);
2100 			save_on_flash(TEMPERATURE_RANGE);
2101 		}
2102 	} else {
2103 		/* The provided value for Range Max cannot be set */
2104 		ctl->temp->status_code = CANNOT_SET_RANGE_MAX;
2105 		return 0;
2106 	}
2107 
2108 	return 0;
2109 }
2110 
light_ctl_temp_range_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2111 static int light_ctl_temp_range_set(const struct bt_mesh_model *model,
2112 				    struct bt_mesh_msg_ctx *ctx,
2113 				    struct net_buf_simple *buf)
2114 {
2115 	uint16_t min, max;
2116 
2117 	min = net_buf_simple_pull_le16(buf);
2118 	max = net_buf_simple_pull_le16(buf);
2119 
2120 	/* This is as per 6.1.3.1 in Mesh Model Specification */
2121 	if (min < TEMP_MIN || min > TEMP_MAX ||
2122 	    max < TEMP_MIN || max > TEMP_MAX) {
2123 		return 0;
2124 	}
2125 
2126 	if (min <= max) {
2127 		ctl->temp->status_code = RANGE_SUCCESSFULLY_UPDATED;
2128 
2129 		if (ctl->temp->range_min != min ||
2130 		    ctl->temp->range_max != max) {
2131 
2132 			ctl->temp->range_min = min;
2133 			ctl->temp->range_max = max;
2134 
2135 			(void)light_ctl_temp_range_get(model, ctx, buf);
2136 			light_ctl_temp_range_publish(model);
2137 			save_on_flash(TEMPERATURE_RANGE);
2138 		} else {
2139 			(void)light_ctl_temp_range_get(model, ctx, buf);
2140 		}
2141 	} else {
2142 		/* The provided value for Range Max cannot be set */
2143 		ctl->temp->status_code = CANNOT_SET_RANGE_MAX;
2144 		return 0;
2145 	}
2146 
2147 	return 0;
2148 }
2149 
2150 /* Light CTL Client message handlers */
light_ctl_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2151 static int light_ctl_status(const struct bt_mesh_model *model,
2152 			    struct bt_mesh_msg_ctx *ctx,
2153 			    struct net_buf_simple *buf)
2154 {
2155 	printk("Acknowledgement from LIGHT_CTL_SRV\n");
2156 	printk("Present CTL Lightness = %04x\n", net_buf_simple_pull_le16(buf));
2157 	printk("Present CTL Temperature = %04x\n",
2158 	       net_buf_simple_pull_le16(buf));
2159 
2160 	if (buf->len == 5U) {
2161 		printk("Target CTL Lightness = %04x\n",
2162 		       net_buf_simple_pull_le16(buf));
2163 		printk("Target CTL Temperature = %04x\n",
2164 		       net_buf_simple_pull_le16(buf));
2165 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
2166 	}
2167 
2168 	return 0;
2169 }
2170 
light_ctl_temp_range_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2171 static int light_ctl_temp_range_status(const struct bt_mesh_model *model,
2172 				       struct bt_mesh_msg_ctx *ctx,
2173 				       struct net_buf_simple *buf)
2174 {
2175 	printk("Acknowledgement from LIGHT_CTL_SRV (Temperature Range)\n");
2176 	printk("Status Code = %02x\n", net_buf_simple_pull_u8(buf));
2177 	printk("Range Min = %04x\n", net_buf_simple_pull_le16(buf));
2178 	printk("Range Max = %04x\n", net_buf_simple_pull_le16(buf));
2179 
2180 	return 0;
2181 }
2182 
light_ctl_temp_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2183 static int light_ctl_temp_status(const struct bt_mesh_model *model,
2184 				 struct bt_mesh_msg_ctx *ctx,
2185 				 struct net_buf_simple *buf)
2186 {
2187 	printk("Acknowledgement from LIGHT_CTL_TEMP_SRV\n");
2188 	printk("Present CTL Temperature = %04x\n",
2189 	       net_buf_simple_pull_le16(buf));
2190 	printk("Present CTL Delta UV = %04x\n",
2191 	       net_buf_simple_pull_le16(buf));
2192 
2193 	if (buf->len == 5U) {
2194 		printk("Target CTL Temperature = %04x\n",
2195 		       net_buf_simple_pull_le16(buf));
2196 		printk("Target CTL Delta UV = %04x\n",
2197 		       net_buf_simple_pull_le16(buf));
2198 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
2199 	}
2200 
2201 	return 0;
2202 }
2203 
light_ctl_default_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2204 static int light_ctl_default_status(const struct bt_mesh_model *model,
2205 				    struct bt_mesh_msg_ctx *ctx,
2206 				    struct net_buf_simple *buf)
2207 {
2208 	printk("Acknowledgement from LIGHT_CTL_SRV (Default)\n");
2209 	printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf));
2210 	printk("Temperature = %04x\n", net_buf_simple_pull_le16(buf));
2211 	printk("Delta UV = %04x\n", net_buf_simple_pull_le16(buf));
2212 
2213 	return 0;
2214 }
2215 
2216 /* Light CTL Temp. Server message handlers */
light_ctl_temp_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2217 static int light_ctl_temp_get(const struct bt_mesh_model *model,
2218 			      struct bt_mesh_msg_ctx *ctx,
2219 			      struct net_buf_simple *buf)
2220 {
2221 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 9 + 4);
2222 
2223 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_TEMP_STATUS);
2224 	net_buf_simple_add_le16(msg, (uint16_t) get_current(CTL_TEMP));
2225 	net_buf_simple_add_le16(msg, (int16_t) get_current(CTL_DELTA_UV));
2226 
2227 	if (ctl->temp->current == ctl->temp->target &&
2228 	    ctl->duv->current == ctl->duv->target) {
2229 		goto send;
2230 	}
2231 
2232 	if (ctl->transition->counter) {
2233 		calculate_rt(ctl->transition);
2234 		net_buf_simple_add_le16(msg, (uint16_t) get_target(CTL_TEMP));
2235 		net_buf_simple_add_le16(msg, (int16_t) get_target(CTL_DELTA_UV));
2236 		net_buf_simple_add_u8(msg, ctl->transition->rt);
2237 	}
2238 
2239 send:
2240 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
2241 		printk("Unable to send LightCTL Temp. Status response\n");
2242 	}
2243 
2244 	return 0;
2245 }
2246 
light_ctl_temp_publish(const struct bt_mesh_model * model)2247 void light_ctl_temp_publish(const struct bt_mesh_model *model)
2248 {
2249 	int err;
2250 	struct net_buf_simple *msg = model->pub->msg;
2251 
2252 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
2253 		return;
2254 	}
2255 
2256 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_TEMP_STATUS);
2257 	net_buf_simple_add_le16(msg, (uint16_t) get_current(CTL_TEMP));
2258 	net_buf_simple_add_le16(msg, (int16_t) get_current(CTL_DELTA_UV));
2259 
2260 	if (ctl->transition->counter) {
2261 		calculate_rt(ctl->transition);
2262 		net_buf_simple_add_le16(msg, (uint16_t) get_target(CTL_TEMP));
2263 		net_buf_simple_add_le16(msg, (int16_t) get_target(CTL_DELTA_UV));
2264 		net_buf_simple_add_u8(msg, ctl->transition->rt);
2265 	}
2266 
2267 	err = bt_mesh_model_publish(model);
2268 	if (err) {
2269 		printk("bt_mesh_model_publish err %d\n", err);
2270 	}
2271 }
2272 
light_ctl_temp_set_unack(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2273 static int light_ctl_temp_set_unack(const struct bt_mesh_model *model,
2274 				    struct bt_mesh_msg_ctx *ctx,
2275 				    struct net_buf_simple *buf)
2276 {
2277 	uint8_t tid, tt, delay;
2278 	int16_t delta_uv;
2279 	uint16_t temp;
2280 	int64_t now;
2281 
2282 	temp = net_buf_simple_pull_le16(buf);
2283 	delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
2284 	tid = net_buf_simple_pull_u8(buf);
2285 
2286 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
2287 		return 0;
2288 	}
2289 
2290 	now = k_uptime_get();
2291 	if (ctl->last_tid == tid &&
2292 	    ctl->last_src_addr == ctx->addr &&
2293 	    ctl->last_dst_addr == ctx->recv_dst &&
2294 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2295 		return 0;
2296 	}
2297 
2298 	switch (buf->len) {
2299 	case 0x00:      /* No optional fields are available */
2300 		tt = ctl->tt;
2301 		delay = 0U;
2302 		break;
2303 	case 0x02:      /* Optional fields are available */
2304 		tt = net_buf_simple_pull_u8(buf);
2305 		if ((tt & 0x3F) == 0x3F) {
2306 			return 0;
2307 		}
2308 
2309 		delay = net_buf_simple_pull_u8(buf);
2310 		break;
2311 	default:
2312 		return 0;
2313 	}
2314 
2315 	ctl->transition->counter = 0U;
2316 	k_timer_stop(&ctl->transition->timer);
2317 
2318 	ctl->last_tid = tid;
2319 	ctl->last_src_addr = ctx->addr;
2320 	ctl->last_dst_addr = ctx->recv_dst;
2321 	ctl->last_msg_timestamp = now;
2322 	ctl->transition->tt = tt;
2323 	ctl->transition->delay = delay;
2324 	ctl->transition->type = NON_MOVE;
2325 	set_target(CTL_TEMP, &temp);
2326 	set_target(CTL_DELTA_UV, &delta_uv);
2327 
2328 	if (ctl->temp->target != ctl->temp->current ||
2329 	    ctl->duv->target != ctl->duv->current) {
2330 		set_transition_values(CTL_TEMP);
2331 	} else {
2332 		return 0;
2333 	}
2334 
2335 	/* For Instantaneous Transition */
2336 	if (ctl->transition->counter == 0U) {
2337 		ctl->temp->current = ctl->temp->target;
2338 		ctl->duv->current = ctl->duv->target;
2339 	}
2340 
2341 	ctl->transition->just_started = true;
2342 	light_ctl_temp_publish(model);
2343 	light_ctl_temp_handler();
2344 
2345 	return 0;
2346 }
2347 
light_ctl_temp_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2348 static int light_ctl_temp_set(const struct bt_mesh_model *model,
2349 			      struct bt_mesh_msg_ctx *ctx,
2350 			      struct net_buf_simple *buf)
2351 {
2352 	uint8_t tid, tt, delay;
2353 	int16_t delta_uv;
2354 	uint16_t temp;
2355 	int64_t now;
2356 
2357 	temp = net_buf_simple_pull_le16(buf);
2358 	delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
2359 	tid = net_buf_simple_pull_u8(buf);
2360 
2361 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
2362 		return 0;
2363 	}
2364 
2365 	now = k_uptime_get();
2366 	if (ctl->last_tid == tid &&
2367 	    ctl->last_src_addr == ctx->addr &&
2368 	    ctl->last_dst_addr == ctx->recv_dst &&
2369 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2370 		(void)light_ctl_temp_get(model, ctx, buf);
2371 		return 0;
2372 	}
2373 
2374 	switch (buf->len) {
2375 	case 0x00:      /* No optional fields are available */
2376 		tt = ctl->tt;
2377 		delay = 0U;
2378 		break;
2379 	case 0x02:      /* Optional fields are available */
2380 		tt = net_buf_simple_pull_u8(buf);
2381 		if ((tt & 0x3F) == 0x3F) {
2382 			return 0;
2383 		}
2384 
2385 		delay = net_buf_simple_pull_u8(buf);
2386 		break;
2387 	default:
2388 		return 0;
2389 	}
2390 
2391 	ctl->transition->counter = 0U;
2392 	k_timer_stop(&ctl->transition->timer);
2393 
2394 	ctl->last_tid = tid;
2395 	ctl->last_src_addr = ctx->addr;
2396 	ctl->last_dst_addr = ctx->recv_dst;
2397 	ctl->last_msg_timestamp = now;
2398 	ctl->transition->tt = tt;
2399 	ctl->transition->delay = delay;
2400 	ctl->transition->type = NON_MOVE;
2401 	set_target(CTL_TEMP, &temp);
2402 	set_target(CTL_DELTA_UV, &delta_uv);
2403 
2404 	if (ctl->temp->target != ctl->temp->current ||
2405 	    ctl->duv->target != ctl->duv->current) {
2406 		set_transition_values(CTL_TEMP);
2407 	} else {
2408 		(void)light_ctl_temp_get(model, ctx, buf);
2409 		return 0;
2410 	}
2411 
2412 	/* For Instantaneous Transition */
2413 	if (ctl->transition->counter == 0U) {
2414 		ctl->temp->current = ctl->temp->target;
2415 		ctl->duv->current = ctl->duv->target;
2416 	}
2417 
2418 	ctl->transition->just_started = true;
2419 	(void)light_ctl_temp_get(model, ctx, buf);
2420 	light_ctl_temp_publish(model);
2421 	light_ctl_temp_handler();
2422 
2423 	return 0;
2424 }
2425 
2426 /* Generic Level (TEMPERATURE) Server message handlers */
gen_level_get_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2427 static int gen_level_get_temp(const struct bt_mesh_model *model,
2428 			      struct bt_mesh_msg_ctx *ctx,
2429 			      struct net_buf_simple *buf)
2430 {
2431 	struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4);
2432 
2433 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
2434 	net_buf_simple_add_le16(msg, (int16_t) get_current(LEVEL_TEMP));
2435 
2436 	if (ctl->temp->current == ctl->temp->target) {
2437 		goto send;
2438 	}
2439 
2440 	if (ctl->transition->counter) {
2441 		calculate_rt(ctl->transition);
2442 		net_buf_simple_add_le16(msg, (int16_t) get_target(LEVEL_TEMP));
2443 		net_buf_simple_add_u8(msg, ctl->transition->rt);
2444 	}
2445 
2446 send:
2447 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
2448 		printk("Unable to send GEN_LEVEL_SRV Status response\n");
2449 	}
2450 
2451 	return 0;
2452 }
2453 
gen_level_publish_temp(const struct bt_mesh_model * model)2454 void gen_level_publish_temp(const struct bt_mesh_model *model)
2455 {
2456 	int err;
2457 	struct net_buf_simple *msg = model->pub->msg;
2458 
2459 	if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
2460 		return;
2461 	}
2462 
2463 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
2464 	net_buf_simple_add_le16(msg, (int16_t) get_current(LEVEL_TEMP));
2465 
2466 	if (ctl->transition->counter) {
2467 		calculate_rt(ctl->transition);
2468 		net_buf_simple_add_le16(msg, (int16_t) get_target(LEVEL_TEMP));
2469 		net_buf_simple_add_u8(msg, ctl->transition->rt);
2470 	}
2471 
2472 	err = bt_mesh_model_publish(model);
2473 	if (err) {
2474 		printk("bt_mesh_model_publish err %d\n", err);
2475 	}
2476 }
2477 
gen_level_set_unack_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2478 static int gen_level_set_unack_temp(const struct bt_mesh_model *model,
2479 				    struct bt_mesh_msg_ctx *ctx,
2480 				    struct net_buf_simple *buf)
2481 {
2482 	uint8_t tid, tt, delay;
2483 	int16_t level;
2484 	int64_t now;
2485 
2486 	level = (int16_t) net_buf_simple_pull_le16(buf);
2487 	tid = net_buf_simple_pull_u8(buf);
2488 
2489 	now = k_uptime_get();
2490 	if (ctl->last_tid == tid &&
2491 	    ctl->last_src_addr == ctx->addr &&
2492 	    ctl->last_dst_addr == ctx->recv_dst &&
2493 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2494 		return 0;
2495 	}
2496 
2497 	switch (buf->len) {
2498 	case 0x00:      /* No optional fields are available */
2499 		tt = ctl->tt;
2500 		delay = 0U;
2501 		break;
2502 	case 0x02:      /* Optional fields are available */
2503 		tt = net_buf_simple_pull_u8(buf);
2504 		if ((tt & 0x3F) == 0x3F) {
2505 			return 0;
2506 		}
2507 
2508 		delay = net_buf_simple_pull_u8(buf);
2509 		break;
2510 	default:
2511 		return 0;
2512 	}
2513 
2514 	ctl->transition->counter = 0U;
2515 	k_timer_stop(&ctl->transition->timer);
2516 
2517 	ctl->last_tid = tid;
2518 	ctl->last_src_addr = ctx->addr;
2519 	ctl->last_dst_addr = ctx->recv_dst;
2520 	ctl->last_msg_timestamp = now;
2521 	ctl->transition->tt = tt;
2522 	ctl->transition->delay = delay;
2523 	ctl->transition->type = NON_MOVE;
2524 	set_target(LEVEL_TEMP, &level);
2525 
2526 	if (ctl->temp->target != ctl->temp->current) {
2527 		set_transition_values(LEVEL_TEMP);
2528 	} else {
2529 		return 0;
2530 	}
2531 
2532 	/* For Instantaneous Transition */
2533 	if (ctl->transition->counter == 0U) {
2534 		ctl->temp->current = ctl->temp->target;
2535 	}
2536 
2537 	ctl->transition->just_started = true;
2538 	gen_level_publish_temp(model);
2539 	level_temp_handler();
2540 
2541 	return 0;
2542 }
2543 
gen_level_set_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2544 static int gen_level_set_temp(const struct bt_mesh_model *model,
2545 			      struct bt_mesh_msg_ctx *ctx,
2546 			      struct net_buf_simple *buf)
2547 {
2548 	uint8_t tid, tt, delay;
2549 	int16_t level;
2550 	int64_t now;
2551 
2552 	level = (int16_t) net_buf_simple_pull_le16(buf);
2553 	tid = net_buf_simple_pull_u8(buf);
2554 
2555 	now = k_uptime_get();
2556 	if (ctl->last_tid == tid &&
2557 	    ctl->last_src_addr == ctx->addr &&
2558 	    ctl->last_dst_addr == ctx->recv_dst &&
2559 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2560 		(void)gen_level_get_temp(model, ctx, buf);
2561 		return 0;
2562 	}
2563 
2564 	switch (buf->len) {
2565 	case 0x00:      /* No optional fields are available */
2566 		tt = ctl->tt;
2567 		delay = 0U;
2568 		break;
2569 	case 0x02:      /* Optional fields are available */
2570 		tt = net_buf_simple_pull_u8(buf);
2571 		if ((tt & 0x3F) == 0x3F) {
2572 			return 0;
2573 		}
2574 
2575 		delay = net_buf_simple_pull_u8(buf);
2576 		break;
2577 	default:
2578 		return 0;
2579 	}
2580 
2581 	ctl->transition->counter = 0U;
2582 	k_timer_stop(&ctl->transition->timer);
2583 
2584 	ctl->last_tid = tid;
2585 	ctl->last_src_addr = ctx->addr;
2586 	ctl->last_dst_addr = ctx->recv_dst;
2587 	ctl->last_msg_timestamp = now;
2588 	ctl->transition->tt = tt;
2589 	ctl->transition->delay = delay;
2590 	ctl->transition->type = NON_MOVE;
2591 	set_target(LEVEL_TEMP, &level);
2592 
2593 	if (ctl->temp->target != ctl->temp->current) {
2594 		set_transition_values(LEVEL_TEMP);
2595 	} else {
2596 		(void)gen_level_get_temp(model, ctx, buf);
2597 		return 0;
2598 	}
2599 
2600 	/* For Instantaneous Transition */
2601 	if (ctl->transition->counter == 0U) {
2602 		ctl->temp->current = ctl->temp->target;
2603 	}
2604 
2605 	ctl->transition->just_started = true;
2606 	(void)gen_level_get_temp(model, ctx, buf);
2607 	gen_level_publish_temp(model);
2608 	level_temp_handler();
2609 
2610 	return 0;
2611 }
2612 
gen_delta_set_unack_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2613 static int gen_delta_set_unack_temp(const struct bt_mesh_model *model,
2614 				    struct bt_mesh_msg_ctx *ctx,
2615 				    struct net_buf_simple *buf)
2616 {
2617 	uint8_t tid, tt, delay;
2618 	static int16_t last_level;
2619 	int32_t target, delta;
2620 	int64_t now;
2621 
2622 	delta = (int32_t) net_buf_simple_pull_le32(buf);
2623 	tid = net_buf_simple_pull_u8(buf);
2624 
2625 	now = k_uptime_get();
2626 	if (ctl->last_tid == tid &&
2627 	    ctl->last_src_addr == ctx->addr &&
2628 	    ctl->last_dst_addr == ctx->recv_dst &&
2629 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2630 
2631 		if (ctl->temp->delta == delta) {
2632 			return 0;
2633 		}
2634 		target = last_level + delta;
2635 
2636 	} else {
2637 		last_level = (int16_t) get_current(LEVEL_TEMP);
2638 		target = last_level + delta;
2639 	}
2640 
2641 	switch (buf->len) {
2642 	case 0x00:      /* No optional fields are available */
2643 		tt = ctl->tt;
2644 		delay = 0U;
2645 		break;
2646 	case 0x02:      /* Optional fields are available */
2647 		tt = net_buf_simple_pull_u8(buf);
2648 		if ((tt & 0x3F) == 0x3F) {
2649 			return 0;
2650 		}
2651 
2652 		delay = net_buf_simple_pull_u8(buf);
2653 		break;
2654 	default:
2655 		return 0;
2656 	}
2657 
2658 	ctl->transition->counter = 0U;
2659 	k_timer_stop(&ctl->transition->timer);
2660 
2661 	ctl->last_tid = tid;
2662 	ctl->last_src_addr = ctx->addr;
2663 	ctl->last_dst_addr = ctx->recv_dst;
2664 	ctl->last_msg_timestamp = now;
2665 	ctl->transition->tt = tt;
2666 	ctl->transition->delay = delay;
2667 	ctl->transition->type = NON_MOVE;
2668 
2669 	if (target < INT16_MIN) {
2670 		target = INT16_MIN;
2671 	} else if (target > INT16_MAX) {
2672 		target = INT16_MAX;
2673 	}
2674 
2675 	set_target(LEVEL_TEMP, &target);
2676 
2677 	if (ctl->temp->target != ctl->temp->current) {
2678 		set_transition_values(LEVEL_TEMP);
2679 	} else {
2680 		return 0;
2681 	}
2682 
2683 	/* For Instantaneous Transition */
2684 	if (ctl->transition->counter == 0U) {
2685 		ctl->temp->current = ctl->temp->target;
2686 	}
2687 
2688 	ctl->transition->just_started = true;
2689 	gen_level_publish_temp(model);
2690 	level_temp_handler();
2691 
2692 	return 0;
2693 }
2694 
gen_delta_set_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2695 static int gen_delta_set_temp(const struct bt_mesh_model *model,
2696 			      struct bt_mesh_msg_ctx *ctx,
2697 			      struct net_buf_simple *buf)
2698 {
2699 	uint8_t tid, tt, delay;
2700 	static int16_t last_level;
2701 	int32_t target, delta;
2702 	int64_t now;
2703 
2704 	delta = (int32_t) net_buf_simple_pull_le32(buf);
2705 	tid = net_buf_simple_pull_u8(buf);
2706 
2707 	now = k_uptime_get();
2708 	if (ctl->last_tid == tid &&
2709 	    ctl->last_src_addr == ctx->addr &&
2710 	    ctl->last_dst_addr == ctx->recv_dst &&
2711 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2712 
2713 		if (ctl->temp->delta == delta) {
2714 			(void)gen_level_get_temp(model, ctx, buf);
2715 			return 0;
2716 		}
2717 		target = last_level + delta;
2718 
2719 	} else {
2720 		last_level = (int16_t) get_current(LEVEL_TEMP);
2721 		target = last_level + delta;
2722 	}
2723 
2724 	switch (buf->len) {
2725 	case 0x00:      /* No optional fields are available */
2726 		tt = ctl->tt;
2727 		delay = 0U;
2728 		break;
2729 	case 0x02:      /* Optional fields are available */
2730 		tt = net_buf_simple_pull_u8(buf);
2731 		if ((tt & 0x3F) == 0x3F) {
2732 			return 0;
2733 		}
2734 
2735 		delay = net_buf_simple_pull_u8(buf);
2736 		break;
2737 	default:
2738 		return 0;
2739 	}
2740 
2741 	ctl->transition->counter = 0U;
2742 	k_timer_stop(&ctl->transition->timer);
2743 
2744 	ctl->last_tid = tid;
2745 	ctl->last_src_addr = ctx->addr;
2746 	ctl->last_dst_addr = ctx->recv_dst;
2747 	ctl->last_msg_timestamp = now;
2748 	ctl->transition->tt = tt;
2749 	ctl->transition->delay = delay;
2750 	ctl->transition->type = NON_MOVE;
2751 
2752 	if (target < INT16_MIN) {
2753 		target = INT16_MIN;
2754 	} else if (target > INT16_MAX) {
2755 		target = INT16_MAX;
2756 	}
2757 
2758 	set_target(LEVEL_TEMP, &target);
2759 
2760 	if (ctl->temp->target != ctl->temp->current) {
2761 		set_transition_values(LEVEL_TEMP);
2762 	} else {
2763 		(void)gen_level_get_temp(model, ctx, buf);
2764 		return 0;
2765 	}
2766 
2767 	/* For Instantaneous Transition */
2768 	if (ctl->transition->counter == 0U) {
2769 		ctl->temp->current = ctl->temp->target;
2770 	}
2771 
2772 	ctl->transition->just_started = true;
2773 	(void)gen_level_get_temp(model, ctx, buf);
2774 	gen_level_publish_temp(model);
2775 	level_temp_handler();
2776 
2777 	return 0;
2778 }
2779 
gen_move_set_unack_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2780 static int gen_move_set_unack_temp(const struct bt_mesh_model *model,
2781 				   struct bt_mesh_msg_ctx *ctx,
2782 				   struct net_buf_simple *buf)
2783 {
2784 	uint8_t tid, tt, delay;
2785 	int16_t delta;
2786 	uint16_t target;
2787 	int64_t now;
2788 
2789 	delta = (int16_t) net_buf_simple_pull_le16(buf);
2790 	tid = net_buf_simple_pull_u8(buf);
2791 
2792 	now = k_uptime_get();
2793 	if (ctl->last_tid == tid &&
2794 	    ctl->last_src_addr == ctx->addr &&
2795 	    ctl->last_dst_addr == ctx->recv_dst &&
2796 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2797 		return 0;
2798 	}
2799 
2800 	switch (buf->len) {
2801 	case 0x00:      /* No optional fields are available */
2802 		tt = ctl->tt;
2803 		delay = 0U;
2804 		break;
2805 	case 0x02:      /* Optional fields are available */
2806 		tt = net_buf_simple_pull_u8(buf);
2807 		if ((tt & 0x3F) == 0x3F) {
2808 			return 0;
2809 		}
2810 
2811 		delay = net_buf_simple_pull_u8(buf);
2812 		break;
2813 	default:
2814 		return 0;
2815 	}
2816 
2817 	ctl->transition->counter = 0U;
2818 	k_timer_stop(&ctl->transition->timer);
2819 
2820 	ctl->last_tid = tid;
2821 	ctl->last_src_addr = ctx->addr;
2822 	ctl->last_dst_addr = ctx->recv_dst;
2823 	ctl->last_msg_timestamp = now;
2824 	ctl->transition->tt = tt;
2825 	ctl->transition->delay = delay;
2826 	ctl->transition->type = MOVE;
2827 	ctl->temp->delta = delta;
2828 
2829 	if (delta < 0) {
2830 		target = ctl->temp->range_min;
2831 	} else if (delta > 0) {
2832 		target = ctl->temp->range_max;
2833 	} else if (delta == 0) {
2834 		target = ctl->temp->current;
2835 	}
2836 	set_target(MOVE_TEMP, &target);
2837 
2838 	if (ctl->temp->target != ctl->temp->current) {
2839 		set_transition_values(MOVE_TEMP);
2840 	} else {
2841 		return 0;
2842 	}
2843 
2844 	if (ctl->transition->counter == 0U) {
2845 		return 0;
2846 	}
2847 
2848 	ctl->transition->just_started = true;
2849 	gen_level_publish_temp(model);
2850 	level_temp_handler();
2851 
2852 	return 0;
2853 }
2854 
gen_move_set_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2855 static int gen_move_set_temp(const struct bt_mesh_model *model,
2856 			     struct bt_mesh_msg_ctx *ctx,
2857 			     struct net_buf_simple *buf)
2858 {
2859 	uint8_t tid, tt, delay;
2860 	int16_t delta;
2861 	uint16_t target;
2862 	int64_t now;
2863 
2864 	delta = (int16_t) net_buf_simple_pull_le16(buf);
2865 	tid = net_buf_simple_pull_u8(buf);
2866 
2867 	now = k_uptime_get();
2868 	if (ctl->last_tid == tid &&
2869 	    ctl->last_src_addr == ctx->addr &&
2870 	    ctl->last_dst_addr == ctx->recv_dst &&
2871 	    (now - ctl->last_msg_timestamp <= (6 * MSEC_PER_SEC))) {
2872 		(void)gen_level_get_temp(model, ctx, buf);
2873 		return 0;
2874 	}
2875 
2876 	switch (buf->len) {
2877 	case 0x00:      /* No optional fields are available */
2878 		tt = ctl->tt;
2879 		delay = 0U;
2880 		break;
2881 	case 0x02:      /* Optional fields are available */
2882 		tt = net_buf_simple_pull_u8(buf);
2883 		if ((tt & 0x3F) == 0x3F) {
2884 			return 0;
2885 		}
2886 
2887 		delay = net_buf_simple_pull_u8(buf);
2888 		break;
2889 	default:
2890 		return 0;
2891 	}
2892 
2893 	ctl->transition->counter = 0U;
2894 	k_timer_stop(&ctl->transition->timer);
2895 
2896 	ctl->last_tid = tid;
2897 	ctl->last_src_addr = ctx->addr;
2898 	ctl->last_dst_addr = ctx->recv_dst;
2899 	ctl->last_msg_timestamp = now;
2900 	ctl->transition->tt = tt;
2901 	ctl->transition->delay = delay;
2902 	ctl->transition->type = MOVE;
2903 	ctl->temp->delta = delta;
2904 
2905 	if (delta < 0) {
2906 		target = ctl->temp->range_min;
2907 	} else if (delta > 0) {
2908 		target = ctl->temp->range_max;
2909 	} else if (delta == 0) {
2910 		target = ctl->temp->current;
2911 	}
2912 	set_target(MOVE_TEMP, &target);
2913 
2914 	if (ctl->temp->target != ctl->temp->current) {
2915 		set_transition_values(MOVE_TEMP);
2916 	} else {
2917 		(void)gen_level_get_temp(model, ctx, buf);
2918 		return 0;
2919 	}
2920 
2921 	if (ctl->transition->counter == 0U) {
2922 		return 0;
2923 	}
2924 
2925 	ctl->transition->just_started = true;
2926 	(void)gen_level_get_temp(model, ctx, buf);
2927 	gen_level_publish_temp(model);
2928 	level_temp_handler();
2929 
2930 	return 0;
2931 }
2932 
2933 /* Generic Level (TEMPERATURE) Client message handlers */
gen_level_status_temp(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2934 static int gen_level_status_temp(const struct bt_mesh_model *model,
2935 				 struct bt_mesh_msg_ctx *ctx,
2936 				 struct net_buf_simple *buf)
2937 {
2938 	printk("Acknowledgement from GEN_LEVEL_SRV\n");
2939 	printk("Present Level = %04x\n", net_buf_simple_pull_le16(buf));
2940 
2941 	if (buf->len == 3U) {
2942 		printk("Target Level = %04x\n", net_buf_simple_pull_le16(buf));
2943 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
2944 	}
2945 
2946 	return 0;
2947 }
2948 
2949 
2950 /* message handlers (End) */
2951 
2952 /* Mapping of message handlers for Generic OnOff Server (0x1000) */
2953 static const struct bt_mesh_model_op gen_onoff_srv_op[] = {
2954 	{ BT_MESH_MODEL_OP_2(0x82, 0x01), BT_MESH_LEN_EXACT(0), gen_onoff_get },
2955 	{ BT_MESH_MODEL_OP_2(0x82, 0x02), BT_MESH_LEN_MIN(2),   gen_onoff_set },
2956 	{ BT_MESH_MODEL_OP_2(0x82, 0x03), BT_MESH_LEN_MIN(2),   gen_onoff_set_unack },
2957 	BT_MESH_MODEL_OP_END,
2958 };
2959 
2960 /* Mapping of message handlers for Generic OnOff Client (0x1001) */
2961 static const struct bt_mesh_model_op gen_onoff_cli_op[] = {
2962 	{ BT_MESH_MODEL_OP_2(0x82, 0x04), BT_MESH_LEN_MIN(1),   gen_onoff_status },
2963 	BT_MESH_MODEL_OP_END,
2964 };
2965 
2966 /* Mapping of message handlers for Generic Level (Light) Server (0x1002) */
2967 static const struct bt_mesh_model_op gen_level_srv_op[] = {
2968 	{ BT_MESH_MODEL_OP_2(0x82, 0x05), BT_MESH_LEN_EXACT(0), gen_level_get },
2969 	{ BT_MESH_MODEL_OP_2(0x82, 0x06), BT_MESH_LEN_MIN(3),   gen_level_set },
2970 	{ BT_MESH_MODEL_OP_2(0x82, 0x07), BT_MESH_LEN_MIN(3),   gen_level_set_unack },
2971 	{ BT_MESH_MODEL_OP_2(0x82, 0x09), BT_MESH_LEN_MIN(5),   gen_delta_set },
2972 	{ BT_MESH_MODEL_OP_2(0x82, 0x0A), BT_MESH_LEN_MIN(5),   gen_delta_set_unack },
2973 	{ BT_MESH_MODEL_OP_2(0x82, 0x0B), BT_MESH_LEN_MIN(3),   gen_move_set },
2974 	{ BT_MESH_MODEL_OP_2(0x82, 0x0C), BT_MESH_LEN_MIN(3),   gen_move_set_unack },
2975 	BT_MESH_MODEL_OP_END,
2976 };
2977 
2978 /* Mapping of message handlers for Generic Level (Light) Client (0x1003) */
2979 static const struct bt_mesh_model_op gen_level_cli_op[] = {
2980 	{ BT_MESH_MODEL_OP_2(0x82, 0x08), BT_MESH_LEN_MIN(2),   gen_level_status },
2981 	BT_MESH_MODEL_OP_END,
2982 };
2983 
2984 /* Mapping of message handlers for Generic Default TT Server (0x1004) */
2985 static const struct bt_mesh_model_op gen_def_trans_time_srv_op[] = {
2986 	{ BT_MESH_MODEL_OP_2(0x82, 0x0D), BT_MESH_LEN_EXACT(0), gen_def_trans_time_get },
2987 	{ BT_MESH_MODEL_OP_2(0x82, 0x0E), BT_MESH_LEN_EXACT(1), gen_def_trans_time_set },
2988 	{ BT_MESH_MODEL_OP_2(0x82, 0x0F), BT_MESH_LEN_EXACT(1), gen_def_trans_time_set_unack },
2989 	BT_MESH_MODEL_OP_END,
2990 };
2991 
2992 /* Mapping of message handlers for Generic Default TT Client (0x1005) */
2993 static const struct bt_mesh_model_op gen_def_trans_time_cli_op[] = {
2994 	{ BT_MESH_MODEL_OP_2(0x82, 0x10), BT_MESH_LEN_EXACT(1), gen_def_trans_time_status },
2995 	BT_MESH_MODEL_OP_END,
2996 };
2997 
2998 /* Mapping of message handlers for Generic Power OnOff Server (0x1006) */
2999 static const struct bt_mesh_model_op gen_power_onoff_srv_op[] = {
3000 	{ BT_MESH_MODEL_OP_2(0x82, 0x11), BT_MESH_LEN_MIN(0),   gen_onpowerup_get },
3001 	BT_MESH_MODEL_OP_END,
3002 };
3003 
3004 /* Mapping of message handlers for Generic Power OnOff Setup Server (0x1007) */
3005 static const struct bt_mesh_model_op gen_power_onoff_setup_srv_op[] = {
3006 	{ BT_MESH_MODEL_OP_2(0x82, 0x13), BT_MESH_LEN_EXACT(1), gen_onpowerup_set },
3007 	{ BT_MESH_MODEL_OP_2(0x82, 0x14), BT_MESH_LEN_EXACT(1), gen_onpowerup_set_unack },
3008 	BT_MESH_MODEL_OP_END,
3009 };
3010 
3011 /* Mapping of message handlers for Generic Power OnOff Client (0x1008) */
3012 static const struct bt_mesh_model_op gen_power_onoff_cli_op[] = {
3013 	{ BT_MESH_MODEL_OP_2(0x82, 0x12), BT_MESH_LEN_EXACT(1), gen_onpowerup_status },
3014 	BT_MESH_MODEL_OP_END,
3015 };
3016 
3017 /* Mapping of message handlers for Light Lightness Server (0x1300) */
3018 static const struct bt_mesh_model_op light_lightness_srv_op[] = {
3019 	{ BT_MESH_MODEL_OP_2(0x82, 0x4B), BT_MESH_LEN_EXACT(0), light_lightness_get },
3020 	{ BT_MESH_MODEL_OP_2(0x82, 0x4C), BT_MESH_LEN_MIN(3),   light_lightness_set },
3021 	{ BT_MESH_MODEL_OP_2(0x82, 0x4D), BT_MESH_LEN_MIN(3),   light_lightness_set_unack },
3022 	{ BT_MESH_MODEL_OP_2(0x82, 0x4F), BT_MESH_LEN_EXACT(0), light_lightness_linear_get },
3023 	{ BT_MESH_MODEL_OP_2(0x82, 0x50), BT_MESH_LEN_MIN(3),   light_lightness_linear_set },
3024 	{ BT_MESH_MODEL_OP_2(0x82, 0x51), BT_MESH_LEN_MIN(3),
3025 	  light_lightness_linear_set_unack },
3026 	{ BT_MESH_MODEL_OP_2(0x82, 0x53), BT_MESH_LEN_EXACT(0), light_lightness_last_get },
3027 	{ BT_MESH_MODEL_OP_2(0x82, 0x55), BT_MESH_LEN_EXACT(0), light_lightness_default_get },
3028 	{ BT_MESH_MODEL_OP_2(0x82, 0x57), BT_MESH_LEN_EXACT(0), light_lightness_range_get },
3029 	BT_MESH_MODEL_OP_END,
3030 };
3031 
3032 /* Mapping of message handlers for Light Lightness Setup Server (0x1301) */
3033 static const struct bt_mesh_model_op light_lightness_setup_srv_op[] = {
3034 	{ BT_MESH_MODEL_OP_2(0x82, 0x59), BT_MESH_LEN_EXACT(2), light_lightness_default_set },
3035 	{ BT_MESH_MODEL_OP_2(0x82, 0x5A), BT_MESH_LEN_EXACT(2),
3036 	  light_lightness_default_set_unack },
3037 	{ BT_MESH_MODEL_OP_2(0x82, 0x5B), BT_MESH_LEN_EXACT(4), light_lightness_range_set },
3038 	{ BT_MESH_MODEL_OP_2(0x82, 0x5C), BT_MESH_LEN_EXACT(4), light_lightness_range_set_unack },
3039 	BT_MESH_MODEL_OP_END,
3040 };
3041 
3042 /* Mapping of message handlers for Light Lightness Client (0x1302) */
3043 static const struct bt_mesh_model_op light_lightness_cli_op[] = {
3044 	{ BT_MESH_MODEL_OP_2(0x82, 0x4E), BT_MESH_LEN_MIN(2),   light_lightness_status },
3045 	{ BT_MESH_MODEL_OP_2(0x82, 0x52), BT_MESH_LEN_MIN(2),   light_lightness_linear_status },
3046 	{ BT_MESH_MODEL_OP_2(0x82, 0x54), BT_MESH_LEN_EXACT(2), light_lightness_last_status },
3047 	{ BT_MESH_MODEL_OP_2(0x82, 0x56), BT_MESH_LEN_EXACT(2), light_lightness_default_status },
3048 	{ BT_MESH_MODEL_OP_2(0x82, 0x58), BT_MESH_LEN_EXACT(5), light_lightness_range_status },
3049 	BT_MESH_MODEL_OP_END,
3050 };
3051 
3052 /* Mapping of message handlers for Light CTL Server (0x1303) */
3053 static const struct bt_mesh_model_op light_ctl_srv_op[] = {
3054 	{ BT_MESH_MODEL_OP_2(0x82, 0x5D), BT_MESH_LEN_EXACT(0), light_ctl_get },
3055 	{ BT_MESH_MODEL_OP_2(0x82, 0x5E), BT_MESH_LEN_MIN(7),   light_ctl_set },
3056 	{ BT_MESH_MODEL_OP_2(0x82, 0x5F), BT_MESH_LEN_MIN(7),   light_ctl_set_unack },
3057 	{ BT_MESH_MODEL_OP_2(0x82, 0x62), BT_MESH_LEN_EXACT(0), light_ctl_temp_range_get },
3058 	{ BT_MESH_MODEL_OP_2(0x82, 0x67), BT_MESH_LEN_EXACT(0), light_ctl_default_get },
3059 	BT_MESH_MODEL_OP_END,
3060 };
3061 
3062 /* Mapping of message handlers for Light CTL Setup Server (0x1304) */
3063 static const struct bt_mesh_model_op light_ctl_setup_srv_op[] = {
3064 	{ BT_MESH_MODEL_OP_2(0x82, 0x69), BT_MESH_LEN_EXACT(6), light_ctl_default_set },
3065 	{ BT_MESH_MODEL_OP_2(0x82, 0x6A), BT_MESH_LEN_EXACT(6), light_ctl_default_set_unack },
3066 	{ BT_MESH_MODEL_OP_2(0x82, 0x6B), BT_MESH_LEN_EXACT(4), light_ctl_temp_range_set },
3067 	{ BT_MESH_MODEL_OP_2(0x82, 0x6C), BT_MESH_LEN_EXACT(4), light_ctl_temp_range_set_unack },
3068 	BT_MESH_MODEL_OP_END,
3069 };
3070 
3071 /* Mapping of message handlers for Light CTL Client (0x1305) */
3072 static const struct bt_mesh_model_op light_ctl_cli_op[] = {
3073 	{ BT_MESH_MODEL_OP_2(0x82, 0x60), BT_MESH_LEN_MIN(4),   light_ctl_status },
3074 	{ BT_MESH_MODEL_OP_2(0x82, 0x63), BT_MESH_LEN_EXACT(5), light_ctl_temp_range_status },
3075 	{ BT_MESH_MODEL_OP_2(0x82, 0x66), BT_MESH_LEN_MIN(4),   light_ctl_temp_status },
3076 	{ BT_MESH_MODEL_OP_2(0x82, 0x68), BT_MESH_LEN_EXACT(6), light_ctl_default_status },
3077 	BT_MESH_MODEL_OP_END,
3078 };
3079 
3080 /* Mapping of message handlers for Light CTL Temp. Server (0x1306) */
3081 static const struct bt_mesh_model_op light_ctl_temp_srv_op[] = {
3082 	{ BT_MESH_MODEL_OP_2(0x82, 0x61), BT_MESH_LEN_EXACT(0), light_ctl_temp_get },
3083 	{ BT_MESH_MODEL_OP_2(0x82, 0x64), BT_MESH_LEN_MIN(5),   light_ctl_temp_set },
3084 	{ BT_MESH_MODEL_OP_2(0x82, 0x65), BT_MESH_LEN_MIN(5),   light_ctl_temp_set_unack },
3085 	BT_MESH_MODEL_OP_END,
3086 };
3087 
3088 /* Mapping of message handlers for Vendor (0x4321) */
3089 static const struct bt_mesh_model_op vnd_ops[] = {
3090 	{ BT_MESH_MODEL_OP_3(0x01, CID_ZEPHYR), BT_MESH_LEN_EXACT(0), vnd_get },
3091 	{ BT_MESH_MODEL_OP_3(0x02, CID_ZEPHYR), BT_MESH_LEN_EXACT(3), vnd_set },
3092 	{ BT_MESH_MODEL_OP_3(0x03, CID_ZEPHYR), BT_MESH_LEN_EXACT(3), vnd_set_unack },
3093 	{ BT_MESH_MODEL_OP_3(0x04, CID_ZEPHYR), BT_MESH_LEN_EXACT(6), vnd_status },
3094 	BT_MESH_MODEL_OP_END,
3095 };
3096 
3097 /* Mapping of message handlers for Generic Level (Temp.) Server (0x1002) */
3098 static const struct bt_mesh_model_op gen_level_srv_op_temp[] = {
3099 	{ BT_MESH_MODEL_OP_2(0x82, 0x05), BT_MESH_LEN_EXACT(0), gen_level_get_temp },
3100 	{ BT_MESH_MODEL_OP_2(0x82, 0x06), BT_MESH_LEN_MIN(3),   gen_level_set_temp },
3101 	{ BT_MESH_MODEL_OP_2(0x82, 0x07), BT_MESH_LEN_MIN(3),   gen_level_set_unack_temp },
3102 	{ BT_MESH_MODEL_OP_2(0x82, 0x09), BT_MESH_LEN_MIN(5),   gen_delta_set_temp },
3103 	{ BT_MESH_MODEL_OP_2(0x82, 0x0A), BT_MESH_LEN_MIN(5),   gen_delta_set_unack_temp },
3104 	{ BT_MESH_MODEL_OP_2(0x82, 0x0B), BT_MESH_LEN_MIN(3),   gen_move_set_temp },
3105 	{ BT_MESH_MODEL_OP_2(0x82, 0x0C), BT_MESH_LEN_MIN(3),   gen_move_set_unack_temp },
3106 	BT_MESH_MODEL_OP_END,
3107 };
3108 
3109 /* Mapping of message handlers for Generic Level (Temp.) Client (0x1003) */
3110 static const struct bt_mesh_model_op gen_level_cli_op_temp[] = {
3111 	{ BT_MESH_MODEL_OP_2(0x82, 0x08), BT_MESH_LEN_MIN(2), gen_level_status_temp },
3112 	BT_MESH_MODEL_OP_END,
3113 };
3114 
3115 const struct bt_mesh_model root_models[] = {
3116 	BT_MESH_MODEL_CFG_SRV,
3117 	BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
3118 
3119 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV,
3120 		      gen_onoff_srv_op, &gen_onoff_srv_pub_root,
3121 		      NULL),
3122 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI,
3123 		      gen_onoff_cli_op, &gen_onoff_cli_pub_root,
3124 		      NULL),
3125 
3126 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV,
3127 		      gen_level_srv_op, &gen_level_srv_pub_root,
3128 		      NULL),
3129 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_CLI,
3130 		      gen_level_cli_op, &gen_level_cli_pub_root,
3131 		      NULL),
3132 
3133 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV,
3134 		      gen_def_trans_time_srv_op,
3135 		      &gen_def_trans_time_srv_pub,
3136 		      NULL),
3137 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI,
3138 		      gen_def_trans_time_cli_op,
3139 		      &gen_def_trans_time_cli_pub,
3140 		      NULL),
3141 
3142 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV,
3143 		      gen_power_onoff_srv_op, &gen_power_onoff_srv_pub,
3144 		      NULL),
3145 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV,
3146 		      gen_power_onoff_setup_srv_op,
3147 		      &gen_power_onoff_srv_pub,
3148 		      NULL),
3149 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI,
3150 		      gen_power_onoff_cli_op, &gen_power_onoff_cli_pub,
3151 		      NULL),
3152 
3153 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV,
3154 		      light_lightness_srv_op, &light_lightness_srv_pub,
3155 		      NULL),
3156 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV,
3157 		      light_lightness_setup_srv_op,
3158 		      &light_lightness_srv_pub,
3159 		      NULL),
3160 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI,
3161 		      light_lightness_cli_op, &light_lightness_cli_pub,
3162 		      NULL),
3163 
3164 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_SRV,
3165 		      light_ctl_srv_op, &light_ctl_srv_pub,
3166 		      NULL),
3167 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV,
3168 		      light_ctl_setup_srv_op, &light_ctl_srv_pub,
3169 		      NULL),
3170 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_CLI,
3171 		      light_ctl_cli_op, &light_ctl_cli_pub,
3172 		      NULL),
3173 };
3174 
3175 const struct bt_mesh_model vnd_models[] = {
3176 	BT_MESH_MODEL_VND(CID_ZEPHYR, 0x4321, vnd_ops,
3177 			  &vnd_pub, &vnd_user_data),
3178 };
3179 
3180 const struct bt_mesh_model s0_models[] = {
3181 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV,
3182 		      gen_level_srv_op_temp, &gen_level_srv_pub_s0,
3183 		      NULL),
3184 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_CLI,
3185 		      gen_level_cli_op_temp, &gen_level_cli_pub_s0,
3186 		      NULL),
3187 
3188 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV,
3189 		      light_ctl_temp_srv_op, &light_ctl_srv_pub,
3190 		      NULL),
3191 };
3192 
3193 static const struct bt_mesh_elem elements[] = {
3194 	BT_MESH_ELEM(0, root_models, vnd_models),
3195 	BT_MESH_ELEM(0, s0_models, BT_MESH_MODEL_NONE),
3196 };
3197 
3198 const struct bt_mesh_comp comp = {
3199 	.cid = CID_ZEPHYR,
3200 	.elem = elements,
3201 	.elem_count = ARRAY_SIZE(elements),
3202 };
3203