state_transition.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. /* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
  2. *
  3. * SPDX-FileCopyrightText: 2018 Vikrant More
  4. * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. */
  8. #include "btc_ble_mesh_generic_model.h"
  9. #include "btc_ble_mesh_lighting_model.h"
  10. #include "btc_ble_mesh_time_scene_model.h"
  11. #include "btc_ble_mesh_sensor_model.h"
  12. #include "mesh/config.h"
  13. #include "mesh/model_opcode.h"
  14. #include "mesh/state_transition.h"
  15. #if (CONFIG_BLE_MESH_GENERIC_SERVER || \
  16. CONFIG_BLE_MESH_TIME_SCENE_SERVER || \
  17. CONFIG_BLE_MESH_LIGHTING_SERVER)
  18. /* Function to calculate Remaining Time (Start) */
  19. void bt_mesh_server_calc_remain_time(struct bt_mesh_state_transition *transition)
  20. {
  21. uint8_t steps = 0U, resolution = 0U;
  22. int32_t duration_remainder = 0;
  23. int64_t now = 0;
  24. if (transition->just_started) {
  25. transition->remain_time = transition->trans_time;
  26. } else {
  27. now = k_uptime_get();
  28. duration_remainder = transition->total_duration -
  29. (now - transition->start_timestamp);
  30. if (duration_remainder > 620000) {
  31. /* > 620 seconds -> resolution = 0b11 [10 minutes] */
  32. resolution = 0x03;
  33. steps = duration_remainder / 600000;
  34. } else if (duration_remainder > 62000) {
  35. /* > 62 seconds -> resolution = 0b10 [10 seconds] */
  36. resolution = 0x02;
  37. steps = duration_remainder / 10000;
  38. } else if (duration_remainder > 6200) {
  39. /* > 6.2 seconds -> resolution = 0b01 [1 seconds] */
  40. resolution = 0x01;
  41. steps = duration_remainder / 1000;
  42. } else if (duration_remainder > 0) {
  43. /* <= 6.2 seconds -> resolution = 0b00 [100 ms] */
  44. resolution = 0x00;
  45. steps = duration_remainder / 100;
  46. } else {
  47. resolution = 0x00;
  48. steps = 0x00;
  49. }
  50. transition->remain_time = (resolution << 6) | steps;
  51. }
  52. }
  53. /* Function to calculate Remaining Time (End) */
  54. static void tt_values_calculator(struct bt_mesh_state_transition *transition)
  55. {
  56. uint8_t steps_multiplier = 0U, resolution = 0U;
  57. resolution = (transition->trans_time >> 6);
  58. steps_multiplier = (transition->trans_time & 0x3F);
  59. switch (resolution) {
  60. case 0: /* 100ms */
  61. transition->total_duration = steps_multiplier * 100;
  62. break;
  63. case 1: /* 1 second */
  64. transition->total_duration = steps_multiplier * 1000;
  65. break;
  66. case 2: /* 10 seconds */
  67. transition->total_duration = steps_multiplier * 10000;
  68. break;
  69. case 3: /* 10 minutes */
  70. transition->total_duration = steps_multiplier * 600000;
  71. break;
  72. }
  73. transition->counter = ((float) transition->total_duration / 100);
  74. if (transition->counter > BLE_MESH_DEVICE_SPECIFIC_RESOLUTION) {
  75. transition->counter = BLE_MESH_DEVICE_SPECIFIC_RESOLUTION;
  76. }
  77. }
  78. static void transition_time_values(struct bt_mesh_state_transition *transition,
  79. uint8_t trans_time, uint8_t delay)
  80. {
  81. transition->trans_time = trans_time;
  82. transition->delay = delay;
  83. if (trans_time == 0U) {
  84. return;
  85. }
  86. tt_values_calculator(transition);
  87. transition->quo_tt = transition->total_duration / transition->counter;
  88. }
  89. static void transition_timer_start(struct bt_mesh_state_transition *transition)
  90. {
  91. transition->start_timestamp = k_uptime_get();
  92. k_delayed_work_submit_periodic(&transition->timer, K_MSEC(transition->quo_tt));
  93. bt_mesh_atomic_set_bit(transition->flag, BLE_MESH_TRANS_TIMER_START);
  94. }
  95. static void transition_timer_stop(struct bt_mesh_state_transition *transition)
  96. {
  97. k_delayed_work_cancel(&transition->timer);
  98. bt_mesh_atomic_clear_bit(transition->flag, BLE_MESH_TRANS_TIMER_START);
  99. }
  100. #if CONFIG_BLE_MESH_GENERIC_SERVER
  101. void generic_onoff_tt_values(struct bt_mesh_gen_onoff_srv *srv,
  102. uint8_t trans_time, uint8_t delay)
  103. {
  104. return transition_time_values(&srv->transition, trans_time, delay);
  105. }
  106. void generic_level_tt_values(struct bt_mesh_gen_level_srv *srv,
  107. uint8_t trans_time, uint8_t delay)
  108. {
  109. transition_time_values(&srv->transition, trans_time, delay);
  110. srv->tt_delta_level =
  111. ((float) (srv->state.level - srv->state.target_level) / srv->transition.counter);
  112. }
  113. void generic_power_level_tt_values(struct bt_mesh_gen_power_level_srv *srv,
  114. uint8_t trans_time, uint8_t delay)
  115. {
  116. transition_time_values(&srv->transition, trans_time, delay);
  117. srv->tt_delta_level =
  118. ((float) (srv->state->power_actual - srv->state->target_power_actual) / srv->transition.counter);
  119. }
  120. #endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
  121. #if CONFIG_BLE_MESH_LIGHTING_SERVER
  122. void light_lightness_actual_tt_values(struct bt_mesh_light_lightness_srv *srv,
  123. uint8_t trans_time, uint8_t delay)
  124. {
  125. transition_time_values(&srv->actual_transition, trans_time, delay);
  126. srv->tt_delta_lightness_actual =
  127. ((float) (srv->state->lightness_actual - srv->state->target_lightness_actual) / srv->actual_transition.counter);
  128. }
  129. void light_lightness_linear_tt_values(struct bt_mesh_light_lightness_srv *srv,
  130. uint8_t trans_time, uint8_t delay)
  131. {
  132. transition_time_values(&srv->linear_transition, trans_time, delay);
  133. srv->tt_delta_lightness_linear =
  134. ((float) (srv->state->lightness_linear - srv->state->target_lightness_linear) / srv->linear_transition.counter);
  135. }
  136. void light_ctl_tt_values(struct bt_mesh_light_ctl_srv *srv,
  137. uint8_t trans_time, uint8_t delay)
  138. {
  139. transition_time_values(&srv->transition, trans_time, delay);
  140. srv->tt_delta_lightness =
  141. ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
  142. srv->tt_delta_temperature =
  143. ((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter);
  144. srv->tt_delta_delta_uv =
  145. ((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter);
  146. }
  147. void light_ctl_temp_tt_values(struct bt_mesh_light_ctl_temp_srv *srv,
  148. uint8_t trans_time, uint8_t delay)
  149. {
  150. transition_time_values(&srv->transition, trans_time, delay);
  151. srv->tt_delta_temperature =
  152. ((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter);
  153. srv->tt_delta_delta_uv =
  154. ((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter);
  155. }
  156. void light_hsl_tt_values(struct bt_mesh_light_hsl_srv *srv,
  157. uint8_t trans_time, uint8_t delay)
  158. {
  159. transition_time_values(&srv->transition, trans_time, delay);
  160. srv->tt_delta_lightness =
  161. ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
  162. srv->tt_delta_hue =
  163. ((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter);
  164. srv->tt_delta_saturation =
  165. ((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter);
  166. }
  167. void light_hsl_hue_tt_values(struct bt_mesh_light_hsl_hue_srv *srv,
  168. uint8_t trans_time, uint8_t delay)
  169. {
  170. transition_time_values(&srv->transition, trans_time, delay);
  171. srv->tt_delta_hue =
  172. ((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter);
  173. }
  174. void light_hsl_sat_tt_values(struct bt_mesh_light_hsl_sat_srv *srv,
  175. uint8_t trans_time, uint8_t delay)
  176. {
  177. transition_time_values(&srv->transition, trans_time, delay);
  178. srv->tt_delta_saturation =
  179. ((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter);
  180. }
  181. void light_xyl_tt_values(struct bt_mesh_light_xyl_srv *srv,
  182. uint8_t trans_time, uint8_t delay)
  183. {
  184. transition_time_values(&srv->transition, trans_time, delay);
  185. srv->tt_delta_lightness =
  186. ((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
  187. srv->tt_delta_x =
  188. ((float) (srv->state->x - srv->state->target_x) / srv->transition.counter);
  189. srv->tt_delta_y =
  190. ((float) (srv->state->y - srv->state->target_y) / srv->transition.counter);
  191. }
  192. void light_lc_tt_values(struct bt_mesh_light_lc_srv *srv,
  193. uint8_t trans_time, uint8_t delay)
  194. {
  195. transition_time_values(&srv->transition, trans_time, delay);
  196. }
  197. #endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */
  198. #if CONFIG_BLE_MESH_TIME_SCENE_SERVER
  199. void scene_tt_values(struct bt_mesh_scene_srv *srv, uint8_t trans_time, uint8_t delay)
  200. {
  201. transition_time_values(&srv->transition, trans_time, delay);
  202. }
  203. #endif /* CONFIG_BLE_MESH_TIME_SCENE_SERVER */
  204. /* Timers related handlers & threads (Start) */
  205. #if CONFIG_BLE_MESH_GENERIC_SERVER
  206. void generic_onoff_work_handler(struct k_work *work)
  207. {
  208. struct bt_mesh_gen_onoff_srv *srv = CONTAINER_OF(work,
  209. struct bt_mesh_gen_onoff_srv,
  210. transition.timer.work);
  211. bt_mesh_gen_server_state_change_t change = {0};
  212. struct bt_mesh_msg_ctx *ctx = NULL;
  213. if (srv == NULL || srv->transition.timer.work.user_data == NULL) {
  214. BT_ERR("%s, Invalid parameter", __func__);
  215. return;
  216. }
  217. bt_mesh_generic_server_lock();
  218. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  219. if (srv->transition.just_started) {
  220. srv->transition.just_started = false;
  221. if (srv->transition.counter == 0U) {
  222. change.gen_onoff_set.onoff = srv->state.onoff;
  223. bt_mesh_generic_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
  224. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  225. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  226. } else {
  227. /**
  228. * Because binary states cannot support transitions, when changing to
  229. * 0x01 (On), the Generic OnOff state shall change immediately when
  230. * the transition starts, and when changing to 0x00, the state shall
  231. * change when the transition finishes.
  232. */
  233. if (srv->state.target_onoff == BLE_MESH_STATE_ON) {
  234. srv->state.onoff = BLE_MESH_STATE_ON;
  235. change.gen_onoff_set.onoff = srv->state.onoff;
  236. bt_mesh_generic_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
  237. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  238. }
  239. transition_timer_start(&srv->transition);
  240. }
  241. bt_mesh_generic_server_unlock();
  242. return;
  243. }
  244. if (srv->transition.counter != 0U) {
  245. srv->transition.counter--;
  246. }
  247. if (srv->transition.counter == 0U) {
  248. transition_timer_stop(&srv->transition);
  249. srv->state.onoff = srv->state.target_onoff;
  250. if (srv->state.target_onoff != BLE_MESH_STATE_ON) {
  251. change.gen_onoff_set.onoff = srv->state.onoff;
  252. bt_mesh_generic_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
  253. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  254. }
  255. }
  256. gen_onoff_publish(srv->model);
  257. bt_mesh_generic_server_unlock();
  258. }
  259. void generic_level_work_handler(struct k_work *work)
  260. {
  261. struct bt_mesh_gen_level_srv *srv = CONTAINER_OF(work,
  262. struct bt_mesh_gen_level_srv,
  263. transition.timer.work);
  264. bt_mesh_gen_server_state_change_t change = {0};
  265. struct bt_mesh_msg_ctx *ctx = NULL;
  266. if (srv == NULL || srv->transition.timer.work.user_data == NULL) {
  267. BT_ERR("%s, Invalid parameter", __func__);
  268. return;
  269. }
  270. bt_mesh_generic_server_lock();
  271. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  272. if (srv->transition.just_started) {
  273. srv->transition.just_started = false;
  274. if (srv->transition.counter == 0U) {
  275. switch (ctx->recv_op) {
  276. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
  277. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK:
  278. change.gen_level_set.level = srv->state.level;
  279. break;
  280. case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
  281. case BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK:
  282. change.gen_delta_set.level = srv->state.level;
  283. break;
  284. case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
  285. case BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK:
  286. change.gen_move_set.level = srv->state.level;
  287. break;
  288. }
  289. bt_mesh_generic_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
  290. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  291. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  292. } else {
  293. transition_timer_start(&srv->transition);
  294. }
  295. bt_mesh_generic_server_unlock();
  296. return;
  297. }
  298. if (srv->transition.counter != 0U) {
  299. srv->transition.counter--;
  300. srv->state.level -= srv->tt_delta_level;
  301. }
  302. if (srv->transition.counter == 0U) {
  303. transition_timer_stop(&srv->transition);
  304. srv->state.level = srv->state.target_level;
  305. }
  306. switch (ctx->recv_op) {
  307. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
  308. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK:
  309. change.gen_level_set.level = srv->state.level;
  310. break;
  311. case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
  312. case BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK:
  313. change.gen_delta_set.level = srv->state.level;
  314. break;
  315. case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
  316. case BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK:
  317. change.gen_move_set.level = srv->state.level;
  318. break;
  319. }
  320. bt_mesh_generic_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
  321. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  322. gen_level_publish(srv->model);
  323. bt_mesh_generic_server_unlock();
  324. }
  325. void generic_power_level_work_handler(struct k_work *work)
  326. {
  327. struct bt_mesh_gen_power_level_srv *srv = CONTAINER_OF(work,
  328. struct bt_mesh_gen_power_level_srv,
  329. transition.timer.work);
  330. bt_mesh_gen_server_state_change_t change = {0};
  331. struct bt_mesh_msg_ctx *ctx = NULL;
  332. if (srv == NULL || srv->state == NULL ||
  333. srv->transition.timer.work.user_data == NULL) {
  334. BT_ERR("%s, Invalid parameter", __func__);
  335. return;
  336. }
  337. bt_mesh_generic_server_lock();
  338. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  339. if (srv->transition.just_started) {
  340. srv->transition.just_started = false;
  341. if (srv->transition.counter == 0U) {
  342. change.gen_power_level_set.power = srv->state->power_actual;
  343. bt_mesh_generic_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
  344. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  345. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  346. } else {
  347. transition_timer_start(&srv->transition);
  348. }
  349. bt_mesh_generic_server_unlock();
  350. return;
  351. }
  352. if (srv->transition.counter != 0U) {
  353. srv->transition.counter--;
  354. srv->state->power_actual -= srv->tt_delta_level;
  355. }
  356. if (srv->transition.counter == 0U) {
  357. transition_timer_stop(&srv->transition);
  358. srv->state->power_actual = srv->state->target_power_actual;
  359. /**
  360. * Whenever the Generic Power Actual state is changed to a non-zero value
  361. * as a result of a non-transactional message or a completed sequence of
  362. * transactional messages, the value of the Generic Power Last state shall
  363. * be set to the value of the Generic Power Actual state.
  364. */
  365. if (srv->state->power_actual) {
  366. srv->state->power_last = srv->state->power_actual;
  367. }
  368. }
  369. change.gen_power_level_set.power = srv->state->power_actual;
  370. bt_mesh_generic_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE,
  371. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  372. gen_power_level_publish(srv->model, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
  373. bt_mesh_generic_server_unlock();
  374. }
  375. #endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
  376. #if CONFIG_BLE_MESH_LIGHTING_SERVER
  377. void light_lightness_actual_work_handler(struct k_work *work)
  378. {
  379. struct bt_mesh_light_lightness_srv *srv = CONTAINER_OF(work,
  380. struct bt_mesh_light_lightness_srv,
  381. actual_transition.timer.work);
  382. bt_mesh_light_server_state_change_t change = {0};
  383. struct bt_mesh_msg_ctx *ctx = NULL;
  384. if (srv == NULL || srv->state == NULL ||
  385. srv->actual_transition.timer.work.user_data == NULL) {
  386. BT_ERR("%s, Invalid parameter", __func__);
  387. return;
  388. }
  389. bt_mesh_light_server_lock();
  390. ctx = (struct bt_mesh_msg_ctx *)srv->actual_transition.timer.work.user_data;
  391. if (srv->actual_transition.just_started) {
  392. srv->actual_transition.just_started = false;
  393. if (srv->actual_transition.counter == 0U) {
  394. change.lightness_set.lightness = srv->state->lightness_actual;
  395. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  396. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  397. bt_mesh_atomic_clear_bit(srv->actual_transition.flag, BLE_MESH_TRANS_TIMER_START);
  398. } else {
  399. transition_timer_start(&srv->actual_transition);
  400. }
  401. bt_mesh_light_server_unlock();
  402. return;
  403. }
  404. if (srv->actual_transition.counter != 0U) {
  405. srv->actual_transition.counter--;
  406. srv->state->lightness_actual -= srv->tt_delta_lightness_actual;
  407. }
  408. if (srv->actual_transition.counter == 0U) {
  409. transition_timer_stop(&srv->actual_transition);
  410. srv->state->lightness_actual = srv->state->target_lightness_actual;
  411. /**
  412. * Whenever the Light Lightness Actual state is changed with a non-
  413. * transactional message or a completed sequence of transactional
  414. * messages to a non-zero value, the value of the Light Lightness
  415. * Last shall be set to the value of the Light Lightness Actual.
  416. */
  417. if (srv->state->lightness_actual) {
  418. srv->state->lightness_last = srv->state->lightness_actual;
  419. }
  420. }
  421. change.lightness_set.lightness = srv->state->lightness_actual;
  422. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  423. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  424. light_lightness_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
  425. bt_mesh_light_server_unlock();
  426. }
  427. void light_lightness_linear_work_handler(struct k_work *work)
  428. {
  429. struct bt_mesh_light_lightness_srv *srv = CONTAINER_OF(work,
  430. struct bt_mesh_light_lightness_srv,
  431. linear_transition.timer.work);
  432. bt_mesh_light_server_state_change_t change = {0};
  433. struct bt_mesh_msg_ctx *ctx = NULL;
  434. if (srv == NULL || srv->state == NULL ||
  435. srv->linear_transition.timer.work.user_data == NULL) {
  436. BT_ERR("%s, Invalid parameter", __func__);
  437. return;
  438. }
  439. bt_mesh_light_server_lock();
  440. ctx = (struct bt_mesh_msg_ctx *)srv->linear_transition.timer.work.user_data;
  441. if (srv->linear_transition.just_started) {
  442. srv->linear_transition.just_started = false;
  443. if (srv->linear_transition.counter == 0U) {
  444. change.lightness_linear_set.lightness = srv->state->lightness_linear;
  445. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  446. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  447. bt_mesh_atomic_clear_bit(srv->linear_transition.flag, BLE_MESH_TRANS_TIMER_START);
  448. } else {
  449. transition_timer_start(&srv->linear_transition);
  450. }
  451. bt_mesh_light_server_unlock();
  452. return;
  453. }
  454. if (srv->linear_transition.counter != 0U) {
  455. srv->linear_transition.counter--;
  456. srv->state->lightness_linear -= srv->tt_delta_lightness_linear;
  457. }
  458. if (srv->linear_transition.counter == 0U) {
  459. transition_timer_stop(&srv->linear_transition);
  460. srv->state->lightness_linear = srv->state->target_lightness_linear;
  461. }
  462. change.lightness_linear_set.lightness = srv->state->lightness_linear;
  463. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  464. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  465. light_lightness_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
  466. bt_mesh_light_server_unlock();
  467. }
  468. void light_ctl_work_handler(struct k_work *work)
  469. {
  470. struct bt_mesh_light_ctl_srv *srv = CONTAINER_OF(work,
  471. struct bt_mesh_light_ctl_srv,
  472. transition.timer.work);
  473. bt_mesh_light_server_state_change_t change = {0};
  474. struct bt_mesh_msg_ctx *ctx = NULL;
  475. if (srv == NULL || srv->state == NULL ||
  476. srv->transition.timer.work.user_data == NULL) {
  477. BT_ERR("%s, Invalid parameter", __func__);
  478. return;
  479. }
  480. bt_mesh_light_server_lock();
  481. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  482. if (srv->transition.just_started) {
  483. srv->transition.just_started = false;
  484. if (srv->transition.counter == 0U) {
  485. change.ctl_set.lightness = srv->state->lightness;
  486. change.ctl_set.temperature = srv->state->temperature;
  487. change.ctl_set.delta_uv = srv->state->delta_uv;
  488. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  489. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  490. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  491. } else {
  492. transition_timer_start(&srv->transition);
  493. }
  494. bt_mesh_light_server_unlock();
  495. return;
  496. }
  497. if (srv->transition.counter != 0U) {
  498. srv->transition.counter--;
  499. srv->state->lightness -= srv->tt_delta_lightness;
  500. srv->state->temperature -= srv->tt_delta_temperature;
  501. srv->state->delta_uv -= srv->tt_delta_delta_uv;
  502. }
  503. if (srv->transition.counter == 0U) {
  504. transition_timer_stop(&srv->transition);
  505. srv->state->lightness = srv->state->target_lightness;
  506. srv->state->temperature = srv->state->target_temperature;
  507. srv->state->delta_uv = srv->state->target_delta_uv;
  508. }
  509. change.ctl_set.lightness = srv->state->lightness;
  510. change.ctl_set.temperature = srv->state->temperature;
  511. change.ctl_set.delta_uv = srv->state->delta_uv;
  512. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  513. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  514. light_ctl_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
  515. bt_mesh_light_server_unlock();
  516. }
  517. void light_ctl_temp_work_handler(struct k_work *work)
  518. {
  519. struct bt_mesh_light_ctl_temp_srv *srv = CONTAINER_OF(work,
  520. struct bt_mesh_light_ctl_temp_srv,
  521. transition.timer.work);
  522. bt_mesh_light_server_state_change_t change = {0};
  523. struct bt_mesh_msg_ctx *ctx = NULL;
  524. if (srv == NULL || srv->state == NULL ||
  525. srv->transition.timer.work.user_data == NULL) {
  526. BT_ERR("%s, Invalid parameter", __func__);
  527. return;
  528. }
  529. bt_mesh_light_server_lock();
  530. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  531. if (srv->transition.just_started) {
  532. srv->transition.just_started = false;
  533. if (srv->transition.counter == 0U) {
  534. change.ctl_temp_set.temperature = srv->state->temperature;
  535. change.ctl_temp_set.delta_uv = srv->state->delta_uv;
  536. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  537. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  538. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  539. } else {
  540. transition_timer_start(&srv->transition);
  541. }
  542. bt_mesh_light_server_unlock();
  543. return;
  544. }
  545. if (srv->transition.counter != 0U) {
  546. srv->transition.counter--;
  547. srv->state->temperature -= srv->tt_delta_temperature;
  548. srv->state->delta_uv -= srv->tt_delta_delta_uv;
  549. }
  550. if (srv->transition.counter == 0U) {
  551. transition_timer_stop(&srv->transition);
  552. srv->state->temperature = srv->state->target_temperature;
  553. srv->state->delta_uv = srv->state->target_delta_uv;
  554. }
  555. change.ctl_temp_set.temperature = srv->state->temperature;
  556. change.ctl_temp_set.delta_uv = srv->state->delta_uv;
  557. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  558. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  559. light_ctl_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
  560. bt_mesh_light_server_unlock();
  561. }
  562. void light_hsl_work_handler(struct k_work *work)
  563. {
  564. struct bt_mesh_light_hsl_srv *srv = CONTAINER_OF(work,
  565. struct bt_mesh_light_hsl_srv,
  566. transition.timer.work);
  567. bt_mesh_light_server_state_change_t change = {0};
  568. struct bt_mesh_msg_ctx *ctx = NULL;
  569. if (srv == NULL || srv->state == NULL ||
  570. srv->transition.timer.work.user_data == NULL) {
  571. BT_ERR("%s, Invalid parameter", __func__);
  572. return;
  573. }
  574. bt_mesh_light_server_lock();
  575. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  576. if (srv->transition.just_started) {
  577. srv->transition.just_started = false;
  578. if (srv->transition.counter == 0U) {
  579. change.hsl_set.lightness = srv->state->lightness;
  580. change.hsl_set.hue = srv->state->hue;
  581. change.hsl_set.saturation = srv->state->saturation;
  582. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  583. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  584. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  585. } else {
  586. transition_timer_start(&srv->transition);
  587. }
  588. bt_mesh_light_server_unlock();
  589. return;
  590. }
  591. if (srv->transition.counter != 0U) {
  592. srv->transition.counter--;
  593. srv->state->lightness -= srv->tt_delta_lightness;
  594. srv->state->hue -= srv->tt_delta_hue;
  595. srv->state->saturation -= srv->tt_delta_saturation;
  596. }
  597. if (srv->transition.counter == 0U) {
  598. transition_timer_stop(&srv->transition);
  599. srv->state->lightness = srv->state->target_lightness;
  600. srv->state->hue = srv->state->target_hue;
  601. srv->state->saturation = srv->state->target_saturation;
  602. }
  603. change.hsl_set.lightness = srv->state->lightness;
  604. change.hsl_set.hue = srv->state->hue;
  605. change.hsl_set.saturation = srv->state->saturation;
  606. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  607. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  608. light_hsl_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
  609. bt_mesh_light_server_unlock();
  610. }
  611. void light_hsl_hue_work_handler(struct k_work *work)
  612. {
  613. struct bt_mesh_light_hsl_hue_srv *srv = CONTAINER_OF(work,
  614. struct bt_mesh_light_hsl_hue_srv,
  615. transition.timer.work);
  616. bt_mesh_light_server_state_change_t change = {0};
  617. struct bt_mesh_msg_ctx *ctx = NULL;
  618. if (srv == NULL || srv->state == NULL ||
  619. srv->transition.timer.work.user_data == NULL) {
  620. BT_ERR("%s, Invalid parameter", __func__);
  621. return;
  622. }
  623. bt_mesh_light_server_lock();
  624. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  625. if (srv->transition.just_started) {
  626. srv->transition.just_started = false;
  627. if (srv->transition.counter == 0U) {
  628. change.hsl_hue_set.hue = srv->state->hue;
  629. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  630. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  631. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  632. } else {
  633. transition_timer_start(&srv->transition);
  634. }
  635. bt_mesh_light_server_unlock();
  636. return;
  637. }
  638. if (srv->transition.counter != 0U) {
  639. srv->transition.counter--;
  640. srv->state->hue -= srv->tt_delta_hue;
  641. }
  642. if (srv->transition.counter == 0U) {
  643. transition_timer_stop(&srv->transition);
  644. srv->state->hue = srv->state->target_hue;
  645. }
  646. change.hsl_hue_set.hue = srv->state->hue;
  647. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  648. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  649. light_hsl_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
  650. bt_mesh_light_server_unlock();
  651. }
  652. void light_hsl_sat_work_handler(struct k_work *work)
  653. {
  654. struct bt_mesh_light_hsl_sat_srv *srv = CONTAINER_OF(work,
  655. struct bt_mesh_light_hsl_sat_srv,
  656. transition.timer.work);
  657. bt_mesh_light_server_state_change_t change = {0};
  658. struct bt_mesh_msg_ctx *ctx = NULL;
  659. if (srv == NULL || srv->state == NULL ||
  660. srv->transition.timer.work.user_data == NULL) {
  661. BT_ERR("%s, Invalid parameter", __func__);
  662. return;
  663. }
  664. bt_mesh_light_server_lock();
  665. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  666. if (srv->transition.just_started) {
  667. srv->transition.just_started = false;
  668. if (srv->transition.counter == 0U) {
  669. change.hsl_saturation_set.saturation = srv->state->saturation;
  670. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  671. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  672. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  673. } else {
  674. transition_timer_start(&srv->transition);
  675. }
  676. bt_mesh_light_server_unlock();
  677. return;
  678. }
  679. if (srv->transition.counter != 0U) {
  680. srv->transition.counter--;
  681. srv->state->saturation -= srv->tt_delta_saturation;
  682. }
  683. if (srv->transition.counter == 0U) {
  684. transition_timer_stop(&srv->transition);
  685. srv->state->saturation = srv->state->target_saturation;
  686. }
  687. change.hsl_saturation_set.saturation = srv->state->saturation;
  688. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  689. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  690. light_hsl_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
  691. bt_mesh_light_server_unlock();
  692. }
  693. void light_xyl_work_handler(struct k_work *work)
  694. {
  695. struct bt_mesh_light_xyl_srv *srv = CONTAINER_OF(work,
  696. struct bt_mesh_light_xyl_srv,
  697. transition.timer.work);
  698. bt_mesh_light_server_state_change_t change = {0};
  699. struct bt_mesh_msg_ctx *ctx = NULL;
  700. if (srv == NULL || srv->state == NULL ||
  701. srv->transition.timer.work.user_data == NULL) {
  702. BT_ERR("%s, Invalid parameter", __func__);
  703. return;
  704. }
  705. bt_mesh_light_server_lock();
  706. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  707. if (srv->transition.just_started) {
  708. srv->transition.just_started = false;
  709. if (srv->transition.counter == 0U) {
  710. change.xyl_set.lightness = srv->state->lightness;
  711. change.xyl_set.x = srv->state->x;
  712. change.xyl_set.y = srv->state->y;
  713. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  714. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  715. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  716. } else {
  717. transition_timer_start(&srv->transition);
  718. }
  719. bt_mesh_light_server_unlock();
  720. return;
  721. }
  722. if (srv->transition.counter != 0U) {
  723. srv->transition.counter--;
  724. srv->state->lightness -= srv->tt_delta_lightness;
  725. srv->state->x -= srv->tt_delta_x;
  726. srv->state->y -= srv->tt_delta_y;
  727. }
  728. if (srv->transition.counter == 0U) {
  729. transition_timer_stop(&srv->transition);
  730. srv->state->lightness = srv->state->target_lightness;
  731. srv->state->x = srv->state->target_x;
  732. srv->state->y = srv->state->target_y;
  733. }
  734. change.xyl_set.lightness = srv->state->lightness;
  735. change.xyl_set.x = srv->state->x;
  736. change.xyl_set.y = srv->state->y;
  737. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  738. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  739. light_xyl_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
  740. bt_mesh_light_server_unlock();
  741. }
  742. void light_lc_work_handler(struct k_work *work)
  743. {
  744. struct bt_mesh_light_lc_srv *srv = CONTAINER_OF(work,
  745. struct bt_mesh_light_lc_srv,
  746. transition.timer.work);
  747. bt_mesh_light_server_state_change_t change = {0};
  748. struct bt_mesh_msg_ctx *ctx = NULL;
  749. if (srv == NULL || srv->transition.timer.work.user_data == NULL) {
  750. BT_ERR("%s, Invalid parameter", __func__);
  751. return;
  752. }
  753. bt_mesh_light_server_lock();
  754. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  755. if (srv->transition.just_started) {
  756. srv->transition.just_started = false;
  757. if (srv->transition.counter == 0U) {
  758. change.lc_light_onoff_set.onoff = srv->lc->state.light_onoff;
  759. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  760. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  761. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  762. } else {
  763. /**
  764. * Because binary states cannot support transitions, when changing to
  765. * 0x01 (On), the Generic OnOff state shall change immediately when
  766. * the transition starts, and when changing to 0x00, the state shall
  767. * change when the transition finishes.
  768. */
  769. if (srv->lc->state.target_light_onoff == BLE_MESH_STATE_ON) {
  770. srv->lc->state.light_onoff = BLE_MESH_STATE_ON;
  771. bt_mesh_light_server_state_change_t change = {
  772. .lc_light_onoff_set.onoff = srv->lc->state.light_onoff,
  773. };
  774. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  775. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  776. }
  777. transition_timer_start(&srv->transition);
  778. }
  779. bt_mesh_light_server_unlock();
  780. return;
  781. }
  782. if (srv->transition.counter != 0U) {
  783. srv->transition.counter--;
  784. }
  785. if (srv->transition.counter == 0U) {
  786. transition_timer_stop(&srv->transition);
  787. srv->lc->state.light_onoff = srv->lc->state.target_light_onoff;
  788. if (srv->lc->state.light_onoff != BLE_MESH_STATE_ON) {
  789. change.lc_light_onoff_set.onoff = srv->lc->state.light_onoff;
  790. bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
  791. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  792. }
  793. }
  794. light_lc_publish(srv->model, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
  795. bt_mesh_light_server_unlock();
  796. }
  797. #endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */
  798. #if CONFIG_BLE_MESH_TIME_SCENE_SERVER
  799. void scene_recall_work_handler(struct k_work *work)
  800. {
  801. struct bt_mesh_scene_srv *srv = CONTAINER_OF(work,
  802. struct bt_mesh_scene_srv,
  803. transition.timer.work);
  804. bt_mesh_time_scene_server_state_change_t change = {0};
  805. struct bt_mesh_msg_ctx *ctx = NULL;
  806. if (srv == NULL || srv->state == NULL ||
  807. srv->transition.timer.work.user_data == NULL) {
  808. BT_ERR("%s, Invalid parameter", __func__);
  809. return;
  810. }
  811. bt_mesh_time_scene_server_lock();
  812. ctx = (struct bt_mesh_msg_ctx *)srv->transition.timer.work.user_data;
  813. if (srv->transition.just_started) {
  814. srv->transition.just_started = false;
  815. if (srv->transition.counter == 0U) {
  816. change.scene_recall.scene_number = srv->state->current_scene;
  817. bt_mesh_time_scene_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE,
  818. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  819. bt_mesh_atomic_clear_bit(srv->transition.flag, BLE_MESH_TRANS_TIMER_START);
  820. } else {
  821. transition_timer_start(&srv->transition);
  822. }
  823. bt_mesh_time_scene_server_unlock();
  824. return;
  825. }
  826. if (srv->transition.counter != 0U) {
  827. srv->transition.counter--;
  828. }
  829. if (srv->transition.counter == 0U) {
  830. transition_timer_stop(&srv->transition);
  831. srv->state->current_scene = srv->state->target_scene;
  832. srv->state->in_progress = false;
  833. srv->state->target_scene = INVALID_SCENE_NUMBER;
  834. }
  835. change.scene_recall.scene_number = srv->state->current_scene;
  836. bt_mesh_time_scene_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE,
  837. srv->model, ctx, (const uint8_t *)&change, sizeof(change));
  838. scene_publish(srv->model, ctx, BLE_MESH_MODEL_OP_SCENE_STATUS);
  839. bt_mesh_time_scene_server_unlock();
  840. }
  841. #endif /* CONFIG_BLE_MESH_TIME_SCENE_SERVER */
  842. /* Timers related handlers & threads (End) */
  843. void bt_mesh_server_stop_transition(struct bt_mesh_state_transition *transition)
  844. {
  845. memset(transition, 0x0, offsetof(struct bt_mesh_state_transition, flag));
  846. if (bt_mesh_atomic_test_and_clear_bit(transition->flag, BLE_MESH_TRANS_TIMER_START)) {
  847. k_delayed_work_cancel(&transition->timer);
  848. }
  849. }
  850. void bt_mesh_server_start_transition(struct bt_mesh_state_transition *transition)
  851. {
  852. k_delayed_work_submit(&transition->timer, K_MSEC(5 * transition->delay));
  853. if (transition->delay) {
  854. bt_mesh_atomic_set_bit(transition->flag, BLE_MESH_TRANS_TIMER_START);
  855. }
  856. }
  857. /* Messages handlers (End) */
  858. #endif /* (CONFIG_BLE_MESH_GENERIC_SERVER || \
  859. CONFIG_BLE_MESH_TIME_SCENE_SERVER || \
  860. CONFIG_BLE_MESH_LIGHTING_SERVER) */