1 // Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <errno.h>
16
17 #include "btc_ble_mesh_time_scene_model.h"
18
19 #include "mesh_config.h"
20 #include "access.h"
21 #include "transport.h"
22 #include "model_opcode.h"
23 #include "state_transition.h"
24
25 #if CONFIG_BLE_MESH_TIME_SCENE_SERVER
26
27 static bt_mesh_mutex_t time_scene_server_lock;
28
bt_mesh_time_scene_server_mutex_new(void)29 static inline void bt_mesh_time_scene_server_mutex_new(void)
30 {
31 if (!time_scene_server_lock.mutex) {
32 bt_mesh_mutex_create(&time_scene_server_lock);
33 }
34 }
35
36 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_time_scene_server_mutex_free(void)37 static inline void bt_mesh_time_scene_server_mutex_free(void)
38 {
39 bt_mesh_mutex_free(&time_scene_server_lock);
40 }
41 #endif /* CONFIG_BLE_MESH_DEINIT */
42
bt_mesh_time_scene_server_lock(void)43 void bt_mesh_time_scene_server_lock(void)
44 {
45 bt_mesh_mutex_lock(&time_scene_server_lock);
46 }
47
bt_mesh_time_scene_server_unlock(void)48 void bt_mesh_time_scene_server_unlock(void)
49 {
50 bt_mesh_mutex_unlock(&time_scene_server_lock);
51 }
52
53 /* message handlers (Start) */
54
55 /* Time Server & Time Setup Server message handlers */
send_time_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)56 static void send_time_status(struct bt_mesh_model *model,
57 struct bt_mesh_msg_ctx *ctx,
58 bool publish, uint16_t opcode)
59 {
60 struct net_buf_simple *msg = NULL;
61 uint8_t zero[5] = {0};
62 uint8_t length = 1 + 10;
63
64 if (ctx == NULL && publish == false) {
65 BT_ERR("%s, Invalid parameter", __func__);
66 return;
67 }
68
69 if (publish == false) {
70 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
71 if (msg == NULL) {
72 BT_ERR("%s, Out of memory", __func__);
73 return;
74 }
75 } else {
76 msg = bt_mesh_server_get_pub_msg(model, length);
77 if (msg == NULL) {
78 return;
79 }
80 }
81
82 bt_mesh_model_msg_init(msg, opcode);
83 switch (opcode) {
84 case BLE_MESH_MODEL_OP_TIME_STATUS:
85 if (model->id == BLE_MESH_MODEL_ID_TIME_SRV) {
86 struct bt_mesh_time_srv *srv = model->user_data;
87 net_buf_simple_add_mem(msg, srv->state->time.tai_seconds, TAI_SECONDS_LEN);
88 if (memcmp(srv->state->time.tai_seconds, zero, TAI_SECONDS_LEN)) {
89 net_buf_simple_add_u8(msg, srv->state->time.subsecond);
90 /**
91 * Set the Uncertainty field to a value that is a sum of the value of
92 * the Uncertainty state and an estimated time it will take the message
93 * to be processed before being sent on the radio interface.
94 *
95 * TODO: how to estimate the processing time?
96 */
97 net_buf_simple_add_u8(msg, srv->state->time.uncertainty);
98 net_buf_simple_add_le16(msg,
99 (srv->state->time.tai_utc_delta_curr << 1) | srv->state->time.time_authority);
100 net_buf_simple_add_u8(msg, srv->state->time.time_zone_offset_curr);
101 }
102 } else if (model->id == BLE_MESH_MODEL_ID_TIME_SETUP_SRV) {
103 struct bt_mesh_time_setup_srv *srv = model->user_data;
104 net_buf_simple_add_mem(msg, srv->state->time.tai_seconds, TAI_SECONDS_LEN);
105 if (memcmp(srv->state->time.tai_seconds, zero, TAI_SECONDS_LEN)) {
106 net_buf_simple_add_u8(msg, srv->state->time.subsecond);
107 net_buf_simple_add_u8(msg, srv->state->time.uncertainty);
108 net_buf_simple_add_le16(msg,
109 (srv->state->time.tai_utc_delta_curr << 1) | srv->state->time.time_authority);
110 net_buf_simple_add_u8(msg, srv->state->time.time_zone_offset_curr);
111 }
112 }
113 break;
114 case BLE_MESH_MODEL_OP_TIME_ZONE_STATUS:
115 if (model->id == BLE_MESH_MODEL_ID_TIME_SRV) {
116 struct bt_mesh_time_srv *srv = model->user_data;
117 net_buf_simple_add_u8(msg, srv->state->time.time_zone_offset_curr);
118 net_buf_simple_add_u8(msg, srv->state->time.time_zone_offset_new);
119 net_buf_simple_add_mem(msg, srv->state->time.tai_zone_change, TAI_OF_ZONE_CHANGE_LEN);
120 } else if (model->id == BLE_MESH_MODEL_ID_TIME_SETUP_SRV) {
121 struct bt_mesh_time_setup_srv *srv = model->user_data;
122 net_buf_simple_add_u8(msg, srv->state->time.time_zone_offset_curr);
123 net_buf_simple_add_u8(msg, srv->state->time.time_zone_offset_new);
124 net_buf_simple_add_mem(msg, srv->state->time.tai_zone_change, TAI_OF_ZONE_CHANGE_LEN);
125 }
126 break;
127 case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS:
128 if (model->id == BLE_MESH_MODEL_ID_TIME_SRV) {
129 struct bt_mesh_time_srv *srv = model->user_data;
130 net_buf_simple_add_le16(msg, srv->state->time.tai_utc_delta_curr);
131 net_buf_simple_add_le16(msg, srv->state->time.tai_utc_delta_new);
132 net_buf_simple_add_mem(msg, srv->state->time.tai_delta_change, TAI_OF_DELTA_CHANGE_LEN);
133 } else if (model->id == BLE_MESH_MODEL_ID_TIME_SETUP_SRV) {
134 struct bt_mesh_time_setup_srv *srv = model->user_data;
135 net_buf_simple_add_le16(msg, srv->state->time.tai_utc_delta_curr);
136 net_buf_simple_add_le16(msg, srv->state->time.tai_utc_delta_new);
137 net_buf_simple_add_mem(msg, srv->state->time.tai_delta_change, TAI_OF_DELTA_CHANGE_LEN);
138 }
139 break;
140 case BLE_MESH_MODEL_OP_TIME_ROLE_STATUS: {
141 struct bt_mesh_time_setup_srv *srv = model->user_data;
142 net_buf_simple_add_u8(msg, srv->state->time_role);
143 break;
144 }
145 default:
146 BT_WARN("Unknown Time status opcode 0x%04x", opcode);
147 if (publish == false) {
148 bt_mesh_free_buf(msg);
149 }
150 return;
151 }
152
153 if (publish == false) {
154 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
155 bt_mesh_free_buf(msg);
156 } else {
157 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
158 }
159 return;
160 }
161
time_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)162 static void time_get(struct bt_mesh_model *model,
163 struct bt_mesh_msg_ctx *ctx,
164 struct net_buf_simple *buf)
165 {
166 struct bt_mesh_server_rsp_ctrl *rsp_ctrl = NULL;
167 uint8_t zero[5] = {0};
168 uint16_t opcode = 0U, val = 0U;
169 uint8_t prev_ttl = 0U;
170
171 if (model->user_data == NULL) {
172 BT_ERR("%s, Invalid model user data", __func__);
173 return;
174 }
175
176 switch (model->id) {
177 case BLE_MESH_MODEL_ID_TIME_SRV: {
178 struct bt_mesh_time_srv *srv = model->user_data;
179 if (srv->state == NULL) {
180 BT_ERR("Invalid Time Server state");
181 return;
182 }
183 rsp_ctrl = &srv->rsp_ctrl;
184 break;
185 }
186 case BLE_MESH_MODEL_ID_TIME_SETUP_SRV: {
187 struct bt_mesh_time_setup_srv *srv = model->user_data;
188 if (srv->state == NULL) {
189 BT_ERR("Invalid Time Setup Server state");
190 return;
191 }
192 rsp_ctrl = &srv->rsp_ctrl;
193 break;
194 }
195 default:
196 BT_ERR("Invalid Time Server, model id 0x%04x", model->id);
197 return;
198 }
199
200 if (rsp_ctrl->get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
201 if (ctx->recv_op != BLE_MESH_MODEL_OP_TIME_STATUS) {
202 bt_mesh_time_scene_server_cb_evt_to_btc(
203 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
204 return;
205 }
206 }
207
208 switch (ctx->recv_op) {
209 case BLE_MESH_MODEL_OP_TIME_GET:
210 opcode = BLE_MESH_MODEL_OP_TIME_STATUS;
211 break;
212 case BLE_MESH_MODEL_OP_TIME_STATUS: {
213 struct bt_mesh_time_srv *srv = model->user_data;
214 if (srv->state == NULL) {
215 BT_ERR("Invalid Time Server state");
216 return;
217 }
218 if (srv->state->time_role != TIME_RELAY &&
219 srv->state->time_role != TIME_CLINET) {
220 /**
221 * If the value of the Time Role state of the element is 0x00 (None) or
222 * 0x01 (Time Authority), the message shall be ignored.
223 */
224 return;
225 }
226 if (rsp_ctrl->status_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
227 bt_mesh_time_scene_server_recv_status_msg_t status = {0};
228 memcpy(status.time_status.tai_seconds, buf->data, TAI_SECONDS_LEN);
229 net_buf_simple_pull(buf, TAI_SECONDS_LEN);
230 if (memcmp(status.time_status.tai_seconds, zero, TAI_SECONDS_LEN)) {
231 if (buf->len != TAI_SECONDS_LEN) {
232 BT_ERR("Invalid Time Status length %d", buf->len + TAI_SECONDS_LEN);
233 return;
234 }
235 status.time_status.subsecond = net_buf_simple_pull_u8(buf);
236 status.time_status.uncertainty = net_buf_simple_pull_u8(buf);
237 val = net_buf_simple_pull_le16(buf);
238 status.time_status.time_authority = val & BIT(0);
239 status.time_status.tai_utc_delta = (val >> 1) & BIT_MASK(15);
240 status.time_status.time_zone_offset = net_buf_simple_pull_u8(buf);
241 }
242 bt_mesh_time_scene_server_cb_evt_to_btc(
243 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_STATUS_MSG, model, ctx, (const uint8_t *)&status, sizeof(status));
244 return;
245 }
246 memcpy(srv->state->time.tai_seconds, buf->data, TAI_SECONDS_LEN);
247 net_buf_simple_pull(buf, TAI_SECONDS_LEN);
248 /**
249 * If the TAI Seconds field is 0x0000000000 the Subsecond, Uncertainty,
250 * Time Authority, TAI-UTC Delta and Time Zone Offset fields shall be
251 * omitted; otherwise these fields shall be present.
252 */
253 if (memcmp(srv->state->time.tai_seconds, zero, TAI_SECONDS_LEN)) {
254 if (buf->len != TAI_SECONDS_LEN) {
255 BT_ERR("Invalid Time Status length %d", buf->len + TAI_SECONDS_LEN);
256 return;
257 }
258 srv->state->time.subsecond = net_buf_simple_pull_u8(buf);
259 srv->state->time.uncertainty = net_buf_simple_pull_u8(buf);
260 val = net_buf_simple_pull_le16(buf);
261 srv->state->time.tai_utc_delta_curr = (val >> 1) & BIT_MASK(15);
262 srv->state->time.time_zone_offset_curr = net_buf_simple_pull_u8(buf);
263 }
264
265 bt_mesh_time_scene_server_state_change_t change = {0};
266 memcpy(change.time_status.tai_seconds, srv->state->time.tai_seconds, TAI_SECONDS_LEN);
267 change.time_status.subsecond = srv->state->time.subsecond;
268 change.time_status.uncertainty = srv->state->time.uncertainty;
269 change.time_status.time_authority = srv->state->time.time_authority;
270 change.time_status.tai_utc_delta_curr = srv->state->time.subsecond;
271 bt_mesh_time_scene_server_cb_evt_to_btc(
272 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
273
274 if (model->pub == NULL || model->pub->msg == NULL ||
275 model->pub->addr == BLE_MESH_ADDR_UNASSIGNED) {
276 return;
277 }
278 prev_ttl = model->pub->ttl;
279 if (srv->state->time_role == TIME_RELAY) {
280 /**
281 * Shall publish a Time Status message using TTL = 0 if the value of the
282 * Time Role state is 0x02 (Time Relay) and the Publish Address for the
283 * Time Server model is not set to unassigned address.
284 */
285 model->pub->ttl = 0U;
286 }
287 send_time_status(model, NULL, true, BLE_MESH_MODEL_OP_TIME_STATUS);
288 /* Restore model publication ttl value */
289 model->pub->ttl = prev_ttl;
290 return;
291 }
292 case BLE_MESH_MODEL_OP_TIME_ZONE_GET:
293 opcode = BLE_MESH_MODEL_OP_TIME_ZONE_STATUS;
294 break;
295 case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_GET:
296 opcode = BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS;
297 break;
298 case BLE_MESH_MODEL_OP_TIME_ROLE_GET:
299 opcode = BLE_MESH_MODEL_OP_TIME_ROLE_STATUS;
300 break;
301 default:
302 BT_WARN("Unknown Time Get opcode 0x%04x", ctx->recv_op);
303 return;
304 }
305
306 send_time_status(model, ctx, false, opcode);
307 return;
308 }
309
time_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)310 static void time_set(struct bt_mesh_model *model,
311 struct bt_mesh_msg_ctx *ctx,
312 struct net_buf_simple *buf)
313 {
314 struct bt_mesh_time_setup_srv *srv = model->user_data;
315 bt_mesh_time_scene_server_state_change_t change = {0};
316 uint16_t opcode = 0U, val = 0U;
317 uint8_t role = 0U;
318
319 if (srv == NULL || srv->state == NULL) {
320 BT_ERR("%s, Invalid model user data", __func__);
321 return;
322 }
323
324 switch (ctx->recv_op) {
325 case BLE_MESH_MODEL_OP_TIME_SET:
326 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
327 bt_mesh_time_scene_server_recv_set_msg_t set = {0};
328 memcpy(set.time_set.tai_seconds, buf->data, TAI_SECONDS_LEN);
329 net_buf_simple_pull(buf, TAI_SECONDS_LEN);
330 set.time_set.subsecond = net_buf_simple_pull_u8(buf);
331 set.time_set.uncertainty = net_buf_simple_pull_u8(buf);
332 val = net_buf_simple_pull_le16(buf);
333 set.time_set.time_authority = val & BIT(0);
334 set.time_set.tai_utc_delta = (val >> 1) & BIT_MASK(15);
335 set.time_set.time_zone_offset = net_buf_simple_pull_u8(buf);
336 bt_mesh_time_scene_server_cb_evt_to_btc(
337 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
338 return;
339 }
340 memcpy(srv->state->time.tai_seconds, buf->data, TAI_SECONDS_LEN);
341 net_buf_simple_pull(buf, TAI_SECONDS_LEN);
342 srv->state->time.subsecond = net_buf_simple_pull_u8(buf);
343 srv->state->time.uncertainty = net_buf_simple_pull_u8(buf);
344 val = net_buf_simple_pull_le16(buf);
345 srv->state->time.time_authority = val & BIT(0);
346 srv->state->time.tai_utc_delta_curr = (val >> 1) & BIT_MASK(15);
347 srv->state->time.time_zone_offset_curr = net_buf_simple_pull_u8(buf);
348 opcode = BLE_MESH_MODEL_OP_TIME_STATUS;
349 break;
350 case BLE_MESH_MODEL_OP_TIME_ZONE_SET:
351 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
352 bt_mesh_time_scene_server_recv_set_msg_t set = {0};
353 set.time_zone_set.time_zone_offset_new = net_buf_simple_pull_u8(buf);
354 memcpy(set.time_zone_set.tai_zone_change, buf->data, TAI_OF_ZONE_CHANGE_LEN);
355 net_buf_simple_pull(buf, TAI_OF_ZONE_CHANGE_LEN);
356 bt_mesh_time_scene_server_cb_evt_to_btc(
357 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
358 return;
359 }
360 srv->state->time.time_zone_offset_new = net_buf_simple_pull_u8(buf);
361 memcpy(srv->state->time.tai_zone_change, buf->data, TAI_OF_ZONE_CHANGE_LEN);
362 net_buf_simple_pull(buf, TAI_OF_ZONE_CHANGE_LEN);
363 opcode = BLE_MESH_MODEL_OP_TIME_ZONE_STATUS;
364 break;
365 case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET:
366 val = net_buf_simple_pull_le16(buf);
367 if ((val >> 15) & BIT(0)) {
368 BT_ERR("Invalid Padding value 1");
369 return;
370 }
371 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
372 bt_mesh_time_scene_server_recv_set_msg_t set = {0};
373 set.tai_utc_delta_set.tai_utc_delta_new = val & BIT_MASK(15);
374 memcpy(set.tai_utc_delta_set.tai_delta_change, buf->data, TAI_OF_DELTA_CHANGE_LEN);
375 net_buf_simple_pull(buf, TAI_OF_DELTA_CHANGE_LEN);
376 bt_mesh_time_scene_server_cb_evt_to_btc(
377 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
378 return;
379 }
380 srv->state->time.tai_utc_delta_new = val & BIT_MASK(15);
381 memcpy(srv->state->time.tai_delta_change, buf->data, TAI_OF_DELTA_CHANGE_LEN);
382 net_buf_simple_pull(buf, TAI_OF_DELTA_CHANGE_LEN);
383 opcode = BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS;
384 break;
385 case BLE_MESH_MODEL_OP_TIME_ROLE_SET:
386 role = net_buf_simple_pull_u8(buf);
387 if (role > TIME_CLINET) {
388 BT_ERR("Invalid Time Role 0x%02x", role);
389 return;
390 }
391 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
392 bt_mesh_time_scene_server_recv_set_msg_t set = {
393 .time_role_set.time_role = role,
394 };
395 bt_mesh_time_scene_server_cb_evt_to_btc(
396 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
397 return;
398 }
399 srv->state->time_role = role;
400 opcode = BLE_MESH_MODEL_OP_TIME_ROLE_STATUS;
401 break;
402 default:
403 BT_ERR("Unknown Time Set opcode 0x%04x", ctx->recv_op);
404 return;
405 }
406
407 switch (ctx->recv_op) {
408 case BLE_MESH_MODEL_OP_TIME_SET:
409 memcpy(change.time_set.tai_seconds, srv->state->time.tai_seconds, TAI_SECONDS_LEN);
410 change.time_set.subsecond = srv->state->time.subsecond;
411 change.time_set.uncertainty = srv->state->time.uncertainty;
412 change.time_set.time_authority = srv->state->time.time_authority;
413 change.time_set.tai_utc_delta_curr = srv->state->time.subsecond;
414 break;
415 case BLE_MESH_MODEL_OP_TIME_ZONE_SET:
416 change.time_zone_set.time_zone_offset_new = srv->state->time.time_zone_offset_new;
417 memcpy(change.time_zone_set.tai_zone_change, srv->state->time.tai_zone_change, TAI_OF_ZONE_CHANGE_LEN);
418 break;
419 case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET:
420 change.tai_utc_delta_set.tai_utc_delta_new = srv->state->time.tai_utc_delta_new;
421 memcpy(change.tai_utc_delta_set.tai_delta_change, srv->state->time.tai_delta_change, TAI_OF_DELTA_CHANGE_LEN);
422 break;
423 case BLE_MESH_MODEL_OP_TIME_ROLE_SET:
424 change.time_role_set.role = srv->state->time_role;
425 break;
426 default:
427 return;
428 }
429
430 bt_mesh_time_scene_server_cb_evt_to_btc(
431 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
432
433 /* Send corresponding time status message */
434 send_time_status(model, ctx, false, opcode);
435 return;
436 }
437
438 /* Scene Server & Scene Setup Server message handlers */
send_scene_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish)439 static void send_scene_status(struct bt_mesh_model *model,
440 struct bt_mesh_msg_ctx *ctx,
441 bool publish)
442 {
443 struct bt_mesh_scene_srv *srv = model->user_data;
444 struct net_buf_simple *msg = NULL;
445 uint8_t length = 1 + 6;
446
447 if (publish == false) {
448 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
449 if (msg == NULL) {
450 BT_ERR("%s, Out of memory", __func__);
451 return;
452 }
453 } else {
454 msg = bt_mesh_server_get_pub_msg(model, length);
455 if (msg == NULL) {
456 return;
457 }
458 }
459
460 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_SCENE_STATUS);
461 /**
462 * If the message is sent as a reply to the Scene Recall message, the
463 * Status Code field identifies the result of the related operation;
464 * otherwise, the Status Code field shall be set to Success.
465 */
466 if (ctx->recv_op == BLE_MESH_MODEL_OP_SCENE_GET) {
467 net_buf_simple_add_u8(msg, SCENE_SUCCESS);
468 } else {
469 net_buf_simple_add_u8(msg, srv->state->status_code);
470 }
471 net_buf_simple_add_le16(msg, srv->state->current_scene);
472 /**
473 * When an element is in the process of changing the Scene state, the
474 * Target Scene field identifies the target Scene Number of the target
475 * Scene state the element is to reach.
476 * When an element is not in the process of changing the Scene state,
477 * the Target Scene field shall be omitted.
478 */
479 if (srv->transition.counter) {
480 bt_mesh_server_calc_remain_time(&srv->transition);
481 net_buf_simple_add_le16(msg, srv->state->target_scene);
482 net_buf_simple_add_u8(msg, srv->transition.remain_time);
483 }
484
485 if (publish == false) {
486 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
487 bt_mesh_free_buf(msg);
488 } else {
489 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
490 }
491 return;
492 }
493
send_scene_register_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t status_code,bool publish)494 static void send_scene_register_status(struct bt_mesh_model *model,
495 struct bt_mesh_msg_ctx *ctx,
496 uint8_t status_code, bool publish)
497 {
498 struct bt_mesh_scene_setup_srv *srv = model->user_data;
499 struct scene_register *scene = NULL;
500 struct net_buf_simple *msg = NULL;
501 uint16_t total_len = 9U;
502 int i;
503
504 if (ctx == NULL && publish == false) {
505 BT_ERR("%s, Invalid parameter", __func__);
506 return;
507 }
508
509 if (publish == false) {
510 msg = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SERVER_RSP_MAX_LEN));
511 if (msg == NULL) {
512 BT_ERR("%s, Out of memory", __func__);
513 return;
514 }
515 } else {
516 msg = bt_mesh_server_get_pub_msg(model, 5);
517 if (msg == NULL) {
518 return;
519 }
520 }
521
522 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS);
523 net_buf_simple_add_u8(msg, status_code);
524 net_buf_simple_add_le16(msg, srv->state->current_scene);
525
526 for (i = 0; i < srv->state->scene_count; i++) {
527 scene = &srv->state->scenes[i];
528 if (scene->scene_number != INVALID_SCENE_NUMBER) {
529 total_len += SCENE_NUMBER_LEN;
530 if ((publish == false && total_len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SERVER_RSP_MAX_LEN)) ||
531 (publish == true && total_len > msg->size + BLE_MESH_SERVER_TRANS_MIC_SIZE)) {
532 /* Add this in case the message is too long */
533 BT_WARN("Too large scene register status");
534 break;
535 }
536 net_buf_simple_add_le16(msg, scene->scene_number);
537 }
538 }
539
540 if (publish == false) {
541 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
542 bt_mesh_free_buf(msg);
543 } else {
544 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
545 }
546 return;
547 }
548
scene_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)549 static void scene_get(struct bt_mesh_model *model,
550 struct bt_mesh_msg_ctx *ctx,
551 struct net_buf_simple *buf)
552 {
553 struct bt_mesh_scene_srv *srv = model->user_data;
554
555 if (srv == NULL || srv->state == NULL) {
556 BT_ERR("%s, Invalid model user data", __func__);
557 return;
558 }
559
560 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
561 bt_mesh_time_scene_server_cb_evt_to_btc(
562 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
563 return;
564 }
565
566 switch (ctx->recv_op) {
567 case BLE_MESH_MODEL_OP_SCENE_GET:
568 send_scene_status(model, ctx, false);
569 return;
570 case BLE_MESH_MODEL_OP_SCENE_REGISTER_GET:
571 /**
572 * When a Scene Server receives a Scene Register Get message, it shall
573 * respond with a Scene Register Status message, setting the Status
574 * Code field to Success.
575 */
576 send_scene_register_status(model, ctx, SCENE_SUCCESS, false);
577 return;
578 default:
579 BT_WARN("Unknown Scene Get opcode 0x%04x", ctx->recv_op);
580 return;
581 }
582 }
583
scene_publish(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t opcode)584 void scene_publish(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint16_t opcode)
585 {
586 struct bt_mesh_scene_srv *srv = model->user_data;
587
588 if (srv == NULL || srv->state == NULL) {
589 BT_ERR("%s, Invalid model user data", __func__);
590 return;
591 }
592
593 send_scene_status(model, ctx, true);
594 return;
595 }
596
scene_recall(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)597 static void scene_recall(struct bt_mesh_model *model,
598 struct bt_mesh_msg_ctx *ctx,
599 struct net_buf_simple *buf)
600 {
601 struct bt_mesh_scene_srv *srv = model->user_data;
602 struct scene_register *scene = NULL;
603 uint8_t tid = 0U, trans_time = 0U, delay = 0U;
604 uint16_t scene_number = 0U;
605 bool optional = false;
606 int64_t now = 0;
607 int i;
608
609 if (srv == NULL || srv->state == NULL) {
610 BT_ERR("%s, Invalid model user data", __func__);
611 return;
612 }
613
614 scene_number = net_buf_simple_pull_le16(buf);
615 if (scene_number == INVALID_SCENE_NUMBER) {
616 BT_ERR("Invalid Scene Number 0x0000");
617 return;
618 }
619 tid = net_buf_simple_pull_u8(buf);
620
621 if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
622 return;
623 }
624
625 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
626 bt_mesh_time_scene_server_recv_set_msg_t set = {
627 .scene_recall.op_en = optional,
628 .scene_recall.scene_number = scene_number,
629 .scene_recall.tid = tid,
630 .scene_recall.trans_time = trans_time,
631 .scene_recall.delay = delay,
632 };
633 bt_mesh_time_scene_server_cb_evt_to_btc(
634 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
635 return;
636 }
637
638 for (i = 0; i < srv->state->scene_count; i++) {
639 scene = &srv->state->scenes[i];
640 if (scene->scene_number == scene_number) {
641 break;
642 }
643 }
644 if (i == srv->state->scene_count) {
645 BT_WARN("Scene Number 0x%04x not exists", scene_number);
646 srv->state->status_code = SCENE_NOT_FOUND;
647 if (ctx->recv_op == BLE_MESH_MODEL_OP_SCENE_RECALL) {
648 send_scene_status(model, ctx, false);
649 }
650 send_scene_status(model, ctx, true);
651 return;
652 }
653 srv->state->status_code = SCENE_SUCCESS;
654
655 /* Mesh Model Spec doesn't mention about this operation. */
656 if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
657 if (ctx->recv_op == BLE_MESH_MODEL_OP_SCENE_RECALL) {
658 send_scene_status(model, ctx, false);
659 }
660 send_scene_status(model, ctx, true);
661 /* In this condition, no event will be callback to application layer */
662 return;
663 }
664
665 bt_mesh_time_scene_server_lock();
666
667 bt_mesh_server_stop_transition(&srv->transition);
668 bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
669
670 srv->state->in_progress = false;
671 /**
672 * When the scene transition is not in progress, the value of the Target
673 * Scene state shall be set to 0x0000.
674 */
675 srv->state->target_scene = INVALID_SCENE_NUMBER;
676
677 /**
678 * If the target state is equal to the current state, the transition
679 * shall not be started and is considered complete.
680 */
681 if (srv->state->current_scene != scene_number) {
682 scene_tt_values(srv, trans_time, delay);
683 } else {
684 if (ctx->recv_op == BLE_MESH_MODEL_OP_SCENE_RECALL) {
685 send_scene_status(model, ctx, false);
686 }
687 send_scene_status(model, ctx, true);
688
689 bt_mesh_time_scene_server_state_change_t change = {
690 .scene_recall.scene_number = scene_number,
691 };
692 bt_mesh_time_scene_server_cb_evt_to_btc(
693 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
694
695 bt_mesh_time_scene_server_unlock();
696 return;
697 }
698
699 /* Copy the ctx of the received message */
700 if (srv->transition.timer.work._reserved) {
701 memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
702 }
703
704 /* For Instantaneous Transition */
705 if (srv->transition.counter == 0U) {
706 srv->state->current_scene = scene_number;
707 } else {
708 /**
709 * When a scene transition is in progress, the value of the Current
710 * Scene state shall be set to 0x0000.
711 */
712 srv->state->in_progress = true;
713 srv->state->current_scene = INVALID_SCENE_NUMBER;
714 srv->state->target_scene = scene_number;
715 }
716
717 srv->transition.just_started = true;
718 if (ctx->recv_op == BLE_MESH_MODEL_OP_SCENE_RECALL) {
719 send_scene_status(model, ctx, false);
720 }
721 send_scene_status(model, ctx, true);
722
723 bt_mesh_time_scene_server_unlock();
724
725 bt_mesh_server_start_transition(&srv->transition);
726 return;
727 }
728
scene_action(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)729 static void scene_action(struct bt_mesh_model *model,
730 struct bt_mesh_msg_ctx *ctx,
731 struct net_buf_simple *buf)
732 {
733 struct bt_mesh_scene_setup_srv *srv = model->user_data;
734 struct scene_register *scene = NULL;
735 uint16_t scene_number = 0U;
736 int i;
737
738 if (srv == NULL || srv->state == NULL) {
739 BT_ERR("%s, Invalid model user data", __func__);
740 return;
741 }
742
743 scene_number = net_buf_simple_pull_le16(buf);
744 if (scene_number == INVALID_SCENE_NUMBER) {
745 BT_ERR("Invalid Scene number 0x0000");
746 return;
747 }
748
749 switch (ctx->recv_op) {
750 case BLE_MESH_MODEL_OP_SCENE_STORE:
751 case BLE_MESH_MODEL_OP_SCENE_STORE_UNACK: {
752 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
753 bt_mesh_time_scene_server_recv_set_msg_t set = {
754 .scene_store.scene_number = scene_number,
755 };
756 bt_mesh_time_scene_server_cb_evt_to_btc(
757 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
758 return;
759 }
760 /* Try to find a matching Scene Number */
761 for (i = 0; i < srv->state->scene_count; i++) {
762 scene = &srv->state->scenes[i];
763 if (scene->scene_number == scene_number) {
764 srv->state->status_code = SCENE_SUCCESS;
765 srv->state->current_scene = scene_number;
766 break;
767 }
768 }
769 /* Try to find a unset entry if no matching Scene Number is found */
770 if (i == srv->state->scene_count) {
771 BT_DBG("No matching Scene Number 0x%04x found", scene_number);
772 for (i = 0; i < srv->state->scene_count; i++) {
773 scene = &srv->state->scenes[i];
774 if (scene->scene_number == INVALID_SCENE_NUMBER) {
775 scene->scene_number = scene_number;
776 srv->state->status_code = SCENE_SUCCESS;
777 srv->state->current_scene = scene_number;
778 break;
779 }
780 }
781 if (i == srv->state->scene_count) {
782 BT_WARN("Scene Register is full!");
783 srv->state->status_code = SCENE_REG_FULL;
784 /* Get the Scene Number of the currently active scene */
785 for (i = 0; i < srv->state->scene_count; i++) {
786 scene = &srv->state->scenes[i];
787 if (scene->scene_number != INVALID_SCENE_NUMBER) {
788 srv->state->current_scene = scene->scene_number;
789 break;
790 }
791 }
792 if (i == srv->state->scene_count) {
793 /* A value of 0x0000 when no scene is active */
794 srv->state->current_scene = INVALID_SCENE_NUMBER;
795 }
796 }
797 }
798
799 if (srv->state->in_progress == true) {
800 /**
801 * When the scene transition is in progress and a new Scene Number is
802 * stored in the Scene Register as a result of Scene Store operation,
803 * the Target Scene state shall be set to the new Scene Number.
804 */
805 srv->state->target_scene = scene_number;
806 }
807 if (srv->state->status_code == SCENE_SUCCESS) {
808 bt_mesh_time_scene_server_state_change_t change = {
809 .scene_store.scene_number = scene_number,
810 };
811 bt_mesh_time_scene_server_cb_evt_to_btc(
812 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
813 }
814 break;
815 }
816 case BLE_MESH_MODEL_OP_SCENE_DELETE:
817 case BLE_MESH_MODEL_OP_SCENE_DELETE_UNACK: {
818 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
819 bt_mesh_time_scene_server_recv_set_msg_t set = {
820 .scene_delete.scene_number = scene_number,
821 };
822 bt_mesh_time_scene_server_cb_evt_to_btc(
823 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
824 return;
825 }
826 for (i = 0; i < srv->state->scene_count; i++) {
827 scene = &srv->state->scenes[i];
828 if (scene->scene_number == scene_number) {
829 scene->scene_number = INVALID_SCENE_NUMBER;
830 break;
831 }
832 }
833 if (i == srv->state->scene_count) {
834 BT_WARN("Scene Number 0x%04x not exists", scene_number);
835 /**
836 * When a Scene Server receives a Scene Delete message with the Scene
837 * Number value that does not match a Scene Number stored within the
838 * Scene Register state, it shall respond with the Scene Register
839 * Status message, setting the Status Code field to Success.
840 */
841 }
842 srv->state->status_code = SCENE_SUCCESS;
843 if (srv->state->current_scene == scene_number) {
844 /**
845 * When the Current Scene Number is deleted from a Scene Register state
846 * as a result of Scene Delete operation, the Current Scene state shall
847 * be set to 0x0000.
848 */
849 srv->state->current_scene = INVALID_SCENE_NUMBER;
850 } else {
851 /**
852 * MMDL/SR/SCES/BV-02-C requires response with Current Scene set to the
853 * latest Scene Number, but this is not mentioned in the spec.
854 *
855 * TODO: Do we need a timestamp for each newly added scene?
856 */
857 for (i = srv->state->scene_count; i > 0; i--) {
858 scene = &srv->state->scenes[i - 1];
859 if (scene->scene_number != INVALID_SCENE_NUMBER) {
860 srv->state->current_scene = scene->scene_number;
861 break;
862 }
863 }
864 if (i == 0) {
865 /* A value of 0x0000 when no scene is active */
866 srv->state->current_scene = INVALID_SCENE_NUMBER;
867 }
868 }
869
870 if (srv->state->target_scene == scene_number &&
871 srv->state->in_progress == true) {
872 /**
873 * When the scene transition is in progress and the target Scene Number
874 * is deleted from a Scene Register state as a result of Scene Delete
875 * operation, the Target Scene state shall be set to 0x0000.
876 */
877 srv->state->target_scene = INVALID_SCENE_NUMBER;
878
879 /**
880 * When a scene is deleted when a scene transition to the deleted Scene
881 * Number is in progress, the scene transition shall be terminated, but
882 * individual model transitions shall not be terminated.
883 */
884 struct bt_mesh_scene_srv *scene_srv = NULL;
885 struct bt_mesh_model *scene_model = NULL;
886
887 scene_model = bt_mesh_model_find(bt_mesh_model_elem(model), BLE_MESH_MODEL_ID_SCENE_SRV);
888 if (scene_model == NULL) {
889 BT_ERR("Scene Server not present in the element");
890 break;
891 }
892
893 scene_srv = scene_model->user_data;
894 if (scene_srv == NULL || scene_srv->state == NULL) {
895 BT_ERR("Invalid Scene Server user data");
896 break;
897 }
898
899 if (srv->state != scene_srv->state) {
900 /**
901 * Add this in case the Scene Setup Server is extending the Scene
902 * Server in another element.
903 */
904 BT_WARN("Different Scene state in Scene Server & Scene Setup Server");
905 break;
906 }
907
908 scene_srv->state->in_progress = false;
909 bt_mesh_server_stop_transition(&scene_srv->transition);
910 }
911
912 bt_mesh_time_scene_server_state_change_t change = {
913 .scene_delete.scene_number = scene_number,
914 };
915 bt_mesh_time_scene_server_cb_evt_to_btc(
916 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
917 break;
918 }
919 default:
920 BT_ERR("Unknown Scene setup action opcode 0x%04x", ctx->recv_op);
921 return;
922 }
923
924 if (ctx->recv_op == BLE_MESH_MODEL_OP_SCENE_STORE ||
925 ctx->recv_op == BLE_MESH_MODEL_OP_SCENE_DELETE) {
926 send_scene_register_status(model, ctx, srv->state->status_code, false);
927 }
928 send_scene_register_status(model, NULL, srv->state->status_code, true);
929
930 return;
931 }
932
get_schedule_reg_bit(struct bt_mesh_scheduler_state * state)933 static uint16_t get_schedule_reg_bit(struct bt_mesh_scheduler_state *state)
934 {
935 uint16_t val = 0U;
936 int i;
937
938 for (i = 0; i < state->schedule_count; i++) {
939 if (state->schedules[i].in_use) {
940 val |= (1 << i);
941 }
942 }
943
944 return val;
945 }
946
get_schedule_reg_state(struct bt_mesh_scheduler_state * state,uint8_t index)947 static uint64_t get_schedule_reg_state(struct bt_mesh_scheduler_state *state, uint8_t index)
948 {
949 struct schedule_register *reg = &state->schedules[index];
950 uint64_t val = 0U;
951
952 val = ((uint64_t)(reg->year) << 4) | index;
953 val |= ((uint64_t)(reg->day) << 23) | ((uint64_t)(reg->month) << 11);
954 val |= ((uint64_t)(reg->minute) << 33) | ((uint64_t)(reg->hour) << 28);
955 val |= ((uint64_t)(reg->day_of_week) << 45) | ((uint64_t)(reg->second) << 39);
956 val |= ((uint64_t)(reg->trans_time) << 56) | ((uint64_t)(reg->action) << 52);
957
958 return val;
959 }
960
send_scheduler_act_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t index)961 static void send_scheduler_act_status(struct bt_mesh_model *model,
962 struct bt_mesh_msg_ctx *ctx,
963 uint8_t index)
964 {
965 NET_BUF_SIMPLE_DEFINE(msg, 1 + 10 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
966 uint64_t value = 0U;
967
968 bt_mesh_model_msg_init(&msg, BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS);
969 switch (model->id) {
970 case BLE_MESH_MODEL_ID_SCHEDULER_SRV: {
971 struct bt_mesh_scheduler_srv *srv = model->user_data;
972 value = get_schedule_reg_state(srv->state, index);
973 net_buf_simple_add_le32(&msg, (uint32_t)value);
974 net_buf_simple_add_le32(&msg, (uint32_t)(value >> 32));
975 net_buf_simple_add_le16(&msg, srv->state->schedules[index].scene_number);
976 break;
977 }
978 case BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV: {
979 struct bt_mesh_scheduler_setup_srv *srv = model->user_data;
980 value = get_schedule_reg_state(srv->state, index);
981 net_buf_simple_add_le32(&msg, (uint32_t)value);
982 net_buf_simple_add_le32(&msg, (uint32_t)(value >> 32));
983 net_buf_simple_add_le16(&msg, srv->state->schedules[index].scene_number);
984 break;
985 }
986 default:
987 BT_ERR("Invalid Scheduler Server, model id 0x%04x", model->id);
988 return;
989 }
990
991 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, &msg, NULL, NULL));
992 return;
993 }
994
scheduler_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)995 static void scheduler_get(struct bt_mesh_model *model,
996 struct bt_mesh_msg_ctx *ctx,
997 struct net_buf_simple *buf)
998 {
999 struct bt_mesh_scheduler_srv *srv = model->user_data;
1000 NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1001
1002 if (srv == NULL || srv->state == NULL) {
1003 BT_ERR("%s, Invalid model user data", __func__);
1004 return;
1005 }
1006
1007 switch (ctx->recv_op) {
1008 case BLE_MESH_MODEL_OP_SCHEDULER_GET: {
1009 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1010 bt_mesh_time_scene_server_cb_evt_to_btc(
1011 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
1012 return;
1013 }
1014
1015 bt_mesh_model_msg_init(&msg, BLE_MESH_MODEL_OP_SCHEDULER_STATUS);
1016 net_buf_simple_add_le16(&msg, get_schedule_reg_bit(srv->state));
1017 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, &msg, NULL, NULL));
1018 return;
1019 }
1020 case BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET: {
1021 uint8_t index = net_buf_simple_pull_u8(buf);
1022 if (index > SCHEDULE_ENTRY_MAX_INDEX) {
1023 BT_ERR("Invalid Scheduler Register Entry index 0x%02x", index);
1024 return;
1025 }
1026
1027 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1028 bt_mesh_time_scene_server_recv_get_msg_t get = {
1029 .scheduler_act_get.index = index,
1030 };
1031 bt_mesh_time_scene_server_cb_evt_to_btc(
1032 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_GET_MSG, model, ctx, (const uint8_t *)&get, sizeof(get));
1033 return;
1034 }
1035
1036 send_scheduler_act_status(model, ctx, index);
1037 return;
1038 }
1039 default:
1040 BT_WARN("Unknown Scheduler Get opcode 0x%04x", ctx->recv_op);
1041 return;
1042 }
1043 }
1044
scheduler_act_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1045 static void scheduler_act_set(struct bt_mesh_model *model,
1046 struct bt_mesh_msg_ctx *ctx,
1047 struct net_buf_simple *buf)
1048 {
1049 /**
1050 * A recommended implementation of the Scheduler should calculate the value
1051 * of the TAI Seconds of the next scheduled event and put it in a queue of
1052 * scheduled events sorted by time. Every second, the first event in the
1053 * queue is compared with the value of the Time state. The first event is
1054 * executed if it is less than or equal to the Time state and then removed
1055 * from the queue. After execution, the Repeat Flag shall be checked, and
1056 * the next occurrence of the scheduled event is calculated and put in the
1057 * queue.
1058 */
1059 struct bt_mesh_scheduler_setup_srv *srv = model->user_data;
1060 uint8_t index = 0U, year = 0U, day = 0U, hour = 0U, minute = 0U,
1061 second = 0U, day_of_week = 0U, action = 0U, trans_time = 0U;
1062 uint16_t month = 0U, scene_number = 0U;
1063 uint64_t value = 0U;
1064
1065 if (srv == NULL || srv->state == NULL) {
1066 BT_ERR("%s, Invalid model user data", __func__);
1067 return;
1068 }
1069
1070 value = net_buf_simple_pull_le32(buf);
1071 value |= ((uint64_t)net_buf_simple_pull_le32(buf) << 32);
1072
1073 index = value & BIT_MASK(4);
1074 year = (value >> 4) & BIT_MASK(7);
1075 month = (value >> 11) & BIT_MASK(12);
1076 day = (value >> 23) & BIT_MASK(5);
1077 hour = (value >> 28) & BIT_MASK(5);
1078 minute = (value >> 33) & BIT_MASK(6);
1079 second = (value >> 39) & BIT_MASK(6);
1080 day_of_week = (value >> 45) & BIT_MASK(7);
1081 action = (value >> 52) & BIT_MASK(4);
1082 trans_time = (value >> 56) & BIT_MASK(8);
1083
1084 if (index > SCHEDULE_ENTRY_MAX_INDEX) {
1085 BT_ERR("Invalid Scheduler Register Entry index 0x%02x", index);
1086 return;
1087 }
1088
1089 if (year > SCHEDULE_YEAR_ANY_YEAR) {
1090 BT_ERR("Invalid Scheduler Register year 0x%02x", year);
1091 return;
1092 }
1093
1094 if (hour > SCHEDULE_HOUR_ONCE_A_DAY) {
1095 BT_ERR("Invalid Scheduler Register hour 0x%02x", hour);
1096 return;
1097 }
1098
1099 if (action > SCHEDULE_ACT_SCENE_RECALL && action != SCHEDULE_ACT_NO_ACTION) {
1100 BT_ERR("Invalid Scheduler Register action 0x%02x", action);
1101 return;
1102 }
1103
1104 scene_number = net_buf_simple_pull_le16(buf);
1105
1106 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1107 bt_mesh_time_scene_server_recv_set_msg_t set = {
1108 .scheduler_act_set.index = index,
1109 .scheduler_act_set.year = year,
1110 .scheduler_act_set.month = month,
1111 .scheduler_act_set.day = day,
1112 .scheduler_act_set.hour = hour,
1113 .scheduler_act_set.minute = minute,
1114 .scheduler_act_set.second = second,
1115 .scheduler_act_set.day_of_week = day_of_week,
1116 .scheduler_act_set.action = action,
1117 .scheduler_act_set.trans_time = trans_time,
1118 .scheduler_act_set.scene_number = scene_number,
1119 };
1120 bt_mesh_time_scene_server_cb_evt_to_btc(
1121 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1122 return;
1123 }
1124
1125 srv->state->schedules[index].in_use = true;
1126 srv->state->schedules[index].year = year;
1127 srv->state->schedules[index].month = month;
1128 srv->state->schedules[index].day = day;
1129 srv->state->schedules[index].hour = hour;
1130 srv->state->schedules[index].minute = minute;
1131 srv->state->schedules[index].second = second;
1132 srv->state->schedules[index].day_of_week = day_of_week;
1133 srv->state->schedules[index].action = action;
1134 srv->state->schedules[index].trans_time = trans_time;
1135 srv->state->schedules[index].scene_number = scene_number;
1136
1137 bt_mesh_time_scene_server_state_change_t change = {
1138 .scheduler_act_set.index = index,
1139 .scheduler_act_set.year = year,
1140 .scheduler_act_set.month = month,
1141 .scheduler_act_set.day = day,
1142 .scheduler_act_set.hour = hour,
1143 .scheduler_act_set.minute = minute,
1144 .scheduler_act_set.second = second,
1145 .scheduler_act_set.day_of_week = day_of_week,
1146 .scheduler_act_set.action = action,
1147 .scheduler_act_set.trans_time = trans_time,
1148 .scheduler_act_set.scene_number = scene_number,
1149 };
1150 bt_mesh_time_scene_server_cb_evt_to_btc(
1151 BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1152
1153 if (ctx->recv_op == BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET) {
1154 send_scheduler_act_status(model, ctx, index);
1155 }
1156
1157 return;
1158 }
1159
1160 /* message handlers (End) */
1161
1162 /* Mapping of message handlers for Time Server (0x1200) */
1163 const struct bt_mesh_model_op bt_mesh_time_srv_op[] = {
1164 { BLE_MESH_MODEL_OP_TIME_GET, 0, time_get },
1165 { BLE_MESH_MODEL_OP_TIME_STATUS, 5, time_get },
1166 { BLE_MESH_MODEL_OP_TIME_ZONE_GET, 0, time_get },
1167 { BLE_MESH_MODEL_OP_TAI_UTC_DELTA_GET, 0, time_get },
1168 BLE_MESH_MODEL_OP_END,
1169 };
1170
1171 /* Mapping of message handlers for Time Setup Server (0x1201) */
1172 const struct bt_mesh_model_op bt_mesh_time_setup_srv_op[] = {
1173 { BLE_MESH_MODEL_OP_TIME_SET, 10, time_set },
1174 { BLE_MESH_MODEL_OP_TIME_ZONE_SET, 6, time_set },
1175 { BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET, 7, time_set },
1176 { BLE_MESH_MODEL_OP_TIME_ROLE_GET, 0, time_get },
1177 { BLE_MESH_MODEL_OP_TIME_ROLE_SET, 1, time_set },
1178 BLE_MESH_MODEL_OP_END,
1179 };
1180
1181 /* Mapping of message handlers for Scene Server (0x1203) */
1182 const struct bt_mesh_model_op bt_mesh_scene_srv_op[] = {
1183 { BLE_MESH_MODEL_OP_SCENE_GET, 0, scene_get },
1184 { BLE_MESH_MODEL_OP_SCENE_RECALL, 3, scene_recall },
1185 { BLE_MESH_MODEL_OP_SCENE_RECALL_UNACK, 3, scene_recall },
1186 { BLE_MESH_MODEL_OP_SCENE_REGISTER_GET, 0, scene_get },
1187 BLE_MESH_MODEL_OP_END,
1188 };
1189
1190 /* Mapping of message handlers for Scene Setup Server (0x1204) */
1191 const struct bt_mesh_model_op bt_mesh_scene_setup_srv_op[] = {
1192 { BLE_MESH_MODEL_OP_SCENE_STORE, 2, scene_action },
1193 { BLE_MESH_MODEL_OP_SCENE_STORE_UNACK, 2, scene_action },
1194 { BLE_MESH_MODEL_OP_SCENE_DELETE, 2, scene_action },
1195 { BLE_MESH_MODEL_OP_SCENE_DELETE_UNACK, 2, scene_action },
1196 BLE_MESH_MODEL_OP_END,
1197 };
1198
1199 /* Mapping of message handlers for Scheduler Server (0x1206) */
1200 const struct bt_mesh_model_op bt_mesh_scheduler_srv_op[] = {
1201 { BLE_MESH_MODEL_OP_SCHEDULER_GET, 0, scheduler_get },
1202 { BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET, 1, scheduler_get },
1203 BLE_MESH_MODEL_OP_END,
1204 };
1205
1206 /* Mapping of message handlers for Scheduler Setup Server (0x1207) */
1207 const struct bt_mesh_model_op bt_mesh_scheduler_setup_srv_op[] = {
1208 { BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET, 10, scheduler_act_set },
1209 { BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET_UNACK, 10, scheduler_act_set },
1210 BLE_MESH_MODEL_OP_END,
1211 };
1212
check_scene_server_init(struct bt_mesh_scenes_state * state)1213 static int check_scene_server_init(struct bt_mesh_scenes_state *state)
1214 {
1215 int i;
1216
1217 if (state->scene_count == 0U || state->scenes == NULL) {
1218 BT_ERR("Invalid Scene state");
1219 return -EINVAL;
1220 }
1221
1222 for (i = 0; i < state->scene_count; i++) {
1223 if (state->scenes[i].scene_value == NULL) {
1224 BT_ERR("Invalid Scene value, index %d", i);
1225 return -EINVAL;
1226 }
1227 }
1228
1229 return 0;
1230 }
1231
time_scene_server_init(struct bt_mesh_model * model)1232 static int time_scene_server_init(struct bt_mesh_model *model)
1233 {
1234 if (model->user_data == NULL) {
1235 BT_ERR("Invalid Time Scene Server user data, model id 0x%04x", model->id);
1236 return -EINVAL;
1237 }
1238
1239 switch (model->id) {
1240 case BLE_MESH_MODEL_ID_TIME_SRV: {
1241 struct bt_mesh_time_srv *srv = model->user_data;
1242 if (srv->state == NULL) {
1243 BT_ERR("Invalid Time State");
1244 return -EINVAL;
1245 }
1246 srv->model = model;
1247 break;
1248 }
1249 case BLE_MESH_MODEL_ID_TIME_SETUP_SRV: {
1250 struct bt_mesh_time_setup_srv *srv = model->user_data;
1251 if (srv->state == NULL) {
1252 BT_ERR("Invalid Time State");
1253 return -EINVAL;
1254 }
1255 srv->model = model;
1256 break;
1257 }
1258 case BLE_MESH_MODEL_ID_SCENE_SRV: {
1259 struct bt_mesh_scene_srv *srv = model->user_data;
1260 if (srv->state == NULL) {
1261 BT_ERR("Invalid Scene State");
1262 return -EINVAL;
1263 }
1264 if (check_scene_server_init(srv->state)) {
1265 return -EINVAL;
1266 }
1267 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
1268 bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
1269 k_delayed_work_init(&srv->transition.timer, scene_recall_work_handler);
1270 }
1271 srv->model = model;
1272 break;
1273 }
1274 case BLE_MESH_MODEL_ID_SCENE_SETUP_SRV: {
1275 struct bt_mesh_scene_setup_srv *srv = model->user_data;
1276 if (srv->state == NULL) {
1277 BT_ERR("Invalid Scene State");
1278 return -EINVAL;
1279 }
1280 if (check_scene_server_init(srv->state)) {
1281 return -EINVAL;
1282 }
1283 srv->model = model;
1284 break;
1285 }
1286 case BLE_MESH_MODEL_ID_SCHEDULER_SRV: {
1287 struct bt_mesh_scheduler_srv *srv = model->user_data;
1288 if (srv->state == NULL) {
1289 BT_ERR("Invalid Scheduler State");
1290 return -EINVAL;
1291 }
1292 if (srv->state->schedule_count == 0U || srv->state->schedules == NULL) {
1293 BT_ERR("Invalid Register Schedule");
1294 return -EINVAL;
1295 }
1296 srv->model = model;
1297 break;
1298 }
1299 case BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV: {
1300 struct bt_mesh_scheduler_setup_srv *srv = model->user_data;
1301 if (srv->state == NULL) {
1302 BT_ERR("Invalid Scheduler State");
1303 return -EINVAL;
1304 }
1305 if (srv->state->schedule_count == 0U || srv->state->schedules == NULL) {
1306 BT_ERR("Invalid Register Schedule");
1307 return -EINVAL;
1308 }
1309 srv->model = model;
1310 break;
1311 }
1312 default:
1313 BT_WARN("Unknown Time Scene Server, model id 0x%04x", model->id);
1314 return -EINVAL;
1315 }
1316
1317 bt_mesh_time_scene_server_mutex_new();
1318
1319 return 0;
1320 }
1321
time_srv_init(struct bt_mesh_model * model)1322 static int time_srv_init(struct bt_mesh_model *model)
1323 {
1324 if (model->pub == NULL) {
1325 BT_ERR("Time Server has no publication support");
1326 return -EINVAL;
1327 }
1328
1329 /**
1330 * When this model is present on an Element, the corresponding Time Setup
1331 * Server model shall also be present.
1332 */
1333 struct bt_mesh_elem *element = bt_mesh_model_elem(model);
1334 if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_TIME_SETUP_SRV) == NULL) {
1335 BT_WARN("Time Setup Server not present");
1336 /* Just give a warning here, continue with the initialization */
1337 }
1338 return time_scene_server_init(model);
1339 }
1340
time_setup_srv_init(struct bt_mesh_model * model)1341 static int time_setup_srv_init(struct bt_mesh_model *model)
1342 {
1343 /* This model does not support subscribing nor publishing */
1344 if (model->pub) {
1345 BT_ERR("Time Setup Server shall not support publication");
1346 return -EINVAL;
1347 }
1348
1349 return time_scene_server_init(model);
1350 }
1351
scene_srv_init(struct bt_mesh_model * model)1352 static int scene_srv_init(struct bt_mesh_model *model)
1353 {
1354 if (model->pub == NULL) {
1355 BT_ERR("Scene Server has no publication support");
1356 return -EINVAL;
1357 }
1358
1359 /* The model may be present only on the Primary element of a node. */
1360 if (!bt_mesh_model_in_primary(model)) {
1361 BT_WARN("Scene Server not on the Primary element");
1362 /* Just give a warning here, continue with the initialization */
1363 }
1364 /**
1365 * When this model is present on an Element, the corresponding Scene Setup
1366 * Server model shall also be present.
1367 */
1368 struct bt_mesh_elem *element = bt_mesh_model_elem(model);
1369 if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_SCENE_SETUP_SRV) == NULL) {
1370 BT_WARN("Scene Setup Server not present");
1371 /* Just give a warning here, continue with the initialization */
1372 }
1373 return time_scene_server_init(model);
1374 }
1375
scene_setup_srv_init(struct bt_mesh_model * model)1376 static int scene_setup_srv_init(struct bt_mesh_model *model)
1377 {
1378 /* The model may be present only on the Primary element of a node. */
1379 if (!bt_mesh_model_in_primary(model)) {
1380 BT_WARN("Scene Setup Server not on the Primary element");
1381 /* Just give a warning here, continue with the initialization */
1382 }
1383 return time_scene_server_init(model);
1384 }
1385
scheduler_srv_init(struct bt_mesh_model * model)1386 static int scheduler_srv_init(struct bt_mesh_model *model)
1387 {
1388 if (model->pub == NULL) {
1389 BT_ERR("Scheduler Server has no publication support");
1390 return -EINVAL;
1391 }
1392
1393 /* The model may be present only on the Primary element of a node. */
1394 if (!bt_mesh_model_in_primary(model)) {
1395 BT_WARN("Scheduler Server not on the Primary element");
1396 /* Just give a warning here, continue with the initialization */
1397 }
1398 /**
1399 * When this model is present on an Element, the corresponding Scheduler
1400 * Setup Server model shall also be present. The model requires the Time
1401 * Server model shall be present on the element.
1402 */
1403 struct bt_mesh_elem *element = bt_mesh_model_elem(model);
1404 if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV) == NULL) {
1405 BT_WARN("Scheduler Setup Server not present");
1406 /* Just give a warning here, continue with the initialization */
1407 }
1408 if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_TIME_SRV) == NULL) {
1409 BT_WARN("Time Server not present");
1410 /* Just give a warning here, continue with the initialization */
1411 }
1412 return time_scene_server_init(model);
1413 }
1414
scheduler_setup_srv_init(struct bt_mesh_model * model)1415 static int scheduler_setup_srv_init(struct bt_mesh_model *model)
1416 {
1417 /* The model may be present only on the Primary element of a node. */
1418 if (!bt_mesh_model_in_primary(model)) {
1419 BT_WARN("Scheduler Setup Server not on the Primary element");
1420 /* Just give a warning here, continue with the initialization */
1421 }
1422 return time_scene_server_init(model);
1423 }
1424
1425 #if CONFIG_BLE_MESH_DEINIT
time_scene_server_deinit(struct bt_mesh_model * model)1426 static int time_scene_server_deinit(struct bt_mesh_model *model)
1427 {
1428 if (model->user_data == NULL) {
1429 BT_ERR("Invalid Time Scene Server user data, model id 0x%04x", model->id);
1430 return -EINVAL;
1431 }
1432
1433 switch (model->id) {
1434 case BLE_MESH_MODEL_ID_SCENE_SRV: {
1435 struct bt_mesh_scene_srv *srv = model->user_data;
1436 if (srv->state == NULL) {
1437 BT_ERR("Invalid Scene State");
1438 return -EINVAL;
1439 }
1440 if (check_scene_server_init(srv->state)) {
1441 return -EINVAL;
1442 }
1443 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
1444 bt_mesh_server_free_ctx(&srv->transition.timer.work);
1445 k_delayed_work_free(&srv->transition.timer);
1446 }
1447 break;
1448 }
1449 case BLE_MESH_MODEL_ID_TIME_SRV:
1450 case BLE_MESH_MODEL_ID_TIME_SETUP_SRV:
1451 case BLE_MESH_MODEL_ID_SCENE_SETUP_SRV:
1452 case BLE_MESH_MODEL_ID_SCHEDULER_SRV:
1453 case BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV:
1454 break;
1455 default:
1456 BT_WARN("Unknown Time Scene Server, model id 0x%04x", model->id);
1457 return -EINVAL;
1458 }
1459
1460 bt_mesh_time_scene_server_mutex_free();
1461
1462 return 0;
1463 }
1464
time_srv_deinit(struct bt_mesh_model * model)1465 static int time_srv_deinit(struct bt_mesh_model *model)
1466 {
1467 if (model->pub == NULL) {
1468 BT_ERR("Time Server has no publication support");
1469 return -EINVAL;
1470 }
1471
1472 return time_scene_server_deinit(model);
1473 }
1474
time_setup_srv_deinit(struct bt_mesh_model * model)1475 static int time_setup_srv_deinit(struct bt_mesh_model *model)
1476 {
1477 if (model->pub) {
1478 BT_ERR("Time Setup Server shall not support publication");
1479 return -EINVAL;
1480 }
1481
1482 return time_scene_server_deinit(model);
1483 }
1484
scene_srv_deinit(struct bt_mesh_model * model)1485 static int scene_srv_deinit(struct bt_mesh_model *model)
1486 {
1487 if (model->pub == NULL) {
1488 BT_ERR("Scene Server has no publication support");
1489 return -EINVAL;
1490 }
1491
1492 return time_scene_server_deinit(model);
1493 }
1494
scene_setup_srv_deinit(struct bt_mesh_model * model)1495 static int scene_setup_srv_deinit(struct bt_mesh_model *model)
1496 {
1497 return time_scene_server_deinit(model);
1498 }
1499
scheduler_srv_deinit(struct bt_mesh_model * model)1500 static int scheduler_srv_deinit(struct bt_mesh_model *model)
1501 {
1502 if (model->pub == NULL) {
1503 BT_ERR("Scheduler Server has no publication support");
1504 return -EINVAL;
1505 }
1506
1507 return time_scene_server_deinit(model);
1508 }
1509
scheduler_setup_srv_deinit(struct bt_mesh_model * model)1510 static int scheduler_setup_srv_deinit(struct bt_mesh_model *model)
1511 {
1512 return time_scene_server_deinit(model);
1513 }
1514 #endif /* CONFIG_BLE_MESH_DEINIT */
1515
1516 const struct bt_mesh_model_cb bt_mesh_time_srv_cb = {
1517 .init = time_srv_init,
1518 #if CONFIG_BLE_MESH_DEINIT
1519 .deinit = time_srv_deinit,
1520 #endif /* CONFIG_BLE_MESH_DEINIT */
1521 };
1522
1523 const struct bt_mesh_model_cb bt_mesh_time_setup_srv_cb = {
1524 .init = time_setup_srv_init,
1525 #if CONFIG_BLE_MESH_DEINIT
1526 .deinit = time_setup_srv_deinit,
1527 #endif /* CONFIG_BLE_MESH_DEINIT */
1528 };
1529
1530 const struct bt_mesh_model_cb bt_mesh_scene_srv_cb = {
1531 .init = scene_srv_init,
1532 #if CONFIG_BLE_MESH_DEINIT
1533 .deinit = scene_srv_deinit,
1534 #endif /* CONFIG_BLE_MESH_DEINIT */
1535 };
1536
1537 const struct bt_mesh_model_cb bt_mesh_scene_setup_srv_cb = {
1538 .init = scene_setup_srv_init,
1539 #if CONFIG_BLE_MESH_DEINIT
1540 .deinit = scene_setup_srv_deinit,
1541 #endif /* CONFIG_BLE_MESH_DEINIT */
1542 };
1543
1544 const struct bt_mesh_model_cb bt_mesh_scheduler_srv_cb = {
1545 .init = scheduler_srv_init,
1546 #if CONFIG_BLE_MESH_DEINIT
1547 .deinit = scheduler_srv_deinit,
1548 #endif /* CONFIG_BLE_MESH_DEINIT */
1549 };
1550
1551 const struct bt_mesh_model_cb bt_mesh_scheduler_setup_srv_cb = {
1552 .init = scheduler_setup_srv_init,
1553 #if CONFIG_BLE_MESH_DEINIT
1554 .deinit = scheduler_setup_srv_deinit,
1555 #endif /* CONFIG_BLE_MESH_DEINIT */
1556 };
1557
1558 #endif /* CONFIG_BLE_MESH_TIME_SCENE_SERVER */
1559