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