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