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