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