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