xref: /nrf52832-nimble/packages/NimBLE-latest/apps/blemesh_models_example_2/src/device_composition.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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 "console/console.h"
9 #include "hal/hal_gpio.h"
10 
11 #include "common.h"
12 #include "ble_mesh.h"
13 #include "device_composition.h"
14 #include "state_binding.h"
15 #include "transition.h"
16 
17 static struct bt_mesh_cfg_srv cfg_srv = {
18 	.relay = BT_MESH_RELAY_DISABLED,
19 	.beacon = BT_MESH_BEACON_ENABLED,
20 
21 #if defined(CONFIG_BT_MESH_FRIEND)
22 	.frnd = BT_MESH_FRIEND_ENABLED,
23 #else
24 	.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
25 #endif
26 
27 #if defined(CONFIG_BT_MESH_GATT_PROXY)
28 	.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
29 #else
30 	.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
31 #endif
32 
33 	.default_ttl = 7,
34 
35 	/* 3 transmissions with 20ms interval */
36 	.net_transmit = BT_MESH_TRANSMIT(2, 20),
37 	.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
38 };
39 
40 static struct bt_mesh_health_srv health_srv = {
41 };
42 
43 
44 static struct bt_mesh_model_pub health_pub;
45 
46 static struct bt_mesh_model_pub gen_onoff_srv_pub_root;
47 static struct bt_mesh_model_pub gen_onoff_cli_pub_root;
48 static struct bt_mesh_model_pub gen_level_srv_pub_root;
49 static struct bt_mesh_model_pub gen_level_cli_pub_root;
50 static struct bt_mesh_model_pub gen_def_trans_time_srv_pub;
51 static struct bt_mesh_model_pub gen_def_trans_time_cli_pub;
52 static struct bt_mesh_model_pub gen_power_onoff_srv_pub;
53 static struct bt_mesh_model_pub gen_power_onoff_cli_pub;
54 static struct bt_mesh_model_pub light_lightness_srv_pub;
55 static struct bt_mesh_model_pub light_lightness_cli_pub;
56 static struct bt_mesh_model_pub light_ctl_srv_pub;
57 static struct bt_mesh_model_pub light_ctl_cli_pub;
58 static struct bt_mesh_model_pub vnd_pub;
59 static struct bt_mesh_model_pub gen_onoff_srv_pub_s0;
60 static struct bt_mesh_model_pub gen_onoff_cli_pub_s0;
61 static struct bt_mesh_model_pub gen_level_srv_pub_s0;
62 static struct bt_mesh_model_pub gen_level_cli_pub_s0;
63 
64 
65 static struct os_mbuf *bt_mesh_pub_msg_health_pub;
66 static struct os_mbuf *bt_mesh_pub_msg_gen_onoff_srv_pub_root;
67 static struct os_mbuf *bt_mesh_pub_msg_gen_onoff_cli_pub_root;
68 static struct os_mbuf *bt_mesh_pub_msg_gen_level_srv_pub_root;
69 static struct os_mbuf *bt_mesh_pub_msg_gen_level_cli_pub_root;
70 static struct os_mbuf *bt_mesh_pub_msg_gen_def_trans_time_srv_pub;
71 static struct os_mbuf *bt_mesh_pub_msg_gen_def_trans_time_cli_pub;
72 static struct os_mbuf *bt_mesh_pub_msg_gen_power_onoff_srv_pub;
73 static struct os_mbuf *bt_mesh_pub_msg_gen_power_onoff_cli_pub;
74 static struct os_mbuf *bt_mesh_pub_msg_light_lightness_srv_pub;
75 static struct os_mbuf *bt_mesh_pub_msg_light_lightness_cli_pub;
76 static struct os_mbuf *bt_mesh_pub_msg_light_ctl_srv_pub;
77 static struct os_mbuf *bt_mesh_pub_msg_light_ctl_cli_pub;
78 static struct os_mbuf *bt_mesh_pub_msg_vnd_pub;
79 static struct os_mbuf *bt_mesh_pub_msg_gen_onoff_srv_pub_s0;
80 static struct os_mbuf *bt_mesh_pub_msg_gen_onoff_cli_pub_s0;
81 static struct os_mbuf *bt_mesh_pub_msg_gen_level_srv_pub_s0;
82 static struct os_mbuf *bt_mesh_pub_msg_gen_level_cli_pub_s0;
83 
84 
init_pub(void)85 void init_pub(void)
86 {
87 	bt_mesh_pub_msg_health_pub			= NET_BUF_SIMPLE(1 + 3 + 0);
88 	bt_mesh_pub_msg_gen_onoff_srv_pub_root		= NET_BUF_SIMPLE(2 + 3);
89 	bt_mesh_pub_msg_gen_onoff_cli_pub_root		= NET_BUF_SIMPLE(2 + 4);
90 	bt_mesh_pub_msg_gen_level_srv_pub_root		= NET_BUF_SIMPLE(2 + 5);
91 	bt_mesh_pub_msg_gen_level_cli_pub_root		= NET_BUF_SIMPLE(2 + 7);
92 	bt_mesh_pub_msg_gen_power_onoff_srv_pub		= NET_BUF_SIMPLE(2 + 1);
93 	bt_mesh_pub_msg_gen_power_onoff_cli_pub		= NET_BUF_SIMPLE(2 + 1);
94 	bt_mesh_pub_msg_gen_def_trans_time_srv_pub	= NET_BUF_SIMPLE(2 + 1);
95 	bt_mesh_pub_msg_gen_def_trans_time_cli_pub	= NET_BUF_SIMPLE(2 + 1);
96 	bt_mesh_pub_msg_light_lightness_srv_pub		= NET_BUF_SIMPLE(2 + 5);
97 	bt_mesh_pub_msg_light_lightness_cli_pub		= NET_BUF_SIMPLE(2 + 5);
98 	bt_mesh_pub_msg_light_ctl_srv_pub		= NET_BUF_SIMPLE(2 + 9);
99 	bt_mesh_pub_msg_light_ctl_cli_pub		= NET_BUF_SIMPLE(2 + 9);
100 	bt_mesh_pub_msg_vnd_pub				= NET_BUF_SIMPLE(3 + 6);
101 	bt_mesh_pub_msg_gen_onoff_srv_pub_s0		= NET_BUF_SIMPLE(2 + 3);
102 	bt_mesh_pub_msg_gen_onoff_cli_pub_s0		= NET_BUF_SIMPLE(2 + 4);
103 	bt_mesh_pub_msg_gen_level_srv_pub_s0		= NET_BUF_SIMPLE(2 + 5);
104 	bt_mesh_pub_msg_gen_level_cli_pub_s0		= NET_BUF_SIMPLE(2 + 7);
105 
106 
107 	health_pub.msg				= bt_mesh_pub_msg_health_pub;
108 	gen_onoff_srv_pub_root.msg		= bt_mesh_pub_msg_gen_onoff_srv_pub_root;
109 	gen_onoff_cli_pub_root.msg		= bt_mesh_pub_msg_gen_onoff_cli_pub_root;
110 	gen_level_srv_pub_root.msg		= bt_mesh_pub_msg_gen_level_srv_pub_root;
111 	gen_level_cli_pub_root.msg		= bt_mesh_pub_msg_gen_level_cli_pub_root;
112 	gen_power_onoff_srv_pub.msg		= bt_mesh_pub_msg_gen_power_onoff_srv_pub;
113 	gen_power_onoff_cli_pub.msg		= bt_mesh_pub_msg_gen_power_onoff_cli_pub;
114 	gen_def_trans_time_srv_pub.msg		= bt_mesh_pub_msg_gen_def_trans_time_srv_pub;
115 	gen_def_trans_time_cli_pub.msg		= bt_mesh_pub_msg_gen_def_trans_time_cli_pub;
116 	light_lightness_srv_pub.msg		= bt_mesh_pub_msg_light_lightness_srv_pub;
117 	light_lightness_cli_pub.msg		= bt_mesh_pub_msg_light_lightness_cli_pub;
118 	light_ctl_srv_pub.msg			= bt_mesh_pub_msg_light_ctl_srv_pub;
119 	light_ctl_cli_pub.msg			= bt_mesh_pub_msg_light_ctl_cli_pub;
120 	vnd_pub.msg				= bt_mesh_pub_msg_vnd_pub;
121 	gen_onoff_srv_pub_s0.msg		= bt_mesh_pub_msg_gen_onoff_srv_pub_s0;
122 	gen_onoff_cli_pub_s0.msg		= bt_mesh_pub_msg_gen_onoff_cli_pub_s0;
123 	gen_level_srv_pub_s0.msg		= bt_mesh_pub_msg_gen_level_srv_pub_s0;
124 	gen_level_cli_pub_s0.msg		= bt_mesh_pub_msg_gen_level_cli_pub_s0;
125 }
126 
127 /* Definitions of models user data (Start) */
128 struct generic_onoff_state gen_onoff_srv_root_user_data;
129 
130 struct generic_level_state gen_level_srv_root_user_data;
131 
132 struct gen_def_trans_time_state gen_def_trans_time_srv_user_data;
133 
134 struct generic_onpowerup_state gen_power_onoff_srv_user_data;
135 
136 struct light_lightness_state light_lightness_srv_user_data;
137 
138 struct light_ctl_state light_ctl_srv_user_data;
139 
140 struct vendor_state vnd_user_data;
141 
142 struct generic_onoff_state gen_onoff_srv_s0_user_data;
143 
144 struct generic_level_state gen_level_srv_s0_user_data;
145 /* Definitions of models user data (End) */
146 
147 static struct bt_mesh_elem elements[];
148 
149 /* message handlers (Start) */
150 
151 /* Generic OnOff Server message handlers */
gen_onoff_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)152 static void gen_onoff_get(struct bt_mesh_model *model,
153 			  struct bt_mesh_msg_ctx *ctx,
154 			  struct os_mbuf *buf)
155 {
156 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4);
157 	struct generic_onoff_state *state = model->user_data;
158 
159 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS);
160 	net_buf_simple_add_u8(msg, state->onoff);
161 
162 	if (state->is_optional_para_available) {
163 		net_buf_simple_add_u8(msg, state->target_onoff);
164 		net_buf_simple_add_u8(msg, state->tt);
165 	}
166 
167 	state->is_optional_para_available = 0x00;
168 
169 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
170 		printk("Unable to send GEN_ONOFF_SRV Status response\n");
171 	}
172 }
173 
gen_onoff_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)174 static bool gen_onoff_setunack(struct bt_mesh_model *model,
175 			    struct bt_mesh_msg_ctx *ctx,
176 			    struct os_mbuf *buf)
177 {
178 	u8_t tid, onoff;
179 	s64_t now;
180 	struct os_mbuf *msg = model->pub->msg;
181 	struct generic_onoff_state *state = model->user_data;
182 
183 	onoff = net_buf_simple_pull_u8(buf);
184 	tid = net_buf_simple_pull_u8(buf);
185 
186 	if (onoff > STATE_ON) {
187 		return false;
188 	}
189 
190 	now = k_uptime_get();
191 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
192 	    (now - state->last_msg_timestamp <= K_SECONDS(6))) {
193 		return true;
194 	}
195 
196 	state->is_optional_para_available = 0x01;
197 
198 	switch (buf->om_len) {
199 	case 0x00:	/* No optional fields are available */
200 		state->tt = default_tt;
201 		state->delay = 0;
202 		state->is_optional_para_available = 0x00;
203 		break;
204 	case 0x02:	/* Optional fields are available */
205 		state->tt = net_buf_simple_pull_u8(buf);
206 		state->delay = net_buf_simple_pull_u8(buf);
207 		break;
208 	default:
209 		return false;
210 	}
211 
212 	enable_transition = DISABLE_TRANSITION;
213 
214 	state->last_tid = tid;
215 	state->last_tx_addr = ctx->addr;
216 	state->last_msg_timestamp = now;
217 	state->target_onoff = onoff;
218 
219 	onoff_tt_values(state);
220 
221 	if (state->tt_counter == 0) {
222 		state->onoff = onoff;
223 	}
224 
225 	if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
226 		/* Root element */
227 		onoff_handler(state);
228 	} else if (bt_mesh_model_elem(model)->addr == elements[1].addr) {
229 		/* Secondary element */
230 		printk("Hello World\n");
231 	}
232 
233 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
234 		int err;
235 
236 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS);
237 		net_buf_simple_add_u8(msg, state->onoff);
238 
239 		err = bt_mesh_model_publish(model);
240 		if (err) {
241 			printk("bt_mesh_model_publish err %d\n", err);
242 		}
243 	}
244 
245 	return true;
246 }
247 
gen_onoff_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)248 static void gen_onoff_set_unack(struct bt_mesh_model *model,
249 				struct bt_mesh_msg_ctx *ctx,
250 				struct os_mbuf *buf)
251 {
252 	gen_onoff_setunack(model, ctx, buf);
253 }
254 
gen_onoff_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)255 static void gen_onoff_set(struct bt_mesh_model *model,
256 			  struct bt_mesh_msg_ctx *ctx,
257 			  struct os_mbuf *buf)
258 {
259 	if (gen_onoff_setunack(model, ctx, buf) == true) {
260 		gen_onoff_get(model, ctx, buf);
261 	}
262 }
263 
264 /* Generic OnOff Client message handlers */
gen_onoff_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)265 static void gen_onoff_status(struct bt_mesh_model *model,
266 			     struct bt_mesh_msg_ctx *ctx,
267 			     struct os_mbuf *buf)
268 {
269 	printk("Acknownledgement from GEN_ONOFF_SRV\n");
270 	printk("Present OnOff = %02x\n", net_buf_simple_pull_u8(buf));
271 
272 	if (buf->om_len == 2) {
273 		printk("Target OnOff = %02x\n", net_buf_simple_pull_u8(buf));
274 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
275 	}
276 }
277 
278 /* Generic Level Server message handlers */
gen_level_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)279 static void gen_level_get(struct bt_mesh_model *model,
280 			  struct bt_mesh_msg_ctx *ctx,
281 			  struct os_mbuf *buf)
282 {
283 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4);
284 	struct generic_level_state *state = model->user_data;
285 
286 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
287 	net_buf_simple_add_le16(msg, state->level);
288 
289 	if (state->is_optional_para_available == 0x01) {
290 		net_buf_simple_add_le16(msg, state->target_level);
291 		net_buf_simple_add_u8(msg, state->tt);
292 	} else if (state->is_optional_para_available == 0x02) {
293 
294 		if (state->last_delta < 0) {
295 			net_buf_simple_add_le16(msg, INT16_MIN);
296 		} else if (state->last_delta > 0) {
297 			net_buf_simple_add_le16(msg, INT16_MAX);
298 		}
299 
300 		net_buf_simple_add_u8(msg, state->tt);
301 	}
302 
303 	state->is_optional_para_available = 0x00;
304 
305 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
306 		printk("Unable to send GEN_LEVEL_SRV Status response\n");
307 	}
308 }
309 
gen_level_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)310 static void gen_level_set_unack(struct bt_mesh_model *model,
311 				struct bt_mesh_msg_ctx *ctx,
312 				struct os_mbuf *buf)
313 {
314 	u8_t tid;
315 	s16_t level;
316 	s64_t now;
317 	struct os_mbuf *msg = model->pub->msg;
318 	struct generic_level_state *state = model->user_data;
319 
320 	level = (s16_t) net_buf_simple_pull_le16(buf);
321 	tid = net_buf_simple_pull_u8(buf);
322 
323 	now = k_uptime_get();
324 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
325 	    (now - state->last_msg_timestamp <= K_SECONDS(6))) {
326 		return;
327 	}
328 
329 	state->is_optional_para_available = 0x01;
330 
331 	switch (buf->om_len) {
332 	case 0x00:	/* No optional fields are available */
333 		state->tt = default_tt;
334 		state->delay = 0;
335 		state->is_optional_para_available = 0x00;
336 		break;
337 	case 0x02:	/* Optional fields are available */
338 		state->tt = net_buf_simple_pull_u8(buf);
339 		state->delay = net_buf_simple_pull_u8(buf);
340 		break;
341 	default:
342 		return;
343 	}
344 
345 	enable_transition = DISABLE_TRANSITION;
346 
347 	state->last_tid = tid;
348 	state->last_tx_addr = ctx->addr;
349 	state->last_msg_timestamp = now;
350 	state->target_level = level;
351 
352 	level_tt_values(state);
353 
354 	if (state->tt_counter == 0) {
355 		state->level = level;
356 	}
357 
358 	if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
359 		/* Root element */
360 		enable_transition = LEVEL_TT;
361 		level_lightness_handler(state);
362 	} else if (bt_mesh_model_elem(model)->addr == elements[1].addr) {
363 		/* Secondary element */
364 		enable_transition = LEVEL_TEMP_TT;
365 		level_temp_handler(state);
366 	}
367 
368 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
369 		int err;
370 
371 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
372 		net_buf_simple_add_le16(msg, state->level);
373 
374 		err = bt_mesh_model_publish(model);
375 		if (err) {
376 			printk("bt_mesh_model_publish err %d\n", err);
377 		}
378 	}
379 }
380 
gen_level_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)381 static void gen_level_set(struct bt_mesh_model *model,
382 			  struct bt_mesh_msg_ctx *ctx,
383 			  struct os_mbuf *buf)
384 {
385 	gen_level_set_unack(model, ctx, buf);
386 	gen_level_get(model, ctx, buf);
387 }
388 
gen_delta_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)389 static void gen_delta_set_unack(struct bt_mesh_model *model,
390 				struct bt_mesh_msg_ctx *ctx,
391 				struct os_mbuf *buf)
392 {
393 	u8_t tid;
394 	s32_t tmp32, delta;
395 	s64_t now;
396 	struct os_mbuf *msg = model->pub->msg;
397 	struct generic_level_state *state = model->user_data;
398 
399 	delta = (s32_t) net_buf_simple_pull_le32(buf);
400 	tid = net_buf_simple_pull_u8(buf);
401 
402 	now = k_uptime_get();
403 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr) {
404 
405 		if (now - state->last_msg_timestamp <= K_SECONDS(6)) {
406 			if (state->last_delta == delta) {
407 				return;
408 			}
409 			tmp32 = state->last_level + delta;
410 		} else {
411 			return;
412 		}
413 
414 	} else {
415 		state->last_level = state->level;
416 		tmp32 = state->level + delta;
417 	}
418 
419 	state->is_optional_para_available = 0x01;
420 
421 	switch (buf->om_len) {
422 	case 0x00:	/* No optional fields are available */
423 		state->tt = default_tt;
424 		state->delay = 0;
425 		state->is_optional_para_available = 0x00;
426 		break;
427 	case 0x02:	/* Optional fields are available */
428 		state->tt = net_buf_simple_pull_u8(buf);
429 		state->delay = net_buf_simple_pull_u8(buf);
430 		break;
431 	default:
432 		return;
433 	}
434 
435 	enable_transition = DISABLE_TRANSITION;
436 
437 	state->last_delta = delta;
438 	state->last_tid = tid;
439 	state->last_tx_addr = ctx->addr;
440 	state->last_msg_timestamp = now;
441 
442 	if (tmp32 < INT16_MIN) {
443 		tmp32 = INT16_MIN;
444 	} else if (tmp32 > INT16_MAX) {
445 		tmp32 = INT16_MAX;
446 	}
447 
448 	state->target_level = tmp32;
449 
450 	delta_level_tt_values(state);
451 
452 	if (state->tt_counter_delta == 0) {
453 		state->level = tmp32;
454 	}
455 
456 	if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
457 		/* Root element */
458 		enable_transition = LEVEL_TT_DELTA;
459 		level_lightness_handler(state);
460 	} else if (bt_mesh_model_elem(model)->addr == elements[1].addr) {
461 		/* Secondary element */
462 		enable_transition = LEVEL_TEMP_TT_DELTA;
463 		level_temp_handler(state);
464 	}
465 
466 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
467 		int err;
468 
469 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
470 		net_buf_simple_add_le16(msg, state->level);
471 
472 		err = bt_mesh_model_publish(model);
473 		if (err) {
474 			printk("bt_mesh_model_publish err %d\n", err);
475 		}
476 	}
477 }
478 
gen_delta_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)479 static void gen_delta_set(struct bt_mesh_model *model,
480 			  struct bt_mesh_msg_ctx *ctx,
481 			  struct os_mbuf *buf)
482 {
483 	gen_delta_set_unack(model, ctx, buf);
484 	gen_level_get(model, ctx, buf);
485 }
486 
gen_move_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)487 static void gen_move_set_unack(struct bt_mesh_model *model,
488 			       struct bt_mesh_msg_ctx *ctx,
489 			       struct os_mbuf *buf)
490 {
491 	u8_t tid;
492 	s16_t delta;
493 	s32_t tmp32;
494 	s64_t now;
495 	struct os_mbuf *msg = model->pub->msg;
496 	struct generic_level_state *state = model->user_data;
497 
498 	delta = (s16_t) net_buf_simple_pull_le16(buf);
499 	tid = net_buf_simple_pull_u8(buf);
500 
501 	now = k_uptime_get();
502 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
503 	    (now - state->last_msg_timestamp <= K_SECONDS(6))) {
504 		return;
505 	}
506 
507 	state->is_optional_para_available = 0x02;
508 
509 	switch (buf->om_len) {
510 	case 0x00:	/* No optional fields are available */
511 		state->tt = default_tt;
512 		state->delay = 0;
513 		state->is_optional_para_available = 0x00;
514 		break;
515 	case 0x02:	/* Optional fields are available */
516 		state->tt = net_buf_simple_pull_u8(buf);
517 		state->delay = net_buf_simple_pull_u8(buf);
518 		break;
519 	default:
520 		return;
521 	}
522 
523 	enable_transition = DISABLE_TRANSITION;
524 
525 	state->last_delta = delta;
526 	state->last_tid = tid;
527 	state->last_tx_addr = ctx->addr;
528 	state->last_msg_timestamp = now;
529 
530 	tmp32 = state->level + delta;
531 	if (tmp32 < INT16_MIN) {
532 		tmp32 = INT16_MIN;
533 	} else if (tmp32 > INT16_MAX) {
534 		tmp32 = INT16_MAX;
535 	}
536 
537 	state->target_level = tmp32;
538 
539 	move_level_tt_values(state);
540 
541 	if (bt_mesh_model_elem(model)->addr == elements[0].addr) {
542 		/* Root element */
543 		if (delta == 0) {
544 			ble_npl_callout_stop(&level_lightness_transition_timer);
545 		} else {
546 			enable_transition = LEVEL_TT_MOVE;
547 			level_lightness_handler(state);
548 		}
549 	} else if (bt_mesh_model_elem(model)->addr == elements[1].addr) {
550 		/* Secondary element */
551 		if (delta == 0) {
552 			ble_npl_callout_stop(&level_temp_transition_timer);
553 		} else {
554 			enable_transition = LEVEL_TEMP_TT_MOVE;
555 			level_temp_handler(state);
556 		}
557 	}
558 
559 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
560 		int err;
561 
562 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS);
563 		net_buf_simple_add_le16(msg, state->level);
564 
565 		err = bt_mesh_model_publish(model);
566 		if (err) {
567 			printk("bt_mesh_model_publish err %d\n", err);
568 		}
569 	}
570 }
571 
gen_move_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)572 static void gen_move_set(struct bt_mesh_model *model,
573 			 struct bt_mesh_msg_ctx *ctx,
574 			 struct os_mbuf *buf)
575 {
576 	gen_move_set_unack(model, ctx, buf);
577 	gen_level_get(model, ctx, buf);
578 }
579 
580 /* Generic Level Client message handlers */
gen_level_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)581 static void gen_level_status(struct bt_mesh_model *model,
582 			     struct bt_mesh_msg_ctx *ctx,
583 			     struct os_mbuf *buf)
584 {
585 	printk("Acknownledgement from GEN_LEVEL_SRV\n");
586 	printk("Present Level = %04x\n", net_buf_simple_pull_le16(buf));
587 
588 	if (buf->om_len == 3) {
589 		printk("Target Level = %04x\n", net_buf_simple_pull_le16(buf));
590 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
591 	}
592 }
593 
594 /* Generic Default Transition Time Server message handlers */
gen_def_trans_time_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)595 static void gen_def_trans_time_get(struct bt_mesh_model *model,
596 				   struct bt_mesh_msg_ctx *ctx,
597 				   struct os_mbuf *buf)
598 {
599 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4);
600 	struct gen_def_trans_time_state *state = model->user_data;
601 
602 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x10));
603 	net_buf_simple_add_u8(msg, state->tt);
604 
605 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
606 		printk("Unable to send GEN_DEF_TT_SRV Status response\n");
607 	}
608 }
609 
gen_def_trans_time_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)610 static bool gen_def_trans_time_setunack(struct bt_mesh_model *model,
611 					struct bt_mesh_msg_ctx *ctx,
612 					struct os_mbuf *buf)
613 {
614 	u8_t tt;
615 	struct os_mbuf *msg = model->pub->msg;
616 	struct gen_def_trans_time_state *state = model->user_data;
617 
618 	tt = net_buf_simple_pull_u8(buf);
619 
620 	/* Here, Model specification is silent about tid implementation */
621 
622 	if ((tt & 0x3F) == 0x3F) {
623 		return false;
624 	}
625 
626 	state->tt = tt;
627 	default_tt = tt;
628 
629 	/* Do some work here to save value of state->tt on SoC flash */
630 
631 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
632 		int err;
633 
634 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x10));
635 		net_buf_simple_add_u8(msg, state->tt);
636 
637 		err = bt_mesh_model_publish(model);
638 		if (err) {
639 			printk("bt_mesh_model_publish err %d\n", err);
640 		}
641 	}
642 
643 	return true;
644 }
645 
gen_def_trans_time_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)646 static void gen_def_trans_time_set_unack(struct bt_mesh_model *model,
647 					 struct bt_mesh_msg_ctx *ctx,
648 					 struct os_mbuf *buf)
649 {
650 	gen_def_trans_time_setunack(model, ctx, buf);
651 }
652 
gen_def_trans_time_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)653 static void gen_def_trans_time_set(struct bt_mesh_model *model,
654 				   struct bt_mesh_msg_ctx *ctx,
655 				   struct os_mbuf *buf)
656 {
657 	if (gen_def_trans_time_setunack(model, ctx, buf) == true) {
658 		gen_def_trans_time_get(model, ctx, buf);
659 	}
660 }
661 
662 /* Generic Default Transition Time Client message handlers */
gen_def_trans_time_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)663 static void gen_def_trans_time_status(struct bt_mesh_model *model,
664 				      struct bt_mesh_msg_ctx *ctx,
665 				      struct os_mbuf *buf)
666 {
667 	printk("Acknownledgement from GEN_DEF_TT_SRV\n");
668 	printk("Transition Time = %02x\n", net_buf_simple_pull_u8(buf));
669 }
670 
671 /* Generic Power OnOff Server message handlers */
gen_onpowerup_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)672 static void gen_onpowerup_get(struct bt_mesh_model *model,
673 			      struct bt_mesh_msg_ctx *ctx,
674 			      struct os_mbuf *buf)
675 {
676 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4);
677 	struct generic_onpowerup_state *state = model->user_data;
678 
679 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x12));
680 	net_buf_simple_add_u8(msg, state->onpowerup);
681 
682 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
683 		printk("Unable to send GEN_POWER_ONOFF_SRV Status response\n");
684 	}
685 }
686 
687 /* Generic Power OnOff Client message handlers */
gen_onpowerup_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)688 static void gen_onpowerup_status(struct bt_mesh_model *model,
689 				 struct bt_mesh_msg_ctx *ctx,
690 				 struct os_mbuf *buf)
691 {
692 	printk("Acknownledgement from GEN_POWER_ONOFF_SRV\n");
693 	printk("OnPowerUp = %02x\n", net_buf_simple_pull_u8(buf));
694 }
695 
696 /* Generic Power OnOff Setup Server message handlers */
gen_onpowerup_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)697 static bool gen_onpowerup_setunack(struct bt_mesh_model *model,
698 				struct bt_mesh_msg_ctx *ctx,
699 				struct os_mbuf *buf)
700 {
701 	u8_t onpowerup;
702 	struct os_mbuf *msg = model->pub->msg;
703 	struct generic_onpowerup_state *state = model->user_data;
704 
705 	onpowerup = net_buf_simple_pull_u8(buf);
706 
707 	/* Here, Model specification is silent about tid implementation */
708 
709 	if (onpowerup > STATE_RESTORE) {
710 		return false;
711 	}
712 	state->onpowerup = onpowerup;
713 
714 	/* Do some work here to save value of state->onpowerup on SoC flash */
715 
716 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
717 		int err;
718 
719 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x12));
720 		net_buf_simple_add_u8(msg, state->onpowerup);
721 
722 		err = bt_mesh_model_publish(model);
723 		if (err) {
724 			printk("bt_mesh_model_publish err %d\n", err);
725 		}
726 	}
727 
728 	return true;
729 }
730 
gen_onpowerup_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)731 static void gen_onpowerup_set_unack(struct bt_mesh_model *model,
732 				    struct bt_mesh_msg_ctx *ctx,
733 				    struct os_mbuf *buf)
734 {
735 	gen_onpowerup_setunack(model, ctx, buf);
736 }
737 
gen_onpowerup_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)738 static void gen_onpowerup_set(struct bt_mesh_model *model,
739 			      struct bt_mesh_msg_ctx *ctx,
740 			      struct os_mbuf *buf)
741 {
742 	if (gen_onpowerup_setunack(model, ctx, buf) == true) {
743 		gen_onpowerup_get(model, ctx, buf);
744 	}
745 }
746 
747 /* Vendor Model message handlers*/
vnd_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)748 static void vnd_get(struct bt_mesh_model *model,
749 		    struct bt_mesh_msg_ctx *ctx,
750 		    struct os_mbuf *buf)
751 {
752 	struct os_mbuf *msg = NET_BUF_SIMPLE(3 + 6 + 4);
753 	struct vendor_state *state = model->user_data;
754 
755 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x03, CID_RUNTIME));
756 
757 	net_buf_simple_add_le16(msg, state->current);
758 	net_buf_simple_add_le32(msg, state->response);
759 
760 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
761 		printk("Unable to send VENDOR Status response\n");
762 	}
763 }
764 
vnd_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)765 static void vnd_set_unack(struct bt_mesh_model *model,
766 			  struct bt_mesh_msg_ctx *ctx,
767 			  struct os_mbuf *buf)
768 {
769 	u8_t tid;
770 	int current;
771 	s64_t now;
772 	struct vendor_state *state = model->user_data;
773 
774 	current = net_buf_simple_pull_le16(buf);
775 	tid = net_buf_simple_pull_u8(buf);
776 
777 	now = k_uptime_get();
778 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
779 	    (now - state->last_msg_timestamp <= 6000)) {
780 		return;
781 	}
782 
783 	state->last_tid = tid;
784 	state->last_tx_addr = ctx->addr;
785 	state->last_msg_timestamp = now;
786 	state->current = current;
787 
788 	/* This is dummy response for demo purpose */
789 	state->response = 0xA578FEB3;
790 
791 	printk("Vendor model message = %04x\n", state->current);
792 
793 	if (state->current == STATE_ON) {
794 		/* LED2 On */
795 		hal_gpio_write(led_device[1], 0);
796 	} else {
797 		/* LED2 Off */
798 		hal_gpio_write(led_device[1], 1);
799 	}
800 }
801 
vnd_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)802 static void vnd_set(struct bt_mesh_model *model,
803 		    struct bt_mesh_msg_ctx *ctx,
804 		    struct os_mbuf *buf)
805 {
806 	vnd_set_unack(model, ctx, buf);
807 	vnd_get(model, ctx, buf);
808 }
809 
vnd_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)810 static void vnd_status(struct bt_mesh_model *model,
811 		       struct bt_mesh_msg_ctx *ctx,
812 		       struct os_mbuf *buf)
813 {
814 	printk("Acknownledgement from Vendor\n");
815 	printk("cmd = %04x\n", net_buf_simple_pull_le16(buf));
816 	printk("response = %08lx\n", net_buf_simple_pull_le32(buf));
817 }
818 
819 /* Light Lightness Server message handlers */
light_lightness_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)820 static void light_lightness_get(struct bt_mesh_model *model,
821 				struct bt_mesh_msg_ctx *ctx,
822 				struct os_mbuf *buf)
823 {
824 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4);
825 	struct light_lightness_state *state = model->user_data;
826 
827 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x4E));
828 	net_buf_simple_add_le16(msg, state->actual);
829 
830 	if (state->is_optional_para_available) {
831 		net_buf_simple_add_le16(msg, state->target_actual);
832 		net_buf_simple_add_u8(msg, state->tt);
833 	}
834 
835 	state->is_optional_para_available = 0x00;
836 
837 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
838 		printk("Unable to send LightLightnessAct Status response\n");
839 	}
840 }
841 
light_lightness_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)842 static void light_lightness_set_unack(struct bt_mesh_model *model,
843 				      struct bt_mesh_msg_ctx *ctx,
844 				      struct os_mbuf *buf)
845 {
846 	u8_t tid;
847 	u16_t actual;
848 	s64_t now;
849 	struct os_mbuf *msg = model->pub->msg;
850 	struct light_lightness_state *state = model->user_data;
851 
852 	actual = net_buf_simple_pull_le16(buf);
853 	tid = net_buf_simple_pull_u8(buf);
854 
855 	now = k_uptime_get();
856 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
857 	    (now - state->last_msg_timestamp <= K_SECONDS(6))) {
858 		return;
859 	}
860 
861 	state->is_optional_para_available = 0x01;
862 
863 	switch (buf->om_len) {
864 	case 0x00:	/* No optional fields are available */
865 		state->tt = default_tt;
866 		state->delay = 0;
867 		state->is_optional_para_available = 0x00;
868 		break;
869 	case 0x02:	/* Optional fields are available */
870 		state->tt = net_buf_simple_pull_u8(buf);
871 		state->delay = net_buf_simple_pull_u8(buf);
872 		break;
873 	default:
874 		return;
875 	}
876 
877 	enable_transition = DISABLE_TRANSITION;
878 
879 	state->last_tid = tid;
880 	state->last_tx_addr = ctx->addr;
881 	state->last_msg_timestamp = now;
882 
883 	if (actual > 0 && actual < state->light_range_min) {
884 		actual = state->light_range_min;
885 	} else if (actual > state->light_range_max) {
886 		actual = state->light_range_max;
887 	}
888 
889 	state->target_actual = actual;
890 
891 	light_lightnes_actual_tt_values(state);
892 
893 	if (state->tt_counter_actual == 0) {
894 		state->actual = actual;
895 	}
896 
897 	light_lightness_actual_handler(state);
898 
899 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
900 		int err;
901 
902 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x4E));
903 		net_buf_simple_add_le16(msg, state->actual);
904 
905 		err = bt_mesh_model_publish(model);
906 		if (err) {
907 			printk("bt_mesh_model_publish err %d\n", err);
908 		}
909 	}
910 }
911 
light_lightness_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)912 static void light_lightness_set(struct bt_mesh_model *model,
913 				struct bt_mesh_msg_ctx *ctx,
914 				struct os_mbuf *buf)
915 {
916 	light_lightness_set_unack(model, ctx, buf);
917 	light_lightness_get(model, ctx, buf);
918 }
919 
light_lightness_linear_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)920 static void light_lightness_linear_get(struct bt_mesh_model *model,
921 				       struct bt_mesh_msg_ctx *ctx,
922 				       struct os_mbuf *buf)
923 {
924 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4);
925 	struct light_lightness_state *state = model->user_data;
926 
927 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x52));
928 	net_buf_simple_add_le16(msg, state->linear);
929 
930 	if (state->is_optional_para_available) {
931 		net_buf_simple_add_le16(msg, state->target_linear);
932 		net_buf_simple_add_u8(msg, state->tt);
933 	}
934 
935 	state->is_optional_para_available = 0x00;
936 
937 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
938 		printk("Unable to send LightLightnessLin Status response\n");
939 	}
940 }
941 
light_lightness_linear_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)942 static void light_lightness_linear_set_unack(struct bt_mesh_model *model,
943 					     struct bt_mesh_msg_ctx *ctx,
944 					     struct os_mbuf *buf)
945 {
946 	u8_t tid;
947 	u16_t linear;
948 	s64_t now;
949 	struct os_mbuf *msg = model->pub->msg;
950 	struct light_lightness_state *state = model->user_data;
951 
952 	linear = net_buf_simple_pull_le16(buf);
953 	tid = net_buf_simple_pull_u8(buf);
954 
955 	now = k_uptime_get();
956 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
957 	    (now - state->last_msg_timestamp <= K_SECONDS(6))) {
958 		return;
959 	}
960 
961 	state->is_optional_para_available = 0x01;
962 
963 	switch (buf->om_len) {
964 	case 0x00:	/* No optional fields are available */
965 		state->tt = default_tt;
966 		state->delay = 0;
967 		state->is_optional_para_available = 0x00;
968 		break;
969 	case 0x02:	/* Optional fields are available */
970 		state->tt = net_buf_simple_pull_u8(buf);
971 		state->delay = net_buf_simple_pull_u8(buf);
972 		break;
973 	default:
974 		return;
975 	}
976 
977 	enable_transition = DISABLE_TRANSITION;
978 
979 	state->last_tid = tid;
980 	state->last_tx_addr = ctx->addr;
981 	state->last_msg_timestamp = now;
982 	state->target_linear = linear;
983 
984 	light_lightnes_linear_tt_values(state);
985 
986 	if (state->tt_counter_linear == 0) {
987 		state->linear = linear;
988 	}
989 
990 	light_lightness_linear_handler(state);
991 
992 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
993 		int err;
994 
995 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x52));
996 		net_buf_simple_add_le16(msg, state->linear);
997 
998 		err = bt_mesh_model_publish(model);
999 		if (err) {
1000 			printk("bt_mesh_model_publish err %d\n", err);
1001 		}
1002 	}
1003 }
1004 
light_lightness_linear_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1005 static void light_lightness_linear_set(struct bt_mesh_model *model,
1006 				       struct bt_mesh_msg_ctx *ctx,
1007 				       struct os_mbuf *buf)
1008 {
1009 	light_lightness_linear_set_unack(model, ctx, buf);
1010 	light_lightness_linear_get(model, ctx, buf);
1011 }
1012 
light_lightness_last_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1013 static void light_lightness_last_get(struct bt_mesh_model *model,
1014 				     struct bt_mesh_msg_ctx *ctx,
1015 				     struct os_mbuf *buf)
1016 {
1017 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4);
1018 	struct light_lightness_state *state = model->user_data;
1019 
1020 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x54));
1021 
1022 	net_buf_simple_add_le16(msg, state->last);
1023 
1024 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1025 		printk("Unable to send LightLightnessLast Status response\n");
1026 	}
1027 }
1028 
light_lightness_default_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1029 static void light_lightness_default_get(struct bt_mesh_model *model,
1030 					struct bt_mesh_msg_ctx *ctx,
1031 					struct os_mbuf *buf)
1032 {
1033 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4);
1034 	struct light_lightness_state *state = model->user_data;
1035 
1036 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x56));
1037 
1038 	net_buf_simple_add_le16(msg, state->def);
1039 
1040 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1041 		printk("Unable to send LightLightnessDef Status response\n");
1042 	}
1043 }
1044 
light_lightness_range_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1045 static void light_lightness_range_get(struct bt_mesh_model *model,
1046 				      struct bt_mesh_msg_ctx *ctx,
1047 				      struct os_mbuf *buf)
1048 {
1049 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4);
1050 	struct light_lightness_state *state = model->user_data;
1051 
1052 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x58));
1053 
1054 	net_buf_simple_add_u8(msg, state->status_code);
1055 	net_buf_simple_add_le16(msg, state->light_range_min);
1056 	net_buf_simple_add_le16(msg, state->light_range_max);
1057 
1058 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1059 		printk("Unable to send LightLightnessRange Status response\n");
1060 	}
1061 
1062 	state->status_code = RANGE_SUCCESSFULLY_UPDATED;
1063 }
1064 
1065 /* Light Lightness Setup Server message handlers */
light_lightness_default_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1066 static void light_lightness_default_set_unack(struct bt_mesh_model *model,
1067 					      struct bt_mesh_msg_ctx *ctx,
1068 					      struct os_mbuf *buf)
1069 {
1070 	struct os_mbuf *msg = model->pub->msg;
1071 	struct light_lightness_state *state = model->user_data;
1072 
1073 	state->def = net_buf_simple_pull_le16(buf);
1074 
1075 	/* Here, Model specification is silent about tid implementation */
1076 
1077 	/* Do some work here to save value of state->def on SoC flash */
1078 
1079 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
1080 		int err;
1081 
1082 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x56));
1083 		net_buf_simple_add_le16(msg, state->def);
1084 
1085 		err = bt_mesh_model_publish(model);
1086 		if (err) {
1087 			printk("bt_mesh_model_publish err %d\n", err);
1088 		}
1089 	}
1090 }
1091 
light_lightness_default_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1092 static void light_lightness_default_set(struct bt_mesh_model *model,
1093 					struct bt_mesh_msg_ctx *ctx,
1094 					struct os_mbuf *buf)
1095 {
1096 	light_lightness_default_set_unack(model, ctx, buf);
1097 	light_lightness_default_get(model, ctx, buf);
1098 }
1099 
light_lightness_range_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1100 static bool light_lightness_range_setunack(struct bt_mesh_model *model,
1101 					   struct bt_mesh_msg_ctx *ctx,
1102                        struct os_mbuf *buf)
1103 {
1104 	u16_t min, max;
1105 	struct os_mbuf *msg = model->pub->msg;
1106 	struct light_lightness_state *state = model->user_data;
1107 
1108 	min = net_buf_simple_pull_le16(buf);
1109 	max = net_buf_simple_pull_le16(buf);
1110 
1111 	/* Here, Model specification is silent about tid implementation */
1112 
1113 	if (min == 0 || max == 0) {
1114 		return false;
1115 	} else {
1116 		if (min <= max) {
1117 			state->status_code = RANGE_SUCCESSFULLY_UPDATED;
1118 
1119 			state->light_range_min = min;
1120 			state->light_range_max = max;
1121 
1122 			/* Do some work here to save values of
1123 			 * state->light_range_min &
1124 			 * state->light_range_max
1125 			 * on SoC flash
1126 			 */
1127 		} else {
1128 			/* The provided value for Range Max cannot be set */
1129 			state->status_code = CANNOT_SET_RANGE_MAX;
1130 			return false;
1131 		}
1132 	}
1133 
1134 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
1135 		int err;
1136 
1137 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x58));
1138 		net_buf_simple_add_u8(msg, state->status_code);
1139 		net_buf_simple_add_le16(msg, state->light_range_min);
1140 		net_buf_simple_add_le16(msg, state->light_range_max);
1141 
1142 		err = bt_mesh_model_publish(model);
1143 		if (err) {
1144 			printk("bt_mesh_model_publish err %d\n", err);
1145 		}
1146 	}
1147 
1148 	return true;
1149 }
1150 
light_lightness_range_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1151 static void light_lightness_range_set_unack(struct bt_mesh_model *model,
1152 					    struct bt_mesh_msg_ctx *ctx,
1153 					    struct os_mbuf *buf)
1154 {
1155 	light_lightness_range_setunack(model, ctx, buf);
1156 }
1157 
light_lightness_range_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1158 static void light_lightness_range_set(struct bt_mesh_model *model,
1159 				      struct bt_mesh_msg_ctx *ctx,
1160 				      struct os_mbuf *buf)
1161 {
1162 	if (light_lightness_range_setunack(model, ctx, buf) == true) {
1163 		light_lightness_range_get(model, ctx, buf);
1164 	}
1165 }
1166 
1167 /* Light Lightness Client message handlers */
light_lightness_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1168 static void light_lightness_status(struct bt_mesh_model *model,
1169 				   struct bt_mesh_msg_ctx *ctx,
1170 				   struct os_mbuf *buf)
1171 {
1172 	printk("Acknownledgement from LIGHT_LIGHTNESS_SRV (Actual)\n");
1173 	printk("Present Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1174 
1175 	if (buf->om_len == 3) {
1176 		printk("Target Lightness = %04x\n",
1177 		       net_buf_simple_pull_le16(buf));
1178 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
1179 	}
1180 }
1181 
light_lightness_linear_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1182 static void light_lightness_linear_status(struct bt_mesh_model *model,
1183 					  struct bt_mesh_msg_ctx *ctx,
1184 					  struct os_mbuf *buf)
1185 {
1186 	printk("Acknownledgement from LIGHT_LIGHTNESS_SRV (Linear)\n");
1187 	printk("Present Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1188 
1189 	if (buf->om_len == 3) {
1190 		printk("Target Lightness = %04x\n",
1191 		       net_buf_simple_pull_le16(buf));
1192 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
1193 	}
1194 }
1195 
light_lightness_last_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1196 static void light_lightness_last_status(struct bt_mesh_model *model,
1197 					struct bt_mesh_msg_ctx *ctx,
1198 					struct os_mbuf *buf)
1199 {
1200 	printk("Acknownledgement from LIGHT_LIGHTNESS_SRV (Last)\n");
1201 	printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1202 }
1203 
light_lightness_default_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1204 static void light_lightness_default_status(struct bt_mesh_model *model,
1205 					   struct bt_mesh_msg_ctx *ctx,
1206 					   struct os_mbuf *buf)
1207 {
1208 	printk("Acknownledgement from LIGHT_LIGHTNESS_SRV (Default)\n");
1209 	printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1210 }
1211 
light_lightness_range_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1212 static void light_lightness_range_status(struct bt_mesh_model *model,
1213 					 struct bt_mesh_msg_ctx *ctx,
1214 					 struct os_mbuf *buf)
1215 {
1216 	printk("Acknownledgement from LIGHT_LIGHTNESS_SRV (Lightness Range)\n");
1217 	printk("Status Code = %02x\n", net_buf_simple_pull_u8(buf));
1218 	printk("Range Min = %04x\n", net_buf_simple_pull_le16(buf));
1219 	printk("Range Max = %04x\n", net_buf_simple_pull_le16(buf));
1220 }
1221 
1222 /* Light CTL Server message handlers */
light_ctl_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1223 static void light_ctl_get(struct bt_mesh_model *model,
1224 			  struct bt_mesh_msg_ctx *ctx,
1225 			  struct os_mbuf *buf)
1226 {
1227 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4);
1228 	struct light_ctl_state *state = model->user_data;
1229 
1230 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x60));
1231 	net_buf_simple_add_le16(msg, state->lightness);
1232 	net_buf_simple_add_le16(msg, state->temp);
1233 
1234 	if (state->is_optional_para_available) {
1235 		net_buf_simple_add_le16(msg, state->target_lightness);
1236 		net_buf_simple_add_le16(msg, state->target_temp);
1237 		net_buf_simple_add_u8(msg, state->tt);
1238 	}
1239 
1240 	state->is_optional_para_available = 0x00;
1241 
1242 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1243 		printk("Unable to send LightCTL Status response\n");
1244 	}
1245 }
1246 
light_ctl_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1247 static bool light_ctl_setunack(struct bt_mesh_model *model,
1248 			       struct bt_mesh_msg_ctx *ctx,
1249 			       struct os_mbuf *buf)
1250 {
1251 	u8_t tid;
1252 	s16_t delta_uv;
1253 	u16_t lightness, temp;
1254 	s64_t now;
1255 	struct os_mbuf *msg = model->pub->msg;
1256 	struct light_ctl_state *state = model->user_data;
1257 
1258 	lightness = net_buf_simple_pull_le16(buf);
1259 	temp = net_buf_simple_pull_le16(buf);
1260 	delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
1261 	tid = net_buf_simple_pull_u8(buf);
1262 
1263 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
1264 		return false;
1265 	}
1266 
1267 	now = k_uptime_get();
1268 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
1269 	    (now - state->last_msg_timestamp <= K_SECONDS(6))) {
1270 		return true;
1271 	}
1272 
1273 	state->is_optional_para_available = 0x01;
1274 
1275 	switch (buf->om_len) {
1276 	case 0x00:	/* No optional fields are available */
1277 		state->tt = default_tt;
1278 		state->delay = 0;
1279 		state->is_optional_para_available = 0x00;
1280 		break;
1281 	case 0x02:	/* Optional fields are available */
1282 		state->tt = net_buf_simple_pull_u8(buf);
1283 		state->delay = net_buf_simple_pull_u8(buf);
1284 		break;
1285 	default:
1286 		return false;
1287 	}
1288 
1289 	enable_transition = DISABLE_TRANSITION;
1290 
1291 	state->last_tid = tid;
1292 	state->last_tx_addr = ctx->addr;
1293 	state->last_msg_timestamp = now;
1294 	state->target_lightness = lightness;
1295 
1296 	if (temp < state->temp_range_min) {
1297 		temp = state->temp_range_min;
1298 	} else if (temp > state->temp_range_max) {
1299 		temp = state->temp_range_max;
1300 	}
1301 
1302 	state->target_temp = temp;
1303 	state->target_delta_uv = delta_uv;
1304 
1305 	light_ctl_tt_values(state);
1306 
1307 	if (state->tt_counter == 0) {
1308 		state->lightness = lightness;
1309 		state->temp = temp;
1310 		state->delta_uv = delta_uv;
1311 	}
1312 
1313 	light_ctl_handler(state);
1314 
1315 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
1316 		int err;
1317 
1318 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x60));
1319 
1320 		/* Here, as per Model specification, status should be
1321 		 * made up of lightness & temperature values only
1322 		 */
1323 		net_buf_simple_add_le16(msg, state->lightness);
1324 		net_buf_simple_add_le16(msg, state->temp);
1325 
1326 		err = bt_mesh_model_publish(model);
1327 		if (err) {
1328 			printk("bt_mesh_model_publish err %d\n", err);
1329 		}
1330 	}
1331 
1332 	return true;
1333 }
1334 
light_ctl_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1335 static void light_ctl_set_unack(struct bt_mesh_model *model,
1336 				struct bt_mesh_msg_ctx *ctx,
1337 				struct os_mbuf *buf)
1338 {
1339 	light_ctl_setunack(model, ctx, buf);
1340 }
1341 
light_ctl_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1342 static void light_ctl_set(struct bt_mesh_model *model,
1343 			  struct bt_mesh_msg_ctx *ctx,
1344 			  struct os_mbuf *buf)
1345 {
1346 	if (light_ctl_setunack(model, ctx, buf) == true) {
1347 		light_ctl_get(model, ctx, buf);
1348 	}
1349 }
1350 
light_ctl_temp_range_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1351 static void light_ctl_temp_range_get(struct bt_mesh_model *model,
1352 				     struct bt_mesh_msg_ctx *ctx,
1353 				     struct os_mbuf *buf)
1354 {
1355 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4);
1356 	struct light_ctl_state *state = model->user_data;
1357 
1358 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x63));
1359 	net_buf_simple_add_u8(msg, state->status_code);
1360 	net_buf_simple_add_le16(msg, state->temp_range_min);
1361 	net_buf_simple_add_le16(msg, state->temp_range_max);
1362 
1363 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1364 		printk("Unable to send LightCTL Temp Range Status response\n");
1365 	}
1366 
1367 	state->status_code = RANGE_SUCCESSFULLY_UPDATED;
1368 }
1369 
light_ctl_default_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1370 static void light_ctl_default_get(struct bt_mesh_model *model,
1371 				  struct bt_mesh_msg_ctx *ctx,
1372 				  struct os_mbuf *buf)
1373 {
1374 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 6 + 4);
1375 	struct light_ctl_state *state = model->user_data;
1376 
1377 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x68));
1378 	net_buf_simple_add_le16(msg, state->lightness_def);
1379 	net_buf_simple_add_le16(msg, state->temp_def);
1380 	net_buf_simple_add_le16(msg, state->delta_uv_def);
1381 
1382 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1383 		printk("Unable to send LightCTL Default Status response\n");
1384 	}
1385 }
1386 
1387 /* Light CTL Setup Server message handlers */
light_ctl_default_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1388 static bool light_ctl_default_setunack(struct bt_mesh_model *model,
1389 				       struct bt_mesh_msg_ctx *ctx,
1390 				       struct os_mbuf *buf)
1391 {
1392 	u16_t lightness, temp;
1393 	s16_t delta_uv;
1394 	struct os_mbuf *msg = model->pub->msg;
1395 	struct light_ctl_state *state = model->user_data;
1396 
1397 	lightness = net_buf_simple_pull_le16(buf);
1398 	temp = net_buf_simple_pull_le16(buf);
1399 	delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
1400 
1401 	/* Here, Model specification is silent about tid implementation */
1402 
1403 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
1404 		return false;
1405 	}
1406 
1407 	if (temp < state->temp_range_min) {
1408 		temp = state->temp_range_min;
1409 	} else if (temp > state->temp_range_max) {
1410 		temp = state->temp_range_max;
1411 	}
1412 
1413 	state->lightness_def = lightness;
1414 	state->temp_def = temp;
1415 	state->delta_uv_def = delta_uv;
1416 
1417 	/* Do some work here to save values of
1418 	 * state->lightness_def, state->temp_Def & state->delta_uv_def
1419 	 * on SoC flash
1420 	 */
1421 
1422 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
1423 		int err;
1424 
1425 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x68));
1426 		net_buf_simple_add_le16(msg, state->lightness_def);
1427 		net_buf_simple_add_le16(msg, state->temp_def);
1428 		net_buf_simple_add_le16(msg, state->delta_uv_def);
1429 
1430 		err = bt_mesh_model_publish(model);
1431 		if (err) {
1432 			printk("bt_mesh_model_publish err %d\n", err);
1433 		}
1434 	}
1435 
1436 	return true;
1437 }
1438 
light_ctl_default_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1439 static void light_ctl_default_set_unack(struct bt_mesh_model *model,
1440 					struct bt_mesh_msg_ctx *ctx,
1441 					struct os_mbuf *buf)
1442 {
1443 	light_ctl_default_setunack(model, ctx, buf);
1444 }
1445 
light_ctl_default_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1446 static void light_ctl_default_set(struct bt_mesh_model *model,
1447 				  struct bt_mesh_msg_ctx *ctx,
1448 				  struct os_mbuf *buf)
1449 {
1450 	if (light_ctl_default_setunack(model, ctx, buf) == true) {
1451 		light_ctl_default_get(model, ctx, buf);
1452 	}
1453 }
1454 
light_ctl_temp_range_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1455 static bool light_ctl_temp_range_setunack(struct bt_mesh_model *model,
1456 					  struct bt_mesh_msg_ctx *ctx,
1457                       struct os_mbuf *buf)
1458 {
1459 	u16_t min, max;
1460 	struct os_mbuf *msg = model->pub->msg;
1461 	struct light_ctl_state *state = model->user_data;
1462 
1463 	min = net_buf_simple_pull_le16(buf);
1464 	max = net_buf_simple_pull_le16(buf);
1465 
1466 	/* Here, Model specification is silent about tid implementation */
1467 
1468 	/* This is as per 6.1.3.1 in Mesh Model Specification */
1469 	if (min < TEMP_MIN || min > TEMP_MAX ||
1470 	    max < TEMP_MIN || max > TEMP_MAX) {
1471 		return false;
1472 	}
1473 
1474 	if (min <= max) {
1475 		state->status_code = RANGE_SUCCESSFULLY_UPDATED;
1476 		state->temp_range_min = min;
1477 		state->temp_range_max = max;
1478 
1479 		/* Do some work here to save values of
1480 		 * state->temp_range_min & state->temp_range_min
1481 		 * on SoC flash
1482 		 */
1483 	} else {
1484 		/* The provided value for Range Max cannot be set */
1485 		state->status_code = CANNOT_SET_RANGE_MAX;
1486 		return false;
1487 	}
1488 
1489 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
1490 		int err;
1491 
1492 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x63));
1493 		net_buf_simple_add_u8(msg, state->status_code);
1494 		net_buf_simple_add_le16(msg, state->temp_range_min);
1495 		net_buf_simple_add_le16(msg, state->temp_range_max);
1496 
1497 		err = bt_mesh_model_publish(model);
1498 		if (err) {
1499 			printk("bt_mesh_model_publish err %d\n", err);
1500 		}
1501 	}
1502 
1503 	return true;
1504 }
1505 
light_ctl_temp_range_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1506 static void light_ctl_temp_range_set_unack(struct bt_mesh_model *model,
1507 					   struct bt_mesh_msg_ctx *ctx,
1508 					   struct os_mbuf *buf)
1509 {
1510 	light_ctl_temp_range_setunack(model, ctx, buf);
1511 }
1512 
light_ctl_temp_range_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1513 static void light_ctl_temp_range_set(struct bt_mesh_model *model,
1514 				     struct bt_mesh_msg_ctx *ctx,
1515 				     struct os_mbuf *buf)
1516 {
1517 	if (light_ctl_temp_range_setunack(model, ctx, buf) == true) {
1518 		light_ctl_temp_range_get(model, ctx, buf);
1519 	}
1520 }
1521 
1522 /* Light CTL Client message handlers */
light_ctl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1523 static void light_ctl_status(struct bt_mesh_model *model,
1524 			     struct bt_mesh_msg_ctx *ctx,
1525 			     struct os_mbuf *buf)
1526 {
1527 	printk("Acknownledgement from LIGHT_CTL_SRV\n");
1528 	printk("Present CTL Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1529 	printk("Present CTL Temperature = %04x\n",
1530 	       net_buf_simple_pull_le16(buf));
1531 
1532 	if (buf->om_len == 5) {
1533 		printk("Target CTL Lightness = %04x\n",
1534 		       net_buf_simple_pull_le16(buf));
1535 		printk("Target CTL Temperature = %04x\n",
1536 		       net_buf_simple_pull_le16(buf));
1537 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
1538 	}
1539 }
1540 
light_ctl_temp_range_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1541 static void light_ctl_temp_range_status(struct bt_mesh_model *model,
1542 					struct bt_mesh_msg_ctx *ctx,
1543 					struct os_mbuf *buf)
1544 {
1545 	printk("Acknownledgement from LIGHT_CTL_SRV (Temperature Range)\n");
1546 	printk("Status Code = %02x\n", net_buf_simple_pull_u8(buf));
1547 	printk("Range Min = %04x\n", net_buf_simple_pull_le16(buf));
1548 	printk("Range Max = %04x\n", net_buf_simple_pull_le16(buf));
1549 }
1550 
light_ctl_temp_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1551 static void light_ctl_temp_status(struct bt_mesh_model *model,
1552 				  struct bt_mesh_msg_ctx *ctx,
1553 				  struct os_mbuf *buf)
1554 {
1555 	printk("Acknownledgement from LIGHT_CTL_TEMP_SRV\n");
1556 	printk("Present CTL Temperature = %04x\n",
1557 	       net_buf_simple_pull_le16(buf));
1558 	printk("Present CTL Delta UV = %04x\n",
1559 	       net_buf_simple_pull_le16(buf));
1560 
1561 	if (buf->om_len == 5) {
1562 		printk("Target CTL Temperature = %04x\n",
1563 		       net_buf_simple_pull_le16(buf));
1564 		printk("Target CTL Delta UV = %04x\n",
1565 		       net_buf_simple_pull_le16(buf));
1566 		printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf));
1567 	}
1568 }
1569 
light_ctl_default_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1570 static void light_ctl_default_status(struct bt_mesh_model *model,
1571 				     struct bt_mesh_msg_ctx *ctx,
1572 				     struct os_mbuf *buf)
1573 {
1574 	printk("Acknownledgement from LIGHT_CTL_SRV (Default)\n");
1575 	printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf));
1576 	printk("Temperature = %04x\n", net_buf_simple_pull_le16(buf));
1577 	printk("Delta UV = %04x\n", net_buf_simple_pull_le16(buf));
1578 }
1579 
1580 /* Light CTL Temp. Server message handlers */
light_ctl_temp_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1581 static void light_ctl_temp_get(struct bt_mesh_model *model,
1582 			       struct bt_mesh_msg_ctx *ctx,
1583 			       struct os_mbuf *buf)
1584 {
1585 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4);
1586 	struct light_ctl_state *state = model->user_data;
1587 
1588 	bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x66));
1589 	net_buf_simple_add_le16(msg, state->temp);
1590 	net_buf_simple_add_le16(msg, state->delta_uv);
1591 
1592 	if (state->is_optional_para_available) {
1593 		net_buf_simple_add_le16(msg, state->target_temp);
1594 		net_buf_simple_add_le16(msg, state->target_delta_uv);
1595 		net_buf_simple_add_u8(msg, state->tt);
1596 	}
1597 
1598 	state->is_optional_para_available = 0x00;
1599 
1600 	if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
1601 		printk("Unable to send LightCTL Temp. Status response\n");
1602 	}
1603 }
1604 
light_ctl_temp_setunack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1605 static bool light_ctl_temp_setunack(struct bt_mesh_model *model,
1606 				    struct bt_mesh_msg_ctx *ctx,
1607 				    struct os_mbuf *buf)
1608 {
1609 	u8_t tid;
1610 	s16_t delta_uv;
1611 	u16_t temp;
1612 	s64_t now;
1613 
1614 	struct os_mbuf *msg = model->pub->msg;
1615 	struct light_ctl_state *state = model->user_data;
1616 
1617 	temp = net_buf_simple_pull_le16(buf);
1618 	delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
1619 	tid = net_buf_simple_pull_u8(buf);
1620 
1621 	if (temp < TEMP_MIN || temp > TEMP_MAX) {
1622 		return false;
1623 	}
1624 
1625 	now = k_uptime_get();
1626 	if (state->last_tid == tid && state->last_tx_addr == ctx->addr &&
1627 	    (now - state->last_msg_timestamp <= K_SECONDS(6))) {
1628 		return true;
1629 	}
1630 
1631 	state->is_optional_para_available = 0x01;
1632 
1633 	switch (buf->om_len) {
1634 	case 0x00:	/* No optional fields are available */
1635 		state->tt = default_tt;
1636 		state->delay = 0;
1637 		state->is_optional_para_available = 0x00;
1638 		break;
1639 	case 0x02:	/* Optional fields are available */
1640 		state->tt = net_buf_simple_pull_u8(buf);
1641 		state->delay = net_buf_simple_pull_u8(buf);
1642 		break;
1643 	default:
1644 		return false;
1645 	}
1646 
1647 	enable_transition = DISABLE_TRANSITION;
1648 
1649 	state->last_tid = tid;
1650 	state->last_tx_addr = ctx->addr;
1651 	state->last_msg_timestamp = now;
1652 
1653 	if (temp < state->temp_range_min) {
1654 		temp = state->temp_range_min;
1655 	} else if (temp > state->temp_range_max) {
1656 		temp = state->temp_range_max;
1657 	}
1658 
1659 	state->target_temp = temp;
1660 	state->target_delta_uv = delta_uv;
1661 
1662 	light_ctl_temp_tt_values(state);
1663 
1664 	if (state->tt_counter_temp == 0) {
1665 		state->temp = temp;
1666 		state->delta_uv = delta_uv;
1667 	}
1668 
1669 	light_ctl_temp_handler(state);
1670 
1671 	if (model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
1672 		int err;
1673 
1674 		bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x66));
1675 		net_buf_simple_add_le16(msg, state->temp);
1676 		net_buf_simple_add_le16(msg, state->delta_uv);
1677 
1678 		err = bt_mesh_model_publish(model);
1679 		if (err) {
1680 			printk("bt_mesh_model_publish err %d\n", err);
1681 		}
1682 	}
1683 
1684 	return true;
1685 }
1686 
light_ctl_temp_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1687 static void light_ctl_temp_set_unack(struct bt_mesh_model *model,
1688 				     struct bt_mesh_msg_ctx *ctx,
1689 				     struct os_mbuf *buf)
1690 {
1691 	light_ctl_temp_setunack(model, ctx, buf);
1692 }
1693 
light_ctl_temp_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)1694 static void light_ctl_temp_set(struct bt_mesh_model *model,
1695 			       struct bt_mesh_msg_ctx *ctx,
1696 			       struct os_mbuf *buf)
1697 {
1698 	if (light_ctl_temp_setunack(model, ctx, buf) == true) {
1699 		light_ctl_temp_get(model, ctx, buf);
1700 	}
1701 }
1702 
1703 /* message handlers (End) */
1704 
1705 /* Mapping of message handlers for Generic OnOff Server (0x1000) */
1706 static const struct bt_mesh_model_op gen_onoff_srv_op[] = {
1707 	{ BT_MESH_MODEL_OP_2(0x82, 0x01), 0, gen_onoff_get },
1708 	{ BT_MESH_MODEL_OP_2(0x82, 0x02), 2, gen_onoff_set },
1709 	{ BT_MESH_MODEL_OP_2(0x82, 0x03), 2, gen_onoff_set_unack },
1710 	BT_MESH_MODEL_OP_END,
1711 };
1712 
1713 /* Mapping of message handlers for Generic OnOff Client (0x1001) */
1714 static const struct bt_mesh_model_op gen_onoff_cli_op[] = {
1715 	{ BT_MESH_MODEL_OP_2(0x82, 0x04), 1, gen_onoff_status },
1716 	BT_MESH_MODEL_OP_END,
1717 };
1718 
1719 /* Mapping of message handlers for Generic Levl Server (0x1002) */
1720 static const struct bt_mesh_model_op gen_level_srv_op[] = {
1721 	{ BT_MESH_MODEL_OP_2(0x82, 0x05), 0, gen_level_get },
1722 	{ BT_MESH_MODEL_OP_2(0x82, 0x06), 3, gen_level_set },
1723 	{ BT_MESH_MODEL_OP_2(0x82, 0x07), 3, gen_level_set_unack },
1724 	{ BT_MESH_MODEL_OP_2(0x82, 0x09), 5, gen_delta_set },
1725 	{ BT_MESH_MODEL_OP_2(0x82, 0x0A), 5, gen_delta_set_unack },
1726 	{ BT_MESH_MODEL_OP_2(0x82, 0x0B), 5, gen_move_set },
1727 	{ BT_MESH_MODEL_OP_2(0x82, 0x0C), 5, gen_move_set_unack },
1728 	BT_MESH_MODEL_OP_END,
1729 };
1730 
1731 /* Mapping of message handlers for Generic Level Client (0x1003) */
1732 static const struct bt_mesh_model_op gen_level_cli_op[] = {
1733 	{ BT_MESH_MODEL_OP_2(0x82, 0x08), 2, gen_level_status },
1734 	BT_MESH_MODEL_OP_END,
1735 };
1736 
1737 /* Mapping of message handlers for Generic Default TT Server (0x1004) */
1738 static const struct bt_mesh_model_op gen_def_trans_time_srv_op[] = {
1739 	{ BT_MESH_MODEL_OP_2(0x82, 0x0D), 0, gen_def_trans_time_get },
1740 	{ BT_MESH_MODEL_OP_2(0x82, 0x0E), 1, gen_def_trans_time_set },
1741 	{ BT_MESH_MODEL_OP_2(0x82, 0x0F), 1, gen_def_trans_time_set_unack },
1742 	BT_MESH_MODEL_OP_END,
1743 };
1744 
1745 /* Mapping of message handlers for Generic Default TT Client (0x1005) */
1746 static const struct bt_mesh_model_op gen_def_trans_time_cli_op[] = {
1747 	{ BT_MESH_MODEL_OP_2(0x82, 0x10), 1, gen_def_trans_time_status },
1748 	BT_MESH_MODEL_OP_END,
1749 };
1750 
1751 /* Mapping of message handlers for Generic Power OnOff Server (0x1006) */
1752 static const struct bt_mesh_model_op gen_power_onoff_srv_op[] = {
1753 	{ BT_MESH_MODEL_OP_2(0x82, 0x11), 0, gen_onpowerup_get },
1754 	BT_MESH_MODEL_OP_END,
1755 };
1756 
1757 /* Mapping of message handlers for Generic Power OnOff Setup Server (0x1007) */
1758 static const struct bt_mesh_model_op gen_power_onoff_setup_srv_op[] = {
1759 	{ BT_MESH_MODEL_OP_2(0x82, 0x13), 1, gen_onpowerup_set },
1760 	{ BT_MESH_MODEL_OP_2(0x82, 0x14), 1, gen_onpowerup_set_unack },
1761 	BT_MESH_MODEL_OP_END,
1762 };
1763 
1764 /* Mapping of message handlers for Generic Power OnOff Client (0x1008) */
1765 static const struct bt_mesh_model_op gen_power_onoff_cli_op[] = {
1766 	{ BT_MESH_MODEL_OP_2(0x82, 0x12), 1, gen_onpowerup_status },
1767 	BT_MESH_MODEL_OP_END,
1768 };
1769 
1770 /* Mapping of message handlers for Light Lightness Server (0x1300) */
1771 static const struct bt_mesh_model_op light_lightness_srv_op[] = {
1772 	{ BT_MESH_MODEL_OP_2(0x82, 0x4B), 0, light_lightness_get },
1773 	{ BT_MESH_MODEL_OP_2(0x82, 0x4C), 3, light_lightness_set },
1774 	{ BT_MESH_MODEL_OP_2(0x82, 0x4D), 3, light_lightness_set_unack },
1775 	{ BT_MESH_MODEL_OP_2(0x82, 0x4F), 0, light_lightness_linear_get },
1776 	{ BT_MESH_MODEL_OP_2(0x82, 0x50), 3, light_lightness_linear_set },
1777 	{ BT_MESH_MODEL_OP_2(0x82, 0x51), 3,
1778 	  light_lightness_linear_set_unack },
1779 	{ BT_MESH_MODEL_OP_2(0x82, 0x53), 0, light_lightness_last_get },
1780 	{ BT_MESH_MODEL_OP_2(0x82, 0x55), 0, light_lightness_default_get },
1781 	{ BT_MESH_MODEL_OP_2(0x82, 0x57), 0, light_lightness_range_get },
1782 	BT_MESH_MODEL_OP_END,
1783 };
1784 
1785 /* Mapping of message handlers for Light Lightness Setup Server (0x1301) */
1786 static const struct bt_mesh_model_op light_lightness_setup_srv_op[] = {
1787 	{ BT_MESH_MODEL_OP_2(0x82, 0x59), 2, light_lightness_default_set },
1788 	{ BT_MESH_MODEL_OP_2(0x82, 0x5A), 2,
1789 	  light_lightness_default_set_unack },
1790 	{ BT_MESH_MODEL_OP_2(0x82, 0x5B), 4, light_lightness_range_set },
1791 	{ BT_MESH_MODEL_OP_2(0x82, 0x5C), 4, light_lightness_range_set_unack },
1792 	BT_MESH_MODEL_OP_END,
1793 };
1794 
1795 /* Mapping of message handlers for Light Lightness Client (0x1302) */
1796 static const struct bt_mesh_model_op light_lightness_cli_op[] = {
1797 	{ BT_MESH_MODEL_OP_2(0x82, 0x4E), 2, light_lightness_status },
1798 	{ BT_MESH_MODEL_OP_2(0x82, 0x52), 2, light_lightness_linear_status },
1799 	{ BT_MESH_MODEL_OP_2(0x82, 0x54), 2, light_lightness_last_status },
1800 	{ BT_MESH_MODEL_OP_2(0x82, 0x56), 2, light_lightness_default_status },
1801 	{ BT_MESH_MODEL_OP_2(0x82, 0x58), 5, light_lightness_range_status },
1802 	BT_MESH_MODEL_OP_END,
1803 };
1804 
1805 /* Mapping of message handlers for Light CTL Server (0x1303) */
1806 static const struct bt_mesh_model_op light_ctl_srv_op[] = {
1807 	{ BT_MESH_MODEL_OP_2(0x82, 0x5D), 0, light_ctl_get },
1808 	{ BT_MESH_MODEL_OP_2(0x82, 0x5E), 5, light_ctl_set },
1809 	{ BT_MESH_MODEL_OP_2(0x82, 0x5F), 5, light_ctl_set_unack },
1810 	{ BT_MESH_MODEL_OP_2(0x82, 0x62), 0, light_ctl_temp_range_get },
1811 	{ BT_MESH_MODEL_OP_2(0x82, 0x67), 0, light_ctl_default_get },
1812 	BT_MESH_MODEL_OP_END,
1813 };
1814 
1815 /* Mapping of message handlers for Light CTL Setup Server (0x1304) */
1816 static const struct bt_mesh_model_op light_ctl_setup_srv_op[] = {
1817 	{ BT_MESH_MODEL_OP_2(0x82, 0x69), 6, light_ctl_default_set },
1818 	{ BT_MESH_MODEL_OP_2(0x82, 0x6A), 6, light_ctl_default_set_unack },
1819 	{ BT_MESH_MODEL_OP_2(0x82, 0x6B), 4, light_ctl_temp_range_set },
1820 	{ BT_MESH_MODEL_OP_2(0x82, 0x6C), 4, light_ctl_temp_range_set_unack },
1821 	BT_MESH_MODEL_OP_END,
1822 };
1823 
1824 /* Mapping of message handlers for Light CTL Client (0x1305) */
1825 static const struct bt_mesh_model_op light_ctl_cli_op[] = {
1826 	{ BT_MESH_MODEL_OP_2(0x82, 0x60), 4, light_ctl_status },
1827 	{ BT_MESH_MODEL_OP_2(0x82, 0x63), 5, light_ctl_temp_range_status },
1828 	{ BT_MESH_MODEL_OP_2(0x82, 0x66), 4, light_ctl_temp_status },
1829 	{ BT_MESH_MODEL_OP_2(0x82, 0x68), 6, light_ctl_default_status },
1830 	BT_MESH_MODEL_OP_END,
1831 };
1832 
1833 /* Mapping of message handlers for Light CTL Temp. Server (0x1306) */
1834 static const struct bt_mesh_model_op light_ctl_temp_srv_op[] = {
1835 	{ BT_MESH_MODEL_OP_2(0x82, 0x61), 0, light_ctl_temp_get },
1836 	{ BT_MESH_MODEL_OP_2(0x82, 0x64), 5, light_ctl_temp_set },
1837 	{ BT_MESH_MODEL_OP_2(0x82, 0x65), 5, light_ctl_temp_set_unack },
1838 	BT_MESH_MODEL_OP_END,
1839 };
1840 
1841 /* Mapping of message handlers for Vendor (0x4321) */
1842 static const struct bt_mesh_model_op vnd_ops[] = {
1843 	{ BT_MESH_MODEL_OP_3(0x00, CID_RUNTIME), 0, vnd_get },
1844 	{ BT_MESH_MODEL_OP_3(0x01, CID_RUNTIME), 3, vnd_set },
1845 	{ BT_MESH_MODEL_OP_3(0x02, CID_RUNTIME), 3, vnd_set_unack },
1846 	{ BT_MESH_MODEL_OP_3(0x03, CID_RUNTIME), 6, vnd_status },
1847 	BT_MESH_MODEL_OP_END,
1848 };
1849 
1850 struct bt_mesh_model root_models[] = {
1851 	BT_MESH_MODEL_CFG_SRV(&cfg_srv),
1852 	BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
1853 
1854 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV,
1855 		      gen_onoff_srv_op, &gen_onoff_srv_pub_root,
1856 		      &gen_onoff_srv_root_user_data),
1857 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI,
1858 		      gen_onoff_cli_op, &gen_onoff_cli_pub_root,
1859 		      NULL),
1860 
1861 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV,
1862 		      gen_level_srv_op, &gen_level_srv_pub_root,
1863 		      &gen_level_srv_root_user_data),
1864 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_CLI,
1865 		      gen_level_cli_op, &gen_level_cli_pub_root,
1866 		      NULL),
1867 
1868 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV,
1869 		      gen_def_trans_time_srv_op,
1870 		      &gen_def_trans_time_srv_pub,
1871 		      &gen_def_trans_time_srv_user_data),
1872 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI,
1873 		      gen_def_trans_time_cli_op,
1874 		      &gen_def_trans_time_cli_pub,
1875 		      NULL),
1876 
1877 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV,
1878 		      gen_power_onoff_srv_op, &gen_power_onoff_srv_pub,
1879 		      &gen_power_onoff_srv_user_data),
1880 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV,
1881 		      gen_power_onoff_setup_srv_op,
1882 		      &gen_power_onoff_srv_pub,
1883 		      &gen_power_onoff_srv_user_data),
1884 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI,
1885 		      gen_power_onoff_cli_op, &gen_power_onoff_cli_pub,
1886 		      NULL),
1887 
1888 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV,
1889 		      light_lightness_srv_op, &light_lightness_srv_pub,
1890 		      &light_lightness_srv_user_data),
1891 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV,
1892 		      light_lightness_setup_srv_op,
1893 		      &light_lightness_srv_pub,
1894 		      &light_lightness_srv_user_data),
1895 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI,
1896 		      light_lightness_cli_op, &light_lightness_cli_pub,
1897 		      NULL),
1898 
1899 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_SRV,
1900 		      light_ctl_srv_op, &light_ctl_srv_pub,
1901 		      &light_ctl_srv_user_data),
1902 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV,
1903 		      light_ctl_setup_srv_op, &light_ctl_srv_pub,
1904 		      &light_ctl_srv_user_data),
1905 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_CLI,
1906 		      light_ctl_cli_op, &light_ctl_cli_pub,
1907 		      NULL),
1908 };
1909 
1910 struct bt_mesh_model vnd_models[] = {
1911 	BT_MESH_MODEL_VND(CID_RUNTIME, 0x4321, vnd_ops,
1912 			  &vnd_pub, &vnd_user_data),
1913 };
1914 
1915 struct bt_mesh_model s0_models[] = {
1916 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV,
1917 		      gen_onoff_srv_op, &gen_onoff_srv_pub_s0,
1918 		      &gen_onoff_srv_s0_user_data),
1919 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI,
1920 		      gen_onoff_cli_op, &gen_onoff_cli_pub_s0,
1921 		      NULL),
1922 
1923 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV,
1924 		      gen_level_srv_op, &gen_level_srv_pub_s0,
1925 		      &gen_level_srv_s0_user_data),
1926 	BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_CLI,
1927 		      gen_level_cli_op, &gen_level_cli_pub_s0,
1928 		      NULL),
1929 
1930 	BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV,
1931 		      light_ctl_temp_srv_op, &light_ctl_srv_pub,
1932 		      &light_ctl_srv_user_data),
1933 };
1934 
1935 static struct bt_mesh_elem elements[] = {
1936 	BT_MESH_ELEM(0, root_models, vnd_models),
1937 	BT_MESH_ELEM(0, s0_models, BT_MESH_MODEL_NONE),
1938 };
1939 
1940 const struct bt_mesh_comp comp = {
1941 	.cid = CID_RUNTIME,
1942 	.elem = elements,
1943 	.elem_count = ARRAY_SIZE(elements),
1944 };
1945