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