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