time_scene_server.c 57 KB

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